/* ==========================================================================
   xBrat Group — design system
   Palette taken from xBratAI-Technologies-Limited-Guidelines.pdf (Logo Colour
   Reference). Dark ground, gold as the primary accent, red as the secondary.
   ========================================================================== */

:root {
  /* --- Brand colours (guidelines, page 4) --- */
  --gold-start: #FBF395;
  --gold-end:   #C89336;
  --red-start:  #CC2027;
  --red-end:    #930E18;
  --peach:      #E5B294;
  --brown:      #614F47;
  --ink:        #010300;   /* "Dark Grey" in the guidelines, effectively black */
  --white:      #FFFFFF;

  /* --- Derived surfaces --- */
  --bg:          #010300;
  --bg-raised:   #0B0B0A;
  --bg-card:     #121110;
  --bg-inset:    #191715;
  --hairline:    rgba(255, 255, 255, 0.09);
  --hairline-strong: rgba(255, 255, 255, 0.16);

  /* --- Text --- */
  --text:        #FFFFFF;
  --text-muted:  rgba(255, 255, 255, 0.62);
  /* 0.50 is the floor that still clears WCAG AA (4.5:1) on this ground; --text-faint
     is used on 12–13px copy (dates, captions, footer legal), so it cannot go lower. */
  --text-faint:  rgba(255, 255, 255, 0.50);

  /* --- Gradients --- */
  --grad-gold: linear-gradient(102deg, var(--gold-start) 0%, var(--gold-end) 100%);
  --grad-red:  linear-gradient(102deg, var(--red-start) 0%, var(--red-end) 100%);
  --grad-duo:  linear-gradient(102deg, var(--gold-start) 0%, var(--gold-end) 48%, var(--red-start) 100%);

  /* --- Rhythm --- */
  --radius:    14px;
  --radius-lg: 20px;
  --section-y: clamp(72px, 10vw, 132px);
}

/* ===== RESET & BASE ===== */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
  scroll-behavior: smooth;
  /* Sticky header is 86px; keep anchored sections clear of it. */
  scroll-padding-top: 106px;
}

body {
  font-family: 'Inter', system-ui, -apple-system, 'Noto Sans TC', 'PingFang HK',
               'Microsoft JhengHei', sans-serif;
  background-color: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  min-height: 100vh;
  overflow-x: hidden;
}

/* Traditional Chinese runs slightly looser and never wants the tight tracking
   that the Latin display sizes rely on. */
html[lang="zh-Hant"] body { line-height: 1.75; }
html[lang="zh-Hant"] .heading-xl,
html[lang="zh-Hant"] .heading-lg,
html[lang="zh-Hant"] .heading-md { letter-spacing: -0.01em; line-height: 1.25; }
html[lang="zh-Hant"] .text-label { letter-spacing: 0.06em; }

a { text-decoration: none; color: inherit; }
img, svg { max-width: 100%; }
img { height: auto; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }

:focus-visible {
  outline: 2px solid var(--gold-start);
  outline-offset: 3px;
  border-radius: 4px;
}

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; top: -100px; left: 16px; z-index: 200;
  background: var(--grad-gold); color: var(--ink);
  padding: 12px 20px; border-radius: 0 0 10px 10px; font-weight: 700;
}
.skip-link:focus { top: 0; }

/* ===== LAYOUT ===== */
.container { max-width: 1400px; margin: 0 auto; padding: 0 24px; }
@media (min-width: 768px)  { .container { padding: 0 40px; } }
@media (min-width: 1200px) { .container { padding: 0 64px; } }

section { padding: var(--section-y) 0; }

/* ===== TYPOGRAPHY ===== */
.heading-xl {
  font-weight: 800;
  font-size: clamp(38px, 7.2vw, 78px);
  line-height: 1.03;
  letter-spacing: -0.04em;
}
.heading-lg {
  font-weight: 800;
  font-size: clamp(30px, 4.6vw, 52px);
  line-height: 1.06;
  letter-spacing: -0.035em;
}
.heading-md {
  font-weight: 700;
  font-size: clamp(20px, 2.4vw, 25px);
  line-height: 1.22;
  letter-spacing: -0.025em;
}
.heading-sm { font-weight: 700; font-size: 17px; line-height: 1.35; letter-spacing: -0.015em; }

.text-body-lg { font-size: clamp(16px, 1.6vw, 19px); line-height: 1.65; }
.text-body    { font-size: 16px; line-height: 1.65; }
.text-sm      { font-size: 14.5px; line-height: 1.65; }
.text-xs      { font-size: 13px; line-height: 1.55; }

.text-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.text-muted { color: var(--text-muted); }
.text-faint { color: var(--text-faint); }

/* The gold wash used on the second line of most headings. */
.gild {
  background: var(--grad-gold);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  /* Descenders get clipped without a touch of padding on some renderers. */
  padding-bottom: 0.04em;
}
.label-gold { color: var(--gold-end); }
/* Brand red (#CC2027) is only 3.75:1 on the dark ground, which fails AA at this
   label's 11px. This is the brand red lifted just far enough to clear 4.5:1. */
.label-red  { color: #E2434A; }

/* ===== BUTTONS ===== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 14px 24px;
  border-radius: 10px;
  font-weight: 700;
  font-size: 14.5px;
  letter-spacing: -0.01em;
  transition: transform 0.18s ease, box-shadow 0.18s ease, background 0.18s ease, border-color 0.18s ease;
  cursor: pointer;
  white-space: nowrap;
}
.btn svg { flex-shrink: 0; }

.btn-gold {
  background: var(--grad-gold);
  color: var(--ink);
  box-shadow: 0 6px 22px rgba(200, 147, 54, 0.24);
}
.btn-gold:hover { transform: translateY(-2px); box-shadow: 0 10px 30px rgba(200, 147, 54, 0.34); }

.btn-red {
  background: var(--grad-red);
  color: var(--white);
  box-shadow: 0 6px 22px rgba(204, 32, 39, 0.26);
}
.btn-red:hover { transform: translateY(-2px); box-shadow: 0 10px 30px rgba(204, 32, 39, 0.36); }

.btn-outline {
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--hairline-strong);
  color: var(--white);
}
.btn-outline:hover { border-color: var(--gold-end); background: rgba(200, 147, 54, 0.08); }

.btn-full { width: 100%; justify-content: space-between; }
.btn-sm { padding: 10px 18px; font-size: 13.5px; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .btn:hover { transform: none; }
  /* The hero slider stops advancing on its own (see app.js); the dots still
     work, so cut the crossfade to a straight swap. */
  .hero-slide { transition: none; }
}

/* ===== HEADER ===== */
.header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(1, 3, 0, 0.82);
  backdrop-filter: saturate(160%) blur(14px);
  -webkit-backdrop-filter: saturate(160%) blur(14px);
  border-bottom: 1px solid var(--hairline);
}
.header-inner {
  display: flex;
  align-items: center;
  gap: 20px;
  height: 86px;
}
.header-logo { display: flex; align-items: center; flex-shrink: 0; }
.header-logo img { height: 46px; width: auto; display: block; }
@media (min-width: 980px) { .header-logo img { height: 54px; } }

.header-nav {
  display: none;
  align-items: center;
  gap: 30px;
  margin-left: 12px;
}
.header-nav a {
  font-size: 14.5px;
  font-weight: 500;
  color: var(--text-muted);
  transition: color 0.18s;
}
.header-nav a:hover { color: var(--white); }

.header-actions { display: flex; align-items: center; gap: 12px; margin-left: auto; }

/* Language switcher */
.lang-switch {
  display: inline-flex;
  align-items: center;
  padding: 3px;
  gap: 2px;
  background: rgba(255, 255, 255, 0.055);
  border: 1px solid var(--hairline);
  border-radius: 9px;
}
.lang-switch a {
  padding: 6px 12px;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 700;
  color: var(--text-faint);
  transition: color 0.18s, background 0.18s;
  line-height: 1.2;
}
.lang-switch a:hover { color: var(--white); }
.lang-switch a[aria-current="true"] {
  background: var(--grad-gold);
  color: var(--ink);
}

.menu-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px; height: 42px;
  border: 1px solid var(--hairline);
  border-radius: 9px;
  color: var(--white);
}
.header-cta { display: none; }

@media (min-width: 980px) {
  .header-nav  { display: flex; }
  .header-cta  { display: inline-flex; }
  .menu-toggle { display: none; }
}

/* Mobile drawer */
.mobile-nav {
  display: none;
  border-top: 1px solid var(--hairline);
  background: var(--bg-raised);
  padding: 16px 0 24px;
}
.mobile-nav.is-open { display: block; }
.mobile-nav a {
  display: block;
  padding: 13px 0;
  font-size: 16px;
  font-weight: 600;
  border-bottom: 1px solid var(--hairline);
}
.mobile-nav .btn { margin-top: 18px; width: 100%; }
@media (min-width: 980px) { .mobile-nav { display: none !important; } }

/* ===== HERO ===== */
.hero {
  position: relative;
  padding: clamp(56px, 8vw, 104px) 0 0;
  overflow: hidden;
}
/* Two soft pools of brand colour behind the hero, gold left, red right. */
.hero::before,
.hero::after {
  content: '';
  position: absolute;
  border-radius: 50%;
  filter: blur(90px);
  pointer-events: none;
  z-index: 0;
}
.hero::before {
  width: 620px; height: 620px;
  top: -280px; left: -180px;
  background: radial-gradient(circle, rgba(200, 147, 54, 0.30) 0%, transparent 68%);
}
.hero::after {
  width: 560px; height: 560px;
  top: -160px; right: -220px;
  background: radial-gradient(circle, rgba(204, 32, 39, 0.26) 0%, transparent 68%);
}
.hero > * { position: relative; z-index: 1; }

.hero-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 48px;
  align-items: center;
}
@media (min-width: 1000px) {
  .hero-grid { grid-template-columns: 1.05fr 0.95fr; gap: 64px; }
}

.hero-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 7px 14px 7px 10px;
  border: 1px solid var(--hairline-strong);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.035);
  margin-bottom: 26px;
}
.hero-eyebrow .dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--grad-gold);
  box-shadow: 0 0 0 3px rgba(200, 147, 54, 0.18);
}

.hero h1 { margin-bottom: 24px; }
/* From 1000px the hero splits into two columns, so the text column halves to
   ~449px at the exact width the global .heading-xl clamp reaches 72px. That was
   survivable for the old, shorter headline; the current one is 30 characters
   plus a 19-character gilded phrase, and at 72px the gold breaks across two
   lines — which reads as a mistake, because the <br /> already promised the
   gold its own line. Sized here against the column rather than the viewport so
   the gilded phrase always fits on one line. Do not raise these numbers without
   re-measuring: the longest unbreakable run is the whole gild span. */
@media (min-width: 1000px) {
  .hero h1 { font-size: clamp(46px, 4.5vw, 65px); }
}
.hero-sub { color: var(--text-muted); max-width: 560px; }
.hero-ctas { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 34px; }

.hero-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin-top: 48px;
  padding-top: 32px;
  border-top: 1px solid var(--hairline);
  max-width: 520px;
}
.hero-stat-value {
  font-size: clamp(26px, 3.4vw, 34px);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.1;
  background: var(--grad-gold);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.hero-stat-label { font-size: 12.5px; color: var(--text-faint); margin-top: 6px; }

/* Hero media panel. Holds a placeholder until the real artwork lands; a
   replacement of any reasonable aspect drops in without touching this. */
.hero-media {
  position: relative;
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--bg-card);
  aspect-ratio: 4 / 3;
}
/* Slides are stacked and crossfaded rather than translated, so the frame stays
   put and adding a photo is just another <img> — no width or offset maths. The
   frame's own aspect-ratio holds the height, since every slide is out of flow. */
.hero-slide {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  opacity: 0;
  transition: opacity 900ms ease;
}
/* Without JS the first slide is the only one shown, which is the single hero
   photo the page had before. */
.hero-slide.is-active { opacity: 1; }

/* Bottom-left: the quietest corner of the lead shot, and clear of the expo
   watermark on the right. */
.hero-slider-dots {
  position: absolute;
  left: clamp(12px, 1.6vw, 20px);
  bottom: clamp(12px, 1.6vw, 20px);
  display: flex;
  gap: 9px;
  /* Above the frame's gradient edge (z-index 2), or it would swallow taps. */
  z-index: 3;
}
.hero-dot {
  width: 10px;
  height: 10px;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.5);
  border-radius: 50%;
  background: rgba(1, 3, 0, 0.4);
  cursor: pointer;
  transition: background 200ms ease, border-color 200ms ease, transform 200ms ease;
}
.hero-dot:hover { border-color: rgba(255, 255, 255, 0.9); }
.hero-dot[aria-current="true"] {
  background: var(--grad-gold);
  border-color: transparent;
  transform: scale(1.2);
}
.hero-dot:focus-visible { outline: 2px solid var(--gold-end); outline-offset: 3px; }
.hero-media::after {
  content: '';
  position: absolute; inset: 0;
  border-radius: var(--radius-lg);
  padding: 1px;
  background: var(--grad-duo);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  opacity: 0.5;
  pointer-events: none;
  /* Above the slides, so the frame's gradient edge is never broken by them. */
  z-index: 2;
}

/* ===== TICKER ===== */
.ticker {
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
  background: var(--bg-raised);
  overflow: hidden;
  padding: 16px 0;
  margin-top: clamp(56px, 8vw, 96px);
}
/* The markup carries ONE set of items; app.js clones it until the track is
   wider than the viewport plus a set, then drives the transform. A fixed
   number of copies cannot be seamless: on a wide screen (or in zh-Hant, where
   the phrases are far shorter) two copies are narrower than the viewport, so
   the wrap point drags bare background across the screen.
   Spacing MUST stay on the items (padding), not as `gap` on the track: a gap
   is also inserted between copies, so the wrap lands a gap short and jumps. */
.ticker-track {
  display: flex;
  width: max-content;
  will-change: transform;
}
.ticker-item {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-shrink: 0;
  padding-right: 44px;
}
.ticker-item span {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
  white-space: nowrap;
}
.ticker-item .diamond {
  width: 7px; height: 7px;
  background: var(--grad-gold);
  transform: rotate(45deg);
  flex-shrink: 0;
}

/* ===== SECTION HEADERS ===== */
.section-header { max-width: 720px; margin-bottom: clamp(40px, 5vw, 60px); }
.section-header .text-label { margin-bottom: 14px; display: block; }
.section-header--split {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
  max-width: none;
  align-items: end;
}
@media (min-width: 900px) {
  .section-header--split { grid-template-columns: 1fr auto; gap: 48px; }
  .section-header--split .section-subtitle { max-width: 420px; text-align: right; }
}
.section-subtitle { color: var(--text-muted); }

/* ===== PRODUCT CARDS ===== */
.cards-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
}
@media (min-width: 720px)  { .cards-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1080px) { .cards-grid { grid-template-columns: repeat(3, 1fr); } }

.product-card {
  position: relative;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  background: var(--bg-card);
  overflow: hidden;
  transition: transform 0.22s ease, border-color 0.22s ease;
}
.product-body { display: flex; flex-direction: column; flex: 1; padding: 28px; }
.product-card:hover { transform: translateY(-4px); border-color: var(--hairline-strong); }

/* Accent bar across the top of each card. Must sit above .product-image, which
   is a direct child and therefore carries z-index 1. */
.product-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  z-index: 2;
}
.product-card--gold::before { background: var(--grad-gold); }
.product-card--red::before  { background: var(--grad-red); }
.product-card--duo::before  { background: var(--grad-duo); }

/* Matching wash bleeding up from behind the body copy. */
.product-card::after {
  content: '';
  position: absolute;
  bottom: 0; left: 0; right: 0; height: 280px;
  pointer-events: none;
  opacity: 0.55;
  transition: opacity 0.22s ease;
}
.product-card--gold::after { background: radial-gradient(90% 100% at 50% 100%, rgba(200, 147, 54, 0.22) 0%, transparent 70%); }
.product-card--red::after  { background: radial-gradient(90% 100% at 50% 100%, rgba(204, 32, 39, 0.22) 0%, transparent 70%); }
.product-card--duo::after  { background: radial-gradient(90% 100% at 50% 100%, rgba(229, 178, 148, 0.20) 0%, transparent 70%); }
.product-card:hover::after { opacity: 0.9; }

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

.product-image {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--bg-inset);
  border-bottom: 1px solid var(--hairline);
}
.product-image img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.4s ease;
}
.product-card:hover .product-image img { transform: scale(1.04); }
/* Fade the image into the card body so the join is not a hard edge. */
.product-image::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(to bottom, transparent 45%, rgba(18, 17, 16, 0.85) 100%);
  pointer-events: none;
}

.product-card .text-label { margin-bottom: 10px; display: block; }
.product-card--gold .text-label { color: var(--gold-end); }
.product-card--red  .text-label { color: #E2434A; }
.product-card--duo  .text-label { color: var(--peach); }

.product-card h3 { margin-bottom: 14px; }
.product-card p  { color: var(--text-muted); margin-bottom: 28px; }
.product-card .btn { margin-top: auto; }

/* ===== REGION SECTION ===== */
.region { background: var(--bg-raised); border-top: 1px solid var(--hairline); border-bottom: 1px solid var(--hairline); }

.region-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 48px;
}
@media (min-width: 1000px) {
  .region-grid { grid-template-columns: 0.9fr 1.1fr; gap: 72px; align-items: start; }
}

.region-points { display: grid; grid-template-columns: 1fr; gap: 4px; }
@media (min-width: 640px) { .region-points { grid-template-columns: repeat(2, 1fr); gap: 8px; } }

.region-point {
  padding: 26px 24px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  background: var(--bg-card);
}
.region-point .icon {
  width: 38px; height: 38px;
  border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  background: rgba(200, 147, 54, 0.12);
  color: var(--gold-start);
  margin-bottom: 16px;
}
.region-point h3 { margin-bottom: 8px; }
.region-point p  { color: var(--text-muted); }

/* Market sessions strip */
.sessions {
  margin-top: 40px;
  padding-top: 32px;
  border-top: 1px solid var(--hairline);
}
.sessions .text-label { color: var(--text-faint); display: block; margin-bottom: 18px; }
.sessions-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}
@media (min-width: 560px) { .sessions-grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1000px) { .sessions-grid { grid-template-columns: repeat(6, 1fr); } }

.session {
  padding: 14px 12px;
  border: 1px solid var(--hairline);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.02);
  text-align: center;
}
/* The four Asia-Pacific sessions are the point of the section, so they lead. */
.session--apac { border-color: rgba(200, 147, 54, 0.35); background: rgba(200, 147, 54, 0.06); }
.session-name { font-size: 13.5px; font-weight: 700; }
.session--apac .session-name { color: var(--gold-start); }
.session-time { font-size: 12px; color: var(--text-faint); margin-top: 3px; font-variant-numeric: tabular-nums; }
.sessions-note { font-size: 12.5px; color: var(--text-faint); margin-top: 14px; }

/* ===== ABOUT ===== */
.about-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 44px;
  align-items: center;
}
@media (min-width: 1000px) { .about-grid { grid-template-columns: 1.1fr 0.9fr; gap: 72px; } }

.about-body { color: var(--text-muted); margin: 22px 0 32px; }

.check-list { display: flex; flex-direction: column; gap: 16px; }
.check-item { display: flex; gap: 14px; align-items: flex-start; }
.check-icon {
  width: 22px; height: 22px; flex-shrink: 0;
  border-radius: 50%;
  background: rgba(200, 147, 54, 0.14);
  display: flex; align-items: center; justify-content: center;
  color: var(--gold-start);
  margin-top: 2px;
}
.check-item p { font-size: 15px; line-height: 1.55; }

.book-badge {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: 34px;
  padding: 16px 20px;
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius);
  background: var(--bg-card);
  transition: border-color 0.2s, transform 0.2s;
}
.book-badge:hover { border-color: var(--gold-end); transform: translateY(-2px); }
.book-badge-icon {
  width: 40px; height: 40px; flex-shrink: 0;
  border-radius: 10px;
  background: var(--grad-gold);
  color: var(--ink);
  display: flex; align-items: center; justify-content: center;
}
.book-badge .arrow { margin-left: auto; color: var(--text-faint); flex-shrink: 0; }

/* ===== COLLECTOR CARD =====
   A trading-card treatment of the portrait. Pointer position is written to
   --mx/--my (percent) and --rx/--ry (degrees) by assets/app.js; every visual
   here degrades to a perfectly good static card if that JS never runs. */
.about-portrait {
  display: flex;
  align-items: center;
  justify-content: center;
  perspective: 1400px;
}

/* Stage holds both the CSS card and, once it loads, the WebGL canvas.
   The CSS card is never removed: it is the pre-load and no-WebGL fallback, and
   pcard-3d.js reads the card's text out of it to build the face texture. */
.pcard-stage {
  position: relative;
  width: 100%;
  max-width: 420px;
  aspect-ratio: 5 / 7;
  display: flex;
  align-items: center;
  justify-content: center;
}
.pcard-stage .pcard { width: 100%; max-width: 380px; }

.pcard-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  cursor: grab;
  touch-action: pan-y;   /* let the page still scroll over the card on mobile */
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s ease;
}
.pcard-stage.is-3d .pcard-canvas { pointer-events: auto; }
.pcard-canvas.is-grabbing { cursor: grabbing; }

/* Cross-fade to WebGL once the first frame has rendered. */
.pcard-stage.is-3d .pcard-canvas { opacity: 1; }
.pcard-stage.is-3d .pcard {
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s ease;
}

.pcard {
  --mx: 50%;
  --my: 50%;
  --rx: 0deg;
  --ry: 0deg;
  width: min(100%, 380px);
  aspect-ratio: 5 / 7;
  cursor: pointer;
}

.pcard-inner {
  position: relative;
  width: 100%;
  height: 100%;
  transform: rotateX(var(--rx)) rotateY(var(--ry));
  transform-style: preserve-3d;
  transition: transform 0.4s cubic-bezier(0.23, 1, 0.32, 1);
  border-radius: 20px;
  /* Gold leaf edge, then the card face inset within it. */
  background: var(--grad-gold);
  padding: 3px;
  box-shadow:
    0 26px 60px rgba(0, 0, 0, 0.62),
    0 0 34px rgba(200, 147, 54, 0.20);
}
.pcard:hover .pcard-inner { transition: transform 0.1s linear; }

.pcard-frame {
  position: relative;
  height: 100%;
  border-radius: 17px;
  background:
    radial-gradient(120% 80% at 50% 0%, rgba(204, 32, 39, 0.28) 0%, transparent 60%),
    linear-gradient(170deg, #1A1714 0%, #0A0908 60%, #120D0D 100%);
  padding: 16px 16px 14px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  overflow: hidden;
}

.pcard-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.pcard-name {
  font-size: clamp(16px, 1.7vw, 19px);
  font-weight: 800;
  letter-spacing: -0.02em;
  background: var(--grad-gold);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* Art window */
.pcard-art {
  position: relative;
  flex: 1;
  min-height: 0;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid rgba(200, 147, 54, 0.42);
  background:
    radial-gradient(85% 70% at 50% 108%, rgba(251, 243, 149, 0.30) 0%, transparent 62%),
    radial-gradient(70% 60% at 22% 12%, rgba(204, 32, 39, 0.42) 0%, transparent 66%),
    linear-gradient(165deg, #2A1F16 0%, #150F0C 55%, #251316 100%);
}
.pcard-portrait {
  position: absolute;
  bottom: 0; left: 50%;
  transform: translateX(-50%);
  height: 100%;
  width: auto;
  max-width: none;
  object-fit: contain;
  object-position: bottom center;
  filter: drop-shadow(0 10px 22px rgba(0, 0, 0, 0.55));
}

/* Holographic sheen: a band that sweeps as the card turns.
   Deliberately restrained. `overlay` at a low opacity reads as foil laid over
   the art; `color-dodge` (the obvious choice) blows out skin tones and turns the
   portrait green, which is why it is not used here. */
.pcard-shine {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    115deg,
    transparent 22%,
    rgba(251, 243, 149, 0.30) 35%,
    rgba(229, 178, 148, 0.22) 42%,
    rgba(204, 32, 39, 0.24) 49%,
    rgba(200, 147, 54, 0.28) 56%,
    transparent 70%
  );
  background-size: 240% 240%;
  background-position: var(--mx) var(--my);
  mix-blend-mode: overlay;
  opacity: 0.3;
  transition: opacity 0.3s ease;
  pointer-events: none;
}
/* Soft specular follow, sitting on top of the sheen. */
.pcard-glare {
  position: absolute;
  inset: 0;
  background: radial-gradient(
    circle at var(--mx) var(--my),
    rgba(255, 255, 255, 0.40) 0%,
    rgba(255, 255, 255, 0.10) 24%,
    transparent 56%
  );
  mix-blend-mode: soft-light;
  opacity: 0;
  transition: opacity 0.3s ease;
  pointer-events: none;
}
.pcard:hover .pcard-shine { opacity: 0.55; }
.pcard:hover .pcard-glare { opacity: 1; }

.pcard-role {
  font-size: 12px;
  font-weight: 600;
  color: var(--peach);
  letter-spacing: 0.02em;
}

.pcard-stats {
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 10px 12px;
  border-radius: 9px;
  background: rgba(0, 0, 0, 0.42);
  border: 1px solid rgba(200, 147, 54, 0.22);
}
.pcard-stat { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.pcard-stat-label {
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.52);
  flex-shrink: 0;
}
.pcard-stat-value {
  font-size: 11.5px;
  font-weight: 700;
  color: #fff;
  text-align: right;
  line-height: 1.35;
}

.pcard-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding-top: 10px;
  border-top: 1px solid rgba(255, 255, 255, 0.10);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.05em;
  color: rgba(255, 255, 255, 0.50);
}
.pcard-holo {
  background: var(--grad-gold);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font-size: 12px;
}

/* CJK needs a touch more room in the tight stat rows. */
html[lang="zh-Hant"] .pcard-stat-label { letter-spacing: 0.04em; }
html[lang="zh-Hant"] .pcard-stat-value { font-size: 11px; }

@media (prefers-reduced-motion: reduce) {
  .pcard-inner { transition: none; transform: none !important; }
  .pcard:hover .pcard-shine { opacity: 0.5; }
  .pcard:hover .pcard-glare { opacity: 0; }
}

/* ===== TESTIMONIALS ===== */
.testimonials { border-top: 1px solid var(--hairline); }

.testimonial-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
  align-items: stretch;
}
@media (min-width: 720px)  { .testimonial-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1080px) { .testimonial-grid { grid-template-columns: repeat(3, 1fr); } }

.testimonial-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 30px 28px 26px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  background: var(--bg-card);
  overflow: hidden;
  transition: transform 0.22s ease, border-color 0.22s ease;
}
.testimonial-card:hover { transform: translateY(-4px); border-color: var(--hairline-strong); }

/* Same accent bar the product cards use, so the two grids read as one family. */
.testimonial-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
}
.testimonial-card--gold::before { background: var(--grad-gold); }
.testimonial-card--red::before  { background: var(--grad-red); }
.testimonial-card--duo::before  { background: var(--grad-duo); }

.testimonial-mark {
  font-size: 46px;
  line-height: 0.6;
  font-weight: 800;
  height: 22px;
  background: var(--grad-gold);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.testimonial-quote {
  font-size: 14.5px;
  line-height: 1.7;
  color: var(--text-muted);
  flex: 1;
}

.testimonial-author {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-top: 18px;
  border-top: 1px solid var(--hairline);
}
.testimonial-name { font-size: 14.5px; font-weight: 700; letter-spacing: -0.01em; }
.testimonial-source { font-size: 12.5px; color: var(--text-faint); }

.testimonials-note {
  max-width: 720px;
  margin: 28px auto 0;
  text-align: center;
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--text-faint);
}

/* ===== VIDEOS ===== */
.videos { background: var(--bg-raised); border-top: 1px solid var(--hairline); }
/* Two video blocks now run back to back, so the second one drops the raised
   ground and keeps only the rule, otherwise they merge into one long band. */
.videos--performance { background: transparent; }

.video-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
}
@media (min-width: 720px)  { .video-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1080px) { .video-grid { grid-template-columns: repeat(3, 1fr); } }

.video-card {
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  background: var(--bg-card);
  overflow: hidden;
  transition: transform 0.22s ease, border-color 0.22s ease;
  display: flex;
  flex-direction: column;
}
.video-card:hover { transform: translateY(-4px); border-color: var(--hairline-strong); }

.video-embed {
  position: relative;
  aspect-ratio: 16 / 9;
  background: var(--bg-inset);
  overflow: hidden;
}
.video-thumb { width: 100%; height: 100%; object-fit: cover; display: block; }
.video-embed a {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  background: rgba(1, 3, 0, 0.28);
  transition: background 0.2s;
}
.video-embed a:hover { background: rgba(1, 3, 0, 0.12); }
.play-btn {
  width: 56px; height: 56px; border-radius: 50%;
  background: var(--grad-red);
  color: var(--white);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 6px 22px rgba(204, 32, 39, 0.42);
  transition: transform 0.2s;
  padding-left: 3px;
}
.video-embed a:hover .play-btn { transform: scale(1.08); }

.video-content { padding: 20px; display: flex; flex-direction: column; gap: 8px; flex: 1; }
.video-title { font-size: 15.5px; font-weight: 700; line-height: 1.4; letter-spacing: -0.015em; }
.video-title a { transition: color 0.18s; }
.video-title a:hover { color: var(--gold-start); }
.video-date { font-size: 12.5px; color: var(--text-faint); margin-top: auto; }

.videos-cta { display: flex; justify-content: center; margin-top: 40px; }

.videos-note {
  max-width: 720px;
  margin: 28px auto 0;
  text-align: center;
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--text-faint);
}

/* ===== CLOSING CTA ===== */
.cta-band { text-align: center; }
.cta-inner {
  position: relative;
  padding: clamp(48px, 7vw, 84px) clamp(24px, 5vw, 64px);
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-lg);
  background:
    radial-gradient(90% 130% at 50% 0%, rgba(200, 147, 54, 0.16) 0%, transparent 62%),
    radial-gradient(70% 120% at 50% 100%, rgba(204, 32, 39, 0.14) 0%, transparent 62%),
    var(--bg-card);
  overflow: hidden;
}
.cta-inner h2 { margin-bottom: 18px; }
.cta-inner p { color: var(--text-muted); max-width: 620px; margin: 0 auto; }
.cta-buttons { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; margin-top: 34px; }

/* ===== FOOTER ===== */
.footer {
  border-top: 1px solid var(--hairline);
  background: var(--bg-raised);
  padding: clamp(56px, 7vw, 80px) 0 32px;
}
.footer-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 40px;
  padding-bottom: 44px;
  border-bottom: 1px solid var(--hairline);
}
@media (min-width: 720px)  { .footer-grid { grid-template-columns: 1.6fr repeat(3, 1fr); gap: 32px; } }

.footer-logo img { height: 58px; width: auto; margin-bottom: 20px; }
.footer-tagline { color: var(--gold-end); font-size: 14px; font-weight: 600; }
.footer-entity { color: var(--text-faint); font-size: 13px; margin-top: 16px; line-height: 1.6; }

.footer-col h3 {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 18px;
}
.footer-col ul { list-style: none; display: flex; flex-direction: column; gap: 12px; }
.footer-col a { font-size: 14.5px; color: var(--text-muted); transition: color 0.18s; }
.footer-col a:hover { color: var(--gold-start); }

.footer-risk { padding: 28px 0; border-bottom: 1px solid var(--hairline); }
.footer-risk h3 {
  font-size: 11px; font-weight: 700; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--text-faint); margin-bottom: 10px;
}
.footer-risk p { font-size: 12.5px; line-height: 1.7; color: var(--text-faint); max-width: 1000px; }

.footer-bottom {
  padding-top: 24px;
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: center;
  justify-content: space-between;
}
.footer-bottom p { font-size: 13px; color: var(--text-faint); }

/* ===== CONFLUENCE GUIDE ===== */
/* A long-read page, so it drops the site's wide grid for a single measured
   column. 68ch keeps the line length in the comfortable range for body copy;
   the Chinese build runs a touch wider because Han characters set denser. */
.container--narrow { max-width: 820px; }
html[lang="zh-Hant"] .container--narrow { max-width: 860px; }

.guide { padding: var(--section-y) 0; }

.guide-breadcrumb {
  display: flex; align-items: center; gap: 10px;
  font-size: 13px; color: var(--text-faint);
  margin-bottom: 28px;
}
.guide-breadcrumb a { transition: color 0.18s; }
.guide-breadcrumb a:hover { color: var(--gold-start); }

.guide-header { margin-bottom: 12px; }
.guide-header .text-label { display: block; margin-bottom: 14px; }
.guide-header h1 { text-wrap: balance; }

.guide-section { padding: 0; margin-top: 44px; }
.guide-section h2 { margin-bottom: 20px; text-wrap: balance; }

.guide-subheading {
  font-size: clamp(17px, 2vw, 21px);
  font-weight: 700;
  letter-spacing: -0.02em;
  margin: 32px 0 14px;
}

.guide-section p {
  font-size: clamp(16px, 1.6vw, 18px);
  line-height: 1.72;
  color: var(--text-muted);
  margin-bottom: 18px;
}
/* Lead-ins ("What it measures:") are the scan path through a long page, so they
   stay full-strength white against the muted paragraph around them. */
.guide-section strong { color: var(--text); font-weight: 700; }
.guide-section a:not(.btn) {
  color: var(--gold-start);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: rgba(251, 243, 149, 0.35);
  transition: text-decoration-color 0.18s;
}
.guide-section a:not(.btn):hover { text-decoration-color: var(--gold-start); }

.guide-list { list-style: none; display: grid; gap: 14px; margin: 4px 0 22px; }
.guide-list li {
  position: relative;
  padding-left: 26px;
  font-size: clamp(15.5px, 1.5vw, 17px);
  line-height: 1.7;
  color: var(--text-muted);
}
.guide-list li::before {
  content: "";
  position: absolute; left: 4px; top: 0.72em;
  width: 7px; height: 7px;
  transform: rotate(45deg);
  background: var(--grad-gold);
}

.guide-faq-item {
  border-top: 1px solid var(--hairline);
  padding: 22px 0;
}
.guide-faq-item:last-child { border-bottom: 1px solid var(--hairline); }
.guide-question {
  font-size: clamp(16px, 1.7vw, 19px);
  font-weight: 700;
  letter-spacing: -0.02em;
  margin-bottom: 12px;
}
.guide-faq-item p { margin-bottom: 0; }

.guide-video {
  margin: 32px 0 8px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg-card);
}

.guide-back { margin-top: 52px; padding-top: 28px; border-top: 1px solid var(--hairline); }
.guide-back a {
  font-size: 14px; font-weight: 600; color: var(--gold-start);
  transition: opacity 0.18s;
}
.guide-back a:hover { opacity: 0.75; }

/* ===== PRESS ===== */
/* Reuses the hero ticker's marquee (.ticker-track + [data-ticker]) at a slower
   speed -- these are cards to be read, not a headline strip to be glanced at. */
.press-strip {
  overflow: hidden;
  padding: 4px 0 8px;
  /* Fades the row into the page edges so cards enter and leave rather than
     being clipped mid-word. */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}

.press-card { flex-shrink: 0; width: 300px; padding-right: 20px; }
.press-card > a {
  display: flex;
  flex-direction: column;
  gap: 12px;
  height: 100%;
  padding: 22px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  background: var(--bg-card);
  transition: transform 0.2s, border-color 0.2s;
}
.press-card > a:hover {
  transform: translateY(-4px);
  border-color: var(--hairline-strong);
}

.press-card-brand { height: 26px; display: flex; align-items: center; }
/* Rendered as authored, deliberately. The logos in Storyblok are a curated set
   already drawn white-on-transparent for dark UI -- one is literally named
   finews-white.svg -- so a tinting filter buys nothing on those and destroys the
   ones it does touch: brightness(0) collapses every colour to one tone, which
   fills in a knockout wordmark and renders it as a solid silhouette. CFOtech's
   three-colour mark failed exactly that way. Opacity alone gives the muted row
   without touching the artwork. A logo that reads badly here is a wrong asset in
   Storyblok, and belongs fixed there. */
.press-card-logo {
  max-height: 26px; width: auto;
  opacity: 0.82;
  transition: opacity 0.2s;
}
.press-card > a:hover .press-card-logo { opacity: 1; }
.press-card-wordmark {
  font-size: 15px; font-weight: 800; letter-spacing: -0.02em;
  color: rgba(255, 255, 255, 0.78);
}

.press-card-headline {
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1.45;
  letter-spacing: -0.01em;
  /* Headlines vary from six words to twenty; clamping keeps every card the same
     height so the row does not jitter as it scrolls. */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.press-card-meta { font-size: 12px; color: var(--text-faint); margin-top: auto; }

@media (max-width: 640px) {
  .press-card { width: 260px; }
}
