@charset "utf-8";

/* ==========================================================================
   gautammahale.com
   Hand-written. No framework, no reset library, no utility classes.
   Layers, in cascade order:
     tokens → reset → type → layout → chrome → hero → pages → figures → code
   ========================================================================== */

@layer tokens, reset, type, layout, chrome, hero, pages, figures, code;

/* ==========================================================================
   FONTS
   Self-hosted, latin subset, variable weight. Two families only.
   ========================================================================== */

/* Supreme, by the Indian Type Foundry via Fontshare. Variable, 100–800, with
   a drawn italic rather than a slanted roman. Self-hosted: the ITF Free Font
   License permits it, and font-src is 'self' in the CSP. */
@font-face {
  font-family: "Supreme";
  src: url("/fonts/supreme-variable-normal.woff2") format("woff2");
  font-weight: 100 800;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Supreme";
  src: url("/fonts/supreme-variable-italic.woff2") format("woff2");
  font-weight: 100 800;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: "Commit Mono";
  src: url("/fonts/commit-mono-latin-400-normal.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Commit Mono";
  src: url("/fonts/commit-mono-latin-500-normal.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

/* ==========================================================================
   TOKENS
   ========================================================================== */

@layer tokens {
  :root {
    /* Warm paper. The accent is the pen, not a brand colour. */
    --paper: #fbf9f4;
    --paper-sunk: #f4f0e7;
    --ink: #171614;
    --ink-soft: #55514a;
    --ink-faint: #8a8478;
    --rule: #e2dcd0;
    --pen: #22365c;
    --pen-lit: #35507f;
    --oxide: #a6451f;
    --selection: #dfe6f2;

    --text: "Supreme", "Helvetica Neue", Helvetica, Arial, sans-serif;
    --mono: "Commit Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

    --measure: 37rem;
    --measure-wide: 52rem;
    --gutter: 1.5rem;

    --step: 1.6rem; /* vertical rhythm unit */

    color-scheme: light;
  }

  @media (prefers-color-scheme: dark) {
    :root {
      /* Not an inversion — a different material. Warm charcoal, no pure black. */
      --paper: #111110;
      --paper-sunk: #1a1917;
      --ink: #e6e1d6;
      --ink-soft: #9a948a;
      --ink-faint: #6b665e;
      --rule: #2a2823;
      --pen: #8fb3e0;
      --pen-lit: #aecbf0;
      --oxide: #d98a5f;
      --selection: #24303f;

      color-scheme: dark;
    }
  }
}

/* ==========================================================================
   RESET
   ========================================================================== */

@layer reset {
  *,
  *::before,
  *::after {
    box-sizing: border-box;
  }

  html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
  }

  body,
  h1, h2, h3, h4, h5, h6,
  p, figure, blockquote, dl, dd, ol, ul {
    margin: 0;
  }

  ol[class],
  ul[class] {
    list-style: none;
    padding: 0;
  }

  img,
  picture,
  canvas,
  svg {
    display: block;
    max-width: 100%;
  }

  button,
  input {
    font: inherit;
    color: inherit;
  }

  ::selection {
    background: var(--selection);
  }

  :focus-visible {
    outline: 2px solid var(--pen);
    outline-offset: 3px;
    border-radius: 1px;
  }

  @media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
      animation-duration: 0.001ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.001ms !important;
      scroll-behavior: auto !important;
    }
  }
}

/* ==========================================================================
   TYPE
   ========================================================================== */

@layer type {
  body {
    background: var(--paper);
    color: var(--ink);
    font-family: var(--text);
    font-size: 1.15rem;
    line-height: 1.65;
    font-weight: 400;
    font-synthesis-weight: none;
    text-rendering: optimizeLegibility;
    -webkit-font-smoothing: antialiased;
  }

  h1, h2, h3, h4 {
    font-family: var(--text);
    line-height: 1.2;
    text-wrap: balance;
    letter-spacing: -0.006em;
  }

  h1 { font-size: 2.15rem; font-weight: 600; }
  h2 { font-size: 1.5rem;  font-weight: 600; }
  h3 { font-size: 1.2rem;  font-weight: 600; }
  h4 { font-size: 1.05rem; font-weight: 600; }

  p {
    /* No `hyphens: auto`. Ragged-right does not need it, and at this measure
       it was breaking two words in the same paragraph. */
    text-wrap: pretty;
  }

  a {
    color: var(--pen);
    text-decoration-thickness: 0.055em;
    text-underline-offset: 0.16em;
    text-decoration-color: color-mix(in srgb, var(--pen) 38%, transparent);
    transition: color 0.15s, text-decoration-color 0.15s;
  }

  a:hover {
    color: var(--pen-lit);
    text-decoration-color: currentColor;
  }

  em { font-style: italic; }
  strong { font-weight: 600; }

  small,
  .meta {
    font-family: var(--mono);
    font-size: 0.76rem;
    letter-spacing: 0.04em;
    color: var(--ink-faint);
    font-variant-numeric: tabular-nums;
  }

  blockquote {
    border-left: 1px solid var(--rule);
    padding-left: 1.25rem;
    color: var(--ink-soft);
    font-style: italic;
  }

  hr {
    border: 0;
    border-top: 1px solid var(--rule);
    margin-block: calc(var(--step) * 1.5);
  }
}

/* ==========================================================================
   LAYOUT
   One grid gives every prose page three widths — text, wide, full — with no
   wrapper divs, and parks footnotes in the right margin when there is room.
   ========================================================================== */

@layer layout {
  .column {
    width: min(100% - (var(--gutter) * 2), var(--measure));
    margin-inline: auto;
  }

  .column--wide {
    width: min(100% - (var(--gutter) * 2), var(--measure-wide));
  }

  .prose {
    display: grid;
    grid-template-columns:
      [full-start] 1fr
      [wide-start] minmax(0, 6rem)
      [text-start] min(100% - (var(--gutter) * 2), var(--measure)) [text-end]
      minmax(0, 6rem) [wide-end]
      1fr [full-end];
  }

  .prose > * {
    grid-column: text;
  }

  .prose > .fig--wide,
  .prose > .wide {
    grid-column: wide;
  }

  .prose > .full {
    grid-column: full;
  }

  /* Vertical rhythm: space between siblings, never leading/trailing. */
  .prose > * + * { margin-top: var(--step); }
  .prose > * + h2 { margin-top: calc(var(--step) * 2.2); }
  .prose > * + h3 { margin-top: calc(var(--step) * 1.6); }
  .prose > h2 + *,
  .prose > h3 + * { margin-top: calc(var(--step) * 0.5); }

  .prose ul,
  .prose ol { padding-left: 1.4rem; }
  .prose li + li { margin-top: 0.35rem; }

  .skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    background: var(--paper);
    color: var(--ink);
    padding: 0.6rem 1rem;
    z-index: 100;
  }

  .skip-link:focus {
    left: 0;
  }
}

/* ==========================================================================
   CHROME — masthead and colophon.
   Deliberately almost nothing. The masthead does not stick.
   ========================================================================== */

@layer chrome {
  /* The masthead rule and the colophon rule line up with the left edge of the
     page's own content, whatever width that page runs at. Pages opt into the
     wider measure with `bodyClass: wide-page`. */
  .wide-page { --page-width: var(--measure-wide); }

  .masthead {
    width: min(100% - (var(--gutter) * 2), var(--page-width, var(--measure)));
    margin: 2.2rem auto 3.5rem;
    padding-bottom: 0.7rem;
    border-bottom: 1px solid var(--rule);
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.5rem;
    align-items: baseline;
    justify-content: space-between;
    font-family: var(--mono);
    font-size: 0.78rem;
    letter-spacing: 0.05em;
  }

  .masthead a {
    color: var(--ink-soft);
    text-decoration: none;
  }

  .masthead a:hover {
    color: var(--ink);
  }

  .masthead__nav {
    display: flex;
    gap: 1.4rem;
  }

  .masthead__nav a[aria-current] {
    color: var(--ink);
    box-shadow: inset 0 -1px 0 0 var(--ink);
  }

  /* No rule across the top. The page ends because it runs out of page, and a
     hairline drawn above the last line only announces that fact twice — the
     space does the separating on its own, given enough of it. */
  .colophon {
    width: min(100% - (var(--gutter) * 2), var(--page-width, var(--measure)));
    margin: 7rem auto 3.5rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.5rem;
    justify-content: space-between;
    align-items: baseline;
    font-family: var(--mono);
    font-size: 0.78rem;
    letter-spacing: 0.04em;
    color: var(--ink-faint);
  }

  .colophon__links {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 1.2rem;
    align-items: baseline;
  }

  /* These are the only way to reach me from the site, so they are set a shade
     above the colophon note beside them rather than level with it. The
     underline is painted at 0.08em — soft and thick, the weight of a marker,
     not the 1px hairline it replaces. */
  .colophon a {
    color: var(--ink-soft);
    text-decoration: none;
    background-image: linear-gradient(
      color-mix(in srgb, var(--ink-faint) 45%, transparent),
      color-mix(in srgb, var(--ink-faint) 45%, transparent)
    );
    background-repeat: no-repeat;
    background-position: 0 100%;
    background-size: 100% 0.08em;
    transition: background-size 0.2s, color 0.2s;
  }

  .colophon a:hover,
  .colophon a:focus-visible {
    color: var(--pen);
    background-image: linear-gradient(var(--pen), var(--pen));
    background-size: 100% 0.08em;
  }

  .colophon__note {
    color: var(--ink-faint);
  }
}

/* ==========================================================================
   HERO — the harmonograph.
   The loader is this same band at full viewport height; there is no separate
   splash element and nothing is thrown away on reveal.
   ========================================================================== */

@layer hero {
  /* The height never changes — not while loading, not on reveal. Animating it
     would force the canvas backing store to be re-fitted and the drawing
     re-rendered on every frame of the transition, which is both expensive and
     visibly wrong. The drawing simply sits on the paper; what arrives on
     reveal is the writing. 78svh rather than a full screen so the first lines
     of the intro show below the fold and invite the scroll. */
  .hero {
    position: relative;
    height: min(78vh, 42rem);
    height: min(78svh, 42rem);
    display: grid;
    align-items: end;
    overflow: hidden;
  }

  .hero__canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
  }

  .hero__body {
    position: relative;
    width: min(100% - (var(--gutter) * 2), var(--measure-wide));
    margin-inline: auto;
    padding-bottom: clamp(1.5rem, 6vh, 3.5rem);
  }

  .hero__name {
    font-size: clamp(2.4rem, 7vw, 3.6rem);
    font-weight: 500;
    letter-spacing: -0.018em;
    line-height: 1;
  }

  .hero__line {
    margin-top: 0.7rem;
    max-width: 34rem;
    color: var(--ink-soft);
    font-size: 1.05rem;
    line-height: 1.5;
    text-wrap: balance;
  }

  /* The landing page runs at the wide measure so the hero, the intro and the
     doors all share one left edge — but prose still has to be set at a readable
     width, not stretched across the whole 52rem. */
  .intro {
    margin-top: calc(var(--step) * 2.5);
  }

  .intro p {
    max-width: 34rem;
  }

  .intro p + p {
    margin-top: var(--step);
  }

  /* Everything that waits for the loader. `.is-loading` is only ever added by
     js/loader.js — never here — so a blocked or broken script leaves the page
     perfectly readable rather than blank. */
  .reveal {
    transition: opacity 0.7s ease 0.15s, transform 0.7s cubic-bezier(0.22, 0.9, 0.24, 1) 0.15s;
  }

  html.is-loading .reveal {
    opacity: 0;
    transform: translateY(0.9rem);
  }

  html.is-loading,
  html.is-loading body {
    overflow: hidden;
  }

  /* --- the intro: a numeral that climbs, and a bar down the edge ---------
     Mechanism adapted from the loader on gregorylalle.com. The field is
     --paper rather than white on purpose: the harmonograph is drawing itself
     behind this the whole time, and the page's own colour makes the end of it
     read as the drawing arriving rather than as a screen being pulled away.

     display:none is the resting state and the class that lifts it is only ever
     added by js/loader.js, so a blocked script leaves the page uncovered. */
     The visible state is keyed to `.is-live`, which intro.js adds, rather than
     to html.is-loading. The two have to come apart at the end: the field needs
     to keep fading for a moment *after* the page has been handed back, so the
     writing comes up underneath it instead of waiting for it to clear. Keyed to
     .is-loading, removing that class would cut the field off mid-fade. */
  .loader {
    display: none;
  }

  .loader.is-live {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 90;
    background: var(--paper);
    pointer-events: none;
    opacity: 1;
    transition: opacity 0.45s ease;
  }

  .loader.is-gone {
    opacity: 0;
  }

  .loader.is-done {
    display: none;
  }

  /* Shares the landing page's content column, so the numeral's left edge lands
     on the same line as the name below it rather than near it. */
  .loader__no {
    position: absolute;
    top: 0.7rem;
    left: 0;
    right: 0;
    width: min(100% - (var(--gutter) * 2), var(--measure-wide));
    margin-inline: auto;
    overflow: hidden;
    font-size: clamp(4.5rem, 21vw, 13rem);
    font-weight: 700;
    letter-spacing: -0.055em;
    line-height: 0.86;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
  }

  /* Armed a frame late, so the numeral starts at the bottom of the screen
     instead of sliding there from the top on the first paint. */
  .loader.is-armed .loader__no {
    transition: transform 0.55s cubic-bezier(0.22, 0.9, 0.24, 1);
  }

  .loader__digits {
    display: block;
  }

  .loader__digits span {
    display: inline-block;
    transition: transform 0.62s cubic-bezier(0.6, 0, 0.2, 1);
  }

  .loader.is-out .loader__digits span {
    transform: translateY(-105%);
  }

  .loader__bar {
    position: absolute;
    top: 0;
    right: 0;
    width: 0.4rem;
    height: 100%;
    background: var(--ink);
    transform: scaleY(0);
    transform-origin: top;
  }

  .loader.is-armed .loader__bar {
    transition: transform 0.5s cubic-bezier(0.22, 0.9, 0.24, 1);
  }

  .loader.is-out .loader__bar {
    transform: scaleY(0);
  }

  /* The two doors — the part titles of the site, and after the drawing the
     loudest thing on the page.

     An earlier version set them as ruled rows: a medium-weight label, a hairline
     leader running out to an arrow, a line of small faint mono underneath. Every
     one of those moves made the doors smaller than they should be. The rules
     drew a box that the words then had to sit politely inside, and setting the
     one sentence that says what each section *is* in 0.76rem mono buried it
     under the decoration. So: no rules, no leader, no arrow. Big words set in
     the weight the family was drawn for, and the sentence underneath in the
     reading face at reading size, because it is meant to be read. */
  .doors {
    display: grid;
    gap: calc(var(--step) * 1.9);
    margin-top: calc(var(--step) * 3);
  }

  .door {
    display: block;
    width: fit-content;
    max-width: 36rem;
    text-decoration: none;
    color: var(--ink);
  }

  .door__label {
    display: inline-block;
    font-size: clamp(2.2rem, 6.5vw, 3rem);
    font-weight: 700;
    letter-spacing: -0.032em;
    line-height: 1.12;
    /* Painted rather than a border or text-decoration, so it can grow out from
       the left edge on hover and be as thick as a pen — a hairline underline
       here would put back exactly what the rules were removed for. */
    background-image: linear-gradient(var(--pen), var(--pen));
    background-repeat: no-repeat;
    background-position: 0 100%;
    background-size: 0 0.085em;
    transition: background-size 0.34s cubic-bezier(0.22, 0.9, 0.24, 1), color 0.2s;
  }

  .door__note {
    display: block;
    margin-top: 0.55rem;
    /* Same measure as the intro above it, so the two blocks share a right rag
       instead of each finding its own. */
    max-width: 34rem;
    color: var(--ink-soft);
    font-size: 1.02rem;
    line-height: 1.5;
    letter-spacing: 0;
    text-wrap: pretty;
  }

  .door:hover .door__label,
  .door:focus-visible .door__label {
    color: var(--pen);
    background-size: 100% 0.085em;
  }
}

/* ==========================================================================
   PAGES — index lists and the art stream.
   ========================================================================== */

@layer pages {
  /* You arrive here by clicking a word set at 3rem on the landing page, so the
     heading that greets you cannot be a 1.6rem semibold — it has to be
     recognisably the same word, and it has to outrank the post titles under it.
     Slightly smaller than the door it came from: the door was an invitation,
     this is a place you are already standing in. */
  .page-title {
    font-size: clamp(1.9rem, 5vw, 2.4rem);
    font-weight: 700;
    letter-spacing: -0.028em;
    line-height: 1.1;
  }

  .page-intro {
    margin-top: 0.75rem;
    color: var(--ink-soft);
    max-width: 34rem;
  }

  /* --- learnings index: date, title, one line. No cards, no thumbnails. --- */

  /* Same reasoning as the doors on the landing page: the rows used to be boxed
     off from each other with a hairline top and bottom, which made a list of
     two posts look like a table that had lost its headers. Space separates them
     now, and the titles carry the weight the rules were standing in for. The
     date stays in mono — it is a date, it wants tabular figures, and it is the
     one thing on the page that is genuinely a label rather than prose. */
  .entries {
    margin-top: calc(var(--step) * 2.5);
    display: grid;
    gap: calc(var(--step) * 1.75);
  }

  .entry {
    display: grid;
    grid-template-columns: 7rem 1fr;
    gap: 0.25rem 1.5rem;
  }

  .entry__date {
    font-family: var(--mono);
    font-size: 0.74rem;
    letter-spacing: 0.04em;
    color: var(--ink-faint);
    /* Sits the mono date's baseline on the title's, which the two different
       line heights do not do on their own. */
    padding-top: 0.46rem;
    font-variant-numeric: tabular-nums;
  }

  .entry__title {
    font-size: 1.5rem;
    font-weight: 700;
    letter-spacing: -0.022em;
    line-height: 1.22;
  }

  .entry__title a {
    color: var(--ink);
    text-decoration: none;
    background-image: linear-gradient(var(--pen), var(--pen));
    background-repeat: no-repeat;
    background-position: 0 100%;
    background-size: 0 0.075em;
    transition: background-size 0.3s cubic-bezier(0.22, 0.9, 0.24, 1), color 0.2s;
  }

  .entry__title a:hover,
  .entry__title a:focus-visible {
    color: var(--pen);
    background-size: 100% 0.075em;
  }

  .entry__blurb {
    grid-column: 2;
    margin-top: 0.35rem;
    max-width: 32rem;
    color: var(--ink-soft);
    font-size: 1.02rem;
    line-height: 1.5;
    text-wrap: pretty;
  }

  @media (max-width: 34rem) {
    .entry { grid-template-columns: 1fr; }
    .entry__date { padding-top: 0; order: -1; }
    .entry__blurb { grid-column: 1; }
  }

  /* --- post header --- */

  .post-header {
    margin-bottom: calc(var(--step) * 2);
  }

  .post-header h1 {
    font-size: clamp(1.9rem, 5vw, 2.5rem);
    font-weight: 600;
  }

  .post-header__meta {
    display: block;
    margin-bottom: 0.7rem;
  }

  .post-header__blurb {
    margin-top: 0.8rem;
    color: var(--ink-soft);
    font-size: 1.08rem;
  }

  /* --- art: a stream, one piece per row. Never a cropped grid. --- */

  .art-filter {
    display: flex;
    flex-wrap: wrap;
    gap: 0.9rem;
    margin-top: calc(var(--step) * 1.5);
    padding-bottom: 0.8rem;
    border-bottom: 1px solid var(--rule);
    font-family: var(--mono);
    font-size: 0.76rem;
    letter-spacing: 0.05em;
  }

  .art-filter button {
    background: none;
    border: 0;
    padding: 0.15rem 0;
    color: var(--ink-faint);
    cursor: pointer;
    letter-spacing: inherit;
    font-family: inherit;
    font-size: inherit;
  }

  .art-filter button:hover { color: var(--ink-soft); }

  .art-filter button[aria-pressed="true"] {
    color: var(--ink);
    box-shadow: inset 0 -1px 0 0 var(--ink);
  }

  .stream {
    margin-top: calc(var(--step) * 2.5);
    display: grid;
    gap: calc(var(--step) * 3);
  }

  .piece[hidden] { display: none; }

  .piece__frame {
    display: block;
    background: var(--paper-sunk);
  }

  .piece__frame img {
    width: 100%;
    height: auto;
  }

  .piece__caption {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem 1rem;
    align-items: baseline;
    margin-top: 0.7rem;
    font-family: var(--mono);
    font-size: 0.76rem;
    letter-spacing: 0.04em;
    color: var(--ink-faint);
  }

  .piece__caption strong {
    font-weight: 500;
    color: var(--ink-soft);
  }

  .piece__caption a {
    color: var(--ink-faint);
    text-decoration: none;
    box-shadow: inset 0 -1px 0 0 var(--rule);
  }

  .piece__caption a:hover { color: var(--ink); }

  .piece__note {
    margin-top: 0.5rem;
    max-width: var(--measure);
    color: var(--ink-soft);
    font-size: 0.97rem;
  }

  .empty-note {
    margin-top: calc(var(--step) * 2);
    color: var(--ink-faint);
    font-family: var(--mono);
    font-size: 0.8rem;
  }
}

/* ==========================================================================
   FIGURES — live canvases and the shared slider.
   ========================================================================== */

@layer figures {
  .fig {
    margin-block: calc(var(--step) * 2);
  }

  .fig__stage {
    position: relative;
    width: 100%;
    background: var(--paper-sunk);
    overflow: hidden;
  }

  .fig__canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    touch-action: none;
  }

  .fig--grab .fig__canvas { cursor: grab; }
  .fig--grab .fig__canvas:active { cursor: grabbing; }

  .fig__controls:not(:empty) {
    display: grid;
    gap: 0.9rem;
    max-width: 30rem;
    margin: 1.4rem auto 0;
  }

  .fig figcaption {
    max-width: 34rem;
    margin: 1rem auto 0;
    text-align: center;
    font-family: var(--mono);
    font-size: 0.76rem;
    line-height: 1.6;
    letter-spacing: 0.03em;
    color: var(--ink-faint);
  }

  /* --- slider: a handle you can actually grab, not a 12px range input --- */

  .slider {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 0.35rem 1rem;
    align-items: center;
    font-family: var(--mono);
    font-size: 0.74rem;
    letter-spacing: 0.04em;
    color: var(--ink-faint);
  }

  .slider__label { grid-column: 1; }
  .slider__value {
    grid-column: 2;
    color: var(--ink-soft);
    font-variant-numeric: tabular-nums;
  }

  .slider__track {
    grid-column: 1 / -1;
    position: relative;
    height: 28px;
    cursor: pointer;
    touch-action: none;
  }

  .slider__track::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    height: 1px;
    background: var(--rule);
  }

  .slider__fill {
    position: absolute;
    left: 0;
    top: 50%;
    height: 1px;
    background: var(--pen);
    transform-origin: left;
  }

  .slider__handle {
    position: absolute;
    top: 50%;
    width: 13px;
    height: 13px;
    margin: -6.5px 0 0 -6.5px;
    background: var(--pen);
    border-radius: 2px;
    cursor: grab;
    transition: transform 0.12s ease;
  }

  .slider__track:hover .slider__handle { transform: scale(1.15); }
  .slider__track:active .slider__handle { cursor: grabbing; transform: scale(0.95); }

  /* The grab target is generously bigger than the visible handle. */
  .slider__handle::after {
    content: "";
    position: absolute;
    inset: -11px;
  }
}

/* ==========================================================================
   CODE, MATH, MARGIN NOTES
   ========================================================================== */

@layer code {
  code, kbd, samp, pre {
    font-family: var(--mono);
    font-size: 0.86em;
    font-variant-ligatures: none;
  }

  :not(pre) > code {
    background: var(--paper-sunk);
    padding: 0.1em 0.35em;
    border-radius: 2px;
    color: var(--ink-soft);
  }

  pre[class*="language-"] {
    background: var(--paper-sunk);
    border-left: 1px solid var(--rule);
    padding: 1rem 1.15rem;
    overflow-x: auto;
    line-height: 1.55;
    tab-size: 2;
    font-size: 0.82rem;
  }

  pre[class*="language-"] code { background: none; padding: 0; }

  /* Prism, themed in the paper palette. A stock dark theme on light paper is
     the loudest possible tell that nobody looked at this page. */
  .token.comment,
  .token.prolog,
  .token.doctype,
  .token.cdata { color: var(--ink-faint); font-style: italic; }

  .token.punctuation { color: var(--ink-faint); }

  .token.keyword,
  .token.atrule,
  .token.rule,
  .token.important { color: var(--pen); font-weight: 500; }

  .token.string,
  .token.char,
  .token.attr-value,
  .token.regex { color: var(--oxide); }

  .token.number,
  .token.boolean,
  .token.constant,
  .token.symbol { color: var(--oxide); }

  .token.function,
  .token.class-name,
  .token.tag { color: var(--ink); font-weight: 500; }

  .token.property,
  .token.attr-name,
  .token.variable,
  .token.parameter { color: var(--ink-soft); }

  .token.operator { color: var(--ink-soft); background: none; }

  .token.deleted { color: var(--oxide); }
  .token.inserted { color: var(--pen); }

  /* --- maths --- */

  .katex-display {
    overflow-x: auto;
    overflow-y: hidden;
    padding-block: 0.4rem;
  }

  /* Inline maths should not break across lines. KaTeX will happily wrap at a
     relation, which puts "2 :" at the end of one line and "3" at the start of
     the next. Display maths keeps its own wrapping. */
  p > .katex,
  li > .katex {
    white-space: nowrap;
  }

  /* --- footnotes become margin notes on wide viewports --- */

  .footnote-ref a {
    text-decoration: none;
    font-family: var(--mono);
    font-size: 0.72em;
    padding-left: 0.1em;
    color: var(--pen);
  }

  .footnotes {
    margin-top: calc(var(--step) * 2);
    padding-top: 1rem;
    border-top: 1px solid var(--rule);
    font-size: 0.92rem;
    color: var(--ink-soft);
  }

  .footnotes-list { padding-left: 1.2rem; }
  .footnotes li + li { margin-top: 0.6rem; }
  .footnote-backref { text-decoration: none; }

  @media (min-width: 68rem) {
    /* Lift each note out of the list and into the right margin, level with
       its reference. `sidenote.js` sets --sn-top per note. */
    .prose > .footnotes {
      grid-column: text;
      position: relative;
      margin: 0;
      padding: 0;
      border: 0;
    }

    .prose > .footnotes .footnotes-list {
      list-style: none;
      padding: 0;
      margin: 0;
    }

    .prose > .footnotes .footnotes-list > li {
      position: absolute;
      left: calc(100% + 2rem);
      top: var(--sn-top, 0);
      width: 12rem;
      margin: 0;
      font-family: var(--mono);
      font-size: 0.72rem;
      line-height: 1.65;
      letter-spacing: 0.02em;
      color: var(--ink-faint);
    }

    .prose > .footnotes .footnotes-list > li p { margin: 0; }
    .prose > .footnotes .footnote-backref { display: none; }
  }
}
