/*
  yeardead: a class as a contact sheet.
  Photo paper, black film, and two china markers: red for the dead, yellow for you.
  Every colour and size comes from the tokens below.
*/
@layer reset, base, layout, components, utilities;

@font-face {
  font-family: "Big Shoulders Display";
  src: url("../fonts/big-shoulders-display-normal-latin.woff2?v=698f996092") format("woff2");
  font-weight: 100 900;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+25B8, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Big Shoulders Display";
  src: url("../fonts/big-shoulders-display-normal-latin-ext.woff2?v=2239cea544") format("woff2");
  font-weight: 100 900;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Atkinson Hyperlegible Next";
  src: url("../fonts/atkinson-hyperlegible-next-normal-latin.woff2?v=18b2a1a39a") format("woff2");
  font-weight: 200 800;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Atkinson Hyperlegible Next";
  src: url("../fonts/atkinson-hyperlegible-next-normal-latin-ext.woff2?v=7dae0c6c66") format("woff2");
  font-weight: 200 800;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Atkinson Hyperlegible Next";
  src: url("../fonts/atkinson-hyperlegible-next-italic-latin.woff2?v=59bc0e9656") format("woff2");
  font-weight: 200 800;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Doto";
  src: url("../fonts/doto-normal-latin.woff2?v=2a4172c50d") format("woff2");
  font-weight: 700;
  font-display: swap;
}

:root {
  /* Materials */
  --paper: #eef0ec;
  --paper-raised: #f8f9f6;
  --paper-shade: #dcdfd9;
  --film: #141311;
  --film-edge: #2a2926;
  --ink: #1c1d1b;
  --ink-soft: #4a4d48;
  --silver: #8e918c;
  --edge-print: #c9ccc6;
  --film-line: #55544f;
  --film-soft: #8a8983;
  --white: #fff;
  --marker: #c8102e;
  --marker-on-film: #ff6b5f;
  --marker-yellow: #f2c230;
  --rule: #c6c9c3;
  --signal-on: #2f8f4e;

  /* Type */
  --font-display: "Big Shoulders Display", "Arial Narrow", sans-serif;
  --font-body: "Atkinson Hyperlegible Next", "Segoe UI", system-ui, sans-serif;
  --font-edge: "Doto", ui-monospace, monospace;
  --text-sm: 0.9375rem;
  --text-base: 1.125rem;
  --text-lg: 1.375rem;
  --text-xl: clamp(1.75rem, 3.2vw, 2.25rem);
  --display-md: clamp(2.75rem, 7vw, 4.5rem);
  --display-lg: clamp(3.5rem, 10.5vw, 8.5rem);

  /* Space */
  --gutter: clamp(16px, 4vw, 48px);
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;
  --space-8: 5rem;
  --measure: 62ch;
  --page: 1280px;

  --control-h: 3rem;
  --radius: 2px;
  --shadow-print: 0 1px 1px rgb(20 19 17 / 0.08), 0 12px 32px -12px rgb(20 19 17 / 0.35);
  --grain: url("../img/grain.svg?v=5d12c56329");
  --halftone: url("../img/halftone.svg?v=599188233a");
  --sprockets: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='10'%3E%3Crect x='4' y='2' width='8' height='6' rx='1.5' fill='%23eef0ec'/%3E%3C/svg%3E");
}

@layer reset {
  *, *::before, *::after { box-sizing: border-box; }
  body, h1, h2, h3, p, ol, ul, dl, dd, figure { margin: 0; }
  ol, ul { padding: 0; }
  img, svg { display: block; max-width: 100%; }
  input, button, select, textarea { font: inherit; color: inherit; }
  [hidden] { display: none !important; }
}

@layer base {
  html { -webkit-text-size-adjust: 100%; }
  html, body { overflow-x: clip; }
  body {
    background: var(--paper);
    color: var(--ink);
    font-family: var(--font-body);
    font-size: var(--text-base);
    line-height: 1.55;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
  }
  main { flex: 1; width: 100%; max-width: var(--page); margin-inline: auto; padding-inline: var(--gutter); }
  a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 0.2em; }
  a:hover { text-decoration-color: var(--marker); }
  :focus-visible { outline: 3px solid var(--ink); outline-offset: 3px; }
  h1, h2, h3 { font-weight: 700; line-height: 1.15; text-wrap: balance; }
  p { text-wrap: pretty; }
  strong { font-weight: 700; }
  ::selection { background: var(--marker-yellow); color: var(--ink); }
}

@layer layout {
  .masthead {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    width: 100%;
    max-width: var(--page);
    margin-inline: auto;
    padding: var(--space-5) var(--gutter);
  }
  .masthead-nav { display: flex; gap: var(--space-5); font-size: var(--text-sm); }
  .masthead-nav a { text-decoration: none; padding-block: var(--space-1); border-bottom: 2px solid transparent; }
  .masthead-nav a:hover { border-bottom-color: var(--marker); }
  .masthead-nav a[aria-current="page"] { border-bottom-color: var(--ink); }

  /* The footer is a strip of film: sprockets along its top edge, then the page grid. */
  .colophon {
    margin-top: var(--space-8);
    padding-top: 22px;
    background-color: var(--film);
    background-image: var(--sprockets), var(--grain);
    background-repeat: repeat-x, repeat;
    background-position: 0 6px, 0 0;
    background-size: 16px 10px, 180px 180px;
    color: var(--edge-print);
    font-size: var(--text-sm);
  }
  .colophon-inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 2fr) auto;
    gap: var(--space-4) var(--space-6);
    align-items: start;
    max-width: var(--page);
    margin-inline: auto;
    padding: var(--space-6) var(--gutter) var(--space-7);
  }
  .colophon-note { max-width: 52ch; color: var(--silver); }
  .colophon-links { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-5); }
  .colophon-links a { color: var(--edge-print); text-decoration: none; }
  .colophon-links a:hover { color: var(--white); text-decoration: underline; text-decoration-color: var(--marker-on-film); }
  .wordmark-small { font-size: 1.375rem; color: var(--paper); }
  .wordmark-small .marker-box path { stroke: var(--marker-on-film); }
}

@layer components {
  /* Wordmark: "dead" boxed in red marker. */
  .wordmark {
    display: inline-flex;
    font-family: var(--font-display);
    font-weight: 800;
    font-size: 1.75rem;
    line-height: 1;
    letter-spacing: 0.01em;
    text-decoration: none;
  }
  .wordmark-dead { position: relative; padding: 0 0.15em; }
  .wordmark-dead .marker-box { --mx: 0.02em; --my: 0.08em; }

  /* Marker marks: a box for the dead, a loop for you. */
  /* An SVG is a replaced element, so insets alone won't stretch it: --mx and --my set how far
     past its box the mark reaches, and the size follows. */
  .marker {
    --mx: 7px;
    --my: 7px;
    position: absolute;
    top: calc(var(--my) * -1);
    left: calc(var(--mx) * -1);
    width: calc(100% + 2 * var(--mx));
    height: calc(100% + 2 * var(--my));
    max-width: none;
    pointer-events: none;
    overflow: visible;
  }
  .marker path {
    fill: none;
    stroke-linecap: round;
    stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
  }
  /* China marker is waxy and never quite opaque; each hand presses a little differently. */
  .marker-box { --ink-w: 4px; --ink-a: 0.86; }
  .marker-box path { stroke: var(--marker); stroke-width: var(--ink-w); opacity: var(--ink-a); }
  .marker-box path.pass { stroke-width: calc(var(--ink-w) * 0.55); opacity: calc(var(--ink-a) * 0.45); }
  .hand-1 { --ink-w: 3.6px; --ink-a: 0.8; }
  .hand-2 { --ink-w: 4.4px; --ink-a: 0.9; }
  .hand-3 { --ink-w: 3.8px; --ink-a: 0.84; }
  .hand-4 { --ink-w: 4.6px; --ink-a: 0.78; }
  .hand-5 { --ink-w: 3.4px; --ink-a: 0.92; }
  .hand-6 { --ink-w: 4.2px; --ink-a: 0.82; }
  .hand-7 { --ink-w: 3.9px; --ink-a: 0.88; }
  .marker-you { --ink-w: 5px; --ink-a: 0.95; }
  .marker-you path { stroke: var(--marker-yellow); }
  /*
    Drawing: a side at a time, each easing out of one corner and into the next the way a hand
    slows to turn. Only where a page asks for it (.draws), so a sheet you've seen stays still.
    --delay staggers boxes; --side is how long one side takes.
  */
  @media (prefers-reduced-motion: no-preference) {
    .draws .marker path {
      --side: 0.2s;
      stroke-dasharray: var(--len, 600px) var(--len, 600px);
      stroke-dashoffset: var(--len, 600px);
      animation: draw var(--side) cubic-bezier(0.5, 0.05, 0.3, 1) var(--delay, 0s) forwards;
    }
    .draws .marker path:nth-of-type(2) { animation-delay: calc(var(--delay, 0s) + var(--side) * 0.95); }
    .draws .marker path:nth-of-type(3) { animation-delay: calc(var(--delay, 0s) + var(--side) * 1.9); }
    .draws .marker path:nth-of-type(4) { animation-delay: calc(var(--delay, 0s) + var(--side) * 2.85); }
    .draws .marker path:nth-of-type(5) { animation-delay: calc(var(--delay, 0s) + var(--side) * 3.9); animation-duration: calc(var(--side) * 1.4); }
    .strip-hero .frame:nth-child(1) { --delay: 0.5s; }
    .strip-hero .frame:nth-child(2) { --delay: 0.85s; }
    .strip-hero .frame:nth-child(3) { --delay: 1.2s; }
    .strip-hero .frame:nth-child(4) { --delay: 1.55s; }
    .strip-hero .frame:nth-child(5) { --delay: 1.9s; }
    .strip-hero .frame:nth-child(6) { --delay: 2.25s; }
    .strip-hero .frame:nth-child(7) { --delay: 2.6s; }
    .strip-hero .frame:nth-child(8) { --delay: 2.95s; }
    .page-home .wordmark-dead { --delay: 0.1s; }
  }
  @keyframes draw { to { stroke-dashoffset: 0; } }

  /* Type */
  .display {
    font-family: var(--font-display);
    font-weight: 800;
    font-size: var(--display-lg);
    line-height: 0.88;
    letter-spacing: -0.005em;
  }
  .display-md { font-size: var(--display-md); line-height: 0.92; }
  .eyebrow {
    font-size: var(--text-sm);
    font-weight: 700;
    letter-spacing: 0.02em;
    color: var(--ink-soft);
    margin-bottom: var(--space-3);
  }
  .lede { font-size: var(--text-lg); line-height: 1.45; max-width: 40ch; margin-top: var(--space-5); }
  .section-title {
    font-family: var(--font-display);
    font-weight: 800;
    font-size: var(--text-xl);
    line-height: 1;
    margin-bottom: var(--space-4);
  }
  .hint { font-size: var(--text-sm); color: var(--ink-soft); }
  .optional { font-weight: 400; color: var(--ink-soft); }
  .edge {
    display: block;
    font-family: var(--font-edge);
    font-weight: 700;
    font-size: 0.8125rem;
    letter-spacing: 0.12em;
    color: var(--silver);
    margin-bottom: var(--space-2);
  }

  /* Film: frames sit edge to edge so a row reads as one strip, sprockets above and below. */
  .frame {
    position: relative;
    background-color: var(--film);
    background-image: var(--sprockets), var(--sprockets), var(--grain);
    background-repeat: repeat-x, repeat-x, repeat;
    background-position: 0 4px, 0 calc(100% - 4px), 0 0;
    background-size: 16px 10px, 16px 10px, 180px 180px;
    padding: 28px 10px 26px;
    color: var(--edge-print);
  }
  .frame-quality {
    position: absolute;
    top: 13px;
    right: 10px;
    font-family: var(--font-edge);
    font-weight: 700;
    font-size: 0.6875rem;
    letter-spacing: 0.08em;
    line-height: 1;
    color: var(--silver);
    background: var(--film);
    padding-left: 4px;
  }
  .frame-source {
    position: absolute;
    left: 0;
    bottom: 0;
    padding: 3px 5px 2px;
    font-family: var(--font-edge);
    font-weight: 700;
    font-size: 0.625rem;
    letter-spacing: 0.08em;
    line-height: 1;
    color: var(--edge-print);
    background: rgb(20 19 17 / 0.82);
    text-transform: uppercase;
  }
  /* Follow and report sit in the edge print above the photo, so they never make a row taller. */
  .frame-acts { position: absolute; top: 5px; right: 6px; display: flex; gap: 2px; }
  .frame-follow { display: contents; }
  .frame-act {
    display: grid;
    place-items: center;
    width: 22px;
    height: 22px;
    padding: 0;
    border: 0;
    border-radius: 3px;
    background: var(--film);
    color: var(--film-soft);
    cursor: pointer;
  }
  .frame-act .icon { width: 11px; height: 11px; }
  .frame-act:hover, .frame-act:focus-visible { color: var(--white); background: var(--film-edge); }
  .frame-act:focus-visible { outline: 2px solid var(--marker-yellow); outline-offset: 1px; }
  .frame-act[aria-pressed="true"] { color: var(--marker-yellow); }
  .frame-act[aria-pressed="true"] .icon { fill: currentColor; }
  @media (hover: hover) {
    .frames .frame-act { opacity: 0; transition: opacity 0.15s ease; }
    .frames .frame:hover .frame-act, .frames .frame-act:focus-visible, .frames .frame-act[aria-pressed="true"] { opacity: 1; }
  }
  .frame-quality.is-low { color: var(--marker-on-film); }
  .frame-quality:empty { display: none; }
  .frame-no {
    position: absolute;
    top: 13px;
    left: 10px;
    font-family: var(--font-edge);
    font-weight: 700;
    font-size: 0.6875rem;
    letter-spacing: 0.08em;
    line-height: 1;
    color: var(--silver);
    background: var(--film);
    padding-right: 4px;
  }
  .frame-photo {
    position: relative;
    display: block;
    aspect-ratio: 4 / 5;
    background: var(--film-edge);
  }
  .frame-photo img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    filter: grayscale(1) contrast(1.06);
  }
  .frame-blank { display: block; width: 100%; height: 100%; background: #22211e; }
  /* Pixel icons are 11 pixels square, shown at whole multiples so every pixel stays crisp. */
  .icon { width: 22px; height: 22px; flex: none; fill: none; }
  .frame-name {
    margin-top: var(--space-3);
    font-size: var(--text-sm);
    line-height: 1.3;
    color: #e7e9e4;
    overflow-wrap: anywhere;
  }
  .frame-years {
    margin-top: 2px;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.125rem;
    letter-spacing: 0.04em;
    color: var(--marker-on-film);
  }
  .frame-you {
    margin-top: 2px;
    font-family: var(--font-display);
    font-weight: 800;
    font-size: 1.125rem;
    color: var(--marker-yellow);
  }
  .obit-report { margin-top: var(--space-3); font-size: var(--text-sm); }
  .frame.is-dead .frame-photo { text-decoration: none; }
  a.frame-photo:focus-visible { outline: 3px solid var(--marker-yellow); outline-offset: 10px; }
  @media (hover: hover) and (prefers-reduced-motion: no-preference) {
    a.frame-photo { transition: transform 0.2s ease; }
    a.frame-photo:hover { transform: translateY(-3px) rotate(-0.6deg); }
  }

  /* Home */
  .hero { padding-top: var(--space-5); }
  /* The strip runs past both edges of the screen, far enough that its tilt never shows a corner. */
  .hero-figure { --tilt: -1.2deg; margin-inline: calc(var(--gutter) * -1); }
  .strip-hero {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(118px, 1fr);
    overflow: hidden;
    margin-inline: -48px;
    box-shadow: var(--shadow-print);
    rotate: var(--tilt);
  }
  .strip-caption {
    rotate: var(--tilt);
    margin-top: var(--space-3);
    padding-inline: var(--gutter);
    text-align: right;
    font-size: 0.8125rem;
    letter-spacing: 0.02em;
    color: var(--ink-soft);
  }
  .strip-hero .frame { padding-bottom: 24px; }
  .hero-copy {
    display: grid;
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
    column-gap: var(--space-7);
    align-items: end;
    padding-top: var(--space-6);
  }
  .hero-side { display: grid; gap: var(--space-5); padding-bottom: 0.4rem; }
  .hero-side .lede { margin-top: 0; }
  .hero-action { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3) var(--space-4); }

  /* Three frames of a roll, numbered in edge print, over a halftone screen. */
  .roll { position: relative; margin-top: var(--space-8); }
  .roll::before {
    content: "";
    position: absolute;
    z-index: -1;
    top: calc(var(--space-6) * -1);
    right: calc(var(--gutter) * -1);
    width: min(40rem, 60%);
    height: calc(100% + var(--space-7));
    background: var(--halftone) top right / 96px 96px;
    -webkit-mask-image: linear-gradient(to left, #000, transparent);
    mask-image: linear-gradient(to left, #000, transparent);
    pointer-events: none;
  }
  .page-home main { isolation: isolate; }
  .roll-list {
    list-style: none;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    border-block: 3px solid var(--film);
  }
  .roll-step {
    position: relative;
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    /* The text's row takes whatever the icon leaves, so every heading sits the same way over its text. */
    grid-template-rows: auto 1fr;
    gap: var(--space-1) var(--space-4);
    align-items: start;
    align-content: start;
    padding: var(--space-5) var(--space-5) var(--space-5) 0;
  }
  .roll-step + .roll-step { padding-left: var(--space-5); border-left: 1px solid var(--rule); }
  .roll-no { position: absolute; top: var(--space-2); right: var(--space-3); font-family: var(--font-edge); font-weight: 700; font-size: 0.8125rem; letter-spacing: 0.12em; color: var(--silver); }
  .roll-icon { grid-row: span 2; width: 48px; height: 48px; color: var(--ink); }
  .roll-step h3 { font-size: var(--text-base); }
  .roll-step p { font-size: var(--text-sm); color: var(--ink-soft); }
  .roll-note { margin-top: var(--space-5); max-width: var(--measure); color: var(--ink-soft); }
  .roll-note .link-arrow { color: var(--ink); white-space: nowrap; }

  /* Documents: how it works, privacy, terms. */
  .doc { padding-top: var(--space-5); }
  .doc-head { max-width: 52rem; padding-bottom: var(--space-6); border-bottom: 3px solid var(--film); }
  .doc-body { display: grid; gap: var(--space-6); max-width: var(--measure); padding-top: var(--space-6); }
  .doc-body h2 { font-family: var(--font-display); font-weight: 800; font-size: var(--text-xl); line-height: 1; margin-bottom: var(--space-3); }
  .doc-body p + p, .doc-body p + ul, .doc-body ul + p, .doc-body p + table, .doc-body table + p { margin-top: var(--space-3); }
  .doc-body ul, .doc-steps { padding-left: 1.2em; display: grid; gap: var(--space-2); }
  /* Numbered steps in edge print, set as close to their words as a bullet is. */
  .doc-steps { list-style: none; padding-left: 0; counter-reset: step; }
  .doc-steps li { position: relative; padding-left: 1.75rem; counter-increment: step; }
  .doc-steps li::before {
    content: counter(step, decimal-leading-zero);
    position: absolute;
    left: 0;
    top: 0.3em;
    font-family: var(--font-edge);
    font-weight: 700;
    font-size: 0.8125rem;
    line-height: 1.55;
    color: var(--silver);
  }
  .doc-aside { padding: var(--space-5); background: var(--grain) var(--film); color: var(--edge-print); }
  .doc-aside h2 { color: var(--paper); }
  .doc-table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
  .doc-table th { text-align: left; padding: var(--space-2) var(--space-3) var(--space-2) 0; border-bottom: 2px solid var(--film); }
  .doc-table td { padding: var(--space-2) var(--space-3) var(--space-2) 0; border-bottom: 1px solid var(--rule); vertical-align: top; }
  .doc-table code { font-family: var(--font-edge); font-weight: 700; font-size: 0.8125rem; white-space: nowrap; }
  .doc-credits { font-size: var(--text-sm); color: var(--ink-soft); padding-top: var(--space-5); border-top: 1px solid var(--rule); }

  /* By sending a photo you agree: small, plain, and never in the way. */
  .agree { font-size: 0.8125rem; color: var(--ink-soft); }
  .agree a { color: inherit; }

  .link-arrow { font-weight: 700; text-decoration: none; border-bottom: 2px solid var(--marker); }
  .link-arrow::after { content: " ▸"; color: var(--marker); }
  .link-back::after { content: none; }
  .link-back::before { content: "◂ "; color: var(--marker); }

  /* Controls */
  .button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-height: var(--control-h);
    padding: 0 var(--space-5);
    border: 2px solid var(--film);
    border-radius: var(--radius);
    background: transparent;
    color: var(--ink);
    font-weight: 700;
    font-size: var(--text-base);
    text-decoration: none;
    cursor: pointer;
    position: relative;
  }
  .button:hover { background: var(--paper-shade); }
  .button:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--field-ring); }
  .button-primary { background: var(--film); color: var(--paper); }
  .button-primary:hover { background: #2c2b28; }
  .button-large { min-height: 3.75rem; padding: 0 var(--space-6); font-size: var(--text-lg); }
  .button-marker { border-color: var(--marker-yellow); background: var(--marker-yellow); }
  .button-marker:hover { background: #e4b21f; }
  .button:has(input:focus-visible) { outline: none; box-shadow: 0 0 0 3px var(--field-ring); }
  .button-link {
    background: none;
    border: 0;
    padding: 0;
    text-decoration: underline;
    text-underline-offset: 0.2em;
    cursor: pointer;
    font-size: var(--text-sm);
    color: var(--ink-soft);
  }
  .button-link:hover { color: var(--ink); text-decoration-color: var(--marker); }

  .form { display: grid; gap: var(--space-4); }
  .field { display: grid; gap: var(--space-1); }
  .field label { font-weight: 700; font-size: var(--text-sm); }
  .field-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 12rem); gap: var(--space-4); }
  .field-row-wrap { grid-template-columns: minmax(0, 13rem) minmax(0, 1fr) minmax(0, 13rem); }
  .field-row-wrap > [hidden] { display: none; }
  .field-narrow { max-width: 14rem; }
  .field-inline { display: flex; flex-wrap: wrap; gap: var(--space-3); }
  .field-inline input { flex: 1 1 16rem; }
  /*
    Fields: one look for every text box, select and checkbox, on paper or on film. A film
    frame sets the --field-* variables darker; nothing is left to the browser's own controls.
  */
  :root {
    --field-bg: var(--white);
    --field-fg: var(--ink);
    --field-border: var(--silver);
    --field-border-hover: var(--ink-soft);
    --field-placeholder: #8f928c;
    --field-ring: var(--marker-yellow);
    --chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9'%3E%3Cpath d='M1.5 1.5 7 7l5.5-5.5' fill='none' stroke='%231c1d1b' stroke-width='2.2'/%3E%3C/svg%3E");
    --tick: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='12' viewBox='0 0 14 12'%3E%3Cpath d='M1.5 6.5 5.2 10 12.5 1.8' fill='none' stroke='%23eef0ec' stroke-width='2.6'/%3E%3C/svg%3E");
  }
  input:not([type="file"], [type="hidden"], [type="checkbox"], [type="radio"]), select {
    appearance: none;
    min-height: var(--control-h);
    width: 100%;
    padding: 0 var(--space-3);
    border: 2px solid var(--field-border);
    border-radius: var(--radius);
    background-color: var(--field-bg);
    color: var(--field-fg);
    font-size: var(--text-base);
    transition: border-color 0.12s ease, box-shadow 0.12s ease;
  }
  input:not([type="file"], [type="hidden"], [type="checkbox"], [type="radio"]):hover, select:hover { border-color: var(--field-border-hover); }
  input:focus-visible, select:focus-visible {
    outline: none;
    border-color: var(--field-fg);
    box-shadow: 0 0 0 3px var(--field-ring);
  }
  input::placeholder { color: var(--field-placeholder); opacity: 1; }
  input[type="search"]::-webkit-search-decoration,
  input[type="search"]::-webkit-search-cancel-button { appearance: none; }
  input:user-invalid { border-color: var(--marker); }
  select {
    padding-right: 2.5rem;
    background-image: var(--chevron);
    background-repeat: no-repeat;
    background-position: right 0.9rem center;
    cursor: pointer;
  }
  select:invalid { color: var(--field-placeholder); }
  select option { color: var(--ink); background: var(--white); }
  .check {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
    min-height: 2.75rem;
    cursor: pointer;
    font-size: var(--text-sm);
    font-weight: 700;
  }
  .check input {
    appearance: none;
    flex: none;
    width: 1.5rem;
    height: 1.5rem;
    margin: 0;
    border: 2px solid var(--film);
    border-radius: var(--radius);
    background: var(--field-bg) center / 0.875rem no-repeat;
    cursor: pointer;
  }
  .check input:checked { background-color: var(--film); background-image: var(--tick); }
  .check input:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--field-ring); }
  .check:hover input:not(:checked) { border-color: var(--ink-soft); }
  .button-link:has(input:focus-visible) { outline: 3px solid var(--field-ring); outline-offset: 3px; }
  .form-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-4); }
  .status { font-size: var(--text-sm); color: var(--ink-soft); min-height: 1.4em; }
  .status.is-error, .alert { color: var(--marker); font-weight: 700; }
  .alert { padding: var(--space-3) var(--space-4); border-left: 4px solid var(--marker); background: var(--paper-raised); }

  /* Scan */
  .page-head { padding-block: var(--space-6); }
  .page-head .alert { margin-top: var(--space-6); max-width: var(--measure); }
  .page-head .lede + .hint { margin-top: var(--space-3); max-width: var(--measure); }

  /*
    Steps read as the edge of a strip of film: a frame number in edge print over a bar, the bar
    filled for steps done and marked in yellow for the one you're on.
  */
  .stepper {
    list-style: none;
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 3px;
    max-width: 48rem;
    padding-top: var(--space-5);
    font-size: var(--text-sm);
    font-weight: 700;
    color: var(--silver);
  }
  .stepper li { position: relative; border-top: 4px solid var(--paper-shade); transition: color 0.4s; }
  .stepper a {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas: "no done" "label label";
    gap: var(--space-1) var(--space-2);
    align-items: center;
    padding-top: var(--space-2);
    color: inherit;
    text-decoration: none;
  }
  .stepper a:hover .step-label { text-decoration: underline; text-decoration-color: var(--marker); }
  /* Each step's bar fills from the left as it's reached. */
  .stepper li::before {
    content: "";
    position: absolute;
    inset: -4px 0 auto 0;
    height: 4px;
    background: var(--film);
    transform: scaleX(0);
    transform-origin: left;
  }
  .step-no { grid-area: no; font-family: var(--font-edge); font-size: 0.8125rem; letter-spacing: 0.12em; line-height: 1; }
  .step-label { grid-area: label; line-height: 1.2; }
  .step-done { grid-area: done; display: none; color: var(--signal-on); }
  .step-done .icon { width: 11px; height: 11px; }
  .stepper .is-done { color: var(--ink-soft); }
  .stepper .is-done::before { transform: none; }
  .stepper .is-done .step-done { display: block; }
  .stepper .is-on { color: var(--ink); }
  .stepper .is-on::before { transform: none; background: var(--marker-yellow); }
  @media (prefers-reduced-motion: no-preference) {
    .stepper li::before { transition: transform 0.6s cubic-bezier(0.6, 0, 0.3, 1), background-color 0.4s; }
  }

  /* A panel's head: edge print, the title, and what's done in it. */
  .panel-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-2) var(--space-4); }
  .panel-head .edge { flex-basis: 100%; margin-bottom: 0; }
  .panel-done { display: inline-flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); font-weight: 700; color: var(--ink-soft); }
  .panel-done::before { content: ""; width: 0.55rem; height: 0.55rem; border-radius: 50%; background: var(--signal-on); }

  /* Capture: a step's own shutter and, on a computer, the phone beside it. */
  .capture { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--space-4) var(--space-5); }
  .capture-own { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3) var(--space-4); }
  .capture:has(.remote.is-on) { flex-direction: column; }
  .remote { display: flex; align-items: center; gap: var(--space-3); }
  .capture:has(.capture-own + .remote) { flex-direction: column; align-items: stretch; gap: var(--space-3); }
  .capture-own + .remote:not(.is-on) { flex-direction: column; align-items: flex-start; gap: var(--space-3); }
  .capture-own + .remote:not(.is-on)::before {
    content: "or";
    display: flex;
    align-items: center;
    gap: var(--space-3);
    width: min(100%, 24rem);
    font-size: var(--text-sm);
    color: var(--ink-soft);
    background: linear-gradient(var(--rule), var(--rule)) left center / calc(50% - 1.25rem) 1px no-repeat,
      linear-gradient(var(--rule), var(--rule)) right center / calc(50% - 1.25rem) 1px no-repeat;
    justify-content: center;
  }
  /* In a wide panel the ways to take photos are one column of buttons the same width: the step's
     own (camera, file) side by side over the phone's, with anything said about them to the right.
     In a narrow one, and on a phone, each button spans the panel. */
  @container (min-width: 44rem) {
    .capture:has(.capture-own + .remote:not(.is-on)) { width: fit-content; }
    .capture-own:has(+ .remote:not(.is-on)) { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; position: relative; }
    .capture-own:has(+ .remote:not(.is-on)) > .button { grid-row: 1; }
    .capture-own:has(+ .remote:not(.is-on)) > :is(.hint, .button-link) { position: absolute; left: calc(100% + var(--space-4)); top: 50%; translate: 0 -50%; white-space: nowrap; }
    .capture-own + .remote:not(.is-on) { align-items: stretch; }
    .capture-own + .remote:not(.is-on)::before { width: 100%; }
  }
  @container (min-width: 44rem) and (max-width: 50rem) {
    .capture-own:has(+ .remote:not(.is-on)) > :is(.hint, .button-link) { position: static; translate: none; grid-row: 2; grid-column: 1; justify-self: start; }
  }
  @container (max-width: 44rem) {
    .capture, .capture-own { flex-direction: column; align-items: stretch; }
    .capture-own > .button-link { align-self: center; }
    .capture-own + .remote:not(.is-on) { align-items: stretch; }
    .capture-own + .remote:not(.is-on)::before { width: 100%; }
  }
  .button-quiet { border-color: var(--rule); background: var(--paper-raised); }
  .button-quiet:hover { border-color: var(--film); background: var(--paper-raised); }
  .remote-on { display: grid; grid-template-columns: minmax(0, 22rem) minmax(0, 1fr); gap: var(--space-5); align-items: center; width: 100%; padding: var(--space-4); background: var(--grain) var(--film); color: var(--edge-print); border-radius: var(--radius); }
  .remote.is-on { width: 100%; }
  /* In a narrow panel (the cover's) the phone's view goes above its controls, not beside them. */
  .panel { container-type: inline-size; }
  @container (max-width: 44rem) {
    .remote-on { grid-template-columns: minmax(0, 1fr); }
    .remote-view { max-width: 26rem; }
  }
  .remote-view {
    position: relative;
    display: grid;
    place-items: center;
    aspect-ratio: 4 / 3;
    background-color: var(--film-edge);
    background-image: var(--sprockets), var(--sprockets);
    background-repeat: repeat-x;
    background-position: 0 4px, 0 calc(100% - 4px);
    background-size: 16px 10px;
    overflow: hidden;
  }
  .remote-view img { position: absolute; inset: 18px 0; width: 100%; height: calc(100% - 36px); object-fit: contain; background: #000; }
  .remote-wait { padding: var(--space-4) var(--space-5); text-align: center; font-size: var(--text-sm); color: var(--film-soft); }
  .remote-view.is-flash::after { content: ""; position: absolute; inset: 0; background: var(--white); animation: flash 0.35s ease-out forwards; }
  @keyframes flash { from { opacity: 0.8; } to { opacity: 0; } }
  .remote-controls { display: grid; gap: var(--space-3); justify-items: start; }
  .remote-controls .phone-on { color: var(--paper); }
  .remote-controls .status { color: var(--edge-print); }
  .remote-tip { font-size: 0.8125rem; color: var(--film-soft); max-width: 40ch; }
  .remote-controls .button-shutter { background: var(--paper); color: var(--ink); border-color: var(--paper); }
  .remote-controls .button-shutter:disabled { opacity: 0.45; cursor: not-allowed; }
  .remote-more { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4); }
  .remote-more .button-link { color: var(--edge-print); }
  .remote-more .button-link:hover { color: var(--white); }
  .remote-note { margin-top: var(--space-3); }
  .phone-on { display: inline-flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); font-weight: 700; }
  .phone-on::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--signal-on); }
  .is-live .phone-on::before { box-shadow: 0 0 0 3px rgb(47 143 78 / 0.35); }
  .button-small { min-height: 2.5rem; padding: 0 var(--space-4); font-size: var(--text-sm); }

  /* Pairing a phone: a dialog with the code, opened from beside a shutter. */
  .pair {
    width: min(40rem, calc(100vw - 2 * var(--gutter)));
    padding: var(--space-6);
    border: 0;
    background: var(--paper-raised);
    color: var(--ink);
    box-shadow: var(--shadow-print);
  }
  .pair[open] { display: flex; gap: var(--space-6); align-items: center; }
  .pair::backdrop { background: rgb(20 19 17 / 0.72); }
  .pair-close { position: absolute; top: var(--space-2); right: var(--space-2); }
  .pair-code { width: 200px; height: 200px; flex: none; background: var(--white); image-rendering: pixelated; padding: 8px; border: 2px solid var(--film); }
  .pair-copy { display: grid; gap: var(--space-3); }
  .pair-copy h2 { font-family: var(--font-display); font-weight: 800; font-size: 2rem; line-height: 1; padding-right: var(--space-6); }
  /* On a phone or tablet the camera is already in hand; a computer chooses files and pairs a
     phone. Copy for one or the other is marked data-only. */
  @media (hover: none) and (pointer: coarse) {
    .remote, .hint-drop, [data-only="computer"] { display: none !important; }
  }
  @media not ((hover: none) and (pointer: coarse)) {
    [data-only="phone"] { display: none !important; }
  }

  .add-missing { margin-top: var(--space-7); padding-top: var(--space-5); border-top: 1px solid var(--rule); display: grid; gap: var(--space-2); }
  .add-missing > p { color: var(--ink-soft); max-width: var(--measure); }
  .add-form { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-2); }
  .add-form .field { flex: 1 1 18rem; max-width: 28rem; }
  /* Two lines kept for them whether they say anything or not, so nothing below moves. */
  .pages-now { display: grid; gap: var(--space-1); }
  .panel .pages-now .status, .panel .pages-now .status:empty { display: block; min-height: 1.5em; }
  .pages-read { font-size: var(--text-sm); }
  .pages-read summary { cursor: pointer; font-weight: 700; color: var(--ink-soft); padding-block: var(--space-2); }
  .pages-read summary:hover { color: var(--ink); }
  .pages-read .page-list { margin-top: var(--space-2); }

  .known-list { list-style: none; display: grid; gap: var(--space-3); }
  .known-card { display: flex; gap: var(--space-4); align-items: flex-start; padding: var(--space-3); background: var(--white); border: 1px solid var(--rule); }
  .known-cover { width: 5rem; flex: none; box-shadow: var(--shadow-print); }
  .known-body { display: grid; gap: var(--space-1); justify-items: start; }
  .known-title { font-weight: 700; }
  .known-why { font-size: var(--text-sm); }
  .known-body .button { margin-top: var(--space-2); }
  .combo { position: relative; }
  .combo-list {
    position: absolute;
    z-index: 5;
    top: calc(100% + 2px);
    left: 0;
    right: 0;
    max-height: 20rem;
    overflow-y: auto;
    list-style: none;
    background: var(--white);
    border: 2px solid var(--film);
    box-shadow: var(--shadow-print);
  }
  .combo-list li { display: grid; padding: var(--space-2) var(--space-3); cursor: pointer; border-bottom: 1px solid var(--paper-shade); }
  .combo-list li[aria-selected="true"], .combo-list li:hover { background: var(--paper-shade); }
  .combo-name { font-weight: 700; }
  .combo-place { font-size: var(--text-sm); color: var(--ink-soft); }
  .combo-own { font-size: var(--text-sm); color: var(--ink-soft); }
  .find.is-closed { gap: var(--space-2); }
  .find-head-actions { display: flex; gap: var(--space-4); margin-left: auto; }
  .find-body { display: grid; gap: var(--space-4); }
  .find-body > p { max-width: var(--measure); }
  .find-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3) var(--space-4); }

  /* The live camera: the picture with what's found drawn over it. */
  .camera, .find-still {
    --camera-you: var(--marker-yellow);
    --camera-face: var(--white);
    position: relative;
    width: min(100%, 40rem);
    background: var(--film);
    border: 8px solid var(--film);
    box-shadow: var(--shadow-print);
  }
  .camera-page { width: 100%; max-width: 56rem; }
  .camera video, .find-still img { display: block; width: 100%; height: auto; }
  .camera-overlay { position: absolute; inset: 0; width: 100%; height: 100%; cursor: pointer; }
  .camera-hint {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: var(--space-2) var(--space-3);
    background: rgb(20 19 17 / 0.72);
    color: var(--paper);
    font-size: var(--text-sm);
    pointer-events: none;
  }
  .camera-turn {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    padding: var(--space-2) var(--space-3);
    background: var(--marker-yellow);
    color: var(--ink);
    font-size: var(--text-sm);
    font-weight: 700;
    pointer-events: none;
  }
  .camera.is-flash::after { content: ""; position: absolute; inset: 0; background: var(--white); opacity: 0.6; pointer-events: none; }
  .button-shutter { min-width: 12rem; }
  .button-shutter::before {
    content: "";
    width: 0.9rem;
    height: 0.9rem;
    border-radius: 50%;
    background: var(--marker);
    box-shadow: 0 0 0 2px var(--paper);
  }
  .name-picks { list-style: none; display: flex; flex-wrap: wrap; gap: var(--space-2); }
  .name-picks:empty { display: none; }
  .find-result { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 26rem); gap: var(--space-5); align-items: start; }
  .find-form { align-content: start; }
  .find-one, .find-key { display: grid; gap: var(--space-3); }
  .find-still .camera-overlay { touch-action: none; cursor: move; }
  .chips { display: flex; flex-wrap: wrap; gap: var(--space-2); }
  .key-list { list-style: none; display: grid; gap: var(--space-2); }
  .key-item {
    display: grid;
    grid-template-columns: 1.5rem 3rem minmax(0, 1fr) auto auto;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2);
    background: var(--white);
    border: 1px solid var(--rule);
  }
  .key-no { font-family: var(--font-edge); font-weight: 700; font-size: 0.8125rem; text-align: center; color: var(--ink-soft); }
  .key-thumb { width: 3rem; height: 3.75rem; background: var(--film); }
  .key-item input[type="text"] { min-height: 2.5rem; font-size: var(--text-sm); }
  .key-moves { display: grid; gap: 2px; }
  .key-move {
    display: grid;
    place-items: center;
    width: 2rem;
    height: 1.2rem;
    padding: 0;
    border: 1px solid var(--field-border);
    border-radius: var(--radius);
    background: var(--field-bg);
    color: var(--ink);
    cursor: pointer;
  }
  .key-move:hover { border-color: var(--ink); }
  .key-move:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--field-ring); }
  .key-me { display: inline-flex; align-items: center; gap: var(--space-1); font-size: var(--text-sm); font-weight: 700; cursor: pointer; }
  .key-me input, .choice-quiet input {
    appearance: none;
    width: 1.25rem;
    height: 1.25rem;
    margin: 0;
    border: 2px solid var(--film);
    border-radius: 50%;
    background: var(--field-bg);
    cursor: pointer;
  }
  .key-me input:checked, .choice-quiet input:checked { background: radial-gradient(var(--film) 0 40%, var(--field-bg) 45%); }
  .key-me input:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--field-ring); }
  .choice-quiet { min-height: 2.5rem; border-width: 1px; }
  .find-ask { font-weight: 700; }
  .scan-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr); gap: var(--space-5); align-items: start; }
  .panel {
    background: var(--paper-raised);
    border: 1px solid var(--rule);
    padding: var(--space-5);
    display: grid;
    gap: var(--space-4);
    align-content: start;
  }
  .panel h2 { font-family: var(--font-display); font-weight: 800; font-size: 2rem; line-height: 1; }
  .panel-wide { grid-column: 1 / -1; }
  .panel.is-over { outline: 3px dashed var(--ink); outline-offset: -8px; }
  .pages-actions,
  .same-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-4); }
  .panel-same { border: 2px solid var(--ink); }
  .panel .status:empty, .page-list:empty { display: none; }
  .page-list { list-style: none; display: grid; gap: var(--space-2); }
  .page-item {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-2) var(--space-3);
    background: var(--white);
    border: 1px solid var(--rule);
    font-size: var(--text-sm);
  }
  .page-item-label { flex: 1; }
  .page-item.is-failed { border-left: 4px solid var(--marker); }
  .page-item.is-done { border-left: 4px solid var(--film); }
  .page-item.is-queued, .page-item.is-working { position: relative; overflow: hidden; }

  /* Waiting: a strip of film winds along under whatever is busy, a status ending in "…", a page
     being read, a photo being sent. */
  .status.is-busy::before, .page-item.is-queued::after, .page-item.is-working::after, .sent .is-sending .sent-state::after {
    content: "";
    display: inline-block;
    width: 2.25em;
    height: 0.55em;
    margin-right: 0.6em;
    vertical-align: 0.05em;
    background: repeating-linear-gradient(90deg, var(--film) 0 0.3em, transparent 0.3em 0.55em);
    border-block: 2px solid var(--film);
  }
  .page-item.is-queued::after, .page-item.is-working::after {
    position: absolute;
    inset: auto 0 0 0;
    width: auto;
    height: 3px;
    margin: 0;
    border: 0;
    background: linear-gradient(90deg, transparent, var(--marker-yellow), transparent) no-repeat;
    background-size: 40% 100%;
  }
  .page-item.is-queued::after { opacity: 0.45; }
  .sent .is-sending .sent-state::after { margin: 0 0 0 0.5em; background-image: repeating-linear-gradient(90deg, var(--edge-print) 0 0.3em, transparent 0.3em 0.55em); border-color: var(--edge-print); }
  @media (prefers-reduced-motion: no-preference) {
    .status.is-busy::before, .sent .is-sending .sent-state::after { animation: wind 0.7s linear infinite; }
    .page-item.is-queued::after, .page-item.is-working::after { animation: sweep 1.4s ease-in-out infinite; }
    .page-item.is-working::after { animation-duration: 1s; }
    .is-arriving { animation: arrive 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
    .is-arriving::after { content: ""; position: absolute; inset: -1px; border: 3px solid var(--marker-yellow); pointer-events: none; animation: arrive-ring 1.6s ease-out both; }
    .phone-stage.is-entering { animation: arrive 0.6s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
  }
  .is-arriving { position: relative; }
  @keyframes wind { to { background-position: 0.55em 0; } }
  @keyframes sweep { from { background-position: -60% 0; } to { background-position: 160% 0; } }
  @keyframes arrive { from { opacity: 0; transform: translateY(18px); } }
  @keyframes arrive-ring { 0%, 40% { opacity: 1; } 100% { opacity: 0; } }
  .proof { margin-top: var(--space-7); display: grid; gap: var(--space-4); }
  .proof h2 { font-family: var(--font-display); font-weight: 800; font-size: var(--display-md); line-height: 0.92; }
  .proof > p { max-width: var(--measure); }
  .proof-grid {
    list-style: none;
    display: grid;
    /* Wide enough for a long name in one line, so a name box never has to scroll. */
    grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
    column-gap: 0;
    row-gap: var(--space-5);
    margin-top: var(--space-3);
  }
  .proof-grid .frame { position: relative; display: grid; gap: var(--space-2); }
  .proof-grid .frame {
    --field-bg: var(--film-edge);
    --field-fg: var(--white);
    --field-border: var(--film-line);
    --field-border-hover: var(--film-soft);
    --field-placeholder: var(--film-soft);
  }
  .proof-grid .frame .button,
  .proof-grid .frame .chip { background: var(--field-bg); color: var(--field-fg); border-color: var(--field-border); }
  .proof-grid .frame .button:hover,
  .proof-grid .frame .chip:hover { border-color: var(--marker-yellow); background: var(--field-bg); }
  .proof-grid input:not([type="hidden"], [type="file"]) { min-height: 2.5rem; font-size: var(--text-sm); }
  /* A long name's letters shrink to fit its box (fitName); the box itself never changes size. */
  .proof-grid .proof-name { padding: 0 var(--space-2); text-overflow: ellipsis; }
  .proof-grid .proof-name:focus { text-overflow: clip; }
  .proof-grid .is-unsure :is(.proof-name, input:not([type="file"])) { border-color: var(--marker-yellow); box-shadow: inset 4px 0 0 var(--marker-yellow); }
  .proof-grid .is-unsure :is(.proof-name, input:not([type="file"])):focus-visible { box-shadow: inset 4px 0 0 var(--marker-yellow), 0 0 0 3px var(--field-ring); }
  .proof-grid .is-fixed .proof-name { border-color: var(--film-soft); }
  .proof-grid .is-error .proof-name { border-color: var(--marker-on-film); }

  /* The actions under a name: icons, each saying what it does to whoever can't see it. */
  .proof-actions { display: flex; align-items: center; gap: var(--space-2); }
  .icon-act {
    position: relative;
    display: grid;
    place-items: center;
    flex: none;
    width: 2.5rem;
    height: 2.5rem;
    padding: 0;
    border: 2px solid var(--film-line);
    border-radius: var(--radius);
    background: var(--film-edge);
    color: var(--edge-print);
    cursor: pointer;
  }
  .icon-act:hover { color: var(--white); border-color: var(--film-soft); }
  .icon-act:focus-visible, .icon-act:has(input:focus-visible) { outline: 2px solid var(--marker-yellow); outline-offset: 1px; }
  .proof-grid .is-weak .proof-retake { color: var(--marker-on-film); border-color: var(--marker-on-film); }
  .proof-reads.is-none { visibility: hidden; }
  .icon-count {
    position: absolute;
    top: -7px;
    right: -7px;
    min-width: 18px;
    height: 18px;
    padding: 0 4px;
    border-radius: 9px;
    background: var(--marker-yellow);
    color: var(--ink);
    font: 700 11px/18px var(--font-edge);
  }
  .icon-count:empty { display: none; }
  .proof-remove.is-armed, .proof-remove.is-armed:hover { color: var(--white); background: var(--marker); border-color: var(--marker); }
  /* Saved, saving or not saved: a mark at the end of the actions, its words for screen readers. */
  .proof-status { flex: 1; min-width: 0; display: flex; justify-content: flex-end; font-size: 0; }
  .proof-status::after { content: ""; width: 11px; height: 11px; }
  .proof-status[data-state="saved"]::after { background: var(--signal-on); }
  .proof-status[data-state="saving"]::after { background: var(--film-soft); animation: blink 0.8s steps(2) infinite; }
  .proof-status[data-state="error"]::after, .proof-status[data-state="ask"]::after { background: var(--marker-on-film); }
  @keyframes blink { 50% { opacity: 0; } }
  @media (prefers-reduced-motion: reduce) { .proof-status[data-state="saving"]::after { animation: none; } }

  /* Over the bottom of a frame: other reads to pick from, or what went wrong. */
  .proof-pop {
    position: absolute;
    left: var(--space-2);
    right: var(--space-2);
    bottom: calc(2.5rem + var(--space-4));
    z-index: 3;
    display: grid;
    gap: var(--space-2);
    padding: var(--space-3);
    background: var(--film);
    border: 2px solid var(--marker-yellow);
    border-radius: var(--radius);
    box-shadow: 0 8px 24px rgb(0 0 0 / 0.45);
    color: var(--edge-print);
    font-size: 0.8125rem;
  }
  .proof-pop.is-error { border-color: var(--marker-on-film); color: var(--white); }
  .proof-pop .chip { justify-content: flex-start; width: 100%; min-height: 2.5rem; text-align: left; white-space: normal; overflow-wrap: anywhere; font-size: var(--text-sm); }
  .proof-pop-close { position: absolute; top: 0; right: 0; border-color: transparent; background: none; }
  .proof-pop-head, .proof-pop.is-error p { min-height: 1.5rem; padding-right: 2.5rem; color: var(--silver); }
  .proof-pop.is-error p { color: var(--white); }

  .proof-more { display: grid; gap: var(--space-2); margin-top: var(--space-5); }
  .proof-more h3 { font-family: var(--font-display); font-weight: 800; font-size: var(--text-xl); line-height: 1; }
  .proof-more > p { max-width: var(--measure); }
  .proof-grid-bare { grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); }
  .proof-grid-bare .frame-photo, .proof-grid-bare .frame-quality { display: none; }
  .proof-miss { display: grid; gap: var(--space-2); }
  .proof-done {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-4);
    margin-top: var(--space-5);
    padding-top: var(--space-5);
    border-top: 3px solid var(--film);
  }

  /* Class sheet. With a cover, the cover is the backdrop: blurred, washed into the paper, and laid
     on the right as a print. */
  .class-head { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--space-6); align-items: end; padding-block: var(--space-6); }
  .class-head .display { font-size: var(--display-lg); }
  .class-title { position: relative; grid-column: 1; grid-row: 1; display: grid; justify-items: start; }
  .class-hero {
    position: absolute;
    z-index: -1;
    inset: calc(var(--space-8) * -2) calc(50% - 50vw) 0;
    overflow: hidden;
    pointer-events: none;
    -webkit-mask-image: linear-gradient(to bottom, #000 0%, rgb(0 0 0 / 0.75) 45%, transparent 100%);
    mask-image: linear-gradient(to bottom, #000 0%, rgb(0 0 0 / 0.75) 45%, transparent 100%);
  }
  .class-hero img { width: 100%; height: 100%; object-fit: cover; filter: saturate(0.55) brightness(1.15); opacity: 0.55; }
  .page-class.has-cover .masthead { position: relative; z-index: 1; }
  .page-class.has-cover main { position: relative; isolation: isolate; }
  .class-up { margin-top: var(--space-3); font-size: var(--text-sm); color: var(--ink-soft); }
  .class-title .alert { margin-top: var(--space-4); }
  .class-link { margin-top: var(--space-5); display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3) var(--space-4); }
  .class-link .hint { flex-basis: 100%; max-width: 46ch; }
  .class-more {
    margin-top: var(--space-8);
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    gap: var(--space-5);
    align-items: center;
    padding: var(--space-5) var(--space-6);
    background: var(--paper-raised);
    border: 1px solid var(--rule);
    border-top: 3px solid var(--film);
    background-image: var(--halftone);
    background-position: right top;
    background-repeat: no-repeat;
  }
  .class-more .section-title { margin-bottom: var(--space-1); }
  .class-more p { color: var(--ink-soft); max-width: 52ch; }
  .class-more-art { width: 3rem; height: 3rem; }

  .teststrip { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-5); }
  /* One cell a classmate: a big class packs them down to hairlines rather than running wide. */
  .teststrip-bar {
    display: flex;
    height: 44px;
    gap: clamp(0px, 0.15vw, 2px);
    overflow: hidden;
    background: var(--paper);
  }
  .cell { flex: 1 1 0; min-width: 0; background: var(--paper-shade); }
  .cell.is-dead { background: var(--film); box-shadow: inset 0 3px 0 var(--marker); }
  .figures { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-5); }
  .figure { display: flex; flex-direction: column; border-top: 1px solid var(--rule); padding-top: var(--space-3); }
  .figure dt { order: 2; font-weight: 700; font-size: var(--text-sm); }
  .figure dd { order: 1; }
  .figure .figure-note { order: 3; font-size: var(--text-sm); color: var(--ink-soft); }
  .figure-num { font-family: var(--font-display); font-weight: 800; font-size: clamp(3rem, 6vw, 4.5rem); line-height: 0.9; }
  .figure-of { font-family: var(--font-display); font-weight: 500; font-size: 1.75rem; margin-left: 0.25em; color: var(--ink-soft); }
  .figure-lead { border-top: 3px solid var(--marker); }
  /*
    The first look at a class (sheet.js): a curtain of dark over the blurred page, film running
    down both sides, and the dead as the credits of a film. Then the class develops.
  */
  :root {
    --sprockets-v: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='16'%3E%3Crect x='2' y='4' width='6' height='8' rx='1.5' fill='%23eef0ec' fill-opacity='.85'/%3E%3C/svg%3E");
  }
  .is-curtained, .is-curtained body { overflow: hidden; }
  .curtain {
    --reel-w: clamp(30px, 6vw, 64px);
    --reel-time: 9s;
    position: fixed;
    inset: 0;
    z-index: 100;
    display: grid;
    grid-template-rows: minmax(0, 1fr) auto;
    padding-inline: calc(var(--reel-w) + var(--gutter));
    background: rgb(12 12 11 / 0.84);
    -webkit-backdrop-filter: blur(14px) grayscale(1);
    backdrop-filter: blur(14px) grayscale(1);
    color: var(--paper);
    opacity: 0;
    transition: opacity 0.8s ease;
  }
  .curtain.is-up { opacity: 1; }
  .curtain.is-going { opacity: 0; transition-duration: 0.6s; }
  /* Film down each side: sprockets at both edges, frames between, running up. */
  .curtain-reel {
    position: absolute;
    top: 0;
    bottom: 0;
    width: var(--reel-w);
    background-color: var(--film);
    background-image: var(--sprockets-v), var(--sprockets-v),
      repeating-linear-gradient(to bottom, #262521 0 70px, var(--film) 70px 84px);
    background-repeat: repeat-y, repeat-y, no-repeat;
    background-size: 10px 16px, 10px 16px, calc(100% - 26px) 100%;
    background-position: 2px 0, calc(100% - 2px) 0, 13px 0;
    box-shadow: 0 0 40px rgb(0 0 0 / 0.6);
    animation: reel var(--reel-time) linear infinite;
  }
  .curtain-reel-left { left: 0; }
  .curtain-reel-right { right: 0; animation-direction: reverse; }
  @keyframes reel {
    to { background-position: 2px -96px, calc(100% - 2px) -96px, 13px -504px; }
  }
  .curtain-stage { display: grid; grid-template-rows: auto minmax(0, 1fr); min-height: 0; padding-top: clamp(1.5rem, 6vh, 4rem); }
  .curtain-head { text-align: center; padding-bottom: var(--space-5); opacity: 0; transform: translateY(10px); transition: opacity 0.9s 0.3s, transform 0.9s 0.3s cubic-bezier(0.2, 0.7, 0.2, 1); }
  .curtain.is-up .curtain-head { opacity: 1; transform: none; }
  .curtain-kicker { font-family: var(--font-edge); font-weight: 700; font-size: 0.8125rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--silver); }
  .curtain-title { margin-top: var(--space-2); font-family: var(--font-display); font-weight: 800; font-size: clamp(2.75rem, 7vw, 5rem); line-height: 0.9; }
  .curtain-sub { margin-top: var(--space-2); color: var(--edge-print); font-size: var(--text-sm); }
  /* The credits fade in from nothing at the bottom and back to nothing at the top. */
  .credits-window {
    position: relative;
    min-height: 0;
    overflow: hidden;
    -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 16%, #000 80%, transparent 100%);
    mask-image: linear-gradient(to bottom, transparent 0, #000 16%, #000 80%, transparent 100%);
  }
  .credits-window.is-still { -webkit-mask-image: none; mask-image: none; display: grid; align-content: start; overflow-y: auto; }
  .credits { list-style: none; display: grid; gap: var(--space-5); padding-block: var(--space-4); will-change: transform; }
  .credit {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: center;
    gap: var(--space-5);
    opacity: 0;
  }
  .credits-window.is-rolling .credit { opacity: 1; }
  .credits-window.is-still .credit.is-in { animation: credit-in 0.9s var(--delay, 0ms) cubic-bezier(0.2, 0.7, 0.2, 1) both; }
  @keyframes credit-in { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
  .credit-photo { position: relative; justify-self: end; width: clamp(64px, 9vw, 92px); aspect-ratio: 4 / 5; background: var(--film-edge); }
  .credit-photo img, .credit-photo .frame-blank { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; filter: grayscale(1) contrast(1.06); }
  .credit-photo .marker { --mx: 6px; --my: 6px; }
  .credit-photo .marker-box path { stroke: var(--marker-on-film); }
  .credit-name { font-family: var(--font-display); font-weight: 800; font-size: clamp(1.5rem, 3.4vw, 2.25rem); line-height: 1; }
  .credit-years { margin-top: var(--space-1); font-family: var(--font-edge); font-weight: 700; font-size: 0.875rem; letter-spacing: 0.1em; color: var(--edge-print); }
  .curtain-foot { display: flex; justify-content: center; padding: var(--space-5) 0 clamp(1.5rem, 5vh, 3rem); opacity: 0; transform: translateY(12px); pointer-events: none; transition: opacity 0.6s, transform 0.6s cubic-bezier(0.2, 0.7, 0.2, 1); }
  .curtain-foot.is-on { opacity: 1; transform: none; pointer-events: auto; }
  .button-light { background: var(--paper); color: var(--ink); border-color: var(--paper); }
  .button-light:hover { background: var(--white); }
  .curtain-skip {
    position: absolute;
    top: var(--space-4);
    right: calc(var(--reel-w) + var(--space-4));
    padding: var(--space-2) var(--space-3);
    border: 1px solid var(--film-line);
    border-radius: var(--radius);
    background: transparent;
    color: var(--edge-print);
    font-size: var(--text-sm);
    font-weight: 700;
    cursor: pointer;
  }
  .curtain-skip:hover { color: var(--white); border-color: var(--edge-print); }
  .curtain-skip:focus-visible { outline: 3px solid var(--marker-yellow); outline-offset: 2px; }
  .is-developing .teststrip-bar { transform-origin: left; animation: wipe 1.4s cubic-bezier(0.6, 0, 0.3, 1) both; }
  .is-developing .figure { animation: arrive 0.6s both; }
  .is-developing .figure + .figure { animation-delay: 150ms; }
  @keyframes wipe { from { transform: scaleX(0); } }
  .checking { display: flex; align-items: center; gap: var(--space-3); font-size: var(--text-sm); }
  .checking-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--marker); flex: none; }
  @media (prefers-reduced-motion: no-preference) {
    .checking-dot { animation: safelight 1.6s ease-in-out infinite; }
  }
  @keyframes safelight { 50% { opacity: 0.25; } }

  .you {
    margin-top: var(--space-7);
    padding: var(--space-5) var(--space-6);
    background: var(--paper-raised);
    border: 1px solid var(--rule);
    border-left: 6px solid var(--marker-yellow);
    display: grid;
    gap: var(--space-4);
  }
  .you .section-title { margin-bottom: 0; }
  .you:has(.you-print) { grid-template-columns: 8.5rem minmax(0, 1fr); column-gap: var(--space-6); align-items: center; }
  .you-print { position: relative; background: var(--film); padding: 8px; rotate: -1.5deg; }
  .you-print img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; filter: grayscale(1) contrast(1.06); }
  .class-you { margin-top: var(--space-3); font-size: var(--text-lg); font-weight: 700; }
  .class-you a { text-decoration: none; }
  .class-you a:hover { text-decoration: underline; text-decoration-color: var(--marker-yellow); }
  .class-you-mark {
    display: inline-block;
    margin-right: var(--space-2);
    padding: 0 0.4em;
    background: var(--marker-yellow);
    font-family: var(--font-display);
    font-weight: 800;
    letter-spacing: 0.02em;
  }
  .you-body { display: grid; gap: var(--space-2); }
  .you-line { font-size: var(--text-lg); max-width: 48ch; }
  .you-line strong { font-weight: 700; }
  .you-ask { display: grid; gap: var(--space-2); }
  .you-ask .section-title { margin-bottom: 0; }
  .you-ask p { color: var(--ink-soft); max-width: 52ch; }
  .curtain:focus { outline: none; }
  .you-actions { display: grid; gap: var(--space-4); justify-items: start; }
  .me-picks { grid-column: 1 / -1; grid-row: 2; list-style: none; display: flex; flex-wrap: wrap; gap: var(--space-2); }
  .you-type [data-me-submit] { grid-row: 1; grid-column: 3; }
  .me-pick {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-height: 2.75rem;
    padding: 4px var(--space-3) 4px 4px;
    border: 2px solid var(--field-border);
    border-radius: var(--radius);
    background: var(--field-bg);
    font-weight: 700;
    font-size: var(--text-sm);
    cursor: pointer;
  }
  .me-pick img { width: 1.75rem; height: 2.2rem; object-fit: cover; filter: grayscale(1); background: var(--film); }
  .me-pick:hover { border-color: var(--ink); }
  .me-pick:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--field-ring); }
  .me-pick[aria-pressed="true"] { border-color: var(--ink); box-shadow: inset 4px 0 0 var(--marker-yellow); }
  .you-type { display: grid; grid-template-columns: minmax(0, 24rem) 9rem auto; gap: var(--space-4); justify-content: start; align-items: end; width: 100%; }
  .field-year { max-width: 9rem; }

  .sheet { margin-top: var(--space-7); }
  .sheet-tools {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3) var(--space-5);
    margin-bottom: var(--space-6);
  }
  .search { position: relative; flex: 1 1 16rem; max-width: 24rem; }
  .search .icon { position: absolute; left: 0.85rem; top: 50%; translate: 0 -50%; color: var(--ink-soft); pointer-events: none; }
  .search input { padding-left: 2.6rem; }
  .sheet-filters { display: flex; flex-wrap: wrap; gap: var(--space-2); }
  .sheet-filters .chip { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2); min-height: var(--control-h); }
  .chip {
    min-height: 2.5rem;
    padding: 0 var(--space-4);
    border: 2px solid var(--film);
    border-radius: var(--radius);
    background: transparent;
    font-weight: 700;
    font-size: var(--text-sm);
    cursor: pointer;
  }
  .chip:hover { background: var(--paper-shade); }
  .chip:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--field-ring); }
  .name-picks .chip[aria-pressed="true"] { background: var(--marker-yellow); color: var(--ink); border-color: var(--ink); }
  .chip[aria-pressed="true"] { background: var(--film); color: var(--paper); }
  .chip-n { font-weight: 400; opacity: 0.8; font-variant-numeric: tabular-nums; }
  .sheet-count { font-size: var(--text-sm); color: var(--ink-soft); }
  .frame[hidden] { display: none; }
  .frames {
    list-style: none;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(152px, 1fr));
    column-gap: 0;
    row-gap: var(--space-6);
  }
  .frames .frame.is-checking .frame-photo img { opacity: 0.7; }
  /* A big class is thousands of elements: frames off screen aren't laid out or painted until near. */
  .frames .frame { content-visibility: auto; contain-intrinsic-size: auto 17rem; }
  /* Columns are fractions of a pixel wide, and the paper shows through where two frames' edges are
     smoothed (more so as each frame paints on its own); each frame reaching 2px under the next
     closes the seam, and the grid gives the last column those 2px back. */
  .frames { padding-inline-end: 2px; }
  .frames .frame { margin-inline-end: -2px; }
  .frame-pick { display: none; }
  .sheet.is-picking .frame-pick { display: block; position: absolute; inset: 0; }
  /* Picking yourself: every photo carries a yellow "This is me" tag across it, and the one under
     the pointer gets the yellow box. */
  .frame-pick-button {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    background: rgb(20 19 17 / 0.12);
    border: 0;
    cursor: pointer;
  }
  .pick-tag {
    padding: 0.15em 0.55em 0.1em;
    background: var(--marker-yellow);
    color: var(--ink);
    font-family: var(--font-display);
    font-weight: 800;
    font-size: 1.25rem;
    line-height: 1;
    letter-spacing: 0.01em;
    text-transform: uppercase;
    rotate: -4deg;
    box-shadow: 0 2px 0 rgb(20 19 17 / 0.35);
  }
  .frame-pick-button:hover, .frame-pick-button:focus-visible {
    background: rgb(242 194 48 / 0.16);
    outline: 4px solid var(--marker-yellow);
    outline-offset: -4px;
  }
  .frame-pick-button:hover .pick-tag, .frame-pick-button:focus-visible .pick-tag { rotate: -2deg; scale: 1.08; }
  .empty { padding: var(--space-6); background: var(--paper-raised); border: 1px dashed var(--silver); }

  /* The enlargement: an obituary laid on the paper like a print. */
  .enlargement {
    width: min(920px, calc(100vw - 2 * var(--gutter)));
    max-height: calc(100vh - 2 * var(--gutter));
    padding: var(--space-6);
    border: 0;
    background: #fbfbf8;
    color: var(--ink);
    box-shadow: var(--shadow-print);
  }
  .enlargement::backdrop { background: rgb(20 19 17 / 0.72); }
  .enlargement-close { position: sticky; top: 0; display: flex; justify-content: flex-end; z-index: 1; margin: calc(var(--space-3) * -1) calc(var(--space-3) * -1) 0 0; }
  .icon-button {
    display: grid;
    place-items: center;
    width: 2.75rem;
    height: 2.75rem;
    padding: 0;
    border: 2px solid transparent;
    border-radius: var(--radius);
    background: var(--paper-raised);
    color: var(--ink);
    cursor: pointer;
  }
  .icon-button:hover { border-color: var(--ink); }
  .icon-button:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--field-ring); }
  .obit { display: grid; grid-template-columns: minmax(0, 220px) minmax(0, 1fr); gap: var(--space-6); align-items: start; }
  .obit.obit-bare { grid-template-columns: minmax(0, 1fr); }
  .obit-print { position: relative; background: var(--film); padding: 12px; rotate: -1.5deg; margin-top: var(--space-3); }
  .obit-print img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; filter: grayscale(1) contrast(1.06); }
  .obit-print .marker-box { --mx: -4px; --my: -4px; height: auto; aspect-ratio: 4 / 5; }
  .obit-caption { margin-top: var(--space-2); font-size: var(--text-sm); color: var(--edge-print); }
  .obit-name { font-family: var(--font-display); font-weight: 800; font-size: clamp(2.25rem, 5vw, 3.5rem); line-height: 0.95; }
  .obit-dates { margin-top: var(--space-3); font-family: var(--font-display); font-weight: 700; font-size: 1.5rem; letter-spacing: 0.02em; color: var(--marker); }
  .obit-age { color: var(--ink-soft); }
  .obit-places { margin-top: var(--space-3); color: var(--ink-soft); }
  .obit-notices { margin-top: var(--space-5); padding: 0; list-style: none; display: grid; gap: var(--space-3); }
  .obit-notices li { display: grid; gap: 2px; justify-items: start; }
  .obit-notices a { font-weight: 700; font-size: 1.0625rem; }
  .obit-home { font-size: var(--text-sm); color: var(--ink-soft); }
  .obit-why { margin-top: var(--space-5); font-size: var(--text-sm); color: var(--ink-soft); max-width: var(--measure); }
  .obit-page { padding-top: var(--space-5); display: grid; gap: var(--space-5); }

  /* Phone */
  .phone { max-width: 34rem; padding-top: var(--space-4); }
  .phone-actions { display: grid; gap: var(--space-3); margin-top: var(--space-6); }
  .phone .camera { margin-top: var(--space-5); }
  .phone .name-picks { margin-top: var(--space-3); }
  .phone-actions .button-link { justify-self: center; padding: var(--space-3); }
  .sent { list-style: none; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-2); margin-top: var(--space-5); }
  .sent li { position: relative; aspect-ratio: 3 / 4; background: var(--film); }
  .sent img { width: 100%; height: 100%; object-fit: cover; }
  .sent .sent-state {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 2px 6px;
    font-size: 0.75rem;
    background: var(--film);
    color: var(--edge-print);
  }
  .sent .is-failed .sent-state { color: var(--marker-on-film); }
  .sent .is-skipped img { opacity: 0.4; }
  .phone-leave { margin-top: var(--space-7); }
  .phone .agree { margin-top: var(--space-5); }
  .phone .status:not(:empty) { margin-top: var(--space-2); }
  .phone-steps { grid-template-columns: repeat(3, minmax(0, 1fr)); margin-top: var(--space-4); padding-top: 0; }
  .phone-steps li { display: grid; grid-template-areas: "no" "label"; justify-items: start; gap: var(--space-1); padding-top: var(--space-2); }
  .phone-stage { display: grid; gap: var(--space-2); margin-top: var(--space-5); }
  .phone-step-of { font-family: var(--font-edge); font-size: 0.8125rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-soft); }
  .phone-step-of:empty { display: none; }

  /* Accounts and notices */
  .auth, .notice-page, .account { max-width: 36rem; padding-top: var(--space-5); display: grid; gap: var(--space-5); }
  .class-list { list-style: none; display: grid; gap: var(--space-2); }
  .class-list a {
    display: grid;
    grid-template-columns: 5rem minmax(0, 1fr) auto;
    gap: var(--space-4);
    align-items: baseline;
    padding: var(--space-3) var(--space-4);
    background: var(--paper-raised);
    border: 1px solid var(--rule);
    text-decoration: none;
  }
  .class-list a:hover { border-color: var(--ink); }
  .class-list-year { font-family: var(--font-display); font-weight: 800; font-size: 1.75rem; line-height: 1; }
  .class-list-count { font-size: var(--text-sm); color: var(--ink-soft); }
  /* Accounts, reports and the admin */
  .auth, .report, .account { max-width: 44rem; }
  .auth-panel, .report-panel { margin-top: var(--space-2); }
  .auth-or { display: grid; gap: var(--space-3); justify-items: start; padding-top: var(--space-5); border-top: 1px solid var(--rule); }
  /* The two ways in, one under the other, are the same width. */
  .auth-panel .button { min-width: 16rem; }
  .auth-note { margin-top: var(--space-5); }
  .alert-ok { color: var(--ink); border-left-color: var(--signal-on); }
  .trap { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
  textarea {
    appearance: none;
    width: 100%;
    min-height: 6rem;
    padding: var(--space-3);
    border: 2px solid var(--field-border);
    border-radius: var(--radius);
    background: var(--field-bg);
    color: var(--field-fg);
    font-size: var(--text-base);
    line-height: 1.45;
    resize: vertical;
    transition: border-color 0.12s ease, box-shadow 0.12s ease;
  }
  textarea:hover { border-color: var(--field-border-hover); }
  textarea:focus-visible { outline: none; border-color: var(--field-fg); box-shadow: 0 0 0 3px var(--field-ring); }
  .choices { border: 0; padding: 0; margin: 0; display: grid; gap: var(--space-2); }
  .choices legend { font-weight: 700; font-size: var(--text-sm); margin-bottom: var(--space-2); padding: 0; }
  .choice {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    min-height: var(--control-h);
    padding: 0 var(--space-4);
    border: 2px solid var(--field-border);
    border-radius: var(--radius);
    background: var(--field-bg);
    cursor: pointer;
    font-weight: 700;
    font-size: var(--text-sm);
  }
  .choice:hover { border-color: var(--field-border-hover); }
  .choice input {
    appearance: none;
    flex: none;
    width: 1.25rem;
    height: 1.25rem;
    margin: 0;
    border: 2px solid var(--film);
    border-radius: 50%;
    background: var(--field-bg);
    cursor: pointer;
  }
  .choice input:checked { background: radial-gradient(var(--film) 0 40%, var(--field-bg) 45%); }
  .choice:has(input:checked) { border-color: var(--film); box-shadow: inset 4px 0 0 var(--marker-yellow); }
  .choice:has(input:focus-visible) { box-shadow: 0 0 0 3px var(--field-ring); }
  .report-head { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--space-5); align-items: center; }
  .report-print { width: 7rem; background: var(--film); padding: 6px; rotate: -1.5deg; }
  .report-print img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; }
  .account-section { margin-top: var(--space-7); display: grid; gap: var(--space-3); }
  .account-out { padding-top: var(--space-5); border-top: 1px solid var(--rule); justify-items: start; }
  .notify-form { gap: var(--space-2); }
  .notify-form .form-actions { margin-top: var(--space-2); }
  .check-hinted { align-items: flex-start; }
  .check-hinted input { margin-top: 0.1rem; }
  .check-hinted .hint { display: block; font-weight: 400; margin-top: 2px; max-width: 52ch; }
  .follow-list { list-style: none; display: grid; gap: var(--space-2); }
  .follow {
    display: grid;
    grid-template-columns: 3rem minmax(0, 1fr) auto;
    gap: var(--space-4);
    align-items: center;
    padding: var(--space-2) var(--space-3);
    background: var(--paper-raised);
    border: 1px solid var(--rule);
  }
  .follow-photo { position: relative; display: block; width: 3rem; aspect-ratio: 4 / 5; background: var(--film); overflow: hidden; }
  .follow-photo img, .follow-photo .frame-blank { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; filter: grayscale(1); }
  .follow-who { display: grid; gap: 2px; }
  .follow-who a { text-decoration: none; }
  .follow-who a:hover { text-decoration: underline; }
  .follow.is-dead { border-left: 4px solid var(--marker); }
  .follow-dead { font-size: var(--text-sm); font-weight: 700; color: var(--marker); }
  .report-list { list-style: none; display: grid; gap: var(--space-2); }
  .report-list li { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-1) var(--space-4); padding: var(--space-3) var(--space-4); background: var(--paper-raised); border: 1px solid var(--rule); }
  .report-list .hint { flex-basis: 100%; }
  .report-state { font-size: var(--text-sm); font-weight: 700; }
  .report-state.is-done { color: var(--signal-on); }
  .admin-tz { padding-top: var(--space-4); font-size: 0.8125rem; }
  .admin-nav { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-5); padding-top: var(--space-5); font-weight: 700; font-size: var(--text-sm); }
  .admin-nav a { text-decoration: none; padding-bottom: var(--space-1); border-bottom: 3px solid transparent; }
  .admin-nav a[aria-current="page"] { border-bottom-color: var(--marker-yellow); }
  .admin-head { display: grid; gap: var(--space-2); padding-block: var(--space-6) var(--space-5); }
  .admin-note { margin: 0; padding: var(--space-3) var(--space-4); border-left: 4px solid var(--marker-yellow); background: var(--paper-raised); white-space: pre-line; max-width: var(--measure); }
  .admin-table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
  .admin-table th { text-align: left; font-weight: 700; padding: var(--space-2) var(--space-3); border-bottom: 2px solid var(--film); }
  .admin-table td { padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--rule); vertical-align: middle; }
  .admin-table input:not([type="hidden"]) { min-height: 2.25rem; font-size: var(--text-sm); }
  .admin-thumb { width: 3rem; aspect-ratio: 4 / 5; object-fit: cover; background: var(--film); }
  .admin-fix { display: flex; flex-wrap: wrap; gap: var(--space-3); }
  .admin-mate { display: flex; gap: var(--space-5); align-items: flex-start; margin-bottom: var(--space-5); }
  .admin-print { margin: 0; width: 9rem; background: var(--film); padding: 6px; }
  .admin-print img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; }
  .admin-print figcaption { font-family: var(--font-edge); font-size: 0.75rem; color: var(--silver); padding-top: 4px; }
  .admin-facts { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--space-1) var(--space-4); }
  .admin-facts dt { font-weight: 700; }
  .admin-actions { display: grid; grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr)); gap: var(--space-5); }
  .admin-act { padding: var(--space-5); background: var(--paper-raised); border: 1px solid var(--rule); align-content: start; }
  .admin-delete { margin-top: var(--space-7); max-width: 36rem; display: grid; gap: var(--space-4); }
  .admin-delete h2 { font-family: var(--font-display); font-weight: 800; font-size: 2rem; line-height: 1; }
  .admin-count { display: inline-grid; place-items: center; min-width: 1.4rem; height: 1.4rem; padding: 0 0.35rem; margin-left: 0.25rem; border-radius: 0.7rem; background: var(--marker-yellow); color: var(--ink); font-size: 0.75rem; }
  .admin-sub { font-family: var(--font-display); font-weight: 800; font-size: 2rem; line-height: 1; margin: var(--space-7) 0 var(--space-4); }
  .held-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); gap: var(--space-5); }
  .held { display: grid; gap: var(--space-3); align-content: start; padding: var(--space-4); background: var(--paper-raised); border: 1px solid var(--rule); }
  .held-photo { position: relative; display: block; overflow: hidden; background: var(--film); cursor: pointer; }
  .held-photo img { display: block; width: 100%; aspect-ratio: 4 / 5; object-fit: contain; filter: blur(22px); transform: scale(1.1); transition: filter 0.2s; }
  .held-photo input:checked ~ img { filter: none; transform: none; }
  .held-show { position: absolute; inset: auto var(--space-3) var(--space-3) auto; padding: var(--space-1) var(--space-3); background: var(--paper); font-weight: 700; font-size: var(--text-sm); }
  .held-photo input:checked ~ .held-show { display: none; }
  .held-photo:has(input:focus-visible) { outline: 3px solid var(--field-ring); outline-offset: 3px; }
  .held-facts { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--space-1) var(--space-3); margin: 0; font-size: var(--text-sm); }
  .held-facts dt { font-weight: 700; }
  .held-facts dd { margin: 0; overflow-wrap: anywhere; }
  .held-act { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; }
  .inline-form { display: inline; }
  .admin-cands { margin-top: var(--space-7); display: grid; gap: var(--space-4); }
  .admin-cands .field-inline { max-width: 36rem; }
  .admin-filter { max-width: 40rem; margin-bottom: var(--space-5); }
  .admin-filter select { flex: 0 0 auto; width: auto; }
  .admin-numbers td:not(:first-child):not(.hint), .admin-numbers th:not(:first-child) { text-align: right; font-variant-numeric: tabular-nums; }
  .admin-numbers td.hint, .admin-numbers th.is-text { text-align: left; }
  .admin-ban { font-size: 0.75rem; font-weight: 700; padding: 0 0.35rem; background: var(--marker-yellow); color: var(--ink); }
  .admin-path { font-family: var(--font-edge); font-size: 0.75rem; overflow-wrap: anywhere; max-width: 22rem; }
  .admin-agent { font-size: 0.75rem; color: var(--silver); overflow-wrap: anywhere; max-width: 18rem; }
  .admin-log td { vertical-align: top; }
  .admin-head + .admin-table, .admin-head + .hint + .admin-act { margin-bottom: var(--space-5); }
  .harvest-state { font-weight: 700; color: var(--signal-on); }
  .harvest-state.is-paused { color: var(--marker); }
  .harvest-state.is-quiet { color: var(--ink-soft); font-weight: 400; }
  .admin-table th.num, .admin-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
  .mail-state { font-weight: 700; }
  .mail-state.is-sent { color: var(--signal-on); }
  .mail-state.is-failed { color: var(--marker); }
  .nowrap { white-space: nowrap; }
  .admin-back { padding-top: var(--space-5); }
  .mail-views { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); gap: var(--space-6); align-items: start; }
  .mail-views .admin-sub { margin-top: var(--space-6); }
  .mail-frame { display: block; width: 100%; height: 34rem; border: 1px solid var(--rule); background: var(--paper); }
  .mail-text { margin: 0; padding: var(--space-4); background: var(--paper-raised); border: 1px solid var(--rule); white-space: pre-wrap; overflow-wrap: anywhere; font-family: var(--font-body); font-size: var(--text-sm); line-height: 1.5; }
  .passkeys { display: grid; gap: var(--space-3); }
  .form-actions:not(:has(> :not([hidden], .status:empty))) { display: none; }
  .passkey-list { list-style: none; display: grid; gap: var(--space-2); }
  .passkey-list li { display: flex; justify-content: space-between; gap: var(--space-4); }

  /* iPhones zoom the page into any field set under 16px when it's tapped. */
  @media (pointer: coarse) {
    .proof-grid input:not([type="hidden"], [type="file"]), .proof-name, .key-item input[type="text"], .admin-table input:not([type="hidden"]) { font-size: 1rem; }
  }

  @media (max-width: 960px) {
    .remote-on { grid-template-columns: minmax(0, 1fr); }
    .mail-views { grid-template-columns: minmax(0, 1fr); }
    .hero-copy { grid-template-columns: minmax(0, 1fr); row-gap: var(--space-5); }
    .roll-list { grid-template-columns: minmax(0, 1fr); }
    .roll-step, .roll-step + .roll-step { padding: var(--space-4) 0; border-left: 0; }
    .roll-step + .roll-step { border-top: 1px solid var(--rule); }
    .colophon-inner { grid-template-columns: minmax(0, 1fr); }
    .scan-grid { grid-template-columns: minmax(0, 1fr); }
    .figures { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .you-type { grid-template-columns: minmax(0, 1fr) 8rem; }
    .you-type .button, .you-type [data-me-submit] { grid-column: 1 / -1; grid-row: 3; justify-self: start; }
    .search { flex-basis: 100%; max-width: none; }
    .sheet-tools { gap: var(--space-3); }
    .sheet-filters { width: 100%; display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: var(--space-2); }
    .sheet-filters .chip { min-height: 2.5rem; padding: 0 var(--space-2); font-size: 0.875rem; }
    .class-head { grid-template-columns: minmax(0, 1fr); }
    .class-more { grid-template-columns: minmax(0, 1fr); padding: var(--space-5); }
    .class-more-art { display: none; }
    .credit { grid-template-columns: clamp(64px, 18vw, 92px) minmax(0, 1fr); justify-content: center; }
    .credits { max-width: 26rem; margin-inline: auto; }
  }
  @media (max-width: 640px) {
    /* A button on its own spans the screen; small ones sit in rows with others. */
    .button:not(.button-small, .proof-grid .button, .admin-table .button) { width: 100%; }
    form:has(> .button:only-of-type) { justify-self: stretch; }
    .masthead-nav { gap: var(--space-4); }
    .strip-hero { grid-auto-columns: 112px; }
    .frames { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .proof-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .field-row { grid-template-columns: minmax(0, 1fr); }
    .you:has(.you-print) { grid-template-columns: 5.5rem minmax(0, 1fr); column-gap: var(--space-4); padding: var(--space-4); }
    .find-result { grid-template-columns: minmax(0, 1fr); }
    .key-item { grid-template-columns: 1.25rem 2.5rem minmax(0, 1fr) auto; }
    .key-me { grid-column: 3 / -1; }
    .report-head { grid-template-columns: 5rem minmax(0, 1fr); gap: var(--space-4); }
    .report-print { width: 5rem; }
    .admin-table { display: block; overflow-x: auto; }
    .camera, .find-still { border-width: 4px; }
    /* A tall phone picture would push the shutter below the screen: the preview is kept to about
       half the screen's height, and the frame shrinks to fit it. */
    .camera { width: fit-content; max-width: 100%; margin-inline: auto; }
    .camera video { width: auto; max-width: 100%; max-height: 52svh; }
    .stepper { padding-top: var(--space-3); }
    .remote, .hint-drop { display: none !important; }
    .panel { padding: var(--space-4); }
    .field-narrow { max-width: none; }
    .stepper { grid-template-columns: repeat(4, minmax(0, 1fr)); padding-bottom: 1.6rem; position: relative; }
    .stepper .step-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
    .stepper .is-on .step-label { left: 0; bottom: 0; width: auto; height: auto; overflow: visible; clip-path: none; }
    .stepper a { position: static; }
    /* The current step's name sits under the whole stepper here, so the bars are plain borders. */
    .stepper li { position: static; }
    .stepper li::before { display: none; }
    .stepper .is-done { border-top-color: var(--film); }
    .stepper .is-on { border-top-color: var(--marker-yellow); }
    .phone-steps { grid-template-columns: repeat(3, minmax(0, 1fr)); padding-bottom: 0; }
    .phone-steps .step-label, .phone-steps .is-on .step-label { position: static; width: auto; height: auto; overflow: visible; clip-path: none; }
    .obit { grid-template-columns: minmax(0, 1fr); }
    .obit-print { max-width: 200px; }
    .enlargement { padding: var(--space-4); }
    .you { padding: var(--space-4); }
  }
}

@layer utilities {
  .visually-hidden {
    position: absolute !important;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .skip { position: absolute; left: -999px; top: 0; }
  .skip:focus { left: var(--space-4); top: var(--space-4); z-index: 10; background: var(--film); color: var(--paper); padding: var(--space-2) var(--space-4); }
}
