:root{
  --bg:#f5f6f7; --bg2:#e9ebed; --ink:#16181a; --muted:#565c61;
  --red:#9a2a28; --red-bright:#b3322f; --line:#d9dcde;
}
*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  background:radial-gradient(120% 90% at 50% 0%, #ffffff 0%, var(--bg) 55%, var(--bg2) 100%);
  color:var(--ink);
  font-family:"Helvetica Neue",-apple-system,"PingFang TC","Microsoft JhengHei",sans-serif;
  -webkit-font-smoothing:antialiased; overflow-x:hidden;
}
/* fixed 3D stage. The HTML hero text still paints first (LCP is never gated on
   the GLB). While the model loads, an ambient backdrop fills this region (never
   blank); on ready the backdrop cross-fades out as the live canvas fades in. */
#stage{position:fixed; inset:0; z-index:0}
canvas{display:block}

/* C — ambient loading backdrop: a calm, low-key glow in the site palette that
   reads as "loading ambiance" (NOT a model screenshot). Pure CSS, no image, so
   it can't gate LCP. While the model loads it gently BREATHES (::after) and
   subtly FLICKERS (::before) so it feels alive / actively working; both stop and
   the whole backdrop cross-fades out once the model is ready. */
#ambient{position:absolute; inset:0; z-index:0; pointer-events:none; opacity:1;
  transition:opacity .9s ease;
  background:radial-gradient(78% 62% at 50% 30%, rgba(255,255,255,.6), rgba(245,246,247,0) 72%)}
/* slow breathing layer */
#ambient::after{content:""; position:absolute; inset:0;
  background:
    radial-gradient(34% 30% at 62% 44%, rgba(154,42,40,.10), transparent 70%),
    radial-gradient(46% 40% at 40% 36%, rgba(158,163,168,.10), transparent 72%);
  animation:ambientPulse 3.4s ease-in-out infinite}
/* subtle, slightly-irregular flicker layer — the "working" shimmer. Small
   opacity-only flutter (compositor-cheap, keeps moving while the GLB decodes). */
#ambient::before{content:""; position:absolute; inset:0;
  background:
    radial-gradient(28% 24% at 58% 41%, rgba(154,42,40,.08), transparent 66%),
    radial-gradient(20% 18% at 45% 34%, rgba(255,255,255,.12), transparent 70%);
  animation:ambientFlicker 1.5s ease-in-out infinite}
@keyframes ambientPulse{0%,100%{opacity:.6; transform:scale(.985)}50%{opacity:1; transform:scale(1.02)}}
@keyframes ambientFlicker{
  0%{opacity:.82} 14%{opacity:1} 23%{opacity:.76} 36%{opacity:.94}
  48%{opacity:.8} 60%{opacity:1} 71%{opacity:.85} 83%{opacity:.96}
  92%{opacity:.78} 100%{opacity:.82}}
#stage.ready #ambient{opacity:0}
/* freeze the motion the instant the model is ready (then it cross-fades out) */
#stage.ready #ambient::before, #stage.ready #ambient::after{animation:none}

/* D — model entrance: the live canvas fades in with a slight scale-up settle
   (~0.96 -> 1) over ~0.7s. Feels like a designed reveal, not a pop-in. */
#stage canvas{position:absolute; inset:0; z-index:1; opacity:0;
  transform:scale(.96); transform-origin:50% 56%;
  transition:opacity .7s ease, transform .78s cubic-bezier(.2,.7,.2,1)}
#stage.ready canvas{opacity:1; transform:none}

/* respect reduced-motion: drop the breathing + flicker and the entrance scale;
   keep a calm static glow and a quick fade */
@media (prefers-reduced-motion: reduce){
  #ambient::before, #ambient::after{animation:none}
  #stage canvas{transform:none; transition:opacity .35s ease}
}

/* top nav */
header{
  position:fixed; top:0; left:0; right:0; z-index:20;
  display:flex; align-items:center; justify-content:space-between;
  padding:22px 40px;
  transition:background .35s ease, box-shadow .35s ease, padding .35s ease;
}
/* frosted bar fades in once the user scrolls, so cards scroll under it cleanly */
header.scrolled{
  padding:14px 40px;
  background:rgba(248,249,249,.82);
  backdrop-filter:blur(12px); -webkit-backdrop-filter:blur(12px);
  box-shadow:0 1px 0 rgba(22,24,26,.06), 0 8px 24px rgba(22,24,26,.05);
}
.wordmark img{height:30px; display:block}
.wordmark{font-weight:800; letter-spacing:.18em; font-size:20px; color:var(--ink)}
.wordmark .a{color:var(--red)}
.wordmark .sub{font-weight:600; color:var(--muted)}
nav a{color:var(--ink); text-decoration:none; margin-left:28px; font-size:13.5px; font-weight:600; letter-spacing:.12em; opacity:.9}
nav a:hover{opacity:1; color:var(--red)}
.hgroup{display:flex; align-items:center; gap:22px}
.lang{appearance:none; -webkit-appearance:none; border:1px solid var(--line);
  background:rgba(255,255,255,.7); color:var(--ink); font-size:12.5px; font-weight:600;
  letter-spacing:.06em; padding:7px 26px 7px 12px; border-radius:20px; cursor:pointer;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6'><path d='M0 0l5 6 5-6z' fill='%23565c61'/></svg>");
  background-repeat:no-repeat; background-position:right 11px center}
.lang:hover{border-color:var(--red)}

/* scroll content */
#scroll{position:relative; z-index:10}
.panel{
  min-height:100vh; display:flex; align-items:center;
  padding:110px 8vw 70px; pointer-events:none;
}
.panel.right{justify-content:flex-end; text-align:right}
.panel.center{justify-content:center; text-align:center}
.card{max-width:520px; opacity:0; transform:translateY(40px);
  transition:opacity .8s ease, transform .8s ease; pointer-events:auto;
  background:rgba(250,251,251,.80); backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px);
  padding:36px 40px; border-radius:22px; box-shadow:0 14px 48px rgba(22,24,26,.07)}
.card.in{opacity:1; transform:none}
.tag{display:inline-block; font-size:12px; letter-spacing:.32em;
  color:var(--red); margin-bottom:18px; text-transform:uppercase; font-weight:700}
.card h1{font-size:clamp(40px,7vw,82px); line-height:1.02; font-weight:800; letter-spacing:-.01em}
.card h2{font-size:clamp(28px,4.5vw,52px); line-height:1.06; font-weight:800; letter-spacing:-.01em}
.card h1 .y,.card h2 .y{color:var(--red)}
.card p{margin-top:20px; font-size:17px; line-height:1.7; color:#3d4347}
.swoosh{height:5px; width:120px; background:linear-gradient(90deg,var(--red-bright),var(--red));
  border-radius:3px; margin:22px 0 0}
.card .photo{margin-top:22px; border-radius:14px; overflow:hidden;
  box-shadow:0 12px 32px rgba(22,24,26,.14)}
.card .photo img{display:block; width:100%; max-height:210px; object-fit:cover}
.card .photo .cap{font-size:12px; letter-spacing:.08em; color:#454b50;
  background:#fff; padding:8px 14px; text-align:left}
.card .thumbs{display:flex; gap:10px; margin-top:18px}
.card .thumbs img{width:calc((100% - 20px)/3); aspect-ratio:1; object-fit:cover;
  border-radius:10px; box-shadow:0 6px 18px rgba(22,24,26,.12)}
.card .thumbs-cap{font-size:12px; letter-spacing:.08em; color:#454b50; margin-top:10px}
.panel.right .swoosh{margin-left:auto}
.panel.center .swoosh{margin:22px auto 0}

/* spec grid */
.specs{display:grid; grid-template-columns:repeat(3,1fr); gap:30px 40px; margin-top:40px}
.specs div{pointer-events:auto}
.specs .n{font-size:clamp(30px,4vw,46px); font-weight:800; color:var(--ink)}
.specs .n span{color:var(--red); font-size:.6em}
.specs .l{font-size:13px; color:var(--muted); margin-top:6px; letter-spacing:.1em}

/* cta */
.btn{display:inline-block; margin-top:32px; pointer-events:auto;
  background:var(--red); color:#fff; font-weight:800; letter-spacing:.08em;
  padding:16px 38px; border-radius:40px; text-decoration:none; font-size:15px;
  transition:transform .2s ease, box-shadow .2s ease, background .2s ease}
.btn:hover{transform:translateY(-2px); background:var(--red-bright);
  box-shadow:0 12px 30px rgba(154,42,40,.30)}

/* hero CTA + mobile scroll chevron: hidden on desktop so the desktop hero is
   byte-for-byte unchanged; both are switched on inside the mobile media query. */
.hero-cta{display:none}
.mscroll{display:none}

/* slim top progress bar — replaces the old full-screen white loader that
   used to cover (and block the paint of) the hero text. Non-blocking: the
   page is fully visible while this fills, then it fades away. */
#loadbar{position:fixed; top:0; left:0; height:3px; width:0; z-index:60;
  background:linear-gradient(90deg,var(--red-bright),var(--red));
  box-shadow:0 0 10px rgba(154,42,40,.5);
  transition:width .25s ease, opacity .6s ease .25s}
#loadbar.done{opacity:0}

/* scroll hint */
.hint{position:fixed; bottom:26px; left:50%; transform:translateX(-50%); z-index:20;
  font-size:11px; letter-spacing:.3em; color:var(--muted); text-transform:uppercase;
  animation:bob 2s ease-in-out infinite; transition:opacity .45s ease}
.hint.gone{opacity:0; pointer-events:none}
@keyframes bob{0%,100%{transform:translate(-50%,0)}50%{transform:translate(-50%,8px)}}

footer{position:relative; z-index:10; text-align:center; padding:26px 20px;
  color:#3d4347; font-size:12.5px; letter-spacing:.1em;
  background:rgba(248,249,249,.85); backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px)}

/* mobile: card hugs the bottom, model gets the upper half of the screen */
@media(max-width:760px){
  .specs{grid-template-columns:repeat(2,1fr); gap:18px 20px; margin-top:22px}
  header{padding:14px 18px}
  .wordmark img{height:24px}
  nav{display:none}
  .panel{align-items:flex-end; padding:84px 5vw 34px}
  .panel.right{justify-content:center; text-align:left}
  .panel.right .swoosh{margin-left:0}
  .card{width:100%; max-width:100%; padding:20px 22px 24px; border-radius:18px;
    background:rgba(250,251,251,.88)}
  .card h1{font-size:32px}
  .card h2{font-size:25px}
  .card p{margin-top:10px; font-size:14px; line-height:1.6}
  .tag{font-size:10.5px; margin-bottom:8px; letter-spacing:.26em}
  .swoosh{height:4px; width:84px; margin-top:12px}
  .card .photo{margin-top:14px}
  .card .photo img{max-height:110px}
  .card .photo .cap{font-size:10.5px; padding:6px 10px}
  .card .thumbs{margin-top:12px}
  .card .thumbs-cap{font-size:10.5px}
  .specs .n{font-size:24px}
  .specs .l{font-size:11px}
  .btn{padding:12px 26px; margin-top:18px; font-size:14px}
  .hint{display:none}

  /* first screen: lift the hero MESSAGING to the top so a visitor sees what it
     is + why + a next step before scrolling. The model is dropped into the
     lower portion by the camera (app.js, first-screen only). A soft top scrim
     keeps the text crisp over the 3D. Other sections keep their bottom card. */
  #s1{align-items:flex-start; padding:70px 5vw 0; position:relative}
  #s1::before{content:""; position:absolute; top:0; left:0; right:0; height:44vh; z-index:1;
    pointer-events:none;
    background:linear-gradient(180deg, rgba(247,248,249,.90) 0%, rgba(247,248,249,.66) 44%, rgba(247,248,249,0) 100%)}
  #s1 .card{position:relative; z-index:2; background:transparent; backdrop-filter:none;
    -webkit-backdrop-filter:none; box-shadow:none; padding:6px 2px 0}
  #s1 .card p{max-width:30ch}
  .hero-cta{display:inline-block; margin-top:16px}

  /* "scroll for more" chevron pinned to the bottom of the first screen */
  .mscroll{display:block; position:absolute; left:calc(50% - 7px); bottom:20px; z-index:2;
    width:14px; height:14px; pointer-events:none; opacity:.8;
    border-right:2px solid var(--muted); border-bottom:2px solid var(--muted);
    filter:drop-shadow(0 1px 2px rgba(255,255,255,.85));
    animation:mbob 1.8s ease-in-out infinite}
  @keyframes mbob{0%,100%{transform:translateY(0) rotate(45deg)}50%{transform:translateY(7px) rotate(45deg)}}
}

@media(max-width:760px) and (prefers-reduced-motion: reduce){
  .mscroll{animation:none}
}
