/*
 * The front page.
 *
 * A real front page, not the app with a headline bolted on: someone arriving cold has to
 * learn what this is, why it is different from every other tabletop tool, and that it is
 * meant for ONE player. Then it hands them the door.
 *
 * Everything here inherits the product's identity from realms.css — ink and leather,
 * oxblood for structure, gold means "this is a rule", ember means "do this". The front
 * page is not allowed its own look; a marketing page that does not resemble the product
 * it sells is a promise the product then breaks.
 */

body.home { overflow-y: auto; font-family: var(--prose); }

/* ═══════════════════════════════════════════════════════════════════════════
   The opening screen
   ══════════════════════════════════════════════════════════════════════════ */
.lede-screen {
  position: relative; min-height: 100svh;
  display: flex; flex-direction: column;
  padding: 0 0 1.5rem;
  isolation: isolate;
}
.lede-art {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center 42%;
  z-index: -2; filter: saturate(.72) contrast(1.04);
}
/*
 * The scrim does the real typographic work. Art behind text is only ever legible if the
 * ground under the words is genuinely dark, so this is heavy on the left and bottom where
 * the type sits, and light in the upper right where the shaft of light is worth seeing.
 */
.lede-scrim {
  position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(90deg, rgba(16,12,10,.94) 0%, rgba(16,12,10,.80) 42%, rgba(16,12,10,.42) 72%, rgba(16,12,10,.62) 100%),
    linear-gradient(180deg, rgba(16,12,10,.72) 0%, transparent 28%, transparent 46%, rgba(16,12,10,.96) 100%);
}

.lede-nav {
  display: flex; align-items: center; gap: 1rem;
  padding: 1.15rem 1.6rem; flex: none;
}
.nav-sp { flex: 1; }
.wordmark {
  font-family: var(--display); font-weight: 700; font-size: 1.05rem;
  letter-spacing: .01em; color: var(--ink); text-decoration: none; white-space: nowrap;
}
.wordmark em { font-style: normal; color: var(--ember); }
.wordmark.small { font-size: .95rem; }
.nav-link {
  font-family: var(--data); font-size: .68rem; letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink-dim); text-decoration: none;
}
.nav-link:hover { color: var(--gold); }

.lede-body {
  flex: 1; display: flex; flex-direction: column; justify-content: center;
  padding: 2rem 1.6rem; max-width: 46rem;
}
.lede-body h1 {
  font-size: clamp(2.4rem, 7vw, 5rem); line-height: .98; letter-spacing: -.03em;
  margin: .5rem 0 0; text-wrap: balance;
  text-shadow: 0 2px 30px rgba(16,12,10,.9);
}
.lede-text {
  font-size: clamp(1.02rem, 1.6vw, 1.22rem); color: var(--ink-dim);
  max-width: 34rem; margin: 1.2rem 0 0; line-height: 1.55;
}
.lede-actions { display: flex; flex-wrap: wrap; gap: .7rem; margin-top: 1.8rem; }
.btn-lg { padding: .85rem 1.5rem; font-size: .78rem; text-decoration: none; }
.lede-fine {
  font-family: var(--data); font-size: .66rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-faint); margin: 1rem 0 0;
}

/*
 * The counts are evidence, so they are set in the data face and given real size.
 *
 * The strip is built by home.js and is empty until the archive answers, so it reserves
 * its own height while busy. Without that the hero jumps a line the moment the fetch
 * lands, and a page whose first claim is "we do not round things off" should not open by
 * shifting under the reader.
 */
.lede-counts {
  display: flex; flex-wrap: wrap; margin: 0 1.6rem; flex: none;
  border-top: 1px solid var(--line); padding-top: 1rem;
  /* Spacing between stats is the item's own padding-right, not a gap, so that a wrapped
     row keeps the same rhythm as an unwrapped one. Declared once, in one place. */
  gap: 0;
}
/* Height of one filled row — label, value, and the rule above them — so the strip does
   not change size when the numbers land. */
.lede-counts[aria-busy="true"] { min-height: 3.9rem; }
.lede-counts > div { padding-right: 2.4rem; }
.lede-counts-note {
  flex: none; margin: .6rem 1.6rem 0; max-width: 34rem;
  font-family: var(--data); font-size: .66rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-faint); line-height: 1.6;
}
.lede-counts dt {
  font-family: var(--data); font-size: .6rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--ink-faint); margin: 0 0 .15rem;
}
.lede-counts dd {
  margin: 0; font-family: var(--data); font-size: 1.15rem; font-weight: 500;
  color: var(--gold); font-variant-numeric: tabular-nums;
}

/* ═══════════════════════════════════════════════════════════════════════════
   Bands
   ══════════════════════════════════════════════════════════════════════════ */
.band { padding: clamp(3.5rem, 8vw, 6.5rem) 1.6rem; border-top: 1px solid var(--line-soft); }
.band-dark { background: var(--sunken); }
.band-close { background: linear-gradient(180deg, var(--sunken), var(--black)); text-align: center; }
.band-close .lede-actions { justify-content: center; }
.band-in { max-width: 68rem; margin: 0 auto; }

.band h2 {
  font-size: clamp(1.8rem, 4vw, 2.9rem); line-height: 1.06; letter-spacing: -.022em;
  margin: .35rem 0 0; text-wrap: balance;
}
.band-lede { font-size: 1.06rem; color: var(--ink-dim); max-width: 44rem; margin: 1.1rem 0 0; }
.band-lede b.g { color: var(--gold); font-family: var(--data); font-size: .95em; }
.band-fine { font-size: .88rem; color: var(--ink-faint); margin: 1.4rem 0 0; max-width: 44rem; }

.three {
  display: grid; gap: 1.6rem; margin-top: 2.6rem;
  grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
}
.three article { border-top: 2px solid var(--blood); padding-top: 1rem; }
.three h3 { font-size: 1.15rem; margin: 0 0 .5rem; }
.three p { margin: 0; color: var(--ink-dim); font-size: .98rem; }
.three .mono { font-family: var(--data); font-size: .88em; color: var(--gold); }

.split { display: grid; gap: 2.6rem; grid-template-columns: minmax(0, 1fr); align-items: start; }
@media (min-width: 62rem) { .split { grid-template-columns: minmax(0, 1fr) 25rem; gap: 4rem; } }

/* ═══════════════════════════════════════════════════════════════════════════
   The demonstration
   ═══════════════════════════════════════════════════════════════════════════
   A real derivation from a real stat block, shown open. This is the product's one
   genuinely unusual idea, so the front page shows it working rather than describing it.
   ────────────────────────────────────────────────────────────────────────── */
.demo-stack {
  margin: 0; background: linear-gradient(180deg, var(--surface), var(--ground));
  border: 1px solid var(--line); box-shadow: var(--shadow); padding: 1.1rem 1.2rem 1rem;
  position: relative;
}
.demo-stack::before { content: ''; position: absolute; inset: -1px -1px auto -1px; height: 2px; background: var(--blood); }
.demo-stack figcaption {
  display: flex; align-items: baseline; gap: .7rem; flex-wrap: wrap;
  padding-bottom: .6rem; border-bottom: 1px solid var(--line-soft); margin-bottom: .9rem;
}
.d-name { font-family: var(--display); font-weight: 700; font-size: 1.05rem; }
.d-cite { font-family: var(--data); font-size: .65rem; color: var(--gold); margin-left: auto; }
.d-cite b { border: 1px solid var(--gold-dim); padding: 0 .3em; font-weight: 400; }

.d-total { display: flex; align-items: baseline; gap: .6rem; margin-bottom: .8rem; }
.d-v {
  font-family: var(--data); font-size: 2.1rem; font-weight: 500; line-height: 1;
  color: var(--gold); border-bottom: 1px solid var(--gold-dim); padding-bottom: 2px;
  font-variant-numeric: tabular-nums;
}
.d-k { font-family: var(--data); font-size: .62rem; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-faint); }

.d-lines { border-left: 2px solid var(--gold-dim); padding-left: .8rem; }
.d-line {
  display: grid; grid-template-columns: 2.6rem 1fr auto; gap: .2rem .7rem; align-items: baseline;
  padding: .3rem 0; border-bottom: 1px solid var(--line-soft);
}
.d-line:last-child { border-bottom: 0; }
.d-line .a { font-family: var(--data); font-size: .92rem; text-align: right; font-variant-numeric: tabular-nums; }
.d-line .t { font-family: var(--data); font-size: .66rem; letter-spacing: .1em; text-transform: uppercase; color: var(--gold); }
.d-line .c { font-family: var(--data); font-size: .6rem; color: var(--ink-faint); white-space: nowrap; }
.d-line .w { grid-column: 2 / -1; font-size: .78rem; font-style: italic; color: var(--fail); line-height: 1.35; }
/* Printed and struck, never removed — hiding it is how a player loses the ability to
   reconstruct their own sheet. */
.d-line.dead .a { text-decoration: line-through; text-decoration-color: var(--fail); color: var(--ink-faint); }
.d-line.dead .t, .d-line.dead .c { color: var(--ink-faint); }
.d-line.sum { border-top: 1px solid var(--line); border-bottom: 0; margin-top: .35rem; padding-top: .5rem; }
.d-line.sum .a { color: var(--gold); font-size: 1.05rem; }
.d-line.sum .t { color: var(--ink-dim); }
.d-extra { font-family: var(--data); font-size: .68rem; color: var(--ink-faint); margin: .8rem 0 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   The three verdicts
   ══════════════════════════════════════════════════════════════════════════ */
.verdicts { display: grid; gap: 1rem; margin-top: 2.4rem; grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr)); }
.v { border: 1px solid var(--line); background: var(--surface); padding: 1rem 1.1rem; }
.v p { margin: .6rem 0 0; font-size: .94rem; color: var(--ink-dim); }
.v-tag {
  font-family: var(--data); font-size: .66rem; letter-spacing: .16em; text-transform: uppercase;
  border: 1px solid currentColor; padding: .2rem .5rem; display: inline-block;
}
.v-legal { border-left: 3px solid var(--pass); }
.v-legal .v-tag { color: var(--pass); }
.v-blocked { border-left: 3px solid var(--fail); }
.v-blocked .v-tag { color: var(--fail); }
/*
 * Unproven gets no status colour, deliberately. Give uncertainty an amber and people
 * learn to dismiss it the way they dismiss every other amber; a neutral hatch reads as
 * unfinished, which is exactly what it is.
 */
.v-unproven { border-left: 3px dashed var(--unproven); background-image: repeating-linear-gradient(45deg, rgba(255,255,255,.022) 0 2px, transparent 2px 8px); }
.v-unproven .v-tag { color: var(--unproven); border-style: dashed; }

/* ═══════════════════════════════════════════════════════════════════════════
   The shelf
   ══════════════════════════════════════════════════════════════════════════ */
/* ── media ────────────────────────────────────────────────────────────────
   One card per walkthrough. The picture is the real screen, so it is framed like a plate
   rather than cropped like a thumbnail: a crop would cut off the citations, which are the
   point. Gold is spent only on the call to read, because on this page gold means a rule. */
.band-media { background: var(--ground); }
.media-list { list-style: none; margin: 2rem 0 0; padding: 0; display: grid; gap: 1.2rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 30rem), 1fr)); }
.media-link { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0; height: 100%;
  border: 1px solid var(--line); border-radius: 3px; overflow: hidden; background: var(--surface);
  color: inherit; text-decoration: none; transition: border-color .15s ease; }
.media-link:hover, .media-link:focus-visible { border-color: var(--gold-dim); }
.media-shot { display: block; background: var(--sunken); border-bottom: 1px solid var(--line);
  max-height: 17rem; overflow: hidden; }
.media-shot img { display: block; width: 100%; height: auto; }
.media-body { display: grid; gap: .45rem; padding: 1.1rem 1.25rem 1.3rem; }
.media-kind { font-family: var(--data); font-size: .62rem; letter-spacing: .18em; text-transform: uppercase; color: var(--ink-faint); }
.media-title { font-family: var(--display); font-weight: 700; font-size: 1.35rem; line-height: 1.2; }
.media-text { color: var(--ink-dim); font-size: .95rem; max-width: 40rem; }
.media-go { font-family: var(--data); font-size: .72rem; letter-spacing: .12em; text-transform: uppercase; color: var(--gold); margin-top: .3rem; }
.media-go::after { content: ' \2192'; }
@media (min-width: 62rem) {
  .media-link { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); }
  .media-shot { max-height: none; border-bottom: 0; border-right: 1px solid var(--line); }
  .media-body { align-content: center; }
}
@media (prefers-reduced-motion: reduce) { .media-link { transition: none; } }

.shelf { list-style: none; margin: 2rem 0 0; padding: 0; display: grid; gap: .4rem; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.shelf li {
  display: flex; align-items: baseline; gap: .6rem;
  border-bottom: 1px solid var(--line-soft); padding: .4rem .2rem;
}
.shelf .n { font-family: var(--data); font-size: .95rem; color: var(--gold); font-variant-numeric: tabular-nums; min-width: 3.6rem; }
.shelf .l { font-size: .92rem; color: var(--ink-dim); text-transform: capitalize; }

/* ═══════════════════════════════════════════════════════════════════════════
   Foot
   ══════════════════════════════════════════════════════════════════════════ */
.foot { border-top: 1px solid var(--line-soft); padding: 2rem 1.6rem 3rem; background: var(--black); }
.foot .band-in { display: flex; align-items: center; gap: 1.4rem; flex-wrap: wrap; }
.foot-links { display: flex; gap: 1.1rem; }
.foot-links a { font-family: var(--data); font-size: .68rem; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint); text-decoration: none; }
.foot-links a:hover { color: var(--gold); }
/* Empty until SOCIAL_LINKS (home.js) has real accounts in it — matches .foot-links so
   whichever links land there need no styling of their own. */
.foot-social { display: flex; gap: 1.1rem; }
.foot-social a { font-family: var(--data); font-size: .68rem; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint); text-decoration: none; }
.foot-social a:hover { color: var(--gold); }
.foot-fine { margin-left: auto; font-family: var(--data); font-size: .62rem; color: var(--ink-faint); }
.foot-legal { max-width: 68rem; margin: 1.2rem auto 0; font-size: .78rem; color: var(--ink-faint); }

/* ═══════════════════════════════════════════════════════════════════════════
   Request access
   ═══════════════════════════════════════════════════════════════════════════
   The same panel grammar as the workshop's peek: the surface, a hairline of oxblood at the
   head, ember for the one thing to do. Gold is not spent here — nothing on this form is a rule. */
.ask {
  width: min(32rem, calc(100vw - 2rem)); max-height: calc(100svh - 2rem);
  padding: 0; border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  box-shadow: var(--shadow); overflow: auto;
}
.ask::before { content: ''; position: sticky; top: 0; display: block; height: 2px; background: var(--blood); }
.ask::backdrop { background: rgba(12, 9, 8, .78); }
.ask-x {
  position: absolute; top: .5rem; right: .5rem; width: 2.6rem; height: 2.6rem;
  background: none; border: 0; color: var(--ink-dim); font-size: 1.6rem; line-height: 1; cursor: pointer;
}
.ask-x:hover { color: var(--ink); }
.ask-face { padding: 1.6rem clamp(1.1rem, 4vw, 2rem) 1.8rem; font-family: var(--prose); }
.ask-face:focus { outline: none; }
.ask-kicker {
  margin: 0; font-family: var(--data); font-size: .62rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--ember);
}
.ask-face h2 {
  margin: .35rem 2rem 0 0; font-family: var(--display); font-size: clamp(1.35rem, 4vw, 1.75rem);
  line-height: 1.12; letter-spacing: -.015em; text-wrap: balance;
}
.ask-lede { margin: .8rem 0 0; color: var(--ink-dim); font-size: 1rem; line-height: 1.5; }
.ask-field { margin-top: 1.1rem; display: grid; gap: .35rem; }
.ask-field label {
  font-family: var(--data); font-size: .66rem; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-dim);
}
.ask-opt { color: var(--ink-faint); text-transform: none; letter-spacing: .02em; margin-left: .35rem; }
.ask-field input {
  width: 100%; min-height: 44px; padding: .6rem .75rem;
  background: var(--ground); color: var(--ink); border: 1px solid var(--line); border-radius: 2px;
  font-family: var(--prose); font-size: 1rem;
}
.ask-field input:focus { border-color: var(--focus); outline: none; }
.ask-field input[aria-invalid="true"] { border-color: var(--fail); }
.ask-field .field-err { margin: 0; }
.ask-check:not(:empty) { margin-top: 1rem; }
.ask-err { margin: 1rem 0 0; color: var(--fail-text); font-size: .95rem; }
.ask-acts { display: flex; flex-wrap: wrap; gap: .7rem; margin-top: 1.5rem; }
.ask-acts .btn { min-height: 44px; justify-content: center; }
#ask-send[aria-busy="true"] { opacity: .7; cursor: progress; }
/* .btn sets its own display, which would beat the hidden attribute on the Request access buttons. */
[data-ask][hidden] { display: none !important; }

@media (max-width: 40em) {
  /*
   * Measured on real device metrics (375 CSS px): wordmark + two nav-links + the sign-in
   * button add up to 427px in this row, 52px past the viewport — the row has no wrap and
   * the button was pinned off the right edge, unreachable without scrolling sideways.
   * Workshop and Archive are both one screen down as full-width CTAs and in the footer,
   * so dropping them from the header here loses no path, only the crowding.
   */
  .lede-nav { gap: .6rem; padding: 1rem 1.1rem; }
  .lede-nav .nav-link { display: none; }
  /* The sign-in button is the one primary control left in the header; 29.7px tall
     measured at 375px is short of a comfortable tap target. */
  .lede-nav #signin-top { min-height: 44px; padding-top: 0; padding-bottom: 0; }

  .lede-counts > div { padding-right: 1.3rem; }
  .lede-counts dd { font-size: 1rem; }
  .lede-counts[aria-busy="true"] { min-height: 3.6rem; }
  .foot-fine { margin-left: 0; }

  /*
   * The derivation's third column holds a citation set `white-space: nowrap`, because a
   * page reference broken across two lines stops looking like a page reference. At 380px
   * that column plus the modifier and its type is wider than the card, and a nowrap grid
   * track cannot shrink — it pushes the whole document sideways instead. So on a narrow
   * screen the citation drops to its own row under the type it belongs to, which is what
   * the struck-bonus row already does with its reason.
   */
  .d-line { grid-template-columns: 2.6rem 1fr; }
  .d-line .c { grid-column: 2 / -1; white-space: normal; }
}

/* The header's page links: 25px tall under a finger (device gate round two, 2026-09-29). */
@media (pointer: coarse) {
  .nav-link { min-height: 44px; display: inline-flex; align-items: center; }
}

/* ── label floor (generated by tools/label-floor.mjs; do not edit by hand) ── */
@media (pointer: coarse) {
  .wordmark.small,
  .band-fine,
  .three p,
  .d-cite,
  .d-line .a,
  .d-line .c,
  .d-line .w,
  .d-extra,
  .v p,
  .media-text,
  .shelf .n,
  .shelf .l,
  .foot-fine,
  .foot-legal,
  .ask-err { font-size: 1rem; }
  .band-lede b.g { font-size: max(1rem, .95em); }
  .three .mono { font-size: max(1rem, .88em); }
}
@media (pointer: coarse) {
  .nav-link,
  .btn-lg,
  .lede-fine,
  .lede-counts-note,
  .lede-counts dt,
  .d-k,
  .d-line .t,
  .v-tag,
  .media-kind,
  .media-go,
  .foot-links a,
  .foot-social a,
  .ask-kicker,
  .ask-field label { font-size: 1rem; letter-spacing: .05em; }
}
@media (pointer: fine) {
  .d-cite,
  .d-line .c,
  .d-line .w,
  .d-extra,
  .foot-fine,
  .foot-legal { font-size: .875rem; }
  .band-lede b.g { font-size: max(.875rem, .95em); }
  .three .mono { font-size: max(.875rem, .88em); }
}
@media (pointer: fine) {
  .nav-link,
  .btn-lg,
  .lede-fine,
  .lede-counts-note,
  .lede-counts dt,
  .d-k,
  .d-line .t,
  .v-tag,
  .media-kind,
  .media-go,
  .foot-links a,
  .foot-social a,
  .ask-kicker,
  .ask-field label { font-size: .875rem; letter-spacing: .05em; }
}
/* ── end label floor ── */
