/* Storyboard wall — S2: chrome + motion system. Scenes are still placeholders (art lands S3/S4).
   Motion rule (M3): no opacity transitions anywhere in this file — things are
   drawn (clip wipe, upgraded to true stroke animation in S4), stamped, slid, or cut. */

/* Self-hosted fonts — no third-party requests (same rule as the main site). */
/* latin-ext */
@font-face {
  font-family: 'Caveat';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url(../fonts/Caveat-normal-400-700-latin-ext.woff2) format('woff2');
  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;
}
/* latin */
@font-face {
  font-family: 'Caveat';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url(../fonts/Caveat-normal-400-700-latin.woff2) format('woff2');
  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;
}
/* latin-ext */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(../fonts/IBMPlexMono-normal-400-latin-ext.woff2) format('woff2');
  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;
}
/* latin */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(../fonts/IBMPlexMono-normal-400-latin.woff2) format('woff2');
  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;
}
/* latin-ext */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(../fonts/IBMPlexMono-normal-500-latin-ext.woff2) format('woff2');
  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;
}
/* latin */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(../fonts/IBMPlexMono-normal-500-latin.woff2) format('woff2');
  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;
}
/* latin-ext */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url(../fonts/Newsreader-normal-300-700-latin-ext.woff2) format('woff2');
  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;
}
/* latin */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url(../fonts/Newsreader-normal-300-700-latin.woff2) format('woff2');
  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;
}
/* latin-ext */
@font-face {
  font-family: 'Newsreader';
  font-style: italic;
  font-weight: 300 700;
  font-display: swap;
  src: url(../fonts/Newsreader-italic-300-700-latin-ext.woff2) format('woff2');
  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;
}
/* latin */
@font-face {
  font-family: 'Newsreader';
  font-style: italic;
  font-weight: 300 700;
  font-display: swap;
  src: url(../fonts/Newsreader-italic-300-700-latin.woff2) format('woff2');
  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;
}

:root {
  --wall: #d9d3c4;
  --paper: #efeadd; /* a visited (inked) sheet */
  --paper-un: #e8e2d3; /* an unvisited sheet — duller, not broken */
  --line: #b3ab97;
  --ink: #2e2b24;
  /* 3.4:1 on paper. At the old #8f8a7a it was 2.6:1, which read as a broken
     drawing rather than an unexplored one. Do not darken further — that would
     eat the difference the inking has to show. */
  --pencil: #7d7868;
  --accent: #e05206; /* safety orange — the one accent */
  --tape: rgba(226, 211, 172, 0.85);
  --serif: 'Newsreader', ui-serif, Georgia, serif;
  --mono: 'IBM Plex Mono', ui-monospace, Consolas, monospace;
  --hand: 'Caveat', 'Segoe Script', cursive;
  --glide: 900ms cubic-bezier(0.22, 0.9, 0.24, 1);
  --card: 480ms cubic-bezier(0.22, 0.9, 0.24, 1);
  --slide: 420ms cubic-bezier(0.22, 0.9, 0.24, 1);
}

* { margin: 0; box-sizing: border-box; }

html, body { background: var(--wall); }

/* paper grain: procedural, self-contained, ~zero bytes */
body {
  font-family: var(--serif);
  color: var(--ink);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='g'><feTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.18  0 0 0 0 0.16  0 0 0 0 0.12  0 0 0 0.07 0'/></filter><rect width='180' height='180' filter='url(%23g)'/></svg>");
}

/* ---------- the wall (the camera transforms this, nothing else) ---------- */

.wall {
  max-width: 1180px;
  margin: 0 auto;
  padding: clamp(16px, 3vw, 40px);
  transform-origin: 0 0;
  transition: transform var(--glide);
}

.wall-header { margin-bottom: clamp(16px, 2.5vw, 32px); }


.wall-header h1 {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 420;
  font-size: clamp(20px, 2.5vw, 28px);
}

.hint {
  font-family: var(--hand);
  font-size: 17px;
  color: var(--pencil);
  margin-top: 4px;
}

/* the hint is hidden once a frame has been opened, never removed — pulling the
   node destroys it for screen readers for the rest of the session */
.hint.is-hidden { visibility: hidden; }

.play {
  margin-top: 10px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink);
  background: none;
  border: 1px solid var(--line);
  padding: 5px 10px;
  cursor: pointer;
}

.play:hover { border-color: var(--ink); }

.frames {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(330px, 100%), 1fr));
  gap: clamp(16px, 2.2vw, 30px);
}

/* ---------- panels ---------- */

/* The state lives in the paper, not only in the stroke colour: an unvisited
   frame is a duller sheet, so it reads as unlit rather than broken (M2). */
.panel {
  position: relative;
  aspect-ratio: 4 / 3;
  background: var(--paper-un);
  color: var(--pencil); /* pencil state until inked */
  border: 1px solid var(--line);
  box-shadow: 0 2px 5px rgba(46, 43, 36, 0.22);
  cursor: pointer;
  outline-offset: 3px;
  transition: transform var(--glide);
}

.panel.is-inked {
  background: var(--paper);
  color: var(--ink);
  border-color: var(--ink);
  --pa: var(--accent);
}

/* taped at slightly imperfect angles; the active frame straightens under the camera */
#frame-1 { transform: rotate(0.5deg); }
#frame-2 { transform: rotate(-0.4deg); }
#frame-3 { transform: rotate(0.7deg); }
#frame-4 { transform: rotate(-0.6deg); }
#frame-5 { transform: rotate(0.4deg); }
#frame-6 { transform: rotate(-1.6deg); border-style: dashed; } /* crooked — it isn't finished */

/* frame 6 never inks, so its one accent element is orange from the start: the
   pencil, and the only orange mark on an unvisited wall (DECISIONS.md ruling 1) */
#frame-6 { --pa: var(--accent); }

.panel.is-active { transform: rotate(0deg) !important; z-index: 5; cursor: default; }

/* tape corners — frames 01 and 06 only; the rest sit on the wall unaided */
#frame-1::before,
#frame-1::after,
#frame-6::before,
#frame-6::after {
  content: '';
  position: absolute;
  top: -9px;
  width: 52px;
  height: 20px;
  background: var(--tape);
  box-shadow: 0 1px 2px rgba(46, 43, 36, 0.15);
}
#frame-1::before { left: 10%; transform: rotate(-4deg); }
#frame-1::after { right: 10%; transform: rotate(3deg); }
#frame-6::before { left: 10%; transform: rotate(5deg); }
#frame-6::after { right: 10%; transform: rotate(-3deg); }

/* ---------- scenes: two sketch layers per panel, parallax-driven (S3 placeholder art) ----------
   All line work strokes in currentColor, so the panel's pencil->ink color IS the
   art's state (M2). Accent elements (.a/.a-fill) stay graphite until inked. */

/* The drawing owns the whole frame. inset:3% is a 4:3 box, the same ratio as the
   viewBox, so the art fills it edge to edge. The old 3% 0 25% 0 band was ~1.85:1
   against that viewBox, which left ~27% of every panel's width as empty gutter. */
.scene { position: absolute; inset: 3%; overflow: visible; pointer-events: none; }

.scene svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* hover parallax (depth 1): fg drifts more than bg. 18px, up from 14px — at
   14px the depth was barely perceptible on a 4:3 panel. */
.scene .bg { transform: translate(calc(var(--px, 0) * 4px), calc(var(--py, 0) * 4px)); transition: transform 150ms linear; }
.scene .fg { transform: translate(calc(var(--px, 0) * 18px), calc(var(--py, 0) * 18px)); transition: transform 150ms linear; }
.panel.is-active .scene .bg,
.panel.is-active .scene .fg { transform: none; }

.scene .a { stroke: var(--pa, currentColor); }
.scene .a-fill { fill: var(--pa, currentColor); stroke: none; font-family: var(--mono); }

/* text sits above the sketch */
.title-block, .note, .send-frame { z-index: 1; }

/* inking draws the accent layer in — stroke by stroke, never a fade (M2 + M3) */
.panel.is-inked .scene .a { stroke-dasharray: 1; animation: ink-draw 700ms ease-out 250ms both; }

@keyframes ink-draw {
  from { stroke-dashoffset: 1; }
  to { stroke-dashoffset: 0; }
}

/* Frame 6 stays pencil forever — it isn't finished yet. The dashed border and
   the accent pencil are set on #frame-6 above; the class is the JS's hook. */

/* the title block says WHERE, not which revision — "REV C" told a visitor nothing */
.title-block {
  position: absolute;
  top: 5.5%;
  left: 6%;
  font-family: var(--mono);
  font-size: 8px;
  font-weight: 500;
  letter-spacing: 0.06em;
  /* the drawing now runs under it, so it carries its own paper veil */
  background: rgba(239, 234, 221, 0.7);
  padding: 1px 3px;
}

.panel.is-active .title-block { font-size: 3.4px; } /* ~11px landed */

/* ---------- the sequence: corner numerals and continuity arrows ----------
   On an unvisited panel the numeral is the darkest mark on the sheet. It reads
   as printed on the paper rather than drawn on it, so it never competes with
   the pencil — and it is what makes six frames read as an ordered reel. */

.num {
  position: absolute;
  top: 3.5%;
  right: 5.5%;
  font: 26px/1 var(--mono);
  letter-spacing: 0.02em;
  color: var(--line);
}

.panel.is-inked .num { color: var(--pencil); }
.panel.is-active .num { font-size: 11px; }

/* the arrow lives in the grid gap, so it survives three-up -> two-up -> one-up */
.cont {
  position: absolute;
  top: 32%;
  right: -30px;
  width: 26px;
  height: 16px;
  color: var(--line);
}

.cont svg {
  width: 100%;
  height: 100%;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.frames .panel:last-child .cont { display: none; }
.panel.is-active .cont { display: none; }

/* ---------- the caption card ----------
   On the wall it carries the title and dateline only. Entering a frame keeps it
   rising until it is the page — 88% of the panel, laid over the drawing rather
   than beside it. Type inside is authored in LOCAL px, which the camera
   multiplies by ~3.2 on a 1400x900 screen; landed sizes are in the comments. */

.caption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 26%;
  display: flex;
  flex-direction: column;
  padding: 0 6% 5%;
  font-size: 4.4px; /* the em basis for everything inside */
  background: var(--paper-un);
  transition: height var(--card);
}

/* the visited state reaches the caption too, not just the stroke */
.panel.is-inked .caption { background: var(--paper); }

.panel.is-active .caption {
  height: 88%;
  padding: 2.4% 6% 3%;
  font-size: 5.4px; /* body copy lands at ~17px */
  border-top: 1px solid currentColor;
  background: rgba(239, 234, 221, 0.92); /* the drawing shows through */
}

/* the title row: on the wall it is parked on the bottom edge by the hidden
   sheet above it; at zoom it becomes the head of the sheet */
.head { display: flex; align-items: flex-end; gap: 10px; margin-top: auto; }
.panel.is-active .head { order: 0; margin-top: 0; align-items: baseline; }

.head h2 { font-size: 15px; font-weight: 550; line-height: 1.15; }

.head .dateline { font-family: var(--mono); font-size: 8.5px; margin-top: 3px; }

/* ---------- depth 1: hover reveals — drawn and stamped, never faded (M3) ---------- */

.note {
  position: absolute;
  top: 15%;
  left: 6%;
  width: fit-content;
  max-width: 62%;
  font-family: var(--hand);
  font-size: 15px;
  line-height: 1.25;
  visibility: hidden;
  /* handwriting sits on the sketch — a paper veil keeps it legible over line work */
  background: rgba(239, 234, 221, 0.82);
  padding: 1px 5px;
}

/* the stamp rides the caption's title row, pushed out to its right edge */
.stamp {
  margin-left: auto;
  font-family: var(--mono);
  font-size: 8px;
  font-weight: 500;
  letter-spacing: 0.08em;
  color: var(--accent);
  border: 1.5px solid var(--accent);
  padding: 2px 6px;
  transform: rotate(-2deg);
  visibility: hidden;
  white-space: nowrap;
}

/* the note is drawn on, once per panel per visit — the class stays, so
   re-hovering never replays it */
.note.is-drawn {
  visibility: visible;
  animation: draw-in 600ms ease-out both;
}

/* The stamp is EARNED: it lands when the frame inks, not on hover. It then
   records where the visitor has been — the inking idea told twice. Frame 6
   never inks, so it never stamps. */
.panel.is-inked .stamp {
  visibility: visible;
  animation: stamp-in 320ms cubic-bezier(0.2, 0.8, 0.3, 1.1) both;
}

/* "drawn": a left-to-right wipe standing in for the S4 stroke animation */
@keyframes draw-in {
  from { clip-path: inset(-8% 100% -8% -2%); }
  to { clip-path: inset(-8% -2% -8% -2%); }
}

/* "slid": the sheet arrives from below the card's edge */
@keyframes card-up {
  from { transform: translateY(46%); }
  to { transform: translateY(0); }
}

/* "stamped": arrives big, thumps down, settles at its 2° cant */
@keyframes stamp-in {
  0% { transform: scale(2.1) rotate(-9deg); }
  65% { transform: scale(0.94) rotate(-1deg); }
  100% { transform: scale(1) rotate(-2deg); }
}

/* ---------- depth 2: zoom-only content, cut in when the camera arrives ---------- */

/* At zoom the drawing does not move — it becomes the ground, and the caption
   card rises over it. The top 12% of the panel stays clear as a title strip:
   title block on the left, the handwritten note beside it. */
.panel.is-active .note { top: 4.6%; left: 32%; max-width: 38%; font-size: 5.2px; }

/* the sheet fills the card under the title row. On the wall it is hidden but
   still a flex child, which is what parks the title row on the bottom edge. */
.detail {
  visibility: hidden;
  flex: 1;
  min-height: 0;
  overflow: hidden;
  order: -1;
  margin-bottom: 3%;
}

.panel.is-active .detail {
  visibility: visible;
  order: 1;
  margin: 2.2% 0 0;
  display: flex;
  gap: 5%;
  animation: card-up var(--slide) both; /* the sheet slides in; it never fades */
}

/* the story column, and the reference column that stays put per frame */
.sheets { flex: 1; min-width: 0; height: 100%; overflow: hidden; }

.ref {
  flex: 0 0 27%;
  border-left: 1px dotted currentColor;
  padding-left: 4%;
  display: flex;
  flex-direction: column;
  gap: 1.2em;
}

.ref-label { font-family: var(--mono); font-size: 0.66em; letter-spacing: 0.12em; opacity: 0.7; }
.ref .pull { margin: 0; font-family: var(--hand); font-size: 1.55em; line-height: 1.12; }
.ref .elsewhere { margin-top: auto; }
.ref .elsewhere .ref-label { margin-bottom: 0.5em; }
.ref .elsewhere p { font-family: var(--mono); font-size: 0.76em; line-height: 1.85; display: flex; flex-direction: column; }
/* a prose note in the reference column, where the frame has something to credit
   rather than somewhere to send you */
.ref p.ref-note,
.ref .elsewhere p.ref-note {
  font-family: var(--serif);
  font-size: 0.8em;
  line-height: 1.5;
  margin: 0.4em 0 0;
  display: block;
}
.ref .todo {
  margin: 0;
  font-family: var(--mono);
  font-size: 0.66em;
  line-height: 1.6;
  border: 1px dashed currentColor;
  padding: 0.6em 0.7em;
  opacity: 0.75;
}

/* the plate number and what follows it — the sheet's footer rule */
.plate-foot {
  visibility: hidden;
  order: 2;
  margin-top: auto;
  padding-top: 1.4%;
  border-top: 1px dotted currentColor;
  display: flex;
  font-family: var(--mono);
  font-size: 0.66em;
  letter-spacing: 0.06em;
  opacity: 0.8;
}

.plate-foot > :last-child { margin-left: auto; }
.panel.is-active .plate-foot { visibility: visible; }

/* the footer said "CONTINUES -> 02" and did nothing; it is the control it
   already claimed to be, and it carries the accent because it is a link */
.plate-next {
  font: inherit;
  letter-spacing: inherit;
  color: var(--accent);
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}
/* on the title row the stamp shares a line with the title, so it runs a size
   smaller there than it does on the wall */
.panel.is-active .stamp { font-size: 3.8px; border-width: 0.6px; padding: 1.5px 4px; }

.panel.is-active .head h2 { font-size: 8px; } /* ~26px landed */
.panel.is-active .head .dateline { font-size: 4.4px; } /* ~14px landed */

/* folder tabs, riding the card's top edge */
.tabs {
  position: absolute;
  top: -11px;
  left: 6%;
  right: 6%;
  display: flex;
  gap: 3px;
  visibility: hidden;
}

.panel.is-active .tabs { visibility: visible; }

.tab {
  font-family: var(--mono);
  font-size: 0.84em;
  color: inherit;
  background: none;
  border: 1px solid currentColor;
  border-bottom: none;
  border-radius: 3px 3px 0 0;
  padding: 2px 6px 3px;
  cursor: pointer;
  opacity: 0.55; /* static weight, not a transition — unselected tabs read as behind */
}

.tab[aria-selected="true"] {
  opacity: 1;
  color: var(--accent);
  border-color: var(--accent);
  font-weight: 500;
}

/* Everything below is sized in em from the card's own font-size, so one
   property drives the whole sheet. The card is 5.4px local, ~17px landed. */

.sheet {
  height: 100%;
  overflow-y: auto;
  scrollbar-width: thin;
  display: flex;
  flex-direction: column;
}

.sheet[hidden] { display: none; }
.sheet p { font-size: 1em; line-height: 1.55; margin: 0; }
.sheet p + p { margin-top: 0.85em; }

/* The rows used to stretch (flex:1, min-height 2.4em) to fill the column, back
   when a sheet was one paragraph and a list. With two paragraphs and a figure
   there is nothing to pad out, and stretched rows just held the entries apart —
   so they sit at their natural height and the slack falls at the foot. */
.rows { list-style: none; padding: 0; margin: 1em 0 0; display: flex; flex-direction: column; }

.rows li {
  display: flex;
  gap: 7px;
  padding: 0.34em 0;
  align-items: baseline;
  border-bottom: 1px dotted currentColor;
}

.rows li:last-child { border-bottom: none; }
.rows .k { flex: 0 0 18%; font-family: var(--mono); font-size: 0.73em; line-height: 1.4; opacity: 0.75; }
.rows .v { flex: 1; font-size: 0.84em; line-height: 1.4; }
.rows .v b { font-weight: 600; color: var(--accent); }

/* The numbers follow the copy. They used to be pinned to the footer rule with
   margin-top:auto, which worked while a .rows list (flex:1) filled the space
   above them; without one that auto margin opens the very void the two-column
   sheet exists to close. Where rows are present they still do the filling. */
.facts { list-style: none; padding: 0; margin: 1.4em 0 0; display: flex; gap: 14px; }
.facts li { display: flex; flex-direction: column; }
.facts b { font-family: var(--mono); font-size: 1.95em; font-weight: 500; color: var(--accent); line-height: 1.1; }
.facts span { font-size: 0.71em; line-height: 1.3; max-width: 15ch; }

.links { margin: 6px 0 0; font-family: var(--mono); font-size: 0.82em; display: flex; gap: 12px; }
.links a { color: var(--accent); text-underline-offset: 2px; }

/* Self-hosted photographs and UI screenshots, per the 2026-08-14 reversal of
   DECISIONS.md ruling 2. Content only — the six drawings stay inline SVG. The
   plate border and mono caption keep them reading as pinned reference material
   rather than as web imagery. Nothing here fades (M3). */
.shots { display: flex; gap: 4%; margin: 1.1em 0 0; }
.shots .shot { flex: 1; min-width: 0; margin: 0; }

/* The story column is short — the card shares it with the title row, the tabs
   and the plate footer. A full-width photograph is several times its height, so
   the figure is scaled down rather than cropped: the collages and the four-panel
   render sheet lose nothing, and the sheet's own overflow handles the rest. */
.shot {
  max-width: 38%;
  margin: 1.1em 0 0;
  border: 1px solid currentColor;
  background: var(--paper-un);
}

.shots .shot { max-width: none; }

.panel.is-inked .shot { background: var(--paper); }

.shot img {
  display: block;
  width: 100%;
  height: auto;
  /* the drawings are line work; a photograph next to them wants the same
     restraint, so it is desaturated a touch rather than left at full chroma */
  filter: saturate(0.82) contrast(1.02);
}


/* ---------- frame 6: the real pencil (M4) ---------- */

/* the card stops at 30% while the visitor is sketching, so the drawing surface
   stays clear and clickable; switching to "Write me" retires the surface and
   lets the full-height sheet take the frame */
#frame-6.is-active:not(.canvas-off) .caption { height: 30%; font-size: 4.6px; }
/* at 30% there is only room for the story, so the reference column stands down */
#frame-6.is-active:not(.canvas-off) .ref { display: none; }
/* .is-active also sets display on these two and would otherwise win the tie on
   source order — the extra class keeps "Write me" clear of the drawing area */
#frame-6.canvas-off.is-active .ask,
#frame-6.canvas-off.is-active .written,
#frame-6.canvas-off.is-active .send-frame { display: none; }

/* The empty frame is completed by writing in it, not by drawing in it: one
   line, one button, and the mail is pre-written. Drawing meant download, open
   mail, attach - four steps asked of a stranger. Geometry is the drawn panel's:
   viewBox 102-342 x, 46-192 y of 400x300. */
.ask, .written { display: none; }

#frame-6.is-active .ask,
#frame-6.is-active.is-written .written {
  display: flex;
  position: absolute;
  top: 19%;
  left: 28.5%;
  width: 53%;
  height: 41%;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 0 4%;
  z-index: 1;
}

#frame-6.is-active.is-written .ask { display: none; }

.ask label { font-family: var(--hand); font-size: 5.5px; color: var(--pencil); } /* ~18px landed */

.ask input {
  width: 100%;
  margin: 3px 0 5px;
  font-family: var(--hand);
  font-size: 8px; /* ~26px landed */
  line-height: 1.25;
  color: var(--ink);
  text-align: center;
  background: none;
  border: none;
  border-bottom: 0.5px solid var(--line);
  padding: 1px 2px 2px;
}

.ask input::placeholder { color: var(--line); }
.ask input:focus { outline: none; border-bottom-color: var(--accent); }

.ask button {
  font-family: var(--mono);
  font-size: 4.4px; /* ~14px landed */
  letter-spacing: 0.06em;
  color: var(--accent);
  background: none;
  border: 0.5px solid var(--accent);
  padding: 2.5px 6px;
  cursor: pointer;
}

.ask button:hover { background: rgba(224, 82, 6, 0.08); }

/* their line, now part of the drawing - wiped in, never faded */
.written {
  margin: 0;
  font-family: var(--hand);
  font-size: 9px; /* ~29px landed */
  line-height: 1.24;
  color: var(--ink);
  animation: draw-in 700ms ease-out both;
}

/* the wall's one unfinished frame is finished by the visitor, so it inks */
#frame-6.is-written { background: var(--paper); color: var(--ink); border-style: solid; border-color: var(--ink); }

/* the way to send it is earned by writing the line, not offered before it */
.send-frame {
  margin-left: auto;
  visibility: hidden;
  font-family: var(--hand);
  text-align: right;
}

#frame-6.is-written.is-active .send-frame,
#frame-6.is-written.is-pinned .send-frame {
  visibility: visible;
  animation: draw-in 500ms ease-out both;
}

.send-btn {
  display: inline-block;
  text-decoration: none;
  font-family: var(--hand);
  font-size: 11px;
  color: var(--accent);
  background: none;
  border: none;
  border-bottom: 1px solid var(--accent);
  padding: 0 2px 1px;
  cursor: pointer;
}


/* ---------- camera state ---------- */

html.is-zoomed body { overflow: hidden; }
html.is-zoomed .site-footer { visibility: hidden; }
html.is-zoomed .wall { cursor: zoom-out; }

/* the focus ring lives inside the camera transform, so divide the zoom back
   out — otherwise a 2px ring reads as a 7px orange frame at full magnification */
.panel:focus-visible {
  outline: calc(2px / var(--cam-scale, 1)) solid var(--accent);
  outline-offset: calc(3px / var(--cam-scale, 1));
}

/* ---------- fixed chrome (not on the wall, so not transformed) ---------- */

/* the roll's bar exists only below 720px, where the camera is replaced by travel */
.mobile-bar { display: none; }

.cam-nav { display: none; }

html.is-zoomed .cam-nav { display: block; }

.cam-nav button {
  position: fixed;
  font-family: var(--mono);
  font-size: 22px;
  line-height: 1;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line);
  width: 40px;
  height: 40px;
  cursor: pointer;
}

.cam-nav button:disabled { color: var(--line); cursor: default; }

.cam-nav [data-cam="prev"] { left: 12px; top: 50%; margin-top: -20px; }
.cam-nav [data-cam="next"] { right: 12px; top: 50%; margin-top: -20px; }
.cam-nav [data-cam="close"] { right: 12px; top: 12px; font-size: 16px; }

.site-footer {
  max-width: 1180px;
  margin: 0 auto;
  padding: 10px clamp(16px, 3vw, 40px) 28px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--pencil);
  display: flex;
  gap: 18px;
}

.site-footer a { color: inherit; }

/* ---------- mobile (<=720px): the camera is replaced by travel ----------
   The computed camera scale on a phone was about 1.002 — magnifying nothing
   while costing everything. So the wall becomes a roll: tapping a frame pins
   it under a 44px bar and the rest of the roll slides out from under it.
   Nothing scales anywhere in here. */

@media (max-width: 720px) {
  .wall { max-width: 430px; margin: 0 auto; padding: 0; }
  .frames { display: flex; flex-direction: column; gap: 22px; padding: 18px 16px 40px; }

  /* the camera's chrome belongs to the desktop only */
  .cam-nav { display: none !important; }
  .cont { display: none; } /* the roll runs top-to-bottom, not left-to-right */

  /* scroll drives the parallax, because hover does not exist on touch */
  .scene .bg { transform: translateY(calc(var(--sy, 0) * 4px)); }
  .scene .fg { transform: translateY(calc(var(--sy, 0) * 14px)); }

  /* the roll's own cards: a 358px panel is not a 4:3 thumbnail on a wall of
     six, it is the width of the screen, so its labels are sized to be read */
  .head h2 { font-size: 17px; }
  .head .dateline { font-size: 10px; }
  .title-block { font-size: 9px; }
  .note { font-size: 16px; }

  .mobile-bar {
    position: sticky;
    top: 0;
    z-index: 9;
    height: 44px;
    background: var(--paper);
    border-bottom: 1px solid var(--ink);
    display: none;
    align-items: center;
    gap: 12px;
    padding: 0 12px;
    font-family: var(--mono);
    font-size: 13px;
  }

  .mobile-bar button {
    background: none;
    border: none;
    color: var(--ink);
    cursor: pointer;
    font: inherit;
    min-width: 44px;
    height: 44px;
  }

  .mobile-bar button:disabled { color: var(--line); }
  .mobile-bar .bar-close { margin-left: auto; min-width: 0; }

  /* a pinned frame IS the page: the other five stand down */
  .wall.has-pin .mobile-bar { display: flex; }
  .wall.has-pin .wall-header { display: none; }
  .wall.has-pin .panel:not(.is-pinned) { display: none; }
  .wall.has-pin .frames { padding-top: 0; }

  /* the tape angles are set per id, which outranks a class — the pinned frame
     is the page here, so it has to sit square */
  .panel.is-pinned { aspect-ratio: auto; transform: rotate(0deg) !important; cursor: default; }
  .panel.is-pinned .scene { position: relative; inset: auto; height: 268px; }

  .panel.is-pinned .caption {
    position: relative;
    height: auto;
    font-size: 15px;
    padding: 0 16px 22px;
    background: none;
    border-top: 1px solid currentColor;
  }

  /* The card reads top-down here: title, then the section menu, then the story.
     .detail carries order:-1 on the wall (it is what parks the title row on the
     bottom edge); left alone that floats the body copy above both. */
  .panel.is-pinned .detail { visibility: visible; display: block; overflow: visible; order: 1; margin: 16px 0 0; }
  .panel.is-pinned .sheets, .panel.is-pinned .sheet { height: auto; overflow: visible; }
  .panel.is-pinned .head { order: -1; margin-top: 14px; align-items: flex-end; }
  .panel.is-pinned .head h2 { font-size: 19px; }
  .panel.is-pinned .head .dateline { font-size: 13px; }
  .panel.is-pinned .note {
    position: static;
    visibility: visible;
    margin: 12px 0 0;
    max-width: none;
    font-size: 17px;
    background: none;
    padding: 0;
  }
  .panel.is-pinned .num { font-size: 26px; top: 10px; right: 14px; }
  .panel.is-pinned .title-block { font-size: 11px; top: 14px; }
  .panel.is-pinned .stamp { font-size: 11px; border-width: 1.5px; padding: 3px 7px; }

  /* Every section visible at once — the row WRAPS, it never scrolls. It also
     rides under the 44px bar, so the menu stays reachable however far down the
     sheet you have scrolled; the artwork alone is 268px of travel. The negative
     margins let the paper bleed to the panel edge while it is stuck. */
  .panel.is-pinned .tabs {
    position: sticky;
    top: 44px;
    z-index: 8;
    order: 0;
    visibility: visible;
    display: flex;
    flex-wrap: wrap;
    gap: 0;
    overflow: visible;
    margin: 14px -16px 0;
    padding: 0 16px;
    background: var(--paper-un);
    border-bottom: 1px solid var(--line);
  }

  .panel.is-inked.is-pinned .tabs { background: var(--paper); }

  .panel.is-pinned .tab {
    height: 44px;
    flex: 0 0 auto;
    padding: 0 12px;
    font-size: 14px;
    border: none;
    border-radius: 0;
    border-bottom: 2px solid transparent;
    opacity: 1;
    white-space: nowrap;
    color: var(--ink);
  }

  /* five sections have to fit two rows without a horizontal gesture */
  .panel.is-pinned .tabs[data-count="5"] .tab { padding: 0 8px; font-size: 13px; }
  .panel.is-pinned .tab[aria-selected="true"] { color: var(--accent); border-bottom-color: var(--accent); font-weight: 500; }

  /* the reference column folds under the story */
  .panel.is-pinned .ref {
    flex: none;
    border-left: none;
    border-top: 1px dotted currentColor;
    padding: 16px 0 0;
    margin-top: 18px;
  }

  /* There is no camera here to multiply the local pixels, so everything carries
     a real phone size. Nothing below 12px: the sheet is meant to be read, and
     the 9-11px labels the camera scale implies are unusable on glass. */
  .panel.is-pinned .plate-foot { visibility: visible; font-size: 12px; margin-top: 18px; align-items: center; }
  /* a 44px target: on a phone this is the main way forward through the roll */
  .panel.is-pinned .plate-next {
    min-height: 44px;
    display: flex;
    align-items: center;
    padding: 0 2px 0 16px;
    font-size: 14px;
  }
  .panel.is-pinned .ref-label { font-size: 12px; }
  .panel.is-pinned .ref .pull { font-size: 22px; }
  .panel.is-pinned .ref .elsewhere p { font-size: 14px; line-height: 2; }
  .panel.is-pinned .ref .todo { font-size: 12px; }
  .panel.is-pinned .ref .ref-note { font-size: 14px; }
  /* the pinned sheet flows down the page, so nothing has to be kept short here:
     the figures take the full column instead of the 38% the zoomed card needs */
  .panel.is-pinned .shot { max-width: none; }
  /* two shots side by side are ~160px wide on a phone — stack them instead */
  .panel.is-pinned .shots { display: block; }
  .panel.is-pinned .shots .shot { margin-top: 1.1em; }
  .panel.is-pinned .sheet p { font-size: 16px; }
  .panel.is-pinned .rows li { min-height: 0; flex: none; padding: 6px 0; }
  .panel.is-pinned .rows .k { font-size: 12px; flex-basis: 27%; }
  .panel.is-pinned .rows .v { font-size: 14px; }
  .panel.is-pinned .facts b { font-size: 22px; }
  .panel.is-pinned .facts span { font-size: 12px; max-width: 14ch; }
  .panel.is-pinned .links { font-size: 14px; gap: 16px; }

  /* frame 6's ask, in its own artboard - here the box IS the empty frame */
  #frame-6.is-pinned .ask,
  #frame-6.is-pinned.is-written .written {
    position: static;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    width: 100%;
    height: auto;
    margin-top: 14px;
    padding: 26px 16px;
    border: 1px solid currentColor;
  }

  #frame-6.is-pinned.is-written .ask { display: none; }
  #frame-6.is-pinned .ask label { font-size: 17px; }
  /* 19px, never under 16: iOS zooms the page when a focused input is smaller */
  #frame-6.is-pinned .ask input { font-size: 19px; margin: 8px 0 14px; border-bottom-width: 1px; padding: 4px; }
  #frame-6.is-pinned .ask button { font-size: 13px; padding: 12px 16px; border-width: 1px; }
  #frame-6.is-pinned .written { font-size: 21px; }

  #frame-6.is-pinned .scene { display: none; }
  #frame-6.canvas-off.is-pinned .ask,
  #frame-6.canvas-off.is-pinned .written { display: none; }
  .panel.is-pinned .send-frame { margin: 12px 0 0; text-align: left; }
  .send-btn { font-size: 19px; }
}

/* ---------- reduced motion: the camera cuts, notes appear pre-drawn ---------- */

@media (prefers-reduced-motion: reduce) {
  .wall, .panel, .caption { transition: none; }
  .note, .stamp, .send-frame, .detail, .panel.is-inked .scene .a { animation: none !important; }
  .scene .bg, .scene .fg { transition: none; } /* JS also skips parallax entirely */
}
