/* ============================================================
   StoryForge Account Page — Codex Identity
   ============================================================ */

/* --- Reset ------------------------------------------------ */

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

/* --- Base ------------------------------------------------- */

html {
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-body);
  line-height: 1.6;
  min-height: 100dvh;
}

/* --- Page layout ------------------------------------------ */

.account-page {
  max-width: 560px;
  margin: 0 auto;
  padding: 0 24px 80px;
}

/* --- Brand block ------------------------------------------ */

.brand-block {
  text-align: center;
  padding: 18px 0 20px;
}

.brand-wordmark {
  font-family: var(--font-body);
  font-size: 25px;
  font-weight: 400;
  letter-spacing: 0.03em;
  color: var(--gold);
  /* line-height: 1 clipped the descender. The SF-VISUAL-01 block below paints
     this wordmark with background-clip: text over a transparent colour, and
     background-clip paints glyphs only inside the element's background box, so
     anything falling outside it gets no paint at all. At line-height 1 the box
     is exactly the font size, the tail of the "g" hangs below it, and it simply
     vanished. The box has to be tall enough to contain the descenders it is
     clipping to. Same fix as .welcome-wordmark. */
  line-height: 1.18;
  padding-bottom: 0.06em;
  /* Was 10px. The two rules above add exactly 0.24em of height (0.18 of
     line-height plus 0.06 of padding), so taking that back off the margin keeps
     the brand block the height it already was and leaves the anchor where it
     was. Expressed in em rather than as a flat 4px because the wordmark shrinks
     to 22px under the mobile breakpoint, where a fixed subtraction would
     over-correct and pull the anchor up. */
  margin-bottom: calc(10px - 0.24em);
  /* faint warm glow off the gold - no new colour */
  text-shadow: 0 0 22px rgba(201, 160, 85, 0.28);
}

.brand-anchor {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
}

/* Gold gradient rules replacing the sub-visible --fg-faint hairlines (SF-VISUAL-01) */
.brand-line {
  height: 1px;
  width: 92px;
  background: linear-gradient(90deg, transparent, rgba(201, 160, 85, 0.55));
}
.brand-anchor .brand-line:last-child {
  background: linear-gradient(90deg, rgba(201, 160, 85, 0.55), transparent);
}

/* Crafted signet: inner gold diamond + concentric outline (SF-VISUAL-01) */
.brand-diamond {
  position: relative;
  height: 13px;
  width: 13px;
  background: transparent;
  transform: none;
  flex-shrink: 0;
}
.brand-diamond::before {
  content: "";
  position: absolute;
  inset: 0;
  transform: rotate(45deg);
  border: 1px solid rgba(201, 160, 85, 0.55);
  border-radius: 1px;
}
.brand-diamond::after {
  content: "";
  position: absolute;
  inset: 4px;
  transform: rotate(45deg);
  background: var(--gold);
  border-radius: 1px;
  box-shadow: 0 0 8px rgba(201, 160, 85, 0.6);
}

/* --- Loading state ---------------------------------------- */

.account-loading {
  text-align: center;
  padding-top: 40px;
}

.account-loading-text {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 20px;
  color: var(--fg-muted);
}

/* --- Container pattern ------------------------------------ */

.codex-container {
  position: relative;
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  border-radius: var(--glass-radius);
  box-shadow: var(--glass-catchlight), var(--glass-shadow);
  padding: 30px 28px;
  margin-bottom: 22px;
}

.codex-container--attention {
  background: rgba(201, 160, 85, 0.05);
  border-color: rgba(201, 160, 85, 0.3);
}

.codex-container--quiet {
  background: transparent;
  border: none;
  border-top: 0.5px solid var(--hairline);
  border-radius: 0;
  box-shadow: none;
  padding: 20px 0;
  margin-bottom: 8px;
}

.codex-container--quiet .codex-label {
  color: var(--fg-dim);
  letter-spacing: 0.24em;
  margin-bottom: 10px;
}

/* Section label with a signet tick (SF-VISUAL-01: matches the approved render;
   replaces the centered top-border tab). */
.codex-label {
  position: static;
  transform: none;
  display: flex;
  align-items: center;
  gap: 8px;
  background: transparent;
  padding: 0;
  margin-bottom: 16px;
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 600;
  color: var(--fg-label);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  white-space: nowrap;
}
.codex-label::before {
  content: "";
  width: 5px;
  height: 5px;
  background: var(--gold);
  transform: rotate(45deg);
  box-shadow: 0 0 6px rgba(201, 160, 85, 0.5);
  flex-shrink: 0;
}

.codex-label--attention {
  color: var(--gold);
}

/* --- LEDGER: identity block ------------------------------- */

.ledger-identity {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 20px;
  padding-bottom: 16px;
  border-bottom: 0.5px solid var(--hairline);
}

.ledger-identity-left {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}

.steam-avatar {
  width: 44px;
  height: 44px;
  border-radius: 4px;
  object-fit: cover;
  flex-shrink: 0;
}

.ledger-identity-text {
  min-width: 0;
}

.account-name {
  font-family: var(--font-body);
  font-size: 26px;
  color: var(--gold);
  line-height: 1.2;
}

.account-email {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 13px;
  color: var(--fg-dim);
  margin-top: 2px;
}

.account-signout-btn {
  all: unset;
  font-family: var(--font-ui);
  font-size: 12px;
  letter-spacing: 0.05em;
  color: var(--fg-dim);
  cursor: pointer;
  white-space: nowrap;
  flex-shrink: 0;
  transition: color var(--dur-fast) var(--ease);
}

@media (hover: hover) and (pointer: fine) {
  .account-signout-btn:hover {
    color: var(--fg-muted);
  }
}

.account-signout-btn:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
  border-radius: 2px;
}

/* --- LEDGER: credits pill --------------------------------- */

.sub-pill {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 14px 16px;
  background: var(--inner-pill-bg);
  border: 0.5px solid var(--inner-pill-border);
  border-radius: 2px;
  margin-bottom: 16px;
}

.sub-pill-left {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.sub-credits-label {
  font-family: var(--font-ui);
  font-size: 11px;
  letter-spacing: 0.2em;
  color: var(--fg-dim);
  text-transform: uppercase;
}

.sub-credits-number {
  font-family: var(--font-body);
  font-size: 24px;
  color: var(--fg);
  line-height: 1;
}

.sub-buy-more {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 13px;
  color: var(--gold);
  text-decoration: none;
  padding: 6px 14px;
  border: 0.5px solid rgba(201, 160, 85, 0.4);
  border-radius: 2px;
  transition: border-color 0.15s, color 0.15s;
  white-space: nowrap;
}

@media (hover: hover) and (pointer: fine) {
  .sub-buy-more:hover {
    border-color: rgba(201, 160, 85, 0.7);
    color: var(--gold);
  }
}

/* --- REFERRALS content ------------------------------------ */

.ref-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 14px;
}

.ref-heading {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 17px;
  color: var(--fg);
}

.ref-coming-soon {
  font-family: var(--font-ui);
  font-size: 10px;
  letter-spacing: 0.2em;
  color: var(--fg-label);
  text-transform: uppercase;
  white-space: nowrap;
  flex-shrink: 0;
}

.ref-blurb {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 15px;
  color: var(--fg-muted);
  line-height: 1.65;
  margin-bottom: 14px;
  max-width: 60ch;
}

.ref-cta-link {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 13px;
  color: var(--gold);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease);
}

@media (hover: hover) and (pointer: fine) {
  .ref-cta-link:hover {
    color: var(--fg-muted);
  }
}

/* Referral enabled state */
.ref-label {
  font-family: var(--font-ui);
  font-size: 10px;
  letter-spacing: 0.2em;
  color: var(--fg-dim);
  text-transform: uppercase;
  margin-bottom: 6px;
}

.ref-link-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  background: rgba(201, 160, 85, 0.04);
  border: 0.5px solid rgba(201, 160, 85, 0.12);
  border-radius: 2px;
  padding: 10px 14px;
  margin-bottom: 12px;
}

.ref-link-text {
  font-family: var(--font-ui);
  font-size: 13px;
  color: var(--fg);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
  min-width: 0;
}

.ref-copy-btn {
  all: unset;
  display: inline-flex;
  align-items: center;
  box-sizing: border-box;
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 500;
  color: var(--gold);
  cursor: pointer;
  white-space: nowrap;
  padding: 3px 8px;
  min-height: 44px;
  border: 0.5px solid rgba(201, 160, 85, 0.35);
  border-radius: 2px;
  transition: border-color 0.15s;
  flex-shrink: 0;
}

@media (hover: hover) and (pointer: fine) {
  .ref-copy-btn:hover {
    border-color: rgba(201, 160, 85, 0.6);
  }
}

.ref-copy-btn:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
  border-radius: 2px;
}

.ref-copy-toast {
  font-family: var(--font-ui);
  font-size: 12px;
  color: var(--gold);
  margin-bottom: 12px;
}

.ref-stats-list {
  list-style: none;
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--fg-dim);
  line-height: 1.9;
  margin-bottom: 14px;
}

.ref-stats-list li::before {
  content: '— ';
  color: var(--fg-faint);
}

.account-referrals-capacity {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 12px;
  color: var(--fg-dim);
  margin-top: 12px;
  margin-bottom: 2px;
}

.account-referrals-capacity--zero {
  color: var(--fg-muted);
}

.account-referrals-warning {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 12px;
  color: var(--fg-dim);
  border-bottom: 1px solid var(--hairline);
  padding-bottom: 10px;
  margin-top: 10px;
  margin-bottom: 10px;
}

/* --- YOUR SAGAS content ----------------------------------- */

/* REMOVED (dedupe): the legacy `.saga-card`, `.saga-card::before` and
   `.saga-card:last-child` rules stood here. They predate the elevated card and
   were silently losing to it on every shared property, while still winning on
   the two it never redeclared:

     overflow: hidden   — clipped the ... menu dropdown, which is why the
                          elevated rule had to force `overflow: visible`.
     margin-bottom:15px — stacked on top of `.saga-grid { gap: 0.85em }`, so
                          cards sat ~28px apart instead of the intended ~14px.

   Everything else it declared (display, position, background, border, radius,
   box-shadow, padding) is set by the authoritative rule below and its two
   documented layers. `text-decoration`/`color: inherit` were vestigial from
   when a card was an <a>; it is a <div> now (account.js buildSagaCard).

   The authoritative definition is "elevated saga card" further down this file,
   layered by SF-VISUAL-03 (paper lit from above), SF-VISUAL-04 (flex column so
   grid-row heights match) and SF-VISUAL-05 (spine inset). Those are deliberate
   sequential layers, not duplicates — do not merge them. */

/* Episode count as a gold-glass pill */
.saga-card-episode-tag {
  position: absolute;
  top: 14px;
  right: 14px;
  font-family: var(--font-ui);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.16em;
  color: var(--gold);
  text-transform: uppercase;
  background: rgba(201, 160, 85, 0.10);
  border: 1px solid rgba(201, 160, 85, 0.28);
  border-radius: 20px;
  padding: 4px 10px;
}

.saga-card-saga-label {
  font-family: var(--font-ui);
  font-size: 11px;
  letter-spacing: 0.25em;
  color: var(--fg-dim);
  text-transform: uppercase;
  margin-bottom: 6px;
}

/* Which vault a saga is in, shown only in the vault view. Same quiet small-caps
   as the label above it, but at --fg-label rather than --fg-dim: this is real
   information a reader with two vaults needs to read, not decoration, and
   --fg-dim sits below --fg-label on contrast. */
.saga-card-vault-tag {
  font-family: var(--font-ui);
  font-size: 11px;
  letter-spacing: 0.2em;
  color: var(--fg-label);
  text-transform: uppercase;
  margin: 0 0 6px;
}

.saga-card-name {
  font-family: var(--font-body);
  font-size: 30px;
  color: var(--gold);
  line-height: 1.15;
  margin-bottom: 4px;
}

.saga-card-title {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 16px;
  color: var(--fg-muted);
  margin-bottom: 20px;
}

.saga-card-affordances {
  display: flex;
  align-items: center;
  gap: 20px;
}

/* Lit-metal primary affordance (SF-VISUAL-01) */
.saga-continue {
  font-family: var(--font-ui);
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--bg);
  background: var(--lit-metal);
  border: none;
  border-radius: var(--btn-radius);
  padding: 9px 16px;
  box-shadow: var(--lit-metal-sheen);
  text-decoration: none;
  transition: filter 0.15s;
}

@media (hover: hover) and (pointer: fine) {
  .saga-continue:hover {
    color: var(--bg);
    filter: brightness(1.06);
  }
}

.saga-episodes {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 13px;
  color: var(--fg-dim);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease);
}

@media (hover: hover) and (pointer: fine) {
  .saga-episodes:hover {
    color: var(--fg-muted);
  }
}

.saga-continue--primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--lit-metal);
  color: var(--bg);
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.05em;
  min-height: 44px;
  padding: 0 18px;
  box-sizing: border-box;
  border-radius: var(--btn-radius);
  border-bottom: none;
  box-shadow: var(--lit-metal-sheen);
  transition: filter 0.12s;
}

@media (hover: hover) and (pointer: fine) {
  .saga-continue--primary:hover {
    filter: brightness(1.06);
    color: var(--bg);
  }
}

.saga-continue--primary:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
  border-radius: var(--btn-radius);
}

/* --- Saga card overflow menu ------------------------------ */

/* ---- The whole card continues the saga --------------------------------------
   The anchor stays the real control and simply stretches its hit area across the
   card. It keeps its href, so Enter activates it, middle-click and
   open-in-new-tab still work, and screen readers still announce a link — none of
   which a div with an onclick would give us.
   .saga-card is already position:relative, so inset:0 resolves against the card.
   .saga-continue must stay position:static or the pseudo-element would stretch
   over the anchor's own little box instead. */
.saga-continue::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

/* The whole face is the button now. */
.saga-card {
  cursor: pointer;
}

/* Reads as interactive. Hover is desktop-only: on touch it sticks after a tap and
   the card would sit lifted until you tapped something else. */
@media (hover: hover) and (pointer: fine) {
  .saga-card:hover {
    border-color: rgba(201, 160, 85, 0.34);
    transform: translateY(-2px);
    box-shadow:
      inset 0 1px 0 rgba(201, 160, 85, 0.2),
      0 10px 28px rgba(0, 0, 0, 0.5),
      0 0 22px rgba(201, 160, 85, 0.07);
  }
}

/* Press state — the one that carries the whole affordance on mobile. */
.saga-card:active {
  transform: translateY(0) scale(0.994);
  transition-duration: 60ms;
}

/* Keyboard focus lands on the anchor, which keeps its own ring; the card echoes
   it so the target being activated is the thing that looks selected. A ring on
   both would read as two controls. */
.saga-card:has(.saga-continue:focus-visible) {
  border-color: rgba(201, 160, 85, 0.45);
  box-shadow:
    inset 0 1px 0 rgba(201, 160, 85, 0.2),
    0 0 0 1px rgba(201, 160, 85, 0.28),
    0 10px 28px rgba(0, 0, 0, 0.5);
}

.saga-continue:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
  border-radius: var(--btn-radius);
}

@media (prefers-reduced-motion: reduce) {
  .saga-card:hover,
  .saga-card:active { transform: none; }
}

/* Above the stretched link, so a tap here opens options instead of continuing the
   saga. The layering is what separates them — the JS stopPropagation below is a
   second line of defence, not the mechanism. */
.card-menu {
  position: relative;
  flex-shrink: 0;
  z-index: 1;
}

.card-menu-btn {
  all: unset;
  display: flex;
  align-items: center;
  justify-content: center;
  /* WCAG 2.5.5 — was 40px. It matters more now that it is the one spot on the
     card that must NOT continue the saga: an undersized target here means a
     mis-tap navigates away instead of opening options. */
  width: 44px;
  height: 44px;
  font-size: 16px;
  letter-spacing: 0.1em;
  color: var(--fg-faint);
  cursor: pointer;
  border-radius: 2px;
  box-sizing: border-box;
  transition: color var(--dur-fast) var(--ease);
}

@media (hover: hover) and (pointer: fine) {
  .card-menu-btn:hover {
    color: var(--fg-muted);
  }
}

.card-menu-btn:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
  border-radius: 2px;
}

.card-menu-dropdown {
  position: absolute;
  bottom: calc(100% + 4px);
  right: 0;
  min-width: 130px;
  background: #1A1814;
  border: 0.5px solid rgba(201, 160, 85, 0.28);
  border-radius: 2px;
  z-index: 100;
  overflow: hidden;
}

.card-menu-dropdown[hidden] {
  display: none;
}

/* The z-index: 100 above can only compete INSIDE the card, because .saga-card
   sets isolation: isolate and is therefore a stacking context. Raising that 100
   to any number changes nothing on the page: the whole card is one layer as far
   as the rest of the page is concerned. So the card itself is what has to lift,
   carrying the open menu with it.
   3 is deliberately small. It needs to clear sibling cards and the segmented
   control, and it must stay far below .vault-overlay (200) so the PIN dialog and
   its scrim always cover an open menu. */
.saga-card:has(.card-menu-dropdown:not([hidden])) {
  z-index: 3;
}

.card-menu-item {
  all: unset;
  display: block;
  width: 100%;
  box-sizing: border-box;
  padding: 11px 16px;
  font-family: var(--font-body);
  font-style: italic;
  font-size: 14px;
  color: var(--fg-muted);
  cursor: pointer;
  transition: color 0.12s, background 0.12s;
}

@media (hover: hover) and (pointer: fine) {
  .card-menu-item:hover {
    color: var(--fg);
    background: rgba(201, 160, 85, 0.06);
  }
}

.card-menu-item:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

/* --- Shelf section (account page) ------------------------- */

.saga-shelf-section {
  padding-top: 8px;
}

.saga-shelf-toggle {
  all: unset;
  display: block;
  width: 100%;
  text-align: center;
  font-family: var(--font-body);
  font-style: italic;
  font-size: 14px;
  color: var(--fg-dim);
  cursor: pointer;
  padding: 12px 0;
  border-top: 0.5px solid var(--hairline);
  box-sizing: border-box;
  transition: color var(--dur-fast) var(--ease);
}

@media (hover: hover) and (pointer: fine) {
  .saga-shelf-toggle:hover {
    color: var(--fg-muted);
  }
}

.saga-shelf-toggle:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
  border-radius: 2px;
}

.saga-shelf-list {
  padding-top: 8px;
}

.saga-shelf-list[hidden] {
  display: none;
}

.saga-shelf-list .saga-card {
  opacity: 0.7;
  transition: opacity 0.2s;
}

@media (hover: hover) and (pointer: fine) {
  .saga-shelf-list .saga-card:hover {
    opacity: 1;
  }
}

/* No sagas empty state */
.no-sagas-text {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 15px;
  color: var(--fg-muted);
  text-align: center;
  margin-bottom: 20px;
}

/* Outlined pill (SF-VISUAL-01) - matches the approved render */
.new-saga-link {
  display: block;
  text-align: center;
  margin-top: 16px;
  padding: 11px;
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--gold);
  text-decoration: none;
  border: 1px solid rgba(201, 160, 85, 0.28);
  border-radius: var(--btn-radius);
  background: rgba(201, 160, 85, 0.04);
  transition: background 0.15s;
}
@media (hover: hover) and (pointer: fine) {
  .new-saga-link:hover {
    background: rgba(201, 160, 85, 0.08);
  }
}

@media (hover: hover) and (pointer: fine) {
  .new-saga-link:hover {
    color: var(--fg-muted);
  }
}

/* --- Buttons ---------------------------------------------- */

.btn-filled {
  all: unset;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.05em;
  background: var(--lit-metal);
  color: var(--bg);
  padding: 12px 24px;
  min-height: 44px;
  box-sizing: border-box;
  border-radius: var(--btn-radius);
  box-shadow: var(--lit-metal-sheen);
  cursor: pointer;
  text-decoration: none;
  transition: background 0.12s;
}

@media (hover: hover) and (pointer: fine) {
  .btn-filled:hover {
    background: rgba(201, 160, 85, 0.85);
  }
}

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

.btn-outlined {
  all: unset;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-ui);
  font-size: 14px;
  letter-spacing: 0.05em;
  color: var(--gold);
  border: 0.5px solid var(--gold);
  padding: 12px 24px;
  min-height: 44px;
  box-sizing: border-box;
  border-radius: 2px;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.15s;
}

@media (hover: hover) and (pointer: fine) {
  .btn-outlined:hover {
    background: rgba(201, 160, 85, 0.06);
  }
}

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

/* --- ATTENTION container content -------------------------- */

.attention-body {
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--fg);
  line-height: 1.55;
  margin-bottom: 18px;
}

.birthdate-section-field {
  margin-bottom: 12px;
}

.birthdate-section-label {
  display: block;
  font-family: var(--font-ui);
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg-muted);
  margin-bottom: 8px;
}

.birthdate-section-input {
  font-family: var(--font-body);
  font-size: 15px;
  background: rgba(201, 160, 85, 0.04);
  border: 0.5px solid rgba(201, 160, 85, 0.2);
  color: var(--fg);
  padding: 10px 14px;
  border-radius: 2px;
  width: 100%;
  max-width: 240px;
  box-sizing: border-box;
}

.birthdate-section-error {
  font-family: var(--font-ui);
  font-size: 13px;
  color: #B06040;
  margin-top: 8px;
}

.birthdate-section-actions {
  margin-top: 12px;
}

/* --- Toast ------------------------------------------------ */

.account-toast {
  font-family: var(--font-body);
  font-size: 14px;
  padding: 12px 16px;
  border-radius: 2px;
  margin-bottom: 16px;
  border: 0.5px solid var(--container-border);
}

.account-toast--success {
  background: rgba(201, 160, 85, 0.08);
  color: var(--gold);
  border-color: rgba(201, 160, 85, 0.25);
}

.account-toast--info {
  background: rgba(201, 160, 85, 0.03);
  color: var(--fg-muted);
}

/* --- How It Works link ------------------------------------ */

.how-it-works-link {
  display: inline-block;
  margin-top: 12px;
  font-family: var(--font-ui);
  font-size: 12px;
  letter-spacing: 0.05em;
  color: var(--fg-dim);
  text-decoration: none;
  transition: color 0.12s;
}

@media (hover: hover) and (pointer: fine) {
  .how-it-works-link:hover {
    color: var(--gold);
  }
}

/* --- What's New update card ------------------------------- */

.update-card {
  border-top: 0.5px solid var(--hairline);
  background: transparent;
  border-radius: 0;
  padding: 0;
  margin-bottom: 24px;
}

.whats-new-header {
  all: unset;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 14px 0;
  width: 100%;
  box-sizing: border-box;
  cursor: pointer;
}

@media (hover: hover) and (pointer: fine) {
  .whats-new-header:hover .update-card-label-text {
    color: var(--fg-muted);
  }
}

.whats-new-header:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
  border-radius: 2px;
}

.update-card-dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--gold);
  flex-shrink: 0;
}

.update-card-label-text {
  font-family: var(--font-ui);
  font-size: 10px;
  letter-spacing: 0.28em;
  color: var(--gold);
  text-transform: uppercase;
}

.whats-new-chevron {
  margin-left: auto;
  color: var(--fg-dim);
  font-size: 16px;
  line-height: 1;
  transition: transform 0.2s;
}

.whats-new-header[aria-expanded="true"] .whats-new-chevron {
  transform: rotate(90deg);
}

.whats-new-body {
  padding-bottom: 12px;
}

.whats-new-body[hidden] {
  display: none;
}

.whats-new-intro {
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--fg-muted);
  line-height: 1.55;
  margin-bottom: 10px;
}

.whats-new-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.whats-new-item {
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--fg-muted);
  line-height: 1.55;
  padding: 3px 0 3px 1.4em;
  position: relative;
}

.whats-new-item::before {
  content: '·';
  position: absolute;
  left: 0;
  color: var(--gold);
}

.whats-new-item:first-child {
  color: var(--fg);
}

.whats-new-hidden {
  display: none;
}

.whats-new-list.whats-new-expanded .whats-new-hidden {
  display: list-item;
}

.whats-new-toggle {
  all: unset;
  font-family: var(--font-ui);
  font-size: 12px;
  letter-spacing: 0.08em;
  color: var(--fg-label);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
  display: block;
  margin-top: 10px;
}

@media (hover: hover) and (pointer: fine) {
  .whats-new-toggle:hover {
    color: var(--fg);
  }
}

.whats-new-toggle:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
  border-radius: 2px;
}

/* --- Feedback / Help shape your stories section ----------- */

.feedback-account-blurb {
  font-family: var(--font-body);
  font-size: 16px;
  color: var(--fg-muted);
  line-height: 1.55;
  margin-bottom: 14px;
}

.feedback-account-blurb--last {
  margin-bottom: 20px;
}

.feedback-account-btn {
  margin-top: 4px;
}

/* --- Anonymous state -------------------------------------- */

.anon-body {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 17px;
  color: var(--fg-muted);
  margin-bottom: 24px;
}

/* --- Ended saga card -------------------------------------- */

.saga-card--ended {
  opacity: 0.85;
}

.saga-card-ended-tag {
  position: absolute;
  top: 12px;
  right: 14px;
  font-family: var(--font-body);
  font-style: italic;
  font-size: 11px;
  letter-spacing: 0.15em;
  color: var(--fg-dim);
}

.saga-card--ended .saga-card-name {
  color: var(--fg-muted);
}

/* --- Responsive ------------------------------------------- */

@media (max-width: 479px) {
  .brand-wordmark {
    font-size: 22px;
  }

  .brand-line {
    width: 80px;
  }

  .codex-container {
    padding: 28px 20px;
  }

  .ledger-identity {
    align-items: flex-start;
    flex-wrap: wrap;
  }

  .ref-header {
    flex-wrap: wrap;
    gap: 6px;
  }

  .saga-card-name {
    font-size: 26px;
  }
}

@media (max-width: 360px) {
  .saga-card-affordances {
    flex-wrap: wrap;
    gap: 10px 12px;
  }
}

/* --- Secondary store link ----------------------------------- */

.sub-store-link {
  display: block;
  text-align: center;
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.05em;
  color: var(--gold);
  text-decoration: none;
  padding: 10px;
  margin-top: 8px;
  border: 0.5px solid rgba(201, 160, 85, 0.3);
  border-radius: 2px;
  transition: background 0.12s, border-color 0.12s;
}

@media (hover: hover) and (pointer: fine) {
  .sub-store-link:hover {
    background: rgba(201, 160, 85, 0.06);
    border-color: rgba(201, 160, 85, 0.5);
  }
}



/* --- Platform status banner -------------------------------- */

.platform-status-banner {
  background: rgba(201, 160, 85, 0.08);
  border: 1px solid var(--gold);
  border-radius: 4px;
  padding: 16px 20px;
  margin-bottom: 24px;
  font-family: var(--font-ui);
  font-size: 14px;
  color: var(--fg);
  line-height: 1.5;
}

/* ===========================================================================
   ACCOUNT REDESIGN — the saga zone
   ---------------------------------------------------------------------------
   The page did not look flat because the token system is thin. It looked flat
   because it used about four of its crayons. --glass-*, --lit-metal,
   --container-bg-active / --container-border-active, --choice-well-bg / inset,
   --inner-pill-*, and --gold-muted were all designed and left unused. This
   section applies them. No new colours are introduced.

   Hierarchy comes from restraint: the saga zone gets the strong treatment and
   everything below it stays quiet.
   ======================================================================== */

.saga-zone {
  /* Deliberately NOT .codex-container. The hero zone is the one place with the
     stronger glass surface, which is what makes it read as the focal point. */
  background: var(--glass-bg-strong);
  border: 1px solid var(--glass-border-strong);
  border-radius: var(--glass-radius);
  box-shadow: var(--glass-shadow);
  padding: 1.25em 1.1em 1.4em;
  margin-bottom: 1.75em;
}

/* --- credit bar: balance + the primary buy affordance --------------------- */

/* This used to live in the LEDGER, down in the quiet footer region, as a small
   outlined link. That put the buy action furthest from the moment it is needed.
   It now sits at the head of the saga zone, and it is the ONE element on the
   page wearing --lit-metal, which is the token reserved for a primary verb. */
.credit-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1em;
  flex-wrap: wrap;
  margin: 0.9em 0 0;
  padding: 0.85em 0.5em 0.9em 0.15em;
  border-bottom: 1px solid var(--hairline);
}

.credit-bar[hidden] { display: none; }

.credit-bar-left {
  display: flex;
  align-items: baseline;
  gap: 0.45em;
  min-width: 0;
}

/* The balance is a number worth reading, so it is set like one. */
.credit-bar-count {
  font-family: var(--font-body);
  font-size: 30px;
  line-height: 1;
  color: var(--fg);
  letter-spacing: -0.015em;
}

.credit-bar-unit {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 14px;
  color: var(--fg-label);
}

/* Lit metal. Dark ink on gold, which is the highest-contrast pairing available
   in the palette and reads as the only pressable thing in the zone. */
.credit-bar-buy {
  flex-shrink: 0;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  padding: 0 1.15em;
  border-radius: var(--btn-radius);
  background: var(--lit-metal);
  box-shadow: var(--lit-metal-sheen);
  color: var(--bg);
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-decoration: none;
  white-space: nowrap;
  transition:
    filter    var(--dur-base) var(--ease),
    transform var(--dur-base) var(--ease),
    box-shadow var(--dur-base) var(--ease);
}

@media (hover: hover) and (pointer: fine) {
  .credit-bar-buy:hover {
    filter: brightness(1.08);
    transform: translateY(-1px);
    box-shadow: var(--lit-metal-sheen), var(--e2);
  }
}

.credit-bar-buy:active {
  transform: translateY(0);
  filter: brightness(0.97);
  transition-duration: var(--dur-fast);
}

/* Running low: the number warms to gold. The bar does not shout, it just stops
   being neutral, which is enough when it sits above everything else. */
.credit-bar--low .credit-bar-count { color: var(--gold); }
.credit-bar--low .credit-bar-unit  { color: var(--fg-muted); }

/* --- segmented control ---------------------------------------------------- */

.saga-views {
  display: flex;
  gap: 2px;
  margin: 0.9em 0 1.25em;
  padding: 3px;
  background: var(--choice-well-bg);
  box-shadow: var(--choice-well-inset);
  border-radius: var(--btn-radius);
}

.saga-view {
  all: unset;
  position: relative;
  flex: 1;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4em;
  cursor: pointer;
  border-radius: calc(var(--btn-radius) - 2px);
  font-family: var(--font-ui);
  font-size: 13px;
  letter-spacing: 0.04em;
  color: var(--fg-dim);
  transition: color var(--dur-base) var(--ease);
}

/* The pill is a pseudo-element so it can SETTLE rather than pop. Selecting a
   view eases it up from 94% to full size as it fades in, which reads as the
   pill arriving under the label instead of a background flicking on. */
.saga-view::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--inner-pill-bg);
  border: 1px solid var(--inner-pill-border);
  box-shadow: var(--e1);
  opacity: 0;
  transform: scale(0.94);
  transition:
    opacity   var(--dur-base) var(--ease),
    transform var(--dur-base) var(--ease);
  pointer-events: none;
}

/* Label and count sit above the pill.
   isolation: isolate on .saga-view is load-bearing, not decoration. Without it
   .saga-view is positioned with z-index auto, so it is NOT a stacking context,
   and the z-index: 1 below does not stay local: it leaks into .account-page and
   puts the label and count on layer 1 of the whole page. Every saga card sits on
   layer 0 (auto), so the counts painted over anything a card contained,
   including the open action menu. Isolating means the 1 only has to beat the
   ::before pill, which is all it was ever for. */
.saga-view { isolation: isolate; }
.saga-view > * { position: relative; z-index: 1; }

@media (hover: hover) and (pointer: fine) {
  .saga-view:hover { color: var(--fg-muted); }
}

.saga-view[aria-selected="true"] { color: var(--fg); }

.saga-view[aria-selected="true"]::before {
  opacity: 1;
  transform: scale(1);
}

/* The count is informational, so it stays at --fg-label. --fg-faint would put
   it at ~2.28:1, below AA, and it is a real number the reader uses. */
.saga-view-count { font-size: 11px; color: var(--fg-label); }
.saga-view[aria-selected="true"] .saga-view-count { color: var(--gold-muted); }

/* --- the grid ------------------------------------------------------------- */

.saga-grid { display: flex; flex-direction: column; gap: 0.85em; }
.saga-grid[hidden] { display: none; }

/* Switching views used to be an instant swap. Now the incoming set rises a few
   pixels into place. The cards are staggered by one frame each so the group
   arrives as a sequence rather than a single block, which is what makes it feel
   composed. Capped at 6 so a long shelf never crawls in.
   No JS: un-hiding the grid re-runs the animation on its children. */
@keyframes saga-rise {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

.saga-grid:not([hidden]) > * {
  animation: saga-rise var(--dur-slow) var(--ease) backwards;
}

.saga-grid:not([hidden]) > *:nth-child(1) { animation-delay: 0ms; }
.saga-grid:not([hidden]) > *:nth-child(2) { animation-delay: 40ms; }
.saga-grid:not([hidden]) > *:nth-child(3) { animation-delay: 80ms; }
.saga-grid:not([hidden]) > *:nth-child(4) { animation-delay: 120ms; }
.saga-grid:not([hidden]) > *:nth-child(5) { animation-delay: 160ms; }
.saga-grid:not([hidden]) > *:nth-child(n+6) { animation-delay: 200ms; }

/* The duration tokens already collapse under reduced motion, but a stagger
   DELAY is not a duration, so it has to be cleared explicitly or the cards
   would still arrive late in sequence. */
@media (prefers-reduced-motion: reduce) {
  .saga-grid:not([hidden]) > * { animation: none; }
}

/* --- elevated saga card --------------------------------------------------- */

/* The centrepiece. A card is a slab of gold-lit glass resting on ink: it sits
   at e2, and on hover it RISES to e3 and drifts up 2px while its edge warms
   l2 -> l3. The lift is what makes it feel like an object rather than a box.
   position/isolation are here so the ::before catchlight can sit on top. */
/* THE SPINE. A saga is a book, so the card is built like one: a gilded spine
   down the leading edge, the text block set in from it the way a page is set
   in from the binding. This is the one change that makes the card read as an
   object from a codex rather than a rounded rectangle, and it costs no markup.

   NOTE: overflow is declared VISIBLE deliberately. It was originally a defence
   against the legacy .saga-card rule (since removed, see the dedupe note above)
   whose overflow:hidden won by cascade and clipped the ... menu dropdown, which
   is absolutely positioned inside the card FOOTER. The legacy rule is gone, so
   this is no longer a workaround, but it stays declared: the dropdown must not
   be clipped, and that intent should be explicit rather than inherited from a
   default. The spine does not need clipping either way, it is corner-radiused
   directly. */
.saga-card {
  position: relative;
  isolation: isolate;
  overflow: visible;
  background: var(--glass-bg);
  border: 1px solid var(--gold-l3);
  border-radius: var(--glass-radius);
  /* catchlight along the top lip, then the resting depth */
  box-shadow: var(--glass-catchlight), var(--e2);
  padding: 1.15em 1.15em 1em 1.6em;
  transition:
    background     var(--dur-base) var(--ease),
    border-color   var(--dur-base) var(--ease),
    box-shadow     var(--dur-base) var(--ease),
    transform      var(--dur-base) var(--ease);
}

.saga-card::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  border-radius: var(--glass-radius) 0 0 var(--glass-radius);
  /* Gilded at the head, falling away toward the tail, like light down a spine. */
  background: linear-gradient(180deg, var(--gold), var(--gold-muted) 62%, var(--gold-l2));
  opacity: 0.8;
  transition: opacity var(--dur-base) var(--ease);
  pointer-events: none;
}

.saga-card:focus-within {
  background: var(--container-bg-active);
  border-color: var(--gold-l3);
  box-shadow: var(--e3);
  transform: translateY(-2px);
}

@media (hover: hover) and (pointer: fine) {
  .saga-card:hover {
    background: var(--container-bg-active);
    border-color: var(--gold-l3);
    box-shadow: var(--e3);
    transform: translateY(-2px);
  }
}

.saga-card:focus-within::before { opacity: 1; }

@media (hover: hover) and (pointer: fine) {
  .saga-card:hover::before { opacity: 1; }
}

/* A press should feel like the card takes the weight, so it settles back down
   rather than staying lifted. */
.saga-card:active {
  transform: translateY(0);
  box-shadow: var(--e1);
  transition-duration: var(--dur-fast);
}

/* Quiet metadata row. Orientation, not content, but it still carries the
   episode number, so it uses --fg-label. --fg-faint is decorative-only at
   ~2.28:1 and must never hold information. */
.saga-card-meta {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-family: var(--font-ui);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-label);
  margin-bottom: 0.75em;
}

/* The episode marker is the reader's place in the book, so it carries a little
   gold. It gives the card a second, quieter anchor above the name. */
.saga-card-meta > span:last-child { color: var(--gold-muted); }

/* The hero line. It was 21px, which put it barely above the body copy around
   it, so no card had a focal point. At 28px with tight leading and a touch of
   negative tracking it reads as a title page, which is what a protagonist name
   in a serif face should feel like. This is the single biggest visible change. */
.saga-card-name {
  font-family: var(--font-body);
  font-size: 28px;
  line-height: 1.12;
  letter-spacing: -0.012em;
  color: var(--fg);
  margin: 0 0 0.28em;
}

/* The episode title is the subtitle beneath it, so it steps down clearly
   instead of competing. */
.saga-card-title {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 15px;
  line-height: 1.5;
  color: var(--fg-muted);
  margin: 0 0 1.05em;
}

/* This is an <hr>, which carries a default 1px grey border in every engine.
   Without clearing it the element measured 2px tall and painted
   rgb(128,128,128) OVER the gold hairline — a cold grey line across a
   candlelit card. Found by rendering and reading computed style. */
.saga-card-rule {
  border: 0;
  height: 1px;
  background: var(--hairline);
  margin: 0 0 0.7em;
}

.saga-card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75em;
}

/* ONE primary verb per card. Everything else lives in the menu. */
.saga-continue {
  all: unset;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  font-family: var(--font-ui);
  font-size: 13px;
  letter-spacing: 0.05em;
  color: var(--gold);
  transition: color var(--dur-fast) var(--ease);
}

@media (hover: hover) and (pointer: fine) {
  .saga-continue:hover { color: var(--fg); }
}
/* Ring comes from the global :focus-visible rule in tokens.css. Only the
   radius is restated, because `all: unset` resets border-radius to 0 and the
   global rule inherits it. Same reason on .saga-learn below. */
.saga-continue:focus-visible { border-radius: var(--r-sm); }

/* State lives in the SURFACE, not in opacity. Dimming the whole card took the
   prose down with it and pushed the saga name toward unreadable. Instead the
   glass recedes down the ladder and the edge quiets, while the text stays at
   full strength. A set-aside saga should look at rest, not damaged. */
.saga-card--ended,
.saga-card--shelved {
  background: var(--gold-s1);
  border-color: var(--gold-l1);
  box-shadow: var(--e1);
}

.saga-card--ended::before,
.saga-card--shelved::before { opacity: 0.25; }

/* The name is the one thing allowed to soften, so a resting saga reads as
   quieter without any of its text dropping below contrast. */
.saga-card--ended .saga-card-name,
.saga-card--shelved .saga-card-name { color: var(--fg-muted); }

.saga-card--ended:focus-within,
.saga-card--shelved:focus-within {
  background: var(--gold-s2);
  border-color: var(--gold-l2);
  box-shadow: var(--e2);
}

@media (hover: hover) and (pointer: fine) {
  .saga-card--ended:hover,
  .saga-card--shelved:hover {
    background: var(--gold-s2);
    border-color: var(--gold-l2);
    box-shadow: var(--e2);
  }
}

/* Vaulted keeps full presence. Its edge is the signal: a warmer, closed line. */
.saga-card--vaulted {
  border-color: var(--gold-muted);
  background: var(--gold-s2);
}

/* The spine is the tell: a vaulted saga gets a cooler, evenly-lit edge rather
   than the gilded fall-off, so it reads as set apart at a glance. */
.saga-card--vaulted::before {
  background: linear-gradient(180deg, var(--gold-muted), var(--gold-l4));
  opacity: 1;
}

/* --- empty state, the newcomer path --------------------------------------- */

/* The newcomer path is a cold buyer's first real impression, so it is composed
   rather than merely centred: a lit signet, a held line of type, generous air.
   It should read as an invitation, not as an error state about emptiness. */
.saga-empty { position: relative; text-align: center; padding: 2.25em 0.5em 1em; }
.saga-empty[hidden] { display: none; }

/* A single warm bloom behind the mark, so the eye lands there first. */
.saga-empty::before {
  content: '';
  position: absolute;
  top: 0.9em;
  left: 50%;
  width: 190px;
  height: 190px;
  transform: translateX(-50%);
  background: radial-gradient(circle, var(--gold-s4), transparent 68%);
  pointer-events: none;
  z-index: 0;
}

.saga-empty > * { position: relative; z-index: 1; }

.saga-empty-mark {
  color: var(--gold);
  font-size: 15px;
  letter-spacing: 0.3em;
  margin: 0 0 1.1em;
  text-shadow: 0 0 18px rgba(201, 160, 85, 0.45);
}

.saga-empty-title {
  font-family: var(--font-body);
  font-size: 20px;
  color: var(--fg);
  margin: 0 0 0.5em;
}

.saga-empty-body {
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.6;
  color: var(--fg-label);
  max-width: 34ch;
  margin: 0 auto 1.35em;
}

.saga-learn {
  display: inline-block;
  min-height: 44px;
  line-height: 44px;
  font-family: var(--font-ui);
  font-size: 13px;
  color: var(--fg-dim);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease);
}

@media (hover: hover) and (pointer: fine) {
  .saga-learn:hover { color: var(--gold); }
}
.saga-learn:focus-visible { border-radius: var(--r-sm); }

.saga-learn--strip { display: block; text-align: center; margin: -0.75em 0 1.75em; }
.saga-learn--strip[hidden] { display: none; }

/* --- vault view ----------------------------------------------------------- */

.vault-slots { display: flex; flex-direction: column; gap: 0.6em; margin-bottom: 1em; }

.vault-slot {
  all: unset;
  display: flex;
  align-items: center;
  gap: 0.7em;
  min-height: 44px;
  padding: 10px 14px;
  box-sizing: border-box;
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  border-radius: var(--glass-radius);
  cursor: pointer;
  font-family: var(--font-ui);
  font-size: 14px;
  color: var(--fg-muted);
  transition:
    background   var(--dur-base) var(--ease),
    border-color var(--dur-base) var(--ease),
    color        var(--dur-base) var(--ease),
    box-shadow   var(--dur-base) var(--ease),
    transform    var(--dur-base) var(--ease);
}

@media (hover: hover) and (pointer: fine) {
  .vault-slot:hover {
    background: var(--container-bg-active);
    border-color: var(--container-border-active);
    color: var(--fg);
  }
}



.vault-slot-icon { font-size: 15px; line-height: 1; }
.vault-slot-name { flex: 1; }

.vault-slot-state {
  font-family: var(--font-ui);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg-faint);
}

.vault-slot--open { border-color: var(--gold-muted); }
.vault-slot--open .vault-slot-state { color: var(--gold); }

.vault-slot-hint {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 13px;
  color: var(--fg-label);
  margin: 0.5em 0 0.9em;
}

/* Dashed slot reads as empty and awaiting content without needing copy.
   It stays quieter than a real vault at rest, then warms fully on hover so the
   affordance is unmistakable once the reader reaches for it. */
.vault-slot--add {
  justify-content: center;
  border-style: dashed;
  border-color: var(--gold-l1);
  background: transparent;
  color: var(--fg-dim);
  font-style: italic;
  box-shadow: none;
}

@media (hover: hover) and (pointer: fine) {
  .vault-slot--add:hover {
    border-style: solid;
    border-color: var(--gold-l3);
    background: var(--gold-s2);
    color: var(--fg);
  }
}

/* --- vault dialog --------------------------------------------------------- */

/* --scrim replaces the raw rgba(0,0,0,0.72) that used to live here. The blur is
   what sells the depth: the page goes soft behind the dialog rather than just
   dark, so the modal reads as being in front of the page instead of on it. */
.vault-overlay {
  position: fixed;
  inset: 0;
  background: var(--scrim);
  -webkit-backdrop-filter: var(--scrim-blur);
  backdrop-filter: var(--scrim-blur);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.25em;
  z-index: 200;
  animation: vault-scrim-in var(--dur-base) var(--ease);
}

.vault-overlay[hidden] { display: none; }

@keyframes vault-scrim-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* The dialog arrives: it eases up and settles from 96%. --dur-slow is the
   token reserved for a panel entrance, and --ease is the settling curve. */
@keyframes vault-modal-in {
  from { opacity: 0; transform: translateY(10px) scale(0.96); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

.vault-modal {
  width: 100%;
  max-width: 380px;
  /* --glass-bg-strong is a translucent gold gradient, designed to sit OVER the
     page background. A card on the page reads fine because --bg is behind it;
     a modal floating on the scrim has almost no fill and looks washed out.
     Solid base first, glass sheen layered on top. */
  background-color: var(--bg);
  background-image: var(--glass-bg-strong);
  border: 1px solid var(--glass-border-strong);
  border-radius: var(--r-lg);
  /* e3 is the float rung, reserved for things in front of the page. */
  box-shadow: var(--e3);
  padding: 1.5em 1.35em;
  animation: vault-modal-in var(--dur-slow) var(--ease);
}

.vault-modal-title {
  font-family: var(--font-body);
  font-size: 20px;
  color: var(--fg);
  margin: 0 0 0.5em;
}

.vault-modal-body {
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.55;
  color: var(--fg-label);
  margin: 0 0 1.25em;
}

.vault-field { margin-bottom: 1em; }

.vault-label {
  display: block;
  font-family: var(--font-ui);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg-dim);
  margin-bottom: 0.5em;
}

.vault-input {
  width: 100%;
  min-height: 44px;
  box-sizing: border-box;
  background: var(--choice-well-bg);
  box-shadow: var(--choice-well-inset);
  border: 1px solid var(--glass-border);
  border-radius: var(--btn-radius);
  padding: 10px 12px;
  color: var(--fg);
  font-family: var(--font-body);
  font-size: 16px;
  outline: none;
}

.vault-input:focus-visible { border-color: var(--gold); }

.vault-input--pin { letter-spacing: 0.6em; text-align: center; font-size: 22px; }

.vault-error {
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--gold);
  margin: 0 0 1em;
}

.vault-error[hidden] { display: none; }

.vault-modal-actions { display: flex; gap: 0.6em; justify-content: flex-end; }

/* --- content limits editor ------------------------------------------------
   Same chips as the setup screen, so editing a saga's limits looks like
   setting them. The one difference is the tap target: setup's chip is 6px/14px
   padding, which is under the 44px minimum, and this dialog is reached mostly
   on a phone. min-height does the work without changing the chip's look. */

.limits-modal { max-width: 30em; }

.limits-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0.9em 0 0.2em;
}

.limits-chips .hard-limit-chip {
  all: unset;
  display: inline-flex;
  align-items: center;
  box-sizing: border-box;
  min-height: 44px;
  padding: 6px 14px;
  background: var(--inner-pill-bg);
  border: 0.5px solid var(--inner-pill-border);
  border-radius: 2px;
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.03em;
  color: var(--fg-dim);
  cursor: pointer;
  user-select: none;
  transition: border-color 0.12s, background 0.12s, color 0.12s;
}

.limits-chips .hard-limit-chip.is-selected {
  background: rgba(201, 160, 85, 0.08);
  border-color: var(--gold);
  color: var(--gold);
}

.limits-chips .hard-limit-chip:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
  border-radius: 2px;
}

.limits-desc {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 13px;
  line-height: 1.5;
  color: var(--fg-label);
  margin: 0.6em 0 0;
}

/* The confirm step. Gold rather than red on purpose: this is the reader making
   an informed choice about their own saga, not an error and not a telling-off.
   It should read as the product being straight with them. */
.limits-confirm {
  margin-top: 1.1em;
  padding: 0.9em 1em;
  border: 0.5px solid rgba(201, 160, 85, 0.34);
  border-left: 2px solid var(--gold);
  border-radius: 2px;
  background: rgba(201, 160, 85, 0.05);
}

.limits-confirm-lead {
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.55;
  color: var(--fg);
  margin: 0;
}

.limits-confirm-list {
  margin: 0.55em 0 0;
  padding-left: 1.15em;
}

.limits-confirm-list li {
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.55;
  color: var(--gold);
  margin-bottom: 0.2em;
}

/* One-time notice that "Character death" changed meaning. Same restrained
   inset as .limits-confirm — this is the product being straight with the
   reader about a change to something they chose, not an alert. */
.limits-changed {
  margin-top: 0.9em;
  padding: 0.9em 1em;
  border: 0.5px solid rgba(201, 160, 85, 0.34);
  border-left: 2px solid var(--gold);
  border-radius: 2px;
  background: rgba(201, 160, 85, 0.05);
}

.limits-changed-text {
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.55;
  color: var(--fg);
  margin: 0;
}

.limits-changed-dismiss {
  all: unset;
  display: inline-block;
  margin-top: 0.7em;
  /* 44px minimum touch target: 12px padding + 12px line-box + 12px padding.
     Verified at 375 and 1440, not assumed from the numbers. */
  padding: 12px 16px;
  min-height: 44px;
  box-sizing: border-box;
  font-family: var(--font-ui);
  font-size: 12px;
  line-height: 20px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--gold);
  border: 0.5px solid rgba(201, 160, 85, 0.45);
  border-radius: 2px;
  cursor: pointer;
}

.limits-changed-dismiss:hover { border-color: var(--gold); }

.limits-changed-dismiss:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
  border-radius: inherit;
}

.limits-confirm-note {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 13px;
  line-height: 1.5;
  color: var(--fg-label);
  margin: 0.7em 0 0;
}

.vault-btn {
  all: unset;
  min-height: 44px;
  min-width: 88px;
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 16px;
  border-radius: var(--btn-radius);
  border: 1px solid var(--gold);
  color: var(--gold);
  font-family: var(--font-ui);
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
}

@media (hover: hover) and (pointer: fine) {
  .vault-btn:hover { background: var(--container-bg-active); }
}

.vault-btn--ghost { border-color: var(--glass-border); color: var(--fg-dim); }

/* --- subordinate zones ---------------------------------------------------- */

#ledgerSection,
#whatsNewSection { margin-bottom: 1.1em; }

/* ===========================================================================
   DESKTOP — deliberate, and secondary. Mobile at 375px stays primary.
   Only the saga grid and the footer region reflow, so a wide window does not
   turn the page into a dashboard.
   ======================================================================== */

@media (min-width: 720px) {
  .account-page { max-width: 680px; margin-inline: auto; }
  .saga-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1em; }
  .saga-views { width: max-content; }
  .saga-view { padding: 0 20px; }
}

@media (min-width: 1080px) {
  .account-page { max-width: 960px; }
  .saga-grid { grid-template-columns: repeat(3, 1fr); }

  .account-footer-region {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1.1em;
    align-items: start;
  }
}

/* ===========================================================================
   SF-VISUAL-03 — CANDLELIGHT ON VELLUM
   ---------------------------------------------------------------------------
   The direction, and the reasoning.

   The page was gold over #0D0C0A, a near-neutral black. Neutral black is what
   a dark-mode APP looks like. StoryForge is a book someone is reading late at
   night, and that is a warm, lit, quiet feeling, not a cold one. So:

   1. The ground is warmed to lamplit brown-black (--ink-1).
   2. A single soft light is placed ABOVE the fold (--candle), so the top of
      the page is lit and the bottom falls away. One light source, from one
      direction, is what makes a scene read as real rather than evenly filled.
   3. A vignette closes the corners, the way lamplight actually falls off.
   4. Surfaces get vellum grain, so they read as paper catching light rather
      than as glass panes floating in space.
   5. --ember, a warmer relative of gold, is spent on exactly ONE thing: the
      primary action. Restraint is what keeps it literary.

   Everything is scoped to this page. --bg is untouched, so no other surface
   moves until it opts in.
   ======================================================================== */

body {
  background-color: var(--ink-1);
  /* candle above the fold, then the warm ground beneath it */
  background-image: var(--candle);
  background-repeat: no-repeat;
  background-attachment: fixed;
}

/* Vignette rides a fixed layer behind content, so scrolling does not drag the
   light with it. The light stays where the candle is. */
body::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%);
}

/* Grain gets its OWN layer with its own opacity, rather than being repeated
   into every surface. Rendered, the per-surface approach compounded wherever
   two grained planes overlapped and the texture became the loudest thing on
   the page. One layer, one strength, sitting over everything at 3.5%. */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  opacity: 0.035;
  background-image: var(--vellum-grain);
  background-repeat: repeat;
}

.account-page { position: relative; z-index: 1; }

/* --- the wordmark catches the light ---------------------------------------- */

.brand-wordmark {
  color: transparent;
  /* The bottom stop was #A87F3E. The descender of the "g" lands at 74–92% of
     the box, so the tail was painted in the darkest part of the gradient: 5.8:1
     against --bg at the ink bottom, below the 6.4:1 floor this palette holds
     informational text to, and barely two thirds of --gold's own 8.05:1. It was
     fully painted — the geometry has been correct since 237e470 — just too dim
     to read, which looks exactly like a clipped descender.
     #C79350 keeps the feet warmer and deeper in hue than --gold, so the
     candlelight fall-off survives, while lifting the tail to 7.36:1. */
  background: linear-gradient(180deg, #F3D9A2, var(--gold) 58%, #C79350);
  -webkit-background-clip: text;
  background-clip: text;
  /* the glow has to be a drop-shadow now, text-shadow paints under clipped text */
  filter: drop-shadow(0 0 18px rgba(201, 160, 85, 0.30));
}

/* --- the saga zone becomes a vellum leaf ----------------------------------- */

.saga-zone {
  position: relative;
  background-color: var(--ink-2);
  background-image:
    linear-gradient(180deg, rgba(201,160,85,0.10), rgba(201,160,85,0.028) 46%, transparent);
  border-color: var(--gold-l3);
  box-shadow:
    inset 0 1px 0 rgba(201,160,85,0.16),
    0 18px 48px rgba(0,0,0,0.55),
    0 2px 6px rgba(0,0,0,0.4);
}

/* --- cards: paper, lit from above ------------------------------------------ */

.saga-card {
  background-color: var(--ink-2);
  background-image:
    linear-gradient(180deg, rgba(201,160,85,0.085), rgba(201,160,85,0.022) 55%, transparent);
  box-shadow:
    inset 0 1px 0 rgba(201,160,85,0.13),
    var(--e2);
}

.saga-card:focus-within {
  background-image:
    linear-gradient(180deg, rgba(201,160,85,0.14), rgba(201,160,85,0.04) 55%, transparent);
  box-shadow:
    inset 0 1px 0 rgba(201,160,85,0.22),
    var(--e3);
}

@media (hover: hover) and (pointer: fine) {
  .saga-card:hover {
    background-image:
      linear-gradient(180deg, rgba(201,160,85,0.14), rgba(201,160,85,0.04) 55%, transparent);
    box-shadow:
      inset 0 1px 0 rgba(201,160,85,0.22),
      var(--e3);
  }
}

/* The spine is gilt, so it should look like metal on paper: bright at the head
   where the candle hits, falling to a dark burnish at the tail. */
.saga-card::before {
  width: 3px;
  background: linear-gradient(180deg, #F3D9A2, var(--gold) 30%, #8A6B33 78%, #4A3A1C);
  opacity: 0.95;
}

.saga-card:focus-within::before {
  box-shadow: 0 0 14px rgba(201, 160, 85, 0.45);
}

@media (hover: hover) and (pointer: fine) {
  .saga-card:hover::before {
    box-shadow: 0 0 14px rgba(201, 160, 85, 0.45);
  }
}

/* --- the one primary action wears ember ------------------------------------ */

.credit-bar-buy {
  background: var(--ember-lit);
  color: #1A1206;
  box-shadow:
    inset 0 1px 0 rgba(255, 244, 214, 0.55),
    0 2px 10px rgba(0,0,0,0.42),
    var(--ember-glow);
  font-weight: 650;
}

@media (hover: hover) and (pointer: fine) {
  .credit-bar-buy:hover {
    filter: brightness(1.06);
    box-shadow:
      inset 0 1px 0 rgba(255, 244, 214, 0.7),
      0 6px 18px rgba(0,0,0,0.5),
      0 0 32px rgba(224, 169, 78, 0.42);
  }
}

/* Running low: the balance glows like an ember rather than merely turning gold */
.credit-bar--low .credit-bar-count {
  color: var(--ember);
  text-shadow: 0 0 20px rgba(224, 169, 78, 0.4);
}

/* --- quiet zones sink into the ground -------------------------------------- */

.codex-container {
  background-color: rgba(22, 18, 12, 0.55);
}

/* --- the vault dialog is lit from the same candle -------------------------- */

.vault-modal {
  background-color: var(--ink-2);
  background-image:
    linear-gradient(180deg, rgba(201,160,85,0.13), rgba(201,160,85,0.035) 50%, transparent);
  box-shadow:
    inset 0 1px 0 rgba(201,160,85,0.2),
    var(--e3);
}

/* --- the newcomer bloom becomes actual candlelight ------------------------- */

.saga-empty::before {
  background: radial-gradient(circle, rgba(224,169,78,0.16), transparent 68%);
}

.saga-empty-mark {
  color: var(--ember);
  text-shadow: 0 0 22px rgba(224, 169, 78, 0.5);
}

/* ===========================================================================
   SF-VISUAL-04 — fixes found by RENDERING the page and looking at it.
   Every item below was measured on screen, not reasoned about.
   ======================================================================== */

/* Measured at 1120px: two cards in one grid row came out 194px and 209px tall.
   Making the card a flex column does two things: it fills the row so heights
   match, and it pushes the rule + footer to the bottom, so "Continue reading"
   lines up ACROSS cards instead of floating at whatever height the title
   happened to end. */
.saga-grid { align-items: stretch; }

.saga-card {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.saga-card-rule { margin-top: auto; }

/* The ... menu measured rgb(92,74,42), which is --fg-faint at ~2.28:1. That is
   the DECORATIVE ONLY token sitting on an interactive control, and on screen it
   was almost invisible against the card. It also measured 40x40, under the 44px
   minimum. Both fixed. */
.card-menu-btn {
  color: var(--fg-label);
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-sm);
  transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}

@media (hover: hover) and (pointer: fine) {
  .card-menu-btn:hover {
    color: var(--gold);
    background: var(--gold-s2);
  }
}

/* ===========================================================================
   SF-VISUAL-05 — two regressions from the candlelight pass, seen on screen.
   ======================================================================== */

/* REGRESSION: the SF-VISUAL-03 rule set background-color on .codex-container.
   .codex-container--quiet cancels its box with the `background` SHORTHAND, and
   a shorthand written EARLIER in the file cannot override a longhand written
   later. So the quiet sections (INSTALL APP, HELP SHAPE YOUR STORIES, VAULT
   PINS, COMMAND CENTER) started painting a box while keeping padding: 20px 0,
   which is zero horizontal padding. The text sat hard against the box edge and
   read as clipped.

   A quiet section is meant to have no box at all, only a hairline above it.
   Restoring that intent rather than papering over it with padding. */
.codex-container--quiet {
  background-color: transparent;
  background-image: none;
}

/* REGRESSION: the spine ran the full height of the card with a 13px corner
   radius applied to a 3px-wide element. A radius four times the width cannot
   resolve as a corner, so it flared and tapered at the top and bottom instead
   of sitting flush, which is the "runs too high and low at the edges".

   It now insets from both ends so it sits inside the card's curve, with fully
   rounded caps. It reads as a ribbon marking the leading edge, which is a
   deliberate object rather than a border that failed to fit. */
.saga-card::before {
  top: 14px;
  bottom: 14px;
  left: 1px;
  width: 3px;
  border-radius: 3px;
}

/* --- Read on mobile ---------------------------------------------------------
   The companion note under the sagas. Reuses .codex-container--quiet so it sits
   in the page as an existing kind of thing rather than a new one, and inherits
   the hairline rule and label treatment from it.

   Hidden below 760px: the reader is already holding the device the note is
   telling them about, and the INSTALL APP card that fires there says the more
   useful thing anyway. account.js hides it too when the page is already running
   as an installed app. */
.companion-note-body {
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.7;
  color: var(--fg-label);
  margin: 0;
}

/* The one part worth carrying to another device, so it takes the page's gold.
   nowrap because a URL broken across two lines stops reading as a URL. */
.companion-note-domain {
  color: var(--gold);
  white-space: nowrap;
}

@media (max-width: 760px) {
  .companion-note { display: none; }
}

/* The one menu item that does not just move a saga somewhere else. Warm red
   rather than the menu's gold, so the eye separates it from its neighbours
   before the hand reaches it. Nothing louder: it is still a menu item, not a
   button, and the confirm is where the weight belongs. */
.card-menu-item--danger {
  color: #C46A5A;
}
.card-menu-item--danger:hover,
.card-menu-item--danger:focus-visible {
  color: #D9806F;
}

/* --- Test genre opt-in ------------------------------------------------------
   Shown only to readers the server reports as eligible. A checkbox rather than
   a button because it is a standing preference, not an action. */
.testgenre-row {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  cursor: pointer;
}
.testgenre-check {
  flex: none;
  margin-top: 3px;
  width: 16px;
  height: 16px;
  accent-color: var(--gold);
  cursor: pointer;
}
.testgenre-check:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}
.testgenre-copy {
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.65;
  color: var(--fg-label);
}
.testgenre-error {
  font-family: var(--font-ui);
  font-size: 13px;
  color: #C46A5A;
  margin: 10px 0 0;
}

/* --- THE DOOR ---------------------------------------------------------------
   The invitation into the StoryForge Discord. Two surfaces: a one-time modal
   the first time a reader becomes eligible, and a standing block that lives on
   the account page from then on. Both use the same gold as everything else;
   nothing here introduces a new colour. */

/* The standing affordance. Matches .codex-container--quiet, so it sits in the
   page rhythm rather than announcing itself. */
.door-line {
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.6;
  color: var(--fg);
  margin: 0 0 14px;
}

.door-btn,
.door-modal-btn {
  all: unset;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  min-height: 44px;               /* WCAG 2.5.5 */
  padding: 10px 22px;
  font-family: var(--font-ui);
  font-size: 14px;
  letter-spacing: 0.06em;
  color: var(--bg);
  background: var(--gold);
  border-radius: 8px;
  cursor: pointer;
  transition: filter 0.14s ease-out;
}
.door-btn:hover,
.door-modal-btn:hover { filter: brightness(1.07); }
.door-btn:focus-visible,
.door-modal-btn:focus-visible,
.door-modal-dismiss:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
  border-radius: inherit;
}
.door-btn[disabled],
.door-modal-btn[disabled] { opacity: 0.55; cursor: default; }

.door-sub,
.door-modal-sub {
  font-family: var(--font-ui);
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--fg-label);
  margin: 10px 0 0;
}

.door-error,
.door-modal-error {
  font-family: var(--font-ui);
  font-size: 13px;
  color: var(--fg-muted);
  margin: 10px 0 0;
}

/* --- the one-time invitation ---------------------------------------------- */

.door-modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  /* Candlelight: a warm glow behind the panel, over a near-black ground. */
  background:
    radial-gradient(60% 50% at 50% 45%, rgba(201, 160, 85, 0.10), transparent 70%),
    rgba(13, 12, 10, 0.82);
  opacity: 0;
  transition: opacity 240ms ease-out;
}
.door-modal.is-open { opacity: 1; }

.door-modal-surface {
  width: 100%;
  max-width: 460px;
  box-sizing: border-box;
  padding: 34px 32px 26px;
  text-align: center;
  background: var(--bg);
  border: 1px solid rgba(201, 160, 85, 0.34);   /* gold hairline */
  border-radius: 14px;
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.6);
  transform: translateY(10px);
  transition: transform 240ms ease-out;
}
.door-modal.is-open .door-modal-surface { transform: none; }

.door-diamond {
  width: 11px;
  height: 11px;
  margin: 0 auto 20px;
  background: var(--gold);
  transform: rotate(45deg);
  box-shadow: 0 0 16px rgba(201, 160, 85, 0.45);
}

.door-modal-heading {
  font-family: var(--font-body);
  font-size: 27px;
  font-weight: 400;
  line-height: 1.24;
  letter-spacing: 0.01em;
  margin: 0 0 16px;
  /* Same treatment as the wordmark: the gradient bottom stop is lifted so the
     descenders stay legible against the dark panel. */
  color: transparent;
  background: linear-gradient(180deg, #F3D9A2, var(--gold) 58%, #C79350);
  -webkit-background-clip: text;
  background-clip: text;
  padding-bottom: 0.06em;
}

.door-modal-body {
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  color: var(--fg);
  margin: 0 0 16px;
}

.door-modal-open {
  font-family: var(--font-body);
  font-size: 16px;
  font-style: italic;
  line-height: 1.6;
  color: var(--gold);
  margin: 0 0 24px;
}

.door-modal-dismiss {
  all: unset;
  display: block;
  margin: 18px auto 0;
  padding: 8px 12px;
  font-family: var(--font-ui);
  font-size: 13px;
  color: var(--fg-dim);
  cursor: pointer;
}
.door-modal-dismiss:hover { color: var(--fg-muted); }

/* Mobile: a full-screen sheet rather than a floating card. */
@media (max-width: 479px) {
  .door-modal { padding: 0; }
  .door-modal-surface {
    max-width: none;
    min-height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    border: none;
    border-radius: 0;
    padding: 40px 26px;
  }
  .door-modal-heading { font-size: 24px; }
}

/* Respect a reader who has asked for less motion. */
@media (prefers-reduced-motion: reduce) {
  .door-modal,
  .door-modal-surface { transition: none; }
}

/* ===========================================================================
   SF-VISUAL-08 — THE DOOR'S COLOURS, AND ONLY ITS COLOURS
   ---------------------------------------------------------------------------
   A previous pass took this much too far: it dissolved the borders, centred
   the whole page and recomposed the balance and the segmented control. That
   was a redesign, and a redesign was not the job. It has been removed
   wholesale — every layout rule, every alignment, every border on this page is
   the one it has always had.

   What was actually wrong is a COLOUR problem, and that is all this block
   fixes.

   /welcome keeps its ground genuinely flat near-black and spends gold on a
   small number of bright things, which is why the gold reads as light. This
   page laid a candle wash, a vignette and a grain layer over the ground, and
   then put a gold-tinted fill on the saga zone, another on every card, and
   another on every container. Twenty surfaces at 3-12% gold do not read as
   twenty subtle accents; they composite into brown, and once the ground is
   brown there is nothing left for gold to be brighter than.

   So: the ground goes flat near-black, the warm fills come down until the
   surfaces read as dark rather than brown, and the borders are made MORE
   visible rather than less — lifted off the ground with a soft gold glow so
   each card reads as an object sitting on the page.
   ======================================================================== */

/* --- the ground --------------------------------------------------------- */

/* Flat near-black, exactly as the front door. The candle wash is what tinted
   every surface above it brown. */
body {
  background-color: var(--bg);
  background-image: none;
}

/* The vignette and grain layers were fighting the flat ground for the same few
   percent of luminance. The door has neither and is the better-looking screen. */
body::before,
body::after { content: none; }

/* --- the masthead ------------------------------------------------------- */

/* The wordmark takes the door's treatment: bigger, lit with the same three-stop
   gradient, with the edition mark beneath it. Layout is untouched — the brand
   block was already centred, and still is. */
.brand-wordmark {
  /* inline-block so the drop-shadow hugs the letters. The filter is computed
     from the element's BACKGROUND BOX, so on a full-width block h1 the glow
     bloomed as a wide rectangle instead of a halo around the word. */
  display: inline-block;
  font-size: 42px;
  letter-spacing: 0.02em;
  /* The three stops are identical to .welcome-wordmark. The bottom stop is
     #C79350 rather than a darker burnish because the "g" descender lands in
     it — see the note there. These two wordmarks must stay in step. */
  background: linear-gradient(180deg, #F3D9A2, var(--gold) 58%, #C79350);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 0 20px rgba(201, 160, 85, 0.26));
  text-shadow: none;
}

/* The edition mark, new markup, styled to match the door exactly. */
.brand-edition {
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 500;
  line-height: 1;
  color: var(--fg);
  text-transform: uppercase;
  letter-spacing: 0.46em;
  margin: 6px 0 0;
  /* Wide tracking leaves a trailing space after the last letter, which throws
     the word visually left of centre. Half the tracking puts it back. */
  text-indent: 0.46em;
}

/* --- surfaces: dark, not brown ------------------------------------------ */

/* Every rule below changes colour only. Padding, borders, radii, alignment and
   layout are all left exactly as they were. */

/* The saga zone keeps its surface and its border. The fill just stops being a
   warm gold-tinted plane and becomes the page ground with a hint of warmth. */
.saga-zone {
  background-color: var(--ink-1);
  background-image: linear-gradient(180deg, rgba(201, 160, 85, 0.045), transparent 46%);
  border-color: var(--gold-l2);
}

/* THE CARDS. Darker than the zone they sit in, so they separate, and lifted off
   it with a soft gold bloom around the edge. The glow is what makes the border
   read as an edge catching light rather than a hairline drawn on a flat page. */
.saga-card {
  background-color: var(--ink-2);
  background-image: linear-gradient(180deg, rgba(201, 160, 85, 0.05), transparent 52%);
  border-color: var(--gold-l2);
  box-shadow:
    inset 0 1px 0 rgba(201, 160, 85, 0.12),
    0 0 20px rgba(201, 160, 85, 0.07),
    var(--e2);
}

/* Hover and focus warm the bloom rather than growing the card. */
.saga-card:focus-within {
  background-image: linear-gradient(180deg, rgba(201, 160, 85, 0.09), transparent 52%);
  border-color: var(--gold-l3);
  box-shadow:
    inset 0 1px 0 rgba(201, 160, 85, 0.20),
    0 0 30px rgba(201, 160, 85, 0.13),
    var(--e3);
}

@media (hover: hover) and (pointer: fine) {
  .saga-card:hover {
    background-image: linear-gradient(180deg, rgba(201, 160, 85, 0.09), transparent 52%);
    border-color: var(--gold-l3);
    box-shadow:
      inset 0 1px 0 rgba(201, 160, 85, 0.20),
      0 0 30px rgba(201, 160, 85, 0.13),
      var(--e3);
  }
}

/* The quiet containers keep their borders; only the muddy fill comes off. */
.codex-container {
  background-color: rgba(16, 13, 9, 0.72);
}

.codex-container--quiet {
  background-color: transparent;
}

/* The modal is lit by the same light. */
.vault-modal {
  background-color: var(--ink-2);
  background-image: linear-gradient(180deg, rgba(201, 160, 85, 0.10), transparent 50%);
  box-shadow:
    inset 0 1px 0 rgba(201, 160, 85, 0.18),
    0 0 34px rgba(201, 160, 85, 0.08),
    var(--e3);
}

/* --- COMPANION is the MOBILE edition ------------------------------------- */

/* Companion names the phone/PWA edition of StoryForge. On a PC — a desktop
   browser, or the Steam desktop client, which is the PC product — there is no
   edition to name: it is just StoryForge. So the mark is hidden by default and
   revealed only on the surfaces it actually describes.

   Hidden by default rather than shown by default on purpose. If a new surface
   ever renders this markup, the safe failure is a missing sub-line, not the
   wrong product name on a PC. */
.brand-edition { display: none; }

/* Phone and small-tablet widths, where the mobile layout is already in play. */
@media (max-width: 760px) {
  .brand-edition { display: block; }
}

/* An installed app on a touch device — a tablet PWA held wider than 760px.
   `pointer: coarse` is the part that keeps the Steam desktop client out: it is
   an installed app too, and can report standalone, but it is a PC with a
   mouse. Width alone would not have separated them. */
@media (display-mode: standalone) and (pointer: coarse) {
  .brand-edition { display: block; }
}

/* ---------------------------------------------------------------------------
   Saga card: genre/theme tags, reader synopsis, pasted cover image.
   Appended as one block so the whole pass lifts off cleanly.
   --------------------------------------------------------------------------- */

/* Orientation, not content. Quiet enough that the card's one primary verb
   still reads first. */
.saga-card-tags {
  margin: 0.25rem 0 0;
  font-family: var(--font-ui);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg-label);
}

/* The reader's own line. Body face, because it is their prose, not a label. */
.saga-card-synopsis {
  margin: 0.5rem 0 0;
  font-family: var(--font-body);
  font-size: 0.875rem;
  line-height: 1.45;
  color: var(--fg-muted);
  /* One line's worth. A 140-char cap is enforced server-side; this keeps a
     pathological render from pushing the primary verb off the card. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Pasted cover. Fixed aspect so a portrait and a panorama produce the same
   card height and the grid does not jump. */
.saga-card-image {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: 2px;
  margin: 0 0 0.75rem;
  background: rgba(0, 0, 0, 0.25);
}

/* --- saga synopsis modal --------------------------------------------------- */

.synopsis-label {
  display: block;
  margin: 1rem 0 0.375rem;
  font-family: var(--font-ui);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fg-label);
}

.synopsis-input {
  width: 100%;
  box-sizing: border-box;
  /* 44px minimum target: 0.75rem padding either side of a 1rem line. */
  padding: 0.75rem;
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.25;
  color: var(--fg);
  background: rgba(0, 0, 0, 0.28);
  border: 1px solid var(--fg-faint);
  border-radius: 2px;
}

.synopsis-input::placeholder { color: var(--fg-faint); }

.synopsis-input:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
  border-radius: inherit;
}

.synopsis-count {
  margin: 0.375rem 0 0;
  font-family: var(--font-ui);
  font-size: 0.75rem;
  color: var(--fg-label);
  text-align: right;
}

.synopsis-count.is-over { color: var(--gold); }

/* ===========================================================================
   EMBERS — the daily floor, shown under the bought balance.

   DELIBERATELY NOT --ember. That token is already spoken for twice on this
   page: it is the colour of the ONE primary action, and it is what the balance
   turns when the reader is running low. Painting the embers count with it would
   make the same colour mean "buy now", "you are nearly out", and "here is your
   free allowance" at once, and the third reading would inherit the alarm of the
   second. Embers are not an alarm. They are the floor that means the reader is
   never stuck, so they are quiet: muted text, no glow, no weight.
   ======================================================================== */

.ember-line {
  margin: 6px 0 0;
  font-family: var(--font-ui);
  font-size: 12px;
  line-height: 1.4;
  color: var(--fg-muted);
  letter-spacing: .01em;
}
