/* ==========================================================
   Story engine styles + Spectral Uplift primitive classes.
   Source: design/SITE_REDESIGN_EXECUTION_SPEC_v1_0_0.md and
   design/DREAMEROS_SPECTRAL_UPLIFT_v1.md.
   Tokens (--sp-1 .. --sp-7, --sp-ribbon, --sp-beat) mount in
   includes/styles.php. This file consumes them.
   ========================================================== */

/* ---- Spectral Uplift primitives ---- */

.surface-card {
  position: relative;
  border: 1px solid var(--border);
  border-radius: var(--r);
  background: var(--bg-card);
  overflow: hidden;
}
.surface-card::before {
  content: '';
  position: absolute; top: 0; left: 0; right: 0;
  height: 2px;
  background: var(--sp-beat);
  opacity: 0.7;
}

.surface-grid {
  display: grid;
  gap: 20px;
  max-width: 1180px;
  margin: 0 auto;
}

.status-chip {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--fm);
  font-size: 11px; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase;
  padding: 4px 10px;
  border-radius: var(--pill);
  border: 1px solid var(--border);
  color: var(--ink-s);
}
.status-chip.is-live { color: var(--green); border-color: rgba(34,255,154,0.35); }
.status-chip.is-watch { color: #fbbf24; border-color: rgba(251,191,36,0.35); }
.status-chip.is-boundary { color: #ff3d7f; border-color: rgba(255,61,127,0.35); }
.status-chip.is-dated { color: var(--ink-f); }

.code-surface {
  background: var(--bg);
  border: 1px solid rgba(139,92,246,0.18);
  border-radius: var(--r);
  padding: 22px 24px;
  font-family: var(--fm);
  font-size: 13px;
  line-height: 1.7;
  color: var(--ink-s);
  overflow-x: auto;
  max-width: 900px;
  margin: 20px auto 0;
  text-align: left;
}

/* Mono orientation label: alias of the existing .section-label. */
.eyebrow { }

.spectral-ribbon {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: var(--sp-ribbon);
  pointer-events: none;
}
.story-beat-last .spectral-ribbon { bottom: auto; top: 0; }

/* ---- Story layout ---- */

.story-hero { position: relative; }

.story-rail {
  position: sticky;
  top: 64px;
  z-index: 40;
  display: flex;
  flex-wrap: nowrap;
  gap: 6px;
  overflow-x: auto;
  padding: 10px 16px;
  justify-content: flex-start;
  background: rgba(5,7,13,0.85);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  scrollbar-width: none;
}
.story-rail::-webkit-scrollbar { display: none; }
/* safe center, not center. A centred flex line that overflows pushes its
   first item to a NEGATIVE offset, and scrollLeft floors at 0, so the
   overflow is unreachable by any route. Measured: from 900px, where this
   query fires, to about 1174px, where the rail stops overflowing, the
   first pill is clipped; between 900 and 930 it is 100 percent off screen
   and no scroll, keyboard or click can bring it back. The safe keyword
   falls back to flex-start the moment the content would overflow, which
   is exactly the case that was broken. */
@media (min-width: 900px) { .story-rail { justify-content: safe center; } }
.story-rail-link {
  flex-shrink: 0;
  font-family: var(--fm);
  font-size: 11px; font-weight: 600;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ink-f);
  text-decoration: none;
  padding: 6px 12px;
  border-radius: var(--pill);
  border: 1px solid transparent;
  transition: color 0.2s, border-color 0.2s;
}
.story-rail-link:hover { color: var(--ink); text-decoration: none; }
.story-rail-link[aria-current="true"] {
  color: var(--ink);
  border-color: color-mix(in srgb, var(--sp-beat) 45%, transparent);
  background: color-mix(in srgb, var(--sp-beat) 12%, transparent);
}

.story-beat { position: relative; }
.story-beat-inner { max-width: 1180px; }
.story-beat-eyebrow { color: var(--sp-beat); }

.story-plain {
  max-width: 720px;
  margin: 0 auto;
  font-size: 17px;
  color: var(--ink-s);
  line-height: 1.8;
}
.story-plain p { margin-bottom: 18px; }
.story-plain p:last-child { margin-bottom: 0; }

.story-figure {
  margin: 28px auto 0;
  max-width: 720px;
  text-align: center;
}
.story-figure img { max-width: min(100%, 360px); height: auto; border-radius: var(--r); }
.story-figure-focal img { max-width: min(100%, 440px); }

.story-expand-set { max-width: 900px; margin: 26px auto 0; }
.story-expand {
  border-bottom: 1px solid var(--border);
}
.story-expand:first-child { border-top: 1px solid var(--border); }
.story-expand-summary {
  padding: 18px 0;
  font-family: var(--fb);
  font-size: 16px;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
  list-style: none;
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  transition: color 0.2s;
}
.story-expand-summary::-webkit-details-marker { display: none; }
.story-expand-summary::after { content: none; }
.story-expand-summary:hover { color: var(--accent-light); }
.story-expand-hint {
  font-family: var(--fm); font-size: 20px; font-weight: 400;
  color: var(--ink-f);
  transition: transform 0.2s, color 0.2s;
}
.story-expand[open] .story-expand-hint { transform: rotate(45deg); color: var(--sp-beat); }
.story-expand-body {
  padding: 0 0 22px;
  font-size: 15px;
  color: var(--ink-s);
  line-height: 1.75;
  text-align: left;
}
.story-expand-body p { margin-bottom: 14px; }
.story-expand-body ul, .story-expand-body ol { margin: 0 0 14px 20px; }
.story-expand-body li { margin-bottom: 10px; }
.story-expand-body strong { color: var(--ink); }
.story-expand-body table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}
.story-expand-body th, .story-expand-body td {
  border: 1px solid var(--border);
  padding: 12px 14px;
  vertical-align: top;
  text-align: left;
}
.story-expand-body th {
  font-family: var(--fm);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-f);
}
.story-table { overflow-x: auto; display: block; }
.story-link { color: var(--accent-light); font-weight: 600; }

.story-proof {
  display: flex; flex-wrap: wrap; gap: 10px;
  justify-content: center;
  margin-top: 26px;
}
.story-proof-chip {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--fm);
  font-size: 12px; font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--ink-s);
  text-decoration: none;
  padding: 8px 14px;
  border-radius: var(--pill);
  border: 1px solid var(--sp-beat-border);
  background: var(--sp-beat-accent);
  transition: color 0.2s, border-color 0.2s;
}
.story-proof-chip:hover { color: var(--ink); text-decoration: none; }
.story-proof-chip::before { content: '\2713'; color: var(--sp-beat); }

.story-next { text-align: center; margin-top: 30px; }

.story-anchor-legacy { position: relative; top: -80px; display: block; height: 0; }

/* One-focal-animation guard: a non-focal beat never animates its visual. */
.story-beat:not(.is-focal) .story-anim { animation: none; }

@media (prefers-reduced-motion: reduce) {
  .story-anim { animation: none !important; }
}

@media (max-width: 720px) {
  .story-plain { font-size: 15.5px; }
  .story-expand-summary { font-size: 15px; }
}

/* ---- Wave 2: stat proof chip and the promise-checkpoint ledger. ---- */

.story-proof-stat { cursor: default; }
.story-proof-stat::before { content: '\2713'; }
.story-proof-date { font-weight: 400; color: var(--ink-f); letter-spacing: 0.02em; }

.story-ledger { margin-top: 8px; }
.story-ledger td { vertical-align: top; }
.story-ledger-evidence {
  margin: 8px 0 0; padding-left: 18px;
  font-size: 12px; color: var(--ink-f); line-height: 1.6;
}
.story-ledger-evidence code {
  font-family: var(--fm); font-size: 11.5px;
  background: transparent; padding: 0; color: var(--ink-f);
}

.status-chip {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--fm);
  font-size: 11px; font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase;
  padding: 4px 10px; border-radius: var(--pill);
  border: 1px solid var(--border);
  color: var(--ink-s);
  white-space: nowrap;
}
.status-chip.is-live {
  color: var(--green);
  border-color: rgba(52, 211, 153, 0.3);
  background: rgba(52, 211, 153, 0.08);
}
.status-chip.is-watch {
  color: var(--blue);
  border-color: rgba(59, 130, 246, 0.3);
  background: rgba(59, 130, 246, 0.08);
}
.status-chip.is-boundary {
  color: var(--pink);
  border-color: rgba(236, 72, 153, 0.3);
  background: rgba(236, 72, 153, 0.08);
}

/* ==========================================================
   WAVE 3 SKIN
   Source: design/WAVE_3_DESIGN_DIRECTIVE_v1_0_0.md

   North star: the luminous fingerprint. Prismatic light alive
   against deep black. Light behaves like light. Spectral color
   is ENERGY on edges, glows and indicators, never paint poured
   over body-width text.

   Scope: this file loads only from includes/story-page.php, so
   every rule here reaches the five story surfaces and nothing
   else on the site. Nothing above is deleted. This block sits
   last and reframes by cascade.
   ========================================================== */

/* ---- 1. One face. Weight and size carry hierarchy. --------
   The site body token is a serif. The directive bans serif on
   these surfaces. Nunito Sans is already loaded by
   shared-head.php at weights 300 to 900, so this costs no new
   font request. Scoped to the story tree only. */

.story-hero,
.story-beat,
.story-rail {
  --story-sans: 'Nunito Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
}

.story-hero h1,
.story-beat .section-title,
.story-plain,
.story-expand-summary,
.story-expand-body,
.story-beat-eyebrow,
.story-rail-link,
.story-proof-chip,
.story-next {
  font-family: var(--story-sans);
}

.story-hero h1 {
  font-size: clamp(34px, 5.4vw, 60px);
  font-weight: 800;
  line-height: 1.04;
  letter-spacing: -0.03em;
}

.story-beat .section-title {
  font-size: clamp(28px, 4.2vw, 50px);
  font-weight: 800;
  line-height: 1.06;
  letter-spacing: -0.028em;
  /* Wide enough that a short headline keeps its own line breaks. A ch
     cap orphaned the last word of every two-clause headline. */
  max-width: 800px;
  margin-left: auto;
  margin-right: auto;
  text-wrap: balance;
}

/* Kicker: same face, small and wide, never monospace. */
.story-beat-eyebrow,
.story-hero .hero-label {
  font-family: var(--story-sans);
  font-size: 11.5px;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

/* ---- 2. One accent per phrase. Rainbow text is banned. -----
   The beat data marks its emphasis phrase with .gradient-text.
   That intent is kept. The rainbow fill is replaced by the
   beat's own single tint, so the two-tone headline still reads
   as two-tone without becoming a paint chart. */

.story-beat .section-title .gradient-text,
.story-beat .section-title .gradient-text-green,
.story-beat .section-title .glow,
.story-hero h1 .gradient-text,
.story-hero h1 .glow {
  background: none;
  -webkit-background-clip: initial;
  background-clip: initial;
  -webkit-text-fill-color: currentColor;
  color: var(--sp-beat);
}

.story-hero h1 .gradient-text,
.story-hero h1 .glow {
  color: var(--sp-7);
}

/* ---- 3. The dark is not flat. -----------------------------
   Two depth layers plus a faint ridge field that echoes the
   fingerprint. Well under the readability floor: the ridge
   field peaks near 4 percent and carries no text. */

.story-beat::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(120% 90% at 50% -20%,
      color-mix(in srgb, var(--sp-beat) 9%, transparent) 0%,
      transparent 62%),
    repeating-radial-gradient(circle at 78% 34%,
      transparent 0 26px,
      color-mix(in srgb, var(--sp-beat) 4%, transparent) 26px 27px,
      transparent 27px 54px);
  opacity: 0.55;
  mask-image: radial-gradient(120% 100% at 50% 0%, #000 0%, transparent 78%);
  -webkit-mask-image: radial-gradient(120% 100% at 50% 0%, #000 0%, transparent 78%);
}

.story-beat > .container { position: relative; z-index: 1; }

.story-hero {
  background:
    radial-gradient(90% 70% at 50% 0%,
      color-mix(in srgb, var(--sp-7) 16%, transparent) 0%,
      transparent 70%),
    var(--bg);
}

/* ---- 4. A collapsed card still looks designed. ------------
   The prior state was a bare hairline rule, which reads as an
   unstyled list. Every group is now a card with its own ground,
   a lit left edge, and a lift on hover. Nothing is hidden that
   was visible before; the same summary and body render. */

.story-expand-set {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 860px;
}

.story-expand {
  position: relative;
  border: 1px solid var(--border);
  border-radius: 14px;
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--sp-beat) 5%, var(--bg-card)) 0%,
      var(--bg-card) 100%);
  overflow: hidden;
  transition: border-color 0.22s ease, transform 0.22s ease, box-shadow 0.22s ease;
}
.story-expand:first-child { border-top: 1px solid var(--border); }

.story-expand::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 2px;
  background: var(--sp-beat);
  opacity: 0.34;
  transition: opacity 0.22s ease, box-shadow 0.22s ease;
}

.story-expand:hover {
  border-color: color-mix(in srgb, var(--sp-beat) 34%, var(--border));
  transform: translateY(-1px);
  box-shadow: 0 10px 30px -18px color-mix(in srgb, var(--sp-beat) 60%, transparent);
}
.story-expand:hover::before,
.story-expand[open]::before {
  opacity: 1;
  box-shadow: 0 0 14px color-mix(in srgb, var(--sp-beat) 70%, transparent);
}

.story-expand[open] {
  border-color: color-mix(in srgb, var(--sp-beat) 30%, var(--border));
}

.story-expand-summary {
  padding: 17px 20px;
  font-size: 15.5px;
  font-weight: 700;
  letter-spacing: -0.005em;
}

.story-expand-body {
  padding: 0 20px 20px;
  font-size: 15px;
}

.story-expand-hint {
  font-size: 18px;
  font-weight: 700;
  line-height: 1;
  width: 26px; height: 26px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%;
  border: 1px solid var(--border);
  color: var(--ink-f);
}
.story-expand[open] .story-expand-hint {
  transform: rotate(45deg);
  color: var(--sp-beat);
  border-color: color-mix(in srgb, var(--sp-beat) 45%, transparent);
}

/* ---- 5. Art glows out of the dark. ------------------------
   The reference art is light on black. A hard rectangle around
   it fights that. The edges now fall off into the page, and a
   soft bloom sits behind the frame. */

.story-figure {
  position: relative;
  margin-top: 34px;
}
.story-figure::before {
  content: '';
  position: absolute;
  left: 50%; top: 50%;
  width: min(120%, 620px);
  height: min(120%, 620px);
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(circle,
    color-mix(in srgb, var(--sp-beat) 22%, transparent) 0%,
    transparent 66%);
  filter: blur(28px);
  pointer-events: none;
  z-index: 0;
}
.story-figure img {
  position: relative;
  z-index: 1;
  border-radius: 0;
  /* The source art carries its own dark ground. A gentle falloff left
     that ground visible as a rectangle, which is the exact hard-edged
     box the directive rules out. This cuts inside the artwork so only
     the lit ridges survive. */
  mask-image: radial-gradient(circle at 50% 50%, #000 40%, transparent 68%);
  -webkit-mask-image: radial-gradient(circle at 50% 50%, #000 40%, transparent 68%);
  /* The mask hides the outer third of the frame, but the element still
     occupies its full box, which left a dead void above and below the
     art. These pull the layout back to the lit area. Percentages
     resolve against the container width, so the recovery scales with
     the image instead of being a fixed guess. */
  margin-block: -7% -11%;
}
.story-figure-focal img { max-width: min(100%, 420px); }

/* ---- 6. Rhythm. No dead voids. ----------------------------
   The directive caps the gap between a section end and the next
   kicker at 120px desktop and 64px mobile. */

.story-beat { padding: clamp(56px, 6vw, 108px) 0; }
.story-beat .story-plain { margin-top: 18px; }
.story-plain p { margin-bottom: 16px; }
.story-expand-set { margin-top: 30px; }
.story-proof { margin-top: 28px; }
.story-next { margin-top: 32px; }

/* ---- 7. Live indicators read as light. -------------------- */

.story-proof-chip {
  border-radius: var(--pill);
  transition: color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}
.story-proof-chip:hover {
  border-color: color-mix(in srgb, var(--sp-beat) 55%, transparent);
  box-shadow: 0 0 18px -4px color-mix(in srgb, var(--sp-beat) 55%, transparent);
}

.story-rail {
  background: color-mix(in srgb, var(--bg) 88%, transparent);
}
.story-rail-link { font-weight: 700; letter-spacing: 0.08em; }
.story-rail-link[aria-current="true"] {
  box-shadow: 0 0 16px -6px color-mix(in srgb, var(--sp-beat) 80%, transparent);
}

/* ---- 8. Motion with restraint. Nothing bounces. ----------- */

.story-hero h1.anim-float { animation: none; }

@media (prefers-reduced-motion: no-preference) {
  .story-beat .section-title,
  .story-beat .story-plain,
  .story-beat .story-expand-set {
    animation: story-rise 0.34s cubic-bezier(0.22, 0.61, 0.36, 1) both;
  }
  .story-beat .story-plain { animation-delay: 0.04s; }
  .story-beat .story-expand-set { animation-delay: 0.08s; }
}

@keyframes story-rise {
  from { opacity: 0.45; transform: translateY(8px); }
  to   { opacity: 1;    transform: none; }
}

/* ---- 9. Phone first. Nothing scrolls sideways. ------------ */

@media (max-width: 720px) {
  .story-beat { padding: 44px 0; }
  .story-beat .section-title { max-width: 100%; font-size: clamp(25px, 7.4vw, 34px); }
  .story-expand-summary { padding: 15px 16px; font-size: 15px; }
  .story-expand-body { padding: 0 16px 17px; }
  .story-figure { margin-top: 26px; }
  .story-proof { margin-top: 22px; }
  .story-next { margin-top: 26px; }
}

.story-hero,
.story-beat,
.story-rail { max-width: 100%; }
