/* Garden: "Field Notes". Paper and ink with a quiet digital layer.
   Organic: paper grain, hand-cut edges, contour lines.
   Digital: monospace subtitles and labels, precise motion on touch.
   Only tokens, ornament, and interaction live here; site.css owns
   structure. */

@font-face {
  font-family: Literata;
  src: url("../fonts/literata-latin.woff2") format("woff2");
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
}
@font-face {
  font-family: Literata;
  src: url("../fonts/literata-latin-italic.woff2") format("woff2");
  font-style: italic;
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("../fonts/jetbrains-mono-latin.woff2") format("woff2");
  font-style: normal;
  font-weight: 100 800;
  font-display: swap;
}

@layer garden {
  /* Palette: the warm cream paper and brown ink of the original site,
     with a soft lavender accent. */
  :root {
    --paper: light-dark(#f5f1e8, #1b1815);
    --surface: light-dark(#ebe5da, #27221e);
    --ink: light-dark(#454038, #d7cdc0);
    --ink-soft: light-dark(#756e63, #a99f93);
    --rust: light-dark(#7d432e, #cf9278);
    --rule: light-dark(#d8d0c3, #403933);
    --rule-strong: light-dark(#c3b8a6, #564c43);

    --accent: light-dark(oklch(53% 0.1 290), oklch(79% 0.08 290));
    --link: var(--ink);
    --highlight: color-mix(in oklch, var(--accent) 22%, transparent);

    --font-prose: Literata, Georgia, "Iowan Old Style", serif;
    --font-mono: "JetBrains Mono", ui-monospace, "SFMono-Regular", Menlo,
      monospace;

    --radius: 0.5rem;
    --plate-tone: sepia(0.16) saturate(0.86) contrast(0.97);
    /* A hand-cut edge: every corner a slightly different curve. */
    --radius-organic: 0.35rem 1.1rem 0.5rem 0.9rem / 0.9rem 0.4rem 1rem 0.35rem;
    --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
    --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);

    --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .35 0 0 0 0 .24 0 0 0 0 .14 0 0 0 .6 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
    --grain-opacity: 0.1;
    --grain-blend: multiply;

    /* Three drifting contour lines, used as a mask so the stroke takes
       whatever color the element paints. */
    --contour: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 24' preserveAspectRatio='none'%3E%3Cg fill='none' stroke='black' stroke-width='1' stroke-linecap='round' vector-effect='non-scaling-stroke'%3E%3Cpath vector-effect='non-scaling-stroke' d='M1 6C30 2 50 10 80 6S130 1 160 6s50 5 79-1'/%3E%3Cpath vector-effect='non-scaling-stroke' d='M1 12c34-4 54 4 84 0s50-5 80 0 50 5 74-1'/%3E%3Cpath vector-effect='non-scaling-stroke' d='M1 18c27-3 59 4 89 0s50-5 80 0 50 4 69-1'/%3E%3C/g%3E%3C/svg%3E");
  }

  @media (prefers-color-scheme: dark) {
    :root {
      --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .5 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
      --grain-opacity: 0.06;
      --grain-blend: screen;
      --plate-tone: sepia(0.16) saturate(0.8) brightness(0.88);
    }
  }

  /* Paper with grain over everything. */
  html {
    scrollbar-color: var(--rule-strong) transparent;
    font-size: 1.0625rem;
    line-height: 1.68;
  }
  body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background-image: var(--grain);
    opacity: var(--grain-opacity);
    mix-blend-mode: var(--grain-blend);
  }

  h1,
  h2,
  h3 {
    font-weight: 450;
  }
  h1 {
    font-size: clamp(2rem, 7vw, 3.5rem);
  }
  .article-body h2 {
    font-size: 1.55rem;
  }
  .article-body h3 {
    font-size: 1.2rem;
  }

  /* Subtitles belong to the digital layer. */
  .article-dek,
  .post-dek {
    color: var(--ink-soft);
    font-family: var(--font-mono);
    letter-spacing: -0.01em;
  }
  .article-dek {
    font-size: 0.92rem;
    line-height: 1.6;
  }
  .post-dek {
    font-size: 0.76rem;
    line-height: 1.55;
  }
  /* The date is stamped above the title, like the head of a field note. */
  .article-date {
    color: var(--ink-soft);
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.08em;
  }

  /* Links: a resting hairline, and an accent line that draws in from the
     left on touch and retracts to the right on release. */
  a {
    --underline-rest: color-mix(in oklch, var(--accent) 45%, transparent);
    --underline-at: 100%;
    --underline-size: 0%;
    text-decoration: none;
    background:
      linear-gradient(var(--accent) 0 0) var(--underline-at) 100% /
        var(--underline-size) 0.1em no-repeat,
      linear-gradient(var(--underline-rest) 0 0) 0 100% / 100% 1px no-repeat;
    padding-block-end: 0.08em;
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
  }
  a:is(:hover, :focus-visible) {
    --underline-at: 0%;
    --underline-size: 100%;
  }

  /* Breadcrumb: the page's address, quiet and monospace. */
  .breadcrumb {
    color: var(--ink-soft);
    font-family: var(--font-mono);
    font-size: 0.78rem;
    letter-spacing: 0.02em;
  }
  .breadcrumb a {
    --underline-rest: transparent;
    color: var(--ink-soft);
    transition: color 250ms var(--ease-out);
  }
  .breadcrumb a:hover,
  .breadcrumb a[aria-current="page"] {
    color: var(--ink);
  }
  .breadcrumb li + li::before {
    color: var(--rule-strong);
  }

  /* Rail: menu rows between dotted rules, each marked by a small glyph.
     Touching a row wipes an inverted ink bar across it; the current page
     carries a small accent square. */
  .rail {
    border-block-start: 1px solid var(--rule);
  }
  @media (min-width: 60rem) {
    .rail {
      border-block-start: 0;
      border-inline-start: 1px solid var(--rule);
    }
  }
  /* Dotted rules: a 1px dot every 4px, crisper than a native dotted
     border, which blurs into a solid line at 1x density. */
  .rail-links li {
    --dots: linear-gradient(to right, var(--rule-strong) 1px, transparent 1px)
      0 0 / 4px 1px repeat-x;
    padding-block: 1px 0;
    background: var(--dots);
  }
  .rail-links li:last-child {
    padding-block-end: 1px;
    background:
      var(--dots),
      linear-gradient(to right, var(--rule-strong) 1px, transparent 1px) 0 100% /
        4px 1px repeat-x;
  }
  .rail-links a {
    color: var(--ink);
    font-family: var(--font-mono);
    font-size: 0.85rem;
    background: linear-gradient(var(--ink) 0 0) 0 0 / 0% 100% no-repeat;
  }
  .rail-links a:is(:hover, :focus-visible) {
    background-size: 100% 100%;
    color: var(--paper);
    outline: none;
  }
  .rail-glyph {
    color: var(--ink-soft);
    font-size: 0.8rem;
  }
  .rail-links a:is(:hover, :focus-visible) .rail-glyph {
    color: color-mix(in srgb, var(--paper) 65%, var(--ink));
  }
  .rail-links a[aria-current="page"] .rail-label::after {
    content: "";
    display: inline-block;
    inline-size: 0.4rem;
    block-size: 0.4rem;
    margin-inline-start: 0.75ch;
    vertical-align: 0.12em;
    background: var(--accent);
  }
  @media (prefers-reduced-motion: no-preference) {
    .rail-links a {
      transition:
        background-size 380ms var(--ease-in-out),
        color 250ms var(--ease-out);
    }
  }
  /* Folded rail: the label is an ink tab pulled out from the row, and the
     current page's square moves beside its glyph. */
  @media (min-width: 60rem) and (max-width: 83.99rem) {
    .rail-label {
      background: var(--ink);
      color: var(--paper);
    }
    .rail-links a[aria-current="page"] .rail-label::after {
      content: none;
    }
    .rail-links a[aria-current="page"]::before {
      content: "";
      position: absolute;
      inset-inline-start: 0.2rem;
      inset-block-start: calc(50% - 0.2rem);
      inline-size: 0.4rem;
      block-size: 0.4rem;
      background: var(--accent);
    }
  }
  @media (min-width: 60rem) and (max-width: 83.99rem) and (prefers-reduced-motion: no-preference) {
    .rail-label {
      transition: clip-path 300ms var(--ease-in-out);
    }
  }

  /* Landing. */
  .landing h1 {
    max-inline-size: 17ch;
    font-size: clamp(2.3rem, 1.1rem + 3.7vw, 4.75rem);
    font-weight: 400;
    letter-spacing: -0.022em;
    line-height: 1.04;
  }
  .landing h1 em {
    color: var(--accent);
  }
  .latest {
    --underline-rest: transparent;
    color: var(--ink);
    background: none;
  }
  .latest-title {
    font-size: 1.3rem;
    background: linear-gradient(var(--accent) 0 0) var(--underline-at) 100% /
      var(--underline-size) 0.08em no-repeat;
  }
  .latest-title::after {
    content: "→";
    display: inline-block;
    margin-inline-start: 0.6ch;
    color: var(--accent);
    font-family: var(--font-mono);
    font-size: 0.85em;
  }
  .latest:hover .latest-title::after {
    translate: 0.25rem 0;
  }
  .latest-dek {
    color: var(--ink-soft);
    font-family: var(--font-mono);
    font-size: 0.8rem;
    line-height: 1.55;
  }
  @media (prefers-reduced-motion: no-preference) {
    .latest-title {
      transition: background-size 450ms var(--ease-in-out);
    }
    .latest-title::after {
      transition: translate 400ms var(--ease-out);
    }
  }

  /* Terminal: unannounced. At rest it is only a faint prompt and a slowly
     blinking cursor, an invitation for the curious. Touch brightens it;
     focus hands the blink to the real caret. */
  .terminal {
    color: var(--ink);
    font-family: var(--font-mono);
    font-size: 0.82rem;
    line-height: 1.65;
  }
  /* iOS Safari zooms into any focused field set below 16px. On touch
     screens the whole terminal steps up to 1rem, so the prompt and its log
     stay one size. */
  @media (pointer: coarse) {
    .terminal {
      font-size: max(1rem, 16px);
    }
  }
  .terminal-prompt .terminal-ps1,
  .terminal-trigger .terminal-ps1 {
    color: var(--ink-soft);
    opacity: 0.6;
    transition:
      color 300ms var(--ease-out),
      opacity 300ms var(--ease-out);
  }
  .terminal-prompt:is(:hover, :focus-within) .terminal-ps1,
  .terminal-trigger:is(:hover, :focus-visible) .terminal-ps1 {
    color: var(--accent);
    opacity: 1;
  }
  .terminal-prompt:not(:focus-within) .terminal-ps1::after,
  .terminal-trigger .terminal-ps1::after {
    content: "";
    display: inline-block;
    inline-size: 0.6em;
    block-size: 1.15em;
    margin-inline-start: 1ch;
    vertical-align: -0.2em;
    background: currentColor;
    animation: terminal-blink 1.2s steps(1) infinite;
  }
  /* Beside a page someone is reading, the cursor holds still until it is
     touched. */
  .terminal-trigger:not(:hover, :focus-visible) .terminal-ps1::after {
    animation: none;
  }
  @keyframes terminal-blink {
    50% {
      opacity: 0;
    }
  }
  @media (prefers-reduced-motion: reduce) {
    .terminal-prompt .terminal-ps1::after {
      animation: none;
    }
  }
  .terminal-prompt input {
    caret-color: var(--accent);
    caret-shape: block;
  }
  .terminal-echo .terminal-ps1 {
    color: var(--accent);
  }
  .terminal-line,
  .terminal-list dd {
    color: var(--ink-soft);
  }
  .terminal-error {
    color: var(--rust);
  }
  .terminal-trigger {
    font-family: var(--font-mono);
    font-size: 0.78rem;
  }
  .terminal-hint {
    color: var(--ink-soft);
    opacity: 0.6;
    font-size: 0.72rem;
  }

  /* The sheet: a fresh slip of paper laid over the page, edged with the
     rail's dotted rule. */
  .terminal-sheet {
    background:
      linear-gradient(to right, var(--rule-strong) 1px, transparent 1px) 0 0 / 4px 1px repeat-x,
      var(--paper);
    color: var(--ink);
  }
  .terminal-sheet::backdrop {
    background: color-mix(in srgb, var(--paper) 55%, transparent);
  }

  /* Contour lines close each header and replace plain rules. */
  .article-header::after,
  .page-header::after,
  hr {
    content: "";
    display: block;
    block-size: 1.3rem;
    border: 0;
    background: var(--rule-strong);
    mask: var(--contour) center / 100% 100% no-repeat;
  }
  .article-header::after,
  .page-header::after {
    margin-block-start: clamp(1.75rem, 4vw, 2.5rem);
  }

  /* Post list: touching an entry draws its title's underline, the same
     gesture as every other link. */
  .post-entry h2 a {
    --underline-rest: transparent;
    color: var(--ink);
  }
  /* ...and eases its tracking open, a typographic breath. */
  .post-entry:hover h2 a {
    --underline-at: 0%;
    --underline-size: 100%;
    letter-spacing: 0.012em;
  }

  @media (prefers-reduced-motion: no-preference) {
    a {
      transition: background-size 450ms var(--ease-in-out);
    }
    .post-entry h2 a {
      transition:
        background-size 450ms var(--ease-in-out),
        letter-spacing 600ms var(--ease-out);
    }
  }

  /* Section permalinks: a mono mark that surfaces when the heading is
     touched or the link is focused. */
  .heading-anchor {
    --underline-rest: transparent;
    color: var(--accent);
    font-family: var(--font-mono);
    font-size: 0.72em;
    font-weight: 400;
    line-height: 1.6;
    opacity: 0;
    transition: opacity 250ms var(--ease-out);
  }
  :is(h2, h3, h4):hover > .heading-anchor,
  .heading-anchor:focus-visible {
    opacity: 1;
  }

  /* Footnote previews: a slip of paper lifted just off the page. */
  .footnote-preview {
    border: 1px dashed var(--rule-strong);
    border-radius: var(--radius-organic);
    background: var(--paper);
    color: var(--ink);
    font-size: 0.85rem;
    line-height: 1.55;
    box-shadow:
      0 1px 2px color-mix(in oklch, var(--ink) 8%, transparent),
      0 14px 32px -14px color-mix(in oklch, var(--ink) 30%, transparent);
  }
  @media (prefers-reduced-motion: no-preference) {
    .footnote-preview {
      transition:
        opacity 180ms var(--ease-out),
        translate 220ms var(--ease-out),
        display 220ms allow-discrete,
        overlay 220ms allow-discrete;
    }
    @starting-style {
      .footnote-preview:popover-open {
        opacity: 0;
        translate: 0 0.25rem;
      }
    }
  }

  /* Prose. */
  .article-body ul > li::marker {
    color: var(--accent);
  }
  .article-body ol > li::marker {
    color: var(--ink-soft);
    font-family: var(--font-mono);
    font-size: 0.85em;
  }
  .article-body blockquote {
    padding-inline-start: 1.25rem;
    border-inline-start: 2px solid var(--rule-strong);
    color: var(--ink-soft);
    font-style: italic;
  }
  .article-body strong {
    font-weight: 600;
  }
  input[type="checkbox"] {
    accent-color: var(--accent);
  }

  pre {
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    background: var(--surface);
  }
  :not(pre) > code {
    background: var(--surface);
  }

  th {
    border-block-end: 1px solid var(--rule-strong);
    font-family: var(--font-mono);
    font-size: 0.75em;
    font-weight: 500;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--ink-soft);
  }
  td {
    border-block-end: 1px solid var(--rule);
  }

  /* Plates: every image is printed onto the same paper. A mat and hairline
     frame hold it, and a gentle warm tone draws photos into the palette;
     touching the image develops it back to full color. */
  .plate:not([data-treatment="raw"], [data-size="full"]) img {
    padding: 0.45rem;
    border: 1px solid var(--rule);
    background: var(--surface);
  }
  .plate:not([data-treatment]) img {
    filter: var(--plate-tone);
  }
  .plate img:hover {
    filter: none;
  }
  .plate figcaption {
    color: var(--ink-soft);
    font-family: var(--font-mono);
    font-size: 0.74rem;
    line-height: 1.5;
    text-align: center;
  }
  .plate figcaption::before {
    content: "Fig. " counter(plate);
    margin-inline-end: 1ch;
    color: var(--accent);
  }
  @media (prefers-reduced-motion: no-preference) {
    .plate img {
      transition: filter 700ms var(--ease-in-out);
    }
  }

  /* Callouts read as notes pinned into the page. */
  .callout {
    --tone: var(--accent);
    border: 1px solid color-mix(in oklch, var(--tone) 28%, var(--rule));
    border-radius: var(--radius-organic);
    background: color-mix(in oklch, var(--tone) 6%, var(--paper));
  }
  .callout:is([data-kind="warning"], [data-kind="caution"]) {
    --tone: var(--rust);
  }
  .callout-label {
    color: var(--tone);
    font-weight: 600;
  }

  /* Footnotes become a notes section with bracketed references. */
  .footnotes {
    padding-block-start: 1.5rem;
    border-block-start: 1px solid var(--rule);
    color: var(--ink-soft);
  }
  .footnotes::before {
    content: "Notes";
    display: block;
    margin-block-end: 0.75rem;
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
  }
  .footnotes ol > li::marker {
    font-family: var(--font-mono);
    font-size: 0.8em;
  }
  a[data-footnote-ref],
  .footnote-backref,
  .sidenote-number {
    color: var(--accent);
    background: none;
  }
  a[data-footnote-ref],
  .sidenote-number {
    font-family: var(--font-mono);
    font-size: 0.7rem;
  }
  a[data-footnote-ref]::before,
  .sidenote-number::before {
    content: "[";
  }
  a[data-footnote-ref]::after,
  .sidenote-number::after {
    content: "]";
  }
  .footnotes li:target,
  a[data-footnote-ref]:target {
    background: var(--highlight);
    border-radius: 0.25rem;
  }

  /* Sidenotes: the notes section's quieter voice, set in the margin. The
     active note (its reference hovered or focused) takes the highlight. */
  .sidenote {
    color: var(--ink-soft);
    font-size: 0.85rem;
    line-height: 1.55;
    border-radius: 0.25rem;
  }
  .sidenote.is-active {
    background: var(--highlight);
    box-shadow: 0 0 0 0.35rem var(--highlight);
  }
  @media (prefers-reduced-motion: no-preference) {
    .sidenote {
      transition:
        background-color 180ms var(--ease-out),
        box-shadow 180ms var(--ease-out);
    }
  }

  /* #lobby: names in ink, events and the room's header in the soft voice,
     and dev's own name in the accent. */
  .chat-name {
    font-weight: 600;
  }
  .chat-name[data-root] {
    color: var(--accent);
  }
  .chat-summary,
  .chat-event,
  .terminal-notice,
  .terminal-sending,
  .terminal-leave,
  .terminal-close button {
    color: var(--ink-soft);
  }
  .terminal-sending,
  .terminal-leave,
  .terminal-close button {
    font-family: var(--font-mono);
    font-size: 0.8rem;
  }
  .terminal-leave:is(:hover, :focus-visible),
  .terminal-close button:is(:hover, :focus-visible) {
    color: var(--ink);
    text-decoration: underline;
  }

  /* Guestbook: a postcard laid on the paper, and notes pinned to the wall
     below in the same card stock. The card itself stays square: turned, its
     hairline ruling breaks up as it's anti-aliased. */
  .postcard,
  .guestbook-entry {
    border: 1px solid var(--rule);
    border-radius: var(--radius-organic);
    background: light-dark(
      color-mix(in oklch, var(--paper) 55%, white),
      color-mix(in oklch, var(--paper) 93%, var(--ink))
    );
  }
  /* The address side is ruled off with the rail's dotted line. */
  @container postcard (min-width: 30rem) {
    .postcard-address {
      background: linear-gradient(var(--rule-strong) 1px, transparent 1px) 0 0 / 1px 4px repeat-y;
    }
  }
  /* The note is written on ruled lines that scroll with the text; they
     take the accent while you write, which is the field's focus ring. */
  .postcard textarea {
    --line: 1.9rem;
    --ruling: var(--rule);
    background: repeating-linear-gradient(
        to bottom,
        transparent 0 calc(var(--line) - 1px),
        var(--ruling) calc(var(--line) - 1px) var(--line)
      )
      local;
    color: var(--ink);
    font-family: var(--font-prose);
    /* 16px or more, or iOS zooms in on focus. */
    font-size: max(1rem, 16px);
    line-height: var(--line);
    outline: 0;
  }
  .postcard textarea:focus-visible {
    --ruling: color-mix(in oklch, var(--accent) 55%, transparent);
  }
  .postcard :is(textarea, input)::placeholder {
    color: var(--ink-soft);
    font-style: italic;
    opacity: 0.75;
  }
  .postcard-label,
  .postcard-left,
  .guestbook-status,
  .guestbook-meta,
  .guestbook-empty {
    color: var(--ink-soft);
    font-family: var(--font-mono);
    font-size: 0.76rem;
  }
  .postcard-label {
    font-size: 0.7rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
  }
  .postcard-left.postcard-low {
    color: var(--rust);
  }
  .postcard-to,
  .postcard-line input {
    color: var(--ink);
    font-family: var(--font-prose);
    font-style: italic;
  }
  /* The from line is a dotted rule until you write on it. */
  .postcard-line input {
    background: linear-gradient(to right, var(--rule-strong) 1px, transparent 1px) 0 100% / 4px 1px
      repeat-x;
    font-size: max(1rem, 16px);
    outline: 0;
  }
  .postcard-line input:focus-visible {
    background: linear-gradient(var(--accent) 0 0) 0 100% / 100% 1px no-repeat;
  }
  /* Sign is the stamp: a perforated edge, set a little crooked. */
  .postcard-stamp {
    border: 1px solid currentColor;
    border-radius: 0.15rem;
    outline: 1px dashed currentColor;
    outline-offset: 3px;
    background: none;
    color: var(--accent);
    font-family: var(--font-mono);
    font-size: 0.78rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    rotate: 2deg;
  }
  .postcard-stamp:is(:hover, :focus-visible) {
    rotate: 0deg;
    background: color-mix(in oklch, var(--accent) 10%, transparent);
  }
  .postcard-stamp:focus-visible {
    outline-style: solid;
  }
  .postcard-stamp:active {
    translate: 0 1px;
  }
  .postcard-stamp:disabled {
    opacity: 0.55;
  }
  .postcard-sent {
    font-style: italic;
  }
  .postmark {
    border: 3px double var(--rust);
    color: var(--rust);
    font-family: var(--font-mono);
    font-size: 0.62rem;
    font-style: normal;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    opacity: 0.85;
    rotate: -14deg;
  }
  .guestbook-failed {
    color: var(--rust);
  }

  /* Section labels belong to the digital layer, as on the resume. */
  .guestbook-heading {
    display: flex;
    align-items: center;
    gap: 1.5ch;
    color: var(--ink-soft);
    font-family: var(--font-mono);
    font-size: 0.72rem;
    font-weight: 400;
    letter-spacing: 0.12em;
    text-transform: uppercase;
  }
  .guestbook-heading::after {
    content: "";
    flex: 1;
    block-size: 1px;
    background: linear-gradient(to right, var(--rule-strong) 1px, transparent 1px) 0 0 / 4px 1px repeat-x;
  }
  /* The doodle board takes colours, not tokens (its canvas is painted from
     its palette), so it is always dressed in the light theme: ink on card,
     a lavender focus ring. In the dark, the whole board is flipped: invert
     plus a half turn of hue keeps each hue and inverts its lightness, so
     ink becomes chalk on a dark slate, and the ring stays lavender. */
  .guestbook-doodle {
    --sb-border: #c3b8a6;
    --sb-surface-inset: #fbf9f5;
    --sb-brand-light: oklch(53% 0.1 290);
    --sb-text-1: #454038;
    --sb-pixel-board-grid: rgb(69 64 56 / 0.07);
  }
  .guestbook-doodle:not(:defined) {
    border: 1px solid var(--sb-border);
    background: var(--sb-surface-inset);
  }
  @media (prefers-color-scheme: dark) {
    .guestbook-doodle {
      filter: invert(1) hue-rotate(180deg);
    }
  }

  /* Pinned notes, each at its own slight angle, straightened by a touch. */
  .guestbook-entry:nth-child(3n + 1) {
    rotate: -0.6deg;
  }
  .guestbook-entry:nth-child(3n + 2) {
    rotate: 0.45deg;
  }
  .guestbook-entry:nth-child(3n) {
    rotate: -0.2deg;
  }
  .guestbook-entry:hover {
    rotate: 0deg;
  }
  .guestbook-message {
    font-size: 0.98rem;
    line-height: 1.6;
  }

  @media (prefers-reduced-motion: no-preference) {
    .postcard-stamp,
    .guestbook-entry {
      transition:
        rotate 450ms var(--ease-out),
        translate 200ms var(--ease-out),
        background-color 250ms var(--ease-out),
        opacity 450ms var(--ease-out);
    }
    /* A note approved while you're here drops onto the wall. */
    @starting-style {
      .guestbook-entry {
        opacity: 0;
        translate: 0 -0.6rem;
      }
    }
  }

  /* Resume: a ledger in the same hand. Section labels belong to the digital
     layer and run out into a dotted rule; dates are mono stamps; titles
     held at a company are set in italic, like a note in the margin. */
  .resume-intro,
  .resume-actions {
    color: var(--ink-soft);
    font-family: var(--font-mono);
    font-size: 0.78rem;
    letter-spacing: -0.01em;
  }
  .resume-intro a,
  .resume-actions :is(a, button) {
    color: var(--ink-soft);
  }
  .resume-intro a:hover,
  .resume-actions :is(a, button):is(:hover, :focus-visible) {
    color: var(--ink);
  }
  .resume-actions li + li::before {
    color: var(--rule-strong);
  }
  /* After the contact line, a summary in the page's own voice. */
  .resume-intro > p + p {
    color: var(--ink);
    font-family: var(--font-prose);
    font-size: 0.95rem;
    letter-spacing: 0;
    line-height: 1.6;
  }
  .resume-section > h2 {
    display: flex;
    align-items: center;
    gap: 1.5ch;
    color: var(--ink-soft);
    font-family: var(--font-mono);
    font-size: 0.72rem;
    font-weight: 400;
    letter-spacing: 0.12em;
    text-transform: uppercase;
  }
  .resume-section > h2::after {
    content: "";
    flex: 1;
    block-size: 1px;
    background: linear-gradient(to right, var(--rule-strong) 1px, transparent 1px) 0 0 / 4px 1px repeat-x;
  }
  .resume-entry h3 {
    font-size: 1.2rem;
    font-weight: 500;
  }
  .resume-entry h3 a {
    --underline-rest: color-mix(in oklch, var(--accent) 35%, transparent);
    color: var(--ink);
  }
  .resume-role h4 {
    font-size: 1rem;
    font-style: italic;
    font-weight: 400;
  }
  .resume-dates {
    color: var(--ink-soft);
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.04em;
    line-height: 1.5;
  }
  /* A company's dates are a shade darker than its roles'. */
  .resume-entry-head .resume-dates {
    color: var(--ink);
  }
  .resume-body {
    font-size: 0.95rem;
    line-height: 1.6;
  }
  .resume-body ul > li::marker {
    color: var(--accent);
  }
  .resume-body p:has(> code):not(:has(> :not(code))) > code {
    padding: 0.1rem 0.45rem;
    border-radius: 0.25rem;
    color: var(--ink-soft);
    font-size: 0.68rem;
    letter-spacing: 0.01em;
  }
  /* The label floats, so it can't share the line's baseline; giving it the
     item's own line height (0.95rem at 1.6) centres both in one line box. */
  .resume-section > .resume-body li > strong:first-child {
    color: var(--ink-soft);
    font-family: var(--font-mono);
    font-size: 0.72rem;
    font-weight: 400;
    letter-spacing: 0.06em;
    line-height: 1.52rem;
    text-transform: uppercase;
  }
  /* A story opens like a slip unfolding: + to −, and the text set back
     behind a pencil line. */
  .resume-story summary {
    color: var(--ink-soft);
    font-family: var(--font-mono);
    font-size: 0.76rem;
    transition: color 250ms var(--ease-out);
  }
  .resume-story summary::before {
    content: "+";
    display: inline-block;
    inline-size: 2ch;
    color: var(--accent);
  }
  .resume-story[open] summary::before {
    content: "−";
  }
  .resume-story summary:hover {
    color: var(--ink);
  }
  .resume-story-body {
    border-inline-start: 2px solid var(--rule-strong);
    color: var(--ink-soft);
    font-size: 0.92rem;
  }

  /* The guestbook form's own network failure, beside its status. */
  .guestbook-failed {
    color: var(--rust);
  }

  .skip-link {
    background: var(--ink);
  }

  /* Print: ink on white paper, no grain. Links can't be followed on paper,
     so they read as text, underlined only in prose. */
  @media print {
    :root {
      color-scheme: light;
      --paper: #fff;
      --ink: #1e1b17;
      --ink-soft: #57514a;
      --rule: #d6d0c6;
      --rule-strong: #b3aa9c;
    }
    html {
      font-size: 10pt;
      line-height: 1.5;
    }
    body::before {
      display: none;
    }
    a {
      background: none;
      color: inherit;
    }
    .article-body a {
      text-decoration: underline 1px var(--rule-strong);
    }
    .article-header::after,
    .page-header::after {
      display: none;
    }

    .resume h1 {
      font-size: 22pt;
    }
    .resume-header {
      padding-block-end: 0.8rem;
      border-block-end: 1px solid var(--rule-strong);
    }
    /* Backgrounds don't print by default; a border does. */
    .resume-section > h2::after {
      block-size: 0;
      border-block-start: 1px solid var(--rule);
      background: none;
    }
    .resume-entry h3 {
      font-size: 11.5pt;
    }
    .resume-role h4 {
      font-size: 10.5pt;
    }
    .resume-body,
    .resume-intro > p + p {
      font-size: 9.5pt;
      line-height: 1.4;
    }
    .resume-section > .resume-body li > strong:first-child {
      line-height: 13.3pt; /* 9.5pt at 1.4, as above */
    }
  }
}
