/* Layout: a tall cork board shaped for a phone. Index cards hurled side to side,
   red string running behind them, the "logic" on masking tape, panic on sticky notes.
   One committed physical look, so a single palette on any host theme. */
:root {
  --cork: #a8743f;
  --cork-hi: #c99c64;
  --cork-lo: #6b4321;
  --paper: #fbf8ef;
  --ink: #23201b;
  --ink-soft: #5d574c;
  --rule: #b3cde2;
  --margin: #d9645a;
  --string: #c4161c;
  --string-dark: #7d0b0f;
  --string-lo: rgba(70, 12, 12, .35);
  --tape: rgba(236, 224, 172, .95);
  --sticky: #f4e15a;
  --stamp: #b0141b;
  --label: #f2ead2;
  --focus: #ffd34d;
  --font-fact: "Courier Prime", "Courier New", Courier, monospace;
  --font-hand: "Caveat", "Segoe Print", "Bradley Hand", cursive;
  /* the controls: plain and calm, before anyone goes down the rabbit hole */
  --font-ui: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-marker: "Permanent Marker", "Marker Felt", Impact, sans-serif;
  color-scheme: light;
}
* { box-sizing: border-box; }
html { background: var(--cork); }
body {
  margin: 0;
  background: var(--cork) var(--cork-img, none);
  color: var(--ink);
  font-family: var(--font-fact);
  padding-inline: 16px;
  padding-block: 20px 56px;
  min-height: 100%;
}
.wrap { max-width: 760px; margin: 0 auto; display: grid; gap: 22px; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }

/* ---------- the ask ---------- */
header { display: grid; gap: 16px; justify-items: start; }
#ask { scroll-margin-top: 10px; }
.label {
  background: var(--label);
  padding: 10px 18px 8px;
  transform: rotate(-1.5deg);
  box-shadow: 0 2px 0 rgba(0,0,0,.08), 0 8px 18px rgba(40,20,5,.35);
  clip-path: polygon(0 4%, 3% 0, 97% 2%, 100% 0, 99% 96%, 96% 100%, 2% 98%, 0 100%);
}
h1 { font-family: var(--font-marker); font-weight: 400; font-size: clamp(28px, 7vw, 46px); line-height: 1.05; margin: 0; text-wrap: balance; }
form { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 14px; }
form label { font-family: var(--font-ui); font-size: 17px; font-weight: 600; color: var(--paper); text-shadow: 0 1px 2px rgba(0,0,0,.55); }
#n, input.word {
  font-family: var(--font-ui); font-size: 20px; color: #1d1d1f;
  background: #fff; border: 1px solid rgba(0,0,0,.25); border-radius: 8px; padding: 8px 10px;
  box-shadow: 0 2px 6px rgba(40,20,5,.25);
}
#n { width: 5ch; text-align: center; }
#n:focus-visible, input.word:focus-visible { outline: 3px solid rgba(255,255,255,.85); outline-offset: 1px; }
[hidden] { display: none !important; }
.field { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 12px; min-width: 0; }
input.word { width: 100%; }
/* two words: "From [  ]" over "to [  ]", lined up */
#f-word:not([hidden]) { display: grid; grid-template-columns: auto minmax(0, 1fr); width: min(100%, 24em); flex-basis: 100%; }
#f-word label { justify-self: end; }
/* the two modes: a plain segmented switch */
.modes { display: flex; gap: 0; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 6px rgba(40,20,5,.25); }
.modes button {
  font-family: var(--font-ui); font-size: 16px; font-weight: 600; cursor: pointer;
  background: rgba(255,255,255,.7); color: #1d1d1f; border: 0; padding: 8px 16px;
}
.modes button + button { border-left: 1px solid rgba(0,0,0,.15); }
.modes button[aria-selected="true"] { background: #fff; box-shadow: inset 0 -3px 0 var(--string); }
.card.word .num { display: none; }
#go {
  font-family: var(--font-ui); font-size: 18px; font-weight: 700;
  background: var(--string); color: #fff; border: 0; border-radius: 8px; cursor: pointer;
  padding: 11px 20px; min-width: 15ch;
  box-shadow: 0 3px 0 var(--string-dark), 0 6px 12px rgba(40,20,5,.35);
  transition: transform .08s, box-shadow .08s;
}
#go:active { transform: translateY(2px); box-shadow: 0 1px 0 var(--string-dark), 0 3px 8px rgba(40,20,5,.35); }
#go span { display: inline-block; }
#err { flex-basis: 100%; margin: 0; font-family: var(--font-ui); font-size: 16px; font-weight: 600; color: var(--paper); text-shadow: 0 1px 2px rgba(0,0,0,.6); min-height: 0; }
#err:empty { display: none; }

/* ---------- paper ---------- */
.board { position: relative; width: 100%; transform-origin: 50% 0; }
.board [hidden] { display: none !important; }
.card {
  position: absolute; width: 250px; z-index: 3;
  background:
    var(--grain, none),
    repeating-linear-gradient(90deg, transparent 0 21px, var(--grid, transparent) 21px 22px),
    repeating-linear-gradient(var(--paper) 0 21px, var(--rule) 21px 22px);
  border-top: 30px solid var(--paper);
  padding: 0 16px 12px;
  box-shadow: 0 1px 0 rgba(0,0,0,.06), 0 10px 22px rgba(40,20,5,.4);
  line-height: 22px; font-size: 15px;
  transform: rotate(var(--rot, 0deg));
}
.card::before { content: ""; position: absolute; left: 0; right: 0; top: -8px; height: 1px; background: var(--margin); }
.card::after {
  content: ""; position: absolute; left: 50%; top: -25px; width: 14px; height: 14px; margin-left: -7px; border-radius: 50%;
  background: radial-gradient(circle at 35% 32%, rgba(255,255,255,.75) 0 2px, transparent 3px), var(--pin, var(--string));
  border: 1.5px solid rgba(0,0,0,.45); box-shadow: 0 3px 3px rgba(40,20,5,.45);
}
.card .num { position: absolute; top: -28px; right: 10px; font-family: var(--font-marker); font-size: 26px; line-height: 1; transform: rotate(4deg); }
.card p { margin: 0; overflow-wrap: anywhere; filter: url(#ink-type); }
/* the ribbon: fresh ones print heavier; tired ones thin out toward the bottom of the card */
.card[data-ribbon="fresh"] p { text-shadow: 0.35px 0 0 currentColor; }
.card[data-ribbon="tired"] p { -webkit-mask-image: linear-gradient(#000 35%, rgba(0,0,0,.8)); mask-image: linear-gradient(#000 35%, rgba(0,0,0,.8)); }
.card p .key { position: relative; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.note .ink, .sticky .ink { filter: url(#ink-pen); }
/* iPhone Safari drops SVG-filtered text while it scrolls, so the notes flashed in and out
   (a layer of their own didn't help). Phones and tablets on Safari get plain ink instead. */
@supports (-webkit-touch-callout: none) {
  .note .ink, .sticky .ink { filter: none; }
}
.card .src { display: block; margin-top: 8px; font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--soft, var(--ink-soft)); overflow-wrap: anywhere; }
.card { color: var(--ink); }

/* Clippings: cut from a newspaper or a book page. Printed, so a serif face set justified, plain
   paper, and edges a pair of scissors left a little crooked. No ruled lines, margin or damage. */
.card.clip {
  background: var(--grain, none), var(--paper);
  font-family: var(--clip-font); font-size: var(--clip-size, 15px); line-height: 1.4;
  text-align: justify; hyphens: auto; padding: 0 14px 12px; border-top-width: 26px;
  clip-path: polygon(2px 1px, 61% 3px, calc(100% - 1px) 0, 100% 48%, calc(100% - 2px) 100%, 38% calc(100% - 2px), 1px calc(100% - 1px), 0 52%);
}
.card.clip[data-halftone] { background: var(--grain, none), radial-gradient(rgba(0,0,0,.07) .7px, transparent 1px) 0 0 / 3px 3px, var(--paper); }
.card.clip::before { display: none; }
/* a newspaper column cut from the page keeps a sliver of the rule between columns */
.card.clip[data-halftone]::before { display: block; left: 5px; right: auto; top: 0; bottom: 6px; width: 1px; height: auto; background: var(--soft); opacity: .5; }
.card.clip[data-halftone] { padding-left: 16px; }
.card.clip::after { top: -21px; }
.card.clip .num { top: -24px; }
.card.clip p { filter: none; }
.card.clip .src { text-align: left; }

/* Damage, for variety. Never on the text: it lives in the empty strip above the text
   (smudge, ring, tape) or in extra padding below it (torn edge, folded corner). The clip
   paths reach 40px above the card so the pin, which sits above it, is never cut off. */
.card .deco { position: absolute; pointer-events: none; }
.card[data-deco="smudge"] .deco {
  left: 10px; top: -26px; width: 70px; height: 20px;
  background: radial-gradient(ellipse at 40% 55%, rgba(55, 45, 35, .22), rgba(55, 45, 35, .08) 45%, transparent 70%);
}
.card[data-deco="ring"] .deco {
  left: 14px; top: -29px; width: 27px; height: 27px; border-radius: 50%;
  border: 2.5px solid rgba(120, 70, 30, .32); border-right-color: rgba(120, 70, 30, .12); transform: rotate(20deg);
}
.card[data-deco="tape"] .deco {
  left: -14px; top: -36px; width: 62px; height: 20px;
  background: rgba(236, 224, 172, .88); transform: rotate(-32deg); box-shadow: 0 1px 2px rgba(40,20,5,.2);
}
.card[data-deco="torn"] {
  padding-bottom: 22px;
  clip-path: polygon(0 -40px, 100% -40px, 100% calc(100% - 5px), 93% calc(100% - 1px), 86% calc(100% - 6px), 78% 100%,
    70% calc(100% - 5px), 62% calc(100% - 1px), 54% calc(100% - 7px), 46% calc(100% - 2px), 38% calc(100% - 6px),
    30% 100%, 22% calc(100% - 5px), 14% calc(100% - 1px), 7% calc(100% - 6px), 0 calc(100% - 2px));
}
.card[data-deco="fold"] {
  padding-bottom: 28px;
  clip-path: polygon(0 -40px, 100% -40px, 100% calc(100% - 24px), calc(100% - 24px) 100%, 0 100%);
}
.card[data-deco="fold"] .deco {
  right: 0; bottom: 0; width: 24px; height: 24px;
  background: linear-gradient(to top left, transparent 50%, color-mix(in srgb, var(--paper) 78%, #000) 50%);
  box-shadow: -1px -1px 2px rgba(40,20,5,.15);
}
.card .src a { color: inherit; }
mark.circ {
  background: none; color: inherit; font-weight: 700;
  display: inline-block; padding: 0 4px; margin: -2px -1px; line-height: 20px;
  border: 2px solid var(--marker, var(--string)); border-radius: 52% 46% 55% 42% / 60% 50% 56% 44%;
  transform: rotate(-4deg);
}
/* the investigator's habit, one per board: circle (above), underline twice, box, highlighter */
.card[data-mark="underline"] mark.circ { display: inline; border: 0; border-radius: 0; transform: none; padding: 0; margin: 0;
  text-decoration: underline double var(--marker, var(--string)); text-decoration-thickness: 2px; text-underline-offset: 3px; }
.card[data-mark="box"] mark.circ { border-radius: 2px 4px 3px 2px; transform: rotate(-1.5deg); }
.card[data-mark="highlight"] mark.circ { border: 0; transform: none; border-radius: 3px 6px 4px 7px; margin: 0 -2px; padding: 0 3px;
  background: color-mix(in srgb, var(--marker, var(--string)) 38%, transparent); transform: rotate(-1deg); }
/* a number the board comes back to later: marked lighter, as if noticed in passing */
mark.circ.also { font-weight: inherit; border-width: 1.5px; border-style: dashed; transform: rotate(3deg); }
.card[data-mark="underline"] mark.circ.also { text-decoration: underline var(--marker, var(--string)); text-decoration-thickness: 1.5px; }
.card[data-mark="highlight"] mark.circ.also { background: color-mix(in srgb, var(--marker, var(--string)) 20%, transparent); }

/* what holds a card up: a pin (the default, in .card::after), a flat thumbtack, tape, a paperclip */
.card[data-holder="tack"]::after { width: 18px; height: 18px; margin-left: -9px; top: -27px;
  background: radial-gradient(circle at 40% 38%, rgba(255,255,255,.55) 0 2px, transparent 4px), radial-gradient(circle, rgba(0,0,0,.25) 0 2px, transparent 2.5px), #b8b8b0;
  border-color: rgba(0,0,0,.35); }
.card[data-holder="tape"]::after { width: 64px; height: 20px; margin-left: -32px; top: -32px; border-radius: 1px; border: 0;
  background: rgba(240, 232, 200, .82); box-shadow: 0 1px 2px rgba(40,20,5,.2); transform: rotate(-3deg); }
.card[data-holder="clip"]::after { width: 12px; height: 32px; margin-left: -6px; top: -40px; border-radius: 6px; background: none;
  border: 2px solid #8d9196; box-shadow: inset 0 0 0 2px transparent, 1px 1px 1px rgba(0,0,0,.25); }

/* rare papers: a carbon copy's ink is a touch soft; a photocopy is grey with toner specks */
.card[data-rare="carbon"] p { text-shadow: 0 0 .6px currentColor; }
.card[data-rare="photocopy"] { background: var(--grain, none), radial-gradient(rgba(0,0,0,.18) .6px, transparent 1px) 1px 2px / 7px 9px, radial-gradient(rgba(0,0,0,.12) .5px, transparent .9px) 3px 0 / 11px 5px, var(--paper); }
.note {
  position: absolute; width: 230px; z-index: 1;
  font-family: var(--notes-font, var(--font-hand)); font-weight: var(--notes-weight, 700); font-size: calc(23px * var(--notes-k, 1)); line-height: 1.15;
  background: var(--grain, none), var(--note-bg, var(--tape)); color: var(--note-ink, var(--ink)); padding: 8px 16px 9px;
  clip-path: polygon(2% 0, 98% 4%, 100% 48%, 97% 100%, 3% 96%, 0 52%);
  transform: rotate(var(--rot, 0deg));
  box-shadow: 0 2px 6px rgba(40,20,5,.25);
}
.sticky {
  position: absolute; z-index: 4; width: 96px; min-height: 76px;
  display: grid; place-items: center; text-align: center;
  font-family: var(--stickies-font, var(--font-hand)); font-weight: var(--stickies-weight, 700); font-size: calc(21px * var(--stickies-k, 1) * var(--fit, 1)); line-height: 1.05; overflow-wrap: anywhere;
  background: var(--grain, none), var(--sticky-bg, var(--sticky)); color: var(--sticky-ink, var(--ink)); padding: 8px 6px;
  box-shadow: 0 6px 10px rgba(40,20,5,.35);
  transform: rotate(var(--rot, 6deg));
}
.stamp {
  position: absolute; z-index: 5;
  font-family: var(--font-marker); color: var(--stamp);
  border: 4px double var(--stamp); padding: 8px 16px 6px;
  line-height: 1.05; text-align: center;
  transform: rotate(-7deg); background: var(--grain, none), rgba(251, 248, 239, .85);
  text-wrap: balance;
}
.empty { display: grid; justify-items: center; padding-block: 48px 120px; }
.empty .note { position: relative; max-width: 300px; }
.loading {
  font-family: var(--font-hand); font-size: 26px; font-weight: 700; color: var(--paper);
  text-shadow: 0 1px 2px rgba(0,0,0,.55); text-align: center; padding-block: 40px;
}
/* string runs behind the paper so it never crosses text; the pin sits on the card */
/* the string runs behind the cards (it's tied to their pins) but over the narrator's notes, so
   it stays visible in the gaps between cards */
svg.string { position: absolute; left: 0; top: 0; pointer-events: none; overflow: visible; z-index: 2; }
svg.string path { fill: none; stroke-linecap: round; }
svg.string path.s { stroke: var(--string); stroke-width: 2.4; }
svg.string path.x { stroke: var(--string); stroke-width: 1.8; opacity: .7; }
svg.string path.sh { stroke: var(--string-lo); stroke-width: 2.4; opacity: .6; transform: translate(1px, 3px); }

@keyframes pinDrop { from { transform: translateY(-28px) rotate(var(--rot, 0deg)) scale(1.04); opacity: 0; } to { transform: rotate(var(--rot, 0deg)); opacity: 1; } }
@keyframes slam { 0% { transform: rotate(-7deg) scale(2.4); opacity: 0; } 70% { transform: rotate(-7deg) scale(.94); opacity: 1; } 100% { transform: rotate(-7deg) scale(1); } }
@keyframes draw { from { stroke-dashoffset: var(--len); } to { stroke-dashoffset: 0; } }
.arrive { animation: pinDrop .3s cubic-bezier(.2,.9,.3,1.2) var(--delay, 0s) both; }
.stamp.arrive { animation: slam .5s cubic-bezier(.3,1.4,.5,1) var(--delay, 0s) both; }
path.drawing { stroke-dasharray: var(--len); animation: draw .4s ease-out var(--delay, 0s) both; }
@media (prefers-reduced-motion: reduce) {
  .arrive, .stamp.arrive, path.drawing { animation: none; }
}

footer { color: var(--paper); font-size: 12px; line-height: 1.5; text-shadow: 0 1px 2px rgba(0,0,0,.5); max-width: 70ch; }
footer a { color: inherit; }
