/* Hallmark · genre: modern-minimal · macrostructure: App Screen (bespoke, structure.md
 * deviation) · knob deltas vs previous build: composition=stat-led stage 2 ·
 * card voice=bordered-white · CTA=ink-filled pill (accent is a signal, not a fill)
 * theme: Coral · nav: N9 edge-aligned · footer: Ft2 inline · enrichment: none
 * axes: light warm paper / Geist sans display / coral signal — differs from previous
 * (Midnight: dark / grotesk / red-pink flood) on paper band + accent discipline +
 * nav + footer + card voice
 * display: Geist (local woff2, single family) · tone: composed, quiet, precise
 * pre-emit critique: P4 H5 E5 S4 R5 V5
 * slop test: 58 gates run · contrast: pass (40–41 — accent-deep carries text signals,
 * accent never carries body text) · honest: pass (46 — figures are the product's own
 * scripted fiction) · chrome: pass (47) · tokens: pass (48) · mobile: pass (34, 49–56)
 * motion: reveals off per genre; only functional feedback moves (sweep, spinner) */

@import url("tokens.css");

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

html, body { overflow-x: clip; }

html { -webkit-text-size-adjust: none; }

body {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--color-paper);
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: var(--text-md);
  line-height: 1.5;
  padding-bottom: calc(58px + env(safe-area-inset-bottom));
  -webkit-tap-highlight-color: transparent;
}

[hidden] { display: none !important; }

/* visually hidden but focusable — keeps the file input reachable for :focus-within */
.vh {
  position: absolute;
  width: 1px; height: 1px;
  clip-path: inset(50%);
  overflow: clip;
  white-space: nowrap;
}

/* ── N9 · edge-aligned minimal ──────────────────────────────────────────── */

.bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: calc(var(--space-sm) + env(safe-area-inset-top)) var(--space-md) 0;
}
.mark {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 650;
  letter-spacing: -0.02em;
  line-height: 1;
}
.bar .dot { display: none; }
.bar .tag {
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--color-muted);
  line-height: 1;
}

/* ── stage machine ──────────────────────────────────────────────────────── */

main {
  flex: 1;
  display: flex;
  width: 100%;
}

.stage { display: none; }
.stage[data-live] {
  display: flex;
  flex-direction: column;
  width: 100%;
  padding: var(--space-lg) var(--space-md);
  animation: appear var(--dur) linear both;
}
@keyframes appear { from { opacity: 0; } to { opacity: 1; } }

/* ── 1 · his face ───────────────────────────────────────────────────────── */

.lede h1 {
  font-family: var(--font-display);
  font-size: var(--text-display);
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -0.03em;
  overflow-wrap: anywhere;
  min-width: 0;
}
.lede .sub {
  margin-top: var(--space-xs);
  color: var(--color-neutral);
  max-width: 45ch;
}

.choose {
  margin-top: var(--space-md);
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm);
  background: var(--color-card);
  border: 1px solid var(--color-rule);
  border-radius: var(--radius-card);
  cursor: pointer;
  transition: border-color var(--dur) var(--ease-out);
}
.choose:hover { border-color: var(--color-rule-2); }
.choose:active { transform: translateY(1px); }
.choose:focus-within {
  outline: 2px solid var(--color-focus);
  outline-offset: 2px;
}
.choose-mark {
  width: 44px; height: 44px;
  border-radius: 50%;
  background: var(--color-accent-soft);
  color: var(--color-accent-deep);
  display: flex; align-items: center; justify-content: center;
  flex: none;
}
.choose-mark svg { width: 21px; height: 21px; display: block; }
.choose-txt {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.01em;
  flex: 1;
  line-height: 1;
}
.choose-arrow { color: var(--color-muted); font-size: 17px; line-height: 1; }

/* what you get back — the page has to explain itself with no other context */
.hint {
  margin-top: var(--space-sm);
  font-size: var(--text-sm);
  color: var(--color-muted);
  max-width: 45ch;
}
body[data-picked] .hint { display: none; }

/* the notice page has no card between the lede and the note, so it needs the gap */
body.notice .hint { margin-top: var(--space-md); }

body:not([data-picked]) .picked { display: none; }
body[data-picked] .choose { display: none; }

.picked { margin-top: var(--space-md); }

.frame {
  position: relative;
  width: 100%;
  aspect-ratio: 1;
  border-radius: var(--radius-card);
  overflow: hidden;
  background: var(--color-card);
  border: 1px solid var(--color-rule);
}
.frame img#preview {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}

.sweep {
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 2px;
  background: var(--color-accent);
  opacity: 0;
}
.frame.reading .sweep {
  opacity: 1;
  animation: sweep 1.15s var(--ease-out) 1 forwards;
}
@keyframes sweep {
  from { transform: translateY(0); }
  to   { transform: translateY(350px); }
}
.frame.locked .sweep { opacity: 0; }

.lock .c {
  position: absolute;
  width: 22px; height: 22px;
  border: 0 solid var(--color-paper-on-ink);
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out);
}
.c.tl { border-left-width: 2px; border-top-width: 2px; }
.c.tr { border-right-width: 2px; border-top-width: 2px; }
.c.bl { border-left-width: 2px; border-bottom-width: 2px; }
.c.br { border-right-width: 2px; border-bottom-width: 2px; }
.frame.locked .c { opacity: 1; }

#cap {
  margin-top: var(--space-xs);
  font-size: var(--text-sm);
  color: var(--color-muted);
  text-align: center;
}
#cap[data-ok] {
  color: var(--color-accent-deep);
  font-weight: 600;
}

/* ── buttons — ink pill primary, outlined secondary ─────────────────────── */

.act {
  margin-top: var(--space-sm);
  width: 100%;
  height: 52px;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--color-ink-fill);
  color: var(--color-paper-on-ink);
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.01em;
  cursor: pointer;
  white-space: nowrap;
  transition: opacity var(--dur) var(--ease-out),
              transform var(--dur) var(--ease-out);
}
.act:hover { opacity: 0.92; }
.act:active { transform: translateY(1px); }
.act:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 3px;
}
.act[disabled] { opacity: 0.5; cursor: not-allowed; }

.act-quiet {
  background: transparent;
  color: var(--color-ink);
  border: 1px solid var(--color-rule-2);
}
.act-quiet:hover { opacity: 1; border-color: var(--color-neutral); }

/* ── 2 · the search — the count is the composition ──────────────────────── */

#s2 .say {
  font-family: var(--font-display);
  font-size: var(--text-title);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.2;
}

.tally { margin-top: var(--space-md); }
.tally #count {
  display: block;
  font-family: var(--font-display);
  font-size: var(--text-tally);
  font-weight: 650;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.tally em {
  display: block;
  margin-top: var(--space-2xs);
  font-style: normal;
  font-size: var(--text-sm);
  color: var(--color-muted);
}

.apps {
  margin-top: var(--space-md);
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}
.app {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  padding: var(--space-sm);
  background: var(--color-card);
  border: 1px solid var(--color-rule);
  border-radius: var(--radius-card);
  transition: opacity 380ms var(--ease-out),
              border-color var(--dur) var(--ease-out);
}
.app .who {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.app .who small {
  display: block;
  margin-top: var(--space-3xs);
  font-size: var(--text-xs);
  font-weight: 400;
  color: var(--color-muted);
}
.app .wait {
  width: 16px; height: 16px; flex: none;
  border-radius: 50%;
  border: 2px solid var(--color-rule);
  border-top-color: var(--color-accent-deep);
  animation: spin 900ms linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.app .said {
  font-size: var(--text-sm);
  color: var(--color-muted);
  font-variant-numeric: tabular-nums;
}
.app.found {
  border-color: var(--color-accent);
  background: var(--color-accent-soft);
}
.app.found .said {
  color: var(--color-accent-deep);
  font-weight: 650;
}
.app.faded { opacity: 0.4; }

/* ── 3 · the answer ─────────────────────────────────────────────────────── */

.verdict {
  font-family: var(--font-display);
  font-size: 31px;
  font-weight: 650;
  letter-spacing: -0.03em;
  line-height: 1.1;
  overflow-wrap: anywhere;
}
#s3 .note {
  margin-top: var(--space-2xs);
  font-size: var(--text-sm);
  color: var(--color-neutral);
}

.dossier {
  margin-top: var(--space-md);
  display: grid;
  grid-template-columns: 138px minmax(0, 1fr);
  background: var(--color-card);
  border: 1px solid var(--color-rule);
  border-radius: var(--radius-card);
  overflow: hidden;
}
/* The image is absolutely positioned rather than sized with height: 100%. iOS WebKit
 * resolves a percentage height inside a stretched grid item to auto, which collapsed
 * the portrait to nothing on-device while Chrome rendered it fine. */
.portrait {
  position: relative;
  min-height: 196px;   /* the absolute image no longer sizes the row, so set the floor */
  background: var(--color-rule);
}
.portrait img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.facts { padding: var(--space-sm); align-self: center; }
.facts dl {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-2xs) var(--space-sm);
  align-items: baseline;
}
.facts dt {
  font-size: var(--text-xs);
  color: var(--color-muted);
}
.facts dd {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}
.facts dd:last-of-type { color: var(--color-accent-deep); }

#s3 .act-alarm { margin-top: var(--space-md); }

/* ── Ft2 · inline single line ───────────────────────────────────────────── */

.close {
  border-top: 1px solid var(--color-rule);
  margin: 0 var(--space-md);
  padding: var(--space-sm) 0;
}
.close p {
  font-size: var(--text-sm);
  color: var(--color-muted);
}

/* ── reduced motion ─────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .stage[data-live] { animation-duration: 120ms; }
  .frame.reading .sweep { animation: none; opacity: 0.6; }
  .app .wait { animation-duration: 1.6s; }
  .act, .choose, .app { transition: none; }
}
