/* ============================================================
   StoryForge — Shared Design Tokens
   Single source of truth for the palette and fonts.
   Every page imports this before its own CSS file.
   Page-specific tokens (container colours, card colours, etc.)
   live in each page's own stylesheet.
   ============================================================ */

:root {
  /* Background */
  --bg:          #0D0C0A;

  /* Foreground scale — all contrast ratios against --bg */
  --fg:          #E8DFC8;   /* ~14.5:1  body text                              */
  --fg-muted:    #A8967A;   /* ~6.75:1  secondary body text                    */
  --fg-dim:      #9A7E58;   /* ~5.5:1   small labels and dim supporting text   */
  --fg-label:    #A68C65;   /* ~6.4:1   informational metadata (section labels)*/
  --fg-faint:    #5C4A2A;   /* ~2.28:1  DECORATIVE ONLY — ornaments, dividers  */

  /* Accent */
  --gold:        #C9A055;   /* ~7.99:1  primary accent                         */

  /* Container surfaces — shared across all reader-facing pages */
  --gold-muted:              #8A7048;
  --container-bg:            rgba(201, 160, 85, 0.03);
  --container-border:        rgba(201, 160, 85, 0.18);
  --container-bg-active:     rgba(201, 160, 85, 0.06);
  --container-border-active: rgba(201, 160, 85, 0.25);
  --inner-pill-bg:           rgba(201, 160, 85, 0.04);
  --inner-pill-border:       rgba(201, 160, 85, 0.12);
  --hairline:                rgba(201, 160, 85, 0.15);

  /* Typography */
  --font-body:   'Crimson Pro', Georgia, serif;
  --font-ui:     'Inter', system-ui, sans-serif;

  /* ==========================================================
     SF-VISUAL-01: shared visual-elevation kit
     NEW tokens only - the palette above is unchanged. Every value
     is built from the existing gold (201,160,85) over the ink --bg,
     plus a white sheen / black shadow for depth. No new hues.
     Reused by every reader-facing screen (the shared component kit).
     ========================================================== */

  /* Gold-glass surfaces (section cards, panels) - a warm gold lift off the ink ground.
     NOTE: these names are kept because they have hundreds of call sites, but they
     are now ALIASES onto the SF-VISUAL-02 ladders below. One definition per value.
     Tune the ladder, not these. */
  --glass-bg:            linear-gradient(180deg, var(--gold-s3), var(--gold-s1));
  --glass-border:        var(--gold-l3);
  --glass-catchlight:    inset 0 1px 0 rgba(201,160,85,0.14);
  --glass-shadow:        var(--e2);  /* TUNABLE (a): card depth. Drop to var(--e1) to flatten on long lists. */
  --glass-radius:        var(--r-lg);

  /* Emphasis surface (saga emblem cards) - a touch more presence */
  --glass-bg-strong:     linear-gradient(180deg, var(--gold-s4), var(--gold-s2));
  --glass-border-strong: var(--gold-l3);

  /* Lit-metal affordance (primary buttons). Highlight derived from --gold, not a new colour. */
  --lit-metal:           linear-gradient(180deg, color-mix(in srgb, var(--gold) 80%, #ffffff 20%), var(--gold));
  --lit-metal-sheen:     inset 0 1px 0 rgba(255,255,255,0.28), 0 3px 10px rgba(0,0,0,0.35);
  --btn-radius:          var(--r-md);

  /* Choice input well - TUNABLE (b): lower this one alpha to recess the choice panel, raise to warm it. */
  --choice-well-bg:      rgba(201,160,85,0.05);
  --choice-well-inset:   inset 0 1px 0 rgba(201,160,85,0.12), inset 0 2px 10px rgba(0,0,0,0.35);

  /* ==========================================================
     SF-VISUAL-02: the ladders
     Everything above this line is unchanged and still valid.

     WHY THIS EXISTS: an audit of the reader-facing CSS found 178
     hand-written rgba(201,160,85,a) values across 20+ distinct
     alphas. Six of them (0.03-0.08) were all doing one job: a faint
     surface fill. Seven more (0.10-0.30) were all doing "border".
     That is not a palette, it is drift. Same story for motion:
     0.1s / 0.12s / 0.15s / 0.18s / 0.2s / 0.22s / 150ms / 200ms /
     220ms, no easing token anywhere.

     The fix is a LADDER per job, not another pile of values. Every
     new token below is one rung on one ladder. If a surface needs a
     value that is not a rung, that is a design question, not a
     licence to inline a new alpha.
     ========================================================== */

  /* --- Gold surface ladder: how far a plane sits off the ink ---
     Rung 1 is barely there (large calm fields). Rung 4 is a raised,
     interactive plane. Pick by ELEVATION, never by taste. */
  --gold-s1:  rgba(201,160,85,0.035);
  --gold-s2:  rgba(201,160,85,0.055);
  --gold-s3:  rgba(201,160,85,0.085);
  --gold-s4:  rgba(201,160,85,0.125);

  /* --- Gold line ladder: how present an edge is ---
     l1 hairline separator, l2 resting edge, l3 hover/active edge,
     l4 committed/selected edge. */
  --gold-l1:  rgba(201,160,85,0.12);
  --gold-l2:  rgba(201,160,85,0.20);
  --gold-l3:  rgba(201,160,85,0.30);
  --gold-l4:  rgba(201,160,85,0.44);

  /* --- Scrim: the dark behind a modal ---
     Was 0.72 / 0.6 / 0.4 in three places. One value, plus an
     optional blur that degrades cleanly where unsupported. */
  --scrim:        rgba(6,5,4,0.74);
  --scrim-blur:   blur(3px) saturate(0.9);

  /* --- Elevation: depth as a scale, not per-card guesses ---
     e1 rests, e2 lifts, e3 floats (modals, popovers). */
  --e1: 0 1px 2px rgba(0,0,0,0.30);
  --e2: 0 10px 30px rgba(0,0,0,0.42);
  --e3: 0 24px 60px rgba(0,0,0,0.58), 0 2px 8px rgba(0,0,0,0.40);

  /* --- Radius ladder --- */
  --r-sm: 6px;
  --r-md: 9px;    /* matches --btn-radius   */
  --r-lg: 13px;   /* matches --glass-radius */
  --r-xl: 18px;

  /* --- Motion: duration by INTENT, one easing family ---
     The two curves are the whole vocabulary. --ease is for things
     settling into place. --ease-out is for things leaving or for
     a press, where the reader should feel the release immediately. */
  --dur-fast: 0.12s;   /* colour / border state on a control        */
  --dur-base: 0.18s;   /* the default: hover, focus, small movement */
  --dur-slow: 0.32s;   /* a panel or modal arriving                 */
  --ease:     cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-out: cubic-bezier(0.33, 0, 0.20, 1);

  /* ==========================================================
     SF-VISUAL-03: candlelight
     A warm ground and a light source. The palette was gold over a
     near-neutral black (#0D0C0A), which reads as a cold app in a
     dark theme. StoryForge is a book you are reading late, so the
     ground is warmed toward lamplit brown-black and an actual light
     is placed above the page.

     These are ADDITIVE. --bg is untouched, so no other surface
     changes until it opts in. Contrast is preserved: --fg (#E8DFC8)
     on --ink-1 measures ~14.2:1, still comfortably past AA.
     ========================================================== */

  /* Warm ground ladder, darkest at the page edge, lifting toward the light */
  --ink-0: #070605;   /* deepest, page vignette   */
  --ink-1: #100D09;   /* the warm page ground     */
  --ink-2: #16120C;   /* raised warm plane        */

  /* The candle. One soft warm source above the fold, plus the ember it throws. */
  --candle:      radial-gradient(120% 62% at 50% -8%, rgba(201,160,85,0.16), rgba(201,160,85,0.05) 42%, transparent 72%);
  --candle-warm: rgba(232, 176, 92, 0.9);

  /* Ember: a warmer, more saturated relative of --gold, reserved for the one
     primary action on a screen. It is a second temperature, not a second hue. */
  --ember:       #E0A94E;
  --ember-lit:   linear-gradient(180deg, #F0C878, var(--ember) 55%, #C08F3C);
  --ember-glow:  0 0 24px rgba(224, 169, 78, 0.30);

  /* Vellum grain. Inline SVG turbulence as a data URI, so still no network
     request and no asset file.

     This REPLACES a pair of repeating-linear-gradients. Rendered and looked at,
     those produced hard vertical corduroy banding rather than paper tooth: a
     regular 3px period lands on the device pixel grid and beats against it, and
     the effect compounded wherever two grained surfaces overlapped. Paper grain
     is NOISE, which has no period to beat against. */
  --vellum-grain:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");

  /* --- Focus ring: one definition, applied identically everywhere ---
     Standing a11y rule says gold, 2px, 2px offset. It was retyped
     at every call site; now it is a token so it cannot drift. */
  --focus-ring:   2px solid var(--gold);
  --focus-offset: 2px;
}

/* Anyone who asked not to be moved is not moved. Colour, border and
   opacity still resolve, so state remains legible without animation. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-fast: 0.01ms;
    --dur-base: 0.01ms;
    --dur-slow: 0.01ms;
  }
}

/* --- Candlelit page treatment (opt-in) ---------------------
   Add class="sf-candlelit" to <body> to light a page the way the
   account page is lit: warm ground, one soft source above the fold,
   a vignette closing the corners, and a single grain layer.

   It is a CLASS, not a global body rule, so a page opts in rather
   than being restyled without asking. Page content needs to sit in a
   positioned, z-indexed wrapper (see .sf-candlelit > * below) so it
   paints above the vignette.

   NOTE: account.css still carries its own copy of this treatment from
   the pass that introduced it. It should migrate onto this class so
   there is one implementation. Not done in the same change that
   introduced the class, to avoid destabilising a page already
   reviewed and approved. */
body.sf-candlelit {
  background-color: var(--ink-1);
  background-image: var(--candle);
  background-repeat: no-repeat;
  background-attachment: fixed;
}

body.sf-candlelit::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: radial-gradient(130% 96% at 50% 32%, transparent 52%, rgba(7,6,5,0.62) 100%);
}

body.sf-candlelit::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  opacity: 0.035;
  background-image: var(--vellum-grain);
  background-repeat: repeat;
}

/* Single source of truth for the focus ring. Any element opting in
   gets the standing treatment without restating it. */
.sf-focus:focus-visible,
a:focus-visible,
button:focus-visible,
[role="button"]:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-offset);
  border-radius: inherit;
}

/* --- hidden actually means hidden -------------------------- */

/* The browser's own `[hidden] { display: none }` lives in the UA stylesheet, so
   ANY author rule that sets `display` beats it. Every full-screen overlay in this
   codebase sets `display: flex` on its base class and is toggled with the `hidden`
   attribute — .feedback-modal (z-index 950, on nearly every page), .door-modal
   (200), .birthdate-gate (70), .forge-wait, .lore-modal-overlay. Each was
   therefore still laid out while "hidden": invisible at opacity 0, inset: 0, with
   default pointer-events — a transparent sheet over the whole viewport that
   swallowed every click on the page.

   This is the one place a global !important is right: it restores the behaviour
   the attribute is defined to have, and every opener in the codebase clears the
   attribute (`el.hidden = false`) rather than relying on a class alone, so
   nothing that should be visible is affected. */
[hidden] {
  display: none !important;
}

/* --- Accessible utility ----------------------------------- */

/* Used on auth-complete, account, and reader pages. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* --- Birthdate trio component ----------------------------- */

/* Three-select birthdate picker (Month / Day / Year).
   Shared by auth-complete and account pages.
   Relies on --container-bg / --container-border / --container-border-active
   defined in each page's own CSS; --fg and --gold from this file. */

.birthdate-trio {
  display: flex;
  gap: 8px;
}

.birthdate-select {
  flex: 1;
  min-width: 0;
  min-height: 44px;
  box-sizing: border-box;
  background: var(--container-bg);
  border: 0.5px solid var(--container-border);
  border-radius: 2px;
  padding: 10px 8px;
  color: var(--fg);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.4;
  cursor: pointer;
  color-scheme: dark;
  transition: border-color 0.15s;
}

.birthdate-select:focus {
  border-color: var(--container-border-active);
  outline: none;
}

.birthdate-select:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
  border-radius: 2px;
}

/* Year field carries 4-digit values — give it slightly more natural weight */
.birthdate-select:last-child {
  flex: 1.2;
}
