/* adventure-theme.css — StoryForge Graphic Novel Design System (PR1: Foundation)
   Loads after adventure-base.css / adventure-play.css / adventure-particles.css /
   adventure-effects.css, BEFORE adventure-responsive.css.
   Re-declares --sf-* tokens with the warm graphic-novel palette. */

:root {
  /* Surfaces */
  --sf-bg-page:        #1A1410;
  --sf-bg-panel:       #221A14;
  --sf-bg-caption:     #F2E8D5;
  --sf-bg-caption-alt: #E8DCC4;

  /* Ink (dark text on cream) */
  --sf-ink-primary:    #1A1410;
  --sf-ink-secondary:  #4A3D2E;
  --sf-ink-muted:      #7A6850;

  /* Text on dark */
  --sf-text-primary:   #F2E8D5;
  --sf-text-secondary: #C4B69A;
  --sf-text-muted:     #8A7A60;

  /* Accent — single warm hazard orange */
  --sf-accent:         #EF8A1F;
  --sf-accent-soft:    #FFB04A;
  --sf-accent-deep:    #C46A0F;
  --sf-accent-glow:    rgba(239, 138, 31, 0.4);
  --sf-accent-rgb:     239, 138, 31;

  /* Status — diegetic, lives on dossier not chrome */
  --sf-status-hp:      #C44A2E;
  --sf-status-xp:      #EF8A1F;
  --sf-status-good:    #6B8E4E;
  --sf-status-warn:    #D4A437;
  --sf-status-danger:  #8B2E1F;

  /* Borders */
  --sf-border-heavy:   #1A1410;
  --sf-border-medium:  #4A3D2E;
  --sf-border-light:   rgba(242, 232, 213, 0.12);

  /* Backwards-compat overrides for legacy tokens still referenced across
     adventure-base/play/effects/particles. New values steer existing rules
     into the warm palette without renaming any of the 590 token references. */
  --sf-bg-deep:           var(--sf-bg-page);
  --sf-bg-surface:        rgba(34, 26, 20, 0.4);
  --sf-bg-surface-solid:  rgba(34, 26, 20, 0.85);
  --sf-bg-surface-hover:  rgba(34, 26, 20, 0.6);
  --sf-bg-elevated:       rgba(34, 26, 20, 0.95);

  --sf-text:     var(--sf-text-primary);
  --sf-text-rgb: 242, 232, 213;

  --sf-cta:       var(--sf-accent);
  --sf-cta-hover: var(--sf-accent-soft);

  --sf-success: var(--sf-status-good);
  --sf-danger:  var(--sf-status-hp);
  --sf-warning: var(--sf-status-warn);
  --sf-info:    var(--sf-status-good);

  --sf-border:        rgba(239, 138, 31, 0.18);
  --sf-border-hover:  rgba(239, 138, 31, 0.35);
  --sf-border-active: rgba(239, 138, 31, 0.55);
  --sf-glass-border:  1px solid rgba(239, 138, 31, 0.18);
  --sf-shadow-glow:   0 0 20px rgba(239, 138, 31, 0.15);
  --sf-gradient:      linear-gradient(135deg, #EF8A1F, #C44A2E);

  /* Typography — four families (Cormorant intentionally dropped per plan) */
  --sf-font-display:  'Bangers', 'Russo One', 'Anton', sans-serif;
  --sf-font-headline: 'Lora', Georgia, serif;
  --sf-font-body:     'Lora', Georgia, serif;
  --sf-font-ui:       'Space Grotesk', 'Inter', system-ui, sans-serif;
  --sf-font-mono:     'JetBrains Mono', 'Space Mono', monospace;
}

/* ── Base body restyle (warm page) ── */
.adv-app {
  background: var(--sf-bg-page);
  color: var(--sf-text-primary);
  font-family: var(--sf-font-body);
}

body[data-theme="dark"] {
  background: var(--sf-bg-page) !important;
}

/* ── Headline + display type defaults ── */
.adv-header__logo {
  font-family: var(--sf-font-display);
  letter-spacing: 0.04em;
}

/* Stacked logo wordmark + "Graphic Novel Hub" tagline (Mock 1) */
.adv-header__logo-stack {
  display: flex;
  flex-direction: column;
  line-height: 1;
  gap: 2px;
}

.adv-header__logo-name {
  font-family: var(--sf-font-display);
  font-size: 18px;
  letter-spacing: 0.06em;
  color: var(--sf-text-primary);
}

.adv-header__logo-tagline {
  font-family: var(--sf-font-ui);
  font-size: 9px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--sf-text-muted);
}

/* ============================================================
   PR5 — Hub mockup fidelity: purge old-palette artifacts,
   hide feature cards & coming-soon, dotted bg, warm save cards
   ============================================================ */

/* Hide the Mock 1 omissions: feature cards + browse-gallery footer.
   Coming-soon kept visible per user request.
   Note: specificity must beat .adv-hub > section (0,1,1) and any later
   self-rules in this file, so we use .adv-hub scoped selectors (0,2,0). */
.adv-hub > .adv-hub__features,
.adv-hub__links {
  display: none;
}

/* Cream banner section titles (Mock 1: "WHAT TO READ NEXT" pill) */
.adv-hub__section-title {
  display: inline-flex;
  background: var(--sf-bg-caption);
  background-image: url("/storyforge/images/assets/paper-tile.png");
  background-size: 256px;
  background-blend-mode: multiply;
  color: var(--sf-ink-primary);
  border: 2px solid var(--sf-border-heavy);
  border-radius: 4px;
  padding: 0.5rem 1.25rem;
  font-family: var(--sf-font-display);
  font-size: 14px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  margin: 0 auto 1.25rem;
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.4);
  align-self: center;
  align-items: center;
  gap: 0.5rem;
}

.adv-hub__section-title i {
  color: var(--sf-accent-deep);
  font-size: 12px;
}

/* Center the section title within its parent <section> */
.adv-hub > section {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.adv-hub > section > .adv-hub__saves,
.adv-hub > section > .adv-hub__genres,
.adv-hub > section > .adv-daily-limit {
  width: 100%;
}

/* ── Daily limit badge — override hardcoded purple with warm amber ── */
.adv-daily-limit {
  background: rgba(212, 164, 55, 0.14) !important;
  border: 1px solid var(--sf-status-warn) !important;
  color: var(--sf-status-warn) !important;
  font-family: var(--sf-font-ui);
  letter-spacing: 0.04em;
  border-radius: 4px;
  padding: 0.4rem 0.75rem;
}

/* ── Saved adventure cards — warm dossier-card treatment ── */
.adv-hub__save-card {
  background: var(--sf-bg-panel);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border: 2px solid var(--sf-border-heavy);
  border-radius: 4px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.45);
  transition: transform 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease;
}

.adv-hub__save-card:hover {
  background: var(--sf-bg-panel);
  border-color: var(--sf-accent);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.55);
  transform: translateY(-2px);
}

.adv-hub__save-thumb {
  background: var(--sf-bg-page);
  border: 1px solid var(--sf-border-heavy);
  border-radius: 2px;
}

.adv-hub__save-thumb i {
  color: var(--sf-accent);
}

.adv-hub__save-story-title {
  font-family: var(--sf-font-display);
  color: var(--sf-accent);
  letter-spacing: 0.06em;
  opacity: 1;
}

.adv-hub__save-name {
  font-family: var(--sf-font-headline);
  color: var(--sf-text-primary);
}

.adv-hub__save-meta {
  font-family: var(--sf-font-mono);
  color: var(--sf-text-muted);
  font-size: 11px;
}

.adv-hub__save-progress {
  background: var(--sf-bg-page);
}

.adv-hub__save-progress-fill {
  background: var(--sf-accent);
}

.adv-hub__save-hp-bar {
  background: var(--sf-bg-page);
  border: 1px solid var(--sf-border-medium);
}

.adv-hub__save-hp-fill {
  background: var(--sf-status-good);
}

.adv-hub__save-hp-fill--warning {
  background: var(--sf-status-warn);
}

.adv-hub__save-hp-fill--low {
  background: var(--sf-status-hp);
}

/* IN PROGRESS / COMPLETED status pills */
.adv-hub__save-status {
  font-family: var(--sf-font-mono);
  letter-spacing: 0.08em;
  border-radius: 2px;
  padding: 0.18rem 0.5rem;
}

.adv-hub__save-status--in_progress {
  background: rgba(239, 138, 31, 0.15);
  color: var(--sf-accent);
  border: 1px solid var(--sf-accent-deep);
}

.adv-hub__save-status--completed {
  background: rgba(107, 142, 78, 0.18);
  color: var(--sf-status-good);
  border: 1px solid var(--sf-status-good);
}

.adv-hub__save-ago {
  font-family: var(--sf-font-mono);
  color: var(--sf-text-muted);
}

.adv-hub__save-delete {
  color: var(--sf-text-muted);
}

.adv-hub__save-delete:hover {
  color: var(--sf-status-hp);
}

/* ── Subtle dotted halftone page background (Mock 1) ──
   Lives behind everything inside the Hub. Tiny dots, very low opacity. */
.adv-hub {
  position: relative;
}

.adv-hub::before {
  content: '';
  position: absolute;
  inset: -2rem;
  pointer-events: none;
  z-index: -1;
  background-image: radial-gradient(
    circle,
    rgba(242, 232, 213, 0.04) 1px,
    transparent 1.5px
  );
  background-size: 18px 18px;
}

/* ============================================================
   PR6 — Hub mockup-fidelity round 2: header pills, hero overhaul,
   genre kicker tab, comic-page edge effects
   ============================================================ */

/* ── Header navigation as pill buttons (Mock 1) ── */
.adv-header__nav {
  gap: 0.6rem;
}

.adv-header__nav .adv-header__link {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.42rem 0.85rem;
  background: transparent;
  border: 2px solid var(--sf-border-heavy);
  border-radius: 4px;
  color: var(--sf-text-primary);
  font-family: var(--sf-font-display);
  font-size: 13px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.adv-header__nav .adv-header__link:hover {
  background: var(--sf-bg-panel);
  border-color: var(--sf-accent);
  color: var(--sf-accent);
}

.adv-header__nav .adv-header__link--active {
  background: var(--sf-accent);
  border-color: var(--sf-border-heavy);
  color: var(--sf-bg-page);
}

.adv-header__nav .adv-header__link--active:hover {
  background: var(--sf-accent-soft);
  color: var(--sf-bg-page);
  border-color: var(--sf-border-heavy);
}

/* Inline icons inside nav pills */
.adv-header__nav .adv-header__link i {
  font-size: 12px;
}

/* ── Hero overhaul: bigger gradient title + caption box + outline CTA ── */

.adv-hub__hero--graphic-novel {
  min-height: 460px;
  border-width: 4px;
}

.adv-hub__hero--graphic-novel::after {
  /* Lighter gradient — the title sits high in the panel now, not bottom */
  background: linear-gradient(
    180deg,
    rgba(26, 20, 16, 0.05) 0%,
    rgba(26, 20, 16, 0.35) 60%,
    rgba(26, 20, 16, 0.85) 100%
  );
}

.adv-hub__hero--graphic-novel .adv-hub__hero-content {
  /* Anchor content to the LEFT side, vertically centered */
  position: absolute;
  inset: 0;
  padding: 3rem 4rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  gap: 1rem;
}

.adv-hub__hero--graphic-novel h1 {
  font-family: var(--sf-font-display);
  font-size: clamp(56px, 9vw, 132px);
  line-height: 0.92;
  letter-spacing: 0.02em;
  background: linear-gradient(
    180deg,
    var(--sf-text-primary) 0%,
    var(--sf-text-primary) 55%,
    var(--sf-accent-soft) 90%,
    var(--sf-accent-deep) 100%
  );
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  text-shadow: 0 6px 0 rgba(0, 0, 0, 0.55), 0 12px 32px rgba(0, 0, 0, 0.6);
  -webkit-text-stroke: 2px rgba(0, 0, 0, 0.65);
  paint-order: stroke fill;
  margin: 0;
  filter: drop-shadow(0 4px 0 rgba(0, 0, 0, 0.4));
  transform: skew(-2deg, -0.5deg);
  max-width: 900px;
}

/* Caption box overlay — separate cream pill with the tagline (Mock 1) */
.adv-hub__hero--graphic-novel p {
  display: inline-block;
  background-color: var(--sf-bg-caption);
  background-image: url("/storyforge/images/assets/paper-tile.png");
  background-size: 256px;
  background-blend-mode: multiply;
  color: var(--sf-ink-primary);
  border: 2px solid var(--sf-border-heavy);
  border-radius: 4px;
  padding: 0.7rem 1.1rem;
  font-family: var(--sf-font-body);
  font-style: normal;
  font-size: 16px;
  line-height: 1.4;
  max-width: 36ch;
  margin: 0;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
  text-shadow: none;
}

/* Hero CTA — outline cream variant matching Mock 1 (caption-box adjacent) */
.adv-hub__hero-cta {
  background: var(--sf-bg-caption);
  background-image: url("/storyforge/images/assets/paper-tile.png");
  background-size: 256px;
  background-blend-mode: multiply;
  color: var(--sf-ink-primary);
  border: 2px solid var(--sf-border-heavy);
}

.adv-hub__hero-cta:hover {
  background: var(--sf-accent);
  background-image: none;
  color: var(--sf-bg-page);
}

/* ── Genre cards: yellow folder-tab kicker at top-left (Mock 1) ──
   The kicker repeats the genre name in a small offset tab. CSS-only via
   ::before so we don't have to touch the JS render. */
.adv-hub__genre {
  /* Make room for the tab to overhang */
  padding-top: 18px;
}

.adv-hub__genre::before {
  content: attr(data-genre);
  position: absolute;
  top: -10px;
  left: 12px;
  padding: 4px 10px 6px;
  background: var(--sf-status-warn);
  color: var(--sf-bg-page);
  font-family: var(--sf-font-display);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  border: 2px solid var(--sf-border-heavy);
  border-radius: 2px;
  z-index: 3;
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.4);
  /* Slight rotation gives the folder-tab feel */
  transform: rotate(-2deg);
}

/* Coming-soon doesn't get the kicker; locked cards DO get the kicker
   (their PRO state is communicated by the existing lock badge). */
.adv-hub__genre--coming-soon::before {
  display: none;
}

/* Genre-ID → proper display label overrides (data-genre is "scifi"/"postapoc";
   we want "SCI-FI" / "POST-APOC" via attribute selectors, CSS-only). */
.adv-hub__genre[data-genre="scifi"]::before {
  content: 'Sci-Fi';
}

.adv-hub__genre[data-genre="postapoc"]::before {
  content: 'Post-Apoc';
}

/* ============================================================
   PR7 — Hub mockup-fidelity round 3
   Address: hero headline drama, header pill weight, card weight,
   comic page-edge action lines (SVG, no bitmaps needed)
   ============================================================ */

/* ── Header pills: chunkier, cream-filled (Mock 1 style) ── */
.adv-header {
  background: var(--sf-bg-page);
  border-bottom: 3px solid var(--sf-border-heavy);
  padding: 0.6rem 1.5rem;
}

.adv-header__nav .adv-header__link {
  /* Override PR6 transparent-bg with cream-filled comic-button look */
  background: var(--sf-bg-caption);
  background-image: url("/storyforge/images/assets/paper-tile.png");
  background-size: 256px;
  background-blend-mode: multiply;
  color: var(--sf-ink-primary);
  border: 2.5px solid var(--sf-border-heavy);
  padding: 0.55rem 1.1rem;
  font-size: 14px;
  letter-spacing: 0.12em;
  box-shadow: 0 3px 0 var(--sf-border-heavy);
  border-radius: 6px;
}

.adv-header__nav .adv-header__link:hover {
  background: var(--sf-accent-soft);
  background-image: none;
  color: var(--sf-bg-page);
  border-color: var(--sf-border-heavy);
  transform: translateY(-1px);
  box-shadow: 0 4px 0 var(--sf-border-heavy);
}

.adv-header__nav .adv-header__link--active {
  background: #F5C842;
  background-image: none;
  color: #000;
  border-color: var(--sf-border-heavy);
}

.adv-header__nav .adv-header__link--active:hover {
  background: var(--sf-accent-soft);
  background-image: none;
}

.adv-header__nav .adv-header__link i {
  font-size: 13px;
}

/* ── Hero headline: dramatic comic-banner treatment ──
   Bigger, heavier 3D depth via stacked text-shadows that simulate offset
   ink layers. The gradient runs cream→accent→deep so it reads as a
   metallic-printed comic title. */
.adv-hub__hero--graphic-novel {
  min-height: 520px;
  border-width: 5px;
}

.adv-hub__hero--graphic-novel h1 {
  font-family: var(--sf-font-display);
  font-size: clamp(72px, 11vw, 168px);
  line-height: 0.88;
  letter-spacing: 0.015em;

  /* Layered gradient — cream highlight on top, deep amber at bottom */
  background: linear-gradient(
    180deg,
    #FFE9C9 0%,
    var(--sf-text-primary) 28%,
    var(--sf-accent-soft) 62%,
    var(--sf-accent) 82%,
    var(--sf-accent-deep) 100%
  );
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;

  /* Heavy black 3D stacked-shadow depth (simulates inked outline + drop) */
  filter:
    drop-shadow(2px 0 0 #1A1410)
    drop-shadow(-2px 0 0 #1A1410)
    drop-shadow(0 2px 0 #1A1410)
    drop-shadow(0 -2px 0 #1A1410)
    drop-shadow(4px 4px 0 rgba(0, 0, 0, 0.85))
    drop-shadow(8px 8px 0 rgba(0, 0, 0, 0.55))
    drop-shadow(12px 12px 24px rgba(0, 0, 0, 0.7));

  /* Subtle perspective skew for the comic-banner feel */
  transform: skew(-3deg, -1deg);
  transform-origin: left center;

  margin: 0;
  max-width: 100%;
  text-shadow: none;
  -webkit-text-stroke: 0;
}

/* ── Genre cards: heavier comic-card weight ── */
.adv-hub__genre:hover {
  transform: translateY(-4px) rotate(-0.3deg);
  box-shadow: 0 10px 0 var(--sf-border-heavy), 0 14px 28px rgba(0, 0, 0, 0.6);
}

/* Bottom panel (title strap + READ NOW) — heavier cream block */
.adv-hub__genre-name {
  font-size: 20px;
  letter-spacing: 0.08em;
  padding: 0.7rem 0.75rem 0.35rem;
  border-top: 3px solid var(--sf-border-heavy);
  background: var(--sf-bg-caption);
  background-image: url("/storyforge/images/assets/paper-tile.png");
  background-size: 256px;
  background-blend-mode: multiply;
  color: var(--genre-color, var(--sf-ink-primary));
  text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.15);
}

.adv-hub__genre-desc {
  background: var(--sf-bg-caption);
  background-image: url("/storyforge/images/assets/paper-tile.png");
  background-size: 256px;
  background-blend-mode: multiply;
  color: var(--sf-ink-secondary);
  font-size: 12px;
  letter-spacing: 0.02em;
  padding: 0 0.75rem 0.6rem;
  font-family: var(--sf-font-body);
  font-style: italic;
}

.adv-hub__genre:not(.adv-hub__genre--locked):not(.adv-hub__genre--coming-soon)::after {
  background: var(--sf-bg-caption);
  background-image: url("/storyforge/images/assets/paper-tile.png");
  background-size: 256px;
  background-blend-mode: multiply;
  color: var(--sf-ink-secondary);
  font-family: var(--sf-font-display);
  font-size: 12px;
  letter-spacing: 0.16em;
  padding: 0.55rem 0;
  border-top: 2px solid var(--sf-border-heavy);
}

.adv-hub__genre:hover:not(.adv-hub__genre--locked):not(.adv-hub__genre--coming-soon)::after {
  background: var(--sf-accent);
  background-image: none;
  color: var(--sf-bg-page);
}

/* Kicker tab — heavier folder-tab feel with shadow */
.adv-hub__genre::before {
  top: -14px;
  left: 14px;
  padding: 6px 14px 8px;
  font-size: 13px;
  letter-spacing: 0.16em;
  border: 3px solid var(--sf-border-heavy);
  border-radius: 3px;
  box-shadow: 0 4px 0 var(--sf-border-heavy), 0 6px 10px rgba(0, 0, 0, 0.5);
}

/* ── Coming-soon card restored (per user request) ──
   Same size as other cards, dashed border, plus icon inside, paper bottom.*/
.adv-hub__genres > .adv-hub__genre--coming-soon {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  background: var(--sf-bg-panel);
  border: 3px dashed var(--sf-border-medium);
  aspect-ratio: 3 / 4;
  padding: 1rem;
  opacity: 0.65;
}

.adv-hub__genre--coming-soon .adv-hub__coming-soon-icon {
  font-size: 2.2rem;
  color: var(--sf-text-muted);
  margin-bottom: 0.6rem;
}

.adv-hub__genre--coming-soon .adv-hub__genre-name,
.adv-hub__genre--coming-soon .adv-hub__genre-desc {
  background: transparent;
  background-image: none;
  border: none;
  color: var(--sf-text-secondary);
  padding: 0.2rem 0;
}

.adv-hub__genre--coming-soon .adv-hub__genre-desc {
  color: var(--sf-text-muted);
  font-style: normal;
}

/* ── Comic-page action lines around the Hub via SVG (no bitmaps) ──
   Two corner overlays in opposite corners + faint full-page sketchy
   border. The SVGs are inline data-URIs so there are zero new HTTP
   requests and they scale crisply to any size. */

.adv-hub::after {
  /* Replace the dashed border from PR6 with corner action-line SVGs */
  content: '';
  position: absolute;
  inset: -1.5rem;
  pointer-events: none;
  z-index: 1;
  background:
    /* Top-left action-line burst */
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220' viewBox='0 0 220 220'><g fill='none' stroke='%23F2E8D5' stroke-width='1.4' stroke-linecap='round' opacity='0.18'><path d='M0,8 L70,40'/><path d='M0,30 L80,55'/><path d='M0,55 L85,72'/><path d='M0,82 L92,90'/><path d='M0,108 L96,108'/><path d='M0,135 L92,128'/><path d='M0,160 L88,148'/><path d='M0,184 L80,165'/><path d='M0,206 L70,180'/><path d='M8,0 L40,70'/><path d='M30,0 L55,80'/><path d='M55,0 L72,85'/><path d='M82,0 L90,92'/></g></svg>") top left no-repeat,
    /* Bottom-right action-line burst (mirrored) */
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220' viewBox='0 0 220 220'><g fill='none' stroke='%23F2E8D5' stroke-width='1.4' stroke-linecap='round' opacity='0.18'><path d='M220,212 L150,180'/><path d='M220,190 L140,165'/><path d='M220,165 L135,148'/><path d='M220,138 L128,130'/><path d='M220,112 L124,112'/><path d='M220,85 L128,92'/><path d='M220,60 L132,72'/><path d='M220,36 L140,55'/><path d='M220,14 L150,40'/><path d='M212,220 L180,150'/><path d='M190,220 L165,140'/><path d='M165,220 L148,135'/><path d='M138,220 L130,128'/></g></svg>") bottom right no-repeat;
  background-size: 220px 220px, 220px 220px;
  border: none;
  border-radius: 0;
}

/* Sketchy SVG frame border around the entire Hub area (replaces the
   plain dashed box from PR6 with hand-drawn-looking ink strokes). */
.adv-hub::before {
  /* Override PR5 dotted-pattern bg with combined dotted + sketchy frame */
  background-image:
    radial-gradient(circle, rgba(242, 232, 213, 0.04) 1px, transparent 1.5px),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100%25' height='100%25' preserveAspectRatio='none'><rect x='4' y='4' width='calc(100%25 - 8px)' height='calc(100%25 - 8px)' fill='none' stroke='%23F2E8D5' stroke-width='2' stroke-dasharray='8 5 2 5' opacity='0.07'/></svg>");
  background-size: 18px 18px, 100% 100%;
  background-repeat: repeat, no-repeat;
}

/* ── Comic-page hand-drawn edge effect ──
   Faint sketchy border around the entire Hub area, adds the "page from
   a comic book" framing without resorting to a bitmap asset. */
.adv-hub::after {
  content: '';
  position: absolute;
  inset: -1rem;
  pointer-events: none;
  z-index: -1;
  border: 2px dashed rgba(242, 232, 213, 0.06);
  border-radius: 6px;
}

/* ── Tighten daily-limit badge so it reads as a small note, not a banner ── */
.adv-daily-limit {
  font-size: 11px !important;
  padding: 0.3rem 0.6rem !important;
  letter-spacing: 0.08em !important;
}

/* ── Center the section content blocks (saves grid + genres grid) ──
   Use auto margins + max-width so the saves cards don't span the full
   1280px Hub width when there's only 1 or 2 of them. */
.adv-hub__saves {
  max-width: 1024px;
  margin: 0 auto;
}

.adv-hub__genres {
  max-width: 1240px;
  margin: 0 auto;
}

.adv-panel__title,
.adv-upgrade-title {
  font-family: var(--sf-font-display);
  letter-spacing: 0.08em;
  color: var(--sf-accent);
}

/* UI labels, nav, buttons */
.adv-header__link,
.adv-btn,
.adv-badge,
.adv-user-status {
  font-family: var(--sf-font-ui);
}

/* ── SVG grain overlay (low opacity; recedes behind everything) ── */
.adv-app::after {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 9999;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='256' height='256'><filter id='g'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0.18 0'/></filter><rect width='100%25' height='100%25' filter='url(%23g)' opacity='0.5'/></svg>");
  mix-blend-mode: overlay;
  opacity: 0.35;
}

/* ============================================================
   HUB — full-bleed comic-panel hero + illustrated genre cards
   ============================================================ */

.adv-hub {
  max-width: 1280px;
}

/* Hero — single full-bleed comic panel with display-font title overlay */
.adv-hub__hero--graphic-novel {
  border: 3px solid var(--sf-border-heavy);
  border-radius: 6px;
  min-height: 420px;
  background: var(--sf-bg-panel);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
}

.adv-hub__hero--graphic-novel .adv-hub__hero-bg {
  opacity: 1;
}

.adv-hub__hero--graphic-novel::after {
  background: linear-gradient(
    180deg,
    rgba(26, 20, 16, 0) 40%,
    rgba(26, 20, 16, 0.55) 75%,
    rgba(26, 20, 16, 0.95) 100%
  );
}

.adv-hub__hero--graphic-novel .adv-hub__hero-content {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  text-align: left;
  padding: 2.5rem 3rem;
}

.adv-hub__hero--graphic-novel h1 {
  font-family: var(--sf-font-display);
  font-size: clamp(48px, 7vw, 96px);
  line-height: 0.95;
  letter-spacing: 0.04em;
  color: var(--sf-text-primary);
  text-shadow: 0 4px 18px rgba(0, 0, 0, 0.85), 0 0 32px rgba(239, 138, 31, 0.25);
  margin: 0 0 0.4rem 0;
}

.adv-hub__hero--graphic-novel p {
  font-family: var(--sf-font-headline);
  font-size: clamp(15px, 1.4vw, 19px);
  font-style: italic;
  color: var(--sf-text-secondary);
  max-width: 540px;
  margin: 0;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.8);
}

/* Section titles (rail headers) */
.adv-hub__section-title {
  font-family: var(--sf-font-display);
  font-size: 16px;
  letter-spacing: 0.12em;
  color: var(--sf-accent);
  text-transform: uppercase;
}

.adv-hub__section-title i {
  color: var(--sf-accent);
}

/* Genre cards as illustrated comic covers (3:4 portrait) */
.adv-hub__genres {
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 1rem;
}

.adv-hub__genre {
  background: var(--sf-bg-panel);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border: 4px solid var(--sf-border-heavy);
  border-radius: 4px;
  padding: 0;
  /* overflow VISIBLE so the kicker-tab pseudo can poke out above the card.
     Inner image clipping handled separately on .adv-hub__genre-img */
  overflow: visible;
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}

.adv-hub__genre-img {
  /* Image still has clean top corners since the parent overflow is now visible */
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}

.adv-hub__genre:hover {
  transform: translateY(-4px);
  border-color: var(--genre-color, var(--sf-accent));
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.55);
  background: var(--sf-bg-panel);
}

.adv-hub__genre::after {
  display: none;
}

.adv-hub__genre-img {
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  opacity: 1;
  display: block;
}

.adv-hub__genre:hover .adv-hub__genre-img {
  opacity: 1;
  transform: none;
}

/* Title strap — black ribbon at the bottom, display font, per-genre warm accent */
.adv-hub__genre-name {
  font-family: var(--sf-font-display);
  font-size: 18px;
  letter-spacing: 0.08em;
  color: var(--genre-color, var(--sf-accent));
  background: var(--sf-bg-page);
  padding: 0.6rem 0.75rem 0.3rem;
  margin: 0;
  text-align: center;
  border-top: 2px solid var(--sf-border-heavy);
}

.adv-hub__genre-desc {
  font-family: var(--sf-font-ui);
  font-size: 11px;
  color: var(--sf-text-secondary);
  background: var(--sf-bg-page);
  padding: 0 0.75rem 0.7rem;
  margin: 0;
  text-align: center;
  letter-spacing: 0.02em;
}

/* Coming-soon card retired — see .adv-hub__genres > .adv-hub__genre--coming-soon
   { display: none } at the top of this file. Decorative styling removed. */

/* Locked card lock badge — warm */
.adv-hub__genre-lock {
  background: rgba(212, 164, 55, 0.18);
  color: var(--sf-status-warn);
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  z-index: 2;
  font-family: var(--sf-font-ui);
  font-size: 10px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 0.25rem 0.5rem;
  border-radius: 2px;
}

/* Feature cards — tighter, less neon */
.adv-hub__features {
  gap: 1rem;
}

.adv-hub__feature {
  background: var(--sf-bg-panel);
  border: 2px solid var(--sf-border-medium);
  border-radius: 4px;
  padding: 1.25rem;
  transition: border-color 0.2s ease;
}

.adv-hub__feature:hover {
  border-color: var(--sf-accent);
  background: var(--sf-bg-panel);
}

.adv-hub__feature i {
  color: var(--sf-accent);
  filter: none;
  font-size: 1.6rem;
}

.adv-hub__feature h3 {
  font-family: var(--sf-font-display);
  font-size: 18px;
  letter-spacing: 0.06em;
  color: var(--sf-text-primary);
  margin: 0.5rem 0 0.3rem;
}

.adv-hub__feature p {
  font-family: var(--sf-font-body);
  font-size: 14px;
  color: var(--sf-text-secondary);
  line-height: 1.5;
  margin: 0;
}

/* ============================================================
   WIZARD — stepper + step 1 dark + steps 2/3 cream-paper mode
   ============================================================ */

/* Stepper */
.adv-wizard__steps {
  margin-bottom: 2rem;
}

.adv-wizard__step {
  background: transparent;
  border: 2px solid var(--sf-border-medium);
  color: var(--sf-text-secondary);
  font-family: var(--sf-font-ui);
}

.adv-wizard__step--active {
  background: var(--sf-accent);
  border-color: var(--sf-accent-deep);
  color: var(--sf-bg-page);
}

.adv-wizard__step-num {
  font-family: var(--sf-font-display);
  font-size: 16px;
  letter-spacing: 0.04em;
}

.adv-wizard__step-label {
  font-family: var(--sf-font-ui);
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.adv-wizard__step-line {
  background: var(--sf-border-medium);
}

.adv-wizard__step--active ~ .adv-wizard__step-line {
  background: var(--sf-border-medium);
}

.adv-wizard__title {
  font-family: var(--sf-font-display);
  color: var(--sf-text-primary);
  letter-spacing: 0.04em;
}

.adv-wizard__subtitle {
  font-family: var(--sf-font-headline);
  color: var(--sf-text-secondary);
  font-style: italic;
}

.adv-wizard__name-input {
  background: var(--sf-bg-panel);
  border: 2px solid var(--sf-border-medium);
  color: var(--sf-text-primary);
  font-family: var(--sf-font-body);
}

.adv-wizard__name-input:focus {
  border-color: var(--sf-accent);
  outline: none;
}

/* Wizard step 1 (Genre) — keep on dark page; restyle the genre cards */
.adv-genre-card {
  background: var(--sf-bg-panel);
  border: 2px solid var(--sf-border-heavy);
  border-radius: 4px;
  overflow: hidden;
  transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}

.adv-genre-card:hover,
.adv-genre-card--selected {
  transform: translateY(-3px);
  border-color: var(--sf-accent);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.5);
}

.adv-genre-card__img {
  aspect-ratio: 3 / 4;
  object-fit: cover;
  width: 100%;
  display: block;
}

.adv-genre-card__name {
  font-family: var(--sf-font-display);
  font-size: 17px;
  letter-spacing: 0.06em;
  color: var(--sf-accent);
  background: var(--sf-bg-page);
  text-align: center;
  padding: 0.6rem 0.5rem 0.2rem;
  border-top: 2px solid var(--sf-border-heavy);
  margin: 0;
}

.adv-genre-card__desc {
  font-family: var(--sf-font-ui);
  font-size: 11px;
  color: var(--sf-text-secondary);
  background: var(--sf-bg-page);
  text-align: center;
  padding: 0 0.5rem 0.6rem;
  margin: 0;
  letter-spacing: 0.02em;
}

/* ── Steps 2 + 3 — CREAM PAPER MODE (all viewports) ── */
.adv-wizard__panel[data-panel="2"],
.adv-wizard__panel[data-panel="3"] {
  background-color: var(--sf-bg-caption);
  background-image: url("/storyforge/images/assets/paper-tile.png");
  background-size: 256px;
  background-blend-mode: multiply;
  border: 3px solid var(--sf-border-heavy);
  border-radius: 4px;
  padding: 2rem;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.45);
}

  .adv-wizard__panel[data-panel="2"] .adv-wizard__title,
  .adv-wizard__panel[data-panel="3"] .adv-wizard__title {
    color: var(--sf-ink-primary);
    border-bottom: 2px solid var(--sf-border-medium);
    padding-bottom: 0.6rem;
    margin-bottom: 1.5rem;
    text-align: center;
    letter-spacing: 0.08em;
  }

  .adv-wizard__panel[data-panel="2"] .adv-wizard__title i,
  .adv-wizard__panel[data-panel="3"] .adv-wizard__title i {
    color: var(--sf-accent);
  }

  /* Form fields on cream */
  .adv-wizard__panel[data-panel="2"] label,
  .adv-wizard__panel[data-panel="3"] label {
    color: var(--sf-ink-secondary);
    font-family: var(--sf-font-ui);
  }

  .adv-wizard__panel[data-panel="2"] select,
  .adv-wizard__panel[data-panel="2"] input[type="text"],
  .adv-wizard__panel[data-panel="2"] textarea,
  .adv-wizard__panel[data-panel="3"] select,
  .adv-wizard__panel[data-panel="3"] input[type="text"] {
    background: var(--sf-bg-caption-alt);
    border: 1px solid var(--sf-border-medium);
    color: var(--sf-ink-primary);
    border-radius: 2px;
    font-family: var(--sf-font-body);
  }

  .adv-wizard__panel[data-panel="2"] select:focus,
  .adv-wizard__panel[data-panel="2"] input:focus,
  .adv-wizard__panel[data-panel="2"] textarea:focus,
  .adv-wizard__panel[data-panel="3"] select:focus,
  .adv-wizard__panel[data-panel="3"] input:focus {
    border-color: var(--sf-accent);
    outline: none;
  }

  .adv-char-creator__preview,
  .adv-stat-allocator__preview {
    color: var(--sf-ink-secondary);
    font-family: var(--sf-font-headline);
    font-style: italic;
  }

  .adv-art-style__label,
  .adv-difficulty__label {
    color: var(--sf-ink-primary);
    font-family: var(--sf-font-display);
    letter-spacing: 0.06em;
  }

  /* Portrait frame on cream — heavy black border, no glow */
  .adv-wizard__panel[data-panel="2"] .adv-portrait__frame {
    border: 3px solid var(--sf-border-heavy);
    background: var(--sf-bg-page);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
  }

  .adv-wizard__panel[data-panel="2"] .adv-portrait__glow {
    display: none;
  }

  /* Stats radar — orange diamond accent */
  .adv-wizard__panel[data-panel="3"] .adv-stat-radar {
    border: 3px solid var(--sf-accent);
    background: var(--sf-bg-caption-alt);
    border-radius: 4px;
    padding: 1rem;
    box-shadow: inset 0 0 0 2px var(--sf-bg-caption);
  }

  /* Stat allocator on cream */
  .adv-wizard__panel[data-panel="3"] .adv-stat-allocator {
    background: var(--sf-bg-caption-alt);
    border: 2px solid var(--sf-border-medium);
    border-radius: 4px;
    color: var(--sf-ink-primary);
  }

  .adv-wizard__panel[data-panel="3"] .adv-stat-allocator__title,
  .adv-wizard__panel[data-panel="3"] .adv-stat-allocator__budget {
    color: var(--sf-ink-primary);
    font-family: var(--sf-font-display);
    letter-spacing: 0.06em;
  }

  .adv-wizard__panel[data-panel="3"] .adv-stat-allocator__budget {
    font-family: var(--sf-font-mono);
    color: var(--sf-accent-deep);
  }

  /* Difficulty pills on cream */
  .adv-wizard__panel[data-panel="3"] .adv-difficulty__btn {
    background: var(--sf-bg-caption-alt);
    border: 2px solid var(--sf-border-medium);
    color: var(--sf-ink-secondary);
    font-family: var(--sf-font-ui);
  }

  .adv-wizard__panel[data-panel="3"] .adv-difficulty__btn--active {
    background: var(--sf-accent);
    border-color: var(--sf-accent-deep);
    color: var(--sf-bg-page);
  }

  .adv-wizard__panel[data-panel="3"] .adv-difficulty__ironman,
  .adv-wizard__panel[data-panel="3"] .adv-narrator-option,
  .adv-wizard__panel[data-panel="3"] .adv-narrator-toggle,
  .adv-wizard__panel[data-panel="3"] .adv-narrator-hint,
  .adv-wizard__panel[data-panel="3"] .adv-difficulty__ironman-hint {
    color: var(--sf-ink-secondary);
    font-family: var(--sf-font-ui);
  }

/* ============================================================
   ACTIVE STORY — comic-panel scene + cream caption + speech-balloons
   ============================================================ */

/* Scene image — heavy comic-panel border */
.adv-scene__image-wrap {
  border: 3px solid var(--sf-border-heavy);
  border-radius: 4px;
  box-shadow:
    inset 0 0 0 1px var(--sf-bg-page),
    0 8px 24px rgba(0, 0, 0, 0.55);
  background: var(--sf-bg-panel);
}

/* Story title above narration */
.adv-story-title {
  font-family: var(--sf-font-display);
  font-size: clamp(28px, 3.4vw, 44px);
  letter-spacing: 0.06em;
  color: var(--sf-text-primary);
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.5);
  text-align: center;
  margin: 1.25rem 0 0.5rem;
}

.adv-location-badge {
  background: var(--sf-bg-panel);
  border: 1px solid var(--sf-border-medium);
  color: var(--sf-text-secondary);
  font-family: var(--sf-font-ui);
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* Caption box — cream paper surface for narration */
@media (min-width: 901px) {
  .adv-scene__text {
    background-color: var(--sf-bg-caption);
    background-image: url("/storyforge/images/assets/paper-tile.png");
    background-size: 256px;
    background-blend-mode: multiply;
    color: var(--sf-ink-primary);
    border: 2px solid var(--sf-border-heavy);
    border-radius: 4px;
    padding: 1.5rem 2rem;
    font-family: var(--sf-font-body);
    font-size: 18px;
    line-height: 1.7;
    max-width: 38rem;
    margin: 1rem auto 1.5rem;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);
  }

  .adv-scene__text p {
    color: var(--sf-ink-primary);
    margin: 0 0 1.2em;
  }

  .adv-scene__text p:last-child {
    margin-bottom: 0;
  }

  /* Drop cap on first paragraph */
  .adv-scene__text > p:first-child::first-letter {
    font-family: var(--sf-font-display);
    font-size: 4em;
    line-height: 0.85;
    float: left;
    padding: 0.05em 0.12em 0 0;
    color: var(--sf-accent);
  }
}

/* Speech-balloon choice cards */
.adv-choices {
  gap: 0.75rem;
  max-width: 56rem;
  margin: 0 auto;
}

.adv-choice {
  background: var(--sf-bg-caption);
  background-image: url("/storyforge/images/assets/paper-tile.png");
  background-size: 256px;
  background-blend-mode: multiply;
  color: var(--sf-ink-primary);
  border: 2px solid var(--sf-border-heavy);
  border-radius: 4px;
  padding: 0.9rem 1rem 0.9rem 3.4rem;
  position: relative;
  font-family: var(--sf-font-body);
  font-size: 17px;
  line-height: 1.4;
  text-align: left;
  cursor: pointer;
  transition: transform 0.1s ease, box-shadow 0.1s ease, border-color 0.1s ease;
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.35);
}

.adv-choice:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.45);
  border-color: var(--sf-accent-deep);
}

.adv-choice--selected {
  border-color: var(--sf-accent);
  box-shadow: 0 0 0 2px var(--sf-accent), 0 6px 16px rgba(0, 0, 0, 0.45);
}

/* Numeric tab top-left, in display font */
.adv-choice__key {
  position: absolute;
  top: -2px;
  left: -2px;
  width: 2.6rem;
  background: var(--sf-bg-page);
  color: var(--sf-accent);
  font-family: var(--sf-font-display);
  font-size: 24px;
  line-height: 1;
  padding: 0.55rem 0;
  text-align: center;
  border: 2px solid var(--sf-border-heavy);
  border-radius: 4px 0 4px 0;
  letter-spacing: 0;
}

.adv-choice__text {
  display: block;
  color: var(--sf-ink-primary);
  font-family: var(--sf-font-body);
}

/* Skill check tag — hazard pill */
.adv-choice__skill {
  display: inline-block;
  background: var(--sf-accent);
  color: var(--sf-bg-page);
  font-family: var(--sf-font-mono);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 3px 7px;
  border-radius: 2px;
  border: 1px solid var(--sf-accent-deep);
  margin-left: 0.5rem;
  vertical-align: middle;
}

.adv-choice__skill::before {
  content: '⚠ ';
}

/* Turn bar / audio controls — recessed UI chrome */
.adv-scene__turn-bar {
  background: var(--sf-bg-panel);
  border: 1px solid var(--sf-border-medium);
  border-radius: 4px;
  color: var(--sf-text-secondary);
  font-family: var(--sf-font-ui);
}

.adv-scene__progress-fill {
  background: var(--sf-accent);
}

.adv-narration-toggle {
  color: var(--sf-text-secondary);
}

.adv-narration-toggle:hover {
  color: var(--sf-accent);
}

/* Dice roll overlay */
.adv-dice {
  background: var(--sf-bg-panel);
  border: 3px solid var(--sf-accent);
  color: var(--sf-text-primary);
}

.adv-dice__label {
  font-family: var(--sf-font-display);
  letter-spacing: 0.08em;
  color: var(--sf-accent);
}

.adv-dice__value {
  font-family: var(--sf-font-mono);
  color: var(--sf-text-primary);
}

/* ============================================================
   DOSSIER (sidebar) — dark panel, mono stats, ember HP, display headers
   ============================================================ */

.adv-sidebar {
  background: var(--sf-bg-panel);
  border: 2px solid var(--sf-border-medium);
  border-radius: 4px;
  padding: 1rem;
}

@media (min-width: 901px) {
  .adv-sidebar {
    border: 3px solid var(--sf-border-heavy);
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.5);
  }
}

.adv-sidebar__portrait {
  border: 2px solid var(--sf-border-heavy);
  border-radius: 4px;
  background: var(--sf-bg-page);
}

/* Section headers inside dossier */
.adv-sidebar .adv-panel {
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border: none;
  border-top: 1px solid var(--sf-border-light);
  border-radius: 0;
  padding: 0.85rem 0;
}

.adv-sidebar .adv-panel:first-of-type {
  border-top: none;
}

.adv-sidebar .adv-panel__title {
  font-family: var(--sf-font-display);
  font-size: 13px;
  letter-spacing: 0.12em;
  color: var(--sf-accent);
  margin-bottom: 0.6rem;
}

/* Level badge + XP bar */
.adv-level-bar__badge {
  background: var(--sf-accent);
  color: var(--sf-bg-page);
  font-family: var(--sf-font-display);
  letter-spacing: 0.05em;
  border-radius: 2px;
}

.adv-level-bar__track {
  background: var(--sf-bg-page);
  border: 1px solid var(--sf-border-medium);
}

.adv-level-bar__fill {
  background: var(--sf-status-xp);
}

.adv-level-bar__xp {
  font-family: var(--sf-font-mono);
  color: var(--sf-text-secondary);
  font-size: 11px;
}

/* HP bar — warm ember red */
.adv-hp__bar {
  background: var(--sf-bg-page);
  border: 1px solid var(--sf-border-medium);
}

.adv-hp__fill {
  background: var(--sf-status-hp);
  box-shadow: inset 0 -2px 0 rgba(0, 0, 0, 0.25);
}

.adv-hp__text {
  font-family: var(--sf-font-mono);
  color: var(--sf-text-primary);
  font-size: 13px;
}

/* Stat readouts */
.adv-stat__label {
  font-family: var(--sf-font-ui);
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--sf-text-secondary);
  text-transform: uppercase;
}

.adv-stat__value {
  font-family: var(--sf-font-mono);
  font-size: 16px;
  font-weight: 700;
  color: var(--sf-text-primary);
}

.adv-stat__buff {
  font-family: var(--sf-font-mono);
  font-size: 10px;
  color: var(--sf-status-good);
}

/* Inventory + companions + journal — minimal restyle */
.adv-inventory__empty,
.adv-event {
  font-family: var(--sf-font-ui);
  font-size: 12px;
  color: var(--sf-text-muted);
  font-style: italic;
}

.adv-inventory__item,
.adv-companion {
  background: var(--sf-bg-page);
  border: 1px solid var(--sf-border-medium);
  border-radius: 2px;
  color: var(--sf-text-primary);
  font-family: var(--sf-font-ui);
  font-size: 13px;
}

.adv-inventory__item:hover,
.adv-companion:hover {
  border-color: var(--sf-accent);
}

/* ── Mobile dossier (≤900px) — clean utility surface ──
   Per plan Fix 6: no comic-panel border, no paper texture, no display divider.
   Drag handle + mini-stats stay simple. */
@media (max-width: 900px) {
  .adv-sidebar {
    border: none;
    box-shadow: none;
    background: var(--sf-bg-panel);
  }

  .adv-sidebar .adv-panel {
    border-top: 1px solid var(--sf-border-light);
  }

  .adv-sidebar .adv-panel__title {
    font-family: var(--sf-font-ui);
    color: var(--sf-text-secondary);
    letter-spacing: 0.08em;
    font-size: 11px;
  }

  /* Mobile choice cards: less heavy shadow, tighter spacing */
  .adv-choice {
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
    padding: 0.75rem 0.85rem 0.75rem 3rem;
    font-size: 16px;
  }

  .adv-choice__key {
    width: 2.2rem;
    font-size: 20px;
    padding: 0.45rem 0;
  }

  /* Mobile narration: no paper-texture caption (saves bandwidth, simpler chrome) */
  .adv-scene__text {
    background: var(--sf-bg-panel);
    background-image: none;
    color: var(--sf-text-primary);
    border: 1px solid var(--sf-border-medium);
    padding: 1rem 1.1rem;
    font-size: 16px;
    line-height: 1.6;
    box-shadow: none;
  }

  .adv-scene__text p {
    color: var(--sf-text-primary);
  }
}

/* ============================================================
   PR3 POLISH — particles retired, hero solid-color fallback
   ============================================================ */

/* Particle retirement.
   Per design principle "UI chrome recedes, scene art carries the weight."
   adventure-particles.css (1,616 lines) stays in the repo for one release
   cycle so rollback is a one-line revert: comment out this rule to restore. */
.adv-particles {
  display: none !important;
}

/* Hub hero solid-color fallback (Fix 3): if hub-hero.png ever 404s, the
   `<img>` carries onerror="this.style.display='none'" in index.html, which
   reveals the panel's --sf-bg-panel background. The display-font title
   overlay stays legible on that solid surface. Old neon "AI Choose-Your-
   Own-Adventure" banner must NOT be served as a fallback under any
   circumstances — the onerror is the only fallback path. */
.adv-hub__hero--graphic-novel {
  background:
    radial-gradient(ellipse at center, rgba(239, 138, 31, 0.04), transparent 60%),
    var(--sf-bg-panel);
}

/* ============================================================
   PR4 — mockup-faithful tweaks
   Halftone particle replacement, CHOICE tabs + horizontal choices,
   dossier header, hero CTA, genre card READ NOW link
   ============================================================ */

/* ── Halftone dot overlay (replaces retired particles) ──
   Comic-book screen pattern, accent-tinted, fades in from the corners
   so it reads as panel atmosphere rather than a flat texture over the art.
   Slow rotation gives it just enough life without distracting. */
.adv-scene__image-wrap {
  position: relative;
}

.adv-scene__image-wrap::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 2;
  background-image: radial-gradient(
    circle,
    rgba(var(--sf-accent-rgb), 0.55) 1px,
    transparent 1.5px
  );
  background-size: 8px 8px;
  -webkit-mask-image: radial-gradient(ellipse at center, transparent 45%, black 95%);
          mask-image: radial-gradient(ellipse at center, transparent 45%, black 95%);
  opacity: 0.18;
  mix-blend-mode: screen;
  animation: adv-halftone-drift 60s linear infinite;
}

@keyframes adv-halftone-drift {
  0%   { background-position: 0 0; }
  100% { background-position: 64px 64px; }
}

/* During skill check, briefly intensify the halftone — like comic action lines */
.adv-scene__image-wrap.adv-scene--checking::before,
.adv-dice + .adv-scene__image-wrap::before {
  opacity: 0.35;
  animation-duration: 8s;
}

/* ── CHOICE tabs: "CHOICE 1" / "CHOICE 2" / "CHOICE 3" ──
   The JS only renders the digit; CSS prepends "CHOICE " via ::before
   so we don't have to touch adventure-engine.js choice-render code. */
.adv-choice__key {
  /* Override the absolute-positioned compact tab from PR2 with a wider
     full-label tab that reads "CHOICE 1" in display font. */
  width: auto;
  min-width: 6.2rem;
  padding: 0.5rem 0.75rem;
  font-size: 16px;
  letter-spacing: 0.06em;
  text-align: center;
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 0.25rem;
}

.adv-choice__key::before {
  content: 'CHOICE';
  color: var(--sf-text-secondary);
  font-size: 11px;
  letter-spacing: 0.12em;
  font-family: var(--sf-font-ui);
  font-weight: 600;
}

/* Push body text down so the wider tab doesn't collide */
.adv-choice {
  padding: 2.6rem 1rem 1rem 1rem;
}

/* ── Horizontal 3-column choice layout on desktop (Mock 4) ── */
@media (min-width: 901px) {
  .adv-choices {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1rem;
    align-items: stretch;
    max-width: 64rem;
  }

  .adv-choice {
    /* Equal-height cards in the row */
    display: flex;
    flex-direction: column;
    justify-content: space-between;
  }

  .adv-choice__text {
    flex: 1;
    margin-bottom: 0.6rem;
  }

  .adv-choice__skill {
    align-self: flex-end;
    margin-left: 0;
  }
}

/* ── "THE DOSSIER" sidebar header ──
   CSS-only header label inserted at top of the dossier panel so we don't
   have to touch the play.html aside markup. Hidden on mobile (the bottom-
   sheet handle already serves as the section identifier). */
@media (min-width: 901px) {
  .adv-sidebar::before {
    content: 'The Dossier';
    display: block;
    font-family: var(--sf-font-display);
    font-size: 18px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--sf-accent);
    text-align: center;
    padding: 0.4rem 0 0.7rem;
    border-bottom: 2px solid var(--sf-border-heavy);
    margin: -0.3rem 0 0.85rem;
  }
}

/* ── Hub hero CTA button (Mock 1) ── */
.adv-hub__hero-cta {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 1.25rem;
  padding: 0.85rem 1.5rem;
  background: var(--sf-accent);
  color: var(--sf-bg-page);
  border: 2px solid var(--sf-border-heavy);
  border-radius: 4px;
  font-family: var(--sf-font-display);
  font-size: 18px;
  letter-spacing: 0.08em;
  text-decoration: none;
  text-transform: uppercase;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
  transition: transform 0.12s ease, box-shadow 0.12s ease, background 0.12s ease;
}

.adv-hub__hero-cta:hover {
  transform: translateY(-2px);
  background: var(--sf-accent-soft);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.6);
}

.adv-hub__hero-cta i {
  font-size: 14px;
}

/* ── Genre card "READ NOW →" link (Mock 1 footer of each card) ──
   CSS-only — appended via ::after so we don't touch the JS render. */
.adv-hub__genre {
  position: relative;
}

.adv-hub__genre:not(.adv-hub__genre--locked):not(.adv-hub__genre--coming-soon)::after {
  content: 'Read Now \2192';
  display: block;
  background: var(--sf-bg-page);
  color: var(--sf-text-secondary);
  font-family: var(--sf-font-ui);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-align: center;
  padding: 0.45rem 0;
  border-top: 1px solid var(--sf-border-medium);
  transition: color 0.2s ease, background 0.2s ease;
  /* Override the PR2 ::after that was set to display:none */
  position: static;
  inset: auto;
  border-radius: 0;
  background-image: none;
  opacity: 1;
  pointer-events: none;
}

.adv-hub__genre:hover:not(.adv-hub__genre--locked):not(.adv-hub__genre--coming-soon)::after {
  color: var(--sf-accent);
  background: var(--sf-bg-panel);
}

/* ── Wizard stepper as a horizontal orange-bar pill (Mock 3) ──
   Replaces the circle-and-line motif with a single segmented bar where
   the active/done steps are filled orange and the next step is outlined. */
.adv-wizard__steps {
  background: var(--sf-bg-panel);
  border: 2px solid var(--sf-border-heavy);
  border-radius: 4px;
  padding: 0;
  gap: 0;
  max-width: 720px;
  margin: 0 auto 2rem;
  overflow: hidden;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
}

.adv-wizard__step-line {
  display: none;
}

.adv-wizard__step {
  flex: 1;
  padding: 0.7rem 0.9rem;
  margin: 0;
  border-radius: 0;
  border: none;
  border-right: 2px solid var(--sf-border-heavy);
  background: var(--sf-bg-panel);
  color: var(--sf-text-secondary);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  font-family: var(--sf-font-ui);
  transition: background 0.18s ease, color 0.18s ease;
}

.adv-wizard__step:last-of-type {
  border-right: none;
}

.adv-wizard__step:hover {
  background: rgba(239, 138, 31, 0.08);
  color: var(--sf-text-primary);
}

.adv-wizard__step--active {
  background: var(--sf-accent);
  color: var(--sf-bg-page);
}

.adv-wizard__step--active:hover {
  background: var(--sf-accent);
  color: var(--sf-bg-page);
}

.adv-wizard__step--done {
  background: var(--sf-accent-deep);
  color: var(--sf-bg-page);
}

.adv-wizard__step-num {
  width: auto;
  height: auto;
  border-radius: 0;
  border: none;
  background: transparent;
  box-shadow: none;
  font-family: var(--sf-font-display);
  font-size: 16px;
  letter-spacing: 0;
  color: inherit;
}

.adv-wizard__step-num::after {
  content: '.';
}

.adv-wizard__step--done .adv-wizard__step-num,
.adv-wizard__step--active .adv-wizard__step-num {
  background: transparent;
  border: none;
  box-shadow: none;
  color: inherit;
}

.adv-wizard__step--done .adv-wizard__step-num::before {
  content: '\2713 \00a0';
}

.adv-wizard__step-label {
  font-family: var(--sf-font-ui);
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: inherit;
}

/* ============================================================
   PR7-FINAL — cascade overrides
   These rules MUST be last in the file. PR5/PR6/PR7 edits landed
   mid-file via Edit-tool anchoring; PR4 lives at line 1650 and was
   winning the cascade for hero h1, hero CTA, genre-name, genre-desc,
   and READ NOW pseudo. Re-asserting the intended PR6/PR7 values here.
   Do not insert rules below this block — append above it.
   ============================================================ */

.adv-hub__hero--graphic-novel {
  border: none;
  border-radius: 2px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.55);
  position: relative;
}

/* Hand-drawn comic border via SVG turbulence-displaced rect stroke.
   inset:0 = SVG canvas fills panel exactly. Stroke sits AT the panel edge
   so the slight wobble overlaps the panel content cleanly (no image-bleed
   gap between border and panel). */
.adv-hub__hero--graphic-novel::before {
  content: '';
  position: absolute;
  inset: -14px;
  pointer-events: none;
  z-index: 5;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 600 200' preserveAspectRatio='none' width='100%25' height='100%25'><defs><filter id='r' x='-2%25' y='-5%25' width='104%25' height='110%25'><feTurbulence type='fractalNoise' baseFrequency='0.012' numOctaves='1' seed='4'/><feDisplacementMap in='SourceGraphic' scale='0.8'/></filter></defs><rect x='5' y='5' width='590' height='190' fill='none' stroke='black' stroke-width='8' stroke-linejoin='round' filter='url(%23r)'/></svg>");
  background-size: 100% 100%;
  background-repeat: no-repeat;
}

/* Hero h1 — PR7 dramatic comic-banner treatment */
.adv-hub__hero--graphic-novel h1 {
  font-family: var(--sf-font-display);
  font-size: clamp(72px, 11vw, 168px);
  line-height: 0.88;
  letter-spacing: 0.015em;
  background: linear-gradient(
    180deg,
    #FFE9C9 0%,
    var(--sf-text-primary) 28%,
    var(--sf-accent-soft) 62%,
    var(--sf-accent) 82%,
    var(--sf-accent-deep) 100%
  );
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  filter:
    drop-shadow(2px 0 0 #1A1410)
    drop-shadow(-2px 0 0 #1A1410)
    drop-shadow(0 2px 0 #1A1410)
    drop-shadow(0 -2px 0 #1A1410)
    drop-shadow(4px 4px 0 rgba(0, 0, 0, 0.85))
    drop-shadow(8px 8px 0 rgba(0, 0, 0, 0.55))
    drop-shadow(12px 12px 24px rgba(0, 0, 0, 0.7));
  transform: skew(-3deg, -1deg);
  transform-origin: left center;
  margin: 0;
  max-width: 100%;
  text-shadow: none;
  -webkit-text-stroke: 0;
}

/* Hero caption box — mustard yellow, comic font, visibly hand-drawn border */
.adv-hub__hero--graphic-novel p {
  position: relative;
  display: inline-block;
  background: #F4D34F;
  background-image: none;
  color: #1A1410;
  border: none;
  border-radius: 4px;
  padding: 1rem 1.5rem;
  font-family: var(--sf-font-display);
  font-style: normal;
  font-weight: 400;
  font-size: 26px;
  line-height: 1.2;
  letter-spacing: 0;
  text-transform: none;
  max-width: 38ch;
  margin: 0;
  box-shadow: 0 8px 18px rgba(0, 0, 0, 0.5);
  text-shadow: none;
}

.adv-hub__hero--graphic-novel p::before {
  content: '';
  position: absolute;
  inset: -4px;
  pointer-events: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 600 200' preserveAspectRatio='none' width='100%25' height='100%25'><defs><filter id='r' x='-3%25' y='-8%25' width='106%25' height='116%25'><feTurbulence type='fractalNoise' baseFrequency='0.025' numOctaves='2' seed='6'/><feDisplacementMap in='SourceGraphic' scale='3'/></filter></defs><rect x='5' y='5' width='590' height='190' fill='none' stroke='black' stroke-width='5' stroke-linejoin='round' filter='url(%23r)'/></svg>");
  background-size: 100% 100%;
  background-repeat: no-repeat;
}

/* Hero CTA — cream paper (matches GALLERY/SIGN IN header pills), Bangers, hand-drawn border */
.adv-hub__hero-cta {
  position: relative;
  background-color: var(--sf-bg-caption);
  background-image: url("/storyforge/images/assets/paper-tile.png");
  background-size: 256px;
  background-blend-mode: multiply;
  color: #1A1410;
  border: none;
  padding: 1rem 1.75rem;
  box-shadow: 0 8px 18px rgba(0, 0, 0, 0.5);
}

.adv-hub__hero-cta::before {
  content: '';
  position: absolute;
  inset: -2px;
  pointer-events: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 600 200' preserveAspectRatio='none' width='100%25' height='100%25'><defs><filter id='r' x='-3%25' y='-8%25' width='106%25' height='116%25'><feTurbulence type='fractalNoise' baseFrequency='0.025' numOctaves='2' seed='9'/><feDisplacementMap in='SourceGraphic' scale='3'/></filter></defs><rect x='5' y='5' width='590' height='190' fill='none' stroke='black' stroke-width='5' stroke-linejoin='round' filter='url(%23r)'/></svg>");
  background-size: 100% 100%;
  background-repeat: no-repeat;
}

/* CTA arrow icon — hide it (comp has no arrow) */
.adv-hub__hero-cta i {
  display: none;
}

.adv-hub__hero-cta:hover {
  background: var(--sf-accent);
  background-image: none;
  color: var(--sf-bg-page);
}

/* === CARD REWORK to match comp ===
   Image fills the card. Title + desc + READ NOW float over the bottom of
   the image with a black gradient overlay (white text on dark). READ NOW
   becomes a small cream pill inside the dark area, not a full-width strip. */

.adv-hub__genre:not(.adv-hub__genre--coming-soon) {
  position: relative;
  display: block;
  overflow: visible;
  aspect-ratio: 3 / 4;
}

.adv-hub__genre:not(.adv-hub__genre--coming-soon) .adv-hub__genre-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  aspect-ratio: auto;
  object-fit: cover;
  z-index: 0;
}

/* Black gradient overlay sitting at the bottom of the image — the title +
   desc area sits on this, white text on dark. */
/* Black gradient overlay (separate pseudo so title/desc/pill stack cleanly above it) */
.adv-hub__genre:not(.adv-hub__genre--coming-soon) .adv-hub__genre-img {
  filter: none;
}

.adv-hub__genre:not(.adv-hub__genre--coming-soon)::after {
  /* The CSS for ::after below positions the READ NOW pill — defined further down */
}

.adv-hub__genre:not(.adv-hub__genre--coming-soon) .adv-hub__genre-name {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 4rem;
  padding: 0 1rem;
  font-family: var(--sf-font-display);
  font-size: 22px;
  letter-spacing: 0.06em;
  color: #FFF;
  background: transparent;
  background-image: none;
  border-top: none;
  text-shadow: 0 2px 6px rgba(0,0,0,0.85), 0 0 12px rgba(0,0,0,0.7);
  margin: 0;
  text-align: center;
  z-index: 3;
  text-transform: uppercase;
}

/* The dark gradient overlay (separate so it can extend up the card without
   being constrained to the title element's height) */
.adv-hub__genre:not(.adv-hub__genre--coming-soon) .adv-hub__genre-img + * {
  /* nothing — placeholder */
}

.adv-hub__genre:not(.adv-hub__genre--coming-soon)::before {
  /* keep the kicker tab — this is its existing rule */
}

/* Add a dedicated dark-gradient overlay via the parent's box-shadow trick won't work.
   Use the :not(coming-soon) wrapper directly with a pseudo if possible,
   but ::before is the kicker. Instead use the .adv-hub__genre-img with
   a sibling overlay via the description's bg gradient. */
.adv-hub__genre:not(.adv-hub__genre--coming-soon) .adv-hub__genre-desc {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 5.5rem 1rem 2.5rem;
  background: linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0.7) 35%, rgba(0,0,0,0.95) 100%);
  background-image: linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0.7) 35%, rgba(0,0,0,0.95) 100%);
  color: rgba(242, 232, 213, 0.9);
  font-family: var(--sf-font-body);
  font-style: italic;
  font-size: 12px;
  letter-spacing: 0.02em;
  margin: 0;
  text-align: center;
  z-index: 2;
  text-shadow: 0 2px 4px rgba(0,0,0,0.7);
  line-height: 1.3;
}

/* READ NOW — small cream pill at the very bottom-center, inside the dark area */
.adv-hub__genre:not(.adv-hub__genre--locked):not(.adv-hub__genre--coming-soon)::after {
  content: 'Read Now';
  position: absolute;
  left: 50%;
  bottom: -1rem;
  transform: translateX(-50%);
  background-color: var(--sf-bg-caption);
  background-image: url("/storyforge/images/assets/paper-tile.png");
  background-size: 256px;
  background-blend-mode: multiply;
  color: var(--sf-ink-primary);
  font-family: var(--sf-font-display);
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-align: center;
  padding: 0.45rem 1rem;
  border: 2px solid #000;
  border-radius: 3px;
  inset: auto auto -1rem 50%;
  margin-left: 0;
  opacity: 1;
  pointer-events: none;
  z-index: 4;
  display: inline-block;
  width: auto;
  white-space: nowrap;
}

.adv-hub__genre:hover:not(.adv-hub__genre--locked):not(.adv-hub__genre--coming-soon)::after {
  background: var(--sf-accent);
  background-image: none;
  color: var(--sf-bg-page);
}

/* Locked (PRO) cards — same pill positioning, but says "Unlock Pro" */
.adv-hub__genre--locked::after {
  content: 'Unlock Pro';
  position: absolute;
  left: 50%;
  bottom: -1rem;
  transform: translateX(-50%);
  background-color: var(--sf-bg-caption);
  background-image: url("/storyforge/images/assets/paper-tile.png");
  background-size: 256px;
  background-blend-mode: multiply;
  color: var(--sf-status-warn);
  font-family: var(--sf-font-display);
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-align: center;
  padding: 0.45rem 1rem;
  border: 2px solid #000;
  border-radius: 3px;
  inset: auto auto -1rem 50%;
  margin-left: 0;
  opacity: 1;
  pointer-events: none;
  z-index: 4;
  display: inline-block;
  width: auto;
  white-space: nowrap;
}

/* Visible comic-page frame around the genre rail (was 0.07 opacity = invisible).
   Wraps #genreGrid with a sketchy dashed cream border + corner action lines
   so the rail reads as a comic-page panel boundary. */
#genreGrid {
  position: relative;
  padding: 2.25rem 1.75rem 2rem;
  margin-top: 0.75rem;
}

/* Frame around #genreGrid retired — no decorative frame for now */
#genreGrid::before {
  content: none;
}

#genreGrid > .adv-hub__genre {
  position: relative;
  z-index: 1;
}


/* Section title pills — black text for CONTINUE ADVENTURE / NEW ADVENTURE */
.adv-hub__section-title,
.adv-hub__section-title i {
  color: #000;
}


/* ============================================================
   POLISH PASS — 7 fixes (single patch)
   Appended last so all rules win the cascade.
   ============================================================ */

/* FIX 2 — 24px between hero tagline (caption) and CTA button.
   Parent gap is 16px; +8px margin-top on CTA = 24px total. */
.adv-hub__hero-cta {
  margin-top: 0.5rem;
}

/* FIX 3 — Section title as plain header, not pill button.
   Removes cream paper bg / border / shadow / padding. */
.adv-hub__section-title {
  background: none;
  background-image: none;
  border: none;
  box-shadow: none;
  padding: 0;
  border-radius: 0;
  margin: 0 auto 1rem;
  color: var(--sf-text-secondary);
  font-family: var(--sf-font-display);
  font-size: 13px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

.adv-hub__section-title i {
  color: var(--sf-accent);
  font-size: 12px;
}

/* FIX 4 — Locked tile visual state.
   1. Kicker tab grey (not accent yellow) on locked
   2. Image art opacity 0.7 (label + button stay readable)
   3. PRO corner badge bigger (~14px font) */
.adv-hub__genre--locked::before {
  background: var(--sf-text-muted);
  color: var(--sf-bg-page);
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.4);
}

.adv-hub__genre--locked .adv-hub__genre-img {
  opacity: 0.7;
}

.adv-hub__genre-lock {
  font-size: 14px;
  padding: 0.4rem 0.75rem;
  letter-spacing: 0.08em;
  font-family: var(--sf-font-display);
  background: rgba(212, 164, 55, 0.95);
  color: #1A1410;
  border: 2px solid #1A1410;
  border-radius: 3px;
}

/* FIX 5 — Continue Adventure story title line-clamp 2.
   Allow two lines instead of single-line ellipsis truncation. */
.adv-hub__save-story-title {
  white-space: normal;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: clip;
  line-height: 1.2;
}

/* FIX 6 — Card hover lift faster (matches choice-button language from PR2).
   Card is already clickable (whole-card click handler in adventure-app.js L213). */
.adv-hub__save-card {
  cursor: pointer;
  transition: transform 80ms ease, box-shadow 80ms ease, border-color 80ms ease;
}

.adv-hub__save-card:hover {
  transform: translateY(-2px);
}

/* FIX 7 — Section spacing audit.
   Override the .adv-hub flex gap (currently 2.5rem) with explicit per-section
   spacing. Hero->Continue=48px, Continue->New=64px, badge->grid=32px. */
.adv-hub {
  gap: 48px;
}

.adv-hub > section + section {
  margin-top: 16px; /* +48px gap = 64px between Continue Adventure and New Adventure */
}

#dailyLimitBadge {
  margin: 0 auto 32px;
}

.adv-hub > section > .adv-hub__section-title {
  margin-bottom: 16px;
}

/* Genre grid — more vertical row gap so the READ NOW pill that hangs
   1rem below each card doesn't overlap the next row. */
#genreGrid {
  row-gap: 3rem;
}


/* ============================================================
   CHARACTER PAGE POLISH PASS — 11-fix patch
   FIX 1, 2, 3, 4, 5, 6, 7, 8 (FIX 9 in JS, FIX 10 confirmed multi-option,
   FIX 11 skipped per spec: optional)
   ============================================================ */

/* FIX 1 — Portrait frame: circle -> square with rounded corners.
   Matches Active Story Dossier portrait shape. */
.adv-portrait__frame {
  border-radius: 6px;
  border: 3px solid #000;
  background: var(--sf-bg-page);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.5);
}

.adv-portrait__glow {
  border-radius: 6px;
}

.adv-portrait__frame--has-portrait {
  border-color: #000;
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.6);
}

/* FIX 2 — Stepper states: clear visual hierarchy (done / current / upcoming) */
.adv-wizard__step {
  background: var(--sf-bg-panel);
  color: var(--sf-text-muted);
  opacity: 0.85;
}

.adv-wizard__step--done {
  background: var(--sf-bg-panel);
  color: var(--sf-text-secondary);
  opacity: 0.7;
}

.adv-wizard__step--done .adv-wizard__step-num,
.adv-wizard__step--done .adv-wizard__step-label {
  color: var(--sf-text-secondary);
}

.adv-wizard__step--active {
  background: var(--sf-accent);
  color: #1A1410;
  opacity: 1;
  box-shadow: inset 0 0 0 2px #000;
}

.adv-wizard__step--active .adv-wizard__step-num,
.adv-wizard__step--active .adv-wizard__step-label {
  color: #1A1410;
  font-weight: 700;
}

/* FIX 3 — Caption box max-width 800px (Option B per spec) so the form
   feels focused, not like a giant sheet of paper. */
@media (min-width: 901px) {
  .adv-wizard__panel[data-panel="2"] {
    max-width: 820px;
    margin-left: auto;
    margin-right: auto;
  }
  .adv-wizard__panel[data-panel="2"] .adv-wizard__panel-inner {
    max-width: none;
  }
}

/* FIX 4 — Preview text: distinct from form fields (clearly generated output) */
.adv-char-creator__preview {
  background: var(--sf-bg-page);
  border: 2px solid #000;
  border-radius: 4px;
  color: var(--sf-text-primary);
  font-style: italic;
  padding: 0.85rem 1rem 0.85rem 4.5rem;
  margin-top: 0.75rem;
  position: relative;
  font-family: var(--sf-font-body);
  line-height: 1.4;
}

.adv-char-creator__preview::before {
  content: 'PREVIEW';
  position: absolute;
  left: 0.75rem;
  top: 50%;
  transform: translateY(-50%);
  font-family: var(--sf-font-display);
  font-size: 11px;
  letter-spacing: 0.14em;
  color: var(--sf-accent);
  text-transform: uppercase;
}

/* Empty preview state — hide if JS has not populated yet */
.adv-char-creator__preview:empty {
  display: none;
}

/* FIX 5 — Art-style card labels: bump contrast on unselected cards */
.adv-art-style__name {
  color: var(--sf-text-primary);
  font-family: var(--sf-font-ui);
  font-weight: 600;
}

.adv-art-style__card {
  color: var(--sf-text-primary);
  border-radius: 2px;
  border-width: 2px;
}

.adv-art-style__card:not(.adv-art-style__card--active) .adv-art-style__name {
  color: var(--sf-text-primary);
  opacity: 0.95;
}

/* Hover: keep dark bg + pure cream text for max readability (was getting washed
   out from the faint accent tint in adventure-play.css). */
.adv-art-style__card:hover:not(.adv-art-style__card--active) {
  background: rgba(0, 0, 0, 0.5) !important;
  border-color: var(--sf-accent);
}

.adv-art-style__card:hover:not(.adv-art-style__card--active) .adv-art-style__name,
.adv-art-style__card:hover:not(.adv-art-style__card--active) .adv-art-style__icon {
  color: #FFF;
  opacity: 1;
}

/* Selected art-style card: solid accent bg, dark text + icon for high contrast */
.adv-art-style__card--active {
  background: var(--sf-accent) !important;
  border-color: #000;
}

.adv-art-style__card--active .adv-art-style__name {
  color: #1A1410;
  opacity: 1;
  font-weight: 700;
}

.adv-art-style__card--active .adv-art-style__icon,
.adv-art-style__card--active i {
  color: #1A1410;
}

/* FIX 6 — Generate Portrait: primary CTA treatment (matches START YOUR JOURNEY) */
.adv-portrait__btn {
  background-color: var(--sf-accent);
  background-image: none;
  color: #1A1410;
  border: 3px solid #000;
  border-radius: 4px;
  padding: 0.85rem 1.5rem;
  font-family: var(--sf-font-display);
  font-size: 16px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 400;
  margin-top: 1rem;
  box-shadow: 0 6px 14px rgba(0, 0, 0, 0.45);
  transition: transform 80ms ease, box-shadow 80ms ease, background-color 80ms ease;
  cursor: pointer;
}

.adv-portrait__btn:hover {
  transform: translateY(-2px);
  background-color: #FFB04A;
  box-shadow: 0 8px 18px rgba(0, 0, 0, 0.55);
}

.adv-portrait__btn:active {
  transform: translateY(0);
}

.adv-portrait__btn i {
  color: #1A1410;
}

/* FIX 7 — Disabled Next button: clearly disabled (was orange-ish, looked clickable) */
#wizardNextBtn:disabled,
#startAdventureBtn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  filter: grayscale(0.6);
  box-shadow: none;
}

#wizardNextBtn:disabled:hover,
#startAdventureBtn:disabled:hover {
  transform: none;
  box-shadow: none;
}

/* FIX 8 — Back button: ghost (transparent + outline) so it does not compete with Next */
#wizardPrevBtn {
  background: transparent;
  border: 2px solid var(--sf-text-muted);
  color: var(--sf-text-secondary);
  box-shadow: none;
  border-radius: 2px;
}

#wizardPrevBtn:hover {
  background: rgba(242, 232, 213, 0.06);
  border-color: var(--sf-text-secondary);
  color: var(--sf-text-primary);
}

/* Square off the wizard Next + Begin Adventure buttons too */
#wizardNextBtn,
#startAdventureBtn {
  border-radius: 2px;
}

/* REGENERATE button: ghost/outline once a portrait exists, so Next is the
   only solid-accent primary CTA. JS adds .adv-portrait__frame--has-portrait
   to the frame when a portrait is loaded; we use the sibling combinator to
   restyle the button without touching JS. */
.adv-portrait__frame--has-portrait ~ .adv-portrait__btn {
  background: transparent;
  background-image: none;
  color: var(--sf-accent);
  border: 2px solid var(--sf-accent);
  box-shadow: none;
}

.adv-portrait__frame--has-portrait ~ .adv-portrait__btn:hover {
  background: rgba(239, 138, 31, 0.1);
  background-image: none;
  color: var(--sf-accent-soft);
  border-color: var(--sf-accent-soft);
  transform: translateY(-1px);
  box-shadow: none;
}

.adv-portrait__frame--has-portrait ~ .adv-portrait__btn i {
  color: var(--sf-accent);
}

.adv-portrait__frame--has-portrait ~ .adv-portrait__btn:hover i {
  color: var(--sf-accent-soft);
}


/* ============================================================
   STATS PAGE POLISH PASS — 9-fix patch
   Root cause: cream/muted text on cream caption-box bg = invisible.
   Bumping all stat-page text to --sf-ink-primary contrast.
   ============================================================ */

/* FIX 1 — Slider labels (STR/DEX/INT/CHA) full ink contrast */
.adv-stat-row__label {
  color: var(--sf-ink-primary);
  font-family: var(--sf-font-display);
  font-weight: 400;
  letter-spacing: 0.06em;
  font-size: 14px;
}

.adv-stat-row__label i,
.adv-stat-row .fa-info-circle,
.adv-stat-row .fa-circle-info {
  color: var(--sf-ink-secondary);
}

.adv-stat-row__value {
  color: var(--sf-ink-primary);
  font-family: var(--sf-font-mono);
  font-weight: 700;
  font-size: 15px;
}

/* FIX 2 — Modifier always visible. +0 = warm grey, +N = good green, -N = ember red.
   Identical font size/weight; only color differs. */
.adv-stat-row__modifier {
  color: var(--sf-ink-muted);
  font-family: var(--sf-font-mono);
  font-weight: 700;
  font-size: 13px;
  opacity: 1;
}

.adv-stat-row__modifier--positive {
  color: var(--sf-status-good);
}

.adv-stat-row__modifier--negative {
  color: var(--sf-status-hp);
}

/* FIX 3 + FIX 9 — Class preset cards (Warrior/Rogue/Mage)
   Default: full opacity, clear borders, cursor pointer, subtle hover lift
   Selected: orange border + tint, matches art-style picker pattern
   Stat distribution: full ink contrast, larger text, breathing room */
.adv-archetype-card {
  background: var(--sf-bg-caption-alt);
  border: 2px solid var(--sf-border-medium);
  border-radius: 2px;
  cursor: pointer;
  opacity: 1;
  transition: transform 80ms ease, border-color 80ms ease, background 80ms ease;
  padding: 0.75rem 0.6rem;
}

.adv-archetype-card:hover {
  border-color: var(--sf-accent);
  transform: translateY(-2px);
  background: var(--sf-bg-caption-alt);
}

.adv-archetype-card--active {
  border-color: var(--sf-accent);
  background: rgba(239, 138, 31, 0.12);
}

.adv-archetype-card__icon {
  color: var(--sf-accent-deep);
  font-size: 1.3rem;
}

.adv-archetype-card--active .adv-archetype-card__icon {
  background: var(--sf-accent);
  color: #1A1410;
  box-shadow: 0 0 12px rgba(239, 138, 31, 0.4);
}

.adv-archetype-card__name {
  color: var(--sf-ink-primary);
  font-family: var(--sf-font-display);
  font-weight: 400;
  letter-spacing: 0.04em;
  font-size: 15px;
}

.adv-archetype-card--active .adv-archetype-card__name {
  color: var(--sf-ink-primary);
}

.adv-archetype-card__stats {
  color: var(--sf-ink-primary);
  font-family: var(--sf-font-mono);
  font-size: 11px;
  line-height: 1.5;
  font-weight: 600;
  margin-top: 0.4rem;
  opacity: 0.85;
}

/* FIX 4 — Reset button readable on cream */
.adv-stat-allocator__reset {
  color: var(--sf-ink-primary);
  font-family: var(--sf-font-ui);
  background: transparent;
  border: 1px solid var(--sf-border-medium);
  cursor: pointer;
  padding: 0.4rem 0.75rem;
  border-radius: 2px;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.adv-stat-allocator__reset:hover {
  background: rgba(0, 0, 0, 0.06);
  border-color: var(--sf-ink-secondary);
  color: var(--sf-ink-primary);
}

.adv-stat-allocator__reset i {
  color: var(--sf-ink-secondary);
}

/* FIX 6 — Allocation tracker pill ('0 / 40') more prominent + state via attribute */
.adv-stat-allocator__budget {
  font-family: var(--sf-font-mono);
  font-size: 16px;
  font-weight: 700;
  color: var(--sf-accent-deep);
  background: var(--sf-bg-caption-alt);
  border: 2px solid var(--sf-accent-deep);
  padding: 0.4rem 0.85rem;
  border-radius: 3px;
  letter-spacing: 0.04em;
}

/* State variation for budget pill — JS would need to add a class for the
   fully-allocated case. For now: when text is '0 / 40' (no remaining) the
   pill stays accent. Real state-class would require JS to toggle, e.g.
   .adv-stat-allocator__budget--done. Flagging as JS work. */

/* FIX 7 — Helper text 'Balanced across all stats' — frame as build description */
.adv-stat-allocator__preview {
  color: var(--sf-ink-secondary);
  font-style: italic;
  font-size: 13px;
  line-height: 1.4;
}

.adv-stat-allocator__preview::before {
  content: 'Build: ';
  color: var(--sf-ink-muted);
  font-style: normal;
  text-transform: uppercase;
  font-family: var(--sf-font-ui);
  font-size: 11px;
  letter-spacing: 0.12em;
  margin-right: 0.4rem;
  font-weight: 600;
}

.adv-stat-allocator__preview:empty {
  display: none;
}

/* FIX 8 — Slider track contrast on cream bg */
.adv-stat-row__slider {
  accent-color: var(--sf-accent);
}

.adv-stat-row__slider::-webkit-slider-runnable-track {
  background: var(--sf-ink-secondary);
  height: 5px;
  border-radius: 2px;
}

.adv-stat-row__slider::-moz-range-track {
  background: var(--sf-ink-secondary);
  height: 5px;
  border-radius: 2px;
}

.adv-stat-row__slider::-webkit-slider-thumb {
  background: var(--sf-accent);
  border: 2px solid var(--sf-border-heavy);
  width: 18px;
  height: 18px;
}

.adv-stat-row__slider::-moz-range-thumb {
  background: var(--sf-accent);
  border: 2px solid var(--sf-border-heavy);
  width: 18px;
  height: 18px;
}

/* Allocator title + header readable on cream too */
.adv-stat-allocator__title {
  color: var(--sf-ink-primary);
  font-family: var(--sf-font-display);
  letter-spacing: 0.06em;
}

.adv-stat-allocator__title i {
  color: var(--sf-ink-secondary);
}

/* Difficulty + Ironman + AI Narrator readable on cream */
.adv-difficulty__label,
.adv-difficulty__ironman,
.adv-difficulty__ironman-hint,
.adv-narrator-toggle,
.adv-narrator-hint {
  color: var(--sf-ink-primary);
}

.adv-difficulty__label i {
  color: var(--sf-ink-secondary);
}


/* Allocation tracker state variations (JS toggles these classes):
   default = points remaining (accent), --low = 1-4 left (warn), 
   --empty = exactly 0 (good/done), --over = negative (danger). */

.adv-stat-allocator__budget--low {
  color: var(--sf-status-warn);
  border-color: var(--sf-status-warn);
  background: rgba(212, 164, 55, 0.12);
}

.adv-stat-allocator__budget--empty {
  color: var(--sf-status-good);
  border-color: var(--sf-status-good);
  background: rgba(107, 142, 78, 0.15);
}

.adv-stat-allocator__budget--over {
  color: var(--sf-status-danger);
  border-color: var(--sf-status-danger);
  background: rgba(139, 46, 31, 0.15);
}


/* ============================================================
   STATS PAGE — Character portrait above radar (additive patch)
   Display-only mirror of the portrait generated in step 2.
   ============================================================ */

.adv-stat-left {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
}

.adv-stat-portrait {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
}

.adv-stat-portrait__frame {
  position: relative;
  width: 220px;
  height: 220px;
  background: var(--sf-bg-page);
  border: 3px solid #000;
  border-radius: 6px;
  overflow: hidden;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.5);
  flex-shrink: 0;
}

.adv-stat-portrait__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  position: relative;
  z-index: 1;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.adv-stat-portrait__img[src]:not([src=""]) {
  opacity: 1;
}

.adv-stat-portrait__placeholder {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--sf-text-muted);
  font-size: 4rem;
  z-index: 0;
}

/* Character name = comic title card. Bangers display, accent orange, all caps. */
.adv-stat-portrait__caption {
  font-family: var(--sf-font-display);
  font-size: 28px;
  letter-spacing: 0.06em;
  color: var(--sf-accent);
  text-align: center;
  text-transform: uppercase;
  min-height: 1em;
  max-width: 260px;
  line-height: 1.1;
  margin-top: 16px;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
}

/* Radar bottom padding so axis labels don't clip — bumped 8px → 20px */
.adv-stat-radar {
  padding-bottom: 20px;
}

/* Mobile: portrait shrinks gracefully */
@media (max-width: 768px) {
  .adv-stat-portrait__frame {
    width: 160px;
    height: 160px;
  }
}


/* Customize Character — Name field as one cell of a shared 2-col grid
   with the dropdown fields. Total = 6 fields (Name + Gender + Race + Build
   + Hair + Distinguishing Feature) → balanced 2x3 grid.
   .adv-char-creator__options uses display:contents so its children
   participate in the parent grid as siblings of the name field. */
.adv-char-creator__field-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
}

.adv-char-creator__field-grid .adv-char-creator__options {
  display: contents;
}

@media (max-width: 600px) {
  .adv-char-creator__field-grid {
    grid-template-columns: 1fr;
  }
}

/* Match the same label + input typography used by the dropdown fields below
   (.adv-char-creator__label = 0.75rem 500wt, .adv-char-creator__select = 0.85rem) */
.adv-char-creator__field--name .adv-char-creator__label {
  display: block;
  font-family: inherit;
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--sf-ink-secondary);
  margin: 0;
}

.adv-char-creator__input {
  width: 100%;
  background: var(--sf-bg-caption-alt);
  border: 1px solid var(--sf-border-medium);
  color: var(--sf-ink-primary);
  border-radius: 2px;
  padding: 0.5rem 0.75rem;
  font-family: inherit;
  font-size: 0.85rem;
  box-sizing: border-box;
  transition: border-color 0.15s ease;
}

.adv-char-creator__input::placeholder {
  color: var(--sf-ink-muted);
  font-style: italic;
}

.adv-char-creator__input:focus {
  outline: none;
  border-color: var(--sf-accent);
}

/* Override Chrome/Edge autofill which forces a white background once you type */
.adv-char-creator__input:-webkit-autofill,
.adv-char-creator__input:-webkit-autofill:hover,
.adv-char-creator__input:-webkit-autofill:focus,
.adv-char-creator__input:-webkit-autofill:active {
  -webkit-box-shadow: 0 0 0 1000px var(--sf-bg-caption-alt) inset !important;
  -webkit-text-fill-color: var(--sf-ink-primary) !important;
  caret-color: var(--sf-ink-primary);
  transition: background-color 999999s ease 0s;
}


/* Square off difficulty pills to match comic-panel button style */
.adv-difficulty__btn {
  border-radius: 2px;
}


/* ================================================================
   PR8 — play.html active-story polish pass (2026-04-25)
   Six fixes for the in-story state. All rules below the PR7-FINAL
   block win the cascade against earlier theme + play.css rules.
   ================================================================ */

/* Chrome accent — does NOT take genre tinting. Used for sidebar
   labels, level badge, and Pause pill so the warm orange identity
   stays constant across all genres. Genre tint still drives the
   scene image treatments and other diegetic chrome. */
:root {
  --sf-accent-chrome:     #EF8A1F;
  --sf-accent-chrome-rgb: 239, 138, 31;
}

/* ── FIX 1: Halftone-print spotlight loading state ────────────────
   Comic-book Lichtenstein-zoom panel: cream parchment surface
   covered in a dim halftone dot field. A spotlight follows the
   cursor (or auto-drifts when idle) revealing larger accent-colored
   dots in its radius — like shining an ink-light over the page or
   inspecting it with a loupe. JS in play.html updates two CSS
   custom properties (--cursor-x, --cursor-y) for the spot center;
   the spotlight radius and softness are tunable here. Spotlight
   color = var(--sf-accent), so each genre paints its own dots. */

.adv-scene__image-placeholder {
  background-color: var(--sf-bg-caption);
  background-image: url('/storyforge/images/assets/paper-tile.png');
  background-size: 256px;
  background-blend-mode: multiply;
  overflow: hidden;
  transition: opacity 0.4s ease;
  z-index: 4;
  /* Re-enable pointer events (adventure-play.css L86 disables them).
     Safe because the engine hides the placeholder via display:none
     once the scene image loads — no events leak to the underlying
     <img> during gameplay. */
  pointer-events: auto;
  cursor: crosshair;
  --cursor-x: 50%;
  --cursor-y: 50%;
  --spot-radius: 220px;
}

/* The scene <img> is z-5 above the placeholder (z-4) AND covers the
   whole wrap with opacity:0 until loaded. That makes it invisible
   but still capture every mousemove, blocking the spotlight handler.
   Disable pointer-events on the image — it's display-only. */
.adv-scene__image {
  pointer-events: none;
}

/* Hide the empty .adv-scene__text caption box while the engine is
   still generating the first scene. min-height:100px (play.css L289)
   + cream paper bg (theme L1273) was rendering as a leftover empty
   rectangle below the audio bar. */
.adv-scene__text:empty {
  display: none;
}

.adv-halftone-print {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 1;
}

/* Base layer — dim warm-grey halftone dot field covering the whole
   panel. Dots are intentionally small and low-contrast so they read
   as paper grain until the spotlight passes over them. */
.adv-halftone-print__field {
  position: absolute;
  inset: 0;
  background-image: radial-gradient(
    circle,
    rgba(122, 104, 80, 0.55) 1.4px,
    transparent 1.9px
  );
  background-size: 9px 9px;
}

/* Spotlight layer — same grid but slightly larger accent-colored
   dots, masked to a soft radial halo that follows the cursor.
   No opaque core: opacity falls off smoothly from the centre to the
   edge so the dots feather in/out instead of popping. Overall layer
   opacity is dialed back so the bloom reads as ambient halo, not
   flashlight. */
.adv-halftone-print__spotlight {
  position: absolute;
  inset: 0;
  background-image: radial-gradient(
    circle,
    var(--sf-accent) 2.6px,
    transparent 3.2px
  );
  background-size: 9px 9px;
  opacity: 0.75;
  -webkit-mask-image: radial-gradient(
    circle var(--spot-radius) at var(--cursor-x) var(--cursor-y),
    rgba(0, 0, 0, 0.85) 0%,
    rgba(0, 0, 0, 0.45) 50%,
    rgba(0, 0, 0, 0) 100%
  );
          mask-image: radial-gradient(
    circle var(--spot-radius) at var(--cursor-x) var(--cursor-y),
    rgba(0, 0, 0, 0.85) 0%,
    rgba(0, 0, 0, 0.45) 50%,
    rgba(0, 0, 0, 0) 100%
  );
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  transition:
    -webkit-mask-image 80ms linear,
            mask-image 80ms linear;
  will-change: mask-image;
}

/* Subtle pulsing on the spotlight radius for visual life */
.adv-halftone-print__spotlight::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(
    circle 80px at var(--cursor-x) var(--cursor-y),
    rgba(var(--sf-accent-rgb), 0.18) 0%,
    transparent 70%
  );
  animation: sf-halftone-pulse 2.4s ease-in-out infinite;
}

@keyframes sf-halftone-pulse {
  0%, 100% { opacity: 0.6; }
  50%      { opacity: 1; }
}

/* Cream caption box for the rotating loading message. Slightly
   darker cream (--sf-bg-caption-alt) than the parchment surface
   so it stamps onto the page instead of washing out. */
.adv-scene__image-placeholder .adv-loading-text {
  position: absolute;
  bottom: 1.25rem;
  left: 50%;
  right: auto;
  transform: translateX(-50%);
  max-width: min(80%, 28rem);
  text-align: center;
  background-color: var(--sf-bg-caption-alt);
  color: var(--sf-ink-primary);
  font-family: var(--sf-font-body);
  font-style: italic;
  font-weight: 500;
  font-size: 0.95rem;
  letter-spacing: normal;
  text-shadow: none;
  padding: 0.5rem 1rem;
  border: 1px solid #000;
  border-radius: 4px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.45);
  white-space: nowrap;
  z-index: 6;
  transition: opacity 0.35s ease;
}

.adv-scene__image-placeholder .adv-loading-text.adv-loading-text--fade {
  opacity: 0;
}

/* ── FIX 2: Dossier sidebar chrome — warm regardless of genre ──── */
.adv-sidebar .adv-panel__title {
  color: var(--sf-accent-chrome);
}

/* "THE DOSSIER" pseudo-header (defined at L1759) inherits genre-tinted
   --sf-accent. Re-route to chrome accent so it stays warm on sci-fi. */
@media (min-width: 901px) {
  .adv-sidebar::before {
    color: var(--sf-accent-chrome);
  }
}

.adv-level-bar__badge {
  background: var(--sf-accent-chrome);
  color: var(--sf-bg-page);
}

/* Inventory / Companion count spans inside the panel title read as
   secondary metadata — keep them muted cream so the count is quiet. */
.adv-sidebar .adv-panel__title #inventoryCount,
.adv-sidebar .adv-panel__title #companionCount {
  color: var(--sf-text-secondary);
  font-family: var(--sf-font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  font-weight: 400;
}

/* ── FIX 3: HP bar — color follows percentage ────────────────────
   Engine sets --warning at <=60%, --danger at <30%. Default state
   (no modifier) is full/healthy and reads green, NOT red. This
   beats theme.css L1508 which painted every HP state ember red. */
.adv-hp__fill {
  background: var(--sf-status-good);
  box-shadow: inset 0 -2px 0 rgba(0, 0, 0, 0.25);
  transition: width 0.5s ease, background 0.3s ease;
  animation: none;
}

.adv-hp__fill--warning {
  background: var(--sf-status-warn);
  box-shadow: inset 0 -2px 0 rgba(0, 0, 0, 0.25);
  animation: none;
}

.adv-hp__fill--danger {
  background: var(--sf-status-hp);
  box-shadow: inset 0 -2px 0 rgba(0, 0, 0, 0.25);
  animation: adv-hpPulse 1.5s ease-in-out infinite;
}

/* ── FIX 4: Dossier portrait — square rounded, larger ────────────
   Mirrors the Customize / Stats portrait shape (6px radius, black
   border). Source already wired via gameState.portraitImage in
   renderSidebarPortrait() — same image as Customize + Stats. */
.adv-sidebar__portrait {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding-bottom: 0.5rem;
}

.adv-sidebar__portrait-frame {
  width: 60px;
  height: 60px;
  border-radius: 6px;
  border: 2px solid #000;
  background: var(--sf-bg-page);
  overflow: hidden;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.5);
  flex-shrink: 0;
}

.adv-sidebar__portrait-frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.adv-sidebar__portrait-name {
  font-family: var(--sf-font-display);
  font-size: 1.1rem;
  letter-spacing: 0.04em;
  color: var(--sf-text-primary);
}

/* ── FIX 5: Pause button — accent-orange comic pill ──────────────
   Distinguishes Pause as a state action vs. nav. Uses --sf-accent-
   chrome so it reads warm orange even on cool-tinted genres (sci-fi). */
.adv-header__nav #pauseBtn {
  background: var(--sf-accent-chrome);
  background-image: none;
  color: var(--sf-bg-page);
  border: 1px solid var(--sf-border-heavy);
  border-radius: 2px;
  padding: 0.5rem 0.95rem;
  font-family: var(--sf-font-display);
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.2s ease, transform 0.15s ease;
}

.adv-header__nav #pauseBtn:hover {
  background: #FFB04A;
  transform: translateY(-1px);
}

.adv-header__nav #pauseBtn i {
  font-size: 12px;
}

/* ── FIX 6: Icon-only nav buttons (fullscreen, undo) — match nav pill ── */
.adv-header__nav .adv-btn--icon {
  background: var(--sf-bg-caption);
  color: var(--sf-ink-primary);
  border: 1px solid var(--sf-border-heavy);
  border-radius: 2px;
  padding: 0.5rem 0.65rem;
  font-size: 13px;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease, transform 0.15s ease;
}

.adv-header__nav .adv-btn--icon:hover {
  background: var(--sf-accent-chrome);
  color: var(--sf-bg-page);
  transform: translateY(-1px);
}

/* ── Inventory expanded detail — cream paper card ─────────────────
   Replaces the navy-dark `rgba(15, 15, 35, 0.6)` from
   adventure-play.css L670 (legacy SaaS palette). The detail panel
   reads as a paper note flipping out from the dark dossier item —
   matches caption-box treatment used for narration + loading text. */
.adv-inventory__detail {
  background-color: var(--sf-bg-caption);
  background-image: url('/storyforge/images/assets/paper-tile.png');
  background-size: 256px;
  background-blend-mode: multiply;
  border-radius: 0 0 6px 6px;
  border: 1px solid #000;
  border-top: none;
  margin-top: -1px;
  font-family: var(--sf-font-body);
}

.adv-inventory__desc {
  color: var(--sf-ink-secondary);
  font-style: italic;
  font-size: 0.78rem;
}

/* Action buttons re-tuned for cream surface — border + label colors
   stay diegetic (red drop, gold use, etc.) but get more saturation
   so they read against cream instead of being washed out. */
.adv-inventory__btn {
  font-family: var(--sf-font-ui);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 700;
}

.adv-inventory__btn--equip {
  background: rgba(var(--sf-accent-rgb), 0.12);
  border-color: rgba(var(--sf-accent-rgb), 0.55);
  color: var(--sf-accent-deep);
}
.adv-inventory__btn--equip:hover {
  background: rgba(var(--sf-accent-rgb), 0.22);
  border-color: var(--sf-accent);
}

.adv-inventory__btn--unequip {
  background: rgba(74, 61, 46, 0.08);
  border-color: rgba(74, 61, 46, 0.45);
  color: var(--sf-ink-secondary);
}
.adv-inventory__btn--unequip:hover {
  background: rgba(74, 61, 46, 0.18);
  border-color: var(--sf-ink-secondary);
}

.adv-inventory__btn--use {
  background: rgba(107, 142, 78, 0.12);
  border-color: rgba(107, 142, 78, 0.55);
  color: var(--sf-status-good);
}
.adv-inventory__btn--use:hover {
  background: rgba(107, 142, 78, 0.22);
  border-color: var(--sf-status-good);
}

.adv-inventory__btn--drop {
  background: rgba(196, 74, 46, 0.1);
  border-color: rgba(196, 74, 46, 0.55);
  color: var(--sf-status-hp);
}
.adv-inventory__btn--drop:hover {
  background: rgba(196, 74, 46, 0.2);
  border-color: var(--sf-status-hp);
}

/* ── Choice card hover — keep cream, don't go dark ────────────────
   adventure-play.css:324 sets `background: rgba(accent, 0.1)` on
   hover, which clobbers `--sf-bg-caption` while leaving the paper-
   tile + multiply blend in place — multiply over a faint accent
   tint reads as dark mush. Restore the cream surface and let the
   border + lift do the hover affordance. */
.adv-choice:hover {
  background-color: var(--sf-bg-caption-alt);
  background-image: url('/storyforge/images/assets/paper-tile.png');
  background-size: 256px;
  background-blend-mode: multiply;
  transform: translateY(-3px);
  border-color: var(--sf-accent);
  box-shadow:
    0 8px 18px rgba(0, 0, 0, 0.5),
    0 0 0 1px var(--sf-accent);
}

.adv-choice:active {
  transform: translateY(-1px);
  background-color: var(--sf-bg-caption);
}

/* ── Scene caption width — align closer to scene image ────────────
   theme.css:1285 set max-width: 38rem (~608px) which created a
   noticeable "wide image, narrow text" jump. Wider reading column
   feels more like a full graphic-novel page; still narrower than
   the image so the eye keeps a distinct text rhythm. */
@media (min-width: 901px) {
  .adv-scene__text {
    max-width: 45rem;
  }

  /* Choice card gap — 16px was reading as a cramped strip. 28px lets
     the three cards breathe and read as distinct decisions instead
     of a single segmented bar. Mobile (≤900px) keeps the 0.75rem
     vertical stack from the base rule. */
  .adv-choices {
    gap: 1.75rem;
  }
}

/* ── Turn counter — promote from chrome whisper to readable callout ─
   Was inheriting 12px muted-grey from the turn bar. Bumped to comic
   display font + brighter color so "Turn 1 / 25" reads as meaningful
   progress at a glance. Other turn-bar chrome (audio controls) stays
   subtle. */
#turnLabel,
#turnMax {
  font-family: var(--sf-font-display);
  font-size: 0.95rem;
  letter-spacing: 0.06em;
  color: var(--sf-text-primary);
}

/* Turn bar horizontal padding — adventure-play.css:109 sets `padding:
   0.4rem 0` (zero horizontal), so "Turn 1" was flush to the bar's
   left edge. Add breathing room on both sides; audio controls on the
   right get the same treatment. */
.adv-scene__turn-bar {
  padding-left: 0.85rem;
  padding-right: 0.85rem;
}

/* ── Continue Adventure cards: graceful 1/2/3 layout ──────────────
   adventure-hub.css:221 used `grid-template-columns: repeat(
   auto-fill, minmax(280px, 1fr))` which leaves empty grid cells when
   there are fewer cards than would fit (the "looks like a 3-slot
   grid where one failed to load" bug). Switch to flex with
   justify-content: center so 1/2/3 cards center cleanly with equal
   spacing, and 4+ wraps to the next row also centered. Keeps the
   existing gap (0.75rem), max-width (1024px), margin auto from the
   source rules. */
.adv-hub__saves {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

.adv-hub__save-card {
  flex: 0 1 320px;
}

/* ── Hub section headlines: 16px → 28px ───────────────────────────
   theme.css:844 set Bangers at 16px which wastes the display font's
   intent — Bangers is designed for headline sizes. Bump to 1.75rem
   so "CONTINUE ADVENTURE" / "NEW ADVENTURE" read as proper section
   headlines, not pill labels. Icon scales proportionally. */
.adv-hub__section-title {
  font-size: 1.75rem;
  letter-spacing: 0.08em;
}

.adv-hub__section-title i {
  font-size: 1.1rem;
}

/* ── Continue Adventure cards: hide redundant IN PROGRESS pill ────
   The Continue Adventure section is filtered at adventure-app.js:132
   to only render adventures where `status !== 'completed' &&
   status !== 'abandoned'` — i.e. every card here is in-progress by
   definition. The pill says nothing the section header doesn't
   already imply, AND on the new 320px-wide cards it was colliding
   with the HP bar in the meta row. Hide it. (If a future state
   ever mixes completed + in-progress here, bring it back.) */
.adv-hub__save-status--in_progress {
  display: none;
}

/* ── Continue Adventure cards: hide empty thumb on new adventures ─
   When a save has no scene image yet (brand-new adventure that
   hasn't generated turn 1), the thumb falls back to a small genre
   icon in a 64×48 bordered box. From the user's perspective it
   reads as a broken image placeholder, not a scene preview. Hide
   the thumb container when it has no <img> child — info column
   takes full width on those cards. */
.adv-hub__save-thumb:not(:has(img)) {
  display: none;
}

/* ── Hide Hub corner action-line bursts on mobile ─────────────────
   theme.css:696 + :727 stack two ::after decorations on .adv-hub:
   220x220 SVG action lines in opposite corners + a dashed border.
   Bleed outside the visible Hub area on narrow viewports — the
   bottom-right burst reads as a 3D perspective-grid artifact rather
   than comic-page flourish. Decoration not worth the cost on small
   screens; hide both at the genre-grid breakpoint. */
@media (max-width: 600px) {
  .adv-hub::after {
    display: none;
  }
}

/* ── Location badge — move to sit under the scene image ──────────
   Was rendering between the turn bar and story title (a confusing
   middle spot, attached to nothing). Now lives directly under the
   image so it reads as "where this scene takes place." Reset the
   negative bottom margin from adventure-play.css:847 (which was
   hugging the title in the old position) and align to the image's
   left edge so it acts like a Tintin-style panel caption pin. */
.adv-location-badge {
  margin: -0.25rem 0 0 0;
  align-self: flex-start;
}

/* ============================================================
   HUB HERO POLISH — Change 1: logo sizing + top-left anchor
   Appended last so all rules win the cascade. Structural note:
   .hero-content is expanded to fill the panel so h1, p, and
   .hero-cta can each be absolutely positioned against the panel
   edges. Change 1 = logo; Change 2 will fine-tune the tagline
   + CTA cluster currently scaffolded at bottom-left.
   ============================================================ */

.adv-hub__hero--graphic-novel .adv-hub__hero-content {
  position: absolute;
  inset: 0;
  padding: 0;
  text-align: left;
}

.adv-hub__hero--graphic-novel h1 {
  position: absolute;
  top: 24px;
  left: 32px;
  max-width: 400px;
  font-size: clamp(48px, 5.2vw, 88px);
  line-height: 0.88;
  margin: 0;
}

.adv-hub__hero--graphic-novel p {
  position: absolute;
  bottom: 32px;
  left: 32px;
  max-width: 380px;
  margin: 0;
}

/* CTA hidden — tagline directs the action, genre grid sits immediately
   below the hero, and a graphic-novel caption reads cleaner without a
   SaaS-style button. Markup kept intact for rollback + a11y. */
.adv-hub__hero--graphic-novel .adv-hub__hero-cta {
  display: none;
}

@media (max-width: 900px) {
  .adv-hub__hero--graphic-novel h1 {
    max-width: 320px;
    font-size: clamp(44px, 7vw, 72px);
  }
}

@media (max-width: 640px) {
  .adv-hub__hero--graphic-novel h1 {
    top: 16px;
    left: 16px;
    max-width: 220px;
    font-size: clamp(32px, 10vw, 48px);
  }
  .adv-hub__hero--graphic-novel p {
    left: 16px;
    right: 16px;
    max-width: none;
    bottom: 16px;
    text-align: center;
  }
}

/* ============================================================
   HUB MOBILE — fix horizontal overflow at narrow viewports.
   Grid items default to min-width: auto (= min-content), and
   the genre card images have natural widths of 848–1024px, so
   each grid track was growing to the image width and forcing
   main.adv-hub 3× wider than the viewport. Three fixes:
     1) min-width: 0 on the grid items to release the min-content
        sizing trap so minmax(…, 1fr) actually shrinks.
     2) Explicit 3-col at ≤900px and 2-col at ≤640px for the
        genre grid (auto-fill minmax(200px,…) was still demanding
        5+ tracks of min-content at tablet widths).
     3) Hide the .adv-hub::before/::after decorations on narrow
        screens — they use inset: -1rem to -2rem and push
        scrollWidth 32px past the viewport.
   ============================================================ */

.adv-hub__genres > .adv-hub__genre,
.adv-hub__saves > .adv-hub__save-card {
  min-width: 0;
}

@media (max-width: 900px) {
  .adv-hub__genres {
    grid-template-columns: repeat(3, 1fr);
  }
  .adv-hub::before,
  .adv-hub::after {
    display: none;
  }
}

@media (max-width: 640px) {
  .adv-hub__genres {
    grid-template-columns: repeat(2, 1fr);
    gap: 0.75rem;
  }
  .adv-hub__saves {
    grid-template-columns: 1fr;
  }
}

/* ============================================================
   GALLERY MOBILE — horizontal overflow fix.
   .adv-gallery__filters at ≤600px uses overflow-x: auto +
   flex-wrap: nowrap (intentional — 9 filter buttons are
   meant to scroll horizontally). Without min-width: 0 on
   the flex item, it took its intrinsic content width
   (~887px) and forced .adv-gallery__toolbar → main →
   document wider than viewport. One-line fix unblocks
   the scroll-inside-its-own-row behavior the author wanted.
   ============================================================ */
@media (max-width: 900px) {
  /* main.adv-gallery is a flex item of .adv-app (which is display:flex),
     and defaults to min-width: auto (= min-content). The filter row's
     9 buttons have a collective min-content of ~887px, so main was
     growing past viewport. Setting min-width: 0 at the flex-item level
     lets main honor the 375px parent, then the nested min-width: 0s
     let the filters' own overflow-x: auto scroll horizontally in place. */
  main.adv-gallery {
    min-width: 0;
    max-width: 100vw;
    overflow-x: hidden;
  }
  .adv-gallery > *,
  .adv-gallery__toolbar > *,
  .adv-gallery__filters {
    min-width: 0;
    max-width: 100%;
  }
  /* Wrap filter pills to multiple rows instead of scrolling horizontally
     (adventure-gallery.css:743 set overflow-x: auto + flex-wrap: nowrap). */
  .adv-gallery__filters {
    flex-wrap: wrap;
    overflow-x: visible;
    justify-content: center;
    padding-bottom: 0;
  }
}

/* Square up the gallery toolbar buttons to match the graphic-novel
   sharp-corner aesthetic (was border-radius: 20px pill at gallery
   .css:152/89/124). Applies on all viewports. */
.adv-gallery__filter,
.adv-gallery__search,
.adv-gallery__sort {
  border-radius: 3px;
}

/* Keep the orange active state visible even while the filter is hovered.
   adventure-gallery.css:164 sets .adv-gallery__filter:hover (specificity
   0,2,0) which was overriding .adv-gallery__filter--active (0,1,0) any
   time the cursor sat on the clicked button — so "All" read orange on
   load but the orange vanished as soon as you clicked another filter. */
.adv-gallery__filter--active,
.adv-gallery__filter--active:hover {
  background: rgba(var(--sf-accent-rgb), 0.15);
  border-color: var(--sf-accent);
  color: var(--sf-accent);
}

/* Sort dropdown — style the native <option> list.
   adventure-gallery.css:138 set the select to background: none + color:
   inherit, but <option> elements render with the OS default (white bg)
   unless explicitly styled, causing white-on-white unreadable options. */
.adv-gallery__sort select,
.adv-gallery__sort select option {
  background-color: var(--sf-bg-panel);
  color: var(--sf-text-primary);
}

/* More breathing room in the sort + search pills — gallery.css:90/125
   set 0.35rem 0.85rem which felt cramped against the squared corners. */
.adv-gallery__sort,
.adv-gallery__search {
  padding: 0.55rem 1.1rem;
}

.adv-gallery__sort select option {
  padding: 1rem 1.5rem;
  min-height: 3rem;
  line-height: 1.6;
  font-size: 0.9rem;
}

/* ============================================================
   CUSTOM DROPDOWN — replaces native <select> so we actually get
   CSS control over the popup (native selects are drawn by OS
   widget code which ignores padding/margin/etc).
   Usage: .adv-dropdown wrapper with a .adv-dropdown__trigger
   button + .adv-dropdown__menu <ul> of .adv-dropdown__option
   items. JS toggles .adv-dropdown--open on the wrapper.
   ============================================================ */

.adv-dropdown {
  position: relative;
}

.adv-dropdown__trigger {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0;
  background: none;
  border: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
  text-align: left;
}

.adv-dropdown__caret {
  margin-left: auto;
  font-size: 0.7rem;
  opacity: 0.7;
  transition: transform 0.15s ease;
}

.adv-dropdown--open .adv-dropdown__caret {
  transform: rotate(180deg);
}

.adv-dropdown__menu {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  min-width: 180px;
  margin: 0;
  padding: 0.35rem 0;
  list-style: none;
  background: var(--sf-bg-panel);
  border: 1px solid var(--sf-border-medium);
  border-radius: 3px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.55);
  z-index: 50;
  display: none;
}

.adv-dropdown--open .adv-dropdown__menu {
  display: block;
}

.adv-dropdown__option {
  padding: 0.75rem 1.25rem;
  font-size: 0.85rem;
  color: var(--sf-text-secondary);
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
  user-select: none;
}

.adv-dropdown__option:hover {
  background: var(--sf-bg-surface-hover);
  color: var(--sf-text-primary);
}

.adv-dropdown__option[aria-selected="true"] {
  background: rgba(var(--sf-accent-rgb), 0.12);
  color: var(--sf-accent);
}
