/* ==========================================================================
   UmaStudies -- Base Design System
   A dark, warm, immersive reading experience for long-form character studies.
   Character theming via CSS custom properties.
   ========================================================================== */

/* --- Fonts --- */
@import url('https://fonts.googleapis.com/css2?family=Source+Serif+4:ital,opsz,wght@0,8..60,300..900;1,8..60,300..900&family=Inter:wght@400;500;600;700&family=Noto+Serif+JP:wght@400;500;700&family=Cormorant+Garamond:ital,wght@0,500;0,600;1,500&family=Bodoni+Moda:ital,opsz,wght@0,6..96,500;0,6..96,600;0,6..96,700;1,6..96,500&family=Gilda+Display&family=Prata&display=swap');

/* --- Base Theme (Index / Default) --- */
:root {
  /* Turf green -- the shared thread across all pages */
  --accent-primary: #5B8C6A;
  --accent-secondary: #7FAF8D;
  --accent-glow: rgba(91, 140, 106, 0.15);

  /* Backgrounds */
  --bg-primary: #0C0C0E;
  --bg-secondary: #131316;
  --bg-tertiary: #1A1A1E;
  --bg-card: #16161A;
  --bg-card-hover: #1C1C21;

  /* Text */
  --text-primary: #E4E2DF;
  --text-secondary: #9E9E9E;
  --text-tertiary: #6B6B6B;
  --text-heading: #F0EEEB;

  /* Structural */
  --quote-border: var(--accent-primary);
  --quote-bg: rgba(91, 140, 106, 0.06);
  --link-color: var(--accent-secondary);
  --link-hover: var(--accent-primary);
  --divider: #2A2A2E;
  --code-bg: #1E1E22;

  /* Spacing scale */
  --space-xs: 0.25rem;
  --space-sm: 0.5rem;
  --space-md: 1rem;
  --space-lg: 1.5rem;
  --space-xl: 2rem;
  --space-2xl: 3rem;
  --space-3xl: 4.5rem;
  --space-4xl: 6rem;

  /* Typography scale */
  --font-serif: 'Source Serif 4', 'Noto Serif JP', Georgia, serif;
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-jp: 'Noto Serif JP', 'Yu Mincho', serif;

  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 1.0625rem;
  --text-lg: 1.1875rem;
  --text-xl: 1.375rem;
  --text-2xl: 1.75rem;
  --text-3xl: 2.25rem;
  --text-4xl: 3rem;
  --text-5xl: 3.75rem;

  --leading-tight: 1.3;
  --leading-body: 1.78;
  --leading-loose: 2.0;

  /* Layout */
  --content-width: 720px;
  --content-width-wide: 960px;
  --sidebar-width: 260px;

  /* Transitions */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --duration-fast: 150ms;
  --duration-base: 250ms;
  --duration-slow: 400ms;

  /* Borders */
  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 12px;
}


/* --- Mejiro Ramonu -- Tanzanite / Violet-Blue --- */
[data-character="mejiro-ramonu"] {
  --accent-primary: #7B6BA6;
  --accent-secondary: #9D8FC8;
  --accent-glow: rgba(123, 107, 166, 0.12);

  --bg-primary: #09080E;
  --bg-secondary: #0F0E16;
  --bg-tertiary: #16141F;
  --bg-card: #12101A;
  --bg-card-hover: #1A1722;

  --quote-border: #9B8EC4;
  --quote-bg: rgba(123, 107, 166, 0.07);
  --link-color: #A99BD4;
  --link-hover: #7B6BA6;
  --divider: #2A2735;
  --code-bg: #15131D;
}

/* Ramonu's header art is a banner, not a ghost. The sea-of-lavender scene (her
   leaping through the flower field) is the point, so show it crisp. Overlay
   darkens top and bottom so the hero text stays legible over the bright
   pastel art; the middle is left clearer. Mirrors Ardan's dark hero. */
[data-character="mejiro-ramonu"] .study-header .header-bg {
  opacity: 0.5;
  filter: saturate(1.02);
  background-position: center 28%;
}
[data-character="mejiro-ramonu"] .study-header .header-overlay {
  background: linear-gradient(
    to bottom,
    var(--bg-primary) 0%,
    rgba(9, 8, 14, 0.52) 34%,
    rgba(9, 8, 14, 0.52) 62%,
    var(--bg-primary) 100%
  );
}
[data-character="mejiro-ramonu"] .study-header .study-epithet,
[data-character="mejiro-ramonu"] .study-header h1,
[data-character="mejiro-ramonu"] .study-header .character-name-jp,
[data-character="mejiro-ramonu"] .study-header .study-meta,
[data-character="mejiro-ramonu"] .study-header .study-subtitle {
  text-shadow: 0 1px 12px var(--bg-primary), 0 0 5px var(--bg-primary);
}

/* Ramonu's display face. Bodoni Moda -- a severe Didone with razor thick/thin
   contrast, cold and gem-cut precise, matching her frightening perfectionism.
   Scoped to her headings so the shared body type system stays intact while her
   page reads as unmistakably hers. */
[data-character="mejiro-ramonu"] {
  --font-display: 'Bodoni Moda', 'Source Serif 4', Georgia, serif;
}
[data-character="mejiro-ramonu"] .study-header h1 {
  font-family: var(--font-display);
  font-weight: 700;
}
[data-character="mejiro-ramonu"] .study-subtitle {
  font-family: var(--font-display);
  font-weight: 500;
}
[data-character="mejiro-ramonu"] .study-content h2,
[data-character="mejiro-ramonu"] .study-content h2.part-heading .part-title,
[data-character="mejiro-ramonu"] .study-content h3 {
  font-family: var(--font-display);
  font-weight: 600;
}
[data-character="mejiro-ramonu"] .study-content h2.part-heading .part-num {
  font-family: var(--font-display);
}


/* --- Curren Bouquetd'or -- Cream / Brown / Gold (light) ---
   The only light study. Palette drawn from her racing dress: warm cream
   ground, deep brown ink (her hair), antique-gold accent (the "d'or").
   A light page needs the text variables overridden too, unlike the dark
   character themes which inherit the default light-on-dark text. */
[data-character="curren-bouquetdor"] {
  --accent-primary: #B0894E;
  --accent-secondary: #9C7438;
  --accent-glow: rgba(176, 137, 78, 0.18);

  --bg-primary: #F7F1E4;
  --bg-secondary: #F1E8D6;
  --bg-tertiary: #EADFC9;
  --bg-card: #FBF6EB;
  --bg-card-hover: #F3E9D5;

  --text-primary: #3D3027;
  --text-secondary: #6B5A49;
  --text-tertiary: #978470;
  --text-heading: #2C231C;

  --quote-border: #B0894E;
  --quote-bg: rgba(176, 137, 78, 0.09);
  --link-color: #8A6630;
  --link-hover: #6E4F22;
  --divider: #E0D4BC;
  --code-bg: #EFE5D0;

  /* Her own display face. Cormorant Garamond -- delicate, literary, high
     contrast. Scoped to her headings so the site keeps one body type system
     while her page still reads as unmistakably hers. */
  --font-display: 'Cormorant Garamond', 'Source Serif 4', Georgia, serif;
}

/* Curren headings in her display face. Cormorant has a small x-height, so it
   runs heavier in weight and a touch larger to hold presence at title size. */
[data-character="curren-bouquetdor"] .study-header h1 {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: 0.01em;
}
[data-character="curren-bouquetdor"] .study-subtitle {
  font-family: var(--font-display);
  font-style: italic;
}
[data-character="curren-bouquetdor"] .study-content h2,
[data-character="curren-bouquetdor"] .study-content h2.part-heading .part-title,
[data-character="curren-bouquetdor"] .study-content h3 {
  font-family: var(--font-display);
  font-weight: 600;
}
[data-character="curren-bouquetdor"] .study-content h2.part-heading .part-num {
  font-family: var(--font-display);
}

/* The shared fixed nav bar fades through a hardcoded near-black middle stop
   (rgba(12,12,14,.95)) that blends fine on the dark studies but renders as an
   odd dark blurry band across the top of her light page. Refade it to cream
   for her only; the dark studies keep the original. */
[data-character="curren-bouquetdor"] .site-header {
  background: linear-gradient(
    to bottom,
    var(--bg-primary) 0%,
    rgba(247, 241, 228, 0.92) 60%,
    transparent 100%
  );
}

/* Curren's header art is a banner, not a ghost. The dark studies render the
   header image at 8% opacity, blurred and desaturated; her MainSSR card is the
   point, so show it. The overlay keeps a cream wash over the middle and full
   cream at top/bottom so the dark hero text stays legible over the art. */
[data-character="curren-bouquetdor"] .study-header .header-bg {
  opacity: 0.72;
  filter: saturate(0.95);
  background-position: center 14%;
}
[data-character="curren-bouquetdor"] .study-header .header-overlay {
  background: linear-gradient(
    to bottom,
    var(--bg-primary) 0%,
    rgba(247, 241, 228, 0.26) 30%,
    rgba(247, 241, 228, 0.26) 64%,
    var(--bg-primary) 100%
  );
}
/* Cream halo so dark hero text reads cleanly over the bright card art. */
[data-character="curren-bouquetdor"] .study-header .study-epithet,
[data-character="curren-bouquetdor"] .study-header h1,
[data-character="curren-bouquetdor"] .study-header .character-name-jp,
[data-character="curren-bouquetdor"] .study-header .study-meta,
[data-character="curren-bouquetdor"] .study-header .study-subtitle {
  text-shadow: 0 1px 10px var(--bg-primary), 0 0 4px var(--bg-primary);
}

/* Curren only -- the red-rose / blue-rose pull-quote accents. She reads
   people as colored flowers (red rose = passion she cannot match; blue rose
   = the impossible made real). These tag a small number of quotes where the
   text itself invokes those colors. Each just re-points the quote-local
   variables, so the existing blockquote styles do the rest. */
[data-character="curren-bouquetdor"] blockquote.rose-red {
  --quote-border: #C05A63;
  --quote-bg: rgba(192, 90, 99, 0.08);
  --accent-glow: rgba(192, 90, 99, 0.14);
}
[data-character="curren-bouquetdor"] blockquote.rose-blue {
  --quote-border: #5E7FB0;
  --quote-bg: rgba(94, 127, 176, 0.08);
  --accent-glow: rgba(94, 127, 176, 0.14);
}
/* sweet-pea is her own flower, the white sweet pea, set in the sage of its
   stem so it shows on cream. It tags the few lines where she wants something
   for herself: to be in the bouquet, not to be left, a corner. */
[data-character="curren-bouquetdor"] blockquote.sweet-pea {
  --quote-border: #7F9672;
  --quote-bg: rgba(127, 150, 114, 0.10);
  --accent-glow: rgba(127, 150, 114, 0.14);
}



/* --- Mejiro Ardan -- Glass / Teal (dark) ---
   The sister study to Ramonu, and dark like her, but teal where Ramonu is
   violet. Ground is a cold blue-black; the accent is a luminous glass-teal
   drawn from her stage dress (teal panels, gold trim) and her ice-blue hair,
   pushed brighter and greener than a plain steel-blue so it reads as the
   "colorful glasswork radiance" the text keeps naming. The lavender (her eye
   color) is reserved for the two intimate trainer quotes via glass-violet. */
[data-character="mejiro-ardan"] {
  --accent-primary: #57A6B4;
  --accent-secondary: #8CCBD6;
  --accent-glow: rgba(120, 200, 214, 0.14);

  --bg-primary: #08090D;
  --bg-secondary: #0D0F15;
  --bg-tertiary: #13161E;
  --bg-card: #101219;
  --bg-card-hover: #171A23;

  --quote-border: #7FC0CC;
  --quote-bg: rgba(87, 166, 180, 0.07);
  --link-color: #8CCBD6;
  --link-hover: #57A6B4;
  --divider: #212a30;
  --code-bg: #12151C;
}

/* Ardan blockquote accents. glass-clear (clear cyan) tags the transcendence and
   glasswork-radiance lines; glass-violet (her eye color) tags the two most
   intimate lines with the trainer. Each just re-points the quote-local
   variables, so the existing blockquote styles do the rest. */
[data-character="mejiro-ardan"] blockquote.glass-clear {
  --quote-border: #8FD0DE;
  --quote-bg: rgba(143, 208, 222, 0.08);
  --accent-glow: rgba(143, 208, 222, 0.14);
}
[data-character="mejiro-ardan"] blockquote.glass-violet {
  --quote-border: #A99BD4;
  --quote-bg: rgba(169, 155, 212, 0.08);
  --accent-glow: rgba(169, 155, 212, 0.14);
}

/* Ardan's header art is a banner, not a ghost. Her main SSR scene (the
   hot-spring night with Ramonu behind her) is the point, so show it. The
   overlay keeps a dark wash top and bottom so the hero text stays legible,
   with the middle left clearer to let the art read. Mirrors Curren's hero
   treatment but tuned dark. */
[data-character="mejiro-ardan"] .study-header .header-bg {
  opacity: 0.5;
  filter: saturate(1.02);
  background-position: center 24%;
}
[data-character="mejiro-ardan"] .study-header .header-overlay {
  background: linear-gradient(
    to bottom,
    var(--bg-primary) 0%,
    rgba(8, 9, 13, 0.5) 34%,
    rgba(8, 9, 13, 0.5) 62%,
    var(--bg-primary) 100%
  );
}
/* Dark halo so the hero text reads cleanly over the lit scene. */
[data-character="mejiro-ardan"] .study-header .study-epithet,
[data-character="mejiro-ardan"] .study-header h1,
[data-character="mejiro-ardan"] .study-header .character-name-jp,
[data-character="mejiro-ardan"] .study-header .study-meta,
[data-character="mejiro-ardan"] .study-header .study-subtitle {
  text-shadow: 0 1px 12px var(--bg-primary), 0 0 5px var(--bg-primary);
}

/* Ardan's display face. Gilda Display -- a delicate high-contrast serif, airy
   and elegant, with the fine luminous strokes of her glass/ballet register.
   Single weight, so headings keep its natural weight with a little tracking for
   presence. Gilda has no italic, so her subtitle runs upright. */
[data-character="mejiro-ardan"] {
  --font-display: 'Gilda Display', 'Source Serif 4', Georgia, serif;
}
[data-character="mejiro-ardan"] .study-header h1 {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: 0.02em;
}
[data-character="mejiro-ardan"] .study-subtitle {
  font-family: var(--font-display);
  font-style: normal;
}
[data-character="mejiro-ardan"] .study-content h2,
[data-character="mejiro-ardan"] .study-content h2.part-heading .part-title,
[data-character="mejiro-ardan"] .study-content h3 {
  font-family: var(--font-display);
  font-weight: 400;
}
[data-character="mejiro-ardan"] .study-content h2.part-heading .part-num {
  font-family: var(--font-display);
}

/* King Halo -- racing green and gold. The ground is a green-black so the page
   reads as hers before a word is read; the accent is a deep racing green
   pushed past the site's turf green, with gold as the secondary for the
   epithet, eyebrows and links (the first-class trim on her dress). The blue
   of her ear covers is held back for one quote tint. */
[data-character="king-halo"] {
  --accent-primary: #2E9E62;
  --accent-secondary: #C9A54A;
  --accent-glow: rgba(46, 158, 98, 0.14);

  --bg-primary: #07110C;
  --bg-secondary: #0B1711;
  --bg-tertiary: #101E16;
  --bg-card: #0D1912;
  --bg-card-hover: #13231A;

  --quote-border: #2E9E62;
  --quote-bg: rgba(46, 158, 98, 0.07);
  --link-color: #C9A54A;
  --link-hover: #E0C277;
  --divider: #1A2A21;
  --code-bg: #0E1913;
}

/* King Halo blockquote accents. crown-gold tags the lines where she claims
   the crown out loud; halo-blue (her ear covers) tags what the crown is
   covering: the denial, the plea for a future tense, the witness, and the
   past-tense proof. */
[data-character="king-halo"] blockquote.crown-gold {
  --quote-border: #C9A54A;
  --quote-bg: rgba(201, 165, 74, 0.07);
  --accent-glow: rgba(201, 165, 74, 0.14);
}
[data-character="king-halo"] blockquote.halo-blue {
  --quote-border: #4A7FCF;
  --quote-bg: rgba(74, 127, 207, 0.08);
  --accent-glow: rgba(74, 127, 207, 0.14);
}
[data-character="king-halo"] blockquote.halo-blue em {
  color: #9DB8E6;
}

/* Her header is set like a fashion-magazine feature opener: Didone masthead
   ranged left and dropped to the foot of the image, not centered. She reads
   fashion magazines and her mother designs racing dresses. The left edge
   lines up with the reading column on wide screens. */
[data-character="king-halo"] .study-header {
  align-items: flex-start;
  justify-content: flex-end;
  text-align: left;
  padding-left: max(var(--space-xl), calc((100% - var(--content-width)) / 2));
  padding-right: var(--space-xl);
}
[data-character="king-halo"] .study-header .study-meta {
  justify-content: flex-start;
}
[data-character="king-halo"] .study-header .study-subtitle {
  margin-left: 0;
  margin-right: 0;
}
[data-character="king-halo"] .study-header .header-bg {
  opacity: 0.5;
  filter: saturate(1.02);
  background-position: center 30%;
}
[data-character="king-halo"] .study-header .header-overlay {
  background: linear-gradient(
    to bottom,
    rgba(7, 17, 12, 0.55) 0%,
    rgba(7, 17, 12, 0.15) 28%,
    rgba(7, 17, 12, 0.6) 62%,
    var(--bg-primary) 100%
  );
}
[data-character="king-halo"] .study-header .study-epithet,
[data-character="king-halo"] .study-header h1,
[data-character="king-halo"] .study-header .character-name-jp,
[data-character="king-halo"] .study-header .study-meta,
[data-character="king-halo"] .study-header .study-subtitle {
  text-shadow: 0 1px 14px var(--bg-primary), 0 0 5px var(--bg-primary);
}

/* King Halo's display face. Prata, a Didone with ball terminals and hard
   contrast: the fashion-plate register, distinct from Ramonu's Bodoni Moda.
   Single weight, no italic, so the subtitle runs upright in the accent green. */
[data-character="king-halo"] {
  --font-display: 'Prata', 'Source Serif 4', Georgia, serif;
}
[data-character="king-halo"] .study-header h1 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--text-5xl);
  line-height: 1.05;
}
[data-character="king-halo"] .study-subtitle {
  font-family: var(--font-display);
  font-style: normal;
  color: var(--accent-primary);
}
[data-character="king-halo"] .study-content h2,
[data-character="king-halo"] .study-content h2.part-heading .part-title,
[data-character="king-halo"] .study-content h3 {
  font-family: var(--font-display);
  font-weight: 400;
}
[data-character="king-halo"] .study-content h2.part-heading .part-num {
  font-family: var(--font-display);
}


/* ==========================================================================
   RESET & BASE
   ========================================================================== */

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

html {
  font-size: 16px;
  scroll-behavior: smooth;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  /* Stop mobile browsers from auto-inflating text after orientation change. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  font-family: var(--font-serif);
  font-size: var(--text-base);
  line-height: var(--leading-body);
  color: var(--text-primary);
  background-color: var(--bg-primary);
  min-height: 100vh;
  /* Guard against stray horizontal scroll on narrow screens. */
  overflow-x: hidden;
  transition: background-color var(--duration-slow) var(--ease-out);
}

::selection {
  background: var(--accent-primary);
  color: var(--bg-primary);
}


/* ==========================================================================
   TYPOGRAPHY
   ========================================================================== */

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-sans);
  font-weight: 600;
  color: var(--text-heading);
  letter-spacing: -0.01em;
  line-height: var(--leading-tight);
}

h1 {
  font-size: var(--text-4xl);
  font-weight: 700;
  letter-spacing: -0.025em;
  margin-bottom: var(--space-lg);
}

h2 {
  font-size: var(--text-2xl);
  margin-top: var(--space-3xl);
  margin-bottom: var(--space-lg);
  padding-bottom: var(--space-sm);
  border-bottom: 1px solid var(--divider);
}

h3 {
  font-size: var(--text-xl);
  margin-top: var(--space-2xl);
  margin-bottom: var(--space-md);
}

h4 {
  font-size: var(--text-lg);
  margin-top: var(--space-xl);
  margin-bottom: var(--space-md);
}

p {
  margin-bottom: var(--space-lg);
}

a {
  color: var(--link-color);
  text-decoration: none;
  transition: color var(--duration-fast) var(--ease-out);
}

a:hover {
  color: var(--link-hover);
  text-decoration: underline;
  text-underline-offset: 3px;
}

strong {
  font-weight: 700;
  color: var(--text-heading);
}

em {
  font-style: italic;
}

hr {
  border: none;
  height: 1px;
  background: var(--divider);
  margin: var(--space-3xl) 0;
}

/* Japanese text styling */
:lang(ja),
.jp-text {
  font-family: var(--font-jp);
  line-height: var(--leading-loose);
}


/* ==========================================================================
   BLOCKQUOTES -- Central to character studies
   ========================================================================== */

blockquote {
  border-left: 3px solid var(--quote-border);
  background: var(--quote-bg);
  padding: var(--space-lg) var(--space-xl);
  margin: var(--space-xl) 0;
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  /* Upright, not italic: the Japanese is the primary voice and CJK should
     never be slanted. Slightly larger to give the original real presence. */
  font-style: normal;
  font-size: var(--text-lg);
  line-height: var(--leading-loose);
  position: relative;
}

blockquote::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: linear-gradient(
    90deg,
    var(--accent-glow) 0%,
    transparent 60%
  );
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  pointer-events: none;
  opacity: 0.5;
}

blockquote p {
  margin-bottom: var(--space-sm);
  position: relative;
}

blockquote p:last-child {
  margin-bottom: 0;
}

/* Nested blockquotes (for thesis statements) */
blockquote blockquote {
  border-left-color: var(--accent-secondary);
  margin: var(--space-md) 0;
}


/* ==========================================================================
   QUIET REFINEMENTS (typography over motion)
   ========================================================================== */

/* Idea 1 -- the English translation is a quiet guide beneath the Japanese.
   It sits below the original, smaller and lighter, in the sans face so it
   reads as subordinate to the authority text rather than competing with it. */
blockquote em {
  display: block;
  margin-top: var(--space-md);
  font-style: normal;
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  line-height: var(--leading-body);
  letter-spacing: 0.01em;
  color: var(--text-secondary);
}

/* Idea 2 -- ceremonial Part openers. A faded numeral, an accent eyebrow
   label, then the title. Gives each Part the feel of turning a page. */
.study-content h2.part-heading {
  border-bottom: none;
  padding-bottom: 0;
  margin-top: var(--space-4xl);
  padding-top: var(--space-2xl);
  border-top: 1px solid var(--divider);
  position: relative;
}

.study-content h2.part-heading .part-eyebrow {
  display: block;
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--accent-secondary);
  margin-bottom: var(--space-xs);
}

.study-content h2.part-heading .part-title {
  display: block;
  font-size: var(--text-2xl);
  line-height: var(--leading-tight);
}

.study-content h2.part-heading .part-num {
  position: absolute;
  top: var(--space-md);
  right: 0;
  font-family: var(--font-serif);
  font-weight: 700;
  font-size: 4.5rem;
  line-height: 1;
  color: var(--accent-primary);
  opacity: 0.09;
  pointer-events: none;
  user-select: none;
}

/* Idea 3 (bespoke, Ramonu only) -- the wound passage given silence.
   The child's voice fragments; space does the work, no animation. */
blockquote.unraveling {
  border-left: none;
  background: none;
  text-align: center;
  margin: var(--space-3xl) auto;
  padding: var(--space-xl) var(--space-lg);
  animation: none;
}

blockquote.unraveling::before {
  display: none;
}

blockquote.unraveling .line {
  display: block;
  margin: var(--space-lg) auto;
}

blockquote.unraveling .line-break {
  letter-spacing: 0.3em;
  line-height: 2.4;
  font-size: var(--text-base);
  color: var(--text-secondary);
}

blockquote.unraveling .line-resolve {
  margin-top: var(--space-2xl);
  font-size: var(--text-xl);
  color: var(--text-heading);
}

blockquote.unraveling em {
  margin-top: var(--space-2xl);
  text-align: center;
}

/* Gem -- the tanzanite photo sits on pure black. Screen blending drops the
   black into the dark page so only the crystal shows, with no box or halo. */
.study-content figure.study-figure.pleochroic img {
  border: none;
  mix-blend-mode: screen;
}

/* Drop caps -- the opening paragraph of the Thesis and of each Part. */
.study-content #thesis + p::first-letter,
.study-content h2.part-heading + p::first-letter {
  float: left;
  font-family: var(--font-serif);
  font-weight: 700;
  font-size: 3.4em;
  line-height: 0.78;
  padding: 0.04em 0.14em 0 0;
  color: var(--accent-secondary);
}

/* Tanzanite text selection. */
::selection {
  background: var(--accent-primary);
  color: var(--bg-primary);
}
::-moz-selection {
  background: var(--accent-primary);
  color: var(--bg-primary);
}

@media (max-width: 768px) {
  .study-content h2.part-heading .part-num {
    display: none;
  }
}


/* ==========================================================================
   READER FEEDBACK FORM
   ========================================================================== */

.feedback {
  max-width: var(--content-width);
  margin: 0 auto var(--space-4xl);
  padding: var(--space-2xl) var(--space-xl) 0;
  border-top: 1px solid var(--divider);
}

.feedback h2 {
  font-size: var(--text-xl);
  border-bottom: none;
  margin-top: var(--space-xl);
  padding-bottom: 0;
}

.feedback p {
  color: var(--text-secondary);
  font-size: var(--text-base);
}

.feedback-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  margin-top: var(--space-lg);
}

.feedback-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--text-tertiary);
}

.feedback-form textarea,
.feedback-form input[type="email"] {
  font-family: var(--font-sans);
  font-size: var(--text-base);
  color: var(--text-primary);
  background: var(--bg-secondary);
  border: 1px solid var(--divider);
  border-radius: var(--radius-md);
  padding: var(--space-sm) var(--space-md);
  width: 100%;
  resize: vertical;
  transition: border-color var(--duration-fast) var(--ease-out);
}

.feedback-form textarea:focus,
.feedback-form input[type="email"]:focus {
  outline: none;
  border-color: var(--accent-primary);
}

.feedback-form button {
  align-self: flex-start;
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: var(--text-sm);
  color: var(--bg-primary);
  background: var(--accent-primary);
  border: none;
  border-radius: var(--radius-md);
  padding: var(--space-sm) var(--space-xl);
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-out);
}

.feedback-form button:hover {
  background: var(--accent-secondary);
}


/* ==========================================================================
   EPITHET, EPIGRAPH, ABOUT PAGE
   ========================================================================== */

/* In-game epithet shown above the character name (e.g. "Onyx Line"). */
.study-header .study-epithet {
  position: relative;
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--accent-secondary);
  margin-bottom: var(--space-md);
}

/* Opening epigraph -- the single heaviest quote, set before the body. */
.study-epigraph {
  max-width: 34ch;
  margin: var(--space-3xl) auto var(--space-2xl);
  padding: 0 var(--space-xl);
  border-left: none;
  background: none;
  text-align: center;
  font-size: var(--text-2xl);
  line-height: var(--leading-tight);
  animation: none;
}

.study-epigraph::before {
  display: none;
}

.study-epigraph .epigraph-jp {
  display: block;
  font-family: var(--font-jp);
  color: var(--text-heading);
}

.study-epigraph .epigraph-en {
  display: block;
  margin-top: var(--space-md);
  font-family: var(--font-sans);
  font-style: normal;
  font-size: var(--text-sm);
  letter-spacing: 0.02em;
  color: var(--text-secondary);
}

/* About page has no study header, so clear the fixed site header. */
/* Two-class selector so this beats the mobile `.study-content` padding
   shorthand (which resets padding-top to 0). Without the extra specificity
   the About title slides under the fixed, blurred site header on small
   screens. */
.study-content.about-content {
  padding-top: calc(80px + var(--space-2xl));
}


/* ==========================================================================
   COMING SOON (planned studies)
   ========================================================================== */

.planned {
  max-width: var(--content-width-wide);
  margin: var(--space-2xl) auto var(--space-4xl);
  padding: 0 var(--space-xl);
}

.planned h2 {
  font-size: var(--text-xl);
  border-bottom: none;
  text-align: center;
  color: var(--text-secondary);
  margin-bottom: var(--space-xl);
}

.planned-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--space-lg);
}

.planned-card {
  background: var(--bg-card);
  border: 1px dashed var(--divider);
  border-radius: var(--radius-lg);
  padding: var(--space-lg);
  text-align: center;
  opacity: 0.7;
}


/* ==========================================================================
   LISTS
   ========================================================================== */

ul, ol {
  margin-bottom: var(--space-lg);
  padding-left: var(--space-xl);
}

li {
  margin-bottom: var(--space-sm);
}

li::marker {
  color: var(--accent-primary);
}


/* ==========================================================================
   TABLES
   ========================================================================== */

table {
  width: 100%;
  border-collapse: collapse;
  margin: var(--space-xl) 0;
  font-size: var(--text-sm);
  font-family: var(--font-sans);
}

thead {
  border-bottom: 2px solid var(--accent-primary);
}

th {
  text-align: left;
  padding: var(--space-sm) var(--space-md);
  font-weight: 600;
  color: var(--text-heading);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

td {
  padding: var(--space-sm) var(--space-md);
  border-bottom: 1px solid var(--divider);
  vertical-align: top;
}

tr:hover td {
  background: var(--bg-tertiary);
}

/* Tables sit in a scroll container so the wide bilingual appendix can scroll
   horizontally on narrow screens rather than overflow or crush its columns. */
.table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  margin: var(--space-xl) 0;
}

.table-scroll table {
  margin: 0;
}


/* ==========================================================================
   CODE
   ========================================================================== */

code {
  font-family: 'JetBrains Mono', 'Fira Code', monospace;
  font-size: 0.9em;
  background: var(--code-bg);
  padding: 0.15em 0.4em;
  border-radius: var(--radius-sm);
  color: var(--accent-secondary);
}

pre {
  background: var(--code-bg);
  padding: var(--space-lg);
  border-radius: var(--radius-md);
  overflow-x: auto;
  margin: var(--space-xl) 0;
  border: 1px solid var(--divider);
}

pre code {
  background: none;
  padding: 0;
  font-size: var(--text-sm);
}


/* ==========================================================================
   SITE HEADER
   ========================================================================== */

.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  padding: var(--space-md) var(--space-xl);
  background: linear-gradient(
    to bottom,
    var(--bg-primary) 0%,
    rgba(12, 12, 14, 0.95) 60%,
    transparent 100%
  );
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  display: flex;
  align-items: center;
  justify-content: space-between;
  transition: background var(--duration-slow) var(--ease-out);
}

.site-logo {
  font-family: var(--font-sans);
  font-size: var(--text-lg);
  font-weight: 700;
  color: var(--text-heading);
  text-decoration: none;
  letter-spacing: -0.02em;
  display: flex;
  align-items: center;
}

.site-logo:hover {
  color: var(--accent-primary);
  text-decoration: none;
}

.site-logo .logo-accent {
  color: var(--accent-primary);
}

.site-logo .logo-mark {
  width: 1.5em;
  height: 1.5em;
  flex-shrink: 0;
  /* Spacing lives on the mark, not on the flex gap. A gap would also separate
     the "Uma" span from the bare "Studies" text node, splitting the wordmark. */
  margin-right: var(--space-sm);
  /* Tints the book+horseshoe mark to the page's accent, so it is green on the
     index and takes each character's color on their study page. */
  background-color: var(--accent-primary);
  -webkit-mask: url("../logo-mark.svg") center / contain no-repeat;
  mask: url("../logo-mark.svg") center / contain no-repeat;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: var(--space-xl);
}

.site-nav a {
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-secondary);
  text-decoration: none;
  transition: color var(--duration-fast) var(--ease-out);
  position: relative;
}

.site-nav a::after {
  content: '';
  position: absolute;
  bottom: -4px;
  left: 0;
  width: 0;
  height: 2px;
  background: var(--accent-primary);
  transition: width var(--duration-base) var(--ease-out);
}

.site-nav a:hover {
  color: var(--text-heading);
  text-decoration: none;
}

.site-nav a:hover::after {
  width: 100%;
}

/* Bilingual nav labels */
.nav-label-jp {
  font-family: var(--font-jp);
  font-size: var(--text-xs);
  color: var(--text-tertiary);
  display: block;
  margin-top: -2px;
}


/* ==========================================================================
   INDEX PAGE -- Study Cards
   ========================================================================== */

.index-hero {
  padding: calc(var(--space-4xl) + 60px) var(--space-xl) var(--space-3xl);
  text-align: center;
  max-width: var(--content-width-wide);
  margin: 0 auto;
}

.index-hero h1 {
  font-size: var(--text-5xl);
  margin-bottom: var(--space-md);
  background: linear-gradient(
    135deg,
    var(--text-heading) 0%,
    var(--accent-secondary) 100%
  );
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* Study page header must NOT inherit the gradient clip */
.study-header h1 {
  color: var(--text-heading);
  -webkit-text-fill-color: var(--text-heading);
}

.index-subtitle {
  font-family: var(--font-serif);
  font-size: var(--text-lg);
  color: var(--text-secondary);
  max-width: 600px;
  margin: 0 auto var(--space-sm);
  line-height: var(--leading-body);
}

.index-subtitle-jp {
  font-family: var(--font-jp);
  font-size: var(--text-base);
  color: var(--text-tertiary);
}

/* --------------------------------------------------------------------------
   HERO AMBIENCE
   Quiet atmosphere for the landing hero: a soft radial glow behind the title,
   a hairline horizon rule beneath it, and a staggered fade-rise on load. The
   drifting embers (.ember divs in the markup) reuse the study-page motif.
   All motion is neutralized under prefers-reduced-motion (see that block).
   -------------------------------------------------------------------------- */
.index-hero {
  position: relative;
}

/* 3D book mark above the title. Uses the depth favicon, with a soft drop
   shadow so it reads as floating. Leads the staggered entrance. */
.hero-logo {
  display: block;
  width: 76px;
  height: 76px;
  margin: 0 auto var(--space-lg);
  filter: drop-shadow(0 6px 18px rgba(0, 0, 0, 0.45));
  animation: fadeInUp var(--duration-slow) var(--ease-out) both;
}

/* Soft radial glow behind the title. Brand green at low alpha. */
.index-hero::before {
  content: "";
  position: absolute;
  top: 45%;
  left: 50%;
  width: min(680px, 92%);
  height: 380px;
  transform: translate(-50%, -50%);
  background: radial-gradient(
    ellipse at center,
    rgba(91, 140, 106, 0.12) 0%,
    transparent 70%
  );
  pointer-events: none;
  z-index: -1;
}

/* Hairline horizon rule beneath the hero text. */
.index-hero::after {
  content: "";
  display: block;
  width: 64px;
  height: 1px;
  margin: var(--space-xl) auto 0;
  background: linear-gradient(
    90deg,
    transparent,
    var(--accent-primary),
    transparent
  );
  opacity: 0.5;
}

/* Staggered fade-rise on load. `both` fill keeps the end state, so under
   reduced motion (animation-duration ~0) the text simply appears, fully
   visible. */
.index-hero h1,
.index-hero .index-subtitle,
.index-hero .index-subtitle-jp {
  animation: fadeInUp var(--duration-slow) var(--ease-out) both;
}

.index-hero h1 { animation-delay: 0.05s; }
.index-hero .index-subtitle { animation-delay: 0.15s; }
.index-hero .index-subtitle-jp { animation-delay: 0.25s; }

.studies-grid {
  max-width: var(--content-width-wide);
  margin: 0 auto;
  padding: 0 var(--space-xl) var(--space-4xl);
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: var(--space-xl);
}

.study-card {
  background: var(--bg-card);
  border: 1px solid var(--divider);
  border-radius: var(--radius-lg);
  padding: var(--space-xl);
  text-decoration: none;
  display: block;
  transition:
    transform var(--duration-base) var(--ease-out),
    border-color var(--duration-base) var(--ease-out),
    box-shadow var(--duration-base) var(--ease-out),
    background var(--duration-base) var(--ease-out);
  position: relative;
  overflow: hidden;
}

.study-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: linear-gradient(
    90deg,
    var(--card-accent, var(--accent-primary)),
    transparent
  );
  opacity: 0;
  transition: opacity var(--duration-base) var(--ease-out);
}

.study-card:hover {
  transform: translateY(-3px);
  border-color: var(--card-accent, var(--accent-primary));
  background: var(--bg-card-hover);
  text-decoration: none;
}

.study-card:hover::before {
  opacity: 1;
}

.study-card .card-character {
  font-family: var(--font-sans);
  font-size: var(--text-xl);
  font-weight: 700;
  color: var(--text-heading);
  margin-bottom: var(--space-xs);
  letter-spacing: -0.01em;
}

.study-card .card-character-jp {
  font-family: var(--font-jp);
  font-size: var(--text-sm);
  color: var(--text-tertiary);
  margin-bottom: var(--space-md);
}

.study-card .card-excerpt {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: 1.6;
  margin-bottom: var(--space-lg);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.study-card .card-meta {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  color: var(--text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.card-meta-divider {
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--text-tertiary);
}

/* Character art on cards. Auto-added by build.py when a card_art.webp exists.
   The bust is anchored bottom-right and bleeds off the card edges (clipped by
   the card's overflow:hidden) for a "half portrait" peek. Text sits in
   .card-body on the left, above the art and width-limited so it never runs
   under the face. */
.study-card.has-art {
  min-height: 210px;
}

.study-card .card-body {
  position: relative;
  z-index: 1;
}

.study-card.has-art .card-body {
  max-width: 62%;
}

.study-card .card-art {
  position: absolute;
  bottom: -10px;
  right: -8px;
  width: 56%;
  max-width: 250px;
  /* Square asset. Set aspect-ratio explicitly so iOS Safari sizes the height
     from the percentage width. WebKit computes height:auto as 0 here, which
     hid the art entirely on real devices. */
  aspect-ratio: 1 / 1;
  height: auto;
  object-fit: contain;
  pointer-events: none;
  /* No CSS mask. The art is already a transparent cutout so it needs no fade to
     avoid a rectangular edge, and iOS Safari blanks masked images. */
  opacity: 0.95;
  transition: transform var(--duration-base) var(--ease-out);
}

.study-card.has-art:hover .card-art {
  transform: translateY(-4px) scale(1.03);
}


/* ==========================================================================
   STUDY PAGE -- Long-form Reading Layout
   ========================================================================== */

.study-header {
  padding: calc(var(--space-4xl) + 80px) var(--space-xl) var(--space-3xl);
  text-align: center;
  position: relative;
  overflow: hidden;
  z-index: 60;
}

/* Subtle radial glow behind the header */
.study-header::before {
  content: '';
  position: absolute;
  top: -20%;
  left: 50%;
  transform: translateX(-50%);
  width: 800px;
  height: 600px;
  background: radial-gradient(
    ellipse at center,
    var(--accent-glow) 0%,
    transparent 70%
  );
  pointer-events: none;
  opacity: 0.6;
}

.study-header h1 {
  font-size: var(--text-4xl);
  position: relative;
  margin-bottom: var(--space-sm);
}

.study-header .character-name-jp {
  font-family: var(--font-jp);
  font-size: var(--text-xl);
  color: var(--text-tertiary);
  font-weight: 400;
  margin-bottom: var(--space-xl);
  position: relative;
}

.study-header .study-meta {
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-md);
  position: relative;
}

.study-subtitle {
  font-family: var(--font-serif);
  font-size: var(--text-lg);
  font-style: italic;
  color: var(--text-secondary);
  max-width: 600px;
  margin: var(--space-lg) auto 0;
  position: relative;
  line-height: var(--leading-body);
}

/* Main content area */
.study-content {
  max-width: var(--content-width);
  margin: 0 auto;
  padding: 0 var(--space-xl) var(--space-4xl);
}

/* Study figures -- character art placed inline with the prose.
   Generated by enhance_images() in build.py from standalone markdown images. */
.study-content figure.study-figure {
  margin: var(--space-3xl) auto;
  text-align: center;
}

.study-content figure.study-figure img {
  display: block;
  margin: 0 auto;
  max-width: 100%;
  max-height: 560px;
  width: auto;
  height: auto;
  border-radius: var(--radius-lg);
  border: 1px solid var(--divider);
  box-shadow:
    0 20px 45px -28px rgba(0, 0, 0, 0.85),
    0 0 0 1px var(--accent-glow);
}

/* Curren race-dress portrait and sweet-pea cutout -- transparent images meant
   to sit flush on the page. Drop the card border/shadow so they read as part
   of the background. */
.study-content figure.study-figure img[src$="race_dress.webp"],
.study-content figure.study-figure img[src$="sweet_pea.webp"] {
  border: none;
  border-radius: 0;
  box-shadow: none;
}

.study-content figure.study-figure figcaption {
  margin-top: var(--space-sm);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  letter-spacing: 0.03em;
  color: var(--text-tertiary);
}

/* Wide figures break past the reading column for atmosphere */
.study-content figure.study-figure.wide {
  width: var(--content-width-wide);
  max-width: 92vw;
  margin-left: 50%;
  transform: translateX(-50%);
}

@media (max-width: 768px) {
  .study-content figure.study-figure.wide {
    width: 100%;
    margin-left: auto;
    transform: none;
  }
}

/* Table of contents (floating sidebar on desktop) */
.study-toc-wrapper {
  position: fixed;
  top: 50%;
  transform: translateY(-50%);
  left: max(calc((100vw - var(--content-width)) / 2 - var(--sidebar-width) - 60px), 20px);
  width: var(--sidebar-width);
  z-index: 50;
  /* Hidden until the header is scrolled past (toggled by JS via .is-visible).
     Prevents the sidebar from overlapping the study header at the top. */
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--duration-base) var(--ease-out),
              transform var(--duration-base) var(--ease-out);
}

.study-toc-wrapper.is-visible {
  opacity: 1;
  pointer-events: auto;
}

/* Zen mode: slide TOC off-screen */
body.zen-mode .study-toc-wrapper {
  opacity: 0;
  transform: translateY(-50%) translateX(-30px);
  pointer-events: none;
}

.study-toc {
  max-height: 60vh;
  overflow-y: auto;
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  line-height: 1.5;
  padding-right: var(--space-sm);

  /* Custom scrollbar for dark theme */
  scrollbar-width: thin;
  scrollbar-color: var(--divider) transparent;
}

.study-toc::-webkit-scrollbar {
  width: 4px;
}

.study-toc::-webkit-scrollbar-track {
  background: transparent;
}

.study-toc::-webkit-scrollbar-thumb {
  background: var(--divider);
  border-radius: 4px;
}

.study-toc::-webkit-scrollbar-thumb:hover {
  background: var(--text-tertiary);
}

.study-toc a {
  display: block;
  padding: var(--space-xs) var(--space-sm);
  color: var(--text-tertiary);
  text-decoration: none;
  border-left: 2px solid transparent;
  transition:
    color var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out);
}

.study-toc a:hover,
.study-toc a.active {
  color: var(--text-primary);
  border-left-color: var(--accent-primary);
  text-decoration: none;
}

.study-toc .toc-h3 {
  padding-left: var(--space-lg);
}

/* TOC toggle button */
.toc-toggle {
  position: fixed;
  bottom: var(--space-xl);
  left: var(--space-xl);
  z-index: 80;
  width: 40px;
  height: 40px;
  border: 1px solid var(--divider);
  border-radius: 50%;
  background: var(--bg-secondary);
  color: var(--text-secondary);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-sm);
  transition:
    background var(--duration-fast) var(--ease-out),
    color var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.toc-toggle:hover {
  background: var(--bg-tertiary);
  color: var(--text-heading);
  border-color: var(--accent-primary);
}

/* Swap icon label when zen mode is active */
.toc-toggle .icon-toc { display: inline; }
.toc-toggle .icon-zen { display: none; }
body.zen-mode .toc-toggle .icon-toc { display: none; }
body.zen-mode .toc-toggle .icon-zen { display: inline; }


/* ==========================================================================
   DISCLAIMER BANNER
   ========================================================================== */

.disclaimer {
  max-width: var(--content-width);
  margin: 0 auto var(--space-2xl);
  padding: var(--space-md) var(--space-lg);
  background: var(--bg-tertiary);
  border: 1px solid var(--divider);
  border-radius: var(--radius-md);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: 1.6;
  font-style: normal;
}

.disclaimer strong {
  color: var(--text-primary);
  font-weight: 600;
}


/* ==========================================================================
   FOOTER
   ========================================================================== */

.site-footer {
  border-top: 1px solid var(--divider);
  padding: var(--space-2xl) var(--space-xl);
  text-align: center;
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  color: var(--text-tertiary);
}

.site-footer a {
  color: var(--text-secondary);
}


/* ==========================================================================
   ANIMATIONS
   ========================================================================== */

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.fade-in-up {
  animation: fadeInUp var(--duration-slow) var(--ease-out) forwards;
  opacity: 0;
}

/* Staggered entrance for study cards */
.study-card:nth-child(1) { animation-delay: 0.05s; }
.study-card:nth-child(2) { animation-delay: 0.1s; }
.study-card:nth-child(3) { animation-delay: 0.15s; }
.study-card:nth-child(4) { animation-delay: 0.2s; }
.study-card:nth-child(5) { animation-delay: 0.25s; }
.study-card:nth-child(6) { animation-delay: 0.3s; }


/* ==========================================================================
   RESPONSIVE
   ========================================================================== */

@media (max-width: 1200px) {
  .study-toc-wrapper {
    display: none;
  }

  .toc-toggle {
    display: none;
  }
}

@media (max-width: 768px) {
  :root {
    --text-4xl: 2.25rem;
    --text-5xl: 2.75rem;
    --text-base: 1rem;
  }

  .site-header {
    padding: var(--space-sm) var(--space-md);
  }

  .site-nav {
    gap: var(--space-md);
  }

  .nav-label-jp {
    display: none;
  }

  .index-hero {
    padding: calc(var(--space-3xl) + 50px) var(--space-md) var(--space-xl);
  }

  .studies-grid {
    grid-template-columns: 1fr;
    padding: 0 var(--space-md) var(--space-2xl);
  }

  .study-header {
    padding: calc(var(--space-3xl) + 60px) var(--space-md) var(--space-xl);
  }

  .study-content {
    padding: 0 var(--space-md) var(--space-2xl);
  }

  blockquote {
    padding: var(--space-md) var(--space-lg);
    margin: var(--space-lg) 0;
  }
}

@media (max-width: 480px) {
  :root {
    --text-4xl: 1.875rem;
    --text-5xl: 2.25rem;
  }

  .study-header .study-meta {
    flex-direction: column;
    gap: var(--space-xs);
  }

  .card-meta-divider {
    display: none;
  }
}


/* ==========================================================================
   LEVEL 3 -- ATMOSPHERIC HEADER (Character art background)
   ========================================================================== */

.study-header {
  min-height: 70vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

/* Character art background layer */
.study-header .header-bg {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-size: cover;
  background-position: center 20%;
  background-repeat: no-repeat;
  opacity: 0.08;
  filter: blur(2px) saturate(0.6);
  pointer-events: none;
  transition: opacity 1s var(--ease-out);
}

/* Gradient overlay to fade art into background */
.study-header .header-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(
    to bottom,
    var(--bg-primary) 0%,
    transparent 30%,
    transparent 60%,
    var(--bg-primary) 100%
  );
  pointer-events: none;
}

/* Animated accent glow that slowly shifts */
.study-header::after {
  content: '';
  position: absolute;
  top: 30%;
  left: 50%;
  transform: translateX(-50%);
  width: 600px;
  height: 400px;
  background: radial-gradient(
    ellipse at center,
    var(--accent-glow) 0%,
    transparent 70%
  );
  opacity: 0.4;
  animation: headerGlow 8s ease-in-out infinite alternate;
  pointer-events: none;
}

@keyframes headerGlow {
  0% { opacity: 0.3; transform: translateX(-50%) scale(1); }
  100% { opacity: 0.6; transform: translateX(-50%) scale(1.15); }
}


/* ==========================================================================
   LEVEL 3 -- FLAME-PULSE BLOCKQUOTES
   "Perfect love is like flame. Never the same shape for an instant."
   ========================================================================== */

/* Opt-in per character (Ramonu/flame). Other studies keep static quote borders. */
body[data-fx-flame] blockquote {
  animation: flamePulse 5s ease-in-out infinite;
}

@keyframes flamePulse {
  0%, 100% { border-left-color: var(--quote-border); }
  33% { border-left-color: color-mix(in srgb, var(--quote-border) 80%, white 20%); }
  66% { border-left-color: color-mix(in srgb, var(--quote-border) 90%, transparent 10%); }
}

/* Stagger the pulse so no two quotes breathe identically */
body[data-fx-flame] blockquote:nth-of-type(2n) { animation-duration: 6s; animation-delay: -1s; }
body[data-fx-flame] blockquote:nth-of-type(3n) { animation-duration: 4.5s; animation-delay: -2s; }
body[data-fx-flame] blockquote:nth-of-type(5n) { animation-duration: 5.5s; animation-delay: -0.5s; }
body[data-fx-flame] blockquote:nth-of-type(7n) { animation-duration: 7s; animation-delay: -3s; }


/* ==========================================================================
   LEVEL 3 -- PAINTERLY CANVAS TEXTURE
   She paints. The background should feel like something you could paint on.
   Opt-in via CHARACTER_FX "canvas".
   ========================================================================== */

body[data-fx-canvas]::after {
  content: '';
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 0;
  opacity: 0.025;
  background-image:
    repeating-linear-gradient(
      0deg,
      transparent,
      transparent 2px,
      rgba(255,255,255,0.03) 2px,
      rgba(255,255,255,0.03) 4px
    ),
    repeating-linear-gradient(
      90deg,
      transparent,
      transparent 3px,
      rgba(255,255,255,0.02) 3px,
      rgba(255,255,255,0.02) 6px
    );
}


/* ==========================================================================
   LEVEL 3 -- GEM-FACET SECTION DIVIDERS
   Angular, crystalline breaks between Parts. The hairline is shared; the
   diamond facet is opt-in via CHARACTER_FX "facets".
   ========================================================================== */

.study-content hr {
  height: auto;
  background: none;
  border: none;
  text-align: center;
  margin: var(--space-4xl) 0;
  position: relative;
  overflow: visible;
}

.study-content hr::before {
  content: '';
  display: block;
  width: 120px;
  height: 1px;
  margin: 0 auto;
  background: linear-gradient(
    90deg,
    transparent 0%,
    var(--accent-primary) 30%,
    var(--accent-secondary) 50%,
    var(--accent-primary) 70%,
    transparent 100%
  );
}

body[data-fx-facets] .study-content hr::after {
  content: '';
  display: block;
  width: 8px;
  height: 8px;
  margin: -4px auto 0;
  background: var(--accent-primary);
  transform: rotate(45deg);
  opacity: 0.7;
}


/* ==========================================================================
   LEVEL 3 -- PULL-QUOTE BREAKOUTS
   Key thesis statements break out of the content column.
   ========================================================================== */

.pull-quote {
  max-width: var(--content-width-wide);
  margin: var(--space-3xl) auto;
  padding: var(--space-2xl) var(--space-3xl);
  text-align: center;
  font-size: var(--text-xl);
  font-style: italic;
  color: var(--text-heading);
  line-height: 1.6;
  position: relative;
  border-left: none;
  background: none;
  animation: none;
}

.pull-quote::before {
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 60px;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--accent-primary), transparent);
}

.pull-quote::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 60px;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--accent-primary), transparent);
}

.pull-quote p {
  margin: 0;
}


/* ==========================================================================
   LEVEL 3 -- SCROLL-TRIGGERED SECTION ENTRANCES
   Each Part fades in as you scroll to it.
   ========================================================================== */

.section-reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.7s var(--ease-out), transform 0.7s var(--ease-out);
}

.section-reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}


/* ==========================================================================
   LEVEL 3 -- PARTICLE EMBERS
   "Better to keep being scorched."
   Sparse, slow-moving, barely visible.
   ========================================================================== */

.ember {
  position: fixed;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--accent-secondary);
  box-shadow: 0 0 6px 1px var(--accent-primary);
  opacity: 0;
  pointer-events: none;
  z-index: 1;
  animation: emberFloat linear infinite;
}

@keyframes emberFloat {
  0% {
    opacity: 0;
    transform: translateY(0) translateX(0);
  }
  15% {
    opacity: 0.7;
  }
  85% {
    opacity: 0.4;
  }
  100% {
    opacity: 0;
    transform: translateY(-100vh) translateX(40px);
  }
}

.ember:nth-child(1) { left: 10%; animation-duration: 18s; animation-delay: 0s; width: 3px; height: 3px; }
.ember:nth-child(2) { left: 25%; animation-duration: 22s; animation-delay: -4s; }
.ember:nth-child(3) { left: 50%; animation-duration: 20s; animation-delay: -8s; width: 3px; height: 3px; }
.ember:nth-child(4) { left: 70%; animation-duration: 25s; animation-delay: -2s; }
.ember:nth-child(5) { left: 85%; animation-duration: 19s; animation-delay: -10s; width: 2px; height: 2px; }
.ember:nth-child(6) { left: 40%; animation-duration: 23s; animation-delay: -6s; }


/* ==========================================================================
   LEVEL 3 -- PLEOCHROIC COLOR SHIFT (JS-driven)
   Colors set via inline style on :root by scroll handler.
   This section just smooths the transition.
   ========================================================================== */

body[data-character] {
  transition:
    --accent-primary 0.3s,
    --quote-border 0.3s,
    --link-color 0.3s;
}


/* ==========================================================================
   LEVEL 3 -- RESPONSIVE OVERRIDES
   ========================================================================== */

@media (max-width: 768px) {
  .study-header {
    min-height: 50vh;
  }

  .pull-quote {
    max-width: 100%;
    padding: var(--space-xl) var(--space-lg);
    font-size: var(--text-lg);
  }

  .ember {
    display: none;
  }
}


/* ==========================================================================
   LEVEL 4 -- LODGE WINDOW CONSTRICTION
   Part 2 narrows like looking through a window.
   The child watched through glass. Now you read through glass.
   ========================================================================== */

.lodge-window {
  max-width: 520px;
  margin-left: auto;
  margin-right: auto;
  position: relative;
  padding: var(--space-2xl) var(--space-xl);
  transition: max-width 0.8s var(--ease-out);
}

/* Frosted glass frame around the constricted section */
.lodge-window::before {
  content: '';
  position: absolute;
  top: 0;
  left: -20px;
  right: -20px;
  bottom: 0;
  border: 1px solid rgba(155, 142, 196, 0.1);
  border-radius: var(--radius-lg);
  background: linear-gradient(
    135deg,
    rgba(155, 142, 196, 0.03) 0%,
    transparent 50%,
    rgba(155, 142, 196, 0.02) 100%
  );
  pointer-events: none;
}

/* Frost corners (subtle window pane effect) */
.lodge-window::after {
  content: '';
  position: absolute;
  top: -1px;
  left: -21px;
  right: -21px;
  bottom: -1px;
  border-radius: var(--radius-lg);
  box-shadow:
    inset 8px 8px 20px rgba(155, 142, 196, 0.04),
    inset -8px -8px 20px rgba(155, 142, 196, 0.04);
  pointer-events: none;
}

/* Section headings inside the window keep their full presence */
.lodge-window h2,
.lodge-window h3 {
  max-width: 100%;
}

/* Caption label at the top of the constricted section */
.lodge-label {
  text-align: center;
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  color: var(--text-tertiary);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  margin-bottom: var(--space-lg);
  opacity: 0.5;
}


/* ==========================================================================
   LEVEL 4 -- READING PROGRESS GEM
   A tanzanite that rotates as you scroll, showing different facets.
   ========================================================================== */

.progress-gem {
  position: fixed;
  bottom: var(--space-xl);
  right: var(--space-xl);
  width: 14px;
  height: 14px;
  z-index: 80;
  pointer-events: none;
  /* Rotation and color set by JS */
  transform: rotate(45deg);
  transition: opacity var(--duration-base) var(--ease-out);
}

.progress-gem::before {
  content: '';
  display: block;
  width: 100%;
  height: 100%;
  background: var(--accent-primary);
  opacity: 0.6;
  clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
  transition: background 0.5s var(--ease-out);
}

/* Glow behind the gem */
.progress-gem::after {
  content: '';
  position: absolute;
  top: -4px;
  left: -4px;
  width: calc(100% + 8px);
  height: calc(100% + 8px);
  background: var(--accent-glow);
  clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
  filter: blur(6px);
  opacity: 0.4;
}


/* ==========================================================================
   LEVEL 4 -- INTERACTIVE APPENDIX
   Hoverable quote rows that pulse the matching text in the article.
   ========================================================================== */

/* Highlighted text in the body when an appendix row is hovered */
.quote-highlight {
  background: var(--accent-glow);
  outline: 2px solid var(--accent-primary);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
  transition: background 0.3s, outline-color 0.3s;
}

/* Appendix table rows become interactive */
.study-content table tr[data-quote-target] {
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-out);
}

.study-content table tr[data-quote-target]:hover td {
  background: rgba(255, 255, 255, 0.04);
  background: color-mix(in srgb, var(--accent-primary) 8%, transparent);
}

/* Tooltip hint */
.study-content table tr[data-quote-target] td:first-child::after {
  content: ' ';
  display: inline-block;
  width: 0;
  overflow: hidden;
  transition: width var(--duration-base) var(--ease-out);
}

.study-content table tr[data-quote-target]:hover td:first-child::after {
  content: ' [click to find]';
  width: auto;
  font-size: var(--text-xs);
  color: var(--accent-secondary);
  font-family: var(--font-sans);
  font-style: normal;
}


/* ==========================================================================
   LEVEL 4 -- RESPONSIVE OVERRIDES
   ========================================================================== */

@media (max-width: 768px) {
  .lodge-window {
    max-width: 100%;
    padding: var(--space-lg) var(--space-md);
  }

  .lodge-window::before,
  .lodge-window::after {
    display: none;
  }

  .progress-gem {
    display: none;
  }
}


/* ==========================================================================
   MOBILE CONTENTS (collapsed <details>, small screens only)
   The floating sidebar TOC is hidden below 1200px, so this gives phone
   readers a quiet, native jump-to-section control with no JavaScript.
   ========================================================================== */

.mobile-toc {
  display: none;
}

.mobile-toc summary {
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--text-secondary);
  cursor: pointer;
  list-style: none;
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--divider);
  border-radius: var(--radius-md);
  background: var(--bg-secondary);
  transition: color var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out);
}

/* Replace the default disclosure triangle with a quiet custom marker. */
.mobile-toc summary::-webkit-details-marker {
  display: none;
}

.mobile-toc summary::after {
  content: '+';
  float: right;
  color: var(--accent-secondary);
  font-weight: 400;
}

.mobile-toc[open] summary {
  color: var(--text-primary);
  border-color: var(--accent-primary);
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}

.mobile-toc[open] summary::after {
  content: '\2212'; /* minus sign */
}

.mobile-toc .mobile-toc-jp {
  font-family: var(--font-jp);
  color: var(--text-tertiary);
  margin-left: var(--space-xs);
}

/* Inside the details the contents expand fully (no fixed-height scroll box). */
.mobile-toc .study-toc {
  max-height: none;
  overflow: visible;
  border: 1px solid var(--divider);
  border-top: none;
  border-radius: 0 0 var(--radius-md) var(--radius-md);
  padding: var(--space-xs) var(--space-sm);
  font-size: var(--text-sm);
}

.mobile-toc .study-toc a {
  padding: var(--space-sm) var(--space-md);
}

@media (max-width: 1200px) {
  .mobile-toc {
    display: block;
    max-width: var(--content-width);
    margin: 0 auto var(--space-2xl);
    padding: 0 var(--space-md);
  }
}


/* ==========================================================================
   SMALL-SCREEN READING REFINEMENTS
   ========================================================================== */

@media (max-width: 768px) {
  /* Keep the appendix columns legible; the .table-scroll wrapper scrolls. */
  .table-scroll table {
    min-width: 34rem;
  }

  /* The epigraph and unraveling passage use wide tracking that overflows on
     narrow screens. Pull it in and let long Japanese lines wrap. */
  .study-epigraph {
    font-size: var(--text-xl);
    padding: 0 var(--space-md);
  }

  blockquote.unraveling .line-break {
    letter-spacing: 0.16em;
    overflow-wrap: anywhere;
  }

  blockquote.unraveling {
    padding: var(--space-lg) var(--space-sm);
  }

  /* A smaller drop cap so it does not crowd the first lines on a phone. */
  .study-content #thesis + p::first-letter,
  .study-content h2.part-heading + p::first-letter {
    font-size: 2.8em;
  }

  /* The ghosted Part numeral overlaps the title in tight widths. */
  .study-content h2.part-heading .part-num {
    display: none;
  }
}


/* ==========================================================================
   REDUCED MOTION
   Honor prefers-reduced-motion: cut transitions/animations and ensure all
   scroll-revealed content stays visible even if its reveal never fires.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }

  .ember {
    display: none;
  }

  .section-reveal {
    opacity: 1 !important;
    transform: none !important;
  }
}


/* ==========================================================================
   LANDING HERO BACKGROUND -- film strip / drift field
   Index page only. Optimized card art from static/images/hero-cards, darkened
   behind the hero text. The live mode is set by body[data-hero-mode]; the
   default comes from HERO_MODE in build.py. Motion is neutralized by the
   global prefers-reduced-motion block above (strip and field freeze to a
   static image). Degrades to a still field when JS is off.
   ========================================================================== */

/* The stage is bounded to the hero zone, so the strip fills the hero and stops
   there. The min-height (a tall enough canvas for the rows to clear the fixed
   header) applies only while a mode is live, so "Off" collapses to a plain hero. */
.hero-zone {
  position: relative;
}
body[data-hero-mode]:not([data-hero-mode="off"]) .hero-zone {
  min-height: min(720px, 92vh);
}

/* Top inset clears the fixed, blurred header: the strip and drift field start
   below it instead of sliding under it and getting clipped/blurred. */
.hero-stage {
  position: absolute;
  inset: 76px 0 0 0;
  overflow: hidden;
  z-index: 0;
  pointer-events: none;
}

/* Hero text sits above the stage. */
.index-hero {
  position: relative;
  z-index: 2;
}

/* Mode switching. Only the active layer is painted; the inactive one is pulled
   from the flow so its animations halt (no offscreen work, no drift swaps). */
body[data-hero-mode="filmstrip"] .drift-layer { display: none; }
body[data-hero-mode="drift"] .filmstrip-layer { display: none; }
body[data-hero-mode="off"] .hero-stage { display: none; }

/* Scrim: darken the art so the hero text stays legible, and fade the bottom
   edge into the page. The first radial darkens the CENTRE (behind the title
   and subtitle); the art breathes at the edges. Dark values match the index
   theme --bg-primary (#0C0C0E). */
.hero-scrim {
  position: absolute;
  inset: 0;
  z-index: 3;
  background:
    radial-gradient(ellipse 62% 46% at 50% 33%,
      rgba(12, 12, 14, 0.85) 0%,
      rgba(12, 12, 14, 0.45) 52%,
      transparent 78%),
    linear-gradient(to bottom,
      rgba(12, 12, 14, 0.5) 0%,
      rgba(12, 12, 14, 0.32) 30%,
      rgba(12, 12, 14, 0.72) 80%,
      var(--bg-primary) 100%);
}

/* Hero-text legibility over the moving art. Applied only when a background
   mode is live, so the plain "off" hero keeps its original styling. The h1 has
   gradient-clipped (transparent-fill) text, so text-shadow will not show on it;
   filter: drop-shadow renders on the clipped shape instead. */
body[data-hero-mode="filmstrip"] .index-subtitle,
body[data-hero-mode="drift"] .index-subtitle,
body[data-hero-mode="filmstrip"] .index-subtitle-jp,
body[data-hero-mode="drift"] .index-subtitle-jp {
  text-shadow: 0 1px 10px rgba(12, 12, 14, 0.92), 0 0 5px rgba(12, 12, 14, 0.8);
}
body[data-hero-mode="filmstrip"] .index-hero h1,
body[data-hero-mode="drift"] .index-hero h1 {
  filter: drop-shadow(0 2px 14px rgba(12, 12, 14, 0.8));
}

/* Film mode: a very slight extra touch of contrast on the hero copy. A tight,
   low-blur dark shadow hugs the glyphs to lift local contrast over the busy
   strip, without darkening the film itself. */
body[data-hero-mode="filmstrip"] .index-subtitle,
body[data-hero-mode="filmstrip"] .index-subtitle-jp {
  text-shadow:
    0 1px 10px rgba(12, 12, 14, 0.95),
    0 0 6px rgba(12, 12, 14, 0.9),
    0 0 2px rgba(12, 12, 14, 0.9);
}
body[data-hero-mode="filmstrip"] .index-hero h1 {
  filter:
    drop-shadow(0 2px 14px rgba(12, 12, 14, 0.82))
    drop-shadow(0 0 3px rgba(12, 12, 14, 0.7));
}

/* -------- Film strip -------- */
.filmstrip-layer,
.drift-layer {
  position: absolute;
  inset: 0;
}

.filmstrip-layer {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 20px;
  height: 100%;
  padding: 24px 0;
}

/* One strip of film: black base, perforated top and bottom edges. */
.filmstrip-row {
  position: relative;
  overflow: hidden;
  padding: 15px 0;
  background: #050505;
  border-top: 1px solid rgba(255, 255, 255, 0.05);
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}

/* The moving track: card set duplicated, translated -50% for a seamless loop. */
.filmstrip-track {
  display: flex;
  gap: 6px; /* black gutter between frames */
  width: max-content;
  height: 100%;
  align-items: center;
  will-change: transform;
  animation: filmScroll var(--film-dur, 60s) linear infinite;
  animation-direction: var(--film-dir, normal);
}

.film-frame {
  flex: 0 0 auto;
  height: 152px;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  background: #000;
  border-radius: 2px;
}

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

@keyframes filmScroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

/* -------- Drift field -------- */
.drift-layer {
  perspective: 1200px;
}

.drift-card {
  position: absolute;
  aspect-ratio: 3 / 4;
  opacity: var(--drift-op, 1); /* depth: some windows sit farther back */
  transform-style: preserve-3d;
  will-change: transform;
  pointer-events: auto; /* re-enable hover; the stage itself is pass-through */
  cursor: pointer;
  filter: drop-shadow(0 16px 38px rgba(0, 0, 0, 0.5));
  animation: driftFloat var(--drift-dur, 22s) ease-in-out infinite;
  animation-delay: var(--drift-delay, 0s);
}

/* Hovered card lifts above the scrim so it reads vivid, then spins. */
.drift-card:hover { z-index: 5; }

.drift-card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 6px;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  transition: opacity 0.6s ease; /* per-cycle face fade */
}

/* Hover spin: one full turn; JS swaps the face at the hidden mid-point. */
.drift-card.is-spinning img {
  animation: cardSpin 0.9s ease-in-out;
}

@keyframes cardSpin {
  from { transform: rotateY(0deg); }
  to { transform: rotateY(360deg); }
}

/* Cards float in place. One full cycle returns to the start; JS swaps the face
   on each cycle. The leading translate(-50%,-50%) makes left/top position the
   card CENTRE, so the jittered grid spreads them evenly across the stage. */
@keyframes driftFloat {
  0% { transform: translate(-50%, -50%) translateY(0) rotate(var(--tilt, 0deg)) rotateY(-15deg); }
  50% { transform: translate(-50%, -50%) translateY(-22px) rotate(calc(var(--tilt, 0deg) * -1)) rotateY(15deg); }
  100% { transform: translate(-50%, -50%) translateY(0) rotate(var(--tilt, 0deg)) rotateY(-15deg); }
}

/* -------- Compare toggle (prototype control; gated by HERO_SHOW_TOGGLE) -------- */
/* Hero mode control: a compact dropdown living in the top nav. */
.hero-menu {
  position: relative;
  display: inline-flex;
}

.hero-menu-trigger {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font: inherit;
  font-size: 0.82rem;
  line-height: 1;
  color: var(--text-secondary);
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--divider, rgba(255, 255, 255, 0.12));
  border-radius: 999px;
  padding: 6px 12px;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.hero-menu-trigger:hover {
  color: var(--text-heading);
  background: rgba(255, 255, 255, 0.09);
}

.hero-menu-eyebrow {
  font-size: 0.66em;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--text-tertiary);
}
.hero-menu-label {
  font-weight: 600;
  color: var(--text-heading);
}
.hero-menu-caret {
  font-size: 0.7em;
  opacity: 0.65;
  transition: transform 0.2s ease;
}
.hero-menu[data-open="true"] .hero-menu-caret { transform: rotate(180deg); }

.hero-menu-list {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 132px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 5px;
  border-radius: 12px;
  background: rgba(14, 14, 18, 0.96);
  border: 1px solid rgba(255, 255, 255, 0.12);
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  opacity: 0;
  transform: translateY(-6px);
  pointer-events: none;
  transition: opacity 0.16s ease, transform 0.16s ease;
  z-index: 200;
}
.hero-menu[data-open="true"] .hero-menu-list {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

.hero-menu-list button {
  font: inherit;
  font-size: 0.85rem;
  text-align: left;
  color: var(--text-secondary);
  background: transparent;
  border: 0;
  border-radius: 8px;
  padding: 7px 12px;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.hero-menu-list button:hover {
  background: rgba(255, 255, 255, 0.07);
  color: var(--text-heading);
}
.hero-menu-list button[aria-checked="true"] {
  color: #fff;
  background: var(--accent-primary, #5B8C6A);
}

/* Phones: film only (drift reads poorly narrow), shorter frames and canvas,
   smaller header inset. The Drift toggle button is hidden here; the script also
   forces filmstrip so a stored drift preference cannot show. */
@media (max-width: 640px) {
  body[data-hero-mode]:not([data-hero-mode="off"]) .hero-zone { min-height: min(560px, 80vh); }
  .hero-stage { inset: 62px 0 0 0; }
  .film-frame { height: 108px; }
  .filmstrip-layer { gap: 14px; }
  .hero-menu-list button[data-mode="drift"] { display: none; }
  .hero-menu-eyebrow { display: none; }
}
