/* convertslate.com — Contact Sheet world
   Tokens only. No literal colour or font may appear below the :root blocks. */

/* ─── Tokens ─────────────────────────────────────────────────────────── */

:root {
  color-scheme: light dark;

  /* Palette — the darkroom object, not a UI theme.
     A contact sheet is a dark field of lit frames, laid on a working surface. */
  --c-desk:        #d5d7d0;  /* the bench the sheet lies on */
  --c-desk-edge:   #b6b9b1;
  --c-sheet:       #141210;  /* the sheet itself: photographic black */
  --c-sheet-edge:  #2b2722;
  --c-frame:       #ede8df;  /* paper white, a lit frame */
  --c-frame-dim:   #3a352e;  /* an unexposed frame */
  --c-ink:         #16150f;
  --c-ink-soft:    #55514a;
  --c-on-sheet:    #e4dfd4;
  --c-on-sheet-soft:#948d80;
  --c-mark:        #d8341f;  /* chinagraph pencil */
  --c-safelight:   #e8a33d;  /* amber: work in progress */
  --c-clear:       #6f8f5a;  /* the green of a fixed, washed print */

  /* Roles */
  --bg:            var(--c-desk);
  --bg-edge:       var(--c-desk-edge);
  --sheet:         var(--c-sheet);
  --sheet-edge:    var(--c-sheet-edge);
  --frame:         var(--c-frame);
  --frame-empty:   var(--c-frame-dim);
  --text:          var(--c-ink);
  --text-soft:     var(--c-ink-soft);
  --text-on-sheet: var(--c-on-sheet);
  --text-edge:     var(--c-on-sheet-soft);
  --accent:        var(--c-mark);
  --pending:       var(--c-safelight);
  --done:          var(--c-clear);
  --focus:         var(--c-mark);

  /* Type — system stacks. Operate mode; no webfont may be fetched. */
  --font-text: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
               "Helvetica Neue", Arial, "Noto Sans", sans-serif;
  --font-edge: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
               "Liberation Mono", monospace;

  --t-edge:   0.6875rem;   /* film edge printing */
  --t-small:  0.8125rem;
  --t-body:   1rem;
  --t-lead:   1.125rem;
  --t-h3:     1.25rem;
  --t-h2:     1.5rem;
  --t-h1:     clamp(1.75rem, 1.2rem + 2.2vw, 2.5rem);

  --track-edge: 0.09em;

  /* Space */
  --s-1: 0.25rem;  --s-2: 0.5rem;   --s-3: 0.75rem;  --s-4: 1rem;
  --s-5: 1.5rem;   --s-6: 2rem;     --s-7: 3rem;     --s-8: 4rem;

  --measure: 34rem;      /* reading width — never widens, this is legibility */
  --page:    64rem;      /* content column */
  --radius:  2px;        /* photographic paper does not have rounded corners */
  --sprocket: 9px;       /* film perforation size */

  --speed: 160ms;
  --ease: cubic-bezier(0.2, 0, 0.15, 1);

  --leading: 1.6;      /* running text */
  --leading-tight: 1.2; /* headings */
}

/* Japanese needs more leading than Latin at the same size, and this is not a
   preference. A kanji or kana glyph fills its em box; Latin lowercase leaves
   visual air above the x-height and below the baseline, and that air is doing
   half the work of separating lines. Set the same 1.6 in Japanese and the
   lines close up. Headings are left alone — they are short and large. */
:root:lang(ja) { --leading: 1.85; }

/* On a large display a 64rem column leaves the tool stranded in the middle of
   the screen. The reading measure stays put — only the column grows, which is
   what gives the sheet more frames per row. */
@media (min-width: 90rem) {
  :root { --page: 76rem; }
}

@media (prefers-color-scheme: dark) {
  :root {
    /* The bench must stay visibly behind the sheet. At #0b0a09 against #17150f
       the two read as one flat black and the whole composition disappears. */
    --c-desk:      #070706;
    --c-desk-edge: #221f1a;
    --c-sheet:     #1b1813;
    --c-sheet-edge:#443b30;
    --c-frame:     #e4dfd4;
    --c-frame-dim: #2a251f;
    --c-ink:       #e8e3d8;
    --c-ink-soft:  #9b948a;
  }
}

:root[data-theme="dark"] {
  --c-desk:      #070706;
  --c-desk-edge: #221f1a;
  --c-sheet:     #1b1813;
  --c-sheet-edge:#443b30;
  --c-frame:     #e4dfd4;
  --c-frame-dim: #2a251f;
  --c-ink:       #e8e3d8;
  --c-ink-soft:  #9b948a;
}

:root[data-theme="light"] {
  --c-desk:      #d5d7d0;
  --c-desk-edge: #b6b9b1;
  --c-sheet:     #141210;
  --c-sheet-edge:#2b2722;
  --c-frame:     #ede8df;
  --c-frame-dim: #3a352e;
  --c-ink:       #16150f;
  --c-ink-soft:  #55514a;
}

/* ─── Base ───────────────────────────────────────────────────────────── */

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: var(--t-body)/var(--leading) var(--font-text);
  padding: 0 var(--s-4) var(--s-8);
}

h1, h2, h3 { line-height: var(--leading-tight); text-wrap: balance; margin: 0; }
h1 { font-size: var(--t-h1); letter-spacing: -0.015em; }
h2 { font-size: var(--t-h2); letter-spacing: -0.01em; }
h3 { font-size: var(--t-h3); }
p  { margin: 0; }

a { color: inherit; text-underline-offset: 0.18em; text-decoration-thickness: 1px; }
a:hover { text-decoration-thickness: 2px; }

:where(a, button, input, select, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

img { max-width: 100%; display: block; }

.wrap { max-width: var(--page); margin-inline: auto; }
/* The column, not the text, is what centres. Each child is then capped at a
   readable measure and starts at the column's left edge, so body copy lines up
   with the h1 and the sheet instead of drifting to the window edge. */
.prose { max-width: var(--page); margin-inline: auto; }
.prose > * { max-width: var(--measure); }
.prose > * + * { margin-top: var(--s-4); }
.prose h2 { margin-top: var(--s-6); }
.prose ul, .prose ol { padding-left: 1.2em; }
.prose li + li { margin-top: var(--s-2); }

.edge {
  font: var(--t-edge)/1.4 var(--font-edge);
  letter-spacing: var(--track-edge);
  text-transform: uppercase;
}

.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* ─── Masthead: the sheet's own edge strip ───────────────────────────── */

.masthead {
  max-width: var(--page);
  margin: 0 auto;
  padding: var(--s-4) 0 var(--s-5);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3) var(--s-5);
  align-items: baseline;
}

.brand {
  font: 600 var(--t-body)/1 var(--font-edge);
  letter-spacing: var(--track-edge);
  text-transform: uppercase;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
}

/* the perforation strip that identifies film stock */
.brand::before {
  content: "";
  width: calc(var(--sprocket) * 3);
  height: var(--sprocket);
  background:
    repeating-linear-gradient(90deg,
      var(--accent) 0 var(--sprocket),
      transparent var(--sprocket) calc(var(--sprocket) * 1.5));
  flex: none;
}

.masthead nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-4);
  margin-left: auto;
}

.masthead nav a {
  font: var(--t-edge)/1 var(--font-edge);
  letter-spacing: var(--track-edge);
  text-transform: uppercase;
  text-decoration: none;
  padding: var(--s-2) 0;
  border-bottom: 2px solid transparent;
  color: var(--text-soft);
}
.masthead nav a:hover { color: var(--text); border-bottom-color: var(--accent); }
.masthead nav a[aria-current="page"] { color: var(--text); border-bottom-color: var(--accent); }

/* ─── Page head ──────────────────────────────────────────────────────── */

.pagehead { max-width: var(--page); margin: 0 auto var(--s-5); }
.pagehead .edge { color: var(--text-soft); margin-bottom: var(--s-2); }
.pagehead h1 { max-width: 20ch; }
.pagehead p { margin-top: var(--s-3); max-width: var(--measure); color: var(--text-soft); }

/* ─── The sheet ──────────────────────────────────────────────────────── */

.sheet {
  max-width: var(--page);
  margin-inline: auto;
  background: var(--sheet);
  color: var(--text-on-sheet);
  border: 1px solid var(--sheet-edge);
  border-radius: var(--radius);
  padding: var(--s-4);
  transition: border-color var(--speed) var(--ease);
}

/* the sheet's top edge printing */
.sheet-edge {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-4);
  align-items: center;
  color: var(--text-edge);
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--sheet-edge);
  margin-bottom: var(--s-4);
}
.sheet-edge .count { margin-left: auto; }

/* Drop target ------------------------------------------------------- */

.dropzone {
  position: relative;
  display: block;
  width: 100%;
  border: 1px dashed var(--frame-empty);
  border-radius: var(--radius);
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  padding: var(--s-6) var(--s-5);
  cursor: pointer;
  transition: border-color var(--speed) var(--ease),
              background-color var(--speed) var(--ease);
}
.dropzone:hover { border-color: var(--text-edge); background: rgb(255 255 255 / 0.02); }
.dropzone:active { background: rgb(255 255 255 / 0.04); }
.dropzone.is-dragover {
  border-color: var(--accent);
  border-style: solid;
  background: rgb(216 52 31 / 0.08);
}
.dropzone:disabled { cursor: not-allowed; opacity: 0.55; }

.dropzone-title {
  display: block;
  font-size: var(--t-lead);
  color: var(--text-on-sheet);
}
.dropzone-hint {
  display: block;
  margin-top: var(--s-2);
  color: var(--text-edge);
  max-width: var(--measure);
}

/* Frames ------------------------------------------------------------- */

.frames {
  list-style: none;
  margin: var(--s-4) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
  gap: var(--s-3);
}

.frame {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--frame-empty);
  border-radius: var(--radius);
  overflow: hidden;
}

.frame-img {
  aspect-ratio: 4 / 3;
  width: 100%;
  object-fit: cover;
  background: var(--frame-empty);
}

.frame-meta {
  padding: var(--s-2);
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  background: var(--sheet);
  border-top: 1px solid var(--sheet-edge);
}

.frame-name {
  font: var(--t-edge)/1.3 var(--font-edge);
  color: var(--text-on-sheet);
  overflow-wrap: anywhere;
}

.frame-state {
  font: var(--t-edge)/1.3 var(--font-edge);
  letter-spacing: var(--track-edge);
  text-transform: uppercase;
  display: flex;
  align-items: center;
  gap: var(--s-2);
}
.frame-state::before {
  content: "";
  width: 7px; height: 7px; border-radius: 50%;
  flex: none;
  background: currentColor;
}
.frame[data-state="queued"]  .frame-state { color: var(--text-edge); }
.frame[data-state="working"] .frame-state { color: var(--pending); }
.frame[data-state="done"]    .frame-state { color: var(--done); }
.frame[data-state="failed"]  .frame-state { color: var(--accent); }

/* The grease-pencil mark: drawn, never an emoji or icon font.
   A corner bracket, not a diagonal — on a real sheet a slash through a frame
   means rejected, and it would cover the photograph the visitor came to check. */
.frame[data-state="done"]::after {
  content: "";
  position: absolute;
  top: var(--s-2);
  right: var(--s-2);
  width: 1.125rem;
  height: 1.125rem;
  border-top: 3px solid var(--accent);
  border-right: 3px solid var(--accent);
  pointer-events: none;
}

.frame[data-state="working"] .frame-img { opacity: 0.45; }

.frame-download {
  font: var(--t-edge)/1 var(--font-edge);
  letter-spacing: var(--track-edge);
  text-transform: uppercase;
  color: var(--text-on-sheet);
  text-decoration: none;
  border: 1px solid var(--sheet-edge);
  border-radius: var(--radius);
  padding: var(--s-2);
  text-align: center;
  transition: border-color var(--speed) var(--ease), color var(--speed) var(--ease);
}
.frame-download:hover { border-color: var(--accent); color: var(--accent); }

/* Controls ----------------------------------------------------------- */

.controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-4);
  margin-top: var(--s-4);
  padding-top: var(--s-4);
  border-top: 1px solid var(--sheet-edge);
}

/* Capped: a 700px-wide quality slider on a large display is absurd, and the
   extra travel buys no extra precision. */
.quality {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  flex: 0 1 24rem;
  min-width: 0;
}
.quality label {
  font: var(--t-edge)/1 var(--font-edge);
  letter-spacing: var(--track-edge);
  text-transform: uppercase;
  color: var(--text-edge);
  flex: none;
}
.quality input[type="range"] { flex: 1 1 auto; min-width: 6rem; accent-color: var(--accent); }
.quality output { font: var(--t-edge)/1 var(--font-edge); color: var(--text-on-sheet); flex: none; }

/* the buttons sit at the far end of the row, away from the slider */
.controls .btn:first-of-type { margin-left: auto; }

.btn {
  font: 600 var(--t-small)/1 var(--font-edge);
  letter-spacing: var(--track-edge);
  text-transform: uppercase;
  padding: var(--s-3) var(--s-5);
  border-radius: var(--radius);
  border: 1px solid var(--accent);
  background: var(--accent);
  color: var(--c-frame);
  cursor: pointer;
  transition: background-color var(--speed) var(--ease), color var(--speed) var(--ease);
}
.btn:hover:not(:disabled) { background: transparent; color: var(--accent); }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled { opacity: 0.4; cursor: not-allowed; }

.btn-quiet {
  background: transparent;
  color: var(--text-on-sheet);
  border-color: var(--sheet-edge);
}
.btn-quiet:hover:not(:disabled) { background: transparent; color: var(--accent); border-color: var(--accent); }

/* ─── Related tools ──────────────────────────────────────────────────── */

.related { max-width: var(--page); margin: var(--s-7) auto 0; }
.related h2 { font-size: var(--t-h3); }
.related ul {
  list-style: none; padding: 0; margin: var(--s-4) 0 0;
  display: grid; gap: var(--s-3);
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
}
.related a {
  display: block;
  padding: var(--s-4);
  border: 1px solid var(--bg-edge);
  border-radius: var(--radius);
  text-decoration: none;
  transition: border-color var(--speed) var(--ease), background-color var(--speed) var(--ease);
}
.related a:hover { border-color: var(--accent); background: rgb(216 52 31 / 0.06); }
.related a .edge { color: var(--text-soft); display: block; margin-bottom: var(--s-1); }
.related a strong { font-weight: 600; }


/* ─── Footer ─────────────────────────────────────────────────────────── */

.site-footer {
  max-width: var(--page);
  margin: var(--s-8) auto 0;
  padding-top: var(--s-4);
  border-top: 1px solid var(--bg-edge);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-5);
  color: var(--text-soft);
}
.site-footer a { text-decoration: none; }
.site-footer a:hover { text-decoration: underline; }

/* ─── Reduced motion ─────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}

/* ─── Demo animation ─────────────────────────────────────────────────── */
/* width/height are set on the img so the space is reserved before it loads
   and the page never jumps. */

/* Deliberately NOT full width and NOT flush with the sheet above it: at full
   width the picture of the interface reads as a second, broken copy of the
   interface, and people try to drop files on it. It sits inset on the bench,
   under its own heading, so it is legible as an illustration. */

.demo {
  max-width: var(--page);
  margin: var(--s-7) auto 0;
}

.demo figure {
  margin: 0;              /* browsers default <figure> to margin-inline: 40px */
  max-width: 42rem;
  padding: var(--s-4);
  border: 1px solid var(--bg-edge);
  border-radius: var(--radius);
}

.demo > h2 {
  font: var(--t-edge)/1.4 var(--font-edge);
  letter-spacing: var(--track-edge);
  text-transform: uppercase;
  color: var(--text-soft);
  margin-bottom: var(--s-3);
}



.demo img {
  width: 100%;
  height: auto;
  display: block;
  border-radius: var(--radius);
}

.demo figcaption {
  margin-top: var(--s-3);
  font-size: var(--t-small);
  color: var(--text-soft);
}

/* ─── Theme control ──────────────────────────────────────────────────── */

.theme-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font: var(--t-edge)/1 var(--font-edge);
  letter-spacing: var(--track-edge);
  text-transform: uppercase;
  color: var(--text-soft);
  background: none;
  border: 1px solid transparent;
  border-radius: var(--radius);
  padding: var(--s-2) var(--s-3);
  cursor: pointer;
  transition: color var(--speed) var(--ease), border-color var(--speed) var(--ease);
}
.theme-toggle:hover { color: var(--text); border-color: var(--accent); }
.theme-toggle:active { transform: translateY(1px); }

/* Half-exposed frame: filled on one side, open on the other. */
.theme-toggle-mark {
  width: 0.75rem;
  height: 0.75rem;
  flex: none;
  border: 1px solid currentColor;
  background: linear-gradient(90deg, currentColor 0 50%, transparent 50% 100%);
}
.theme-toggle[data-state="dark"] .theme-toggle-mark {
  background: linear-gradient(90deg, transparent 0 50%, currentColor 50% 100%);
}

/* ─── Reveal ─────────────────────────────────────────────────────────── */
/* Only ever applied by script — see assets/js/site.js. Without JavaScript no
   element carries the attribute, so everything is simply visible. */

[data-reveal="pending"] {
  opacity: 0;
  transform: translateY(10px);
}

[data-reveal="in"] {
  opacity: 1;
  transform: none;
  transition:
    opacity 480ms var(--ease) var(--reveal-delay, 0ms),
    transform 480ms var(--ease) var(--reveal-delay, 0ms);
}

@media (prefers-reduced-motion: reduce) {
  [data-reveal] { opacity: 1 !important; transform: none !important; }
}

/* ─── Language switcher ──────────────────────────────────────────────── */
/* A disclosure, not a row of links. Five locales laid flat wrapped onto two
   rows of the mobile masthead and pushed the h1 below the fold. Collapsed,
   the control is one line; the open panel is positioned, so opening it never
   reflows the page beneath.

   Hidden entirely while only one locale exists, so the markup can ship
   before the translations do. */

.lang {
  position: relative;
  font: var(--t-edge)/1 var(--font-edge);
  letter-spacing: var(--track-edge);
  text-transform: uppercase;
}

.lang > summary {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-2) var(--s-3);
  cursor: pointer;
  list-style: none;
  color: var(--text-soft);
  border: 1px solid var(--bg-edge);
  border-radius: var(--radius);
  /* A tap target, not prose: double-tapping it should open the menu, not
     select the word. */
  -webkit-user-select: none;
  user-select: none;
  transition: color var(--speed) var(--ease), border-color var(--speed) var(--ease);
}
.lang > summary::-webkit-details-marker { display: none; }
.lang > summary:hover { color: var(--text); border-color: var(--accent); }
.lang > summary:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
.lang[open] > summary { color: var(--text); border-color: var(--accent); }

/* The label is the affordance on desktop; on a narrow screen the locale name
   alone carries it, and the word is dropped rather than wrapped. */
.lang-label { color: var(--text-soft); }
.lang-current { color: var(--text); }

/* Drawn chevron: a rotating caret, no icon font and no emoji. */
.lang > summary::after {
  content: "";
  flex: none;
  width: 0.4rem;
  height: 0.4rem;
  margin-left: var(--s-1);
  border-right: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  transform: translateY(-2px) rotate(45deg);
  transition: transform var(--speed) var(--ease);
}
.lang[open] > summary::after { transform: translateY(1px) rotate(225deg); }

.lang-menu {
  position: absolute;
  z-index: 20;
  top: calc(100% + var(--s-2));
  right: 0;
  display: flex;
  flex-direction: column;
  min-width: 100%;
  padding: var(--s-2);
  background: var(--bg);
  border: 1px solid var(--bg-edge);
  border-radius: var(--radius);
  box-shadow: 0 6px 20px rgb(0 0 0 / 0.18);
}

.lang-menu > * {
  padding: var(--s-2) var(--s-3);
  white-space: nowrap;
  border-left: 2px solid transparent;
}

.lang-here {
  color: var(--text);
  border-left-color: var(--accent);
}

.lang-menu a {
  color: var(--text-soft);
  text-decoration: none;
  transition: color var(--speed) var(--ease), border-color var(--speed) var(--ease);
}
.lang-menu a:hover { color: var(--text); border-left-color: var(--accent); }
.lang-menu a:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }
.lang-menu a:active { color: var(--accent); }

/* The masthead's two controls share one row rather than taking one each. */
.masthead-tools {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin-left: auto;
}

/* Under ~26rem the word "Language" and the locale name compete for the same
   line. The label goes; the locale name is the one that must survive. */
@media (max-width: 26rem) {
  .lang-label { display: none; }
}

/* ─── Format chooser ─────────────────────────────────────────────────── */

.chooser { max-width: var(--page); margin: var(--s-7) auto 0; }
.chooser > h2 { font-size: var(--t-h2); }

.chooser ul {
  list-style: none;
  padding: 0;
  margin: var(--s-5) 0 0;
  display: grid;
  gap: var(--s-4);
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}

.chooser a {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  height: 100%;
  padding: var(--s-3);
  border: 1px solid var(--bg-edge);
  border-radius: var(--radius);
  text-decoration: none;
  transition: border-color var(--speed) var(--ease), transform var(--speed) var(--ease);
}
.chooser a:hover { border-color: var(--accent); transform: translateY(-2px); }
.chooser a:active { transform: none; }

.chooser img {
  width: 100%;
  height: auto;
  border-radius: var(--radius);
  margin-bottom: var(--s-1);
}

.chooser .edge { color: var(--text-soft); }
.chooser strong { font-size: var(--t-h3); font-weight: 600; letter-spacing: -0.01em; }
.chooser-line { color: var(--text-soft); font-size: var(--t-small); line-height: 1.5; }

/* ─── Contrast table ─────────────────────────────────────────────────── */

.contrast { max-width: var(--page); margin: var(--s-8) auto 0; }
.contrast > h2 { font-size: var(--t-h2); }

.contrast-grid {
  display: grid;
  gap: var(--s-4);
  margin-top: var(--s-5);
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
}

.contrast-col {
  padding: var(--s-4);
  border: 1px solid var(--bg-edge);
  border-radius: var(--radius);
}

/* The side that is ours is stated on the sheet's own material, so the
   comparison reads as two objects rather than two lists. */
.contrast-col.is-ours {
  background: var(--sheet);
  border-color: var(--sheet-edge);
  color: var(--text-on-sheet);
}

.contrast-col h3 { color: var(--text-soft); margin-bottom: var(--s-3); }
.contrast-col.is-ours h3 { color: var(--accent); }

.contrast-col ul { list-style: none; padding: 0; margin: 0; }
.contrast-col li { padding-left: 1.1rem; position: relative; }
.contrast-col li + li { margin-top: var(--s-3); }
.contrast-col li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.6em;
  width: 6px; height: 1px;
  background: currentColor;
  opacity: 0.5;
}

.contrast-note {
  margin-top: var(--s-5);
  max-width: var(--measure);
  color: var(--text-soft);
  font-size: var(--t-small);
}

/* ─── Section rules ──────────────────────────────────────────────────── */
/* A hairline that starts at chinagraph red and runs out, the way a grease
   pencil does when the wax gives up. Not a generic gradient border: this one
   belongs to the same hand that draws the corner marks. */

.chooser, .contrast, .related, .demo {
  position: relative;
  padding-top: var(--s-6);
}

.chooser::before, .contrast::before, .related::before, .demo::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 2px;
  background: linear-gradient(90deg,
    var(--accent) 0,
    var(--accent) 8%,
    color-mix(in srgb, var(--accent) 45%, transparent) 26%,
    color-mix(in srgb, var(--accent) 12%, transparent) 55%,
    transparent 82%);
}

/* The same stroke, quieter, under each prose heading. */
.prose h2 {
  position: relative;
  padding-top: var(--s-4);
}
.prose h2::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  width: 100%;
  max-width: var(--measure);
  height: 1px;
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--accent) 70%, transparent) 0,
    color-mix(in srgb, var(--accent) 20%, transparent) 40%,
    transparent 78%);
}

/* ─── Film grain ─────────────────────────────────────────────────────── */
/* Photographic stock is never perfectly flat. Barely visible, but it stops the
   sheet reading as a plain filled rectangle. */

.sheet, .contrast-col.is-ours {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='0.035'/%3E%3C/svg%3E");
  background-repeat: repeat;
}

/* ─── FAQ ────────────────────────────────────────────────────────────── */

.faq {
  border-top: 1px solid var(--bg-edge);
  max-width: var(--measure);
}
.faq:last-of-type { border-bottom: 1px solid var(--bg-edge); }

.faq summary {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  padding: var(--s-4) 0;
  cursor: pointer;
  list-style: none;
  transition: color var(--speed) var(--ease);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary:hover { color: var(--accent); }
.faq summary:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }

.faq summary h3 {
  font-size: var(--t-body);
  font-weight: 600;
  margin: 0;
  flex: 1;
}

/* Drawn marker: a plus that becomes a minus. No icon font, no emoji. */
.faq summary::after {
  content: "";
  flex: none;
  width: 0.75rem;
  height: 0.75rem;
  margin-top: 0.3em;
  background:
    linear-gradient(var(--accent), var(--accent)) center/100% 2px no-repeat,
    linear-gradient(var(--accent), var(--accent)) center/2px 100% no-repeat;
  transition: transform var(--speed) var(--ease);
}
.faq[open] summary::after {
  transform: rotate(90deg);
  background:
    linear-gradient(var(--accent), var(--accent)) center/100% 2px no-repeat;
}

.faq > p {
  padding: 0 0 var(--s-5);
  color: var(--text-soft);
  max-width: var(--measure);
}

@media (prefers-reduced-motion: no-preference) {
  .faq[open] > p { animation: faq-open 260ms var(--ease); }
  @keyframes faq-open {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: none; }
  }
}
