/* ============================================================
   Ztor 2.0 — Components
   Mirrors Figma component sets:
   - Button (Type × Size × State)
   - IconButton (State + Icon swap)
   - Header (State=Before Login | After Login)
   ============================================================ */

/* ─────────────────────────────────────────
   BUTTON
   variants: primary | ghost | yellow-ghost | destructive
   sizes:    lg | md | sm
   states:   default | :hover | :active | :disabled
   ───────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  cursor: pointer;
  white-space: nowrap;
  transition: filter 150ms ease,
              box-shadow 150ms ease,
              background 150ms ease,
              border-color 150ms ease,
              color 150ms ease;
}

.btn:disabled { cursor: not-allowed; }
.btn:focus-visible {
  outline: 2px solid var(--yellow-500);
  outline-offset: 2px;
}

/* ── Sizes ── */
.btn--lg {
  padding: 16px 36px;
  font-family: var(--font-cjk-display);
  font-size: var(--fs-h5);
  line-height: var(--lh-body);
  font-weight: var(--fw-bold);
}

.btn--md {
  padding: 12px 28px;
  font-family: var(--font-cjk-text);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body-sm);
  font-weight: var(--fw-medium);
}

.btn--sm {
  padding: 8px 16px;
  font-family: var(--font-cjk-text);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  font-weight: var(--fw-medium);
}

/* ── PRIMARY ──
   Flat solid yellow. LG adds soft top highlight (4px inner shadow).
   Hover: + outer yellow glow 24px. Pressed: glow 40px (no highlight).
*/
.btn--primary {
  background: var(--yellow-500);
  color: var(--yellow-ink);
  border-color: transparent;
}

.btn--primary.btn--lg {
  box-shadow: inset 0 1px 4px rgba(255, 255, 255, 0.9);
}

.btn--primary:hover:not(:disabled) {
  box-shadow: 0 0 24px rgba(255, 230, 0, 0.35);
}

.btn--primary.btn--lg:hover:not(:disabled) {
  box-shadow: inset 0 1px 4px rgba(255, 255, 255, 0.9),
              0 0 24px rgba(255, 230, 0, 0.35);
}

.btn--primary:active:not(:disabled) {
  box-shadow: 0 0 40px rgba(255, 230, 0, 0.5);
}

.btn--primary:disabled { opacity: 0.4; }

/* ── GHOST (Artlist-style glass) ──
   background = bottom-edge bright stripe gradient
   box-shadow = top + bottom edge highlights + inner soft shadow
   text-shadow = subtle text glow
*/
.btn--ghost {
  background: linear-gradient(0deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 0.18) 2.45%,
    rgba(255, 255, 255, 0) 126.14%);
  border-color: transparent;
  color: var(--text-primary);
  text-shadow: none;
  box-shadow:
    rgba(255, 255, 255, 0.9) 1.1px 2.2px 0.5px -1.8px inset,
    rgba(255, 255, 255, 0.9) -1px -2.2px 0.5px -1.8px inset,
    rgba(0, 0, 0, 0.10) 2px 3px 2px 0 inset;
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
}

.btn--ghost:hover:not(:disabled) {
  background: linear-gradient(0deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 0.30) 2.45%,
    rgba(255, 255, 255, 0) 126.14%);
  text-shadow: rgba(255, 255, 255, 0.45) 0 0 10px;
}

.btn--ghost:active:not(:disabled) {
  background: linear-gradient(0deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 0.42) 2.45%,
    rgba(255, 255, 255, 0) 126.14%);
  box-shadow:
    rgba(255, 255, 255, 0.6) 1.1px 2.2px 0.5px -1.8px inset,
    rgba(255, 255, 255, 0.6) -1px -2.2px 0.5px -1.8px inset,
    rgba(0, 0, 0, 0.20) 2px 3px 4px 0 inset;
}

.btn--ghost:disabled {
  background: rgba(255, 255, 255, 0.04);
  color: var(--text-disabled);
  text-shadow: none;
  box-shadow:
    rgba(255, 255, 255, 0.25) 1.1px 2.2px 0.5px -1.8px inset,
    rgba(255, 255, 255, 0.25) -1px -2.2px 0.5px -1.8px inset;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

/* ── YELLOW-GHOST ── */
.btn--yellow-ghost {
  background: linear-gradient(0deg,
    rgba(255, 230, 0, 0) 0%,
    rgba(255, 230, 0, 0.18) 2.45%,
    rgba(255, 230, 0, 0) 126.14%);
  border-color: transparent;
  color: var(--yellow-500);
  text-shadow: none;
  box-shadow:
    rgba(255, 230, 0, 0.9) 1.1px 2.2px 0.5px -1.8px inset,
    rgba(255, 230, 0, 0.9) -1px -2.2px 0.5px -1.8px inset,
    rgba(0, 0, 0, 0.10) 2px 3px 2px 0 inset;
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
}

.btn--yellow-ghost:hover:not(:disabled) {
  background: linear-gradient(0deg,
    rgba(255, 230, 0, 0) 0%,
    rgba(255, 230, 0, 0.30) 2.45%,
    rgba(255, 230, 0, 0) 126.14%);
  text-shadow: rgba(255, 230, 0, 0.4) 0 0 10px;
}

.btn--yellow-ghost:active:not(:disabled) {
  background: linear-gradient(0deg,
    rgba(255, 230, 0, 0) 0%,
    rgba(255, 230, 0, 0.42) 2.45%,
    rgba(255, 230, 0, 0) 126.14%);
  box-shadow:
    rgba(255, 230, 0, 0.6) 1.1px 2.2px 0.5px -1.8px inset,
    rgba(255, 230, 0, 0.6) -1px -2.2px 0.5px -1.8px inset,
    rgba(0, 0, 0, 0.20) 2px 3px 4px 0 inset;
}

.btn--yellow-ghost:disabled {
  background: rgba(255, 230, 0, 0.04);
  color: rgba(255, 230, 0, 0.4);
  text-shadow: none;
  box-shadow:
    rgba(255, 230, 0, 0.3) 1.1px 2.2px 0.5px -1.8px inset,
    rgba(255, 230, 0, 0.3) -1px -2.2px 0.5px -1.8px inset;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

/* ── DESTRUCTIVE ──
   default/hover: hollow red glass (Artlist-style)
   pressed: solid red + ink text (state escalation)
*/
.btn--destructive {
  background: linear-gradient(0deg,
    rgba(239, 68, 68, 0) 0%,
    rgba(239, 68, 68, 0.20) 2.45%,
    rgba(239, 68, 68, 0) 126.14%);
  border-color: transparent;
  color: var(--error-500);
  text-shadow: none;
  box-shadow:
    rgba(239, 68, 68, 0.9) 1.1px 2.2px 0.5px -1.8px inset,
    rgba(239, 68, 68, 0.9) -1px -2.2px 0.5px -1.8px inset,
    rgba(0, 0, 0, 0.10) 2px 3px 2px 0 inset;
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
}

.btn--destructive:hover:not(:disabled) {
  background: linear-gradient(0deg,
    rgba(239, 68, 68, 0) 0%,
    rgba(239, 68, 68, 0.34) 2.45%,
    rgba(239, 68, 68, 0) 126.14%);
  text-shadow: rgba(239, 68, 68, 0.4) 0 0 10px;
}

.btn--destructive:active:not(:disabled) {
  background: var(--error-500);
  color: var(--error-ink);
  text-shadow: none;
  box-shadow:
    rgba(255, 255, 255, 0.5) 1.1px 2.2px 0.5px -1.8px inset,
    rgba(0, 0, 0, 0.3) 0 4px 12px;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

.btn--destructive:disabled {
  background: rgba(239, 68, 68, 0.05);
  color: rgba(239, 68, 68, 0.4);
  text-shadow: none;
  box-shadow:
    rgba(239, 68, 68, 0.3) 1.1px 2.2px 0.5px -1.8px inset,
    rgba(239, 68, 68, 0.3) -1px -2.2px 0.5px -1.8px inset;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

/* ─────────────────────────────────────────
   ICON BUTTON
   40×40 glass pill, swap-in icon child
   ───────────────────────────────────────── */

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 8px;
  border-radius: var(--radius-pill);
  background: var(--glass-bg-default);
  border: 1px solid var(--glass-stroke-default);
  color: var(--text-primary);
  cursor: pointer;
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  transition: background 150ms ease, border-color 150ms ease;
}

.icon-btn:hover:not(:disabled) {
  background: var(--glass-bg-hover);
  border-color: var(--glass-stroke-hover);
}

.icon-btn:active:not(:disabled) {
  background: var(--glass-bg-pressed);
  border-color: var(--glass-stroke-pressed);
}

.icon-btn:disabled {
  background: var(--glass-bg-disabled);
  border-color: var(--glass-stroke-disabled);
  color: var(--text-disabled);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  cursor: not-allowed;
}

.icon-btn svg {
  width: 24px;
  height: 24px;
  stroke: currentColor;
  fill: none;
}

/* ─────────────────────────────────────────
   AI MOSAIC
   AI 原力創作計畫 section: 2-col layout — copy + CTA on left, mosaic on right.
   Mosaic = 1 big tile (top, full row) + 4 small tiles (2×2 below).
   ───────────────────────────────────────── */

.ai-mosaic {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 80px;
  align-items: center;
}

.ai-mosaic__copy {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.ai-mosaic__ctas {
  display: flex;
  gap: 12px;
  margin-top: 12px;
  flex-wrap: wrap;
}

.ai-mosaic__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

/* Each tile is 16:9 (matches 1.0 image spec 1056×594).
   Big tile spans both columns; small tiles fill 1 col each. */
.ai-mosaic__tile {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-md);
  border: 1px solid var(--border-subtle);
  overflow: hidden;
  background: var(--bg-tertiary);
  text-decoration: none;
  color: inherit;
  transition: transform 320ms cubic-bezier(0.23, 1, 0.32, 1),
              border-color 220ms ease;
}

.ai-mosaic__tile-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
  /* Smooth ken-burns zoom on hover (gated below). */
  transition: transform 600ms cubic-bezier(0.23, 1, 0.32, 1);
}

/* Hover polish — gated on hover-capable pointers so touch devices don't
   get stuck-hover states. Matches community-card hover language:
   tile lifts, image zooms inside the clipped frame, title shifts yellow,
   border edge picks up a subtle yellow accent. */
@media (hover: hover) and (pointer: fine) {
  .ai-mosaic__tile:hover {
    transform: translateY(-4px);
    border-color: rgba(255, 219, 41, 0.4);
  }
  .ai-mosaic__tile:hover .ai-mosaic__tile-img {
    transform: scale(1.06);
  }
  .ai-mosaic__tile-title {
    transition: color 220ms ease;
  }
  .ai-mosaic__tile:hover .ai-mosaic__tile-title {
    color: #ffdb29;
  }
}

/* Bottom-darken gradient — ensures status badge + title stay legible
   over any image content. */
.ai-mosaic__tile::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg,
    rgba(0, 0, 0, 0.10) 0%,
    rgba(0, 0, 0, 0)    35%,
    rgba(0, 0, 0, 0.65) 100%);
  pointer-events: none;
  z-index: 1;
}

.ai-mosaic__tile--big {
  grid-column: 1 / -1;
  border-radius: var(--radius-lg);
}

.ai-mosaic__tile-status {
  position: absolute;
  top: 14px;
  left: 16px;
  z-index: 2;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.ai-mosaic__tile-title {
  position: absolute;
  left: 16px;
  right: 16px;
  bottom: 14px;
  z-index: 2;
  font-family: var(--font-cjk-display);
  font-weight: var(--fw-bold);
  font-size: 14px;
  line-height: 1.3;
  color: var(--text-primary);
  letter-spacing: -0.005em;
  text-wrap: balance;
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.4);
}

.ai-mosaic__tile--big .ai-mosaic__tile-title {
  font-size: 22px;
  letter-spacing: -0.01em;
}

/* ─────────────────────────────────────────
   CO-CREATION CARD / GRID
   3-up cards for 影視共創計畫 section.
   Card structure: 16:9 hero image → badge → title → desc → metrics block
   ───────────────────────────────────────── */

.cocreation-grid {
  display: grid;
  /* Self-collapsing 3→2→1 — no mobile @media needed for the grid count.
     Floor 280px keeps poster + body legible; below that, drop to 1-col. */
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 20px;
}

.cocreation-card {
  display: flex;
  flex-direction: column;
  background: var(--bg-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: transform 250ms ease, border-color 250ms ease;
  text-decoration: none;
  color: inherit;
}

.cocreation-card:hover {
  transform: translateY(-4px);
  border-color: var(--border-default);
}

.cocreation-card__poster {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--neutral-900);
}

.cocreation-card__poster img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.cocreation-card__body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 22px;
  flex: 1;
}

.cocreation-card__title {
  font-family: var(--font-cjk-display);
  font-weight: var(--fw-bold);
  font-size: 22px;
  line-height: 1.3;
  color: var(--text-primary);
  margin: 0;
}

.cocreation-card__desc {
  font-family: var(--font-cjk-text);
  font-weight: var(--fw-light);
  font-size: 14px;
  line-height: 1.7;
  color: var(--text-secondary);
  margin: 0;
}

.cocreation-card__metrics {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.cocreation-card__amount {
  font-family: var(--font-cjk-text);
  font-size: 18px;
  font-weight: var(--fw-bold);
  color: var(--text-primary);
}

.cocreation-card__bar {
  height: 3px;
  background: rgba(255, 255, 255, 0.10);
  border-radius: var(--radius-pill);
  overflow: hidden;
}

.cocreation-card__bar-fill {
  height: 100%;
  background: var(--yellow-500);
  box-shadow: 0 0 8px rgba(255, 230, 0, 0.35);
  border-radius: var(--radius-pill);
  transition: width 1s ease;
}

.cocreation-card__meta-row {
  display: flex;
  justify-content: space-between;
  font-family: var(--font-cjk-text);
  font-size: 12px;
  font-weight: var(--fw-regular);
  color: var(--text-tertiary);
}

/* Generic badge — yellow tinted pill (used inside cards / labels)
   Modifier .badge--success → green tinted + ✓ icon (for 目標達成 / 已完成 狀態) */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  align-self: flex-start;
  padding: 4px 12px;
  border-radius: var(--radius-pill);
  background: rgba(255, 230, 0, 0.12);
  border: 1px solid rgba(255, 230, 0, 0.25);
  color: var(--yellow-500);
  font-family: var(--font-cjk-text);
  font-size: 11px;
  font-weight: var(--fw-semibold);
  letter-spacing: 0.05em;
}

.badge--success {
  background: rgba(34, 197, 94, 0.12);
  border-color: rgba(34, 197, 94, 0.30);
  color: var(--success-500);
}

.badge--urgent {
  background: rgba(239, 68, 68, 0.14);
  border-color: rgba(239, 68, 68, 0.32);
  color: var(--error-500);
}

.badge--ended {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.16);
  color: var(--text-tertiary);
}

/* ─────────────────────────────────────────
   HERO CAROUSEL
   Full-bleed image-led banner. Each slide stacks:
     <bg image>  +  <darken gradients>  +  <foreground content bottom-left>
   Auto-advance, pause-on-hover, dots, prev/next, counter.

   ─── BANNER UPLOAD SPEC (for backend / content team) ───
     Aspect ratio:  3 : 1  (wide cinematic, balances height + minimal cropping)
     Master size:   2400 × 800  (retina-ready up to 1200px CSS at 2× DPR)
     Format:        JPG (≤ 700 KB).  WebP (≤ 500 KB) optional later for ~30% size win.
     Subject safe-zone:
       central 1080 × 800 area must contain the hero subject so the
       browser's center-crop survives portrait-phone viewports without
       cutting off faces / titles.
     If a separate mobile asset is supported later:
       1080 × 1350  (4:5 portrait)  — same content, recropped.
   ───────────────────────────────────────────────────────── */

.hero-carousel {
  position: relative;
  width: 100%;
  /* Aspect-aware height: tracks viewport width to match image's 3:1 ratio.
     - On 1680–2400px viewports: hero height ≈ viewport_width / 3 → image fits with no vertical crop.
     - Min 560px on narrow viewports (≤ 1680 wide) — slight horizontal crop, subject in safe zone survives.
     - Max 800px on ultra-wide (≥ 2400 wide) — image native height, no upscale.
     - Beyond 2400 CSS px (true 4K+ at 1× DPR) image still crops vertically;
       fix would be a larger source asset (e.g. 4800×1600). */
  height: clamp(560px, 33.33vw, 800px);
  overflow: hidden;
  background: var(--bg-primary);
}

.hero-carousel__slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  pointer-events: none;
  transition: opacity 800ms ease;
}

.hero-carousel__slide.is-active {
  opacity: 1;
  pointer-events: auto;
}

.hero-carousel__image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 30%;
  transform: scale(1.04);
}

.hero-carousel__darken-bottom,
.hero-carousel__darken-left {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* Bottom-up darken — fades into page bg for smooth section join */
.hero-carousel__darken-bottom {
  background: linear-gradient(180deg,
    rgba(0, 0, 0, 0.15) 0%,
    rgba(0, 0, 0, 0)    30%,
    rgba(0, 0, 0, 0.55) 70%,
    var(--bg-primary)   100%);
}

/* Left-side darken — gives copy on the bottom-left enough contrast */
.hero-carousel__darken-left {
  background: linear-gradient(90deg,
    rgba(0, 0, 0, 0.7)  0%,
    rgba(0, 0, 0, 0.35) 35%,
    transparent         60%);
}

.hero-carousel__content {
  position: relative;
  z-index: 1;
  height: 100%;
  display: flex;
  align-items: flex-end;
  padding-bottom: clamp(72px, 10vh, 128px);
}

.hero-carousel__copy {
  display: flex;
  flex-direction: column;
  gap: 22px;
  max-width: 880px;
}

.hero-carousel__eyebrow {
  font-family: var(--font-cjk-text);
  font-size: 12px;
  font-weight: var(--fw-medium);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.85);
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.5);
}

.hero-carousel__title {
  font-family: var(--font-cjk-display);
  font-weight: var(--fw-bold);
  font-size: clamp(44px, 5.4vw, 76px);
  line-height: 1.18;
  letter-spacing: -0.02em;
  color: var(--text-primary);
  margin: 0;
  text-shadow: 0 2px 24px rgba(0, 0, 0, 0.4);
  /* Default to single line (cinematic 1-line feel).
     Slides that want a 2-line title use explicit <br> — <br> overrides nowrap. */
  white-space: nowrap;
}

.hero-carousel__sub {
  font-family: var(--font-cjk-text);
  font-weight: var(--fw-light);
  font-size: 18px;
  line-height: 1.7;
  color: rgba(255, 255, 255, 0.85);
  margin: 0;
  max-width: 520px;
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.4);
}

/* Meta line — used for countdown / status meta on event-style slides
   (e.g. AI 競賽：「參賽截止還有 1 天」) */
.hero-carousel__meta {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  font-family: var(--font-cjk-text);
  font-size: 16px;
  line-height: 1.7;
  color: rgba(255, 255, 255, 0.85);
  margin: 0;
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.4);
}

.hero-carousel__countdown {
  font-family: var(--font-latin);
  font-size: 24px;
  font-weight: var(--fw-bold);
  color: var(--neutral-white);
  margin: 0 6px;
  font-style: normal;
}

.hero-carousel__ctas {
  display: flex;
  gap: 12px;
  margin-top: 8px;
  flex-wrap: wrap;
}

/* Prev / next nav buttons — Artlist-style glass (matches popcorn / notification)
   Hidden by default, fade in when carousel is hovered or nav is focused. */
.hero-carousel__nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 44px;
  height: 44px;
  border-radius: var(--radius-pill);
  border: none;
  padding: 0;
  cursor: pointer;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  background: linear-gradient(0deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 0.18) 2.45%,
    rgba(255, 255, 255, 0) 126.14%);
  box-shadow:
    rgba(255, 255, 255, 0.9) 1.1px 2.2px 0.5px -1.8px inset,
    rgba(255, 255, 255, 0.9) -1px -2.2px 0.5px -1.8px inset,
    rgba(0, 0, 0, 0.10) 2px 3px 2px 0 inset;
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  transition: opacity 250ms ease, background 200ms ease;
}

.hero-carousel:hover .hero-carousel__nav,
.hero-carousel__nav:focus-visible {
  opacity: 1;
  pointer-events: auto;
}

.hero-carousel__nav:hover {
  background: linear-gradient(0deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 0.30) 2.45%,
    rgba(255, 255, 255, 0) 126.14%);
}

.hero-carousel__nav--prev { left: 24px; }
.hero-carousel__nav--next { right: 24px; }

.hero-carousel__nav img {
  width: 22px;
  height: 22px;
  display: block;
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.5));
}

/* Dots — bottom center; active = wider yellow + glow */
.hero-carousel__dots {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 32px;
  display: flex;
  justify-content: center;
  gap: 14px;
  z-index: 2;
}

.hero-carousel__dot {
  height: 4px;
  width: 16px;
  padding: 0;
  border: none;
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, 0.3);
  cursor: pointer;
  transition: width 350ms ease, background 250ms ease, box-shadow 250ms ease;
}

.hero-carousel__dot.is-active {
  width: 36px;
  background: var(--yellow-500);
  box-shadow: 0 0 12px rgba(255, 230, 0, 0.55);
}

/* Counter — bottom-right "01 / 03" */
.hero-carousel__counter {
  position: absolute;
  right: 32px;
  bottom: 30px;
  font-family: var(--font-cjk-text);
  font-size: 12px;
  letter-spacing: 0.1em;
  color: rgba(255, 255, 255, 0.6);
  z-index: 2;
}

/* ─────────────────────────────────────────
   HEADER
   Mirrors Figma node 485:1139 (State=Before Login | After Login)
   Structure:
     header
       header/nav   (gap 40)  → header/logo + header/nav-links (gap 36)
       header/actions (gap 24) → search-icon + lang-icon + buttons-cluster
   ───────────────────────────────────────── */

.header {
  position: sticky;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  height: var(--header-height);
  background: rgba(10, 10, 10, 0.72);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border-subtle);
}

.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 100%;
  padding: 0 var(--container-padding-x);
}

.header__nav {
  display: flex;
  align-items: center;
  gap: 40px;
}

.header__logo {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  height: 30px;
}

.header__logo-img {
  height: 30px;
  width: auto;
  display: block;
}

.header__nav-links {
  display: flex;
  align-items: center;
  gap: 36px;
}

.header__nav-link {
  position: relative;
  padding: 8px 4px;
  font-family: var(--font-cjk-display);
  font-size: 16px;
  line-height: 24px;
  font-weight: var(--fw-regular);
  color: var(--neutral-400);
  white-space: nowrap;
  transition: color 200ms ease;
}

.header__nav-link:hover { color: var(--neutral-white); }

.header__nav-link.is-active {
  color: var(--neutral-white);
  font-weight: var(--fw-bold);
}

.header__nav-link.is-active::after {
  content: '';
  position: absolute;
  left: 4px;
  right: 4px;
  bottom: 0;
  height: 2px;
  border-radius: 1px;
  background: var(--yellow-500);
  box-shadow: 0 0 8px rgba(255, 230, 0, 0.55);
}

.header__actions {
  display: flex;
  align-items: center;
  gap: 24px;
  flex-shrink: 0;
}

/* Bare 24×24 icon button (search / language) — no glass pill
   Uses mask-image so the SVG (white-fill) can be recolored on hover.
   Set the icon via inline style: style="--icon: url('assets/icons/search.svg');" */
.header__icon-btn {
  display: inline-block;
  width: 24px;
  height: 24px;
  padding: 0;
  border: none;
  cursor: pointer;
  background-color: var(--neutral-white);
  -webkit-mask: var(--icon) center / 24px 24px no-repeat;
          mask: var(--icon) center / 24px 24px no-repeat;
  transition: background-color 200ms ease;
}

.header__icon-btn:hover { background-color: var(--yellow-500); }

/* Buttons cluster (right of icons) */
.header__buttons {
  display: flex;
  align-items: center;
  gap: 8px;
}

.header__buttons--logged-in { gap: 12px; }

/* PopcornSection — Before Login (計畫與價格 pill, Artlist-style glass) */
.popcorn-section {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 40px;
  padding: 0 16px;
  border: none;
  border-radius: var(--radius-pill);
  cursor: pointer;
  background: linear-gradient(0deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 0.18) 2.45%,
    rgba(255, 255, 255, 0) 126.14%);
  box-shadow:
    rgba(255, 255, 255, 0.9) 1.1px 2.2px 0.5px -1.8px inset,
    rgba(255, 255, 255, 0.9) -1px -2.2px 0.5px -1.8px inset,
    rgba(0, 0, 0, 0.10) 2px 3px 2px 0 inset;
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  transition: background 150ms ease;
}

.popcorn-section:hover {
  background: linear-gradient(0deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 0.30) 2.45%,
    rgba(255, 255, 255, 0) 126.14%);
}

.popcorn-section:hover .popcorn-section__label {
  text-shadow: rgba(255, 255, 255, 1) 0 0 10px;
}

.popcorn-section__balance {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.popcorn-section__label {
  font-family: var(--font-cjk-display);
  font-size: 14px;
  line-height: 20px;
  font-weight: var(--fw-regular);
  color: var(--neutral-white);
  white-space: nowrap;
}

.popcorn-section__icon {
  width: 24px;
  height: 24px;
  display: block;
  flex-shrink: 0;
}

.popcorn-section__chevron {
  width: 18px;
  height: 18px;
  display: block;
  flex-shrink: 0;
}

/* PopcornSection — After Login (popcorn + balance + deposit) */
.popcorn-section--logged-in {
  gap: 6px;
  padding: 0 4px 0 16px;
}

.popcorn-section__amount {
  font-family: var(--font-latin);
  font-size: 16px;
  line-height: 27px;
  font-weight: var(--fw-medium);
  color: #eae9f7;
  text-align: right;
  min-width: 40px;
}

.popcorn-section__deposit {
  width: 32px;
  height: 32px;
  border-radius: var(--radius-pill);
  background: var(--yellow-500);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  padding: 0;
  cursor: pointer;
  flex-shrink: 0;
  transition: filter 150ms ease;
}

.popcorn-section__deposit:hover { filter: brightness(1.04); }

/* plus.svg is white-fill → recolor to yellow-ink via mask on ::before */
.popcorn-section__deposit::before {
  content: '';
  display: block;
  width: 16px;
  height: 16px;
  background-color: var(--yellow-ink);
  -webkit-mask: url('assets/icons/plus.svg') center / contain no-repeat;
          mask: url('assets/icons/plus.svg') center / contain no-repeat;
}

/* btn-login-signup — yellow pill */
.header__login-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 40px;
  padding: 0 20px;
  background: var(--yellow-500);
  color: var(--yellow-ink);
  border: none;
  border-radius: var(--radius-pill);
  font-family: var(--font-cjk-text);
  font-size: 14px;
  line-height: 20px;
  font-weight: var(--fw-medium);
  cursor: pointer;
  box-shadow: inset 0 1px 4px rgba(255, 255, 255, 0.9);
  transition: filter 150ms ease, box-shadow 150ms ease;
}

.header__login-btn:hover {
  filter: brightness(1.04);
  box-shadow: inset 0 1px 4px rgba(255, 255, 255, 0.9),
              0 0 24px rgba(255, 230, 0, 0.35);
}

.header__login-btn:active {
  filter: brightness(0.98);
}

/* btn-notification (After Login) — 40×40 Artlist-style glass pill
   Red-dot for unread state lives inside notification_active.svg itself,
   so swap the src to notification_regular.svg to clear the badge. */
.header__notification-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 8px;
  border: none;
  border-radius: var(--radius-pill);
  cursor: pointer;
  background: linear-gradient(0deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 0.18) 2.45%,
    rgba(255, 255, 255, 0) 126.14%);
  box-shadow:
    rgba(255, 255, 255, 0.9) 1.1px 2.2px 0.5px -1.8px inset,
    rgba(255, 255, 255, 0.9) -1px -2.2px 0.5px -1.8px inset,
    rgba(0, 0, 0, 0.10) 2px 3px 2px 0 inset;
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  transition: background 150ms ease;
}

.header__notification-btn:hover {
  background: linear-gradient(0deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 0.30) 2.45%,
    rgba(255, 255, 255, 0) 126.14%);
}

.header__notification-btn img {
  width: 24px;
  height: 24px;
  display: block;
}

/* Avatar (After Login) — 40×40 圓形容器，內含用戶頭照
   未上傳時 fallback 到 assets/icons/avatar.svg */
.avatar {
  width: 40px;
  height: 40px;
  border-radius: var(--radius-pill);
  border: none;
  padding: 0;
  background: none;
  cursor: pointer;
  flex-shrink: 0;
  overflow: hidden;
}

.avatar__img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  border-radius: inherit;
}

/* ─────────────────────────────────────────
   DEV-ONLY: header state toggle
   切換 body[data-auth] 控制顯示 Before/After Login header
   出貨前移除（這支 class 與底部 button）
   ───────────────────────────────────────── */

body[data-auth="logged-out"] .header[data-state="after-login"],
body[data-auth="logged-in"]  .header[data-state="before-login"] {
  display: none;
}

.dev-toggle {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 9999;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 40px;
  padding: 0 16px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: var(--radius-pill);
  background: rgba(20, 20, 20, 0.85);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  color: var(--text-primary);
  font-family: var(--font-cjk-text);
  font-size: 13px;
  font-weight: var(--fw-medium);
  cursor: pointer;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
}

.dev-toggle::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: var(--radius-pill);
  background: var(--neutral-400);
}

body[data-auth="logged-in"] .dev-toggle::before { background: var(--yellow-500); }

.dev-toggle:hover { background: rgba(30, 30, 30, 0.9); }

/* ─────────────────────────────────────────
   MOBILE TWEAKS  ─  single breakpoint @ 768px
   Quick adaptation to make the desktop layout legible on phones for
   demo. Not a full mobile design — future sprint will redesign per
   section (proper nav, hero crop, card hierarchy, etc.).
   ───────────────────────────────────────── */

/* ─────────────────────────────────────────
   TABLET — 1024px breakpoint (Jony's call: middle state for 800–1024)
   ───────────────────────────────────────── */
@media (max-width: 1024px) {
  /* Container padding bridges desktop→mobile */
  :root { --container-padding-x: 32px; }

  /* Header — tighten nav-link gap + font, keep visible */
  .header__nav-links { gap: 16px; }
  .header__nav-link { font-size: 14px; }

  /* Section header h2 — bridge desktop (76px) → mobile (28px) */
  .section-header__title { font-size: clamp(32px, 5vw, 44px); }

  /* 影視共創 — 3 col → 2 col (posters too cramped at 800px in 3-col) */
  .cocreation-grid { grid-template-columns: repeat(2, 1fr); gap: 24px; }

  /* 電影庫 rail — peek-next at ~3.4 cards */
  .films-rail__track { --rail-cols: 3.4; }
  .films-rail__track--ranked { --rail-cols: 2.5; }

}

/* Touch-target floor — 44×44 on header icons for any touch device.
   FLAT compound query (not nested inside the 1024px @media above) — nested
   @media caused a silent parser failure on Safari that cascaded down and
   broke every subsequent mobile rule. Never nest at-rules in flat CSS. */
@media (max-width: 1024px) and (hover: none) and (pointer: coarse) {
  .header__icon-btn {
    min-width: 44px;
    min-height: 44px;
  }
  .header__actions { gap: 8px; }
}

@media (max-width: 768px) {

  /* Tighter horizontal padding for all .container / sections */
  :root { --container-padding-x: 20px; }

  /* Header — hide nav links, keep logo + actions; tighter padding */
  .header__nav-links { display: none; }
  .header { padding-inline: 16px; }
  .header__actions { gap: 12px; }

  /* Section rhythm — smaller vertical padding */
  .section { padding-block: clamp(48px, 12vw, 72px); }

  /* Section header — stack title row, scale down heading */
  .section-header { margin-bottom: 36px; }
  .section-header__title { font-size: clamp(28px, 7vw, 36px); line-height: 1.3; }
  .section-header__row {
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
  }

  /* Hero carousel — shorter, scaled text */
  .hero-carousel { height: clamp(420px, 70vw, 560px); }
  .hero-carousel__title { font-size: clamp(28px, 7.5vw, 40px); }
  .hero-carousel__sub { font-size: 14px; }
  .hero-carousel__ctas { gap: 10px; }
  .hero-carousel__nav--prev { left: 12px; }
  .hero-carousel__nav--next { right: 12px; }
  .hero-carousel__counter { right: 20px; }

  /* 影視共創 — 3 col → 1 col */
  .cocreation-grid { grid-template-columns: 1fr; gap: 20px; }

  /* AI 原力 — outer 2-col → 1-col, mosaic becomes horizontal scroll rail.
     Jony: "the mosaic's whole pleasure is the asymmetry, and asymmetry
     needs width. On 375px there is no width to be asymmetric in." */
  .ai-mosaic { grid-template-columns: 1fr; gap: 28px; }
  .ai-mosaic__grid {
    display: flex;
    grid-template-columns: none;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    gap: 12px;
    scrollbar-width: none;
    -ms-overflow-style: none;
    padding-inline: var(--container-padding-x);
    margin-inline: calc(-1 * var(--container-padding-x));
  }
  .ai-mosaic__grid::-webkit-scrollbar { display: none; }
  .ai-mosaic__tile {
    flex: 0 0 78%;
    scroll-snap-align: start;
    aspect-ratio: 4 / 3;
    grid-column: auto !important; /* drop the desktop col-span on --big */
  }
  .ai-mosaic__tile--big {
    flex: 0 0 88%; /* leading tile slightly larger to signal its role */
  }

  /* 電影庫 — rail shows ~1.2 cards (one card + peek); ranked ~1.05.
     L's call: thumbnails at 2.4 cols were too small; bigger posters
     with horizontal scroll is the editorial poster-browsing feel. */
  .films-rail__track { --rail-cols: 1.2; --rail-gap: 12px; }
  .films-rail__track--ranked { --rail-cols: 1.05; }
  .films-rail__tabs { overflow-x: auto; scrollbar-width: none; }
  .films-rail__tabs::-webkit-scrollbar { display: none; }
  .film-card--ranked { padding-left: 48px; }
  .film-card__rank { font-size: 180px; bottom: 36px; }

  /* 社群 — 3 col → 1 col, only first 3 cards visible (Jony's call).
     The remaining 3 cards collapse; a "see more" CTA replaces them.
     Three is the right number for first impression on a phone. */
  .community-grid { grid-template-columns: 1fr; gap: 20px; }
  .community-grid > .community-card:nth-child(n+4) { display: none; }
  .community-grid__more-mobile { display: flex; }

  /* 新聞 — 2 col → stack; list card 圖左 38% */
  .news-grid { grid-template-columns: 1fr; gap: 28px; }
  .news-card--hero .news-card__title { font-size: 20px; }
  .news-card--hero .news-card__body { padding: 20px; }
  .news-card--list { gap: 14px; padding: 16px 0; }
  .news-card--list .news-card__cover { flex: 0 0 38%; }
  .news-card--list .news-card__title { font-size: 14px; line-height: 1.45; }

  /* 同場加映 — 3 col → 1 col, card 自然 hug */
  .activity-grid { grid-template-columns: 1fr; gap: 16px; }
  .activity-card { min-height: auto; padding: 24px; }

  /* Footer — 5 col → 1 col stack */
  .site-footer { padding: 56px 0 24px; }
  .site-footer__top { grid-template-columns: 1fr; gap: 28px; }
  .site-footer__brand { max-width: 100%; }
  .site-footer__divider { margin: 32px 0 20px; }
  .site-footer__bottom-row {
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
  }
  .site-footer__notice { max-width: 100%; }
}

/* ─────────────────────────────────────────
   FILMS RAIL — 第三章·電影庫預覽
   橫向 rail with 3 tabs (最新影片 / 現正熱播 / Ztor. 精選).
   Each panel = a horizontally scrollable track of .film-card.
   Nav arrows reuse hero-carousel glass style: hover-to-show.
   ───────────────────────────────────────── */

.films-rail {
  position: relative;
}

/* Tabs row — sits between section header and the rail */
.films-rail__tabs {
  display: flex;
  gap: var(--space-1);
  margin-top: calc(var(--space-16) * -1 + var(--space-4));
  margin-bottom: var(--space-8);
  border-bottom: 1px solid var(--border-subtle);
}

.films-rail__tab {
  position: relative;
  padding: 12px 18px;
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  color: var(--text-tertiary);
  font-family: var(--font-cjk-text);
  font-size: 14px;
  font-weight: var(--fw-medium);
  cursor: pointer;
  transition: color 200ms ease, border-color 200ms ease;
}

.films-rail__tab:hover { color: var(--text-secondary); }

.films-rail__tab[aria-selected="true"] {
  color: var(--yellow-500);
  border-bottom-color: var(--yellow-500);
}

/* Panel — only the selected one renders the track. Fade-in on switch
   so tab activations feel responsive. */
.films-rail__panel { display: none; }
.films-rail__panel.is-active {
  display: block;
  animation: filmsRailFade 260ms ease both;
}

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

/* Track — horizontal scroll container, snap to start.
   --rail-cols controls how many cards perfectly fill the row at the
   default desktop width. Card width uses calc() so the row always
   spans flush from the section's left edge to the right.
   Modifier .films-rail__track--ranked drops cols to 5 (Top 5 shelf). */
.films-rail__track {
  --rail-cols: 6;
  --rail-gap: 20px;
  display: flex;
  gap: var(--rail-gap);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none; /* Firefox */
  padding: 4px 2px 16px;
  margin: -4px -2px 0;   /* offset padding so cards align with section edges */
}
.films-rail__track::-webkit-scrollbar { display: none; }

.films-rail__track--ranked { --rail-cols: 5; }

/* Nav arrows — same glass + hover-to-show as hero carousel.
   Vertical position is set dynamically via JS to align with the poster's
   vertical center (the active panel's first card). The .is-enabled class
   is toggled by JS based on whether scrolling further in that direction
   is still possible — only enabled buttons reveal on hover. */
.films-rail__nav {
  position: absolute;
  /* `top` is set inline by JS once the rail mounts / on resize / on tab change. */
  transform: translateY(-50%);
  width: 44px;
  height: 44px;
  border-radius: var(--radius-pill);
  border: none;
  padding: 0;
  cursor: pointer;
  z-index: 3;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  background: linear-gradient(0deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 0.18) 2.45%,
    rgba(255, 255, 255, 0) 126.14%);
  box-shadow:
    rgba(255, 255, 255, 0.9) 1.1px 2.2px 0.5px -1.8px inset,
    rgba(255, 255, 255, 0.9) -1px -2.2px 0.5px -1.8px inset,
    rgba(0, 0, 0, 0.10) 2px 3px 2px 0 inset;
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  transition: opacity 250ms ease, background 200ms ease;
}

.films-rail:hover .films-rail__nav.is-enabled,
.films-rail__nav.is-enabled:focus-visible {
  opacity: 1;
  pointer-events: auto;
}

.films-rail__nav.is-enabled:hover {
  background: linear-gradient(0deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 0.30) 2.45%,
    rgba(255, 255, 255, 0) 126.14%);
}

.films-rail__nav--prev { left: -22px; }
.films-rail__nav--next { right: -22px; }

.films-rail__nav img {
  width: 22px;
  height: 22px;
  display: block;
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.5));
}

/* ─────────────────────────────────────────
   FILM CARD
   2:3 poster + popcorn-price badge (br) + body (title / meta / score)
   Hover: poster lifts + bottom darken overlay reveals.
   Variant .film-card--ranked: huge outlined number behind the poster (Top 5).
   ───────────────────────────────────────── */

/* Card width is computed from --rail-cols / --rail-gap on the track,
   so 6 cards fill the row flush at 1440 wide (or 5 in the ranked panel). */
.film-card {
  --card-w: calc(
    (100% - (var(--rail-cols) - 1) * var(--rail-gap)) / var(--rail-cols)
  );
  position: relative;
  flex: 0 0 var(--card-w);
  width: var(--card-w);
  scroll-snap-align: start;
  overflow: hidden; /* contain large .film-card__rank font (180px) */
  display: flex;
  flex-direction: column;
  text-decoration: none;
  color: inherit;
}

.film-card__poster {
  position: relative;
  aspect-ratio: 2 / 3;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--bg-tertiary);
  border: 1px solid var(--border-subtle);
  transition: transform 350ms ease, border-color 250ms ease;
  z-index: 1; /* above ranked number */
}

.film-card:hover .film-card__poster {
  transform: translateY(-4px);
  border-color: var(--border-default);
}

.film-card__poster img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Hover darken — reveals price badge and stays subtle on idle */
.film-card__poster::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg,
    rgba(0, 0, 0, 0) 55%,
    rgba(0, 0, 0, 0.55) 100%);
  opacity: 0.6;
  transition: opacity 250ms ease;
  pointer-events: none;
}

.film-card:hover .film-card__poster::after { opacity: 1; }

/* Popcorn price — bottom-right glass pill (mirrors 1.0) */
.film-card__price {
  position: absolute;
  right: 8px;
  bottom: 8px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px 4px 6px;
  border-radius: var(--radius-pill);
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  font-family: var(--font-cjk-text);
  font-size: 12px;
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
  z-index: 2;
}

.film-card__price-icon {
  width: 14px;
  height: 14px;
  display: inline-block;
  background-color: var(--neutral-white);
  -webkit-mask: url('assets/icons/popcorn_single.svg') center / contain no-repeat;
          mask: url('assets/icons/popcorn_single.svg') center / contain no-repeat;
}

/* Body — title + meta row (year/tag on left, score on right) */
.film-card__body {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px 4px 0;
}

.film-card__title {
  font-family: var(--font-cjk-display);
  font-weight: var(--fw-bold);
  font-size: 15px;
  line-height: 1.35;
  color: var(--text-primary);
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.film-card__meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: 28px; /* match score ring height to keep rail rhythm */
}

.film-card__meta-text {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-cjk-text);
  font-size: 11px;
  color: var(--text-tertiary);
  min-width: 0;
}

.film-card__meta-tag {
  display: inline-block;
  padding: 1px 6px;
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-secondary);
  white-space: nowrap;
  flex-shrink: 0;
}

/* Ranked variant — outlined number sits behind the poster on the left.
   Width is inherited from --rail-cols (5 in the ranked panel); the
   padding-left reserves a slot for the digit so part of it stays
   visible to the left of the poster. Sized to also fit double-digit
   "10" — the leading "1" reads, the "0" tucks behind the poster. */
.film-card--ranked {
  padding-left: 56px;
}

.film-card__rank {
  position: absolute;
  left: -8px;
  bottom: 28px;       /* aligns near the poster bottom */
  font-family: var(--font-cjk-display);
  font-weight: var(--fw-black);
  font-size: 240px;
  line-height: 0.85;
  color: transparent;
  -webkit-text-stroke: 2px rgba(255, 255, 255, 0.22);
          text-stroke: 2px rgba(255, 255, 255, 0.22);
  pointer-events: none;
  user-select: none;
  z-index: 0;
  letter-spacing: -0.05em;
}

/* ─────────────────────────────────────────
   ZTOR SCORE — 評分 ring
   Conic-gradient progress ring, central numeric value.
   Tier modifiers paint the ring color:
     --gold   → 85–100  (Ztor brand yellow)
     --green  → 70–84   (success)
     --orange → 50–69   (warning)
     --red    → 0–49    (error)
     --empty  → 評分不足 3 筆 → "--"
   Usage: <span class="ztor-score ztor-score--green" style="--score:77">
            <span class="ztor-score__value">77</span>
          </span>
   ───────────────────────────────────────── */

.ztor-score {
  --score: 0;
  --ring-color: var(--neutral-500);
  --track-color: rgba(255, 255, 255, 0.10);
  --inner-bg: var(--bg-primary);   /* match the section bg behind the ring */
  position: relative;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background:
    conic-gradient(var(--ring-color) calc(var(--score) * 1%), var(--track-color) 0);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.ztor-score::before {
  content: '';
  position: absolute;
  inset: 2px;
  background: var(--inner-bg);
  border-radius: 50%;
}

.ztor-score__value {
  position: relative;
  z-index: 1;
  font-family: var(--font-latin);
  font-size: 11px;
  font-weight: var(--fw-bold);
  line-height: 1;
  color: var(--text-primary);
}

.ztor-score--gold   { --ring-color: var(--yellow-500); }
.ztor-score--green  { --ring-color: var(--success-500); }
.ztor-score--orange { --ring-color: var(--warning-500); }
.ztor-score--red    { --ring-color: var(--error-500); }

.ztor-score--empty {
  --score: 100;
  --ring-color: rgba(255, 255, 255, 0.10);
}
.ztor-score--empty .ztor-score__value {
  color: var(--text-disabled);
  font-size: 12px;
  letter-spacing: -0.05em;
}

/* When score sits on a surface bg (neutral-800), match the inner cutout */
.section-bg-surface .ztor-score { --inner-bg: var(--bg-secondary); }

/* ─────────────────────────────────────────
   COMMUNITY — 第四章·社群
   3-col grid of article preview cards. Each card pairs a 1920×1024
   landscape cover with a short headline/desc and an author meta row.
   Image spec is fixed (no portrait variants on the homepage for now);
   later, post-detail / community list pages can introduce portrait
   covers + blur-fill, or a true masonry layout.
   ───────────────────────────────────────── */

.community-grid {
  display: grid;
  /* Self-collapsing 3→2→1. 300px floor preserves cover + 2-line title. */
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 24px;
}

/* "See more" CTA — hidden by default, shown only at <=768px via the mobile
   media query below. Mirrors the section-link visual but full-width. */
.community-grid__more-mobile {
  display: none;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 18px 24px;
  margin-top: 4px;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  color: var(--text-primary);
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  background: transparent;
  transition: border-color 200ms ease, background 200ms ease;
}
.community-grid__more-mobile:hover { border-color: var(--border-strong); background: rgba(255,255,255,0.03); }
.community-grid__more-mobile::after { content: "→"; transition: transform 200ms ease; }
.community-grid__more-mobile:hover::after { transform: translateX(2px); }

.community-card {
  display: flex;
  flex-direction: column;
  background: var(--bg-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  transition: transform 250ms ease, border-color 250ms ease;
}

.community-card:hover {
  transform: translateY(-4px);
  border-color: var(--border-default);
}

/* Cover image — 1920/1024 (≈ 15:8). Matches 1.0 landscape post spec. */
.community-card__cover {
  position: relative;
  aspect-ratio: 1920 / 1024;
  overflow: hidden;
  background: var(--bg-tertiary);
}

.community-card__cover img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 500ms ease;
}

.community-card:hover .community-card__cover img {
  transform: scale(1.03);
}

/* Header — author chip left, date right. Sits between the cover and body,
   inherits the social-post pattern from 1.0 (avatar + name + date). */
.community-card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 22px 0;
}

.community-card__date {
  font-family: var(--font-cjk-text);
  font-size: 12px;
  color: var(--text-tertiary);
  white-space: nowrap;
  flex-shrink: 0;
}

/* Body — title → desc → optional chips → meta row (stats + bookmark). */
.community-card__body {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 22px 18px;
  flex: 1;
}

/* Topic chips — subdued, low-contrast pills that surface campaign /
   programme affiliations (e.g. AI 創作 posts pointing to specific
   contests). Designed to be readable but not compete with title/author. */
.community-card__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 2px;
}

.community-card__chip {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border-subtle);
  background: rgba(255, 255, 255, 0.03);
  color: var(--text-tertiary);
  font-family: var(--font-cjk-text);
  font-size: 11px;
  font-weight: var(--fw-regular);
}

.community-card__title {
  font-family: var(--font-cjk-display);
  font-weight: var(--fw-bold);
  font-size: 19px;
  line-height: 1.4;
  color: var(--text-primary);
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  transition: color 200ms ease;
}

.community-card:hover .community-card__title {
  color: var(--yellow-500);
}

.community-card__desc {
  font-family: var(--font-cjk-text);
  font-weight: var(--fw-light);
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-secondary);
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Meta row — stats cluster left, bookmark action right. Pinned to the
   bottom of the body via margin-top: auto so action rows align across
   cards in the same grid row regardless of title/desc/chip length. */
.community-card__meta {
  margin-top: auto;
  padding-top: 6px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.community-card__author {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  font-family: var(--font-cjk-text);
  font-size: 12px;
  color: var(--text-tertiary);
}

/* Avatar — small circular user image. Falls back to a neutral tile bg
   while the image loads. */
.community-card__avatar {
  width: 28px;
  height: 28px;
  border-radius: var(--radius-pill);
  background: var(--bg-tertiary);
  object-fit: cover;
  display: block;
  flex-shrink: 0;
}

.community-card__author-text {
  font-family: var(--font-cjk-text);
  font-size: 12px;
  color: var(--text-tertiary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.community-card__author-name {
  color: var(--text-secondary);
  font-weight: var(--fw-medium);
}

/* Stats cluster — heart/comment counts + bookmark + share icons. */
.community-card__stats {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  color: var(--text-tertiary);
}

.community-card__stat {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: var(--font-cjk-text);
  font-size: 12px;
  color: var(--text-tertiary);
}

.community-card__stat-icon,
.community-card__action-icon {
  width: 20px;
  height: 20px;
  display: inline-block;
  background-color: currentColor;
  flex-shrink: 0;
}

.community-card__stat-icon--heart   { -webkit-mask: url('assets/icons/heart.svg')   center / contain no-repeat;
                                               mask: url('assets/icons/heart.svg')   center / contain no-repeat; }
.community-card__stat-icon--comment { -webkit-mask: url('assets/icons/comment.svg') center / contain no-repeat;
                                               mask: url('assets/icons/comment.svg') center / contain no-repeat; }
.community-card__stat-icon--share   { -webkit-mask: url('assets/icons/share.svg')   center / contain no-repeat;
                                               mask: url('assets/icons/share.svg')   center / contain no-repeat; }
.community-card__action-icon--bookmark { -webkit-mask: url('assets/icons/bookmark_regular.svg') center / contain no-repeat;
                                                  mask: url('assets/icons/bookmark_regular.svg') center / contain no-repeat; }

/* Active (bookmarked) state — toggle the .is-bookmarked class on the
   button to swap to the filled variant and highlight in brand yellow. */
.community-card__action.is-bookmarked .community-card__action-icon--bookmark {
  -webkit-mask: url('assets/icons/bookmark_active.svg') center / contain no-repeat;
          mask: url('assets/icons/bookmark_active.svg') center / contain no-repeat;
  background-color: var(--yellow-500);
}

/* Action buttons are clickable bare icons — hover lifts contrast. */
.community-card__action {
  background: none;
  border: none;
  padding: 4px;
  margin: -4px;
  cursor: pointer;
  color: var(--text-tertiary);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: color 150ms ease;
}

.community-card__action:hover { color: var(--text-secondary); }

/* ─────────────────────────────────────────
   NEWS — 第五章·新聞與公告
   Magazine layout: 1 hero card (image-led, larger) on the left + 3 list
   cards (horizontal compact, image-left/content-right) stacked on the
   right. No social stats — news is editorial chrome, not user posts.
   Each card carries:  tag (yellow) → title → optional excerpt → meta
   (source · date).
   ───────────────────────────────────────── */

.news-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
}

.news-card {
  display: flex;
  text-decoration: none;
  color: inherit;
  background: var(--bg-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: transform 250ms ease, border-color 250ms ease;
}

.news-card:hover {
  transform: translateY(-4px);
  border-color: var(--border-default);
}

/* Hero variant — image stacked on top, content below (image-led). */
.news-card--hero {
  flex-direction: column;
}

.news-card--hero .news-card__cover {
  aspect-ratio: 1920 / 1024;
  width: 100%;
}

.news-card--hero .news-card__body {
  padding: 24px 26px 26px;
  gap: 12px;
}

.news-card--hero .news-card__title {
  font-size: 24px;
  line-height: 1.35;
}

.news-card--hero .news-card__excerpt {
  -webkit-line-clamp: 3;
}

/* List variant — divider-only style, no card chrome. Image left
   (≈ 40% width), content right. Cards stack inside .news-list with
   subtle horizontal dividers between them. */
.news-card--list {
  flex-direction: row;
  align-items: stretch;
  background: transparent;
  border: none;
  border-radius: 0;
  overflow: visible;
  gap: 18px;
  padding: 20px 0;
}

.news-card--list:hover {
  transform: none;
  border-color: transparent;
}

.news-card--list .news-card__cover {
  flex: 0 0 40%;
  aspect-ratio: 1920 / 1024;
  border-radius: var(--radius-md);
  overflow: hidden;
}

.news-card--list .news-card__body {
  flex: 1;
  padding: 4px 0;
  gap: 10px;
  justify-content: center;
}

.news-card--list .news-card__title {
  font-size: 17px;
  line-height: 1.4;
}

/* One-line excerpt under the title for editorial breathing room. */
.news-card--list .news-card__excerpt {
  display: -webkit-box;
  -webkit-line-clamp: 1;
  font-size: 13px;
  line-height: 1.5;
  margin: 0;
}

/* Cover (shared) */
.news-card__cover {
  position: relative;
  overflow: hidden;
  background: var(--bg-tertiary);
}

.news-card__cover img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 500ms ease;
}

.news-card:hover .news-card__cover img { transform: scale(1.03); }

/* Body (shared) */
.news-card__body {
  display: flex;
  flex-direction: column;
  flex: 1;
}

.news-card__tag {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  padding: 4px 12px;
  border-radius: var(--radius-pill);
  background: var(--yellow-500);
  color: var(--yellow-ink);
  font-family: var(--font-cjk-text);
  font-size: 12px;
  font-weight: var(--fw-bold);
  letter-spacing: 0.04em;
}

.news-card__title {
  font-family: var(--font-cjk-display);
  font-weight: var(--fw-bold);
  color: var(--text-primary);
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  transition: color 200ms ease;
}

/* Hover affordance — title turns brand yellow on either hero or list card. */
.news-card:hover .news-card__title {
  color: var(--yellow-500);
}

.news-card__excerpt {
  font-family: var(--font-cjk-text);
  font-weight: var(--fw-light);
  font-size: 14px;
  line-height: 1.65;
  color: var(--text-secondary);
  margin: 0;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.news-card__meta {
  margin-top: auto;
  padding-top: 12px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-cjk-text);
  font-size: 12px;
  color: var(--text-tertiary);
}

.news-card__meta-source { color: var(--text-secondary); font-weight: var(--fw-medium); }

/* Right column wrapper — stacks the 3 list cards with thin dividers in
   between (no card chrome on individual cards). */
.news-list {
  display: flex;
  flex-direction: column;
}

.news-list > .news-card--list:not(:last-child) {
  border-bottom: 1px solid var(--border-subtle);
}

.news-list > .news-card--list:first-child  { padding-top: 0; }
.news-list > .news-card--list:last-child   { padding-bottom: 0; }

/* ─────────────────────────────────────────
   ACTIVITY — 第六章·同場加映
   3-col grid of lightweight feature cards: icon → title → desc → CTA.
   Each card has a subtle yellow ambient glow in the top-right to hint
   at the playful / supplementary tone of this section.
   Variant .activity-card--disabled drops opacity and removes hover lift
   (used for 敬請期待 / coming-soon CTAs).
   ───────────────────────────────────────── */

.activity-grid {
  display: grid;
  /* Self-collapsing 3→2→1. 260px floor — activity cards are simpler. */
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 24px;
}

.activity-card {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 32px;
  min-height: 280px;
  background: var(--bg-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  text-decoration: none;
  color: inherit;
  overflow: hidden;
  transition: transform 250ms ease, border-color 250ms ease;
}

.activity-card:hover {
  transform: translateY(-4px);
  border-color: var(--border-default);
}

/* Yellow ambient glow at top-right — playful tone marker.
   Circle center is anchored exactly on the card's top-right corner so
   only the bottom-left quadrant of the circle bleeds into the card. */
.activity-card::before {
  content: '';
  position: absolute;
  top: -130px;
  right: -130px;
  width: 260px;
  height: 260px;
  background: radial-gradient(circle,
    rgba(255, 230, 0, 0.20) 0%,
    rgba(255, 230, 0, 0.07) 30%,
    transparent 70%);
  pointer-events: none;
  z-index: 0;
}

.activity-card > * { position: relative; z-index: 1; }

/* Icon chip — outline icon inside a yellow-tinted rounded square. */
.activity-card__icon {
  width: 56px;
  height: 56px;
  border-radius: var(--radius-md);
  background: rgba(255, 230, 0, 0.08);
  border: 1px solid rgba(255, 230, 0, 0.22);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--yellow-500);
  margin-bottom: 24px;
}

/* Glass variant — chip keeps the base yellow tint as the "halo" behind
   the icon; the class is kept on the markup as a hook for future
   chip-level glass effects (e.g. backdrop-filter blur, refraction). */

.activity-card__icon-img {
  width: 32px;
  height: 32px;
  display: inline-block;
}

.activity-card__title {
  font-family: var(--font-cjk-display);
  font-weight: var(--fw-bold);
  font-size: 22px;
  line-height: 1.4;
  color: var(--text-primary);
  margin: 0 0 12px;
}

.activity-card__desc {
  font-family: var(--font-cjk-text);
  font-weight: var(--fw-regular);
  font-size: 14px;
  line-height: 1.65;
  color: var(--text-secondary);
  margin: 0;
  flex: 1;
}

.activity-card__cta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 24px;
  font-family: var(--font-cjk-text);
  font-size: 14px;
  font-weight: var(--fw-medium);
  color: var(--yellow-500);
  transition: gap 200ms ease;
}

.activity-card:hover .activity-card__cta { gap: 10px; }

.activity-card__cta-arrow {
  width: 14px;
  height: 14px;
  display: inline-block;
  background-color: currentColor;
  -webkit-mask: url('assets/icons/arrow_right.svg') center / contain no-repeat;
          mask: url('assets/icons/arrow_right.svg') center / contain no-repeat;
}

/* Disabled / coming-soon CTA — muted text, no arrow, no hover gap shift. */
.activity-card__cta--disabled {
  color: var(--text-disabled);
}

.activity-card--disabled {
  cursor: default;
  opacity: 0.55;
}

.activity-card--disabled:hover {
  transform: none;
  border-color: var(--border-subtle);
}

.activity-card--disabled:hover .activity-card__cta { gap: 6px; }

/* Disabled glow — swap the yellow ambient for a neutral one so the
   dimmed card doesn't compete tonally with the active siblings. */
.activity-card--disabled::before {
  background: radial-gradient(circle,
    rgba(255, 255, 255, 0.10) 0%,
    rgba(255, 255, 255, 0.03) 30%,
    transparent 70%);
}

/* ─────────────────────────────────────────
   SITE FOOTER
   5-col layout: brand block (logo + tagline + email + social) on the
   left, 4 nav columns on the right. Below the grid: a divider, then
   a chain of legal links, then the © row, then a small legal notice.
   ───────────────────────────────────────── */

.site-footer {
  background: var(--bg-primary);
  padding: clamp(64px, 8vw, 96px) 0 32px;
  border-top: 1px solid var(--border-subtle);
  color: var(--text-secondary);
}

.site-footer__top {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr 1fr;
  gap: 48px;
}

/* Brand block (col 1) — logo + tagline + body + email + socials. */
.site-footer__brand {
  display: flex;
  flex-direction: column;
  gap: 18px;
  max-width: 360px;
}

.site-footer__logo {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  line-height: 1;
  text-decoration: none;
  height: 40px;
}

.site-footer__logo-img {
  height: 40px;
  width: auto;
  display: block;
}

.site-footer__tagline {
  font-family: var(--font-cjk-display);
  font-weight: var(--fw-bold);
  font-size: 18px;
  line-height: 1.5;
  color: var(--text-primary);
  margin: 0;
}

.site-footer__desc {
  font-family: var(--font-cjk-text);
  font-weight: var(--fw-regular);
  font-size: 13px;
  line-height: 1.75;
  color: var(--text-tertiary);
  margin: 0;
}

.site-footer__email {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-cjk-text);
  font-size: 13px;
  color: var(--text-secondary);
  text-decoration: none;
  transition: color 150ms ease;
}

.site-footer__email:hover { color: var(--yellow-500); }

/* Contact row — socials + email side by side on a single row. */
.site-footer__contact {
  display: flex;
  align-items: center;
  gap: 20px;
  margin-top: 4px;
}

.site-footer__social {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.site-footer__social-link {
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border-subtle);
  color: var(--text-secondary);
  transition: color 150ms ease, border-color 150ms ease, background 150ms ease;
}

.site-footer__social-link:hover {
  color: var(--yellow-500);
  border-color: rgba(255, 230, 0, 0.35);
  background: rgba(255, 230, 0, 0.06);
}

.site-footer__social-icon {
  width: 22px;
  height: 22px;
  display: inline-block;
  background-color: currentColor;
}

.site-footer__social-icon--instagram { -webkit-mask: url('assets/icons/ig.svg')     center / contain no-repeat;
                                                mask: url('assets/icons/ig.svg')     center / contain no-repeat; }
.site-footer__social-icon--threads   { -webkit-mask: url('assets/icons/thread.svg') center / contain no-repeat;
                                                mask: url('assets/icons/thread.svg') center / contain no-repeat; }

/* Nav columns (cols 2–5). */
.site-footer__nav {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.site-footer__nav-title {
  font-family: var(--font-cjk-text);
  font-size: 13px;
  font-weight: var(--fw-semibold);
  letter-spacing: 0.04em;
  color: var(--yellow-500);
  margin: 0 0 6px;
}

.site-footer__nav-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.site-footer__nav-link {
  font-family: var(--font-cjk-text);
  font-size: 14px;
  color: var(--text-secondary);
  text-decoration: none;
  transition: color 150ms ease;
}

.site-footer__nav-link:hover { color: var(--text-primary); }

/* Bottom blocks — divider then 條款 chain → © row → legal notice. */
.site-footer__divider {
  height: 1px;
  background: var(--border-subtle);
  margin: 56px 0 24px;
}

.site-footer__legal-chain {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 18px;
  font-family: var(--font-cjk-text);
  font-size: 12px;
  color: var(--text-tertiary);
}

.site-footer__legal-chain a {
  color: inherit;
  transition: color 150ms ease;
}

.site-footer__legal-chain a:hover { color: var(--text-secondary); }

.site-footer__bottom-row {
  margin-top: 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  font-family: var(--font-cjk-text);
  font-size: 12px;
  color: var(--text-tertiary);
}

.site-footer__copy {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.site-footer__locale {
  display: inline-flex;
  align-items: center;
  gap: 14px;
}

.site-footer__locale a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: inherit;
  text-decoration: none;
  transition: color 150ms ease;
}

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

.site-footer__locale-icon {
  width: 14px;
  height: 14px;
  display: inline-block;
  background-color: currentColor;
  -webkit-mask: url('assets/icons/language.svg') center / contain no-repeat;
          mask: url('assets/icons/language.svg') center / contain no-repeat;
}

/* Legal notice — sits on the right of the © row. Matches the copy's
   12px to keep both sides of the row visually balanced. max-width
   keeps it a clean block instead of stretching across the row. */
.site-footer__notice {
  margin: 0;
  font-family: var(--font-cjk-text);
  font-size: 12px;
  line-height: 1.65;
  color: var(--text-tertiary);
  max-width: 640px;
}
