/* ============================================================
   Ztor 2.0 — Design Tokens
   Source of truth: Figma file PjfXW29QsWoPUSaFvYC0Wb (Foundations)
   ============================================================ */

:root {
  /* ─────────────────────────────────────────
     COLOR — Primitives
     ───────────────────────────────────────── */

  /* Accent — Orange (brand). Anchored on #ffa33f at 500; tints/shades
     mirror the prior ramp's lightness curve. Var names kept (--yellow-*)
     so all 32 consumers resolve unchanged — only the values moved. */
  --yellow-50:  #fff5e5;
  --yellow-100: #ffe7c7;
  --yellow-200: #ffcf94;
  --yellow-300: #ffba6b;
  --yellow-400: #ffab52;
  --yellow-500: #ffa33f;   /* brand */
  --yellow-600: #f37e12;
  --yellow-700: #be600e;
  --yellow-800: #85410a;
  --yellow-900: #4f2708;
  --yellow-ink: #271302;   /* text on accent bg */

  /* Neutral */
  --neutral-50:  #fafafa;
  --neutral-100: #f5f5f5;
  --neutral-200: #e5e5e5;
  --neutral-300: #d4d4d4;
  --neutral-400: #a3a3a3;
  --neutral-500: #737373;
  --neutral-600: #525252;
  --neutral-700: #1e1e1e;
  --neutral-800: #131313;
  --neutral-900: #0a0a0a;  /* canvas dark */
  --neutral-white: #ffffff;
  --neutral-black: #000000;

  /* Content-vertical accents — the colour-coded category pills
     (.section-eyebrow--tag). Two PRIMARY pillars (film/music) carry the loud,
     opposed pair (blue/red); two SECONDARY verticals (AI/events) take the
     quiet pair (orange/green); functional sections stay charcoal (no colour).
     White label on every fill. Re-theme verticals here. */
  --cat-film:    #8b5cf6;   /* 影視 — violet · PRIMARY pillar (re-hued off brand orange 2026-06-20; was #ff6a00, clashed with accent #ffa33f) */
  --cat-music:   #ff3b30;   /* 音樂    — red    · PRIMARY pillar     */
  --cat-origin:  #014aff;   /* 原力/AI — blue   · secondary (cool = AI; freed when film took orange) */
  --cat-events:  #00c853;   /* 活動/同場加映 — green · secondary      */
  --cat-neutral: #565656;   /* 功能/跨類 — charcoal (not a vertical)  */

  /* Skeleton-loader surface — sits just above the dark canvas. */
  --skeleton-surface: #161616;

  /* Score-orb liquid tiers — psychological grade scale, harmonized to
     brand yellow #ffa33f by ANALOGOUS hues (not complements):
       rust   = poor    (red psychology, on yellow's warm side)
       honey  = caution (literally darkened brand yellow)
       leaf   = good    (green psychology, on yellow's green side)
       prism  = exceptional (a muted, antique rainbow — the film
                outgrows the scale; saturation kept low on purpose)
     Deliberately separate from Status colors: scores are a grading
     scale, not system feedback. */
  /* Stops compressed toward the center: the liquid layer is an
     oversized block (140%) clipped by the orb, so the gradient's
     outer reaches are never visible — all four hues must live in
     the central band. */
  /* ONE LIQUID: true black, every tier. The fill level alone encodes the
     score — 77 is a glass 77% full of the brand's own ink. The four
     liquid tokens are kept (components and 16 pages reference the tier
     classes) but they all point at the same material on purpose — don't
     "fix" this back into a ramp without a design decision. */
  --score-liquid-top: #0a0a0a;
  --score-liquid-high: #0a0a0a;
  --score-liquid-mid:  #0a0a0a;
  --score-liquid-low:  #0a0a0a;

  /* Score-orb NUMERAL inks — the tier lives in the number, not the
     liquid (design decision 2026-06-11). The ladder follows grade
     PSYCHOLOGY (gold-medal / green-good / amber-caution / red-poor),
     each hue tuned to sit elegantly with the yellow canvas and pop on
     the black liquid (all ≥7:1 on #0a0a0a):
       top  = brand yellow — gold-medal: excellence owns the brand color
       high = #30d158, Apple's dark-mode system green — engineered for
              colored text on near-black (APCA Lc 61 on the liquid vs 55
              for --success-500, which read too dark). True green, so it
              stays unmistakably distinct from gold; saturated, so it
              doesn't go pastel-cheap like the old #4ade80
       mid  = honey amber — caution, warm side of the brand
       low  = signal red, softened just enough to stay refined */
  --score-ink-top:  #ffa33f;
  --score-ink-high: #30d158;
  --score-ink-mid:  #ffb340;
  --score-ink-low:  #ff5a5a;

  /* Status */
  --success-500: #22c55e;
  --success-700: #15803d;
  --warning-500: #fb923c;
  --warning-700: #c2410c;
  --error-500:   #ef4444;
  --error-700:   #b91c1c;
  --error-ink:   #2a0a0a;  /* text on red bg */
  --info-500:    #3b82f6;
  --info-700:    #1d4ed8;

  /* White Alpha — standard transparency stops for overlays / borders / glass */
  --white-alpha-4:  rgba(255, 255, 255, 0.04);
  --white-alpha-8:  rgba(255, 255, 255, 0.08);
  --white-alpha-16: rgba(255, 255, 255, 0.16);
  --white-alpha-24: rgba(255, 255, 255, 0.24);

  /* ─────────────────────────────────────────
     COLOR — Semantic (Dark mode)
     ───────────────────────────────────────── */

  --bg-primary:   var(--neutral-900);   /* page bg */
  --bg-secondary: var(--neutral-800);   /* surface (raised section) */
  --bg-tertiary:  var(--neutral-700);   /* card / elevated panel */
  --bg-card:      var(--bg-tertiary);   /* semantic alias */

  --text-primary:   rgba(255, 255, 255, 0.95);
  --text-secondary: rgba(255, 255, 255, 0.65);
  --text-tertiary:  rgba(255, 255, 255, 0.45);
  --text-disabled:  rgba(255, 255, 255, 0.35);

  --border-subtle:  rgba(255, 255, 255, 0.04);
  --border-default: rgba(255, 255, 255, 0.12);
  --border-strong:  rgba(255, 255, 255, 0.22);

  --interactive-primary:    var(--yellow-500);
  --interactive-on-primary: var(--yellow-ink);

  /* Glass overlay tokens (used by Ghost/IconButton) */
  --glass-bg-default:  rgba(255, 255, 255, 0.10);
  --glass-bg-hover:    rgba(255, 255, 255, 0.18);
  --glass-bg-pressed:  rgba(255, 255, 255, 0.26);
  --glass-bg-disabled: rgba(255, 255, 255, 0.04);

  --glass-stroke-default:  rgba(255, 255, 255, 0.20);
  --glass-stroke-hover:    rgba(255, 255, 255, 0.32);
  --glass-stroke-pressed:  rgba(255, 255, 255, 0.45);
  --glass-stroke-disabled: rgba(255, 255, 255, 0.08);

  /* GLASS effect web equivalent (Figma GLASS effect ≈ backdrop-filter) */
  --glass-blur: blur(20px) saturate(1.4);

  /* ─────────────────────────────────────────
     MOTION
     One easing curve for the whole site — a fast-out deceleration
     (the element meets the cursor, then settles). Use for all
     hover/press/reveal transitions instead of the browser default
     `ease`. Durations stay per-component (120–250ms typical).

     BREAKPOINTS (reference — CSS vars can't drive @media):
       1280px  header condensation stage 1
       1024px  header condensation stage 2, tablet adjustments
        768px  site-wide mobile breakpoint (single source: the
               MOBILE TWEAKS block at the END of components.css)
     ───────────────────────────────────────── */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);

  /* ─────────────────────────────────────────
     TYPOGRAPHY
     ───────────────────────────────────────── */

  /* Font stacks — Latin tier first so mixed CJK+EN runs render English / 數字
     in Proxima Nova (Adobe Typekit kit `mul0tkj`), then fall through to Inter,
     and finally to the CJK face for Chinese glyphs (browsers walk the stack
     per-glyph).
     'proxima-nova' (lowercase) is Typekit's exposed family name.
     'Proxima Nova' kept for any future self-hosted copy.
     Display tier:  brand UI — Hero / H1–H4 / Button LG / Nav.
     Text tier:     reading & secondary UI. */
  --font-cjk-display: 'proxima-nova', 'Proxima Nova', 'Inter',
                      'LINE Seed TW', 'Noto Sans TC',
                      'PingFang TC', 'Microsoft JhengHei', sans-serif;
  --font-cjk-text:    'proxima-nova', 'Proxima Nova', 'Inter',
                      'Noto Sans TC',
                      'PingFang TC', 'Microsoft JhengHei', sans-serif;
  /* ^ Text tier 中文 = Noto Sans TC（Dolly DS 規範雙 tier 分層:Display tier
     用 LINE Seed、Text tier 用 Noto——LINE Seed 字重不足,需 Medium 的場景靠
     Noto）。2026-06-17 移除 L 暫塞的 LINE Seed,恢復 Text tier=Noto。 */
  --font-latin:       'proxima-nova', 'Proxima Nova', 'Inter',
                      system-ui, -apple-system, sans-serif;

  /* Font weights */
  --fw-thin:      100;
  --fw-light:     300;
  /* Regular = 400 per Dolly DS 規範（2026-06-17 改回）。L 曾設 500,稱 16px
     Noto 400 在暗底 shimmer;但實測一般文案 400 無虞,且需與 Medium(500)
     拉開階層(Regular≠Medium),故回 400。 */
  --fw-regular:   400;
  --fw-medium:    500;
  --fw-semibold:  600;
  --fw-bold:      700;
  --fw-extrabold: 800;
  --fw-black:     900;

  /* Font sizes */
  --fs-display:  76px;
  --fs-h1:       48px;
  --fs-h2:       42px;
  --fs-feature-title: 36px;
  --fs-h3:       24px;
  --fs-h4:       20px;
  --fs-h5:       16px;
  --fs-body-lg:  18px;
  --fs-body:     16px;
  --fs-body-sm:  14px;
  --fs-caption:  12px;

  /* Line heights */
  --lh-display:  83px;
  --lh-h1:       57px;
  --lh-h2:       50px;
  --lh-feature-title: 43px;
  --lh-h3:       31px;
  --lh-h4:       26px;
  --lh-h5:       24px;
  --lh-body-lg:  30px;
  --lh-body:     27px;
  --lh-body-sm:  23px;
  --lh-caption:  18px;
  --lh-label:    15px;

  /* Letter spacing */
  --ls-display: -2px;
  --ls-h1:      -1px;
  --ls-h2:      -1px;
  --ls-h3:      -0.5px;
  --ls-h4:       0;
  --ls-h5:       0;
  --ls-body:     0;
  --ls-body-lg:  0;
  --ls-body-sm:  0;
  --ls-caption:  0;
  --ls-label:    1.2px;

  /* ─────────────────────────────────────────
     SPACING (4px base scale)
     ───────────────────────────────────────── */

  --space-1:  4px;
  --space-2:  8px;
  --space-3:  12px;
  --space-4:  16px;
  --space-5:  20px;
  --space-6:  24px;
  --space-8:  32px;
  --space-10: 40px;
  --space-12: 48px;
  --space-14: 56px;
  --space-16: 64px;
  --space-20: 80px;
  --space-24: 96px;
  --space-32: 128px;
  --space-40: 160px;

  /* ─────────────────────────────────────────
     RADIUS
     ───────────────────────────────────────── */

  --radius-none: 0;
  --radius-xs:   2px;
  --radius-sm:   4px;
  --radius-md:   8px;
  --radius-lg:   12px;
  --radius-xl:   16px;
  --radius-2xl:  24px;
  --radius-pill: 9999px;

  /* ─────────────────────────────────────────
     LAYOUT
     ───────────────────────────────────────── */

  --container-max:        1280px;
  --container-wide:       1440px;
  --container-padding-x:  48px;
  --header-height:        64px;
}

/* ─────────────────────────────────────────
   TYPOGRAPHY UTILITY CLASSES
   17 styles matching Figma Foundations
   ───────────────────────────────────────── */

.t-display {
  font-family: var(--font-cjk-display);
  font-size: var(--fs-display);
  line-height: var(--lh-display);
  letter-spacing: var(--ls-display);
  font-weight: var(--fw-bold);
}

.t-h1 {
  font-family: var(--font-cjk-display);
  font-size: var(--fs-h1);
  line-height: var(--lh-h1);
  letter-spacing: var(--ls-h1);
  font-weight: var(--fw-bold);
}

.t-h2 {
  font-family: var(--font-cjk-display);
  font-size: var(--fs-h2);
  line-height: var(--lh-h2);
  letter-spacing: var(--ls-h2);
  font-weight: var(--fw-bold);
}

.t-feature-title {
  font-family: var(--font-cjk-display);
  font-size: var(--fs-feature-title);
  line-height: var(--lh-feature-title);
  letter-spacing: var(--ls-h2);
  font-weight: var(--fw-bold);
}

.t-h3 {
  font-family: var(--font-cjk-display);
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  letter-spacing: var(--ls-h3);
  font-weight: var(--fw-bold);
}

.t-h4 {
  font-family: var(--font-cjk-display);
  font-size: var(--fs-h4);
  line-height: var(--lh-h4);
  font-weight: var(--fw-bold);
}

.t-h5 {
  font-family: var(--font-cjk-text);
  font-size: var(--fs-h5);
  line-height: var(--lh-h5);
  font-weight: var(--fw-bold);
}

.t-body-lg {
  font-family: var(--font-cjk-text);
  font-size: var(--fs-body-lg);
  line-height: var(--lh-body-lg);
  font-weight: var(--fw-regular);
}

.t-body {
  font-family: var(--font-cjk-text);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: var(--fw-regular);
}

.t-body-sm {
  font-family: var(--font-cjk-text);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body-sm);
  font-weight: var(--fw-regular);
}

.t-body-reading {
  font-family: var(--font-cjk-text);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: var(--fw-light);
}

.t-body-preview {
  font-family: var(--font-cjk-text);
  font-size: var(--fs-body-lg);
  line-height: var(--lh-body-lg);
  font-weight: var(--fw-light);
}

.t-caption {
  font-family: var(--font-cjk-text);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  font-weight: var(--fw-regular);
}

.t-eyebrow {
  font-family: var(--font-cjk-text);
  font-size: var(--fs-caption);
  line-height: var(--lh-label);
  letter-spacing: var(--ls-label);
  font-weight: var(--fw-medium);
  text-transform: uppercase;
}

.t-nav {
  font-family: var(--font-cjk-display);
  font-size: var(--fs-h5);
  line-height: var(--lh-h5);
  font-weight: var(--fw-regular);
}

.t-button-lg {
  font-family: var(--font-cjk-display);
  font-size: var(--fs-h5);
  line-height: var(--lh-h5);
  font-weight: var(--fw-bold);
}

.t-button-md {
  font-family: var(--font-cjk-text);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body-sm);
  font-weight: var(--fw-medium);
}

.t-button-sm {
  font-family: var(--font-cjk-text);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  font-weight: var(--fw-medium);
}

/* ─────────────────────────────────────────
   GLOBAL RESET / BASE
   ───────────────────────────────────────── */

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

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg-primary);
  color: var(--text-primary);
  font-family: var(--font-cjk-text);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Sticky footer：main 自己撐到「視窗高 − header 高」，內部 flex column，
   footer 用 margin-top:auto 推到底。內容少的短頁（如活動頁）下方留白落在
   main 內，footer 不浮上來。footer 位於 main 內部（全站結構一致）。
   main 自帶 min-height，不依賴 body 是否為 flex 容器。 */
main {
  display: flex;
  flex-direction: column;
  min-height: calc(100vh - var(--header-height));
}

/* Reserve the scrollbar gutter so navigating between a tall page (scrollbar
   shown) and a short one (no scrollbar) doesn't shift centred content — the
   "jump" on page change. No-op on overlay-scrollbar systems (e.g. macOS). */
html {
  scrollbar-gutter: stable;
}

a { color: inherit; text-decoration: none; }
button { font-family: inherit; cursor: pointer; }
img { max-width: 100%; display: block; }

/* Text selection — brand yellow with ink text, replacing the browser
   default magenta/blue. */
::selection {
  background: var(--yellow-500);
  color: var(--yellow-ink);
}
::-moz-selection {
  background: var(--yellow-500);
  color: var(--yellow-ink);
}

/* ─────────────────────────────────────────
   LAYOUT UTILITIES
   ───────────────────────────────────────── */

.container {
  max-width: var(--container-max);
  margin: 0 auto;
  padding-left: var(--container-padding-x);
  padding-right: var(--container-padding-x);
}

.container--wide {
  max-width: var(--container-wide);
}

.full-bleed {
  width: 100%;
}

/* ─────────────────────────────────────────
   SECTION RHYTHM
   Each homepage chapter sits inside a .section.
   Backgrounds alternate page <-> surface for cinematic zebra rhythm.
   ───────────────────────────────────────── */

.section {
  position: relative;
  padding-block: clamp(64px, 9vw, 100px);
}

.section--tight { padding-block: clamp(48px, 6vw, 80px); }
.section--loose { padding-block: clamp(96px, 12vw, 160px); }

/* ── SECTION BACKGROUNDS + THEMES moved out ───────────────────────────────
   The zebra background classes (.section-bg-page / .section-bg-surface) and
   all their foreground contrast rules now live in their own file:
       section-themes.css   (linked after components.css on every page)
   Keep section-background work there — do NOT re-add it here. ──────────── */

/* ─────────────────────────────────────────
   SECTION EYEBROW
   Yellow brand label that opens each homepage section.
   ───────────────────────────────────────── */

.section-eyebrow {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-cjk-text);
  font-size: var(--fs-caption);
  line-height: 1.33;
  letter-spacing: 0.12em;
  font-weight: var(--fw-medium);
  text-transform: uppercase;
  color: var(--yellow-500);
}

/* ─────────────────────────────────────────
   SECTION HEADER
   Pattern: [chapter-eyebrow] → [title row: title/sub on left, link on right]
   Used at the top of every chapter on the homepage.
   ───────────────────────────────────────── */

.section-header {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-bottom: var(--space-10);
}

.section-header__row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-8);
  flex-wrap: wrap;
}

.section-header__copy {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.section-header__title {
  font-family: var(--font-cjk-display);
  font-weight: var(--fw-bold);
  font-size: clamp(28px, 3.4vw, 42px);
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--text-primary);
  margin: 0;
}

.section-header__sub {
  font-family: var(--font-cjk-text);
  font-weight: var(--fw-regular);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--text-secondary);
  max-width: 520px;
  margin: 0;
}

/* "查看所有 →" right-side link */
.section-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-cjk-text);
  font-size: var(--fs-body-sm);
  font-weight: var(--fw-medium);
  color: var(--yellow-500);
  white-space: nowrap;
  /* Invisible hit-area expansion: padding grows the tap target to ~44px,
     the matching negative margin cancels the layout shift, so the link
     looks identical but is far easier to hit. Visual weight unchanged
     on purpose — the section's CTA is its content, not this exit. */
  padding: 12px 14px;
  margin: -12px -14px;
  border-radius: var(--radius-pill);
  transition: gap 150ms ease;
}

.section-link:hover { gap: var(--space-3); }

.section-link__arrow {
  width: 16px;
  height: 16px;
  display: inline-block;
  /* Glass arrow — the same material family as the score orb (specular
     above, depth below). Two baked SVG variants instead of currentColor
     masking, because a gradient body can't ride a single-color mask.
     16px (was 14) so the material can actually read at glyph size. */
  background: url('assets/icons/arrow_right_glass.svg') center / contain no-repeat;
  /* The "beckon" loop lives below, gated behind .is-beckoning — a per-link
     IntersectionObserver (index.html / screening-room.html) adds the class
     when THE LINK enters the viewport, removes it when fully off-screen.
     So the knock plays the moment you arrive at a section, every visit.
     Without JS the arrow is simply still — motion is enhancement. */
}

/* Ambient "beckon": the arrow alone knocks twice (6px, then a 3px echo)
   the moment its section arrives, then rests — 840ms of motion at the
   START of a 3.5s cycle (76% silence after). Knock-first matters: the
   observer adds the class on entry, so the eye sees the loop begin.
   Horizontal on purpose: it rehearses the hover's gap-widen instead of
   introducing a second motion language. Whole-link bounce is banned —
   moving text can't be read. Viewport entry IS the stagger: links arrive
   one at a time, so no per-section delays are needed.
   Percentages = absolute knock times (240/480/660/840ms) over the cycle —
   change the duration and you change the knock speed; recompute, don't
   eyeball. */
.section-link.is-beckoning .section-link__arrow {
  animation: section-link-beckon 3.5s infinite;
}

@keyframes section-link-beckon {
  0%     { transform: translateX(0);
           animation-timing-function: var(--ease-out); }
  6.9%   { transform: translateX(6px);
           animation-timing-function: cubic-bezier(0.77, 0, 0.175, 1); }
  13.7%  { transform: translateX(0);
           animation-timing-function: var(--ease-out); }
  18.9%  { transform: translateX(3px);
           animation-timing-function: cubic-bezier(0.77, 0, 0.175, 1); }
  24%    { transform: translateX(0); }
  100%   { transform: translateX(0); }
}

/* On hover the invitation goes quiet and the gap-widen does its job.
   Pause (not none) — `none` would snap a mid-knock arrow back. */
@media (hover: hover) and (pointer: fine) {
  .section-link:hover .section-link__arrow { animation-play-state: paused; }
}

/* The loop is pure decoration — remove it entirely, keep hover feedback. */
@media (prefers-reduced-motion: reduce) {
  .section-link__arrow { animation: none; }
}

/* ──────────────────────────────────────────────────────────────
   English locale type system. i18n.js sets <html lang="en"> and loads
   Satoshi (UI/body) + Afacad (display headings). Chinese is untouched.

   Roles:
     • Hero headlines, page & section titles → Afacad
     • Body, buttons, forms, navigation, prices, stats, dense UI → Satoshi

   Base = everything Satoshi (the 3 font tokens), then an explicit Afacad
   allow-list for the editorial title tier only. */
html[lang="en"] {
  --font-cjk-display: 'Satoshi', 'Inter', system-ui, -apple-system, sans-serif;
  --font-cjk-text:    'Satoshi', 'Inter', system-ui, -apple-system, sans-serif;
  --font-latin:       'Satoshi', 'Inter', system-ui, -apple-system, sans-serif;
}

/* Afacad — hero headlines + page/section titles only. Higher specificity
   than the component rules (html[lang="en"] prefix), so no !important. */
html[lang="en"] :is(
  .hero-carousel__title,
  .page-head__title,
  .section-header__title,
  .shop-head__title,
  .lb-head__title,
  .creator-hero__name,
  .creator-sec__title,
  .rf-hero__title,
  .t-display, .t-h1, .t-h2
) {
  font-family: 'Afacad', 'Satoshi', 'Inter', system-ui, -apple-system, sans-serif;
}
