/* ==========================================================================
   TELL — chapter-map.css · THE CASE WALL (results) + THE CASE FILE (select)
   ==========================================================================
   design/50-ui-redress.md §2. Both screens are painted paper objects: a cork
   investigation wall and a drawer of manila folders. Every plate under
   assets/ui/ is BLANK — every word here is runtime type drawn over the top.

   Plate geometry (measured off the alpha channels, not guessed):
     card-face / card-back  640x420, card body x 98–542, y 48–370  →  the body
       is centred, so cropping to it is background-size 144.1% 130.4% / centre,
       and the element's own aspect ratio is 444/322.
     receipt                420x900, strip x 114–277, full height  →  257.7%
       101.4% at 44.35% 100%; the element is squashed to 163/600 so a receipt
       that would otherwise run 1000px tall fits beside a board.
     pin-sprites            5x2 grid of cut-outs: background-size 500% 200%,
       cells at 0/25/50/75/100% x and 0/100% y. Six brass pins, four clips.
     folder / folder-open   900x640, tab x 530–740 y 48–100, face x 148–760
       y 85–570; painted on their own dark desk, so they are feathered into the
       ground with a mask instead of composited.

   The palette law holds: ONE saturated element per screen, and it is the red
   thread (and the stamp that shares its ink). The four buckets are INKED, not
   coloured — no gold/blue/slate legend competing with the thread, and nothing
   anywhere near a choice that could read as right or wrong.
   ========================================================================== */

#chapter-map {
  position: fixed;
  inset: 0;
  z-index: 60;
  overflow-y: auto;
  overscroll-behavior: contain;
  background:
    radial-gradient(120% 70% at 50% -10%, rgba(74, 53, 36, 0.35), transparent 62%),
    radial-gradient(90% 60% at 50% 110%, rgba(11, 18, 32, 0.9), transparent 70%),
    var(--pp-ink, #0b1220);
  color: var(--pp-ledger, #e8dfc9);
  font-family: var(--font-ui);
  transition: opacity var(--t-ui, 220ms) ease;
}

#chapter-map.hidden { opacity: 0; visibility: hidden; pointer-events: none; }

.chm-body {
  width: min(1180px, 94vw);
  margin: 0 auto;
  padding: clamp(2rem, 6vh, 4rem) 0 4rem;
  /* Deliberate, and load-bearing. `.hidden` sets visibility on the ROOT and every
     descendant inherits that flip — while theme.css's reduced-motion safety net
     gives EVERY element `transition-duration: 0.01ms` and transition-property's
     initial value is `all`. So for one frame after the screen opens, its own
     buttons still compute `visibility: hidden`, and focus() silently refuses an
     element that is not visible: the wall opened with nothing focused and Enter
     did nothing. Declaring the body visible keeps the flip off the subtree.
     Hiding is unaffected — hide() empties this element, sets `inert` on the root
     and takes its opacity to 0. */
  visibility: visible;
}

/* ------------------------------------------------------------- head + type */

.cw-head { margin-bottom: 1.5rem; }

.chm-kicker {
  margin: 0 0 0.5rem;
  font-size: 0.68rem;
  letter-spacing: 0.32em;
  color: rgba(232, 223, 201, 0.52);
}

.chm-title {
  margin: 0;
  font-family: var(--font-prose);
  font-size: clamp(1.8rem, 4.2vw, 2.8rem);
  font-weight: 400;
  letter-spacing: 0.01em;
  color: var(--pp-card, #ede6d6);
  text-wrap: balance;
}

.chm-sub {
  margin: 0.9rem 0 0;
  max-width: 46ch;
  color: rgba(232, 223, 201, 0.66);
  font-size: 0.86rem;
  line-height: 1.55;
}

/* INVISIBLE INK — a base defect, fixed 2026-08-31. Both heads ship the kicker
   as `class="chm-kicker paper-type"` (chapter-map.js:484, :753) and
   css/ui-paper.css is linked AFTER this file, so `.paper-type { color:
   var(--pp-type); letter-spacing: var(--track-type) }` — near-black ink at
   0.06em — beats `.chm-kicker`'s pale 0.32em above at EQUAL specificity. On
   this screen's near-black ground that drew ACT I · CHAPTER 1 in ink you
   cannot see, at the wrong tracking. The paper face from .paper-type is
   wanted and kept; only the two properties that lost are restated here, at
   (0,0,2), which is the smallest thing that outranks a single class. The case
   file's own head sets both explicitly further down and never depended on
   this. */
.cw .chm-kicker {
  letter-spacing: 0.32em;
  color: rgba(232, 223, 201, 0.52);
}

/* ============================== THE CASE WALL ============================= */

.cw-wall {
  display: flex;
  align-items: flex-start;
  gap: 0;
}

/* ---- the corkboard --------------------------------------------------------
   The plate carries its own painted wooden frame, so it is STRETCHED to the
   board (100% 100%) rather than cover-fitted: a cover fit crops the frame off
   the moment the board grows taller than 16:9, which it does at three scenes.
   Cork texture does not read as stretched; a missing frame does. */
.cw-board {
  position: relative;
  flex: 1 1 auto;
  min-width: 0;
  padding: clamp(30px, 4vw, 52px) clamp(24px, 3vw, 42px);
  background: var(--plate-cork-wall) 0 0 / 100% 100% no-repeat;
  background-color: var(--pp-cork-deep, #5d452a);
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.55), inset 0 0 90px rgba(0, 0, 0, 0.28);
  border-radius: 2px;
}

.cw-thread {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  overflow: visible;
  z-index: 1;
}

/* THE one saturated element on this screen. Dried blood, not alarm red. */
.cw-line, .cw-stub {
  fill: none;
  stroke: var(--pp-red, #8e2f2a);
  stroke-linecap: round;
  stroke-linejoin: round;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.55));
}
.cw-line { stroke-width: 2.4; }
.cw-stub { stroke-width: 1.8; opacity: 0.78; }

.cw-groups {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: clamp(20px, 2.4vw, 34px);
}

/* ---- a scene's run of pins ------------------------------------------------ */

.cw-group-title {
  margin: 0 0 0.55rem;
  font-size: 0.64rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(24, 16, 8, 0.72);
  text-shadow: 0 1px 0 rgba(255, 246, 224, 0.16);
}

/* A scene you have never entered in ANY lineage keeps its name. DBH's rule:
   you learn HOW MUCH you missed, never what it was. */
.cw-redact {
  display: inline-block;
  width: 5.5em;
  height: 0.5em;
  border-bottom: 2px dashed rgba(24, 16, 8, 0.42);
  vertical-align: middle;
}

.cw-pins {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: clamp(18px, 2vw, 30px) clamp(14px, 1.6vw, 24px);
}

.cw-slot {
  position: relative;
  width: var(--cw-card-w, clamp(148px, 15.5vw, 196px));
  padding-top: 13px;                 /* the pin sits above the card's top edge */
}

/* ---- the brass pin (sprite sheet, cut at runtime) ------------------------- */

.cw-pin {
  position: absolute;
  top: 0;
  left: 50%;
  width: 26px;
  height: 26px;
  margin-left: -13px;
  z-index: 4;
  background-image: var(--plate-pin-sprites);
  background-size: 500% 200%;
  background-repeat: no-repeat;
  filter: drop-shadow(0 2px 2px rgba(0, 0, 0, 0.5));
  pointer-events: none;
}
.cw-pin[data-pin-i="0"] { background-position: 0% 0%; }
.cw-pin[data-pin-i="1"] { background-position: 25% 0%; }
.cw-pin[data-pin-i="2"] { background-position: 50% 0%; }
.cw-pin[data-pin-i="3"] { background-position: 75% 0%; }
.cw-pin[data-pin-i="4"] { background-position: 100% 0%; }
.cw-pin[data-pin-i="5"] { background-position: 0% 100%; }

/* ---- the cards ------------------------------------------------------------ */

.cw-card {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 444 / 322;
  padding: 0;
  border: 0;
  background: transparent no-repeat;
  background-size: 144.1% 130.4%;
  background-position: 50% 50%;
  color: var(--pp-type, #22242b);
  font: inherit;
  text-align: left;
  cursor: pointer;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.45));
  transform: rotate(var(--tilt, 0deg));
  transition: transform var(--pp-t-lift, 140ms) var(--pp-ease-paper, ease),
              filter var(--pp-t-lift, 140ms) var(--pp-ease-paper, ease);
}

.cw-card.is-face { background-image: var(--plate-card-face); }
.cw-card.is-back { background-image: var(--plate-card-back); }

/* Deterministic scatter — a hand pinned these, not a grid engine. */
.cw-slot:nth-child(3n+1) .cw-card { --tilt: -0.9deg; }
.cw-slot:nth-child(3n+2) .cw-card { --tilt: 0.7deg; }
.cw-slot:nth-child(4n+3) .cw-card { --tilt: 1.3deg; }

/* Paper lift, never glow: the card rises and its shadow deepens, and only the
   card moves — the pin is a sibling, so it stays in the cork. */
.cw-card:hover,
.cw-card:focus-visible,
.cw-card.is-open {
  z-index: 6;
  outline: none;
  transform: rotate(0deg) scale(var(--cw-zoom, 1.42));
  filter: drop-shadow(0 8px 16px rgba(0, 0, 0, 0.55));
}
.cw-card:focus-visible { box-shadow: 0 0 0 2px rgba(142, 47, 42, 0.85); }

/* The route is legible without the thread too — the taken card sits square and
   a shade brighter than the ones beside it. */
.cw-card.on-route { filter: drop-shadow(0 3px 6px rgba(0, 0, 0, 0.5)) brightness(1.04); }
.cw-card.is-face:not(.on-route) { filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.45)) brightness(0.93); }

/* The card's writing area. The thumbnail is a flow child, not an overlay, so the
   text below it always gets the leftover — a 12:5 crop leaves ~28% of the card
   for type, which is exactly what two title lines plus a cue line need when the
   card is held open. */
.cw-card-in {
  position: absolute;
  inset: 5% 6% 6%;
  display: flex;
  flex-direction: column;
  gap: 0.12rem;
  overflow: hidden;
}

.cw-thumb {
  display: block;
  flex: 0 0 auto;
  width: 100%;
  aspect-ratio: 12 / 5;
  overflow: hidden;
  background: rgba(34, 36, 43, 0.16);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.28);
}
.cw-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  filter: grayscale(0.35) contrast(1.02);
}

.cw-kind {
  font-size: 0.48rem;
  letter-spacing: 0.2em;
  color: rgba(34, 36, 43, 0.5);
}
.cw-card:hover .cw-kind,
.cw-card:focus-visible .cw-kind,
.cw-card.is-open .cw-kind { display: none; }

/* Held open the card is 1.42x, so a wider crop still ENLARGES the picture in
   absolute terms (74px → 82px tall) while handing the extra back to the type —
   the cue line and the third title line have to fit inside the card, not spill. */
.cw-card:hover .cw-thumb,
.cw-card:focus-visible .cw-thumb,
.cw-card.is-open .cw-thumb { aspect-ratio: 3 / 1; }

.cw-card-title {
  font-size: 0.58rem;
  line-height: 1.28;
  color: var(--pp-type, #22242b);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.cw-card:hover .cw-card-title,
.cw-card:focus-visible .cw-card-title,
.cw-card.is-open .cw-card-title { -webkit-line-clamp: 3; line-clamp: 3; }

/* The cue line. Read tells are NAMED; everything else is a mark without a name,
   because naming a tell the player never resolved would hand over the answer
   the Attention economy charged for. */
.cw-tells { display: none; margin-top: 0.15rem; font-size: 0.46rem; letter-spacing: 0.08em; }
.cw-card:hover .cw-tells,
.cw-card:focus-visible .cw-tells,
.cw-card.is-open .cw-tells { display: block; }

.cw-tells-k {
  margin-right: 0.45em;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(34, 36, 43, 0.42);
}
.cw-tell { margin-right: 0.5em; white-space: nowrap; }
.cw-tell.is-read { color: var(--pp-type, #22242b); border-bottom: 1px solid rgba(34, 36, 43, 0.4); }
.cw-tell.is-seen { color: rgba(34, 36, 43, 0.6); letter-spacing: 0.1em; }
.cw-tell.is-dimmed { color: rgba(34, 36, 43, 0.38); letter-spacing: 0.1em; }
.cw-tell.is-missed { color: rgba(34, 36, 43, 0.3); }

/* "needed a read" in pencil on the back of a card you never turned over — and, a shade
   lighter, "not asked" on a question row. The lighter ink is the point: a question cost
   no Attention and demanded no read, so its note states a fact rather than naming a
   thing the player failed to do. Cards gated on a FACULTY are not on the wall at all
   (js/chapter-map.js, groupHTML) and so have no note to style. */
.cw-back-note {
  position: absolute;
  inset: auto 10% 12%;
  font-size: 0.72rem;
  text-align: center;
  color: rgba(58, 63, 69, 0.72);
  transform: rotate(-2deg);
}
.cw-back-note.is-ask { color: rgba(58, 63, 69, 0.5); transform: rotate(-1.2deg); }

/* ---- the fourth bucket, made physical -------------------------------------
   An empty pin-hole and a pale rectangle of cork the sun never reached. No
   asset: it IS the absence of one. */
.cw-hole {
  display: block;
  width: 100%;
  aspect-ratio: 444 / 322;
  border-radius: 1px;
  background:
    radial-gradient(circle at 50% -3%, rgba(28, 18, 8, 0.55) 0 2.2px, transparent 2.6px),
    linear-gradient(178deg, rgba(240, 226, 196, 0.16), rgba(240, 226, 196, 0.09));
  box-shadow:
    inset 0 0 0 1px rgba(255, 244, 214, 0.07),
    inset 0 2px 9px rgba(60, 40, 16, 0.22);
}
.cw-slot.is-hole { opacity: 0.92; }

/* ---- the stapled evidence receipt ----------------------------------------- */

/* The strip's height comes from what is PRINTED on it, not from a fixed ratio: a
   420x900 plate at this width would run past 1000px and trail a screenful of
   blank paper under the stamp. The plate is mapped across whatever height the
   tally needs (the painted texture is soft bands — a little vertical squash is
   invisible, an acre of empty receipt is not). */
.cw-receipt {
  position: relative;
  isolation: isolate;                /* keeps the stamp's multiply local       */
  flex: 0 0 auto;
  width: clamp(168px, 16vw, 206px);
  min-height: clamp(440px, 48vh, 600px);
  margin: -14px -6px 0 -18px;        /* stapled ONTO the board's right edge     */
  z-index: 3;
  background-image: var(--plate-receipt);
  background-repeat: no-repeat;
  background-size: 257.7% 101.4%;
  background-position: 44.35% 100%;
  filter: drop-shadow(0 6px 14px rgba(0, 0, 0, 0.5));
  transform: rotate(0.6deg);
}

.cw-receipt-in {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 6% 9% 8%;
  color: var(--pp-type, #22242b);
}

/* THE PAPER CURLS, AND THE NUMBERS HAVE TO STAY ON IT. receipt.webp is a torn
   strip photographed with its right edge rolling inward, so the PAINTED paper is
   narrower at the top than at the bottom. Measured off the plate through this
   block's own background-size/position, the paper's right edge runs 86.5% of the
   element width at 5% height and only reaches 87.8% by 15% — while the content
   box ends at 91% (padding-right 9%). The head rule, the bar and the four bucket
   values therefore ran off the edge of the paper and the widest value was cut in
   half; 'OUT OF REACH 20' printed as a 2 and half a 0. The note and the stamp sit
   lower, where the paper opens out to 95-98%, and are left alone — a global
   padding change would re-wrap the note for a problem it does not have.
   --cw-curl is stated against the PARENT'S content box (0.82W), so 7% here is
   ~5.7% of the receipt's width and lands the column at ~85%, inside the paper at
   every row. */
.cw-r-head, .cw-bar, .cw-r-rows { margin-right: var(--cw-curl, 7%); }

.cw-r-head {
  margin: 0 var(--cw-curl, 7%) 0 0;   /* `margin: 0` here would undo the curl inset above */
  font-size: 0.56rem;
  letter-spacing: 0.22em;
  color: rgba(34, 36, 43, 0.72);
  border-bottom: 1px solid rgba(34, 36, 43, 0.28);
  padding-bottom: 0.35rem;
}

/* Inked, not coloured — weight carries the four buckets. */
.cw-bar {
  display: flex;
  height: 6px;
  overflow: hidden;
  border: 1px solid rgba(34, 36, 43, 0.45);
}
.cw-bar span { display: block; height: 100%; }
.cw-bar-read { background: rgba(34, 36, 43, 0.92); }
.cw-bar-seen { background: rgba(34, 36, 43, 0.55); }
.cw-bar-dimmed { background: rgba(34, 36, 43, 0.28); }
.cw-bar-missed { background: transparent; }

.cw-r-rows { margin: 0 var(--cw-curl, 7%) 0 0; padding: 0; list-style: none; font-size: 0.55rem; }
.cw-r-rows li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.4rem;
  padding: 0.16rem 0;
  letter-spacing: 0.12em;
  border-bottom: 1px dotted rgba(34, 36, 43, 0.22);
}
.cw-r-k { color: rgba(34, 36, 43, 0.74); }
.cw-r-v { font-weight: 700; font-variant-numeric: tabular-nums; font-size: 0.78rem; }
.cw-r-rows li.is-missed .cw-r-k,
.cw-r-rows li.is-missed .cw-r-v { color: rgba(34, 36, 43, 0.55); }

.cw-r-note {
  margin: 0.1rem 0 0;
  font-size: 0.86rem;
  line-height: 1.2;
  color: rgba(58, 63, 69, 0.9);
}

/* The stamp: the plate is an empty rubber-stamp impression on cream, so it is
   MULTIPLIED onto the receipt (its paper vanishes, its ink does not) and the
   percentage is typed inside the ring at runtime. */
.cw-stamp {
  position: relative;
  margin-top: 0.55rem;
  width: 100%;
  aspect-ratio: 500 / 220;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.05rem;
  transform: rotate(-3.5deg);
}
.cw-stamp::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--plate-stamp-ring) center / 100% 100% no-repeat;
  mix-blend-mode: multiply;
  opacity: 0.92;
}
.cw-stamp-n {
  position: relative;
  font-size: 1.15rem;
  letter-spacing: 0.06em;
  line-height: 1;
}
.cw-stamp-w {
  position: relative;
  font-size: 0.44rem;
  letter-spacing: 0.28em;
  opacity: 0.85;
}

/* ---- reveal choreography ---------------------------------------------------
   Classes only, all of them removed again by a timer in chapter-map.js. If a
   frame never arrives, the wall was already in its finished state — nothing on
   this screen waits for an animation to become true. */
.cw.is-drawing .cw-slot,
.cw.is-settling .cw-slot { will-change: transform, opacity; }

.cw.is-drawing .cw-card,
.cw.is-drawing .cw-hole { opacity: 0; }
.cw.is-drawing .cw-pin { opacity: 0.45; }

.cw.is-settling .cw-card,
.cw.is-settling .cw-hole {
  animation: cw-settle var(--pp-t-settle, 320ms) var(--pp-ease-paper, ease) both;
}
.cw.is-drawing .cw-stamp,
.cw.is-settling .cw-stamp { opacity: 0; }
.cw.is-stamping .cw-stamp {
  animation: cw-stamp var(--pp-t-stamp, 220ms) var(--pp-ease-stamp, ease) both;
}

@keyframes cw-settle {
  from { opacity: 0; transform: translateY(-7px) rotate(var(--tilt, 0deg)) scale(1.02); }
  to   { opacity: 1; transform: translateY(0) rotate(var(--tilt, 0deg)) scale(1); }
}
@keyframes cw-stamp {
  from { opacity: 0; transform: rotate(-3.5deg) scale(1.5); }
  to   { opacity: 1; transform: rotate(-3.5deg) scale(1); }
}

/* ============================== THE CASE FILE ============================= */

/* ---- THE CHAPTERS HEAD — the drawer front and its brass plate -------------
   Elected 2026-08-31 from css/skins/frame-a.css ("the object, blocked") and
   folded down here, prefix gone. The case file is a drawer of folders; its
   heading used to be white serif floating on the gradient. It is now the
   DRAWER FRONT: the desk-wood strip with the act-rail emboss, and the word
   Chapters engraved on a small brass plate screwed to it. It reads as a
   different object from the act rails below (.cf-rail-edge) because it is
   taller, carries the plate, and shows the wood at its natural scale where the
   rails squash it.

   SCOPED TO `.cf`, which chapter-map.js gives ONLY to the chapter-select
   screen (chapter-map.js:751). The results wall reuses the same .cw-head /
   .chm-kicker / .chm-title markup (chapter-map.js:483) and deliberately keeps
   the base head above — a different screen, a different object.

   URL LAW: written against THIS file's location (css/), so '../assets/ui/…'.
   ui-paper.css's --plate-desk-edge is not consumed even though it resolves
   identically today: a url() carried in a custom property resolves against the
   sheet that USES the var, and a failed background layer draws nothing at all
   rather than erroring. */
#chapter-map .cf .cw-head {
  position: relative;
  display: block;
  margin: 0 0 clamp(1.7rem, 3.4vw, 2.6rem);
  padding: clamp(1rem, 2.4vh, 1.6rem) clamp(1.1rem, 2.6vw, 2rem)
           clamp(1.05rem, 2.4vh, 1.6rem);
  text-align: center;
  /* The same wood as the act rails below, at its NATURAL height rather than
     squashed into a 40px bar — a drawer front, not another divider. */
  background-image: url('../assets/ui/desk-edge.png');          /* NOT the var */
  background-repeat: no-repeat;
  background-size: 100% 100%;
  background-color: var(--pp-wood-deep, #241a12);
  border-radius: 2px;
  box-shadow:
    inset 0 1px 0 rgba(255, 226, 176, 0.1),
    inset 0 -2px 0 rgba(0, 0, 0, 0.6),
    0 2px 4px rgba(0, 0, 0, 0.45),
    0 10px 26px -8px rgba(0, 0, 0, 0.62);
}

/* Stencilled above the plate, cut into the wood (the .cf-act-n idiom). Colour
   and tracking are explicit, which is also what keeps ui-paper.css's
   .paper-type off this kicker — see INVISIBLE INK at the top of this file. */
#chapter-map .cf .chm-kicker {
  margin: 0 0 0.75rem;
  font-family: var(--font-type);
  font-size: clamp(0.54rem, 1.1vw, 0.66rem);
  letter-spacing: 0.34em;
  text-indent: 0.34em;
  text-transform: uppercase;
  color: rgba(226, 208, 176, 0.7);
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.75), 0 1px 0 rgba(255, 226, 176, 0.14);
}

/* THE BRASS PLATE. Engraved, so the letters are the dark part and the lit lip
   sits BELOW each stroke — the exact inverse of the wood's emboss above, which
   is what tells the eye the plate is proud of the drawer and the letters are
   sunk into the plate. Desaturated brass (the --hn-gold family), which sits in
   the same saturation band as --pp-manila and so does not spend the palette
   law's one saturated element. */
#chapter-map .cf .chm-title {
  display: inline-block;
  position: relative;
  margin: 0;
  padding: clamp(0.42rem, 1vh, 0.6rem) clamp(1.7rem, 4.2vw, 3rem)
           clamp(0.44rem, 1vh, 0.62rem);
  font-family: var(--font-type);
  font-weight: 700;
  font-size: clamp(0.82rem, 2vw, 1.18rem);
  letter-spacing: 0.34em;
  text-indent: 0.34em;
  text-transform: uppercase;
  color: rgba(30, 25, 15, 0.9);
  background-image: linear-gradient(178deg, #d8c294 0%, #bfaa80 44%, #9c8a62 100%);
  border-radius: 1.5px;
  box-shadow:
    inset 0 1px 0 rgba(255, 248, 222, 0.6),
    inset 0 -1px 0 rgba(0, 0, 0, 0.45),
    0 1px 2px rgba(0, 0, 0, 0.6),
    0 6px 14px -6px rgba(0, 0, 0, 0.6);
  text-shadow: 0 1px 0 rgba(255, 247, 219, 0.45);
}

/* Two screws. Decorative pseudo-elements, no content, no accessible name. */
#chapter-map .cf .chm-title::before,
#chapter-map .cf .chm-title::after {
  content: '';
  position: absolute;
  top: 50%;
  width: 0.38rem;
  height: 0.38rem;
  margin-top: -0.19rem;
  border-radius: 50%;
  background-image: radial-gradient(circle at 34% 30%,
    #efe0bb 0%, #b09a6c 55%, #7d6b48 100%);
  box-shadow: 0 1px 0 rgba(255, 248, 222, 0.28), inset 0 0 0 1px rgba(0, 0, 0, 0.28);
}
#chapter-map .cf .chm-title::before { left: clamp(0.55rem, 1.3vw, 0.95rem); }
#chapter-map .cf .chm-title::after  { right: clamp(0.55rem, 1.3vw, 0.95rem); }

/* Typed on the wood under the plate — the drawer's own note. */
#chapter-map .cf .chm-sub {
  margin: 0.95rem auto 0;
  max-width: 46ch;
  font-family: var(--font-type);
  font-size: clamp(0.62rem, 1.15vw, 0.72rem);
  line-height: 1.62;
  letter-spacing: 0.05em;
  color: rgba(226, 208, 176, 0.74);
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.6);
}

.cf-rail { margin: 0 0 clamp(1.8rem, 3vw, 2.8rem); }

/* The drawer edge: the desk-wood strip with the act label embossed into it. */
.cf-rail-edge {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  padding: 0.65rem clamp(0.9rem, 2vw, 1.6rem);
  margin-bottom: clamp(0.9rem, 1.6vw, 1.4rem);
  background: var(--plate-desk-edge) center / 100% 100% no-repeat;
  background-color: var(--pp-wood-deep, #241a12);
  border-radius: 2px;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.45), inset 0 -1px 0 rgba(0, 0, 0, 0.5);
}

/* Embossed = cut into the wood: a dark press above, a lit lip below. */
.cf-act-n, .cf-act-t {
  color: rgba(226, 208, 176, 0.62);
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.75), 0 1px 0 rgba(255, 226, 176, 0.16);
}
.cf-act-n { font-size: 0.66rem; letter-spacing: 0.3em; }
.cf-act-t { font-size: 0.78rem; letter-spacing: 0.24em; color: rgba(226, 208, 176, 0.82); }

.cf-folders {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(clamp(148px, 16vw, 206px), 1fr));
  gap: clamp(0.7rem, 1.4vw, 1.2rem);
}

.cf-folder {
  position: relative;
  aspect-ratio: 900 / 640;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--pp-type, #22242b);
  font: inherit;
  text-align: left;
  cursor: pointer;
  isolation: isolate;
  transition: transform var(--pp-t-lift, 140ms) var(--pp-ease-paper, ease),
              filter var(--pp-t-lift, 140ms) var(--pp-ease-paper, ease);
}

/* The plate lives on a pseudo-element so the MASK stays on the plate. Masking the
   button itself also masked its children — and the first panel, paperclipped, rises
   out past the folder's top edge, which is exactly where the mask goes transparent:
   the peek was being cut in half by the feather meant for the desk behind it. */
.cf-folder::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--plate-folder) center / 100% 100% no-repeat;
  /* The plates are painted on their own dark desk; the mask feathers that
     rectangle into the screen's ground instead of leaving a visible edge. */
  -webkit-mask-image: radial-gradient(118% 118% at 50% 50%, #000 58%, transparent 93%);
  mask-image: radial-gradient(118% 118% at 50% 50%, #000 58%, transparent 93%);
}

.cf-folder[disabled] { cursor: default; filter: brightness(0.72) saturate(0.7); }

/* Open a finger's width. */
.cf-folder:not([disabled]):hover,
.cf-folder:not([disabled]):focus-visible {
  outline: none;
  z-index: 3;                        /* the lifted photo overlaps its neighbours */
  transform: translateY(var(--pp-lift-y, -2px));
  filter: brightness(1.06);
}
.cf-folder:not([disabled]):hover::before,
.cf-folder:not([disabled]):focus-visible::before { background-image: var(--plate-folder-open); }
.cf-folder:focus-visible .cf-tab { box-shadow: 0 0 0 2px rgba(142, 47, 42, 0.9); }

/* The tab, measured off the plate (x 530–740, y 48–100 of 900x640). */
.cf-tab {
  position: absolute;
  left: 58.9%;
  width: 23.3%;
  top: 7.5%;
  height: 8.1%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.cf-tab-n {
  font-size: clamp(0.5rem, 1vw, 0.62rem);
  letter-spacing: 0.14em;
  font-variant-numeric: tabular-nums;
  color: rgba(34, 36, 43, 0.78);
}
.cf-folder.is-locked .cf-tab-n { color: rgba(34, 36, 43, 0.42); }

/* The folder's front, likewise measured (x 148–760, y 85–570). */
.cf-face {
  position: absolute;
  left: 16.4%;
  right: 15.6%;
  top: 38%;
  bottom: 11%;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.cf-title {
  font-size: clamp(0.54rem, 1.05vw, 0.68rem);
  line-height: 1.3;
  color: rgba(34, 36, 43, 0.86);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.cf-pct {
  margin-top: auto;
  font-size: 0.5rem;
  letter-spacing: 0.16em;
  font-variant-numeric: tabular-nums;
  color: rgba(34, 36, 43, 0.55);
}

.cf-mark {
  position: absolute;
  right: 0;
  bottom: 0;
  font-size: 0.46rem;
  letter-spacing: 0.2em;
  color: rgba(34, 36, 43, 0.5);
}

/* REPLAY is a stamp, not a button label. */
.cf-stamp {
  position: absolute;
  right: 1%;
  bottom: 1%;
  width: 62%;
  aspect-ratio: 500 / 220;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: clamp(0.4rem, 0.78vw, 0.5rem);
  transform: rotate(-7deg);
}
.cf-stamp::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--plate-stamp-ring) center / 100% 100% no-repeat;
  mix-blend-mode: multiply;
  opacity: 0.9;
}

/* The first panel, paperclipped, rising out of the folder as it opens. */
.cf-peek {
  position: absolute;
  left: 6%;
  width: 46%;
  top: -8%;
  aspect-ratio: 16 / 9;
  opacity: 0;
  transform: translateY(9px);
  transition: opacity var(--pp-t-lift, 140ms) var(--pp-ease-paper, ease),
              transform var(--pp-t-lift, 140ms) var(--pp-ease-paper, ease);
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.5);
  background: rgba(11, 18, 32, 0.6);
}
.cf-peek img { width: 100%; height: 100%; object-fit: cover; display: block; filter: grayscale(0.3); }

.cf-folder:not([disabled]):hover .cf-peek,
.cf-folder:not([disabled]):focus-visible .cf-peek { opacity: 1; transform: translateY(0); }

.cf-clip {
  position: absolute;
  left: -7%;
  top: -14%;
  width: 26%;
  aspect-ratio: 160 / 200;
  background-image: var(--plate-pin-sprites);
  background-size: 500% 200%;
  background-position: 25% 100%;      /* row 2, col 2 — the first paperclip     */
  background-repeat: no-repeat;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.55));
}

/* --------------------------------------------------------------- actions --- */

.chm-actions { margin-top: clamp(1.6rem, 3vw, 2.6rem); }

/* An index-card slip, not a rectangle of UI: the card plate cropped to its
   paper band, with the label typed on it. */
.chm-btn {
  padding: 0.72rem 2.4rem;
  border: 0;
  border-radius: 1px;
  background-image: var(--plate-card-face);
  background-repeat: no-repeat;
  background-size: 144.1% auto;
  background-position: center;
  background-color: var(--pp-card, #ede6d6);
  color: var(--pp-type, #22242b);
  font-family: var(--font-type);
  font-size: 0.72rem;
  letter-spacing: 0.26em;
  cursor: pointer;
  box-shadow: var(--pp-shadow-rest, 0 1px 2px rgba(0, 0, 0, 0.45));
  transform: translateY(0) rotate(-0.4deg);
  transition: transform var(--pp-t-lift, 140ms) var(--pp-ease-paper, ease),
              box-shadow var(--pp-t-lift, 140ms) var(--pp-ease-paper, ease);
}

.chm-btn:hover, .chm-btn:focus-visible {
  outline: none;
  transform: translateY(var(--pp-lift-y, -2px)) rotate(-0.4deg);
  box-shadow: var(--pp-shadow-lift, 0 3px 7px rgba(0, 0, 0, 0.52));
}
.chm-btn:focus-visible { box-shadow: var(--pp-shadow-lift), 0 0 0 2px rgba(142, 47, 42, 0.9); }

/* ------------------------------------------------------------- responsive - */

@media (max-width: 820px) {
  .cw-wall { flex-direction: column; align-items: stretch; }
  .cw-receipt { margin: -22px auto 0; transform: rotate(-0.8deg); }
}

/* --------------------------------------------------------- reduced motion -
   Motion is only ever REMOVED. The reveal classes never run (chapter-map.js
   returns before adding them), so these rules are the belt to that braces:
   even if a class survived, nothing here would hide or move anything. */
@media (prefers-reduced-motion: reduce) {
  #chapter-map, .cw-card, .cf-folder, .cf-peek, .chm-btn { transition: none; }
  .cw.is-drawing .cw-card,
  .cw.is-drawing .cw-hole,
  .cw.is-drawing .cw-stamp,
  .cw.is-settling .cw-stamp { opacity: 1; }
  .cw.is-settling .cw-card,
  .cw.is-settling .cw-hole,
  .cw.is-stamping .cw-stamp { animation: none; }
  .cw-card:hover, .cw-card:focus-visible, .cw-card.is-open { transform: rotate(0deg) scale(1.42); }
}
.cw-stamp .cw-chapter-word { font-size: 1.2rem; letter-spacing: .12em; }
.cw-exploration { margin-top: 1.5rem; font-family: var(--font-type); font-size: .78rem; line-height: 1.55; }
.cw-exploration summary { cursor: pointer; text-decoration: underline; text-underline-offset: .2em; }
.cw-exploration p { margin: .65rem 0 0; }
.cw-exploration summary:focus-visible { outline: 2px solid currentColor; outline-offset: 4px; }

/* Reading pass, 2026-09-14. Paper remains the object; its contents no longer
   depend on a magnifying hover. These dimensions follow the reading preference
   and let the cards grow around complete text instead of clipping it. */
#chapter-map { --chm-scale: var(--reading-scale, 1); scroll-padding-top: 110px; }
#chapter-map .chm-body { width: min(1280px, calc(100% - 40px)); padding-top: 32px; }
#chapter-map .cw .chm-kicker {
  font-size: calc(.875rem * var(--chm-scale));
  letter-spacing: .14em;
  color: #d7cbb5;
}
#chapter-map .chm-sub {
  max-width: 66ch;
  font-size: calc(1rem * var(--chm-scale));
  line-height: 1.55;
  color: #d0c6b3;
}
#chapter-map .chm-actions {
  position: sticky;
  top: 0;
  z-index: 12;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin: 0 0 24px;
  padding: 12px 0;
  background: #0b1220;
  border-bottom: 1px solid #5b5141;
}
#chapter-map .chm-btn {
  min-height: 48px;
  padding: 12px 20px;
  font-size: calc(.875rem * var(--chm-scale));
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: .07em;
  transform: none;
}
#chapter-map .chm-btn:focus-visible {
  outline: 3px solid #e8dfc9;
  outline-offset: 4px;
}
#chapter-map #chm-return-title {
  background: #172127;
  color: #e8dfc9;
  border: 1px solid #ac9979;
  box-shadow: inset 0 0 0 3px #172127, inset 0 0 0 4px #665b4b;
}
#chapter-map .cw-wall { gap: 20px; align-items: flex-start; }
#chapter-map .cw-board { padding: 32px 28px; }
#chapter-map .cw-groups { gap: 34px; }
#chapter-map .cw-group-title {
  display: inline-block;
  max-width: 100%;
  padding: 7px 10px;
  margin: 0 0 12px;
  color: #252626;
  background: #e5d7b8;
  box-shadow: 0 1px 3px #241a1280;
  font-size: calc(.875rem * var(--chm-scale));
  letter-spacing: .035em;
  line-height: 1.45;
  text-transform: none;
  text-shadow: none;
}
#chapter-map .cw-pins { gap: 20px; align-items: flex-start; }
#chapter-map .cw-slot { flex: 1 1 250px; width: 250px; max-width: 340px; min-width: 0; }
#chapter-map .cw-slot:has(.is-back),
#chapter-map .cw-slot.is-hole { flex: 0 1 112px; width: 112px; }
#chapter-map .cw-card.is-face {
  aspect-ratio: auto;
  min-height: 190px;
  padding: 14px 16px;
  background-color: #ede6d6;
  border-radius: 2px 2px 10px 2px;
}
#chapter-map .cw-card-in {
  position: relative;
  inset: auto;
  gap: 8px;
  overflow: visible;
}
#chapter-map .cw-thumb { aspect-ratio: 16 / 7; }
#chapter-map .cw-kind {
  display: block;
  font-size: calc(.75rem * var(--chm-scale));
  color: #48443b;
  letter-spacing: .09em;
}
#chapter-map .cw-card-title {
  display: block;
  overflow: visible;
  -webkit-line-clamp: unset;
  line-clamp: unset;
  font-family: var(--font-prose);
  font-size: calc(1rem * var(--chm-scale));
  letter-spacing: 0;
  line-height: 1.5;
  overflow-wrap: anywhere;
}
#chapter-map .cw-card:hover,
#chapter-map .cw-card:focus-visible,
#chapter-map .cw-card.is-open { transform: rotate(0); }
#chapter-map .cw-card:focus-visible {
  outline: 3px solid #22242b;
  outline-offset: 4px;
  box-shadow: 0 0 0 6px #e8dfc9;
}
#chapter-map .cw-card:not(button) { cursor: default; box-sizing: border-box; }
#chapter-map .cw-card-hint {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding-top: 8px;
  border-top: 1px solid #9e9687;
  font-size: calc(.8125rem * var(--chm-scale));
  line-height: 1.4;
  color: #383a38;
  letter-spacing: 0;
}
#chapter-map .cw-card.is-open .cw-card-hint > span { transform: rotate(45deg); }
#chapter-map .cw-tells { display: none; }
#chapter-map .cw-card.is-open .cw-tells {
  display: block;
  margin: 2px 0;
  padding: 8px;
  font-size: calc(.875rem * var(--chm-scale));
  line-height: 1.65;
  letter-spacing: .025em;
  background: #ede6d6;
}
#chapter-map .cw-tells-k,
#chapter-map .cw-tell { color: #45443e; }
#chapter-map .cw-tell { display: block; white-space: normal; overflow-wrap: anywhere; border: 0; }
#chapter-map .cw-back-note {
  font-size: calc(1rem * var(--chm-scale));
  color: #383a38;
  line-height: 1.15;
}
#chapter-map .cw-receipt {
  width: clamp(290px, 25vw, 330px);
  margin: 0;
  min-height: 0;
  transform: none;
}
#chapter-map .cw-receipt-in {
  margin: 8% 14% 12% 9%;
  padding: 14px 10px;
  gap: 12px;
  background: rgba(237, 230, 214, .91);
}
#chapter-map .cw-r-head,
#chapter-map .cw-r-rows,
#chapter-map .cw-bar { margin-right: 0; }
#chapter-map .cw-r-head {
  font-size: calc(.8125rem * var(--chm-scale));
  letter-spacing: .08em;
  line-height: 1.4;
  color: #383a38;
}
#chapter-map .cw-r-rows { font-size: calc(.875rem * var(--chm-scale)); }
#chapter-map .cw-r-rows li { padding: 7px 0; letter-spacing: 0; gap: 10px; }
#chapter-map .cw-r-k,
#chapter-map .cw-r-rows li.is-missed .cw-r-k,
#chapter-map .cw-r-rows li.is-missed .cw-r-v { color: #383a38; }
#chapter-map .cw-r-v { font-size: calc(1.25rem * var(--chm-scale)); }
#chapter-map .cw-r-note {
  font-family: var(--font-prose);
  font-size: calc(1rem * var(--chm-scale));
  line-height: 1.55;
  color: #30332f;
}
#chapter-map .cw-stamp .cw-chapter-word { font-size: calc(1rem * var(--chm-scale)); }
#chapter-map .cw-stamp-w { font-size: calc(.75rem * var(--chm-scale)); letter-spacing: .13em; }
#chapter-map .cw-exploration {
  margin-top: 0;
  font-size: calc(.875rem * var(--chm-scale));
  line-height: 1.55;
  color: #30332f;
  letter-spacing: 0;
}
#chapter-map .cw-exploration summary { min-height: 44px; padding: 8px 0; }
@media(max-width: 960px) {
  #chapter-map .cw-wall { flex-direction: column; align-items: stretch; }
  #chapter-map .cw-receipt { order: -1; width: min(460px, 100%); align-self: center; }
  #chapter-map .cw-board { width: 100%; box-sizing: border-box; }
}
@media(max-width: 540px) {
  #chapter-map .chm-body { width: calc(100% - 24px); padding-top: 20px; }
  #chapter-map .chm-actions { gap: 8px; padding: 10px 0; }
  #chapter-map .chm-btn { flex: 1 1 100%; padding: 10px 12px; }
  #chapter-map .cw-board { padding: 24px 16px; }
  #chapter-map .cw-slot:has(.is-face) { flex-basis: 100%; max-width: 100%; }
  #chapter-map .cw-slot:has(.is-back),
  #chapter-map .cw-slot.is-hole { flex: 0 1 96px; }
  #chapter-map .cw-card { --tilt: 0deg; }
  #chapter-map { scroll-padding-top: 150px; }
}

/* The same readable scale in the file drawer. Labels stay on the folder,
   and the replay stamp has its own space below the exploration note. */
#chapter-map .cf .chm-kicker {
  font-size: calc(.875rem * var(--chm-scale));
  color: #e1d4bb;
  letter-spacing: .16em;
}
#chapter-map .cf .chm-title { font-size: calc(1.25rem * var(--chm-scale)); letter-spacing: .2em; }
#chapter-map .cf .chm-sub {
  font-family: var(--font-prose);
  font-size: calc(1rem * var(--chm-scale));
  color: #e4d8c0;
  letter-spacing: 0;
  max-width: 64ch;
  padding: 10px 14px;
  background: rgba(26, 21, 17, .86);
  text-shadow: none;
}
#chapter-map .cf-rail-edge { flex-wrap: wrap; gap: 8px 18px; padding: 14px 20px; }
#chapter-map .cf-act-n,
#chapter-map .cf-act-t {
  color: #e8dcc4;
  font-size: calc(.9375rem * var(--chm-scale));
  letter-spacing: .08em;
  line-height: 1.4;
  text-shadow: 0 1px 2px #0b1220;
}
#chapter-map .cf-folders { grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr)); gap: 24px; }
#chapter-map .cf-folder {
  aspect-ratio: auto;
  min-height: 235px;
  padding: 30% 16.4% 12%;
}
#chapter-map .cf-folder.is-locked { aspect-ratio: 900 / 640; min-height: 0; }
#chapter-map .cf-folder[disabled]:not(.is-locked) { filter: none; }
#chapter-map .cf-folder:focus-visible { outline: 3px solid #e8dfc9; outline-offset: 4px; }
#chapter-map .cf-tab-n {
  font-size: calc(.875rem * var(--chm-scale));
  color: #252626;
  letter-spacing: .04em;
}
#chapter-map .cf-folder.is-locked .cf-tab-n { color: #33352f; }
#chapter-map .cf-face { position: relative; inset: auto; gap: 10px; }
#chapter-map .cf-title {
  display: block;
  overflow: visible;
  -webkit-line-clamp: unset;
  line-clamp: unset;
  font-size: calc(1rem * var(--chm-scale));
  line-height: 1.45;
  letter-spacing: .025em;
  color: #252626;
}
#chapter-map .cf-pct,
#chapter-map .cf-mark {
  position: static;
  margin: 0;
  color: #33352f;
  font-size: calc(.8125rem * var(--chm-scale));
  line-height: 1.5;
  letter-spacing: .02em;
}
#chapter-map .cf-stamp {
  position: relative;
  inset: auto;
  align-self: flex-end;
  width: min(160px, 100%);
  min-height: 48px;
  aspect-ratio: 500 / 220;
  margin-top: 2px;
  font-size: calc(.875rem * var(--chm-scale));
  transform: rotate(-3deg);
}
body.clear-reading #chapter-map .cw-card-title,
body.clear-reading #chapter-map .cw-r-note,
body.clear-reading #chapter-map .cf-title { font-family: var(--font-ui); }
