/* PhopWatch landing v2. Uses tokens.css, components.css, motion.css. Animates transform/opacity only
   (documented exceptions live in motion.css). Mobile first; desktop-only effects are gated in JS. */
.section{padding:var(--sp-9) 0 0}
.section.tight{padding-top:var(--sp-8)}
.lead{color:var(--text-muted);font-size:var(--fs-lg)}
.icon-tile{display:inline-grid;place-items:center;width:44px;height:44px;border-radius:var(--r-md);background:var(--accent-soft);color:var(--accent);flex:none}

/* ---------- hero ---------- */
.hero{position:relative;overflow-x:clip;padding:clamp(40px,8vw,104px) 0 var(--sp-9)}
.hero::before,.hero::after{content:"";position:absolute;z-index:-1;border-radius:50%;pointer-events:none}
.hero::before{width:560px;height:560px;right:-120px;top:-140px;background:radial-gradient(closest-side,rgba(109,91,232,.22),transparent)}
.hero::after{width:520px;height:520px;left:-160px;bottom:-200px;background:radial-gradient(closest-side,rgba(251,191,36,.20),transparent)}
.hero-grid{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:var(--sp-6);align-items:center}
.hero h1{font-size:var(--fs-4xl);line-height:var(--lh-display);margin:0 0 var(--sp-4)}
.hero-sub{font-size:var(--fs-lg);color:var(--text-muted);max-width:44ch;margin:0 0 var(--sp-3)}
.hero-for{font-size:var(--fs-lg);margin:0 0 var(--sp-5)}
.hero-cta{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-3) var(--sp-4)}
.hero-note{font-size:var(--fs-sm);color:var(--text-muted)}
.hero-hb{margin-top:var(--sp-6);max-width:460px}
.hero-hb .cap{font-size:var(--fs-sm);color:var(--text-muted);margin:0 0 var(--sp-1)}
.btn-lg{min-height:52px;padding:14px 30px;font-size:var(--fs-lg)}

/* isometric floating cards. Decorative: sandbox data, aria-hidden in the markup */
.vis{position:relative;height:600px;perspective:1500px;min-width:0}
.vis-tilt{position:absolute;inset:0;transform-style:preserve-3d;transform:rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg));transition:transform var(--dur-slow) var(--ease-glide)}
.iso{position:absolute;left:52%;top:50%;width:0;height:0;transform-style:preserve-3d;transform:rotateX(20deg) rotateZ(-12deg)}
.iw{position:absolute;transform-style:preserve-3d;translate:0 var(--py,0px)}
.ic{position:relative;width:290px;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);box-shadow:var(--sh-2);padding:var(--sp-4);animation:pw-float 6s var(--ease-inout) infinite alternate;animation-delay:var(--fd,0s)}
@keyframes pw-float{from{translate:0 0}to{translate:0 -8px}}
.iw.a{left:-260px;top:-280px;transform:translateZ(0)}
.iw.b{left:-40px;top:-95px;transform:translateZ(46px)}
.iw.c{left:-250px;top:95px;transform:translateZ(22px)}
.iw.d{left:215px;top:-190px;transform:translateZ(70px)}
.ic.b{--fd:-1.5s}.ic.c{--fd:-3s}.ic.d{--fd:-4.5s;width:230px}
.ic .row{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-2)}
.ic .nm{font-weight:600;font-size:var(--fs-sm);display:flex;align-items:center;gap:var(--sp-2);min-width:0}
.ic .nm span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ic .sand{font-size:var(--fs-xs);color:var(--text-muted);margin-top:var(--sp-2)}
.ic .big{font-size:var(--fs-3xl);line-height:1.2;font-weight:700;margin:var(--sp-2) 0 0}
.ic .lbl{font-size:var(--fs-sm);color:var(--text-muted)}
.bars{display:flex;align-items:flex-end;gap:3px;height:34px;margin-top:var(--sp-3)}
.bars i{flex:1;background:var(--up);border-radius:2px;opacity:.85}
.bars i.dn{background:var(--down);opacity:1}
.line-head{display:flex;align-items:center;gap:var(--sp-2);font-size:var(--fs-sm);font-weight:600;margin-bottom:var(--sp-3)}
.line-head .ico{color:var(--up)}
.flex-card{border:1px solid var(--border);border-radius:var(--r-md);overflow:hidden;background:var(--surface)}
.flex-card .hd{background:var(--down);color:#fff;padding:var(--sp-2) var(--sp-3);font-weight:700;font-size:var(--fs-sm);display:flex;align-items:center;gap:var(--sp-2)}
.flex-card .bd{padding:var(--sp-3);font-size:var(--fs-sm);display:grid;gap:2px}
.flex-card .bd b{font-size:var(--fs-sm)}
.flex-card .bd .m{color:var(--text-muted)}
.typing::after{content:"";display:inline-block;width:1px;height:1em;background:currentColor;margin-left:2px;vertical-align:-2px;animation:pw-caret 1s steps(1) infinite}
.typing.done::after{display:none}
@keyframes pw-caret{50%{opacity:0}}
.up-mini{position:absolute;right:-26px;bottom:-40px;width:196px;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-md);box-shadow:var(--sh-2);overflow:hidden;opacity:0;transform:translateY(14px) scale(.94);transition:opacity var(--dur-base) linear,transform var(--dur-slow) var(--ease-spring)}
.up-mini.show{opacity:1;transform:none}
.up-mini .hd{background:var(--up);color:#fff;padding:var(--sp-1) var(--sp-3);font-weight:700;font-size:var(--fs-xs)}
.up-mini .bd{padding:var(--sp-2) var(--sp-3);font-size:var(--fs-xs)}
.pdf-pill{display:inline-flex;align-items:center;gap:6px;margin-top:var(--sp-3);background:var(--accent);color:var(--on-accent);border-radius:var(--r-pill);padding:6px 14px;font-size:var(--fs-sm);font-weight:600}

/* ---------- trust strip ---------- */
.trust{padding:var(--sp-6) 0 0}
.trust-in{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--sp-3);background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);box-shadow:var(--sh-1);padding:var(--sp-4)}
.trust-i{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-2)}
.trust-i b{font-size:var(--fs-sm);line-height:1.4}

/* ---------- personas ---------- */
.personas{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--sp-4)}
.persona h3{font-size:var(--fs-xl);margin:var(--sp-3) 0 var(--sp-2)}
.persona .pain{margin:0 0 var(--sp-3);font-size:var(--fs-base)}
.persona .fix{margin:0;color:var(--text-muted);font-size:var(--fs-sm);display:flex;gap:var(--sp-2);align-items:flex-start}
.persona .fix .ico{color:var(--up);margin-top:3px}

/* ---------- features bento ---------- */
.feat{display:grid;grid-template-columns:repeat(6,1fr);gap:var(--sp-3)}
.feat .card{display:flex;flex-direction:column;gap:var(--sp-2);grid-column:span 2}
.feat .card.w3{grid-column:span 3}
.feat .card.w6{grid-column:span 6;flex-direction:row;align-items:center;gap:var(--sp-5)}
.feat .num-tag{font-size:var(--fs-sm);font-weight:700;color:var(--accent);letter-spacing:.06em}
.feat h3{font-size:var(--fs-xl);margin:0}
.feat p{margin:0;color:var(--text-muted)}
.feat .caveat{font-size:var(--fs-sm)}
.feat .head{display:flex;align-items:center;justify-content:space-between}
.feat.bento{gap:var(--sp-3)}
@media (hover:hover){.feat:has(.card:hover)>.card:not(:hover){opacity:.6;transform:scale(.985)}.feat>.card:hover{transform:scale(1.015)}}
.feat>.card{transition:transform var(--dur-base) var(--ease-glide),opacity var(--dur-base) linear}

/* ---------- how it works ---------- */
.steps{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--sp-4);counter-reset:s;position:relative}
.step{position:relative;padding-top:var(--sp-5)}
.step .sn{position:absolute;top:0;left:0;width:44px;height:44px;border-radius:50%;background:var(--ink);color:var(--on-ink);display:grid;place-items:center;font-weight:700;font-size:var(--fs-lg)}
.step:not(:last-child)::after{content:"";position:absolute;top:22px;left:56px;right:-12px;height:2px;background:var(--border-input);opacity:.5;transform-origin:left;transform:scaleX(0);transition:transform var(--dur-reveal) var(--ease-inout) .3s}
.steps.in .step:not(:last-child)::after{transform:scaleX(1)}
.step h3{font-size:var(--fs-xl);margin:var(--sp-5) 0 var(--sp-2)}
.step p{margin:0;color:var(--text-muted)}
.line-id{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-2);margin-top:var(--sp-3)}
.line-id code{font:600 var(--fs-base) var(--font-num);background:var(--surface-2);border:1px solid var(--border);padding:6px 12px;border-radius:var(--r-sm)}

/* ---------- FAQ ---------- */
.faq{max-width:780px}
.faq .acc-q{font-size:var(--fs-lg)}
.faq .acc-p a{color:var(--accent)}

/* ---------- final CTA ---------- */
.final{margin-top:var(--sp-9)}
.final-in{position:relative;overflow:clip;background:var(--accent-soft);border:1px solid var(--border);border-radius:var(--r-lg);padding:clamp(32px,6vw,72px) var(--sp-5);text-align:center;isolation:isolate}
.final-in::before{content:"";position:absolute;inset:auto -10% -70% -10%;height:120%;z-index:-1;background:radial-gradient(closest-side,rgba(109,91,232,.22),transparent)}
.final-in h2{font-size:var(--fs-3xl);line-height:var(--lh-display);margin:0 0 var(--sp-3)}
.final-in p{margin:0 auto var(--sp-5);max-width:46ch;color:var(--text-muted)}

/* ---------- signup dialog ---------- */
.su-note{font-size:var(--fs-sm);color:var(--text-muted);margin:var(--sp-3) 0 0;text-align:center}
.su-err{display:none;background:var(--down-bg);color:var(--down);border-radius:var(--r-md);padding:var(--sp-3) var(--sp-4);font-size:var(--fs-sm);font-weight:600;margin:0 0 var(--sp-3)}
.su-err.on{display:flex;gap:var(--sp-2)}
.consent{display:flex;gap:var(--sp-3);align-items:flex-start;font-size:var(--fs-sm);margin:0 0 var(--sp-4)}
.consent input{width:22px;height:22px;margin-top:2px;accent-color:var(--accent);flex:none}
.modal-x{position:absolute;top:var(--sp-3);right:var(--sp-3)}
.modal-panel{position:relative}

/* ---------- responsive ---------- */
@media (max-width:1000px){
  .hero-grid{grid-template-columns:1fr}
  .vis{height:470px;order:-1;margin-top:var(--sp-3)}
  .iso{left:50%}
  .iw.d{display:none}
  .vis-tilt{scale:.8}
  .trust-in{grid-template-columns:1fr 1fr}
  .personas{grid-template-columns:1fr}
  .feat{grid-template-columns:repeat(2,1fr)}
  .feat .card,.feat .card.w3{grid-column:span 1}
  .feat .card.w6{grid-column:span 2;flex-direction:column;align-items:flex-start}
  .steps{grid-template-columns:1fr}
  .step:not(:last-child)::after{display:none}
}
@media (max-width:860px){
  .anav-in>.lang{display:none}
  .lang-li{display:block;padding:var(--sp-2) var(--sp-3)}
}
@media (max-width:640px){
  .section{padding-top:var(--sp-8)}
  .anav-in{gap:var(--sp-2)}
  .brand span{font-size:var(--fs-base)}
  .vis{height:360px}
  .vis-tilt{scale:.62}
  .ic{animation:none}
  .trust-in{grid-template-columns:1fr}
  .feat{grid-template-columns:1fr}
  .feat .card.w6{grid-column:span 1}
  .btn-lg{width:100%}
  .hero-cta{flex-direction:column;align-items:stretch}
  .up-mini{right:-10px}
}
@media (prefers-reduced-motion:reduce){
  .ic{animation:none}
  .typing::after{animation:none}
  .up-mini{transition:none}
  .step::after{transition:none}
  .vis-tilt{transition:none}
}

/* ---- perf fixes 2026-09-30 (Phase 2B step A). Overrides motion.css for the landing only. ----
   1. .gt looped background-position on background-clip:text. That repaints the text layer every frame on the main
      thread (Paint 443 ms per 6 s in the trace, clip reaching 4000 px). Now one 3 s shimmer pass, then static.
   2. .hb-dot looped offset-distance, also main-thread. Same path as piecewise-linear translate keyframes
      (every vertex of the path is a straight segment), which runs on the compositor. cqw also keeps the dot
      on the line when the trace is narrower than 520px. */
.gt{animation-duration:3s;animation-iteration-count:1;animation-direction:normal;animation-fill-mode:forwards}
.hb{container-type:inline-size}
.hb-dot{offset-path:none;animation:pw-hb2 3.6s linear infinite;will-change:translate}
@keyframes pw-hb2{0.00%{translate:0.000cqw 32px}18.50%{translate:23.077cqw 32px}20.97%{translate:26.154cqw 32px}25.11%{translate:28.462cqw 8px}32.91%{translate:31.538cqw 56px}37.05%{translate:33.846cqw 32px}56.17%{translate:57.692cqw 32px}58.63%{translate:60.769cqw 32px}62.77%{translate:63.077cqw 8px}70.57%{translate:66.154cqw 56px}74.71%{translate:68.462cqw 32px}100.00%{translate:100.000cqw 32px}}
@media (prefers-reduced-motion:reduce){.hb-dot{animation:none;translate:100cqw 32px}}
.hero-off .ic,.hero-off .hb-dot,.hero-off .typing::after{animation-play-state:paused}
.pulse[data-off]::after{animation-play-state:paused}
html{scroll-padding-top:88px}
@media (prefers-reduced-motion:no-preference){html:not(.lenis){scroll-behavior:smooth}}

/* ---- perf: skip layout and paint of below-the-fold sections until they near the viewport ----
   First layout of a long Thai page is the biggest single task (about 690 ms at 4x CPU throttle, ICU word breaking).
   Intrinsic sizes are the measured heights (375 / 768 / 1280 wide) so the scrollbar and anchors do not jump; `auto`
   remembers the real size after first render. */
main>section:nth-child(n+3),.footer{content-visibility:auto}
/* measured with everything rendered, merged art layer, at 375 / 768 / 1100 / 1280 */
main>section:nth-child(3){contain-intrinsic-block-size:auto 980px}
main>section:nth-child(4){contain-intrinsic-block-size:auto 1882px}
main>section:nth-child(5){contain-intrinsic-block-size:auto 750px}
main>section:nth-child(6){contain-intrinsic-block-size:auto 493px}
main>section:nth-child(7){contain-intrinsic-block-size:auto 309px}
.footer{contain-intrinsic-block-size:auto 766px}
@media (min-width:700px){
  main>section:nth-child(3){contain-intrinsic-block-size:auto 986px}
  main>section:nth-child(4){contain-intrinsic-block-size:auto 1446px}
  main>section:nth-child(5){contain-intrinsic-block-size:auto 684px}
  main>section:nth-child(6){contain-intrinsic-block-size:auto 525px}
  main>section:nth-child(7){contain-intrinsic-block-size:auto 260px}
}
@media (min-width:1001px){
  main>section:nth-child(3){contain-intrinsic-block-size:auto 536px}
  main>section:nth-child(4){contain-intrinsic-block-size:auto 1058px}
  main>section:nth-child(5){contain-intrinsic-block-size:auto 481px}
  main>section:nth-child(7){contain-intrinsic-block-size:auto 299px}
  .footer{contain-intrinsic-block-size:auto 392px}
}
@media (min-width:1200px){
  main>section:nth-child(3){contain-intrinsic-block-size:auto 522px}
  main>section:nth-child(4){contain-intrinsic-block-size:auto 1091px}
  main>section:nth-child(5){contain-intrinsic-block-size:auto 410px}
  main>section:nth-child(7){contain-intrinsic-block-size:auto 311px}
  .footer{contain-intrinsic-block-size:auto 364px}
}
/* in-page navigation renders everything first (art.js adds .cv-off), so anchors land exactly */
html.cv-off main>section,html.cv-off .footer{content-visibility:visible!important}

/* ===== Phase 2B art layer merged into the landing (DESIGN.md "Surfaces, texture and art") =====
   Rules honoured: no decorative layer behind text under 18px (dots and radar sit behind the isometric scene only, the
   connector pulse rides a line, the FAQ network sits beside the text column); glow only on --surface cards; grain is
   a background layer of the card itself (no extra pseudo element, so SpotlightCard keeps ::before); motion only
   transform and opacity, paused off-screen by .art-anim / .is-off (art.js) and off for reduced motion. */
.container{max-width:var(--container-wide);padding:0 24px}
.feat,.personas,.steps{gap:24px}
@media (min-width:1280px){.feat,.personas,.steps{gap:32px}}

/* cards: grain tile + corner glow + hairline + accent bar on titles + ghost numeral (features) */
.feat .card,.persona{position:relative;isolation:isolate;overflow:hidden;padding:var(--card-pad);
  background:var(--grain-tile) 0 0/96px 96px,var(--glow-corner) right -90px top -90px/320px 320px no-repeat,var(--surface)}
.feat .card>*,.persona>*{position:relative;z-index:1}
.feat .card{padding-bottom:calc(var(--card-pad) + 28px)} /* keeps the ghost numeral clear of the last text line */
.feat .card::after{content:attr(data-n);position:absolute;z-index:0;right:20px;bottom:-4px;font:700 80px/1 var(--font-sans);color:var(--ghost-num);pointer-events:none;user-select:none}
.feat h3,.persona h3{position:relative;padding-left:14px}
.feat h3::before,.persona h3::before{content:"";position:absolute;left:0;top:.2em;bottom:.2em;width:3px;border-radius:2px;background:var(--accent)}
@media (min-width:768px){
  .feat p,.persona .pain{font-size:var(--fs-lg);max-width:var(--measure-th)}
  .feat .caveat{font-size:var(--fs-base)}
  .persona .fix{font-size:var(--fs-base)}
}

/* hero: dot grid and a slow radar behind the isometric scene only */
.hero{isolation:isolate}
.vis-art{position:absolute;inset:0;z-index:0;pointer-events:none}
.vis-art .dots{position:absolute;inset:0;background-image:radial-gradient(color-mix(in srgb,var(--border-input) 40%,transparent) 1.4px,transparent 1.6px);background-size:24px 24px;-webkit-mask-image:radial-gradient(closest-side,#000,transparent);mask-image:radial-gradient(closest-side,#000,transparent)}
.vis-art .radar{position:absolute;left:52%;top:50%;width:380px;height:380px;margin:-190px 0 0 -190px;border-radius:50%}
.vis-art .radar .sweep{position:absolute;inset:0;border-radius:50%;background:conic-gradient(from 0deg,transparent 0 290deg,rgba(59,54,201,.14) 360deg);animation:spin 9s linear infinite;will-change:transform}
.vis-art .radar svg{position:absolute;inset:0;width:100%;height:100%}
.vis-tilt{z-index:1}
@media (max-width:1000px){.vis-art .radar{display:none}}
@media (prefers-reduced-motion:reduce){.vis-art .radar .sweep{animation:none}}

/* how it works: a pulse travels along the connector between the numbered circles (desktop) */
.pulse-track{display:none}
@media (min-width:1001px){
  .pulse-track{display:block;position:absolute;left:22px;right:22px;top:22px;height:0;container-type:inline-size;pointer-events:none}
  .pulse-track i{position:absolute;left:0;top:0;width:10px;height:10px;margin:-5px 0 0 -5px;border-radius:50%;background:var(--accent);box-shadow:0 0 0 4px var(--accent-soft);animation:trk 6s linear infinite;will-change:translate}
  @keyframes trk{from{translate:0 0}to{translate:100cqw 0}}
}
@media (prefers-reduced-motion:reduce){.pulse-track i{animation:none;display:none}}

/* FAQ: constellation in the free space right of the 780px column */
#faq .container{position:relative}
.faq-net{display:none}
@media (min-width:1240px){
  .faq-net{display:block;position:absolute;right:24px;top:50%;width:min(400px,calc(100% - 860px));translate:0 -50%;pointer-events:none}
}

/* final CTA: same grain tile on the accent-soft panel; the paragraph is 18px so nothing small sits on the texture */
.final-in{background:var(--grain-tile) 0 0/96px 96px,var(--accent-soft)}
.final-in p{font-size:var(--fs-lg)}
.final-in::before{z-index:-1}

/* footer: soft curve at the top edge, inside the footer box (content-visibility clips outside it) */
.footer{position:relative;border-top:0;padding-top:calc(var(--sp-7) + 24px)}
.footer::before{content:"";position:absolute;left:0;right:0;top:0;height:28px;background:var(--bg);border-radius:0 0 50% 50%/0 0 100% 100%;pointer-events:none}
.footer>.container{position:relative}

/* native scrollbar (works with Lenis): thumb 3.30:1 on track */
html{scrollbar-width:thin;scrollbar-color:var(--sb-thumb) var(--sb-track)}
@supports not (scrollbar-color:auto){
  ::-webkit-scrollbar{width:12px;height:12px}
  ::-webkit-scrollbar-track{background:var(--sb-track)}
  ::-webkit-scrollbar-thumb{background:var(--sb-thumb);border-radius:999px;border:3px solid var(--sb-track)}
  ::-webkit-scrollbar-thumb:hover{background:var(--sb-thumb-hover)}
}

/* perf: no blur filter on the headline word reveal on small screens (opacity and translate only) */
@media (max-width:768px){.bt-w{filter:none;transition:opacity var(--dur-reveal) var(--ease-glide),transform var(--dur-reveal) var(--ease-glide)}}

/* ambient loop video inside the persona section: reserved 16:9 framed card (no layout shift). The poster, source and play state come from landing.js. */
#h-persona{text-wrap:balance}
.loopvid{margin:var(--sp-7) auto 0;max-width:960px}
.loopvid-box{position:relative;aspect-ratio:16/9;width:100%;background:var(--surface-2);border:var(--card-border);border-radius:var(--card-radius);box-shadow:var(--card-shadow);overflow:hidden}
.loopvid-box video,.loopvid-box img{display:block;width:100%;height:100%;object-fit:cover}
.loopvid-box video[hidden]{display:none}
.loopvid figcaption{margin:var(--sp-3) 0 0;text-align:center;font-size:var(--fs-sm);color:var(--text-muted)}
.loopvid-btn{position:absolute;right:var(--sp-3);bottom:var(--sp-3);width:44px;height:44px;padding:0;display:grid;place-items:center;border-radius:var(--r-pill);border:1.5px solid var(--border-input);background:var(--surface);color:var(--text);box-shadow:var(--sh-1);cursor:pointer;transition:opacity var(--dur-fast) var(--ease-glide)}
.loopvid-btn[hidden]{display:none}
.loopvid-btn .i-play{display:none}
.loopvid-btn[aria-pressed="true"] .i-play{display:block}
.loopvid-btn[aria-pressed="true"] .i-pause{display:none}
.loopvid-btn:focus-visible{outline-offset:3px}
@media (hover:hover) and (pointer:fine){
  .loopvid-btn{opacity:.72}
  .loopvid-box:hover .loopvid-btn,.loopvid-btn:focus-visible{opacity:1}
}
@media (max-width:768px){.loopvid{margin-top:var(--sp-6)}}

