/* ============================================================
   EVENLY LAB · 均研科技 — Site stylesheet (AUTHORITATIVE)
   Editorial / Swiss-brutalist: warm paper ground, hairline grid
   rules, oversized left-aligned type, mono index numbers, flat
   solid colour blocks (no gradients), square corners.
   Fonts/icons from CDN, degrade to system fonts offline.

   ----------------------------------------------------------------
   ⚠️  MODULARISATION NOTE  ⚠️
   ----------------------------------------------------------------
   This file (styles-main.css) is loaded LAST in <link> order, so it
   overrides duplicate rules from evenly.css. When both files define
   the same selector, THIS file is the canonical version.

   evenluy.css currently contains ~298 duplicate rules (~986 lines)
   that are dead code. Migrate unique rules here and eventually
   retire evenly.css.

   Cascading order in index.html:
     1. evenly.css
     2. experience-mobile.css
     3. hero-cinematic.css
     4. globals.css (just @imports the first three)
     5. styles-main.css  ← loaded last, wins
   ----------------------------------------------------------------
   ============================================================ */

:root{
  /* Base — Evenly Blue */
  --el-blue-50:#EEF4FF;--el-blue-100:#DBE8FE;--el-blue-200:#B6CFFC;--el-blue-300:#8AB1F8;--el-blue-400:#5E8FFA;--el-blue-500:#2B6CF6;--el-blue-600:#1C55DB;--el-blue-700:#173FA0;--el-blue-800:#122E75;--el-blue-900:#0C1F4E;
  /* Accents */
  --el-yellow-100:#FFF1C2;--el-yellow-400:#FFC72E;--el-yellow-500:#F5B301;
  --el-green-100:#DCF5E3;--el-green-500:#23B14D;--el-green-600:#1B8F3D;
  --el-coral-100:#FFE1DA;--el-coral-500:#FF5A3F;--el-coral-600:#E23D24;
  --el-aqua-100:#D5F7F5;--el-aqua-500:#0FC1BC;--el-aqua-aaa:#0A5250;
  /* AAA text colors */
  --el-blue-aaa:#1B4AB5;--el-green-aaa:#0F5A28;--el-amber-aaa:#7A4E00;--el-coral-aaa:#8F1F0D;

  /* ---- Editorial palette ---- */
  --paper:#F4F1E8;        /* warm off-white ground */
  --paper-2:#EAE6D8;      /* slightly deeper panel */
  --ink:#12162A;          /* near-black text / rules */
  --ink-soft:#3A4058;     /* muted body text */
  --navy:#0C1F4E;         /* solid dark blocks */
  --navy-2:#122E75;       /* labels, numbers, accents on paper */
  --accent:#FFC72E;       /* yellow */
  --accent-ink:#4A3600;   /* text on yellow */
  --rule:#12162A;         /* hairline colour */
  --rule-w:1.5px;
  --link:#173FA0;

  /* Type */
  --font-display:'Space Grotesk','Noto Sans TC',sans-serif;
  --font-body:'Atkinson Hyperlegible','Instrument Sans','Noto Sans TC',sans-serif;
  --font-mono:'Space Mono','Noto Sans TC',monospace;
  --text-xs:12px;--text-sm:14px;--text-md:16px;--text-lg:18px;--text-xl:22px;--text-2xl:28px;--text-3xl:36px;--text-4xl:48px;

  /* Layout */
  --container-max:1180px;--gutter:26px;
  --ease-out:cubic-bezier(.16,1,.3,1);
  --dur-fast:120ms;--dur-med:240ms;
}

/* ---------------- Base ---------------- */
*,*::before,*::after{box-sizing:border-box}
/* overflow-x:clip (not :hidden) so <html>/<body> don't become a scrolling
   container — that would break position:sticky on .nav. clip keeps the
   visual clipping (no horizontal scrollbar if content overflows the viewport)
   without establishing a scroll port. */
html{scroll-behavior:smooth;overflow-x:clip}
body{
  margin:0;background:var(--paper);color:var(--ink);
  font-family:var(--font-body);font-size:var(--text-md);line-height:1.6;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
  overflow-x:clip;
}
h1,h2,h3,h4{font-family:var(--font-display);font-weight:700;color:var(--ink);letter-spacing:-.02em;line-height:1.08;margin:0}
p{margin:0}
img,svg{max-width:100%}
a{color:var(--link);text-decoration:underline;text-underline-offset:2px;text-decoration-thickness:.08em}
a:hover{color:var(--navy);text-decoration-thickness:.14em}
*:focus-visible{outline:3px solid var(--ink);outline-offset:2px}
::selection{background:var(--accent);color:var(--ink)}

.container{max-width:var(--container-max);margin:0 auto;padding:0 var(--gutter)}
.skip-link{position:absolute;left:-9999px;top:0;background:var(--ink);color:#fff;padding:12px 18px;z-index:100;font-family:var(--font-body);font-weight:700;text-decoration:none}
.skip-link:focus{left:0}

/* --- Shared helpers --- */
.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}
.kicker{font-family:var(--font-mono);font-size:12px;letter-spacing:.16em;text-transform:uppercase;color:var(--navy-2);display:inline-flex;align-items:center;gap:8px;margin:0}
.mono{font-family:var(--font-mono)}
.idx{font-family:var(--font-mono);font-weight:700;font-size:15px;color:var(--navy-2);letter-spacing:.02em}
.hl{background:linear-gradient(transparent 60%,var(--accent) 60%);padding:0 .02em}
.rule{height:var(--rule-w);background:var(--rule);border:0;margin:0}
.em{font-style:italic}

/* Logo lockup (verbatim colourful mark, never recoloured).
   The SVG is self-contained (icon + "EVENLY LAB" text embedded),
   so this is now a single <img> per side of the nav.
   • `flex-shrink:0` stops the logo from being crushed to zero width
     when the surrounding .row / .nav-cta flex container overflows.
   • `min-width` reserves a floor so the mark can never collapse below
     a legible width, even under aggressive flex-shrink or in nested
     flex parents. */
.lockup{display:inline-flex;align-items:center;text-decoration:none;flex-shrink:0}
.lockup .logo-lockup{height:36px;width:auto;min-width:140px;max-width:none;display:block;flex-shrink:0}
.lockup:hover{text-decoration:none}
/* Defence-in-depth: even if a downstream rule somehow nukes height
   or sets display:none on the .logo-lockup itself (third-party
   extensions, browser quirks), make sure the integrated SVG renders.
   The colourful mark is intentionally NOT recoloured, and its embedded
   text (#000 / #fff) keeps the right contrast against either background. */
/* ---------------- Buttons (square, hard-shadow) ---------------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;min-height:52px;padding:0 26px;font-family:var(--font-body);font-weight:700;font-size:16px;line-height:1;border:var(--rule-w) solid var(--ink);border-radius:0;background:transparent;color:var(--ink);cursor:pointer;text-decoration:none;transition:transform var(--dur-fast) var(--ease-out),box-shadow var(--dur-fast) var(--ease-out),background var(--dur-fast) var(--ease-out),color var(--dur-fast) var(--ease-out)}
.btn i{font-size:18px;line-height:1}
.btn:hover{text-decoration:none;transform:translate(-2px,-2px);box-shadow:4px 4px 0 var(--ink)}
.btn:active{transform:translate(0,0);box-shadow:none}
.btn-primary{background:var(--ink);color:var(--paper)}
.btn-primary:hover{background:var(--navy);color:#fff}
.btn-secondary{background:transparent;color:var(--ink)}
.btn-secondary:hover{background:var(--paper-2);color:var(--ink)}
.btn-outline{background:transparent;color:var(--ink);border:var(--rule-w) solid var(--ink)}
.btn-outline:hover{background:var(--ink);color:var(--paper);transform:translate(-2px,-2px);box-shadow:4px 4px 0 var(--ink)}
.btn-yellow{background:var(--accent);color:var(--accent-ink);border-color:var(--ink)}
.btn-yellow:hover{background:#FFD65C;color:var(--accent-ink)}
.btn-on-dark{background:var(--paper);color:var(--ink);border-color:var(--paper)}
.btn-on-dark:hover{background:#fff;color:var(--ink);box-shadow:4px 4px 0 rgba(255,255,255,.45)}
.btn-lg{min-height:60px;padding:0 30px;font-size:18px}

/* ---------------- Chips / tags ---------------- */
.chip{display:inline-flex;align-items:center;gap:8px;padding:7px 13px;border-radius:0;border:1.5px solid var(--ink);font-family:var(--font-mono);font-size:12px;letter-spacing:.04em;text-transform:uppercase;background:transparent;color:var(--ink)}
.chip.green{border-color:var(--el-green-aaa);color:var(--el-green-aaa)}
.chip.yellow{background:var(--accent);border-color:var(--ink);color:var(--accent-ink)}
.chip.aqua{border-color:var(--el-aqua-aaa);color:var(--el-aqua-aaa)}
.chip.blue{border-color:var(--el-blue-aaa);color:var(--el-blue-aaa)}

/* ---------------- Reveal-on-scroll (default VISIBLE) ---------------- */
.reveal{opacity:1;transform:none}
html.js-anim .reveal{opacity:0;transform:translateY(16px);transition:opacity .55s var(--ease-out),transform .55s var(--ease-out)}
html.js-anim .reveal.in{opacity:1;transform:none}

/* ---------------- Section scaffolding ---------------- */
/* ============ SECTION RHYTHM ============
   Uniform vertical padding across all .sec blocks so Market Gap,
   Value Proposition, Deployment Timeline, and FAQ share the same
   vertical cadence. The clamp() scales with viewport but caps the
   upper bound at 96px to keep things from stretching on ultra-wide
   displays. The companion .sec.tight variant below trims only the
   top padding for sections that visually attach to a preceding group. */
.sec{padding:clamp(80px,10vw,120px) 0}
.sec.tight{padding-top:0}
.sec-head{display:grid;gap:16px;margin-bottom:44px;max-width:66ch}
.sec-head.wide{max-width:none}
.sec-head h2{font-size:clamp(30px,5vw,56px)}
.sec-head p{font-size:var(--text-lg);color:var(--ink-soft)}
/* Vertical air between the lede <p> and the hairline rule that follows
   it. 24px (up from 8px) so the rule reads as a section divider rather
   than an underline stuck to the paragraph above it. */
.sec-head .rule{margin-top:24px}

/* Utility: hide an element below the tablet/mobile breakpoint
   (~720px). Use sparingly — pair with a desktop equivalent so the
   content is still readable on larger screens. */
@media (max-width:720px){
  .hide-on-mobile{display:none}
}

/* ============ FAQ (contact) ============ */
.faq-list{border-top:var(--rule-w) solid var(--rule);max-width:820px}
.faq-item{border-bottom:var(--rule-w) solid var(--rule)}
.faq-item summary{
  cursor:pointer;list-style:none;padding:22px 0;font-family:var(--font-display);
  font-weight:700;font-size:var(--text-lg);display:flex;align-items:center;justify-content:space-between;gap:16px;
}
.faq-item summary::-webkit-details-marker{display:none}
.faq-item summary::after{content:"+";font-family:var(--font-mono);font-size:20px;color:var(--navy-2);flex-shrink:0}
.faq-item[open] summary::after{content:"−"}
.faq-item p{padding:0 0 22px;color:var(--ink-soft);max-width:62ch}

/* ============ FOUNDER MESSAGE (team) ============ */
.founder-msg{border-top:var(--rule-w) solid var(--rule);border-bottom:var(--rule-w) solid var(--rule);background:var(--paper-2);padding:clamp(40px,6vw,72px) 0}
.founder-msg .inner{display:grid;grid-template-columns:auto 1fr;gap:36px;align-items:start;max-width:1040px}
.founder-msg .mk{font-family:var(--font-display);font-weight:700;font-size:72px;line-height:.5;color:var(--navy-2)}
.founder-msg blockquote{margin:0;font-size:var(--text-xl);color:var(--ink)}
.founder-msg .who{margin-top:24px;font-family:var(--font-mono);font-size:12px;text-transform:uppercase;letter-spacing:.08em;color:var(--navy-2)}
.founder-msg .who b{display:block;font-size:15px;color:var(--ink);margin-bottom:4px;font-family:var(--font-body);text-transform:none;letter-spacing:0}

/* ============ LINKEDIN (team) ============ */
.member-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.linkedin-link{
  display:inline-grid;place-items:center;width:32px;height:32px;border:1.5px solid var(--ink);
  color:var(--ink);text-decoration:none;transition:background var(--dur-fast) var(--ease-out),color var(--dur-fast) var(--ease-out);
}
.linkedin-link:hover{background:var(--navy);color:#fff;text-decoration:none;transform:none;box-shadow:none}
.linkedin-link .bi{font-size:16px;line-height:1}
.member.lead .linkedin-link{align-self:start;margin-top:6px}

/* "More Detail" button in each team card. Lives near .linkedin-link so
   member-card chrome stays grouped. flex-start keeps the button pinned
   to the left edge in both card layouts (flex column inside .member and
   grid column inside .member.lead).

   margin-top:auto anchors the button to the bottom of each equal-height
   card (grid stretch on .team-grid keeps the row aligned). The minimum
   gap between the bio <p> and the button is enforced by padding-bottom
   on .member p, so this stays a single auto margin. */
.member .profile-link,
.member.lead .profile-link{margin-top:auto;align-self:flex-start}

/* Extra-large avatar variant for individual profile pages.
   Matches the navy-on-paper treatment of .member.lead .av so the
   hero portrait reads as part of the same family. */
.av-xl{
  width:140px;height:140px;
  border:1.5px solid var(--ink);border-radius:0;
  background:var(--navy);color:#fff;
  display:block;flex-shrink:0;object-fit:cover;
}
@media (max-width:480px){
  .av-xl{width:96px;height:96px}
}

/* ============ MEMBER PROFILE PAGE — three-section body ============
   Each member detail page groups the bio into three titled sections
   (Education / About / Why Evenly Lab). The section heading pairs an
   English label and a Chinese one inside .zh-b so the bilingual
   toggle reveals both, while the body paragraphs follow the same
   <span class="en"> + <span class="zh-b"> rhythm as the rest of the
   site. The section number uses the same mono kicker style as the
   page-head .kicker, so the page reads as one consistent system.

   The wrap is intentionally full-width (no max-width cap) so the
   three-section bio uses the full 1180px container on desktop
   instead of leaving a wide right-side gutter. Reading measure
   stays comfortable because 1180px ≈ 65ch at the 18px body size,
   which is inside the 60-75ch target band for long-form prose.
   On mobile, .container's own gutter + padding keeps text off
   the screen edge. */
.profile-bio{margin-top:36px;width:100%}
/* 48px (up from 32px) gives each titled section enough air above the
   hairline rule so the heading + copy never feel pinned to the
   divider. The margin-bottom pulls the next section's hairline
   down so the gap between section body and the next rule stays
   roughly equal to the gap above the heading. */
.profile-bio .pb-section{margin-top:0;margin-bottom:24px;padding-top:48px;border-top:var(--rule-w) solid var(--rule)}
.profile-bio .pb-section:last-child{margin-bottom:0}
.profile-bio .pb-section:first-of-type{padding-top:0;border-top:0}
.profile-bio .pb-section h2{
  display:flex;align-items:baseline;gap:14px;flex-wrap:wrap;
  font-family:var(--font-mono);font-size:12px;font-weight:700;
  text-transform:uppercase;letter-spacing:.12em;color:var(--navy-2);
  margin:0 0 16px 0;
}
.profile-bio .pb-section h2 .pb-num{
  font-family:var(--font-display);font-size:18px;color:var(--ink-soft);
  letter-spacing:0;font-weight:700;line-height:1;
}
.profile-bio .pb-section h2 .pb-en,
.profile-bio .pb-section h2 .pb-zh{color:var(--navy-2)}
.profile-bio .pb-section h2 .pb-sep{
  display:inline-block;width:24px;height:1.5px;background:var(--rule);
  transform:translateY(-4px);
}
.profile-bio .pb-section p{margin:0 0 14px 0;color:var(--ink);font-size:var(--text-lg);line-height:1.65}
.profile-bio .pb-section p:last-child{margin-bottom:0}

/* Inside the "Why Evenly Lab" section, the final paragraph can carry
   a pull-quote treatment if the page marks it with .pb-lead. */
.profile-bio .pb-lead{font-size:var(--text-xl);line-height:1.45;color:var(--navy-2);font-weight:500}

/* The tags row + Back-to-Team button live below the three sections.
   We give the link a generous top margin so it clearly belongs to the
   page chrome rather than the bio body, and centre the row on wider
   viewports. The .tags rules above already cap the row at its
   intrinsic width. */
.profile-bio + .profile-actions{
  display:flex;flex-wrap:wrap;gap:20px;align-items:center;
  margin-top:48px;padding-top:28px;border-top:var(--rule-w) solid var(--rule);
}
/* Force the .tags row to occupy its own line so the Back-to-Team
   button can never wrap onto the same line or float up beside the
   tags on wide viewports. Without this, on screens where the 5
   tags + the button would both fit, the button sat to the right
   of the tags — visually it read as "next to" instead of "below".
   flex-basis:100% + max-width:100% gives the row its own line;
   align-self:flex-start keeps tags left-aligned at the natural
   flex line start. */
.profile-actions .tags{
  margin-top:0;flex:0 0 100%;max-width:100%;
  align-self:flex-start;
}
.profile-actions .profile-link{
  margin:0;align-self:flex-start; /* override .member .profile-link auto margin */
  /* Sit directly below the tags row with a comfortable 12px gap so
     the two elements read as one "tags · back-link" group rather
     than a disconnected pair. */
}

@media (max-width:560px){
  .profile-bio .pb-section{padding-top:24px}
  .profile-bio .pb-section h2{gap:10px}
  .profile-bio .pb-section p{font-size:17px;line-height:1.6}
  .profile-bio + .profile-actions{margin-top:36px;padding-top:20px}
}

/* ============ AWARD SLIDER — text badges ============
   Dark text on the warm paper-2 ground: borders, bg and color all neutral
   so the badge reads as a contrast chip rather than a glass tile. */
.award-item.award-text{
  display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;
  min-width:220px;height:56px;padding:0 24px;border:1.5px solid var(--ink);background:var(--paper);
  font-family:var(--font-mono);font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:var(--ink);white-space:nowrap;line-height:1.2;
  align-self:center; /* Ensure text badges are vertically centered in 80px container */
}
.trust .award-item{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;height:80px;border-right:0;border-bottom:0;box-shadow:none}
.trust .award-item img{max-width:none;width:auto;height:64px;max-height:64px;object-fit:contain;flex-shrink:0;display:block}
.trust .award-item img.logo-hkust-ec{height:48px;width:auto;object-fit:contain}
.trust .award-item img.logo-award-highlight{height:78px;max-height:80px;border-radius:8px;object-fit:contain;width:auto;filter:grayscale(.15) contrast(1.05);transition:filter .25s ease}
.trust .award-item:hover img.logo-award-highlight{filter:none}

/* ============ PRODUCT VISUALS (A-EYE) ============ */
.visual-grid{display:grid;grid-template-columns:repeat(3,1fr);border-top:var(--rule-w) solid var(--rule)}
.visual-card{padding:28px;border-left:var(--rule-w) solid var(--rule)}
.visual-card:first-child{border-left:0}
.visual-card .screen-mini{background:var(--navy);color:#fff;border:var(--rule-w) solid var(--ink);padding:18px;min-height:180px;display:flex;flex-direction:column;justify-content:flex-end;gap:8px}
.visual-card .screen-mini .lbl{font-family:var(--font-mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--accent)}
.visual-card .screen-mini .line{height:8px;background:rgba(255,255,255,.25);width:72%}
.visual-card .screen-mini .line.short{width:48%}
.visual-card h3{font-size:var(--text-lg);margin-top:18px}
.visual-card p{margin-top:8px;color:var(--ink-soft);font-size:15px}

/* ============ MEDIA EMBED (video) ============
   Centre + enlarge so the demos feel like the focal point of each
   section. .large pushes the cap to 1080px (used on demo/validation/
   retail-demo) while the default 820px still works for narrower
   sections elsewhere. The media-embed-block wrapper centres any
   following .media-caption with the same width. */
.media-embed{position:relative;aspect-ratio:16/9;border:var(--rule-w) solid var(--ink);background:var(--ink);max-width:820px;margin:0 auto}
.media-embed.large{max-width:1080px}
.media-embed iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.media-caption{margin-top:14px;font-size:15px;color:var(--ink-soft);max-width:820px}
.media-caption a{margin-left:8px;font-weight:700}

/* ============ MEDIA BLOCK (video placeholder) ============ */
.media-block{position:relative;aspect-ratio:16/9;background:var(--navy);border:var(--rule-w) solid var(--ink);display:grid;place-items:center;color:#fff;text-align:center;padding:24px}
.media-block .play{width:64px;height:64px;border:2px solid #fff;display:grid;place-items:center;font-size:28px;margin-bottom:16px}
.media-block p{color:#C9D6FF;font-size:var(--text-md);max-width:36ch;margin:0 auto}

/* ============ RETAIL STORY ============ */
.retail-grid{display:grid;grid-template-columns:repeat(3,1fr);border-top:var(--rule-w) solid var(--rule)}
.retail-card{padding:34px 28px;border-left:var(--rule-w) solid var(--rule)}
.retail-card:first-child{border-left:0}
.retail-card .idx{font-family:var(--font-mono);font-weight:700;font-size:clamp(24px,3vw,36px);color:var(--navy-2);display:block;margin-bottom:14px}
.retail-card h3{font-size:var(--text-xl)}
.retail-card p{margin-top:10px;color:var(--ink-soft)}

/* ============ A-EYE PAGE — scroll sidebar (user journey nav) ============ */

.journey-nav{
  position:fixed;left:max(18px,calc((100vw - var(--container-max))/2 - 168px));
  top:50%;transform:translateY(-50%);z-index:45;
  opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity var(--dur-med) var(--ease-out),visibility var(--dur-med) var(--ease-out);
}
.journey-nav.is-visible{opacity:1;visibility:visible;pointer-events:auto}
.journey-nav ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px}
.journey-nav a{
  display:block;font-family:var(--font-mono);font-size:11px;font-weight:500;
  letter-spacing:.1em;text-transform:uppercase;text-decoration:none;
  color:var(--ink-soft);padding:7px 0 7px 14px;border-left:2px solid transparent;
  transition:color var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out);
}
.journey-nav a:hover{color:var(--ink);text-decoration:none}
.journey-nav a.is-active{color:var(--ink);border-left-color:var(--accent);font-weight:700}

/* ============ NAV ============ */
/* Sticky nav — must stay pinned on scroll, both desktop & mobile.
   Important: any ancestor with `overflow: hidden | auto | scroll` will
   establish a scrolling container and break `position: sticky`. The
   fix is to use `overflow-x: clip` (not `hidden`) on <html>/<body>,
   which clips visually without creating a scroll port. See lines 48/53. */
.nav{
  position:sticky;top:0;z-index:50;
  width:100%;
  background:var(--paper);
  border-bottom:var(--rule-w) solid var(--ink);
  /* Subtle shadow only appears once the nav is pinned (i.e. user has
     scrolled past the page top). Most browsers don't have CSS scroll
     drivers widely, so we keep it static and rely on the border-bottom. */
  /* Ensure transform/filter/will-change on descendants can't promote a
     containing block that breaks sticky. None are set today, but this
     is a defensive note for future contributors. */
}
.nav .row{display:flex;align-items:center;justify-content:space-between;min-height:70px;gap:16px}
.nav .lockup{flex-shrink:0}
.nav-toggle{display:none;align-items:center;justify-content:center;width:44px;height:44px;padding:0;margin-left:auto;margin-right:8px;border:var(--rule-w) solid var(--ink);background:var(--paper);color:var(--ink);cursor:pointer}
.nav-toggle .bi{font-size:24px;line-height:1}
.nav-links{display:flex;align-items:center;gap:26px;margin:0;padding:0;list-style:none}
.nav-links a{color:var(--ink);text-decoration:none;font-family:var(--font-mono);text-transform:uppercase;letter-spacing:.08em;font-size:12px}
.nav-links a:hover{color:var(--navy-2);text-decoration:underline;text-underline-offset:4px}
.nav-links a[aria-current="page"]{text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:2px;text-decoration-color:var(--accent)}
.nav-cta{display:flex;align-items:center;gap:12px}

/* Contrast toggle */
.ct-toggle{display:inline-flex;align-items:center;gap:8px;min-height:44px;padding:0 14px;border-radius:0;border:1.5px solid var(--ink);background:transparent;color:var(--ink);font-family:var(--font-mono);text-transform:uppercase;letter-spacing:.06em;font-weight:700;font-size:12px;cursor:pointer;transition:background var(--dur-fast) var(--ease-out),color var(--dur-fast) var(--ease-out)}
.ct-toggle:hover{background:var(--paper-2)}
.ct-toggle .bi{font-size:17px;line-height:1}

/* Language toggle — shares .ct-toggle; fills solid navy when Chinese is active */
.lang-toggle .ct-label{font-family:var(--font-mono),"Noto Sans TC";letter-spacing:.1em}
.lang-toggle[aria-pressed="true"]{background:var(--navy);color:var(--paper);border-color:var(--navy)}
.lang-toggle[aria-pressed="true"]:hover{background:var(--navy-2);color:var(--paper);border-color:var(--navy-2)}

/* ============ MASTHEAD (universal top info bar) ============
   共用基底，所有頁面的頂部資訊條都套用這套樣式。
   .hero .masthead / .page-head .masthead 的祖先限定規則
   保留為向後相容的細部覆寫（差異屬性）。
   屬性順序：先定義 font 等字型屬性，再 flex 佈局。
   ============================================================ */
.masthead{display:flex;justify-content:space-between;align-items:baseline;gap:16px;
  font-family:var(--font-mono);font-size:12px;font-weight:400;font-style:normal;
  text-transform:uppercase;letter-spacing:.12em;color:var(--navy-2);
  padding:20px 0;border-bottom:var(--rule-w) solid var(--rule)}
.masthead .r{color:var(--ink-soft)}

/* ============ HERO (home) ============ */
.hero .masthead{display:flex;justify-content:space-between;align-items:baseline;gap:16px;font-family:var(--font-mono);font-size:12px;text-transform:uppercase;letter-spacing:.12em;color:var(--navy-2);padding:20px 0;border-bottom:var(--rule-w) solid var(--rule)}
.hero .masthead .r{color:var(--ink-soft)}
.hero-main{padding:clamp(40px,7vw,80px) 0 0}
.hero h1{font-size:clamp(46px,10.5vw,128px);line-height:.96;letter-spacing:-.035em;max-width:15ch}
.hero .zh{display:block;font-weight:500;font-size:clamp(26px,4.4vw,54px);letter-spacing:0;margin-top:.14em;color:var(--navy-2)}
.hero-grid{display:grid;grid-template-columns:1.15fr .85fr;gap:44px;align-items:end;margin-top:clamp(34px,6vw,60px);padding-bottom:clamp(44px,7vw,72px)}
.hero .lede{font-size:var(--text-xl);color:var(--ink);max-width:42ch}
.hero-side{display:flex;flex-direction:column;gap:22px;align-items:flex-start}
.hero-actions{display:flex;gap:14px;flex-wrap:wrap}
.hero-badges{display:flex;gap:10px;flex-wrap:wrap}

/* ============ PAGE HEADER (sub-pages) ============ */
.page-head{border-bottom:var(--rule-w) solid var(--rule)}
.page-head .masthead{display:flex;justify-content:space-between;align-items:baseline;gap:16px;font-family:var(--font-mono);font-size:12px;text-transform:uppercase;letter-spacing:.12em;color:var(--navy-2);padding:20px 0;border-bottom:var(--rule-w) solid var(--rule)}
.page-head .masthead .r{color:var(--ink-soft)}
.page-head .inner{padding:clamp(40px,7vw,84px) 0 clamp(34px,5vw,60px);display:grid;grid-template-columns:1.2fr .8fr;gap:44px;align-items:end}
.page-head h1{font-size:clamp(42px,8.5vw,104px);line-height:.98;letter-spacing:-.03em;max-width:14ch}
/* Loose line-height variant — used by about.html's "Technology should aid
   everyone" h1 so the long bilingual phrase reads with breathing room.
   Tuned to 1.15 (slightly looser than the default 0.98 for page-head h1
   but tighter than the previous 1.45, per the user feedback that the
   gap between lines was too wide). */
.page-head h1.loose{line-height:1.15;max-width:22ch;letter-spacing:-.045em;font-size:clamp(38px,7.5vw,88px)}
.page-head .zh{display:block;font-weight:500;font-size:clamp(22px,3.6vw,42px);letter-spacing:0;margin-top:.16em;color:var(--navy-2)}
.page-head .lede{font-size:var(--text-xl);color:var(--ink);max-width:40ch}
.page-head .kicker{margin-bottom:18px}

/* ============ TRUST BAR (mid-tone band — neutral paper-2 ground) ============
   Sits between --paper (cream) and --ink (near-black) so both light/white
   logos and dark text/logos render legibly without washing either out.
   AA-compliant (>=4.5:1) against both white and navy text. */
.trust{background:var(--paper-2);color:var(--ink);border-top:var(--rule-w) solid var(--rule);border-bottom:var(--rule-w) solid var(--rule)}
.trust .row{display:flex;flex-wrap:wrap;gap:36px 30px;align-items:center;padding:18px 0;font-family:var(--font-mono);font-size:12px;letter-spacing:.08em;text-transform:uppercase}
/* "Proudly Funded By" caption that sits above the .award-slider on pages
   that show awards/funding logos. Reuses the .kicker base style for the
   mono caps look, plus a tighter size + lighter weight so it reads as a
   secondary caption rather than a top-level section header.
   `flex-basis:100%` forces the <p> to wrap to its own line inside the
   .container.row flex container (otherwise it would sit side-by-side
   with the .award-slider instead of above it). */
.trust .funded-by{margin:18px 0 14px;font-size:16px;font-weight:700;letter-spacing:.14em;color:var(--navy);gap:6px;flex:0 0 100%;order:0;width:100%;text-align:center;justify-content:center;text-transform:uppercase}
.trust .funded-by .bi{font-size:18px}
.trust b{color:var(--navy);font-weight:700}
.trust .sep{opacity:.45}
.trust .tall{display:flex;align-items:center;justify-content:center;min-height:140px;height:auto}
/* Award marquee: fixed 80px tall track, overflow hidden, relative
   positioning so the left/right gradient fade overlays anchor to the
   slider rect. Flex centering on the slider puts the track vertically
   and horizontally centered inside the strip. height:80px matches the
   tallest item (.trust .award-item has height:80px below) so items
   never overflow above/below the clip region. */
.trust .award-slider{overflow:hidden;padding:0;white-space:nowrap;position:relative;width:100%;height:80px;display:flex;align-items:center;justify-content:flex-start;box-sizing:border-box}
.trust .award-slider::before,
.trust .award-slider::after{content:"";position:absolute;top:0;width:150px;height:100%;z-index:2;pointer-events:none}
.trust .award-slider::before{left:0;background:linear-gradient(to right,var(--paper-2),rgba(247,245,240,0))}
.trust .award-slider::after{right:0;background:linear-gradient(to left,var(--paper-2),rgba(247,245,240,0))}
/* Track is a horizontal flex container that holds two identical .award-set
   copies for seamless looping. width:max-content keeps both copies on one
   row at their natural width. flex-shrink:0 on every level guarantees the
   two copies stay exactly the same width — required for translateX(-50%)
   to land back on the visual seam. */
.trust .award-slider .award-track{display:flex;gap:0;width:max-content;align-items:center;flex-shrink:0;height:80px;margin:0;padding:0;will-change:transform;animation:marquee-scroll 25s linear infinite;box-sizing:border-box}
.trust .award-set{display:flex;align-items:center;gap:60px;flex:0 0 auto;flex-shrink:0;margin-left:0;margin-top:0;margin-bottom:0;padding:0;height:80px}
.trust .award-set .award-item:last-child{margin-right:60px}
.trust .award-slider:hover .award-track{animation-play-state:paused}
/* Seamless scroll: the track contains two identical .award-set copies so
   translateX(-50%) lands back at the visual start of the original set,
   producing a gap-free loop. The 50% assumes both copies share the track
   width equally — must keep .award-set at flex:0 0 auto (no grow/shrink)
   or the two copies can drift apart and break the loop. */
@keyframes marquee-scroll{0%{transform:translateX(0)}100%{transform:translateX(-50%)}}

/* Reverse marquee: .award-slider.reverse flips animation-direction so the
   track scrolls the opposite way. The edge fade masks are also swapped so
   they always "appear to come from" the leading edge. */
.trust .award-slider.reverse .award-track{animation-direction:reverse}
.trust .award-slider.reverse::before{left:auto;right:0;background:linear-gradient(to left,var(--paper-2),rgba(247,245,240,0))}
.trust .award-slider.reverse::after{right:auto;left:0;background:linear-gradient(to right,var(--paper-2),rgba(247,245,240,0))}

/* Award-text placeholder logos: bilingual span renders in mono caps so
   they visually match the existing logo strip but with no image asset. */
.trust .award-item.award-text{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  padding:0 24px;height:60px;line-height:1.1;text-align:center;
  font-family:var(--font-display);font-weight:700;font-size:14px;letter-spacing:.02em;color:var(--navy-2);
}
.trust .award-item.award-text .zh-b{font-size:11px;font-weight:500;color:var(--ink-soft);margin-top:2px;font-family:var(--font-body)}

/* Award-logo items: real SVG logos (HK01, Sing Tao, SCMP, Ming Pao, HKET,
   Wen Wei Po). Transparent container so the logo sits cleanly on the
   paper background; .trust .award-item img above already constrains the
   image to height:56px so the marquee rhythm matches. */
.trust .award-item.award-logo{
  display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;
  height:80px;padding:0;border:0;background:transparent;min-width:0;
  filter:grayscale(.15) contrast(1.05);
  transition:filter .25s ease,opacity .25s ease;
}
.trust .award-item.award-logo:hover{filter:none}
/* Smaller-than-default media logos so they read as supportive coverage
   rather than competing with the headline awards. The .trust .award-item
   img rule above sets 64px, so this img selector wins on specificity
   (.trust .award-item.award-logo img = 0,3,1 > 0,2,1) and shrinks the
   image to 44px while keeping the 80px container. */
.trust .award-item.award-logo img{height:44px;width:auto;object-fit:contain;flex-shrink:0;display:block}

/* ============ STATS (data table) ============ */
.stats-wrap{border-top:var(--rule-w) solid var(--rule);border-bottom:var(--rule-w) solid var(--rule)}
.stat-grid{display:grid;grid-template-columns:repeat(4,1fr)}
.stat{padding:34px 26px;border-left:var(--rule-w) solid var(--rule)}
.stat:first-child{border-left:0}
.stat .num{font-family:var(--font-display);font-weight:700;font-size:clamp(34px,4.6vw,54px);letter-spacing:-.03em;line-height:1;color:var(--navy-2)}
.stat .lbl{margin-top:14px;font-size:15px;color:var(--ink-soft)}
.stat cite{display:block;margin-top:12px;font-family:var(--font-mono);font-size:11px;color:var(--ink-soft);font-style:normal;opacity:.85}

/* ============ VALUES (numbered grid) ============ */
.values-grid{display:grid;grid-template-columns:repeat(3,1fr);border-top:var(--rule-w) solid var(--rule)}
.value{padding:34px 30px 40px;border-left:var(--rule-w) solid var(--rule)}
.value:first-child{border-left:0}
.value .top{display:flex;align-items:center;justify-content:space-between;margin-bottom:22px}
.value .sw{width:16px;height:16px;display:inline-block;border:1.5px solid var(--ink)}
.value .sw.blue{background:var(--el-blue-500)}
.value .sw.green{background:var(--el-green-500)}
.value .sw.yellow{background:var(--accent)}
.value h3{font-size:var(--text-2xl)}
.value p{margin-top:12px;color:var(--ink-soft)}

/* ============ FEATURE LIST (two-column detail rows) ============ */
.features{border-top:var(--rule-w) solid var(--rule)}
/* Each .feature row sits between two hairline rules. The 44px top/bottom
   padding (up from 30px) gives the text enough breathing room so the
   heading and copy never feel pinned to the rules above and below. */
.feature{display:grid;grid-template-columns:220px 1fr;gap:30px;padding:44px 0;border-bottom:var(--rule-w) solid var(--rule)}
.feature .f-label{font-family:var(--font-mono);text-transform:uppercase;letter-spacing:.08em;font-size:12px;color:var(--navy-2);display:flex;gap:10px;align-items:baseline}
.feature .f-label i{font-size:16px;color:var(--ink)}
.feature h3{font-size:var(--text-xl);margin-bottom:8px}
.feature p{color:var(--ink-soft);max-width:60ch}

/* ============ A-EYE SPOTLIGHT (solid navy block) ============ */
.spotlight{background:var(--navy);color:#fff;padding:clamp(34px,5vw,64px);display:grid;grid-template-columns:1.05fr .95fr;gap:48px;align-items:center}
.spotlight .kicker{color:var(--accent)}
.spotlight h2{color:#fff;font-size:clamp(30px,4.6vw,54px)}
.spotlight .zh{display:block;font-weight:500;font-size:var(--text-xl);color:#C9D6FF;margin-top:8px;letter-spacing:0}
.spotlight p{color:#DCE7FF;font-size:var(--text-lg);margin-top:20px;max-width:46ch}
.spotlight ul{list-style:none;margin:26px 0 0;padding:0;display:grid;gap:14px}
.spotlight li{display:flex;gap:12px;align-items:flex-start;color:#EAF1FF}
.spotlight li i{color:var(--accent);font-size:18px;margin-top:2px}

/* Phone / receipt card */
.phone{background:#fff;color:var(--ink);border:var(--rule-w) solid var(--ink);padding:24px}
.phone .tag{display:flex;align-items:center;gap:8px;font-family:var(--font-mono);font-size:12px;text-transform:uppercase;letter-spacing:.08em;color:var(--navy-2);border-bottom:1.5px solid var(--ink);padding-bottom:12px}
.phone .wave{display:flex;align-items:flex-end;gap:5px;height:56px;margin:20px 0}
.phone .wave span{flex:1;background:var(--navy-2);animation:eq 1.1s var(--ease-out) infinite alternate}
@keyframes eq{from{height:16%}to{height:100%}}
@keyframes pulse{0%,100%{opacity:.4;transform:scale(.85)}50%{opacity:1;transform:scale(1.1)}}
.phone .said{background:var(--paper);border:1.5px solid var(--ink);padding:16px;font-size:14px;line-height:1.5}
.phone .said b{color:var(--ink)}
.phone .chips{display:flex;gap:8px;flex-wrap:wrap;margin-top:16px}

/* ============ TIMELINE (about) ============ */
.timeline{border-top:var(--rule-w) solid var(--rule)}
/* 40px top/bottom (up from 28px) so the when-label and the headline
   + body paragraphs sit comfortably between the hairline rules. */
.tl-row{display:grid;grid-template-columns:170px 1fr;gap:30px;padding:40px 0;border-bottom:var(--rule-w) solid var(--rule);align-items:baseline}
.tl-row .when{font-family:var(--font-mono);font-weight:700;font-size:var(--text-lg);color:var(--navy-2);letter-spacing:.02em}
.tl-row h3{font-size:var(--text-xl);margin-bottom:6px}
.tl-row p{color:var(--ink-soft);max-width:62ch}

/* ============ TEAM (members grid) ============ */
/* One connected hairline grid: the founder spans the full top row, the four
   co-founders fill the row below — a complete rectangle, no orphaned cell. */
.team-grid{display:grid;grid-template-columns:repeat(4,1fr);border-top:var(--rule-w) solid var(--rule);border-left:var(--rule-w) solid var(--rule)}
.member{padding:30px 28px 34px;border-right:var(--rule-w) solid var(--rule);border-bottom:var(--rule-w) solid var(--rule);background:var(--paper);display:flex;flex-direction:column}
.member .av{width:64px;height:64px;border-radius:0;border:1.5px solid var(--ink);background:var(--paper-2);color:var(--ink);display:block;flex-shrink:0;object-fit:cover}
.member .role{margin-top:20px;font-family:var(--font-mono);text-transform:uppercase;letter-spacing:.08em;font-size:11px;color:var(--navy-2)}
/* Reserve two lines so co-founder names align whether the title wraps or not */
.team-grid .member:not(.lead) .role{line-height:1.45;min-height:2.9em}
.member-head h3,.member h3{font-size:var(--text-xl);margin-top:6px}
.member.lead .member-head h3,.member.lead h3{font-size:var(--text-2xl)}
.member .zh{display:block;font-family:var(--font-body);font-weight:500;font-size:14px;color:var(--ink-soft);margin-top:2px}
.member p{margin-top:12px;color:var(--ink-soft);font-size:15px}
/* Reserve minimum spacing between the bio <p> and the "More detail" button.
   Combined with margin-top:auto on .profile-link, this guarantees at least
   24px of breathing room on every card regardless of bio length, without
   re-introducing button misalignment across the row (grid stretch keeps
   all cards the same height; only the inner gap grows).

   For the lead card, .lead-bio sits inside .lead-bio-wrap which uses
   justify-content:space-between — the padding there simply pads the
   bio element itself, so the wrap's space-between layout still pins
   the button to the bottom. */
.member p,
.member.lead .lead-bio{padding-bottom:24px}
.member .tags{display:flex;flex-wrap:wrap;gap:8px;margin-top:16px}
.member .tags .t{font-family:var(--font-mono);font-size:11px;text-transform:uppercase;letter-spacing:.04em;color:var(--ink-soft)}
/* Featured founder — full-width masthead row: avatar · identity · bio */
.member.lead{grid-column:1/-1;display:grid;grid-template-columns:auto minmax(220px,.9fr) 1.3fr;gap:36px;align-items:center;padding:36px 34px}
.member.lead .av{width:84px;height:84px;border-color:var(--navy);background:var(--navy);object-fit:cover}
.member.lead .role{margin-top:0}
.member.lead .zh{font-size:15px}
.member.lead .lead-bio{margin-top:0;color:var(--ink-soft);font-size:var(--text-lg);max-width:48ch}

/* Wraps .lead-bio <p> + .profile-link <a> inside the founder card's
   bio grid column. Flex column pushes the button to the bottom via
   margin-top:auto, matching the bottom-alignment trick used on .member cards. */
.lead-bio-wrap{display:flex;flex-direction:column;height:100%;justify-content:space-between}

/* ============ VOICES ============ */
.voices-grid{display:grid;grid-template-columns:repeat(3,1fr);border-top:var(--rule-w) solid var(--rule)}
.voice-card{padding:34px 28px 32px;border-left:var(--rule-w) solid var(--rule)}
.voice-card:first-child{border-left:0}
.voice-card .mk{font-family:var(--font-display);font-weight:700;font-size:clamp(36px,8vw,62px);line-height:.5;color:var(--navy-2);height:clamp(26px,5vw,34px)}
.voice-card blockquote{margin:0;font-size:var(--text-lg);color:var(--ink)}

/* ★ 明確寬度：讓 .voice-card 撐滿父容器，並防止被窄祖先壓縮 */
.voice-card{
  width: 100%;
  max-width: none;
  box-sizing: border-box;
}

/* ★ 引言段落撐滿卡片內寬 */
.voice-card blockquote{
  width: 100%;
  max-width: none;
  box-sizing: border-box;
}

/* ★ 確保 .voice-card 作為 <figure> 元素時不被瀏覽器預設樣式壓縮 */
figure.voice-card{
  margin-left: 0;
  margin-right: 0;
}
.voice-card .who{margin-top:24px;display:flex;align-items:center;gap:12px}
.voice-card .av{width:44px;height:44px;border-radius:0;border:1.5px solid var(--ink);background:transparent;color:var(--ink);display:grid;place-items:center;font-family:var(--font-mono);font-weight:700;font-size:14px}
.voice-card .who b{display:block;color:var(--ink);font-size:15px}
.voice-card .who span{font-size:12px;color:var(--ink-soft);font-family:var(--font-mono);text-transform:uppercase;letter-spacing:.04em}

/* ============ CTA (yellow band) ============ */
.cta{background:var(--accent);border-top:var(--rule-w) solid var(--ink);border-bottom:var(--rule-w) solid var(--ink)}
.cta .inner{padding:clamp(56px,8vw,96px) var(--gutter);text-align:center;max-width:820px;margin:0 auto;box-sizing:border-box}
.cta .kicker{color:var(--accent-ink);justify-content:center}
.cta h2{color:var(--ink);font-size:clamp(32px,5.6vw,60px);margin-top:16px}
.cta p{color:var(--accent-ink);font-size:var(--text-lg);margin-top:16px;max-width:52ch;margin-left:auto;margin-right:auto}
/* `width:100% + box-sizing:border-box` keeps .cta-actions inside the
   .inner safe area at every viewport — when buttons go full-width on
   mobile (single column), they still respect the container's gutter
   instead of bleeding past the screen edge. */
.cta-actions{display:flex;gap:14px;justify-content:center;flex-wrap:wrap;margin-top:32px;width:100%;max-width:100%;box-sizing:border-box}

/* ============ FOOTER (ink band) ============ */
.site-footer{background:var(--ink);color:#C7CCDB}
.site-footer .foot-grid{display:grid;grid-template-columns:1.6fr 1fr 1fr 1fr;gap:40px;padding:60px 0 30px}
.site-footer h4{color:#fff;font-family:var(--font-mono);text-transform:uppercase;letter-spacing:.1em;font-size:12px;margin-bottom:16px}
.site-footer ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:10px}
.site-footer .foot-links a{color:#C7CCDB;text-decoration:none;font-size:15px}
.site-footer .foot-links a:hover{color:#fff;text-decoration:underline}
.site-footer .foot-bottom{border-top:1px solid rgba(255,255,255,.18);padding:20px 0;display:flex;flex-wrap:wrap;gap:12px 24px;justify-content:space-between;align-items:center;font-family:var(--font-mono);font-size:12px;letter-spacing:.04em;color:#8B93AB}

/* ============================================================
   FLOATING WHATSAPP BUTTON
   Persistent bottom-right CTA, accessible focus state.
   Hidden in print.
   ============================================================ */
.fab-whatsapp{
  position:fixed;right:20px;bottom:20px;z-index:60;
  display:inline-grid;place-items:center;
  width:60px;height:60px;
  background:#25D366;color:#fff;
  border:2px solid var(--ink);
  border-radius:50%;
  text-decoration:none;
  box-shadow:4px 4px 0 var(--ink);
  transition:transform var(--dur-fast) var(--ease-out),box-shadow var(--dur-fast) var(--ease-out),background var(--dur-fast) var(--ease-out);
}
.fab-whatsapp i{font-size:30px;line-height:1;color:#fff}
.fab-whatsapp:hover{
  background:#1ebe57;color:#fff;text-decoration:none;
  transform:translate(-2px,-2px);box-shadow:6px 6px 0 var(--ink);
}
.fab-whatsapp:active{transform:translate(0,0);box-shadow:2px 2px 0 var(--ink)}
.fab-whatsapp:focus-visible{outline:3px solid var(--ink);outline-offset:3px}
.fab-whatsapp .sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
@media (max-width:480px){
  .fab-whatsapp{right:14px;bottom:14px;width:54px;height:54px}
  .fab-whatsapp i{font-size:26px}
  .fab-whatsapp{box-shadow:3px 3px 0 var(--ink)}
}
@media print{.fab-whatsapp{display:none}}

/* ============================================================
   HERO BACKGROUND IMAGE — product.html (#hero / .hero-split)
   Scoped to .hero-grid-split (the top split area above the
   "View for:" toggle). Rendered as a small, low-opacity visual
   cue (~220px square, top-left of the grid) rather than a full-
   bleed background. The .hero-toggle-row and sections below the
   hero stay clean. Pseudo-element approach keeps markup clean.
   sits behind .hero-content / .hero-visual via z-index:-1 +
   position:relative on .hero-grid-split (existing), so it never
   intercepts pointer events or overlays content.
   ============================================================ */
/* ============================================================
   HERO ENHANCEMENTS — product.html
   Hero h1 uses a moderate clamp so it never overwhelms the
   hero container; hero-desc sits beneath at a comfortable
   body size and the audience toggle is centred.
   ============================================================ */
.hero-split .hero-content .hero-desc{
  font-size:var(--text-md);line-height:1.65;color:var(--ink-soft);
  max-width:48ch;margin-top:22px;
}
.hero-split .hero-content .hero-actions{
  justify-content:center;flex-wrap:wrap;margin-top:24px;
}
.hero-actions .btn-yellow{background:#FFC72E;color:#4A3600;border-color:var(--ink)}
.hero-actions .btn-yellow:hover{background:#FFD65C;color:#4A3600;box-shadow:4px 4px 0 var(--ink);transform:translate(-2px,-2px)}

/* Full-width row that hosts the audience mode toggle beneath the hero grid.
   Centred on the viewport, not constrained to a single column. */
.hero-toggle-row{
  border-top:var(--rule-w) solid var(--rule);
  padding:24px 0 4px;margin-top:32px;
  display:flex;justify-content:center;
}
.hero-toggle-row .mode-toggle{
  margin:0;padding:0;
  display:flex;flex-direction:column;align-items:center;text-align:center;
}
.hero-toggle-row .toggle-label{display:block;margin-bottom:10px}
.hero-toggle-row .toggle-switch{margin:0 auto}

/* ============================================================
   VIEW-TOGGLE CONTAINER — the "View for: For Users / For Retails"
   mode switcher. Lives between the .trust awards marquee and the
   user-flow content. Upgraded from the original thin hero-bottom
   strip into a proper "pivot" call-to-action:
   - Big vertical breathing room (60px top + 60px bottom)
   - Paper-card background with a hairline rule + soft shadow so
     the toggle reads as a deliberate choice, not a footer link
   - Bigger label (~1.5rem) + bigger buttons (14×28 padding)
   ============================================================ */
.view-toggle-container{
  margin-top:60px;
  margin-bottom:60px;
  padding:clamp(40px,5vw,56px) 0;
  /* Paper-card wrapper — gives the toggle its own visual "frame"
     so users see a clear call-to-action rather than a stranded row. */
  position:relative;
}
.view-toggle-container::before{
  content:"";
  position:absolute;
  inset:0;
  background:var(--paper-2);
  border-top:var(--rule-w) solid var(--ink);
  border-bottom:var(--rule-w) solid var(--ink);
  /* Soft shadow under the card to lift it off the page background
     and visually anchor the toggle. */
  box-shadow:0 6px 18px rgba(12,31,78,.08);
  z-index:-1;
}
.view-toggle-container .container{
  display:flex;justify-content:center;
}

/* The actual switcher: label on top, button row below, both
   centred. Slightly more vertical room than the original so the
   large label doesn't crash into the buttons. */
.view-toggle-container .role-switcher{
  display:flex;flex-direction:column;align-items:center;
  text-align:center;
  gap:18px;
}
/* Big label — "View for:" — sized up to 1.5rem per the design spec. */
.view-toggle-container .toggle-label{
  display:inline-flex;
  align-items:center;
  gap:10px;
  font-family:var(--font-mono);
  font-size:clamp(1.25rem,2vw,1.5rem);  /* 1.25rem → 1.5rem responsive */
  text-transform:uppercase;
  letter-spacing:.12em;
  color:var(--ink);
  font-weight:700;
  margin:0;
}
.view-toggle-container .toggle-label .bi{
  color:var(--accent);
  font-size:1.2em;
  line-height:1;
}

/* Switch row — wider so the bigger buttons have somewhere to live.
   The 14×28 padding comes straight from the design spec. */
.view-toggle-container .toggle-switch{
  display:flex;
  gap:0;
  max-width:520px;
  width:100%;
  margin:0 auto;
  border-radius:14px;
  overflow:hidden;
  background:var(--paper);
  border:var(--rule-w) solid var(--ink);
  box-shadow:
    0 2px 0 var(--ink),                   /* Swiss-brutalist 2px hard shadow */
    0 8px 18px rgba(12,31,78,.08);          /* + soft lift */
}
.view-toggle-container .toggle-btn{
  flex:1;
  display:flex;align-items:center;justify-content:center;gap:10px;
  /* Upgraded padding per design spec */
  padding:14px 28px;
  min-height:54px;                          /* generous tap target */
  font-family:var(--font-body);
  font-weight:700;
  font-size:clamp(1rem,1.4vw,1.125rem);     /* 16px → 18px responsive */
  white-space:nowrap;
  background:transparent;color:var(--ink);
  border:0;
  border-right:var(--rule-w) solid var(--ink);
  cursor:pointer;
  transition:
    background var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out),
    transform var(--dur-fast) var(--ease-out);
}
.view-toggle-container .toggle-btn:last-child{
  border-right:0;
}
.view-toggle-container .toggle-btn:hover{
  background:var(--paper-2);
}
.view-toggle-container .toggle-btn:active{
  transform:scale(.985);
}
.view-toggle-container .toggle-btn.active{
  background:var(--ink);color:var(--paper);
}
.view-toggle-container .toggle-btn.active .bi{color:var(--accent)}
.view-toggle-container .toggle-btn i{font-size:20px;line-height:1}

/* RWD: stack the label + buttons more tightly on mobile */
@media (max-width:560px){
  .view-toggle-container{margin-top:36px;margin-bottom:36px;padding:32px 0}
  .view-toggle-container .role-switcher{gap:14px}
  .view-toggle-container .toggle-btn{padding:12px 16px;font-size:1rem;min-height:48px}
  .view-toggle-container .toggle-btn i{font-size:18px}
}

.hero-split .hero-content h1{
  font-size:clamp(28px,3.5vw,42px);
  line-height:1.18;letter-spacing:-.01em;
}

/* Mode Toggle — bigger label + buttons in the hero */
/* Mode Toggle label + buttons — generic (no longer scoped to hero-content) */
.mode-toggle .toggle-label{
  font-size:15px;letter-spacing:.12em;margin-bottom:14px;
}
.mode-toggle .toggle-btn{
  font-size:15px;padding:10px 18px;min-height:auto;
}

/* iPhone device frame — realistic phone bezel & notch */
.iphone-frame{
  position:relative;width:100%;max-width:320px;margin:0 auto;
  aspect-ratio:9/19;background:#0a0a0a;border-radius:42px;
  padding:10px;border:2px solid var(--ink);
  box-shadow:8px 8px 0 rgba(18,22,42,.18);
}
.iphone-frame::before{
  content:"";position:absolute;top:14px;left:50%;transform:translateX(-50%);
  width:96px;height:22px;background:#000;border-radius:14px;z-index:2;
}
.iphone-frame .iphone-screen{
  width:100%;height:100%;background:var(--paper);border-radius:32px;overflow:hidden;
  position:relative;display:flex;flex-direction:column;
}
.iphone-frame .iphone-status{
  display:flex;justify-content:space-between;align-items:center;
  padding:12px 22px 4px;font-family:var(--font-mono);font-size:11px;color:var(--ink);
}
.iphone-frame .iphone-content{flex:1;padding:20px 18px;display:flex;flex-direction:column;gap:12px}
.iphone-frame .iphone-cta{
  margin:auto 18px 18px;padding:12px;text-align:center;
  background:var(--ink);color:var(--paper);font-family:var(--font-body);font-weight:700;font-size:14px;
}

/* ============================================================
   APPLE-STYLE IMMERSIVE HERO — product.html (.hero-immersive)
   Full-bleed cinematic hero inspired by Apple.com product pages:
   a dark (#02040a) atmospheric backdrop, a centred mega headline
   with a subtle gradient, and a sticky phone stage beneath it.

   Layout:
     .hero-immersive          — full-width section, dark ground
     .hero-headline           — centred text block above the stage
     .hero-mega-title         — Apple's signature "ultra-thin" headline
     .scrolly-hero-container  — sticky scroll runway (unchanged behaviour)
     .scrolly-hero-sticky     — pins the phone canvas to the viewport
   ============================================================ */
.hero-immersive{
  /* Cinematic dark ground — the stage against which Apple
     renders its hero. Transitions seamlessly from deep navy at the
     top to near-black at the bottom so the glows feel natural. */
  background:
    radial-gradient(ellipse 90% 70% at 50% 0%, #0a1628 0%, #060d1a 45%, #02040a 100%);
  /* Ambient depth — multiple overlapping glows simulate the
     atmospheric lighting Apple uses behind its product shots. */
  position:relative;
  /* FIX: overflow:hidden creates a Scroll Container (per CSS Scroll Snap
     / CSS Overflow spec) and breaks position:sticky on ALL descendants.
     overflow-x:clip clips horizontally without establishing a scroll
     port, so position:sticky on .phone-scroll-sticky (inside the
     400vh .phone-scroll-container) works correctly end-to-end. */
  overflow:clip;
}
/* The three glow sources: blue (navy brand), yellow (accent),
   and a soft white fill behind the phone so it "floats". */
.hero-immersive::before,
.hero-immersive::after,
.hero-immersive > .phone-scroll-container::before{
  content:"";
  position:absolute;
  border-radius:50%;
  pointer-events:none;
  filter:blur(80px);
  z-index:0;
}
.hero-immersive::before{
  /* Top-centre blue glow — brand colour, 40% opacity */
  width:60vw;height:40vw;
  top:-10%;left:50%;transform:translateX(-50%);
  background:radial-gradient(circle,#1C55DB 0%,transparent 70%);
  opacity:.18;
}
.hero-immersive::after{
  /* Bottom-right accent glow — A-EYE yellow, 20% opacity */
  width:40vw;height:30vw;
  bottom:5%;right:-5%;
  background:radial-gradient(circle,#FFC72E 0%,transparent 70%);
  opacity:.10;
}
.hero-immersive > .phone-scroll-container::before{
  /* Centre ambient white fill — the "light from behind the device"
     Apple always uses; it makes the phone feel lit from the front. */
  width:50vw;height:50vw;
  top:20%;left:50%;transform:translateX(-50%);
  background:radial-gradient(circle,rgba(255,255,255,.06) 0%,transparent 65%);
}

/* ---------- Hero headline block (Apple-style centred layout) ---------- */
.hero-headline{
  position:relative;
  z-index:1;
  display:flex;
  flex-direction:column;
  align-items:center;
  text-align:center;
  padding:clamp(60px,8vw,96px) clamp(24px,5vw,60px) clamp(0px,2vw,16px);
  gap:0;
}
.hero-headline .kicker{
  color:rgba(255,255,255,.5);
  font-size:clamp(11px,1.2vw,13px);
}
.hero-headline .kicker .bi{color:var(--accent)}

/* Apple-style mega title: ultra-light weight, tight tracking,
   subtle top-to-bottom gradient (dark → slightly lighter).
   The clamp gives Apple-like responsive scaling. */
.hero-mega-title{
  font-family:var(--font-display);
  font-size:clamp(40px,7.5vw,88px);
  font-weight:800;
  line-height:.96;
  letter-spacing:-.03em;
  /* Multi-stop gradient: very dark at top, slightly lighter at bottom
     so the headline reads like it's lit from below. */
  background:linear-gradient(
    180deg,
    #ffffff 0%,
    rgba(220,230,255,.92) 55%,
    rgba(180,200,240,.80) 100%
  );
  -webkit-background-clip:text;
  -webkit-text-fill-color:transparent;
  background-clip:text;
  margin:clamp(12px,2vw,20px) 0 0;
  max-width:22ch;
  margin-inline:auto;
}
.hero-mega-title .zh-b{
  /* Chinese variant stays solid light colour (no gradient needed
     for CJK — they look better flat) but inherits the weight. */
  background:linear-gradient(180deg,rgba(200,215,255,.95) 0%,rgba(160,185,235,.85) 100%);
  -webkit-background-clip:text;
  -webkit-text-fill-color:transparent;
  background-clip:text;
  display:block;
}
.hero-sub{
  font-size:clamp(15px,1.8vw,20px);
  color:rgba(255,255,255,.60);
  max-width:46ch;
  margin:clamp(16px,2vw,26px) 0 0;
  line-height:1.55;
  letter-spacing:.01em;
}
.hero-headline .hero-actions{
  margin:clamp(22px,3vw,36px) 0 0;
  justify-content:center;
  flex-wrap:wrap;
  gap:14px;
}
.hero-headline .btn-yellow{
  background:var(--accent);color:var(--accent-ink);
  border-color:var(--accent);
}
/* Ghost-light button — white outline on dark ground, Apple CTA style */
.btn-ghost-light{
  display:inline-flex;align-items:center;justify-content:center;
  gap:10px;min-height:60px;padding:0 30px;
  font-family:var(--font-body);font-weight:700;font-size:18px;line-height:1;
  border:var(--rule-w) solid rgba(255,255,255,.55);
  border-radius:0;background:transparent;
  color:rgba(255,255,255,.85);cursor:pointer;
  text-decoration:none;
  transition:transform var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out),
              background var(--dur-fast),color var(--dur-fast),
              border-color var(--dur-fast);
}
.btn-ghost-light i{font-size:18px;line-height:1}
.btn-ghost-light:hover{
  background:rgba(255,255,255,.10);
  border-color:rgba(255,255,255,.80);
  color:#fff;
  text-decoration:none;
  transform:translate(-2px,-2px);
  box-shadow:4px 4px 0 rgba(255,255,255,.20);
}
.btn-ghost-light:active{transform:translate(0,0);box-shadow:none}

/* ---------- Sticky container — transparent so the .hero-immersive
     background glows show through. No margin hack needed: the new
     .phone-scroll-container sits flush beneath the headline. ---------- */

/* ============================================================
   APPLE-STYLE DEVICE CHROME — phone frame rebuilt from scratch
   for a titanium/glass aesthetic: large corner radii, subtle
   metallic bezel inset, Dynamic Island, glass sheen.

   Structure:
     .phone-3d-card       — the device body (metallic titanium)
     .phone-3d-card::before — 1px inner bezel highlight (polished edge)
     .iphone-frame         — the glass screen inset + bezel rim
     .iphone-bezel-highlight — hairline metal rim between frame & glass
     .iphone-screen        — actual UI surface (cream background)
     .dynamic-island       — Apple-style pill notch
     .glass-reflection     — diagonal sheen painted on the glass
   ============================================================ */

/* Device body — titanium-grade dark metal with polished edges */
.phone-3d-card{
  border-radius:48px;         /* Apple's Pro corner radius */
  /* Multi-layer titanium finish:
       outer glow → dark base → subtle blue tint → rim highlight */
  background:linear-gradient(
    145deg,
    #1c2030 0%,
    #0d1018 40%,
    #0a0d14 70%,
    #141820 100%
  );
  /* Outer shadow: the phone lifts off the dark background */
  box-shadow:
    /* Soft ambient glow */
    0 0 0 1px rgba(255,255,255,.04),
    0 0 60px rgba(28,85,219,.12),
    /* Device body drop-shadow */
    0 32px 64px rgba(0,0,0,.70),
    0 12px 24px rgba(0,0,0,.55);
}
/* 1px inner edge — simulates the polished titanium chamfer on
   Apple's Pro devices. Done via inset box-shadow on the body. */
.phone-3d-card::before{
  content:"";
  position:absolute;inset:1px;
  border-radius:47px;
  background:linear-gradient(
    145deg,
    rgba(255,255,255,.10) 0%,
    rgba(255,255,255,.04) 30%,
    transparent 60%
  );
  pointer-events:none;
  z-index:10;
}

/* Glass screen frame — the visible metallic rim between the titanium
   body and the actual display surface. A thin dark band with a
   hairline inner highlight. */
.iphone-frame{
  position:relative;
  width:calc(100% - 10px);   /* 5px metallic rim on each side */
  height:calc(100% - 10px);
  margin:5px auto;
  border-radius:42px;
  /* Dark titanium surround between body and glass */
  background:linear-gradient(
    160deg,
    rgba(30,35,50,.95) 0%,
    rgba(15,18,26,.98) 100%
  );
  padding:0;
  /* Inner rim highlight — the hairline polished edge */
  box-shadow:
    inset 0 1.5px 0 rgba(255,255,255,.12),
    inset 0 -1px 0 rgba(0,0,0,.4),
    inset 1.5px 0 0 rgba(255,255,255,.07),
    inset -1.5px 0 0 rgba(255,255,255,.07);
  overflow:hidden;
}
/* Bezel highlight — 1px subtle metallic line between frame & screen */
.iphone-bezel-highlight{
  position:absolute;inset:0;
  border-radius:42px;
  /* Thin top-left highlight: simulates the way Apple's titanium
     frame catches a light source from the upper-left. */
  background:linear-gradient(
    135deg,
    rgba(255,255,255,.08) 0%,
    transparent 50%
  );
  pointer-events:none;
  z-index:5;
}

/* Actual display surface — slightly inset from the frame.
   Uses the site's warm cream so the App UI reads naturally. */
.iphone-frame .iphone-screen{
  position:absolute;inset:2px;
  border-radius:39px;
  background:var(--paper);
  overflow:hidden;
  display:flex;flex-direction:column;
}

/* Dynamic Island — Apple iPhone 14/15 Pro pill notch.
   A dark rounded rectangle that "floats" inside the screen's
   top inset, slightly darker than the body so it reads as a hole. */
.dynamic-island{
  position:absolute;
  top:8px;left:50%;
  transform:translateX(-50%);
  width:90px;height:26px;
  background:#000;
  border-radius:16px;
  z-index:20;
  /* Subtle shadow so it feels "punched in" to the glass */
  box-shadow:
    inset 0 1.5px 3px rgba(0,0,0,.8),
    0 0 0 1px rgba(255,255,255,.04);
  display:flex;align-items:center;justify-content:flex-end;
  padding:0 10px;
  gap:6px;
}
/* Front-facing camera lens dot inside the island */
.di-lens{
  display:block;
  width:9px;height:9px;
  background:radial-gradient(circle at 35% 35%,#2a3040 0%,#080a0e 70%);
  border-radius:50%;
  border:0.5px solid rgba(255,255,255,.06);
  box-shadow:inset 0 1px 1px rgba(255,255,255,.04);
}
/* Status bar inherits dark text so it sits cleanly above the island */
.iphone-frame .iphone-status{color:var(--ink)}

/* Glass reflection — the signature Apple sheen painted across the
   upper-left of the device glass. A diagonal gradient that
   fades from semi-transparent white to transparent.
   pointer-events:none so it never blocks taps. */
.glass-reflection{
  position:absolute;inset:0;
  border-radius:39px;
  background:linear-gradient(
    125deg,
    rgba(255,255,255,.22) 0%,
    rgba(255,255,255,.08) 20%,
    transparent 48%
  );
  pointer-events:none;
  z-index:30;
  /* Mix-blend-mode adds a physical-glass look: the sheen
     brightens the colours beneath rather than painting white over them. */
  mix-blend-mode:screen;
  /* Animate the sheen subtly so it feels alive */
  animation:glassShimmer 6s ease-in-out infinite;
}
@keyframes glassShimmer{
  0%,100%{opacity:.90;transform:scaleX(1)}
  50%{opacity:1;transform:scaleX(1.02)}
}

/* ============================================================
   HERO 3D SCROLLY — product.html (.hero-immersive)
   The whole right column becomes a scroll-driven stage, in the spirit
   of meetbutler.ai's sticky-scroll storytelling: one tall runway
   (.scrolly-hero-container) with a pinned visual (.scrolly-hero-sticky
   + .scrolly-stage) that re-frames itself through 4 phases as the user
   scrolls.

     .scrolly-hero-container   — outer wrapper that owns the scroll
                                 runway (height ≈ 250vh on desktop). It
                                 gives us ~1.5 viewports of scroll to
                                 map onto the four phases below.
     .scrolly-hero-sticky      — pins the visual to the top of the
                                 viewport while the user scrolls past
                                 the container, so the same scene can
                                 transition through 4 phases.
     .scrolly-stage            — sets the CSS 3D perspective for the
                                 phone flip; child layers stack into
                                 z-order.

   Phases (driven by --scrolly-progress, written by js/main.js):
     0.00 – 0.60  zoom-in: scale the whole stage from 1 → 3.6 and
                 pull the camera toward the phone (which is hanging
                 on the visually-impaired shopper's lanyard). The
                 blurred store shelves recede; the shopper fades
                 mid-phase so the camera ends "on" the device.
     0.60 – 0.90  rotateY 0 → 180° on the .phone-3d-card so the
                 back-face (camera module) flips to the front-face
                 (App UI). The store bg is now fully gone.
     0.90 – 1.00  pin the front face; enable the in-app tabs
                 (.app-screen-ui is the only layer with pointer-events
                 at this point) and show the "Try the app" caption.

   The character SVG and store shelves are pure CSS/SVG (no asset
   dependency) and the phone re-uses the existing .iphone-* visual
   language so the final UI matches the rest of the site. The colour
   palette stays on Navy #0C1F4E and Yellow #FFC72E so the scroll
   story reads as a continuation of the rest of the page.
   ============================================================ */
.phone-scroll-container{
  /* 400vh runway = ~3 extra screens of scroll distance without the
     page actually moving. Combined with the sticky child below this
     is what guarantees the user cannot accidentally scroll past the
     device before every screen has played out. Tuned so 4 inner
     pages each get ~one full viewport of scrub space. */
  position:relative;
  height:400vh;
  /* Pull up so the sticky stage sits flush beneath the headline,
     with no white gap in between. */
  margin-top:-1px;
}
.phone-scroll-sticky{
  position:sticky;
  top:0;
  height:100vh;
  /* Centre the device horizontally + vertically inside the pin. */
  display:grid;
  grid-template-columns:1fr;
  place-items:center;
  z-index:1;
  /* Transparent so the .hero-immersive gradient glows stay visible
     behind the device. */
  background:transparent;
}
.phone-scroll-stage{
  /* Single source of truth for the progress — JS writes here.
     --scroll-active-screen: which inner screen (0..3) is currently
     centred. --scroll-release: 0 while pinned, 1 the instant the
     last screen has finished its scrub. */
  --scrolly-progress:0;
  --scroll-active-screen:0;
  --scroll-release:0;
  position:relative !important;
  width:min(920px,96%);
  display:grid;
  grid-template-rows:auto 1fr auto;
  align-items:center;
  justify-items:center;
  gap:clamp(16px,2vw,28px);
  /* Increased bottom padding so the "Continue scrolling" hint button
     sits with comfortable breathing room above the dark hero bottom
     edge, and the black background transitions smoothly into the
     light-paper trust section below. Before: clamp(20px,4vh,40px). */
  padding:clamp(20px,4vh,40px) clamp(16px,3vw,32px) clamp(32px,5vh,56px);
  pointer-events:none;  /* outer wrapper stops clicks; children opt back in */
}

/* ----- Caption strip across the top ----- */
.phone-scroll-caption{
  pointer-events:auto;
  display:flex;align-items:center;gap:14px;
  width:100%;
  max-width:560px;
  font-family:var(--font-mono);
  font-size:12px;
  letter-spacing:.08em;
  text-transform:uppercase;
  color:rgba(255,255,255,.65);
  user-select:none;
}
.phone-scroll-index{
  display:inline-block;
  padding:4px 10px;
  background:rgba(255,255,255,.10);
  border:1px solid rgba(255,255,255,.18);
  color:#fff;
  font-weight:700;
  border-radius:2px;
  min-width:62px;text-align:center;
}
.phone-scroll-title{
  flex:1;
  font-family:var(--font-display);
  font-size:clamp(14px,1.4vw,18px);
  letter-spacing:-.01em;
  text-transform:none;
  color:#fff;
  font-weight:700;
}
.phone-scroll-title .psc-default[hidden]{display:none}
.phone-scroll-hint{
  display:inline-flex;align-items:center;gap:6px;
  opacity:.6;
  transition:opacity .2s ease;
}
.phone-scroll-hint .bi{font-size:13px}
.phone-scroll-stage[data-released="1"] .phone-scroll-hint{opacity:0}

/* ----- The big device itself (Apple-style titanium body) ----- */
.iphone-frame--scroll{
  pointer-events:auto;
  position:relative;
  width:min(360px,78vw);
  aspect-ratio:9/19;
  border-radius:48px;
  background:linear-gradient(145deg,#2a2f42 0%,#141820 40%,#0a0d14 70%,#1c2030 100%);
  border:3px solid rgba(255,255,255,.28);     /* ★ 加粗：1.5px→3px，並提高 alpha */
  outline:1px solid rgba(0,0,0,.6);           /* ★ 外圈加深，與深色 Hero 背景分離 */
  box-shadow:
    0 0 0 1px rgba(255,255,255,.10),
    0 0 80px rgba(28,85,219,.22),
    0 0 0 3px rgba(255,255,255,.05),
    0 36px 72px rgba(0,0,0,.75),
    0 14px 28px rgba(0,0,0,.6);
  overflow:hidden;
}
.iphone-frame--scroll::before{
  content:"";
  position:absolute;inset:3px;                /* ★ 1px→3px，貼合新 border-width */
  border-radius:45px;                          /* ★ 47px→45px：48 − 3 border = 45 同心 */
  background:linear-gradient(
    145deg,rgba(255,255,255,.10) 0%,rgba(255,255,255,.04) 30%,transparent 60%
  );
  pointer-events:none;
  z-index:10;
}

/* ----- The screen that the JS slides horizontally ----- */
.iphone-frame--scroll .iphone-screen{
  position:absolute;inset:4px;                /* ★ 10px→4px：黑框由 10px 收窄至 4px */
  border-radius:44px;                         /* ★ 48 − 4 = 44 同心 */
  background:#0a0a0a;
  overflow:hidden;
  display:block;
  isolation:isolate;                           /* 確保子層圓角不被裁破 */
}

/* Status bar pinned at the top of every screen (same on all 4).
   flex:0 keeps it from being stretched by the track. */
.iphone-frame--scroll .iphone-status{
  position:absolute;
  top:10px;left:0;right:0;                      /* ★ 4px inset + 6px 視覺呼吸 */
  display:flex;justify-content:space-between;align-items:center;
  padding:0 22px 4px;                           /* ★ 36→26→22，貼齊 4px inset 玻璃邊 */
  z-index:5;
  color:#fff;
  font-family:var(--font-mono);font-size:11px;
}
.iphone-frame--scroll .dynamic-island{
  position:absolute;
  top:8px;left:50%;                             /* ★ 4px inset + 4px */
  transform:translateX(-50%);
  width:96px;height:28px;
  background:#000;
  border-radius:16px;
  z-index:20;
  box-shadow:inset 0 1.5px 3px rgba(0,0,0,.8),0 0 0 1px rgba(255,255,255,.04);
  display:flex;align-items:center;justify-content:flex-end;
  padding:0 10px;
}
.iphone-frame--scroll .di-lens{
  display:block;
  width:9px;height:9px;
  background:radial-gradient(circle at 35% 35%,#2a3040 0%,#080a0e 70%);
  border-radius:50%;
  border:0.5px solid rgba(255,255,255,.06);
}
.iphone-frame--scroll .glass-reflection{
  position:absolute;inset:0;
  border-radius:inherit;                        /* ★ 新增：避免反光溢出玻璃圓角 */
  background:linear-gradient(
    125deg,rgba(255,255,255,.22) 0%,rgba(255,255,255,.08) 20%,transparent 48%
  );
  mix-blend-mode:screen;
  pointer-events:none;
  z-index:30;
  animation:glassShimmer 6s ease-in-out infinite;
}

/* The horizontal track inside the device screen.
   4 screens side-by-side, translated by JS. */
.phone-screen-track{
  position:absolute;
  top:0;left:0;
  height:100%;
  display:flex;
  /* horizontal width = 4 × 100% of the screen. */
  width:400%;
  border-radius:inherit;                        /* ★ 新增：與玻璃同心，圓角處不被裁破 */
  overflow:hidden;                              /* ★ 新增：防止子畫面在圓角處溢出 */
  transform:translate3d(0,0,0);
  /* Smooth slide — JS writes transforms directly so this transition
     tweens between successive writes for the springy feel Apple uses. */
  transition:transform .8s cubic-bezier(.22,.61,.36,1);
  will-change:transform;
}
.phone-screen{
  flex:0 0 25%;
  height:100%;
  position:relative;
  overflow:hidden;
  border-radius:inherit;                        /* ★ 新增：讓子層繼承玻璃圓角 */
  display:flex;
  flex-direction:column;
  justify-content:flex-start;
  padding:54px 22px 20px;                       /* ★ 58/24/22 → 54/22/20：玻璃只內縮 4px，內容距邊可縮 */
}

/* Each screen has its own coloured backdrop, painted via
   [data-phone-screen="N"] selectors. */
.screen-screen-1-bg,
.screen-screen-2-bg,
.screen-screen-3-bg,
.screen-screen-4-bg{
  position:absolute;inset:0;
  z-index:0;
}
/* 1: Voice Nav — warm cream like the rest of the site */
.phone-screen[data-phone-screen="0"]{background:linear-gradient(165deg,#F4F1E8 0%,#EAE6D8 100%)}
.phone-screen[data-phone-screen="0"] .phone-screen-inner{color:var(--ink)}
/* 2: Allergen — warm warning tone */
.phone-screen[data-phone-screen="1"]{background:linear-gradient(165deg,#FFF4D6 0%,#FFE0B2 100%)}
.phone-screen[data-phone-screen="1"] .phone-screen-inner{color:var(--ink)}
/* 3: Compare — brand navy */
.phone-screen[data-phone-screen="2"]{background:linear-gradient(165deg,#122E75 0%,#0C1F4E 100%)}
.phone-screen[data-phone-screen="2"] .phone-screen-inner{color:#fff}
/* 4: Checkout — brand yellow accent + ink */
.phone-screen[data-phone-screen="3"]{background:linear-gradient(165deg,#FFC72E 0%,#F5B301 100%)}
.phone-screen[data-phone-screen="3"] .phone-screen-inner{color:var(--ink)}

/* Inner content area sits above the backdrop. */
.phone-screen-inner{
  position:relative;z-index:1;
  display:flex;flex-direction:column;gap:10px;
  height:100%;
}
.screen-kicker{
  display:inline-flex;align-items:center;gap:6px;
  font-family:var(--font-mono);
  font-size:9px;text-transform:uppercase;letter-spacing:.08em;
  padding:4px 8px;
  background:rgba(0,0,0,.12);
  color:inherit;
  align-self:flex-start;
  border:1px solid rgba(0,0,0,.18);
}
.phone-screen[data-phone-screen="2"] .screen-kicker{
  background:rgba(255,255,255,.14);
  border-color:rgba(255,255,255,.25);
  color:#fff;
}
.screen-kicker .bi{font-size:11px}

/* Big chapter title — Apple's "huge but airy" aesthetic on each screen */
.screen-title{
  font-family:var(--font-display);
  font-weight:800;
  font-size:clamp(22px,4.6vw,30px);
  line-height:1;
  letter-spacing:-.02em;
  margin:8px 0 6px;
  color:inherit;
}
.screen-title .en,
.screen-title .zh-b{display:block}

/* Meta line — navy/white rules under titles */
.screen-meta{
  font-family:var(--font-mono);
  font-size:9px;letter-spacing:.06em;
  text-transform:uppercase;
  margin-top:auto;
  padding-top:8px;
  border-top:1.5px solid currentColor;
  color:inherit;
  opacity:.75;
}
.screen-chip{
  display:inline-flex;align-items:center;gap:6px;
  padding:6px 10px;
  font-size:11px;font-weight:700;
  align-self:flex-start;
  border:1.5px solid currentColor;
}
.screen-chip--danger{
  background:var(--accent);color:var(--accent-ink);
  border-color:var(--ink);
}
.screen-chip--primary{
  background:var(--ink);color:#fff;
  border-color:var(--ink);
}

/* Compare-screen special: two pills side-by-side, the left marked
   "winner" with a hairline ring + accent colour fill. */
.compare-row{
  display:grid;grid-template-columns:1fr 1fr;gap:8px;
  margin-top:auto;
}
.compare-pill{
  display:flex;flex-direction:column;
  padding:10px;
  background:rgba(255,255,255,.06);
  border:1.5px solid rgba(255,255,255,.22);
  text-align:center;color:#fff;
}
.compare-pill--winner{
  background:var(--accent);color:var(--accent-ink);
  border-color:#fff;
  position:relative;
}
.compare-pill--winner::after{
  content:"★";
  position:absolute;
  top:-8px;right:-8px;
  width:20px;height:20px;
  background:#fff;color:var(--ink);
  border:1.5px solid var(--ink);
  display:grid;place-items:center;
  font-size:11px;line-height:1;
  border-radius:50%;
}
.compare-mark{
  font-family:var(--font-display);font-weight:800;font-size:16px;
  opacity:.7;
}
.compare-amount{
  font-family:var(--font-display);font-weight:800;
  font-size:clamp(15px,3.6vw,20px);line-height:1.1;
  margin-top:2px;
  color:inherit;
}
.compare-tiny{font-family:var(--font-mono);font-size:9px;text-transform:uppercase;letter-spacing:.04em;opacity:.85}

/* Checkout list — looks like a receipt */
.checkout-list{
  list-style:none;margin:6px 0 0;padding:0;
  display:flex;flex-direction:column;gap:4px;
  font-size:11px;
}
.checkout-list li{
  display:flex;justify-content:space-between;
  padding:4px 6px;border-bottom:1px solid rgba(0,0,0,.18);
}
.checkout-list li b{font-weight:700;font-family:var(--font-mono)}
.checkout-list-total{
  margin-top:4px;border-top:1.5px solid currentColor!important;
  font-weight:700;
}

/* EQ bars (Screen 1) */
.eq-bars{display:flex;align-items:flex-end;gap:3px;height:28px}
.eq-bars span{flex:1;background:var(--navy-2);height:var(--h,50%);animation:eq 1.1s ease-in-out infinite alternate}
.eq-bars span:nth-child(2){animation-delay:.1s}
.eq-bars span:nth-child(3){animation-delay:.2s}
.eq-bars span:nth-child(4){animation-delay:.3s}
.eq-bars span:nth-child(5){animation-delay:.15s}

/* ----- Bottom dot pager ----- */
.phone-scroll-pager{
  pointer-events:auto;
  display:flex;align-items:center;gap:10px;
  padding:8px 14px;
  background:rgba(0,0,0,.35);
  border:1px solid rgba(255,255,255,.12);
  backdrop-filter:blur(6px);
  border-radius:50px;
}
.phone-scroll-dot{
  width:8px;height:8px;border-radius:50%;
  background:rgba(255,255,255,.25);
  border:0;padding:0;
  cursor:pointer;
  transition:background .2s ease,transform .2s ease,width .2s ease;
}
.phone-scroll-dot:hover{background:rgba(255,255,255,.50)}
.phone-scroll-dot.is-active{
  background:var(--accent);
  width:24px;
  border-radius:5px;
}

/* Release cue — only visible after the pin has done its job. */
.phone-scroll-release{
  pointer-events:none;
  display:inline-flex;align-items:center;gap:8px;
  font-family:var(--font-mono);font-size:11px;letter-spacing:.08em;
  text-transform:uppercase;
  color:rgba(255,255,255,.80);
  padding:8px 14px;
  background:rgba(0,0,0,.35);
  border:1px solid rgba(255,255,255,.12);
  /* Extra breathing room below the hint button so it doesn't crowd the
     dark hero bottom edge. The grid's auto rows + padding-bottom on
     .phone-scroll-stage already provide spacing; margin-bottom gives
     a second, more deliberate layer of visual clearance. */
  margin-bottom:2.5rem;
  opacity:0;
  transform:translateY(8px);
  transition:opacity .35s ease,transform .35s ease;
}
.phone-scroll-release .bi{color:var(--accent);font-size:14px}
.phone-scroll-stage[data-released="1"] .phone-scroll-release{
  opacity:1;transform:translateY(0);
}

/* Reduced-motion users get a static "first screen + final" treatment:
   the device is always pinned to screen 1 and there's no scroll
   scrub, so they still see the whole product but never have to
   scroll-tween. */
@media (prefers-reduced-motion:reduce){
  .phone-scroll-container{height:auto}
  .phone-scroll-sticky{position:static;height:auto}
  .phone-screen-track{
    transform:none!important;
    width:100%;
    flex-wrap:wrap;
    transition:none!important;     /* ★ 確保 transition 也關閉 */
  }
  .phone-screen{flex:0 0 50%;height:auto;min-height:60vh}
  .iphone-frame--scroll{width:min(320px,80vw)}
  .glass-reflection,.glassShimmer{animation:none!important}    /* ★ 停用玻璃反光 6s 閃爍 */
}

/* ---------- Mobile (RWD): shorter runway + smaller device ---------- */
@media (max-width:900px){
  /* ★ 跑道高度：300vh 提供足夠的滾動距離驅動 4 個畫面切換 */
  .phone-scroll-container{height:300vh}
  .iphone-frame--scroll{
    /* ★ 核心修正：使用 min() 將寬度限制在 max-width 與 max-height 換算的寬度之間 */
    /* 這樣當高度受限時，寬度會自動縮小，嚴格保持 9:19 比例不變形 */
    width: min(300px, 76vw, calc(65svh * 9 / 19));
    aspect-ratio: 9 / 19;
    height: auto;
    max-width: none;
    max-height: none;
    /* ★ 與桌面版同心比：邊框 2px、玻璃 inset 4px、::before 2px */
    border-width:2px;
  }
  .iphone-frame--scroll .iphone-screen{inset:4px;border-radius:44px}    /* 48 − 4 = 44 */
  .iphone-frame--scroll::before{inset:2px;border-radius:46px}            /* 48 − 2 = 46 */
  .phone-scroll-caption{flex-wrap:wrap}
  .phone-scroll-hint{display:none}
  /* ★ 行動端：手機 sticky 在導航列下方 */
  .phone-scroll-sticky{
    position:sticky !important;
    top:70px !important;
    height:calc(100vh - 70px) !important;
  }
}
@media (max-width:560px){
  .phone-scroll-container{height:300vh}
  .iphone-frame--scroll{
    /* ★ 核心修正：使用 min() 將寬度限制在 max-width 與 max-height 換算的寬度之間 */
    /* 這樣當高度受限時，寬度會自動縮小，嚴格保持 9:19 比例不變形 */
    width: min(240px, 72vw, calc(55svh * 9 / 19));
    max-width: none;
    max-height: none;
    aspect-ratio: 9 / 19;
    height: auto;
    border-width:2px;
  }
  /* ★ 在 240px 迷你框上與 900px 採相同 inset，避免內容再被擠掉 */
  .iphone-frame--scroll .iphone-screen{inset:4px;border-radius:44px}
  .iphone-frame--scroll::before{inset:2px;border-radius:46px}
  .screen-title{font-size:22px}
  .screen-meta{font-size:8px}
  /* ★ 維持 sticky 跑道行為（不 collapse） */
  .phone-scroll-sticky{
    position:sticky !important;
    top:70px !important;
    height:calc(100vh - 70px) !important;
  }
}

/* ---------- Mobile (RWD): smaller device + retain scroll runway ----------
   900px↓ 也走 scroll-driven 模式（由 JS 透過 .phoneScroll 偵測）：
   - 容器保留 300vh 跑道（由 @media (max-width:900px) 設定）
   - sticky child 維持 sticky 行為（不再 collapse 為 static）
   - 控制按鈕 + 滑動手勢仍可用，但「主動畫切換 = 滾動」
   - Pager dots 仍可點擊跳轉（呼叫 JS goTo）。 */
@media (max-width:768px){
  /* 不要再把跑道收回 auto，也不要再把 sticky 改為 static——
     300vh 跑道與 sticky 行為已由 (max-width:900px) 區塊接管。 */
  .phone-scroll-stage{
    padding:20px 12px 12px;
    gap:14px;
    width:100%;
    /* ★ 改為 auto auto auto：不再讓 1fr 把 iphone-frame 撐滿，
       確保 controls 不會被擠出 viewport。 */
    grid-template-rows:auto auto auto !important;
    justify-items:center;
    /* ★ v2.29 — 在 stage 底部加 padding-bottom，把整個 stage 內容上移，
       為右下角 WhatsApp FAB 預留垂直空間。
       注意：grid-item 上的 margin 在 grid 中可能不會撐開軌道，
       所以避讓空間放在 stage padding 上更可靠。 */
    padding-bottom:84px;
  }

  /* Caption strip — drop the "scroll to explore" hint on mobile
     because the user is already driving by scrolling directly. */
  .phone-scroll-hint{display:none}
  .phone-scroll-release{display:none}

  /* Track is translated by the scroll-driven JS on mobile
     (proportional to the runway scroll progress).
     We keep the same easing so the carousel arrows + swipe gestures
     still feel consistent when invoked manually.

     ★ v4.0 — 改用反 S 曲線（cubic-bezier(.87, 0, .13, 1)），
     先慢起步、快速中段、緩慢落點。0.5s 比桌面 .55s 略短，
     避免手機滾動驅動下的拖影感，但仍保留視覺落點。 */
  .phone-screen-track{
    transition:transform .5s cubic-bezier(.87, 0, .13, 1) !important;
  }

  /* ★ v4.0 — beat 文字淡入與畫面切換節奏同步 */
  .xp-beat,
  .dash-beat{
    transition: opacity .3s ease !important;
  }

  /* Device scales down a touch on mobile + smaller padding inside
     each screen so the content fits comfortably in 360-414px viewports.
     ★ 同時加 max-height 約束：在 800px 視窗下，
     viewport(800) - top_padding(20) - caption(40) - controls(44+12) - bottom_padding(12)
     ≈ 660px 可用，clamp(420px, 62svh, 500px) 確保 iphone 不會擠出 controls。 */
  .iphone-frame--scroll{
    /* ★ 核心修正：使用 min() 將寬度限制在 max-width 與 max-height 換算的寬度之間 */
    /* 這樣當高度受限時，寬度會自動縮小，嚴格保持 9:19 比例不變形 */
    width: min(280px, 72vw, calc(62svh * 9 / 19));
    height: auto;
    max-height: none;
    max-width: none;
    aspect-ratio: 9 / 19;
    /* ★ 桌面版同心比：邊框 2px */
    border-width:2px;
  }
  .iphone-frame--scroll .iphone-screen{inset:4px;border-radius:44px}    /* 48 − 4 = 44 */
  .iphone-frame--scroll::before{inset:2px;border-radius:46px}
  .phone-screen{padding:50px 20px 20px}    /* 240px 迷你框下縮減內容內距，Voice Checkout 仍可容納 3 行 */

  /* Carousel arrows appear in a row sandwiching the dot pager.
     Pointer-events:auto so they're tap targets, not just decoration.
     ★ v2.29 — 對稱 padding 讓控制組與上方 iPhone 框水平居中對齊。
       FAB 垂直避讓由 .phone-scroll-stage 的 padding-bottom 負責。 */
  .phone-scroll-controls{
    display:flex;
    align-items:center;
    justify-content:center;
    gap:10px;
    pointer-events:auto;
    width:100%;
    padding:0 12px;
    box-sizing:border-box;
    position:relative;
    z-index:2;
  }
  .phone-scroll-arrow{
    display:flex;
    align-items:center;
    justify-content:center;
    flex:0 0 auto;
    width:44px;height:44px;                 /* WCAG tap-target */
    background:rgba(0,0,0,.55);
    border:1px solid rgba(255,255,255,.18);
    color:#fff;
    border-radius:50%;
    cursor:pointer;
    backdrop-filter:blur(6px);
    -webkit-tap-highlight-color:transparent;
    transition:background .15s ease,transform .15s ease,opacity .15s ease;
  }
  .phone-scroll-arrow:hover{background:rgba(0,0,0,.75)}
  .phone-scroll-arrow:active{transform:scale(.92)}
  .phone-scroll-arrow .bi{font-size:18px;line-height:1}
  /* Disabled state — when the carousel is at the first/last screen
     and not looping, the corresponding arrow dims out and stops
     responding to clicks. JS toggles [aria-disabled]. */
  .phone-scroll-arrow[aria-disabled="true"]{
    opacity:.35;
    cursor:not-allowed;
    pointer-events:none;
  }
  /* The pager keeps its existing look but sits between the arrows
     instead of below them. */
  .phone-scroll-pager{
    flex:0 0 auto;
  }
  .phone-scroll-dot{
    width:8px;height:8px;
  }
  .phone-scroll-dot.is-active{width:24px}
}

/* ============================================================
   v2.29 — 極窄視口（≤480px）強化 FAB 避讓：
   Galaxy A55 / iPhone SE 等窄螢幕下，FAB 縮小到 48×48，
   但 stage padding-bottom 仍需 84px 才能容納 FAB + 安全邊距。
   ============================================================ */
@media (max-width:480px){
  .phone-scroll-stage{
    padding-bottom:84px !important;
  }
}

/* ============================================================
   v2.29 — 平板（769–900px）FAB 避讓：
   平板上 controls 內只有 pager（prev/next 為 display:none），
   但居中的 pager 仍需避開 FAB 的垂直範圍。
   ============================================================ */
@media (max-width:900px) and (min-width:769px){
  .phone-scroll-stage{
    padding-bottom:88px !important;
  }
}

/* Make sure arrows are *never* visible on desktop, even if some
   other rule accidentally set display:flex. The base rule below
   lives outside the @media so it has full specificity weight.
   v2.29 — 範圍調整為 ≥901px：769–900px 平板區間由 .phone-scroll-controls
   在 @media (max-width:900px) and (min-width:769px) 接管，
   但 prev/next 按鈕在平板上仍需隱藏。 */
@media (min-width:901px){
  .phone-scroll-arrow{display:none!important}
}
@media (min-width:769px) and (max-width:900px){
  .phone-scroll-arrow{display:none!important}
}

/* ============================================================
   FEATURE STEPPER — manually-navigated prev/next arrow carousel.
   Renders one pill-card at a time; dots indicate position.
   Falls back to a flowing grid when JS is unavailable — see
   .stepper-track fallback CSS below.
   ============================================================ */
.feature-stepper{
  margin-top:32px;display:grid;
  grid-template-columns:auto 1fr auto;
  align-items:center;gap:18px;
}
.stepper-viewport{
  overflow:hidden;border:var(--rule-w) solid var(--ink);
  background:var(--paper-2);
}
.stepper-track{
  display:flex;gap:0;
  transform:translateX(0);
  transition:transform var(--dur-fast) var(--ease-out);
  will-change:transform;
}
.stepper-track .pill-card{
  flex:0 0 100%;
  min-width:100%;background:var(--paper);
  padding:22px 24px;display:flex;flex-direction:column;gap:6px;
  border:0;border-right:var(--rule-w) solid var(--ink);
}
.stepper-track .pill-card:last-child{border-right:0}
.stepper-arrow{
  width:48px;height:48px;display:grid;place-items:center;
  background:var(--paper);border:var(--rule-w) solid var(--ink);
  color:var(--ink);font-size:22px;cursor:pointer;
  transition:transform var(--dur-fast) var(--ease-out),box-shadow var(--dur-fast) var(--ease-out),background var(--dur-fast);
}
.stepper-arrow:hover{background:var(--accent);transform:translate(-2px,-2px);box-shadow:4px 4px 0 var(--ink)}
.stepper-arrow:focus-visible{outline:3px solid var(--accent);outline-offset:2px}
.stepper-arrow[disabled]{opacity:.35;cursor:not-allowed;transform:none;box-shadow:none;background:var(--paper);color:var(--ink-soft)}
.stepper-arrow i{pointer-events:none}
.stepper-dots{
  grid-column:1/-1;display:flex;justify-content:center;gap:8px;
  list-style:none;margin:14px 0 0;padding:0;
}
.stepper-dots li{
  width:10px;height:10px;border-radius:50%;
  background:var(--paper);border:var(--rule-w) solid var(--ink);
  cursor:pointer;transition:background var(--dur-fast);
}
.stepper-dots li[aria-current="true"]{background:var(--accent)}

/* No-JS fallback: lay all cards out in a flowing grid inside the
   stepper viewport so the controls degrade gracefully (arrows hidden).
   Activated when the page does NOT have the .js-anim class on <html>
   (which the reveal-on-scroll IIFE in this same file adds once it has
   been able to run). */
.js-anim-off .feature-stepper{grid-template-columns:1fr;gap:0}
.js-anim-off .stepper-arrow,.js-anim-off .stepper-dots{display:none}
.js-anim-off .stepper-viewport{overflow:visible;border:0;background:transparent}
.js-anim-off .stepper-track{transform:none;flex-wrap:wrap;gap:14px;display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}
.js-anim-off .stepper-track .pill-card{flex:0 0 auto;min-width:0;border:var(--rule-w) solid var(--ink);padding:18px 20px}

/* Print: flatten stepper so all cards show on paper. */
@media print{
  .stepper-arrow,.stepper-dots{display:none}
  .stepper-viewport{overflow:visible;border:0;background:transparent}
  .stepper-track{transform:none;flex-wrap:wrap;gap:14px;display:grid;grid-template-columns:repeat(2,1fr)}
  .stepper-track .pill-card{flex:0 0 auto;min-width:0;border:var(--rule-w) solid var(--ink);padding:14px 16px}
}

/* Compact feature card (for inline use) */
.feature-compact{
  border-top:var(--rule-w) solid var(--rule);
  padding:24px 0;display:grid;gap:14px;
}
.feature-compact .row{
  display:grid;grid-template-columns:auto 1fr;gap:18px 22px;
  padding:18px 0;border-bottom:var(--rule-w) solid var(--rule);
  align-items:baseline;
}
.feature-compact .row i{font-size:22px;color:var(--ink);line-height:1.2}
.feature-compact .row h4{font-size:var(--text-xl);margin:0 0 4px;font-family:var(--font-display);font-weight:700}
.feature-compact .row p{margin:0;color:var(--ink-soft);font-size:15px;line-height:1.55;max-width:60ch}

/* Custom UI block (warm paper / navy border / yellow accent) */
.custom-ui-block{
  margin-top:28px;background:var(--paper);border:var(--rule-w) solid var(--ink);
  display:grid;grid-template-columns:auto 1fr auto;gap:22px;align-items:center;
  padding:22px 26px;
}
.custom-ui-block .ui-icon{
  width:54px;height:54px;display:grid;place-items:center;
  background:var(--accent);color:var(--accent-ink);border:var(--rule-w) solid var(--ink);font-size:22px;
}
.custom-ui-block .ui-body h4{font-size:var(--text-lg);margin:0 0 6px;font-family:var(--font-display);font-weight:700}
.custom-ui-block .ui-body p{margin:0;color:var(--ink-soft);font-size:14px;line-height:1.55;max-width:54ch}
.custom-ui-block .ui-arrow{
  font-family:var(--font-mono);font-size:22px;color:var(--ink);background:transparent;border:0;line-height:1;
}

/* ============================================================
   ABOUT MISSION — grid w/ photo placeholders alongside stats
   ============================================================ */
/* Mission section — single-column flow (stats above, photos below).
   The mission-photos row is itself a 3-column grid; it collapses to
   1 column on narrow viewports. */
.mission-grid{
  display:flex;flex-direction:column;gap:24px;
  margin-top:8px;
}
.mission-photos{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px;
  margin-top:8px;align-items:start;
}
.mission-photo{
  margin:0;display:flex;flex-direction:column;gap:10px;
}
.mission-photo .mission-photo-frame{
  background:var(--paper-2);border:var(--rule-w) solid var(--ink);
  aspect-ratio:4/3;display:grid;place-items:center;color:var(--navy-2);
  padding:18px;position:relative;
}
.mission-photo .mission-photo-frame i{font-size:34px;color:var(--navy-2)}
.mission-photo .label{
  font-family:var(--font-mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--paper);background:var(--ink);padding:8px 12px;display:block;text-align:center;
  border:var(--rule-w) solid var(--ink);
}
@media (max-width:900px){
  .mission-photos{grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}
}
@media (max-width:600px){
  .mission-photos{grid-template-columns:1fr;gap:14px}
}

/* Story image frame */
.story-image-frame{
  margin-top:24px;background:var(--paper-2);border:var(--rule-w) solid var(--ink);
  aspect-ratio:16/10;display:grid;place-items:center;color:var(--navy-2);
  font-family:var(--font-mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;
}
.story-image-frame .frame-inner{
  display:flex;flex-direction:column;align-items:center;gap:12px;
}
.story-image-frame i{font-size:42px;color:var(--navy-2)}

/* Story two-column layout — image left, text right on tablet/desktop; stacks on mobile. */
.story-grid{
  display:grid;grid-template-columns:1fr 1fr;gap:48px;align-items:start;
  margin-top:24px;
}
.story-grid .story-image-frame{margin-top:0}
.story-grid .story-text h3{font-size:clamp(24px,3vw,32px);margin:0 0 12px;line-height:1.3}
.story-grid .story-text p{font-size:var(--text-lg);color:var(--ink-soft);line-height:1.6;max-width:60ch}
.story-grid .story-text p + p{margin-top:14px}
@media (max-width:780px){
  .story-grid{grid-template-columns:1fr;gap:24px}
}

/* ============================================================
   JOURNEY FLOW (matches sample-2.html's horizontal process flow)
   A horizontal row of numbered + icon cards connected by a dashed
   line running through the vertical centre of the number badges.
   Square / brutalist styling (flat hairline border, hard-shadow
   hover) per the site's existing design language — no soft shadows.
   ============================================================ */
.journey-flow{
  list-style:none;padding:0;margin:0;
  display:flex;justify-content:space-between;align-items:flex-start;
  gap:20px;position:relative;
}
/* When a journey-flow row sits directly below another journey-flow row
   (steps 3 & 4 sit below steps 1 & 2), add a vertical gap so the two
   horizontal process rows breathe — addresses the user feedback that
   "Process flow 1 & 2 and 3 & 4 are touching each other". The gap is
   only applied BETWEEN sibling .journey-flow lists; the first list
   keeps its own spacing from the parent section. */
.journey-flow + .journey-flow{margin-top:clamp(28px,4vw,44px)}
/* Dashed connector line, runs across the row at the vertical centre of
   the number badges. Token-driven neutral, not raw #999. */
.journey-flow::before{
  content:"";
  position:absolute;
  top:23px; /* centres on a 46px-tall number badge */
  left:46px;right:46px;
  border-top:2px dashed var(--rule);
  z-index:1;
}
.journey-step{
  flex:1;display:flex;flex-direction:column;align-items:center;
  position:relative;z-index:2;
  list-style:none;padding:0;margin:0;
}
.journey-number{
  width:46px;height:46px;border-radius:50%;
  background:var(--paper);border:2px solid var(--ink);
  display:grid;place-items:center;
  font-family:var(--font-mono);font-weight:700;font-size:16px;
  color:var(--ink);letter-spacing:.02em;
  margin-bottom:18px;
}
.journey-card{
  background:var(--paper);border:var(--rule-w) solid var(--ink);
  aspect-ratio:1/1;width:100%;max-width:180px;
  padding:14px;box-sizing:border-box;
  display:flex;flex-direction:column;justify-content:center;align-items:center;
  text-align:center;gap:10px;
  transition:transform var(--dur-fast) var(--ease-out),box-shadow var(--dur-fast) var(--ease-out);
}
.journey-card:hover{transform:translate(-4px,-4px);box-shadow:4px 4px 0 var(--ink)}
.journey-card i{
  font-size:42px;color:var(--navy-2);line-height:1;
}
.journey-card p{
  margin:0;font-family:var(--font-display);font-weight:700;
  font-size:14px;letter-spacing:-.005em;color:var(--ink);line-height:1.25;
  overflow-wrap:break-word;word-break:break-word;
}

/* Interactive journey step — show pointer cursor + active ring on hover/focus.
   The card is a button (role=button + tabindex=0) but keeps the original
   .journey-card visual treatments. */
.journey-step[role="button"]{cursor:pointer;background:none;border:0;padding:0;font:inherit;color:inherit;text-align:inherit;list-style:none}
.journey-step[role="button"]:hover .journey-card{transform:translate(-4px,-4px);box-shadow:4px 4px 0 var(--ink)}
.journey-step[role="button"]:focus-visible{outline:0}
.journey-step[role="button"]:focus-visible .journey-card{box-shadow:0 0 0 3px var(--accent),4px 4px 0 var(--ink)}
.journey-step[aria-pressed="true"] .journey-card{background:var(--navy);color:var(--paper)}
.journey-step[aria-pressed="true"] .journey-card i,
.journey-step[aria-pressed="true"] .journey-card p{color:var(--paper)}
.journey-step[aria-pressed="true"] .journey-number{background:var(--accent);color:var(--accent-ink)}

/* Detail panel — swap-in region under the journey steps. JS toggles the
   .is-active class on the matching [data-step-detail] panel. */
.journey-detail-panel{
  margin-top:28px;padding:28px 32px;
  background:var(--paper-2);border:var(--rule-w) solid var(--ink);
  min-height:96px;display:flex;align-items:center;
}
.journey-detail-panel .journey-detail-placeholder{
  margin:0;display:flex;align-items:center;gap:14px;color:var(--ink-soft);
  font-family:var(--font-mono);font-size:13px;letter-spacing:.04em;text-transform:uppercase;
}
.journey-detail-panel .journey-detail-placeholder i{font-size:22px;color:var(--navy-2)}
.journey-detail-panel .step-detail{display:none}
.journey-detail-panel .step-detail.is-active{display:grid;grid-template-columns:auto 1fr;gap:18px;align-items:start;width:100%}
.journey-detail-panel .step-detail .step-detail-icon{
  width:48px;height:48px;display:grid;place-items:center;
  background:var(--navy);color:var(--accent);font-size:24px;
  border:var(--rule-w) solid var(--ink);flex-shrink:0;
}
.journey-detail-panel .step-detail .step-detail-body h4{
  margin:0 0 6px;font-size:clamp(18px,2vw,22px);font-family:var(--font-display);
}
.journey-detail-panel .step-detail .step-detail-body p{margin:0;font-size:var(--text-md);color:var(--ink-soft);line-height:1.55;max-width:70ch}

/* Connector banner between major steps — sits BETWEEN two .journey-flow
   rows in the vertical flow (no longer a grid item). Reuses the
   existing .custom-ui-block icon / body / arrow rules above. */
/* ============================================================
   COMPACT FEATURE CARD (image2.png reference)
   Concise pill-card format with index label, bold title,
   1-line muted description.
   ============================================================ */
.pill-grid{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px;margin:24px 0 12px;
}
.pill-card{
  background:var(--paper);border:var(--rule-w) solid var(--ink);
  padding:18px 20px;display:flex;flex-direction:column;gap:6px;flex:0 0 auto;
  transition:transform var(--dur-fast) var(--ease-out),box-shadow var(--dur-fast) var(--ease-out);
}
.pill-card:hover{transform:translate(-2px,-2px);box-shadow:4px 4px 0 var(--ink)}
.pill-card .pill-idx{
  font-family:var(--font-mono);font-size:11px;color:var(--navy-2);letter-spacing:.1em;
  text-transform:uppercase;font-weight:700;
}
.pill-card .pill-idx i{font-size:14px;color:var(--ink);margin-right:4px;vertical-align:-2px}
.pill-card h4{
  font-family:var(--font-display);font-weight:700;font-size:var(--text-lg);
  margin:2px 0 0;letter-spacing:-.01em;color:var(--ink);
}
.pill-card p{
  margin:2px 0 0;font-size:14px;color:var(--ink-soft);line-height:1.5;
}

/* ============================================================
   TIGHT SECTION SPACING
   Eliminate awkward white gaps between consecutive sections.
   ============================================================ */
.sec.tight{padding:40px 0}
@media (max-width:720px){
  .sec.tight{padding:32px 0}
  /* Journey flow: stack vertically, hide dashed connector line,
     turn each step into a horizontal row (number left, card right). */
  .journey-flow{flex-direction:column;align-items:stretch;gap:24px}
  .journey-flow::before{display:none}
  .journey-step{
    flex-direction:row;justify-content:flex-start;
    gap:16px;width:100%;
  }
  .journey-number{margin-bottom:0;flex-shrink:0}
  .journey-card{
    aspect-ratio:auto;max-width:none;
    flex-direction:row;justify-content:flex-start;
    padding:14px 18px;gap:14px;
  }
  /* Ultra-narrow: shrink icon + horizontal padding to keep text on one line
     even with longer Chinese labels (e.g. 提問與互動) at 320px viewports. */
  .journey-card{padding:12px 14px;gap:12px}
  .journey-card i{font-size:34px}
  .pill-grid{grid-template-columns:1fr 1fr;gap:12px}
}
@media (max-width:480px){
  .pill-grid{grid-template-columns:1fr}
}

/* Chinese mode: reveal companions, hide the paired English on bilingual headings */
html[data-lang="zh"] .en{display:none}
html[data-lang="zh"] .hero .zh,html[data-lang="zh"] .page-head .zh{margin-top:0}

/* Full-page body translation: Cantonese copy is hidden until Chinese mode is on.
   Paired with an .en sibling; keeps the display face's sizing but swaps to a
   CJK face and relaxes the Latin tracking so Chinese doesn't read cramped. */
.zh-b{display:none}
html[data-lang="zh"] .zh-b{display:inline;font-family:"Noto Sans TC",var(--font-body);letter-spacing:.01em}
html[data-lang="zh"] h1 .zh-b,html[data-lang="zh"] h2 .zh-b,html[data-lang="zh"] h3 .zh-b{letter-spacing:0}

/* Bilingual role titles — the member-page ".role" / ".who" blocks show both
   the English and Chinese job titles in Chinese mode (so visitors always
   see the full bilingual pair), separated by a centered dot. Other .en
   spans on the page are still hidden as normal.

   The member-head h3 also keeps the English name visible alongside the
   Chinese name (already in `.zh`) so each card reads as a full bilingual
   identity regardless of which language mode is active. */
html[data-lang="zh"] .role .en,
html[data-lang="zh"] .who .en,
html[data-lang="zh"] .member-head h3 .en,
/* Bilingual person names — h1 blocks that pair an .en name with a .zh
   name (member profile pages, team founder quote) keep the English
   name visible in Chinese mode so the visitor always sees both forms. */
html[data-lang="zh"] h1 .zh ~ .en,
html[data-lang="zh"] h1 .en:has(+ .zh){display:inline}
html[data-lang="zh"] .role .zh-b::before,
html[data-lang="zh"] .who .zh-b::before{content:" · ";color:var(--ink-soft);margin:0 .25em}

/* Chinese hero/page-head headlines: render at a "large headline" weight that
   matches the bilingual headline's visual mass in the page, instead of
   inheriting the 104-128px English h1 size (which would make CJK characters
   look disproportionately huge). Sizes sit a step below the English h1 but
   still read as primary hero/page-head copy. */
html[data-lang="zh"] .page-head h1 .zh-b{font-size:clamp(28px,6vw,64px);font-weight:600;line-height:1.18;margin-top:.14em;display:inline-block;max-width:18ch}
html[data-lang="zh"] .page-head h1.loose .zh-b{line-height:1.32;max-width:18ch}
html[data-lang="zh"] .hero h1 .zh-b{font-size:clamp(34px,7vw,78px);font-weight:600;line-height:1.12;margin-top:.14em;display:inline-block;max-width:18ch}
html[data-lang="zh"] .hero-split .hero-content h1 .zh-b{font-size:clamp(32px,3.8vw,46px);font-weight:600;line-height:1.2;display:inline-block}

/* ---------------- Responsive ---------------- */
@media (max-width:1280px){
  .journey-nav{display:none}
}
@media (max-width:980px){
  .page-head .inner{grid-template-columns:1fr;gap:24px;align-items:start}
}
@media (max-width:900px){
  .nav .row{position:relative}
  .nav-toggle{display:flex;margin-left:auto}
  .nav #primaryNav{display:none;position:absolute;left:0;right:0;top:100%;background:var(--paper);border-bottom:var(--rule-w) solid var(--ink);box-shadow:0 8px 0 rgba(18,22,42,.14);z-index:51}
  .nav #primaryNav.is-open{display:block}
  .nav #primaryNav .nav-links{display:flex;flex-direction:column;align-items:stretch;gap:0;padding:10px 0 14px}
  .nav #primaryNav .nav-links a{display:block;padding:11px 0;width:100%}
  .hero-grid{grid-template-columns:1fr;gap:28px;align-items:start}
  .stat-grid{grid-template-columns:repeat(2,1fr)}
  .stat:nth-child(odd){border-left:0}
  .stat:nth-child(n+3){border-top:var(--rule-w) solid var(--rule)}
  .values-grid,.voices-grid{grid-template-columns:1fr}
  .value,.voice-card{border-left:0;border-top:var(--rule-w) solid var(--rule)}
  .value:first-child,.voice-card:first-child{border-top:0}
  .team-grid{grid-template-columns:repeat(2,1fr)}
  .member.lead{grid-template-columns:auto 1fr;gap:26px 30px}
  .member.lead .lead-bio{grid-column:1/-1;max-width:none}
  .spotlight{grid-template-columns:1fr;gap:32px}
  .feature{grid-template-columns:1fr;gap:8px}
  .visual-grid,.retail-grid{grid-template-columns:1fr}
  .visual-card,.retail-card{border-left:0;border-top:var(--rule-w) solid var(--rule)}
  .visual-card:first-child,.retail-card:first-child{border-top:0}
  .founder-msg .inner{grid-template-columns:1fr;gap:16px}
  /* New components responsive */
  .hero-grid-split{grid-template-columns:1fr;gap:32px}
  .hero-content{order:1}
  .hero-visual{order:2;margin-top:24px}
  .awards-grid{grid-template-columns:repeat(2,1fr)}
  .award-item{flex:0 0 50%}
  .feature-visuals{grid-template-columns:1fr}
  .timeline-item{grid-template-columns:1fr;gap:8px}
}
@media (max-width:720px){
  .nav-links{display:none}
  .nav-cta .btn{padding:0 16px;min-height:44px;font-size:14px}
  .masthead .r,.hero .masthead .r,.page-head .masthead .r{display:none}
  .tl-row{grid-template-columns:1fr;gap:8px}
}
@media (max-width:620px){
  .team-grid{grid-template-columns:1fr}
  .member.lead{grid-template-columns:1fr;gap:16px;padding:28px}
  .member.lead .av{width:64px;height:64px;font-size:20px}
  /* Restore spacing rhythm that the desktop overrides (.member.lead .role
     and .member.lead .lead-bio both pinned margin-top:0 for the 3-column
     grid layout) so the lead card reads with the same vertical cadence
     as the co-founder .member cards below. */
  .member.lead .role{margin-top:20px}
  .member.lead .member-head h3{margin-top:6px}
  .member.lead .lead-bio{margin-top:12px}
  /* The lead-bio-wrap uses height:100% + space-between on desktop so the
     "More detail" button pins to the bottom of the bio column. In a single
     column at this width that creates unwanted stretch + button position
     jump — relax it. */
  .member.lead .lead-bio-wrap{height:auto;justify-content:flex-start}
  .member.lead .lead-bio-wrap .profile-link{margin-top:16px}
}
@media (max-width:560px){
  .nav-cta .btn{display:none}
  .stat-grid{grid-template-columns:1fr}
  .stat{border-left:0!important;border-top:var(--rule-w) solid var(--rule)}
  .stat:first-child{border-top:0}
  .site-footer .foot-grid{grid-template-columns:1fr}
  .nav-cta{gap:8px}
  .ct-toggle .ct-label{display:none}
  .ct-toggle{padding:0 12px}
  .awards-grid{grid-template-columns:1fr}
  .award-item{flex:0 0 100%}
  .feature-pills{flex-wrap:wrap}
  .feature-pills .pill{flex:0 0 50%;border-bottom:1px solid rgba(255,255,255,.1)}
}
@media (min-width:561px) and (max-width:820px){
  .site-footer .foot-grid{grid-template-columns:1fr 1fr;gap:30px;padding:46px 0 24px}
}
@media (max-width:430px){
  .nav .lockup .logo-lockup{height:32px}
}
/* ============================================================
   ULTRA-NARROW BREAKPOINTS (480px & below)
   Guarantees clean single-column layout, safe text wrapping,
   stacked buttons, and full-bleed media on the smallest
   mobile screens (iPhone SE, small Androids in portrait).
   ============================================================ */
@media (max-width:480px){
  /* Base — reduce gutter, type scale, padding so nothing bleeds
     outside the viewport. word-wrap prevents any oversized token
     from breaking the grid. */
  :root{--gutter:14px;--text-md:15px;--text-lg:16px;--text-xl:18px;--text-2xl:22px;--text-3xl:26px;--text-4xl:32px}
  html,body{overflow-x:clip;max-width:100%}
  h1,h2,h3,h4{word-break:break-word;overflow-wrap:anywhere;hyphens:auto}
  p,li,blockquote,span,a,button{overflow-wrap:break-word;word-break:break-word}

  /* Section padding — increase vertical breathing room between
     different-color sections on mobile (was 44px). */
  .sec{padding:60px 0}
  .container{padding:0 20px;max-width:100%}

  /* ---------- Header / Nav ---------- */
  .nav .row{min-height:60px;gap:8px;flex-wrap:nowrap}
  .nav .lockup .logo-lockup{height:32px}
  .nav-toggle{width:40px;height:40px;margin-right:0;flex-shrink:0}
  .nav-toggle .bi{font-size:22px}
  .nav #primaryNav{left:0;right:0}
  .nav #primaryNav .nav-links{padding:8px 16px 14px}
  .nav #primaryNav .nav-links a{padding:14px 4px;min-height:48px;font-size:13px}
  .nav-cta{gap:6px;flex-shrink:0}
  .ct-toggle{min-height:40px;padding:0 10px;font-size:11px;gap:6px}
  .ct-toggle .bi{font-size:15px}
  .ct-toggle .ct-label{display:none}

  /* ---------- Hero / Page-head ---------- */
  .masthead,.hero .masthead,.page-head .masthead{padding:14px 0;font-size:11px;letter-spacing:.1em}
  .masthead .r,.hero .masthead .r,.page-head .masthead .r{display:none}
  .hero-main{padding:32px 0 0}
  .hero h1{font-size:clamp(34px,10vw,48px);letter-spacing:-.03em;max-width:14ch}
  .hero .zh{font-size:clamp(20px,6vw,30px);margin-top:.18em}
  .hero .lede{font-size:var(--text-lg)}
  .page-head .inner{padding:32px 0 28px;gap:18px}
  .page-head h1{font-size:clamp(34px,9vw,54px);max-width:12ch}
  .page-head h1.loose{font-size:clamp(30px,8vw,48px)}
  .page-head .zh{font-size:clamp(20px,5.5vw,30px)}
  .page-head .lede{font-size:var(--text-lg)}

  /* ---------- Hero-split (product page) ---------- */
  .hero-split{padding:32px 0}
  .hero-grid-split{grid-template-columns:1fr;gap:24px}
  .hero-content{order:1}
  .hero-visual{order:2}
  .hero-desc{font-size:var(--text-lg);margin-top:14px}
  .hero-actions{flex-direction:column;align-items:stretch;gap:10px;margin-top:20px}
  .hero-actions .btn{width:100%;justify-content:center}
  .hero-toggle-row{margin-top:24px;padding-top:18px}
  .hero-toggle-row .mode-toggle{margin-top:0;padding-top:0}
  .toggle-switch{flex-direction:column;max-width:100%;gap:10px}
  .toggle-btn{border-right-width:var(--rule-w)!important;width:100%;min-height:48px}
  .hero-visual{margin-top:18px}

  /* ---------- Buttons in general ---------- */
  .btn{min-height:48px;padding:0 18px;font-size:15px}
  .btn-lg{min-height:54px;padding:0 22px;font-size:16px}

  /* ---------- Stat grid ---------- */
  .stat-grid{grid-template-columns:1fr}
  .stat{padding:24px 18px;border-left:0!important;border-top:var(--rule-w) solid var(--rule)}
  .stat:first-child{border-top:0}
  .stat .num{font-size:clamp(28px,9vw,40px)}
  .stat .lbl{font-size:14px;margin-top:10px}

  /* ---------- Values / Voices / Visual / Retail grids ---------- */
  .values-grid,.voices-grid,.visual-grid,.retail-grid{grid-template-columns:1fr}
  .value,.voice-card,.visual-card,.retail-card{border-left:0;border-top:var(--rule-w) solid var(--rule);padding:24px 18px}
  .value:first-child,.voice-card:first-child,.visual-card:first-child,.retail-card:first-child{border-top:0}
  .value h3,.voice-card blockquote,.retail-card h3,.visual-card h3{font-size:var(--text-lg)}
  .voice-card .mk{font-size:44px;height:26px}
  /* Voice card on mobile: a touch more air above the quote
     and a clearer gap between the quote and the byline. */
  .voice-card blockquote{margin-top:12px}
  .voice-card .who{margin-top:32px}
  .retail-card .idx{font-size:clamp(22px,7vw,30px)}

  /* ---------- feature-visuals / awards ---------- */
  .feature-visuals,.awards-grid{grid-template-columns:1fr;gap:14px}
  .award-item{flex:0 0 100%;padding:18px 14px;min-width:0}
  .feature-visual-card{padding:18px}
  .feature-visual-card .visual-placeholder{aspect-ratio:16/9}

  /* ---------- Team grid ---------- */
  .team-grid{grid-template-columns:1fr}
  .member{padding:22px 18px 26px}
  .member.lead{grid-template-columns:1fr;gap:14px;padding:24px 18px}
  .member.lead .av{width:60px;height:60px;font-size:18px}
  .member.lead h3{font-size:var(--text-xl)}
  .member.lead .role{margin-top:16px;font-size:11px}
  .member.lead .member-head h3{margin-top:6px}
  .member.lead .lead-bio{font-size:var(--text-md);max-width:none;grid-column:auto;margin-top:12px}
  /* Same single-column relax as at 620px — keep the bio + button grouped
     tightly so they read as one stackable unit below the avatar block. */
  .member.lead .lead-bio-wrap{height:auto;justify-content:flex-start}
  .member.lead .lead-bio-wrap .profile-link{margin-top:16px}

  /* ---------- Spotlight / Feature rows ---------- */
  .spotlight{grid-template-columns:1fr;gap:24px;padding:28px 20px}
  .spotlight h2{font-size:clamp(24px,7vw,36px)}
  .spotlight p{font-size:var(--text-md)}
  .feature{grid-template-columns:1fr;gap:6px;padding:22px 0}
  .feature h3{font-size:var(--text-lg)}
  .feature p{font-size:14px}

  /* ---------- Timeline ---------- */
  .timeline-item,.tl-row{grid-template-columns:1fr;gap:6px;padding:20px 0}
  .tl-row .when{font-size:var(--text-md)}

  /* ---------- Founder msg ---------- */
  .founder-msg{padding:36px 0}
  .founder-msg .inner{grid-template-columns:1fr;gap:14px}
  .founder-msg .mk{font-size:54px}
  .founder-msg blockquote{font-size:var(--text-lg)}

  /* ---------- FAQ ---------- */
  .faq-item summary{padding:18px 0;font-size:var(--text-md)}
  .faq-item p{padding:0 0 18px;font-size:14px}

  /* ---------- Device frame / mockups ---------- */
  .device-frame{width:100%;max-width:100%}
  .device-screen{padding:14px}
  .app-interface{min-height:160px}
  .feature-pills{flex-wrap:wrap}
  .feature-pills .pill{flex:0 0 50%;padding:12px 6px;font-size:9px;border-bottom:1px solid rgba(255,255,255,.1)}

  /* ---------- Awards slider text badges ---------- */
  .trust .award-item.award-text{min-width:160px;height:48px;padding:0 14px;font-size:10px}
  .trust .award-item img{height:52px;max-height:52px}
  .trust .award-item img.logo-hkust-ec{height:40px}
  .trust .award-item img.logo-award-highlight{height:64px;max-height:64px}
  .trust .award-item.award-logo{height:64px}
  .trust .award-item.award-logo img{height:38px}
  .trust .award-slider::before,.trust .award-slider::after{width:60px}

  /* ---------- contact.html trust info row ----------
     The text-only .trust row on contact.html (EMAIL / HK / Pilot enquiries)
     uses a 30px column gap which is too wide for sub-600px viewports and
     pushes items past the container edge. Tighten the gap, hide the slashes,
     centre the items, and trim padding so the text reads cleanly on iPhone
     SE / 12 / 13 / 14 widths. */
  .trust{padding:16px 0;box-sizing:border-box}
  .trust .row{gap:24px 14px;font-size:11px;letter-spacing:.06em;padding:14px 0;justify-content:center;text-align:center}
  .trust .sep{display:none}
  /* On very narrow phones (<480px) drop the type scale another notch and
     tighten line-height so three short lines stack with no awkward gap. */
  .trust .row{line-height:1.5;padding:12px 0}
  .trust .row > span{display:inline-block}

  /* ---------- CTA / dynamic-cta ----------
     The 480px override preserves a 20px horizontal gutter (matches the
     20px set on .container at this breakpoint). Without an explicit
     horizontal value, the default `padding:44px 0` would let the
     full-width buttons touch the screen edges on small phones — the
     exact bug this rule was added to prevent. */
  .cta .inner,.dynamic-cta .inner{padding:44px 20px;width:100%}
  .cta h2,.dynamic-cta h2{font-size:clamp(26px,8vw,36px)}
  .cta p,.dynamic-cta p{font-size:var(--text-md);margin-top:12px}
  .cta-actions{flex-direction:column;align-items:stretch;gap:10px;margin-top:22px;padding:0;width:100%;max-width:100%;box-sizing:border-box}
  .cta-actions .btn{width:100%;max-width:100%;justify-content:center;box-sizing:border-box}
  .cta-actions .btn i{display:none}
  .cta-label{font-size:12px}

  /* ---------- Footer ---------- */
  .site-footer .foot-grid{grid-template-columns:1fr;gap:24px;padding:40px 0 20px}
  .site-footer h4{margin-bottom:10px}
  .site-footer ul{gap:8px}
  .site-footer .foot-links a{font-size:14px}
  .site-footer .foot-bottom{flex-direction:column;align-items:flex-start;gap:8px;padding:16px 0;font-size:11px}

  /* ---------- Footer / trust safe gutters ----------
     The .container rule above caps horizontal padding at 16px on phones.
     That is enough for most sections, but .foot-grid and .foot-bottom
     sit *inside* .container with their own padding-left/right set to 0,
     so the only thing keeping the text off the screen edge is that 16px.
     Bump it to 20px here so brand / links / copyright / trust info all
     read with a consistent safe gutter on 375 / 390 / 414 / 428 viewports. */
  .site-footer .container,
  .trust .container{padding-left:20px;padding-right:20px}
  .site-footer .foot-grid{padding-left:0;padding-right:0}
  .site-footer .foot-bottom{padding-left:0;padding-right:0}
  .trust .row{padding-left:0;padding-right:0}

  /* ---------- Chips / tags ---------- */
  .chip{padding:5px 10px;font-size:11px}
  .hero-badges{gap:8px}
}

/* Mid-narrow breakpoint — bridges 720px and 480px to ensure
   iPhone 12/13/14 Pro Max (430px) and large Android (540px)
   land in a clean single-column layout without horizontal
   overflow. */
@media (max-width:720px) and (min-width:481px){
  :root{--gutter:18px}
  .hero-actions{flex-wrap:wrap}
  .hero-actions .btn{flex:1 1 calc(50% - 7px);min-width:0}
  .cta-actions{flex-direction:row;flex-wrap:wrap;justify-content:center;width:100%;max-width:100%;box-sizing:border-box}
  .cta-actions .btn{flex:1 1 220px;max-width:100%;box-sizing:border-box}
}

/* Tablet / large phone breakpoint — 769-768px and below.
   Adds a dedicated 20px container gutter so content stays clear
   of screen edges on iPad mini portrait and most Android phones.
   Forces single-column, centred alignment on the contact.html
   trust info row so the EMAIL / HK / Pilot lines never bleed
   past the container. */
@media (max-width:768px){
  .container{padding-left:20px;padding-right:20px}
  .trust{padding:16px 0;box-sizing:border-box}
  .trust .row{gap:10px 18px;justify-content:center;text-align:center;padding:14px 20px;box-sizing:border-box}
  .trust .sep{opacity:.3}
  /* .cta / .dynamic-cta .inner defaults to `padding:... var(--gutter)` —
     force an explicit 20px horizontal gutter at this breakpoint so the
     full-width CTA buttons never bleed past the screen edge on tablets
     and large phones in portrait. */
  .cta .inner,.dynamic-cta .inner{padding-left:20px;padding-right:20px;box-sizing:border-box}
  .cta-actions{padding-left:0;padding-right:0;box-sizing:border-box}
}
/* ============ HERO SPLIT LAYOUT (desktop) ============
   Scoped to min-width:901px so the two-column side-by-side
   layout is reserved for tablet/desktop. The narrower media
   queries below (max-width:900px / 720px / 480px) flip the
   grid to a single column and stack the iPhone under the
   title. Because these mobile rules also set grid-template-
   columns, the wrapping here is what guarantees the mobile
   styles win on phones — without it the un-scoped rules
   below would override the mobile overrides because of CSS
   source-order tie-breaking. */
@media (min-width:901px){
  .hero-split{padding:clamp(40px,6vw,72px) 0;border-bottom:var(--rule-w) solid var(--rule)}
  .hero-grid-split{
    display:grid;grid-template-columns:1.1fr .9fr;gap:48px;align-items:center;
  }
  .hero-content{order:1}
  .hero-visual{order:2}
}
.hero-desc{
  font-size:var(--text-xl);color:var(--ink-soft);max-width:46ch;margin-top:20px;
}
.hero-actions{display:flex;gap:14px;flex-wrap:wrap;margin-top:28px}

/* Mode Toggle — generic (now lives inside .hero-toggle-row on product page) */
.mode-toggle{
  display:flex;flex-direction:column;align-items:center;text-align:center;
}
.mode-toggle .toggle-label{display:block;margin-bottom:12px}
.mode-toggle .toggle-switch{margin:0 auto}
.toggle-label{
  font-family:var(--font-mono);font-size:12px;text-transform:uppercase;letter-spacing:.1em;
  color:var(--ink-soft);display:block;margin-bottom:12px;
}
.toggle-switch{display:flex;gap:0;max-width:400px}
.toggle-btn{
  flex:1;display:flex;align-items:center;justify-content:center;gap:8px;
  padding:14px 20px;font-family:var(--font-body);font-weight:700;font-size:14px;
  white-space:nowrap;
  border:var(--rule-w) solid var(--ink);border-right-width:0;background:transparent;color:var(--ink);
  cursor:pointer;transition:background var(--dur-fast) var(--ease-out),color var(--dur-fast) var(--ease-out);
}
.toggle-btn:last-child{border-right-width:var(--rule-w)}
.toggle-btn:hover{background:var(--paper-2)}
.toggle-btn.active{background:var(--ink);color:var(--paper)}
.toggle-btn i{font-size:18px}

/* Device Frame */
.device-frame{
  background:var(--navy);border:var(--rule-w) solid var(--ink);overflow:hidden;
}
.device-header{
  display:flex;align-items:center;gap:12px;padding:12px 16px;
  background:rgba(0,0,0,.3);border-bottom:1px solid rgba(255,255,255,.1);
}
.device-dots{display:flex;gap:6px}
.device-dots span{width:10px;height:10px;border-radius:50%;background:rgba(255,255,255,.25)}
.device-title{
  font-family:var(--font-mono);font-size:11px;text-transform:uppercase;letter-spacing:.08em;
  color:rgba(255,255,255,.5);
}
.device-screen{padding:20px}
.app-interface{min-height:200px}
.app-status{
  display:flex;align-items:center;gap:8px;font-family:var(--font-mono);font-size:12px;
  color:rgba(255,255,255,.6);text-transform:uppercase;letter-spacing:.06em;margin-bottom:16px;
}
.waveform{
  display:flex;align-items:center;justify-content:center;gap:4px;height:48px;margin-bottom:20px;
}
.waveform span{
  flex:0 0 4px;height:100%;background:var(--accent);animation:wave 0.8s ease-in-out infinite alternate;
}
.waveform span:nth-child(1){animation-delay:0ms}
.waveform span:nth-child(2){animation-delay:100ms}
.waveform span:nth-child(3){animation-delay:200ms}
.waveform span:nth-child(4){animation-delay:300ms}
.waveform span:nth-child(5){animation-delay:400ms}
.waveform span:nth-child(6){animation-delay:300ms}
.waveform span:nth-child(7){animation-delay:200ms}
@keyframes wave{from{height:20%}to{height:100%}}
.conversation-bubble{
  padding:12px 16px;border-radius:12px;font-size:13px;line-height:1.5;
  margin-bottom:12px;max-width:90%;
}
.conversation-bubble.user{background:var(--el-blue-600);color:#fff;margin-left:auto}
.conversation-bubble.aeye{background:rgba(255,255,255,.12);color:#fff}
.conversation-bubble b{display:block;margin-bottom:4px}

/* Feature Pills */
.feature-pills{
  display:flex;gap:0;border-top:var(--rule-w) solid rgba(255,255,255,.1);
}
.feature-pills .pill{
  flex:1;display:flex;flex-direction:column;align-items:center;gap:6px;
  padding:14px 8px;font-family:var(--font-mono);font-size:10px;text-transform:uppercase;
  letter-spacing:.06em;color:rgba(255,255,255,.5);border-right:1px solid rgba(255,255,255,.1);
  background:transparent;cursor:pointer;transition:background var(--dur-fast),color var(--dur-fast);
}
.feature-pills .pill:last-child{border-right:0}
.feature-pills .pill:hover,.feature-pills .pill.active{background:rgba(255,255,255,.08);color:#fff}
.feature-pills .pill i{font-size:20px}

/* Awards Section */
.awards-section{
  background:var(--paper-2);border-top:var(--rule-w) solid var(--rule);border-bottom:var(--rule-w) solid var(--rule);
  padding:clamp(28px,4vw,44px) 0;
}
.awards-section .kicker{justify-content:center;margin-bottom:20px}
.awards-grid{
  display:flex;flex-wrap:wrap;justify-content:center;gap:0;
  border-top:var(--rule-w) solid var(--rule);border-left:var(--rule-w) solid var(--rule);
}
.award-item{
  flex:0 0 25%;min-width:200px;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:10px;padding:24px 20px;
  border-right:var(--rule-w) solid var(--rule);border-bottom:var(--rule-w) solid var(--rule);
  text-align:center;
}
.award-item i{font-size:28px;color:var(--navy-2)}
.award-item span{font-family:var(--font-mono);font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--ink-soft)}

/* ============================================================
   DESKTOP READABILITY — relax ch-capped paragraph widths
   --------------------------------------------------------------
   Many section / card paragraphs use a fixed max-width in ch
   to keep line lengths comfortable on phones. On wide desktop
   viewports those caps force line breaks while there is plenty
   of horizontal room left over (e.g. .custom-ui-block .ui-body p
   at 54ch was wrapping a ~96-char English sentence on product
   page User Journey connectors). The override below only runs
   on ≥901px, so the mobile breakpoints still see the original
   caps. The values are tuned per surface so each block keeps a
   sensible reading measure on big screens without exploding
   into a single 200-character line.
   ============================================================ */
@media (min-width:901px){
  /* Section headings + lede copy.
     .sec-head's mobile cap is 66ch; on wide viewports we let the
     heading stretch to the full container width and cap the
     inner h2 at 24ch so the title still wraps onto two lines
     instead of becoming one giant horizontal string. */
  .sec-head{max-width:none !important}
  .sec-head p{max-width:none !important}
  .sec-head h2{max-width:24ch}
  .faq-item p{max-width:86ch}

  /* Hero / page-head lede text (index, about, team, product) */
  .hero .lede{max-width:72ch}
  .page-head .lede{max-width:72ch}
  .hero-desc{max-width:78ch}
  .hero-split .hero-content .hero-desc{max-width:78ch}

  /* Product page card / feature copy */
  .feature p{max-width:84ch}
  .feature-compact .row p{max-width:84ch}
  .spotlight p{max-width:72ch}

  /* The User Journey connectors — root cause of the bug report */
  .custom-ui-block .ui-body p{max-width:none}

  /* Team + timeline + cta */
  .member.lead .lead-bio{max-width:68ch}
  .tl-row p{max-width:84ch}
  .timeline-content p{max-width:74ch}
  .cta p{max-width:74ch}

  /* Member profile pages — .profile-bio is intentionally width:100%
     (no max-width cap) so the three-section bio fills the full
     1180px container on desktop and reads at ~65ch. The mobile
     base rule keeps it full-width too; .container's own gutter
     protects the screen edge on small viewports. */
}

/* Flow Content Toggle */
.flow-content{display:none}
.flow-content.active{display:block}

/* Feature Visuals (inspired by 9.png) */
.feature-visuals{
  display:grid;grid-template-columns:repeat(3,1fr);gap:24px;margin-top:40px;
  border-top:var(--rule-w) solid var(--rule);padding-top:40px;
}
.feature-visual-card{
  background:var(--paper-2);border:var(--rule-w) solid var(--rule);padding:24px;
}
.feature-visual-card .visual-placeholder{
  width:100%;aspect-ratio:4/3;background:var(--navy);
  display:grid;place-items:center;margin-bottom:16px;position:relative;
}
.feature-visual-card .visual-placeholder i{font-size:40px;color:var(--accent)}
.feature-visual-card .star-badge{
  position:absolute;top:12px;right:12px;width:28px;height:28px;
  background:var(--accent);display:grid;place-items:center;color:var(--accent-ink);font-size:14px;
}
.feature-visual-card h4{font-size:var(--text-lg);margin-bottom:6px}
.feature-visual-card p{font-size:14px;color:var(--ink-soft)}

/* Dynamic CTA */
.dynamic-cta{background:var(--navy);border-top:var(--rule-w) solid var(--ink);border-bottom:var(--rule-w) solid var(--ink)}
/* Horizontal padding re-applies the .container gutter here — earlier this
   rule set only `padding:... 0` which clobbered .container's `padding:0
   var(--gutter)` and let buttons bleed to the screen edge on mobile.
   `box-sizing:border-box` keeps the 820px max-width honest when the
   horizontal padding is large on tablet (var(--gutter)=26px → 52px total). */
.dynamic-cta .inner{padding:clamp(56px,8vw,96px) var(--gutter);text-align:center;max-width:820px;margin:0 auto;box-sizing:border-box;width:100%}
.dynamic-cta .cta-label{
  font-family:var(--font-mono);font-size:14px;font-weight:700;text-transform:uppercase;
  letter-spacing:.12em;color:var(--accent);display:flex;align-items:center;justify-content:center;
  gap:10px;margin-bottom:20px;
}
.dynamic-cta h2{color:#fff;font-size:clamp(28px,5vw,48px);line-height:1.2;margin-top:0}
/* `width:100% + box-sizing:border-box + max-width:100%` guarantee that when
   .cta-actions goes single-column on mobile and buttons stretch to 100%
   width, the row stays inside the .inner safe area and never overflows
   the viewport or touches the screen edge. */
.dynamic-cta .cta-actions{display:flex;gap:14px;justify-content:center;flex-wrap:wrap;margin-top:36px;width:100%;max-width:100%;box-sizing:border-box}
.dynamic-cta .btn-primary{background:var(--accent);color:var(--ink);border-color:var(--accent)}
.dynamic-cta .btn-primary:hover{background:#FFD65C}
.dynamic-cta .btn-secondary{background:transparent;color:#fff;border-color:#fff}
.dynamic-cta .btn-secondary:hover{background:rgba(255,255,255,.1)}

/* Timeline */
.timeline{border-top:var(--rule-w) solid var(--rule)}
.timeline-item{
  display:grid;grid-template-columns:120px 1fr;gap:24px;padding:24px 0;
  border-bottom:var(--rule-w) solid var(--rule);align-items:start;
}
.timeline-item:last-child{border-bottom:0}
.timeline-marker{
  font-family:var(--font-mono);font-weight:700;font-size:var(--text-md);color:var(--navy-2);
  letter-spacing:.02em;padding-top:4px;
}
.timeline-content h4{font-size:var(--text-xl);margin-bottom:6px}
.timeline-content p{color:var(--ink-soft);max-width:52ch}

/* FAQ Enhancement */
.faq-list{border-top:var(--rule-w) solid var(--rule);max-width:820px}
.faq-item{border-bottom:var(--rule-w) solid var(--rule)}
.faq-item summary{
  cursor:pointer;list-style:none;padding:22px 0;font-family:var(--font-display);
  font-weight:700;font-size:var(--text-lg);display:flex;align-items:center;justify-content:space-between;gap:16px;
}
.faq-item summary::-webkit-details-marker{display:none}
.faq-item summary::after{content:"+";font-family:var(--font-mono);font-size:20px;color:var(--navy-2);flex-shrink:0}
.faq-item[open] summary::after{content:"−"}
.faq-item p{padding:0 0 22px;color:var(--ink-soft);max-width:62ch}

/* Stat Highlight */
.stat-highlight{margin-top:32px}
.stat-card{
  background:var(--paper-2);border:var(--rule-w) solid var(--rule);padding:28px 26px;max-width:600px;
}
.stat-card .lbl{font-size:var(--text-lg);color:var(--ink)}

/* Media Placeholder */
.media-placeholder{
  margin-top:16px;padding:20px;background:var(--paper-2);border:var(--rule-w) dashed var(--rule);
  display:flex;align-items:center;gap:12px;color:var(--ink-soft);font-family:var(--font-mono);
  font-size:12px;text-transform:uppercase;letter-spacing:.06em;
}

/* Button bolder */
.btn-bolder{font-weight:800}

/* Story Placeholder */
.story-placeholder{
  background:var(--paper-2);border:var(--rule-w) dashed var(--rule);padding:48px 32px;
  text-align:center;margin-top:24px;
}
.story-placeholder .placeholder-icon{
  display:inline-grid;place-items:center;width:56px;height:56px;
  background:var(--navy);color:var(--accent);font-size:24px;margin-bottom:16px;
}
.story-placeholder .placeholder-text{
  font-family:var(--font-display);font-size:var(--text-lg);color:var(--ink-soft);
  max-width:48ch;margin:0 auto;line-height:1.5;
}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  html.js-anim .reveal{opacity:1;transform:none;transition:none}
  .phone .wave span{animation:none;height:60%}
  .trust .award-slider .award-track{animation:none;transform:none}
  .trust .award-set[aria-hidden="true"]{display:none}
  .btn:hover{transform:none;box-shadow:none}
  *{animation-duration:.001ms !important;animation-iteration-count:1 !important;transition-duration:.001ms !important}
}

/* ============================================================
   v2.24 — Fix: side columns stay visible alongside the phone
   throughout the entire 400vh scrub, not only at the tail end.
   Must live at the END of styles-main.css so it loads after the
   v2.22 `align-items: center` rule and wins the cascade.
   ============================================================ */
@media (min-width: 901px){
  /* 統一 nav offset，讓 sticky phone 與側邊欄共用同一個吸附基準 */
  #experience,
  #experience .xp-sticky-root{
    --xp-nav-offset: 96px;
  }

  /* 明確把 row 對齊由 center 改為 start —— 這是本 bug 的根本修正。
     只有 align-items:start 能讓 .xp-copy / .xp-highlight 這兩個
     矮的 grid item 停在 400vh row 的頂端，配合下面的 sticky 才能
     在整個跑道期間吸附在視口中。 */
  #experience .xp-layout{
    display: grid !important;
    grid-template-columns:
      minmax(220px, 1fr)
      minmax(320px, 1.15fr)
      minmax(220px, 1fr) !important;
    grid-template-rows: 1fr !important;
    align-items: start !important;        /* ★★ 關鍵 ★★ */
    gap: clamp(20px, 3vw, 40px) !important;
    overflow: visible !important;
  }

  /* 兩側欄：sticky 吸附於 nav 下方，不建立內部 scroll container */
  #experience .xp-copy,
  #experience .xp-highlight{
    position: sticky !important;
    top: calc(var(--xp-nav-offset) + 24px) !important;
    align-self: start !important;         /* ★★ 關鍵 ★★ */
    max-height: calc(100vh - var(--xp-nav-offset) - 48px) !important;
    height: fit-content !important;
    overflow: visible !important;         /* 取消 scroll container，讓 sticky 不被中斷 */
    box-sizing: border-box !important;
  }

  /* 明確指定兩側欄的 grid column（v2.24 殘留，flexbox 下已無效，但保留不影響） */
  /* 2026-09-20: 已由 v2.26 的 flex order 接管，grid-column 在 flex 中被忽略 */

  /* 保險：stage 必須是普通流、無 sticky、無 filter/transform/will-change，
     否則會成為子層 sticky 的 containing block，破壞 .phone-scroll-sticky
     與 .xp-copy 的視窗級吸附。 */
  #experience .xp-sticky-stage{
    position: relative !important;
    top: auto !important;
    overflow: visible !important;
    contain: none !important;
    transform: none !important;
    filter: none !important;
    will-change: auto !important;
    perspective: none !important;
  }

  /* 防禦：隱藏 #experience 內的 .xp-scroll-track / .xp-pin，
     它們是殘留物，會佔據額外高度，干擾跑道計算。 */
  #experience .xp-scroll-track,
  #experience .xp-pin{
    display: none !important;
    height: 0 !important;
    min-height: 0 !important;
  }
}

/* ============================================================
   v2.25 — Force all three #experience columns into grid row 1
   Root cause: v2.24 only set grid-column (not grid-row), so the
   grid auto-placement pushed .xp-copy and .xp-highlight into an
   implicit second row (289px tall). Their sticky range was then
   capped at 289px, releasing long before the 400vh phone runway
   ended — which is why the user only saw them AFTER scrolling
   past the phone.

   Fix: use named grid areas so all three children are locked to
   row 1. grid-template-rows becomes `auto` (height determined by
   the tallest cell = the phone at 400vh), which gives the two
   side columns a full 400vh sticky range.
   ============================================================ */
@media (min-width: 901px){
  #experience,
  #experience .xp-sticky-root{
    --xp-nav-offset: 96px;
  }

  #experience .xp-layout{
    display: grid !important;
    grid-template-columns:
      minmax(220px, 1fr)
      minmax(360px, 1.15fr)
      minmax(220px, 1fr) !important;
    grid-template-areas: "copy phone highlight" !important;
    grid-template-rows: auto !important;   /* ★ 由手機決定行高（~400vh），不再用 1fr */
    align-items: start !important;
    gap: clamp(24px, 3vw, 44px) !important;
    overflow: visible !important;
    contain: none !important;
  }

  /* ★ 用 grid-area 鎖定三個子元素到第一行，杜絕 auto-placement 意外 */
  #experience .xp-copy                { grid-area: copy !important; }
  #experience .phone-scroll-container { grid-area: phone !important; }
  #experience .xp-highlight           { grid-area: highlight !important; }

  /* 兩側欄：sticky 吸附於 nav 下方，貫穿整個跑道 */
  #experience .xp-copy,
  #experience .xp-highlight{
    position: sticky !important;
    top: calc(var(--xp-nav-offset) + 24px) !important;
    align-self: start !important;
    height: fit-content !important;
    max-height: calc(100vh - var(--xp-nav-offset) - 48px) !important;
    overflow: visible !important;
    box-sizing: border-box !important;
    z-index: 2;
  }

  /* 手機（保持上一輪已修好的置中與吸附） */
  #experience .phone-scroll-container{
    margin: 0 auto !important;
    width: 100% !important;
    max-width: 100% !important;
  }
  #experience .phone-scroll-sticky{
    position: sticky !important;
    top: var(--xp-nav-offset) !important;
    height: calc(100vh - var(--xp-nav-offset)) !important;
    display: flex !important;
    flex-direction: column !important;
    align-items: center !important;
    justify-content: center !important;
    box-sizing: border-box !important;
    padding: 0 !important;
    margin: 0 !important;
    background: transparent !important;
    overflow: visible !important;
  }

  /* stage 必須是普通流 */
  #experience .xp-sticky-stage{
    position: relative !important;
    top: auto !important;
    overflow: visible !important;
    contain: none !important;
    transform: none !important;
    filter: none !important;
    will-change: auto !important;
    perspective: none !important;
  }

  /* 防禦：隱藏 #experience 內殘留的 track / pin */
  #experience .xp-scroll-track,
  #experience .xp-pin{
    display: none !important;
    height: 0 !important;
    min-height: 0 !important;
  }
}

/* ============================================================
   v2.26 — #experience three-column via FLEXBOX + vertical centering

   Why: In CSS Grid with `align-self: start`, .xp-copy / .xp-highlight
   have their own box height = content height. Some Chromium builds
   treat sticky's containing block as only the item's own occupied
   grid area (286px) instead of the full grid area (3676px). Sticky
   range collapses to 0 → side columns scroll away with the page.

   Fix: use flex row. sticky's containing block becomes the flex
   container (.xp-layout, height = tallest item = 400vh phone), so
   the sticky range matches the full runway.

   Centering: side columns get height = 100vh - nav-offset and use
   flex column justify-content:center, matching the phone's behavior.
   ============================================================ */
@media (min-width: 901px){
  #experience,
  #experience .xp-sticky-root{
    --xp-nav-offset: 96px;
  }

  /* Flex row — no grid auto-placement, no sticky-range collapse */
  #experience .xp-layout{
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    align-items: flex-start !important;
    justify-content: space-between !important;
    gap: clamp(24px, 3vw, 44px) !important;
    /* 清掉所有 grid 相關屬性，避免 v2.25 殘留 */
    grid-template-areas: none !important;
    grid-template-columns: none !important;
    grid-template-rows: none !important;
    overflow: visible !important;
    contain: none !important;
  }

  /* ★ 修改 A — 明確鎖定三欄 flex order，讓 DOM 源順序 = 視覺順序
     order: 1 = .xp-copy（左欄）, 2 = 手機（中間）, 3 = .xp-highlight（右欄） */
  #experience .xp-copy{
    order: 1 !important;
    flex: 0 0 auto !important;
    /* 修改 B — 加寬到 320-420px，確保英文長句正常換行 */
    width: clamp(320px, 30%, 420px) !important;
    align-self: flex-start !important;
    position: sticky !important;
    top: var(--xp-nav-offset) !important;
    height: calc(100vh - var(--xp-nav-offset)) !important;
    display: flex !important;
    flex-direction: column !important;
    justify-content: center !important;
    align-items: flex-start !important;
    gap: 0 !important;
    padding: 0 !important;
    margin: 0 !important;
    overflow: visible !important;
    box-sizing: border-box !important;
    z-index: 2;
  }

  /* 中欄：手機跑道 */
  #experience .phone-scroll-container{
    order: 2 !important;
    flex: 1 1 auto !important;
    min-width: 0 !important;
    width: auto !important;
    max-width: 100% !important;
    margin: 0 auto !important;
    align-self: flex-start !important;
    /* 清除 grid-column 殘留 */
    grid-column: auto !important;
  }

  /* ★ 修改 A — 右欄：黃底整體卡片，高度自適應內容，垂直居中於剩餘視口 */
  #experience .xp-highlight{
    order: 3 !important;
    flex: 0 0 auto !important;
    /* 修改 B — 對稱加寬到 280-360px */
    width: clamp(280px, 26%, 360px) !important;
    align-self: stretch !important;
    position: sticky !important;
    top: var(--xp-nav-offset) !important;
    /* 容器撐滿視口（保持 stretch）— 用 flex 居中卡組 */
    height: calc(100vh - var(--xp-nav-offset)) !important;
    display: flex !important;
    flex-direction: column !important;
    justify-content: center !important;
    align-items: stretch !important;
    padding: 0 !important;
    margin: 0 !important;
    min-height: 0 !important;
    overflow: visible !important;
    box-sizing: border-box !important;
    background: transparent !important;
    border: 0 !important;
    z-index: 2;
  }

  /* ★ 任務 3：黃底整體卡片群組（使用 .xp-highlight-card wrapper）
     黃底、邊框只放在 wrapper 上；label/text 純文字，絕對不會視覺斷開 */
  #experience .xp-highlight-card,
  #retail-dashboard .xp-highlight-card{
    background: var(--accent) !important;
    border: var(--rule-w) solid var(--ink) !important;
    margin: 0 !important;
    padding: 0 !important;
    display: block !important;
    width: 100% !important;
    box-sizing: border-box !important;
  }
  #experience .xp-highlight > .xp-highlight-card > .xp-highlight-label,
  #experience .xp-highlight > .xp-highlight-card > .xp-highlight-text,
  #retail-dashboard .xp-highlight > .xp-highlight-card > .xp-highlight-label,
  #retail-dashboard .xp-highlight > .xp-highlight-card > .xp-highlight-text{
    background: transparent !important;
    border: 0 !important;
    margin: 0 !important;
    display: block !important;
    width: 100% !important;
    box-sizing: border-box !important;
  }
  #experience .xp-highlight > .xp-highlight-card > .xp-highlight-label,
  #retail-dashboard .xp-highlight > .xp-highlight-card > .xp-highlight-label{
    padding: 10px clamp(18px, 2.5vw, 28px) 8px !important;
  }
  #experience .xp-highlight > .xp-highlight-card > .xp-highlight-text,
  #retail-dashboard .xp-highlight > .xp-highlight-card > .xp-highlight-text{
    padding: 4px clamp(18px, 2.5vw, 28px) clamp(18px, 2.5vw, 28px) !important;
    line-height: 1.25 !important;
  }

  /* 清除 grid-column 殘留（flexbox 下無效但避免衝突） */
  #experience .xp-copy,
  #experience .phone-scroll-container,
  #experience .xp-highlight{
    grid-column: auto !important;
  }

  /* 修改 C — 放寬 .xp-beat 文字限制 + 為左欄子元素增加間距 */
  #experience .xp-beat-desc{
    max-width: none !important;
    font-size: 16px !important;
    line-height: 1.55 !important;
    word-spacing: normal !important;
    letter-spacing: normal !important;
  }
  #experience .xp-beat h3{
    font-size: clamp(24px, 2.6vw, 34px) !important;
    white-space: normal !important;
    word-spacing: normal !important;
    letter-spacing: -.01em !important;
    line-height: 1.2 !important;
    margin-bottom: 12px !important;
  }
  /* 確保 .xp-beats 容器不被絕對定位的兄弟節點擠壓高度 */
  #experience .xp-beats{
    min-height: auto !important;
    width: 100% !important;
    overflow: visible !important;
  }
  #experience .xp-beat{
    width: 100% !important;
    word-wrap: break-word !important;
    overflow-wrap: break-word !important;
  }

  /* ★ 新增：左欄內部子元素垂直間距 */
  #experience .xp-copy{
    gap: 18px !important;
  }
  #experience .xp-step-status{
    margin-bottom: 4px !important;
  }
  #experience .xp-beats{
    margin: 0 !important;
  }
  #experience .xp-progress{
    margin-top: 6px !important;
    gap: 12px !important;
  }

  /* ★ 新增：.xp-beat 內部元素間距（kicker / h3 / desc） */
  #experience .xp-beat .xp-beat-kicker{
    margin: 0 0 14px !important;
  }
  #experience .xp-beat.is-active{
    position: relative !important;
    display: block !important;
    width: 100% !important;
  }

  /* 手機（保持置中與吸附） */
  #experience .phone-scroll-sticky{
    position: sticky !important;
    top: var(--xp-nav-offset) !important;
    height: calc(100vh - var(--xp-nav-offset)) !important;
    display: flex !important;
    flex-direction: column !important;
    align-items: center !important;
    justify-content: center !important;
    box-sizing: border-box !important;
    padding: 0 !important;
    margin: 0 !important;
    background: transparent !important;
    overflow: visible !important;
  }

  /* stage 保持普通流 */
  #experience .xp-sticky-stage{
    position: relative !important;
    top: auto !important;
    overflow: visible !important;
    contain: none !important;
    transform: none !important;
    filter: none !important;
    will-change: auto !important;
    perspective: none !important;
  }

  /* 隱藏 #experience 內殘留的 track / pin */
  #experience .xp-scroll-track,
  #experience .xp-pin{
    display: none !important;
    height: 0 !important;
    min-height: 0 !important;
  }
}

/* ============================================================
   v2.27 — #validation 引言卡片全寬修復
   確保 #validation 內的 .voice-card 不被任何祖先寬度限制壓縮
   ============================================================ */
#validation .voice-card{
  width: 100% !important;
  max-width: none !important;
  box-sizing: border-box !important;
  display: block !important;
}

#validation .voice-card blockquote{
  width: 100% !important;
  max-width: none !important;
  box-sizing: border-box !important;
  display: block !important;
}

/* 保險：若 .voice-card 被誤加入 .pain-callout class（或反之），
   #validation 內一律不受 720px 限制 */
#validation .voice-card.pain-callout{
  max-width: none !important;
}

/* ============================================================
   v2.28 — 刪除 #experience 標題與手機之間的殘留白色文字
   .phone-scroll-caption 原設計為深色 Hero 底上的白色標題條，
   現在被置入奶油色 #experience 中會變成極淡的視覺雜訊，
   因此在使用者體驗區塊中隱藏它。
   ============================================================ */
#experience .phone-scroll-caption,
#experience .phone-scroll-index,
#experience .phone-scroll-title,
#experience .phone-scroll-hint{
  display: none !important;
}

/* 若未來在 #experience 中重新引入 caption，務必改用 --ink 深色文字，
   而非舊版 Hero 的白色文字，否則會再次變成「看不見的雜訊」：
   #experience .phone-scroll-caption{ color: var(--ink-soft); }
   #experience .phone-scroll-index,
   #experience .phone-scroll-title{ color: var(--ink); } */

/* ============================================================
   v4.1 — 手機版 Hero CTA：2 欄 Grid 佈局
   ============================================================
   目標（僅 ≤900px）：
     - .btn:first-child（免費體驗先導計劃）→ 跨 2 欄獨佔一行
     - 其餘兩顆（觀看實際示範 / 成為合作商戶）→ 各佔 1 欄並排
   桌面版（≥901px）不受影響，仍為 flex 橫向一行。

   ⚠️ Specificity 備註：
   hero-cinematic.css 第 815 / 1097 行已有
   `.hero-cinematic .hero-actions { display: grid !important; ... }`
   specificity 為 (0,2,0)。本區塊使用 `body ` 與重複 class 將
   specificity 提升至 (0,3,1)，確保在 source-order 較晚載入下
   仍能擊敗 hero-cinematic.css。
   ============================================================ */
@media (max-width: 900px){
  body .hero-split .hero-actions,
  body .hero-cinematic .hero-actions,
  body .hero-actions,
  body .cine-stage .hero-actions{
    display: grid !important;
    grid-template-columns: 1fr 1fr !important;
    grid-auto-rows: auto;
    gap: 8px 10px !important;
    align-items: stretch !important;
    justify-content: stretch !important;
    /* 取消先前所有 flex 相關設定 */
    flex-wrap: nowrap !important;
    flex-direction: row !important;
  }

  /* 第一顆按鈕跨滿兩欄 */
  body .hero-split .hero-actions .btn:first-child,
  body .hero-cinematic .hero-actions .btn:first-child,
  body .hero-actions .btn:first-child,
  body .cine-stage .hero-actions .btn:first-child{
    grid-column: 1 / -1 !important;
    width: 100% !important;
    min-width: 0 !important;
    /* 略放大主 CTA 以突顯優先層級 */
    min-height: 48px !important;
    padding: 12px 14px !important;
    font-size: 14px !important;
    line-height: 1.2 !important;
    justify-content: center !important;
    gap: 6px !important;
  }

  /* 其餘兩顆按鈕各佔 1 欄 */
  body .hero-split .hero-actions .btn:not(:first-child),
  body .hero-cinematic .hero-actions .btn:not(:first-child),
  body .hero-actions .btn:not(:first-child),
  body .cine-stage .hero-actions .btn:not(:first-child){
    grid-column: auto !important;
    width: 100% !important;
    min-width: 0 !important;
    min-height: 44px !important;
    padding: 10px 10px !important;
    font-size: 12.5px !important;
    line-height: 1.2 !important;
    justify-content: center !important;
    gap: 5px !important;
    /* 允許長文字自然換行（例如「成為合作商戶」） */
    white-space: normal !important;
    text-align: center !important;
  }

  /* 圖示在窄按鈕內縮小 */
  body .hero-split .hero-actions .btn i,
  body .hero-cinematic .hero-actions .btn i,
  body .hero-actions .btn i,
  body .cine-stage .hero-actions .btn i{
    font-size: 13px !important;
    margin-right: 4px !important;
    flex-shrink: 0;
  }

  /* 防禦：如頁面使用 .btn-lg 也一併套用 */
  body .hero-split .hero-actions .btn-lg:first-child,
  body .hero-cinematic .hero-actions .btn-lg:first-child,
  body .hero-actions .btn-lg:first-child,
  body .cine-stage .hero-actions .btn-lg:first-child{
    grid-column: 1 / -1 !important;
  }
  body .hero-split .hero-actions .btn-lg:not(:first-child),
  body .hero-cinematic .hero-actions .btn-lg:not(:first-child),
  body .hero-actions .btn-lg:not(:first-child),
  body .cine-stage .hero-actions .btn-lg:not(:first-child){
    grid-column: auto !important;
  }
}

/* 極窄螢幕（≤380px）再縮一級字級，避免英文換行破字 */
@media (max-width: 380px){
  body .hero-split .hero-actions .btn:first-child,
  body .hero-cinematic .hero-actions .btn:first-child,
  body .hero-actions .btn:first-child,
  body .cine-stage .hero-actions .btn:first-child{
    font-size: 13px !important;
    min-height: 44px !important;
    padding: 10px 10px !important;
  }
  body .hero-split .hero-actions .btn:not(:first-child),
  body .hero-cinematic .hero-actions .btn:not(:first-child),
  body .hero-actions .btn:not(:first-child),
  body .cine-stage .hero-actions .btn:not(:first-child){
    font-size: 11.5px !important;
    padding: 8px 6px !important;
  }
  body .hero-split .hero-actions .btn i,
  body .hero-cinematic .hero-actions .btn i,
  body .hero-actions .btn i,
  body .cine-stage .hero-actions .btn i{
    font-size: 12px !important;
    margin-right: 3px !important;
  }
}
