/* ReplyBox landing · V3 (7 Oct 2026): an AI-first "Intelligent Reply System" page on the light Kreativ ground
   (Plus Jakarta Sans headings + DM Sans, devices and glass panels, soft glows; V3.2) in the ReplyBox emerald, with ONE extra colour for AI.
   Phone first. Motion is opacity/transform only and runs under html.motion (set in the head when the visitor has not asked
   for reduced motion). Fixed elements: the header, the floating WhatsApp button, the menu and the film dialog.
   This is the shared stylesheet of every page. A page's own styles go in <page>.css, loaded after it.

   THE AI COLOUR. One token pair, violet --ai1 #7c3aed -> fuchsia --ai2 #d946ef, on AI things only (every one carries
   data-ai): AI chips, the "extremely smart" words, the AI band, Toppie's draft strip, the Ask Toppie and voice-typing
   chips. Nothing else on the page uses a violet or fuchsia hue (avatars and presence dots included). Emerald --accent is
   the product colour; WhatsApp green is for WhatsApp things only.

   ONE GRID. Every section sits in .wrap (max 1152 px, 20 px gutter on a phone, 24 px from 640 px) and keeps one left
   edge for its words: chip, heading, line, button. Pictures are <figure>s and may sit anywhere inside the container.

   TWO PARTS. Everything above the line "@critical-end" is what the first screen of the home page needs; build.mjs
   writes it to landing.critical.css (loaded in the head of the home page) and the rest to landing.rest.css (loaded in
   the body, after the logo wall). Other pages load this whole file. Keep first-screen styles above the line.
   Part 1: fonts · tokens · base · header · buttons, chips · floating WhatsApp button · main + hero ground · AI tokens ·
           hero + its product picture · the cast · logo wall · first-screen motion
   Part 2: menu · sections, bands (shared with pricing) · section heads · problem · AI band + cards · Ask Toppie ·
           voice typing · team inbox + all features · numbers · watch (film + tour) · pricing teaser · questions ·
           final call · faq + cta (pricing) · footer · motion */

/* ------------------------------------------------------------------ fonts */
/* V3.2 (CY 8 Oct): every heading in Plus Jakarta Sans (one variable woff2, latin, weights 200-800, self-hosted, preloaded in
   the head of both pages). DM Sans stays the body face. zh/th fall back to the CJK / Thai stack in --f-head. */
@font-face{font-family:"Plus Jakarta Sans";font-style:normal;font-weight:200 800;font-display:swap;src:url(assets/fonts/plus-jakarta-sans-latin.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"DM Sans";font-style:normal;font-weight:400 700;font-display:swap;src:url(assets/fonts/dm-sans-latin.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
/* fallbacks sized to the web fonts, so the swap does not re-wrap a line */
@font-face{font-family:"PJS Fallback";font-weight:600 800;src:local("Arial Bold"),local("Arial-BoldMT");size-adjust:103%;ascent-override:104%;descent-override:28%;line-gap-override:0%}
@font-face{font-family:"PJS Fallback";font-weight:200 500;src:local("Arial"),local("ArialMT");size-adjust:106%;ascent-override:104%;descent-override:28%;line-gap-override:0%}
@font-face{font-family:"DM Fallback";font-weight:400 500;src:local("Arial"),local("ArialMT");size-adjust:106%;ascent-override:93.6%;descent-override:29.2%;line-gap-override:0%}
@font-face{font-family:"DM Fallback";font-weight:600 700;src:local("Arial Bold"),local("Arial-BoldMT");size-adjust:102%;ascent-override:97.3%;descent-override:30.4%;line-gap-override:0%}

:root{
  --bg:#f3f7f5; --fg:#07130f; --fg-rgb:7,19,15;
  /* The accent. Every page-chrome colour that follows the brand is one of these, so the page is re-coloured here
     and nowhere else (README.md). Product-picture colours (--em, number tags, avatars, chat bubbles) and the
     WhatsApp green (--wa, for WhatsApp things only) are separate on purpose and do not follow it. */
  --accent:#116956;          /* ReplyBox emerald: buttons, kickers, numbers, check boxes, the focus ring */
  --accent-hi:#178a70;       /* top of the button gradient */
  --accent-lt:#3fae96;       /* light end of the small gradients: step numbers, bar fills */
  --accent-dk:#0c4f41;       /* text on a tint */
  --accent-rgb:17,105,86;    /* --accent as r,g,b for shadows and rings: rgba(var(--accent-rgb),.5) */
  --glow-rgb:108,202,182;    /* the soft glows */
  --t0:#f5fbfa; --t1:#dcf1ed; --t2:#eef9f6; --t3:#e5f5f2;   /* tints: lightest · card-art top · card-art bottom · middle */
  --mint:#e9f5f0;            /* the tinted section ground */
  --line:#a5d8cd; --dash:#96d3c6;                            /* dashed connector lines · dashed outlines */
  --wa:#25d366; --wa-dk:#1da851; --wa-rgb:37,211,102;        /* WhatsApp green */
  --f-head:"Plus Jakarta Sans","PJS Fallback","PingFang SC","Noto Sans SC","Noto Sans Thai","Thonburi",system-ui,sans-serif;
  /* V3.2: ONE visual system for every UI picture: a device (the phone, the laptop) or a designed panel with depth
     (a layered shadow, a 1 px inner highlight), on a three-step radius scale */
  --r-dev:34px; --r-panel:22px; --r-in:14px;
  --sh-panel:0 1px 2px rgba(7,19,15,.04),0 14px 34px -18px rgba(8,40,30,.3),0 0 0 1px rgba(7,19,15,.06),inset 0 1px 0 rgba(255,255,255,.9);
  --sh-float:0 36px 80px -34px rgba(8,50,38,.5),0 14px 30px -18px rgba(8,40,30,.28),0 0 0 1px rgba(7,19,15,.06),inset 0 1px 0 rgba(255,255,255,.85);
  --grain:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .55 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  --f-body:"DM Sans","DM Fallback","PingFang SC","Noto Sans SC","Noto Sans Thai","Thonburi",ui-sans-serif,system-ui,sans-serif;
  --f-app:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"PingFang SC","Noto Sans SC",sans-serif;
  --ease:cubic-bezier(.22,1,.36,1);
}

/* ------------------------------------------------------------------- base */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{margin:0;background:var(--bg);color:var(--fg);font-family:var(--f-body);font-size:16px;line-height:1.5;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}
h1,h2,h3,p,ul,figure,blockquote{margin:0;padding:0}
h1,h2,h3,h4{font-family:var(--f-head)} /* V3.2 r4: every heading in Plus Jakarta Sans, also the ones a class does not size */
ul{list-style:none}
a{color:inherit;text-decoration:none}
img,svg,video{display:block;max-width:100%}
button,input,textarea{font:inherit;color:inherit}
button{background:none;border:0;padding:0;cursor:pointer;-webkit-tap-highlight-color:transparent}
section[id],article[id]{scroll-margin-top:88px}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:6px}
.vh{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.sprite{position:absolute;width:0;height:0;overflow:hidden}
.ico{width:1em;height:1em;flex:none;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.skip{position:absolute;left:12px;top:-60px;z-index:60;padding:12px 16px;border-radius:12px;background:#000;color:#fff;font-size:15px}
.skip:focus{top:12px}
.page{position:relative;min-height:100vh;overflow-x:hidden;overflow-x:clip}
.wrap{width:100%;max-width:1152px;margin-inline:auto;padding-inline:20px}
@media (min-width:640px){.wrap{padding-inline:24px}}

/* ----------------------------------------------------------- header (glass) */
/* Clear over the top of the page; once the page has moved (core.js: .is-stuck) a translucent, strongly blurred bar with a
   hairline, so the words of the page never read through it. */
.nav-sentinel{position:absolute;left:0;top:0;width:1px;height:24px;pointer-events:none}
.nav{position:fixed;top:8px;left:50%;z-index:50;width:min(1120px,calc(100% - 16px));transform:translateX(-50%)}
.nav__bar{display:flex;align-items:center;justify-content:space-between;gap:8px;min-height:56px;padding:6px 6px 6px 14px;border-radius:18px;background:rgba(255,255,255,0);box-shadow:0 0 0 1px rgba(255,255,255,0);transition:background-color .3s,box-shadow .3s}
.nav.is-stuck .nav__bar{background:rgba(255,255,255,.96);-webkit-backdrop-filter:blur(18px) saturate(1.7);backdrop-filter:blur(18px) saturate(1.7);box-shadow:0 12px 34px -16px rgba(8,40,30,.32),0 0 0 1px rgba(8,40,30,.09),inset 0 1px 0 rgba(255,255,255,.8)}
.nav__brand{display:flex;flex:none;align-items:center;min-height:44px}
.nav__brand img{height:24px;width:auto}
/* CY 4 Nov: the bar is logo · Features · Pricing · Sign in · one WhatsApp button · the menu icon (craft.md › Restraint
   "simplify before polishing"; "say it once"). A phone: logo · Sign in · menu icon, the floating button is its WhatsApp
   button. From 768 to 899 px the WhatsApp button is the glyph only and stays away while the page's own first WhatsApp
   button is on screen (core.js 3b). One gap (8 px) between controls, never leftover space-between (craft.md › Spacing). */
.nav__links{display:none}
.nav__right{display:flex;align-items:center;gap:4px;margin-left:auto}
.nav__link{display:inline-flex;align-items:center;justify-content:center;min-height:44px;padding:0 10px;border-radius:12px;font-size:15px;font-weight:600;color:rgba(var(--fg-rgb),.78);white-space:nowrap;transition:color .2s}
.nav__link:hover{color:var(--fg)}
.nav .nav__wa{width:44px;min-height:44px;padding:0;border-radius:14px;font-size:15px;transition:opacity .22s,visibility .22s}
.nav .nav__wa span{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.js .nav__wa.is-away{opacity:0;visibility:hidden;pointer-events:none}
.nav__menu{display:flex;flex:none;align-items:center;justify-content:center;width:44px;height:44px;border-radius:14px;font-size:22px;color:var(--fg);transition:background-color .2s}
.nav__menu:hover,.nav__menu[aria-expanded="true"]{background:rgba(var(--fg-rgb),.07)}
.nav__menu:focus-visible{outline-offset:-2px;border-radius:14px} /* round 19: the ring inside the button's own box, on the bar's edge, never past it (craft.md › Restraint "focus rings sit fully inside the content edge") */
@media (max-width:767px){.nav .nav__wa{display:none}}
@media (min-width:380px){.nav__brand img{height:26px}}
@media (min-width:600px){.nav__brand img{height:28px}}
@media (min-width:900px){
  .nav{top:14px;width:min(1120px,calc(100% - 32px))}
  .nav__bar{min-height:60px;padding:8px 8px 8px 20px}
  .nav__links{display:flex;align-items:center;gap:4px;margin-left:auto}
  .nav__right{gap:8px;margin-left:12px}
  .nav__signin{display:none}
  .nav .nav__wa{width:auto;padding:0 18px 0 15px}
  .nav .nav__wa span{position:static;width:auto;height:auto;overflow:visible;clip-path:none}
  .js .nav__wa.is-away{opacity:1;visibility:visible;pointer-events:auto}
}

/* ---------------------------------------------------------------- buttons */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:44px;padding:0 20px;border-radius:14px;font-size:15px;font-weight:500;white-space:nowrap;transition:translate .2s,box-shadow .2s,background-color .2s}
.btn--lg{min-height:50px;padding:0 24px;font-size:16px}
.btn--xl{min-height:58px;padding:0 30px;border-radius:18px;font-size:18px}
.btn--primary{background:linear-gradient(180deg,var(--accent-hi),var(--accent));color:#fff;box-shadow:0 10px 25px -8px rgba(var(--accent-rgb),.6)}
.btn--white{background:#fff;color:var(--fg);box-shadow:0 1px 2px rgba(0,0,0,.05),0 0 0 1px rgba(7,19,15,.09)}
.btn--black{background:#000;color:#fff}
.btn--navy{background:#0a2a22;color:#fff;font-weight:600;box-shadow:0 10px 30px -10px rgba(10,42,34,.5)}
.btn--glass{background:rgba(255,255,255,.75);color:#0a2a22;font-weight:600;box-shadow:0 0 0 1px rgba(10,42,34,.1)}
/* WhatsApp green, for WhatsApp buttons only, with the official glyph */
/* the fill runs #118049 to #0e7440: white text on it measures 4.99:1 to 5.85:1 (the bright #25d366 gave 1.9:1) */
.btn--wa{background:linear-gradient(180deg,#118049,#0e7440);color:#fff;font-weight:700;letter-spacing:.005em;box-shadow:inset 0 1px 0 rgba(255,255,255,.22),0 12px 26px -10px rgba(14,116,64,.75),0 0 0 1px rgba(10,90,48,.5)}
.btn--wa .ico--wa{font-size:1.3em;color:#fff}
.btn--wa{max-width:100%;padding-block:10px;line-height:1.2;text-align:center;white-space:normal} /* a long label (BM, Thai, any language at 320) wraps to two lines and stays inside the screen */
.ico--play{font-size:15px;color:var(--accent)}
.ico--wa{font-size:19px;color:#1fb955;stroke:none}
@media (hover:hover){
  .btn--primary:hover,.btn--white:hover,.btn--navy:hover,.btn--wa:hover{translate:0 -2px}
  .btn--wa:hover{background:linear-gradient(180deg,#0f7743,#0c6a3a)}
  .btn--black:hover{background:rgba(0,0,0,.85)}
  .btn--glass:hover{background:#fff}
}
/* small chips: "Add-on" (amber, so it is never mistaken for a feature colour), a soft name chip, a tiny count */
.addon,.softchip,.statchip{display:inline-flex;align-items:center;flex:none;height:22px;padding:0 8px;border-radius:7px;font-family:var(--f-body);font-size:12px;font-style:normal;font-weight:600;line-height:1;letter-spacing:.01em;white-space:nowrap}
.addon{background:#fff1cf;color:#7a4d00;box-shadow:0 0 0 1px rgba(122,77,0,.16)}
.softchip{background:var(--t1);color:var(--accent-dk)}
.softchip--plain{background:#fff;box-shadow:0 0 0 1px rgba(7,19,15,.1);color:rgba(var(--fg-rgb),.7)}
.statchip{background:rgba(var(--accent-rgb),.09);color:var(--accent)}

/* --------------------------------------------- floating WhatsApp button */
.wa-fab{position:fixed;right:16px;bottom:calc(16px + env(safe-area-inset-bottom,0px));z-index:45;display:flex;align-items:center;justify-content:center;width:48px;height:48px;border-radius:50%;background:linear-gradient(180deg,#2bd96c,#1fbf5c);color:#fff;box-shadow:0 12px 28px -8px rgba(var(--wa-rgb),.9),0 2px 6px rgba(0,0,0,.14),inset 0 1px 0 rgba(255,255,255,.3);transition:opacity .22s,visibility .22s}
.wa-fab svg{width:26px;height:26px}
.motion .wa-fab::before{content:"";position:absolute;inset:0;border-radius:50%;border:2px solid var(--wa);opacity:0;animation:fab-ring 1.6s cubic-bezier(.25,.8,.25,1) 1s 1 both;pointer-events:none} /* one ring as the button arrives, then still: "holding a result means stop" (Benji r4; it pulsed forever) */
.wa-fab__label{position:absolute;right:60px;top:50%;padding:9px 13px;border-radius:12px;background:#0a2a22;font-size:14px;font-weight:600;color:#fff;white-space:nowrap;opacity:0;visibility:hidden;transform:translate(6px,-50%);transition:opacity .2s,transform .2s,visibility .2s;pointer-events:none}
@media (hover:hover){.wa-fab:hover .wa-fab__label,.wa-fab:focus-visible .wa-fab__label{opacity:1;visibility:visible;transform:translate(0,-50%)}}
.wa-fab.is-ducked,.js .wa-fab.is-away,.is-modal .wa-fab{opacity:0;visibility:hidden;pointer-events:none}
html:has(dialog[open]) .wa-fab{opacity:0;visibility:hidden;pointer-events:none}
@media (min-width:900px){.wa-fab{right:24px;bottom:24px;width:56px;height:56px}.wa-fab svg{width:30px;height:30px}}

/* ----------------------------------------------- main + the hero ground (pricing uses .main, .hero-bg, .pill) */
.main{position:relative;padding-top:66px;padding-bottom:48px} /* round 20: the last section ends one section gap above the footer, not two */
/* the ground behind the hero: a soft green mesh and a dot grid that fades out. Plain CSS, nothing moves. */
.hero-bg{position:absolute;z-index:-1;left:0;right:0;top:0;height:1080px;overflow:hidden;pointer-events:none;background:radial-gradient(64% 34% at 6% 6%,rgba(var(--wa-rgb),.16),transparent 70%),radial-gradient(58% 30% at 98% 3%,rgba(var(--accent-rgb),.17),transparent 70%),radial-gradient(130% 40% at 50% 52%,rgba(var(--glow-rgb),.52),transparent 72%)}
.hero-bg::before{content:"";position:absolute;inset:0;background-image:radial-gradient(circle at 1px 1px,rgba(var(--accent-rgb),.24) 1px,transparent 0);background-size:22px 22px;-webkit-mask-image:radial-gradient(ellipse 80% 46% at 50% 22%,#000 20%,transparent 72%);mask-image:radial-gradient(ellipse 80% 46% at 50% 22%,#000 20%,transparent 72%)}
.hero-bg::after{content:"";position:absolute;left:0;right:0;bottom:0;height:160px;background:linear-gradient(180deg,rgba(243,247,245,0),var(--bg))}
.grain{position:absolute;inset:0;z-index:-1;background-image:var(--grain);background-size:180px 180px;opacity:.28;mix-blend-mode:multiply;pointer-events:none}
/* the small AI mark (V3.2): a superscript chip in the AI colour beside an AI feature's name */
.aisup{display:inline-block;margin-left:.3em;padding:.12em .36em;border-radius:.4em;background:var(--ai-grad);font-family:var(--f-body);font-size:max(9px,.5em);font-weight:800;line-height:1.2;letter-spacing:.04em;vertical-align:top;color:#fff;transform:translateY(-.1em)}
.aisup--w{background:#fff;color:var(--ai-ink)}
.pill{display:inline-flex;align-items:center;gap:8px;padding:6px 14px;border-radius:999px;background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.05),0 0 0 1px rgba(0,0,0,.04);font-size:13px;white-space:nowrap}
.pill__soft{color:rgba(var(--fg-rgb),.8)}
.pill__flag{width:20px;height:auto;border-radius:2px;box-shadow:0 0 0 1px rgba(0,0,0,.08)}

/* ------------------------------------------------------------- AI colour */
:root{
  --ai1:#7c3aed; --ai2:#d946ef; --ai-ink:#6d28d9; --ai-rgb:124,58,237; --ai2-rgb:217,70,239;
  --ai-grad:linear-gradient(100deg,#7c3aed 0%,#a63cec 50%,#d946ef 100%);
  --ai-tint:#f6f1ff;
  --sec:24px;              /* half the space between sections (phone): 24 px + a 1 px line + 24 px = 49 px */
}
@media (min-width:900px){:root{--sec:60px}}
/* AI words: the violet-to-fuchsia gradient set in the letters (each line keeps the whole gradient) */
.ai-words{background:var(--ai-grad);-webkit-background-clip:text;background-clip:text;color:transparent;-webkit-box-decoration-break:clone;box-decoration-break:clone}
/* V3.1: the "extremely smart" words glow: a darker run of the AI gradient in the letters (every stop 4.5:1 or more on white),
   an AI-coloured halo (drop-shadow, which a gradient-filled text keeps), and a slow shimmer that moves only the
   gradient's background-position, only while the words are on screen (data-art + is-inview). Reduced motion: the still glow. */
.ai-glow{background-image:linear-gradient(100deg,#6d28d9 0%,#8b2fd6 35%,#a21caf 65%,#6d28d9 100%);background-size:220% 100%;background-position:0% 50%;filter:drop-shadow(0 0 7px rgba(var(--ai-rgb),.42)) drop-shadow(0 1px 1px rgba(var(--ai2-rgb),.25))}
.motion .is-inview .ai-glow,.motion .is-inview.ai-glow{animation:ai-shimmer 5s ease-in-out infinite}
@keyframes ai-shimmer{0%,100%{background-position:0% 50%}50%{background-position:100% 50%}}

/* chips: one small label per section. Spans, never paragraphs, so they are not body text. */
.chips{display:flex;flex-wrap:wrap;align-items:center;gap:8px}
.chip{display:inline-flex;align-items:center;align-self:flex-start;gap:7px;height:30px;padding:0 12px 0 10px;border-radius:999px;background:#fff;box-shadow:0 0 0 1px rgba(7,19,15,.09),0 1px 2px rgba(7,19,15,.04);font-family:var(--f-body);font-size:13.5px;font-weight:600;line-height:1;letter-spacing:.005em;color:rgba(var(--fg-rgb),.78);white-space:nowrap}
.chip .ico{flex:none;font-size:15px;color:var(--accent)}
.chip--plain{padding:0 12px;background:rgba(var(--fg-rgb),.04);box-shadow:none}
.chip--plain .ico{color:rgba(var(--fg-rgb),.6)}
.chip--ai{background:linear-gradient(#fff,#fff) padding-box,var(--ai-grad) border-box;border:1.5px solid transparent;box-shadow:0 6px 16px -10px rgba(var(--ai-rgb),.7);color:var(--ai-ink)}
.chip--ai .ico{color:var(--ai1)}
.chip--ai-soft{padding:0 12px;background:var(--ai-tint);box-shadow:inset 0 0 0 1px rgba(var(--ai-rgb),.22);color:var(--ai-ink)}
.chip--dark{background:rgba(255,255,255,.12);box-shadow:inset 0 0 0 1px rgba(255,255,255,.18);color:#fff}
.chip--dark .ico{color:#8ef0cf}

/* -------------------------------------------------------------- the cast */
/* build.mjs @cast: the cast's own web file in a box cut to the picture's ink (the transparent margin falls outside it) */
.cast{position:relative;display:block;aspect-ratio:var(--ar);overflow:hidden;pointer-events:none}
.cast picture{display:contents}
.cast img{position:absolute;max-width:none;height:auto}

/* ------------------------------------------------------------------- hero */
.hero3{position:relative;padding-top:20px}
.hero3__copy{display:flex;flex-direction:column;align-items:flex-start}
.hero3__title{font-family:var(--f-head);font-size:2.5rem;font-weight:700;line-height:1.06;letter-spacing:-.04em;text-wrap:balance;color:#05140f}
@media (max-width:379px){.hero3__title{font-size:2.25rem}}
/* V3.1: the slogan is the kicker above the outcome H1 */
.hero3__slogan{margin-bottom:12px;font-family:var(--f-head);font-size:1.2rem;font-weight:700;line-height:1.25;letter-spacing:-.02em;color:#05140f;text-wrap:balance}
/* the struck word "hours": a red line sweeps across it (transform only); the word then dims. Without the script, or with
   reduced motion, the line is there and the word is dim: the finished frame. */
.h1x{position:relative;display:inline-block}
.h1x>span{transition:opacity .4s var(--ease)}
.h1x__line{position:absolute;left:-2%;right:-2%;top:52%;height:.085em;border-radius:3px;background:#d93025;transform:scaleX(1);transform-origin:0 50%;transition:transform .55s var(--ease)}
/* Without motion (or before the reveal timeout) this is the finished frame. With motion the FIRST paint is already the start
   frame (word whole, no line, no stopwatch), so the finished frame never shows and then rewinds (Benji round 2). */
[data-outcome] .h1x>span{opacity:.5}
.motion [data-outcome]:not(.is-done):not(.p-strike) .h1x>span{opacity:1}
.motion [data-outcome]:not(.is-done):not(.p-strike) .h1x__line{transform:scaleX(0)}
.rb-snap,.rb-snap *{transition:none!important}
/* CY 4 Nov: the feature line under the H1. One word rolls at a time in one grid cell sized to the longest word
   (motion.md › Changing text: "every change moves", "change only what changed"; travel curve, 0.45 s). Each word is a
   small opaque pill with its icon; the AI one wears the AI colour. Reduced motion: the still sentence instead. */
.hero3__rot{max-width:560px;margin-top:18px;font-size:18px;font-weight:500;line-height:1.5;color:rgba(var(--fg-rgb),.72);text-wrap:pretty}
.hero3__rot--still{display:none}
html:not(.motion) .hero3__rot--live{display:none}
html:not(.motion) .hero3__rot--still{display:block}
.rot{display:inline-grid;vertical-align:middle;margin-left:.15em}
.rot__w{grid-area:1/1;display:inline-flex;align-items:center;justify-self:start;gap:.4em;height:1.9em;padding:0 .7em 0 .55em;border-radius:999px;background:#fff;box-shadow:0 0 0 1px rgba(7,19,15,.08),0 6px 16px -10px rgba(7,19,15,.35);font-weight:700;color:var(--accent-dk);white-space:nowrap;opacity:0;transform:translateY(.75em);transition:opacity .28s var(--ease),transform .45s cubic-bezier(.45,0,.1,1)}
.rot__w .ico{flex:none;font-size:1em;color:var(--accent)}
.rot__w--ai{color:var(--ai-ink)}
.rot__w--ai .ico{color:var(--ai1)}
.rot__w.is-on{opacity:1;transform:none;transition-delay:.16s}
.rot__w.is-out{opacity:0;transform:translateY(-.75em);transition-duration:.16s,.3s} /* the old word is gone before the new one lands: two pills never overlap (craft.md "nothing translucent overlaps") */
/* round 14 (reviewer 8): one width rule. The two buttons stack in one column as wide as the wider one (full width on a
   phone), the green one first (craft.md › Spacing "Columns line up"; "No near-tangents": two right edges 11 px apart) */
.hero3__cta{display:grid;grid-template-columns:minmax(0,1fr);gap:10px;width:100%;margin-top:26px}
.hero3__cta .btn{min-height:52px;padding:0 22px}
@media (min-width:640px){.hero3__cta{width:max-content;max-width:100%}}
@media (max-width:379px){.hero3__cta .btn{gap:7px;padding-inline:12px;font-size:15px}} /* a 360 phone: the label stays on one line beside its icon */
/* the tour: a video button, the green one's height and radius; a filled play disc, the label, its length */
.hero3__play{gap:10px;padding:0 18px 0 8px!important;font-weight:600}
.play__disc{display:flex;flex:none;align-items:center;justify-content:center;width:36px;height:36px;border-radius:50%;background:var(--accent);color:#fff;font-size:14px}
.play__disc .ico{margin-left:2px;fill:currentColor;stroke:none}
.play__len{font-size:13px;font-style:normal;font-weight:600;color:rgba(var(--fg-rgb),.5)}
.hero3__proof{margin-top:20px;font-size:16px;font-weight:700;line-height:1.45;color:var(--fg)}
.hero3__proof b{font-weight:700}
:lang(zh) .hero3__title,:lang(th) .hero3__title{line-height:1.18;letter-spacing:-.02em}

/* ------------------------------------------------- the phone (V3.2) */
/* ONE component for every chat picture: a real phone (thin bezel, island, 9:41 status bar, side keys, soft shadow, 9:19.5)
   holding a faithful WhatsApp chat: header (back, avatar, name, online, call icons), doodle wallpaper, tailed bubbles with
   time and ticks, the input bar with mic. Every size inside is in em: font-size scales the whole phone (12 px = 300 px wide).
   Toppie's drafts sit above the input bar in the AI colour; they carry no ticks until the person taps Send. */
.ph{position:relative;z-index:1;width:25em;aspect-ratio:9/19.5;padding:.7em;border-radius:3.9em;background:linear-gradient(160deg,#2b2f35,#0b0d10 42%,#15181c);font-family:var(--f-app);font-size:12px;line-height:1.35;color:#111b21;box-shadow:0 44px 90px -34px rgba(8,30,24,.6),0 18px 36px -20px rgba(8,30,24,.35),0 0 0 1px rgba(0,0,0,.65),inset 0 0 0 1px rgba(255,255,255,.16)}
.ph::before{content:"";position:absolute;left:-.22em;top:9em;width:.22em;height:2.4em;border-radius:.2em 0 0 .2em;background:#1b1e23;box-shadow:0 3.6em 0 #1b1e23}
.ph::after{content:"";position:absolute;right:-.22em;top:11em;width:.22em;height:4em;border-radius:0 .2em .2em 0;background:#1b1e23}
.ph__screen{position:relative;display:flex;flex-direction:column;height:100%;overflow:hidden;border-radius:3.2em;background:#efeae2;box-shadow:inset 0 0 0 1px rgba(0,0,0,.45)}
.ph__status{position:relative;display:flex;flex:none;align-items:center;justify-content:space-between;height:3.7em;padding:.35em 2em 0 2.4em;background:#fff;font-size:1.1em;font-weight:600;letter-spacing:.01em;color:#111}
.ph__island{position:absolute;left:50%;top:1em;width:6em;height:2em;border-radius:1.2em;background:#0b0d10;transform:translateX(-50%)}
.ph__sys{display:inline-flex;align-items:center;gap:.45em}
.ph__sig{display:block;width:1.45em;height:.95em;background:repeating-linear-gradient(90deg,#111 0 .25em,transparent .25em .4em);clip-path:polygon(0 62%,25% 62%,25% 42%,50% 42%,50% 22%,75% 22%,75% 0,100% 0,100% 100%,0 100%)}
.ph__wifi{display:block;width:1.25em;height:.95em;background:radial-gradient(circle at 50% 100%,#111 0 .2em,transparent .2em .36em,#111 .36em .5em,transparent .5em .66em,#111 .66em .8em,transparent .8em);clip-path:polygon(50% 100%,0 20%,0 0,100% 0,100% 20%)}
.ph__bat{display:block;width:2em;height:1em;padding:.14em;border:.12em solid rgba(0,0,0,.45);border-radius:.32em;background:#111 content-box}
.wa__head{position:relative;z-index:1;display:flex;flex:none;align-items:center;gap:.55em;height:4.5em;padding:0 1em 0 .55em;background:#fff;box-shadow:0 1px 0 rgba(0,0,0,.07)}
.wa__head>.ico{font-size:1.6em;color:#111b21;stroke-width:2.2}
.wa__head .av{width:3em;height:3em}
.wa__who{display:flex;flex:1;flex-direction:column;min-width:0;line-height:1.2}
.wa__who b{font-size:1.25em;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.wa__who small{font-size:.95em;color:#667781}
.wa__call{display:inline-flex;gap:1.2em;margin-left:auto}
.wa__call .ico{font-size:1.65em;color:#111b21}
.wa__wall{position:relative;display:flex;flex:1;flex-direction:column;gap:.55em;min-height:0;padding:1.1em .9em;overflow:hidden}
.wa__wall::before{content:"";position:absolute;inset:0;background:url(assets/brand/wa-doodle-tile-grey.webp) 0 0/20em auto repeat;mix-blend-mode:multiply;opacity:.16;pointer-events:none}
.wa__wall>*{position:relative}
.wa__day{align-self:center;padding:.35em .8em;border-radius:.6em;background:rgba(255,255,255,.9);box-shadow:0 1px .5px rgba(11,20,26,.13);font-size:.95em;color:#54656f}
.ph .bub{max-width:84%;padding:.45em .55em .4em .7em;border-radius:.8em;font-size:1.2em;line-height:1.3;box-shadow:0 1px .5px rgba(11,20,26,.13)}
.ph .bub--in{align-self:flex-start;display:block}
.ph .bub--out{align-self:flex-end;display:block}
/* the tails (also on the loose bubbles of the AI rows and the Malaysia band) */
.ph .bub--in,.bub--tail.bub--in{border-top-left-radius:0}
.ph .bub--out,.bub--tail.bub--out{border-top-right-radius:0}
.ph .bub--in::before,.bub--tail.bub--in::before{content:"";position:absolute;left:-.55em;top:0;border-top:.75em solid #fff;border-left:.55em solid transparent}
.ph .bub--out::before,.bub--tail.bub--out::before{content:"";position:absolute;right:-.55em;top:0;border-top:.75em solid #d9fdd3;border-right:.55em solid transparent}
.bub__meta{position:relative;float:right;display:inline-flex;align-items:center;gap:.25em;margin:.6em -.15em -.15em .7em;font-size:.72em;line-height:1;color:#667781}
.bub__meta .ticks{width:1.35em;height:1em;stroke:#53bdeb}
.bub__meta .ticks--1{position:absolute;right:0;top:0;opacity:0;stroke:#8696a0}
.wa__bar{display:flex;flex:none;align-items:center;gap:.6em;padding:.6em .8em 1.3em;background:#f0f2f5}
.wa__bar>.ico{font-size:2em;color:#54656f;stroke-width:2}
.wa__input{position:relative;display:flex;flex:1;align-items:center;height:3.3em;min-width:0;padding:0 1.1em;border-radius:1.65em;background:#fff;box-shadow:0 0 0 1px rgba(0,0,0,.04);font-size:1.1em;white-space:nowrap;overflow:hidden}
.wa__ph{color:#8696a0}
.wa__typed{position:absolute;left:1.1em;top:50%;max-width:calc(100% - 2.2em);overflow:hidden;text-overflow:ellipsis;transform:translateY(-50%);opacity:0}
.wa__act{position:relative;display:grid;flex:none;width:3.3em;height:3.3em}
.wa__mic,.wa__send{position:relative;grid-area:1/1;display:flex;align-items:center;justify-content:center;width:3.3em;height:3.3em;border-radius:50%;background:#1daa61;color:#fff;box-shadow:0 2px 6px -2px rgba(0,0,0,.3)}
.wa__mic .ico,.wa__send .ico{font-size:1.6em}
.wa__send{opacity:0;transform:scale(.6)}
.wa__tap{position:absolute;inset:-.35em;border-radius:50%;border:.25em solid rgba(29,170,97,.9);opacity:0;pointer-events:none}

/* ------------------------------------------- the hero picture: the phone, alive */
/* Round 14 (fresh-eye review, 5 Nov): the WHOLE phone stands on its stage with air on four sides (framing.md "whole and
   centered with air on four sides, it floats"), so the status bar and the WhatsApp header (contact, "online") are always
   in frame and the stage edge never cuts a word. The chat is full from the first paint and the loop only ever adds new
   messages at the bottom, as WhatsApp does (motion.md › Loops "A loop keeps a complete product picture", "Data never
   rewinds in view ... bring the next loop's data in as new"; "A new row carries the rows below it"). */
.hp3{position:relative;margin-top:28px;font-family:var(--f-app)}
/* the one stage every device stands on (craft.md "one figure language: one ground, one gutter, one window shadow") */
.stage{--g:18px;position:relative;overflow:hidden;border-radius:24px;background:radial-gradient(120% 80% at 50% 0%,#21927a 0%,#13705c 45%,#0c5244 100%);box-shadow:inset 0 0 0 1px rgba(255,255,255,.07),0 30px 60px -36px rgba(6,40,32,.55)}
.stage::before{content:"";position:absolute;inset:0;background-image:radial-gradient(circle at 1px 1px,rgba(255,255,255,.09) 1px,transparent 0);background-size:18px 18px;pointer-events:none}
.stage>.ph{position:absolute;left:50%;margin:0;font-size:1em;translate:-50% 0;box-shadow:0 30px 50px -24px rgba(0,0,0,.55),0 0 0 1px rgba(255,255,255,.06)}
/* the phone is 25em x 54.17em (9 : 19.5); the stage is the phone plus one gutter top and bottom and a wider gutter at
   each side, where the WhatsApp marks sit */
.hp3__stage{--gw:max(46px,calc((100% - 25em) / 2));height:calc(54.17em + 2 * var(--g));max-width:44em;margin-inline:auto;font-size:10px}
@media (min-width:400px){.hp3__stage{font-size:10.6px}}
@media (min-width:640px){.hp3__stage{font-size:11px}}
.hp3 .ph{top:var(--g)}
.hp3__toppie{position:absolute;z-index:4}
.hp3__toppie--phone{display:none}
.hp3__toppie--wide{display:none}
/* CY 4 Nov "more WhatsApp marks around the hero": four marks, ONE object (the WhatsApp app tile, its own green and glyph),
   two sizes of one family, two in each side gutter, never over the phone or a word (craft.md › Icons "One family, one
   stroke weight, one size", "Other products' logos ... in original proportions and colors"). Opaque; they land once. */
.wachip{position:absolute;z-index:3;display:flex;align-items:center;justify-content:center;width:var(--s);height:var(--s);border-radius:calc(var(--s) * .27);background:linear-gradient(180deg,#2bd96c,#1aa84f);box-shadow:0 12px 24px -12px rgba(6,60,34,.8),inset 0 1px 0 rgba(255,255,255,.35);color:#fff}
.wachip svg{width:58%;height:58%;fill:currentColor}
.wachip{--s:34px;--c:calc(var(--gw) / 2 - var(--s) / 2)}
.wachip--s{--s:28px}
.wachip--a{left:var(--c);top:9%}
.wachip--b{right:var(--c);top:27%}
.wachip--c{left:var(--c);top:52%}
.wachip--d{right:var(--c);top:74%}
.motion .wachip{animation:chip-in .6s cubic-bezier(.25,.8,.25,1) both}
.motion .wachip--a{animation-delay:.35s}.motion .wachip--b{animation-delay:.45s}.motion .wachip--c{animation-delay:.55s}.motion .wachip--d{animation-delay:.65s}
@keyframes chip-in{from{opacity:0;translate:0 12px}}
@media (min-width:640px){.wachip{--s:44px}.wachip--s{--s:36px}}
/* the chat: a track at the bottom of the wall; new messages are added under it and the track rises (landing.js 6) */
.hp3 .wa__wall{justify-content:flex-end}
.hp3__track{display:flex;flex-direction:column;gap:.55em}
.hp3__track>*{flex:none}
.hp3__sent{display:flex;flex-direction:column;align-items:flex-end;gap:.3em}
.hp3__by{padding:.2em .6em;border-radius:.7em;background:#fff;font-size:.95em;color:#667781}
.ai-mark{font-weight:700;color:var(--ai1)}
.hp3 .is-pending .ticks--1{opacity:1}
.hp3 .is-pending .ticks--2{opacity:0}
.hp3 .bub__meta .ticks{transition:opacity .3s var(--ease)}
.hp3__track>.is-new{opacity:0}
/* Toppie's drafts above the input bar, in the AI colour: always two filled drafts (never grey loading bars) */
.hp3__ai{position:relative;flex:none;margin:0 .7em .55em;padding:.65em .7em .7em;border:1.5px solid transparent;border-radius:1.1em;background:linear-gradient(180deg,#fff,#fbf8ff) padding-box,var(--ai-grad) border-box;box-shadow:0 .9em 1.8em -1.2em rgba(var(--ai-rgb),.7)}
.hp3__ai-h{display:flex;align-items:center;gap:.45em;font-size:1em;color:var(--ai-ink)}
.hp3__ai-h .ico{font-size:1.25em;color:var(--ai1)}
.hp3__ai-h b{font-weight:700}
.hp3__ai-h .dots{margin-left:.2em;opacity:0;color:var(--ai1);transition:opacity .25s var(--ease)}
.hp3.t-think .hp3__ai-h .dots{opacity:1}
.dots{display:inline-flex;gap:3px}
.dots i{width:5px;height:5px;border-radius:50%;background:currentColor;opacity:.45}
.hp3__drafts{position:relative;display:grid;gap:.45em;margin-top:.55em}
.hp3__skel{position:absolute;inset:0;display:grid;gap:.45em;opacity:0;pointer-events:none}
.hp3__skel i{border-radius:.7em;background:linear-gradient(90deg,rgba(var(--ai-rgb),.08),rgba(var(--ai-rgb),.16),rgba(var(--ai-rgb),.08))}
.hp3__draft{position:relative;padding:.55em .7em;border-radius:.7em;background:var(--ai-tint);font-size:1.15em;line-height:1.3;box-shadow:inset 0 0 0 1px rgba(var(--ai-rgb),.14)}
.hp3__d1{background:#efe6ff;box-shadow:inset 0 0 0 2px rgba(var(--ai-rgb),.75)}
.hp3__tap{position:absolute;right:1em;top:50%;width:2em;height:2em;margin-top:-1em;border-radius:50%;background:rgba(var(--ai-rgb),.28);opacity:0;pointer-events:none}
.hp3__drafts{position:relative;display:grid;gap:.45em;margin-top:.55em}
.hp3__draft{position:relative;padding:.55em .7em;border-radius:.7em;background:var(--ai-tint);font-size:1.15em;line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;box-shadow:inset 0 0 0 1px rgba(var(--ai-rgb),.14);transition:opacity .22s var(--ease),transform .3s var(--ease),background-color .25s,box-shadow .25s}
.hp3__draft>[data-hp-d]{display:block;overflow:hidden;text-overflow:ellipsis} /* the text's box is the draft's width: a new draft changes words, not geometry */
.hp3__draft.is-leave{opacity:.4}
.hp3__draft.is-enter{opacity:.4;transition:none} /* round 21 (gate): opacity only; a snap down and back read as a jump */
.hp3.d-pick .hp3__d1{background:#efe6ff;box-shadow:inset 0 0 0 2px rgba(var(--ai-rgb),.75)}
.hp3__tap{position:absolute;right:1em;top:50%;width:2em;height:2em;margin-top:-1em;border-radius:50%;background:rgba(var(--ai-rgb),.28);opacity:0;pointer-events:none}
.motion .hp3.d-tap .hp3__tap{animation:tap .7s ease-out}
/* wordless stand-ins inside the pictures (a name, a message): grey bars, so the pictures carry only the words that matter */
.bars{display:inline-flex;flex-direction:column;gap:5px;min-width:0}
.bars i{display:block;height:8px;border-radius:4px;background:rgba(17,27,33,.14)}
.bars--name i{width:92px;height:9px}
.bars--row{flex:1 1 auto}
.bars--row i{width:72%}.bars--row i+i{width:46%}
.bars--badge i{width:52px;height:7px;background:rgba(255,255,255,.75)}
.bars--draft{width:100%}.bars--draft i{width:70%}
.bub{position:relative;max-width:86%;padding:7px 10px;border-radius:10px;font-size:14.5px;line-height:1.35;box-shadow:0 1px .5px rgba(11,20,26,.13)}
.bub--in{justify-self:start;background:#fff;border-top-left-radius:3px;color:#111b21}
.bub--out{justify-self:end;display:flex;align-items:flex-end;gap:6px;background:#d9fdd3;border-top-right-radius:3px}
.ticks{flex:none;width:16px;height:12px;fill:none;stroke:#34a7e0;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}

/* the loop (landing.js 6, only while on screen): the customer writes -> Toppie's dots -> two new drafts replace the last
   two -> Arun picks one (it fills the box, the mic becomes Send) -> he taps Send -> his bubble goes out, one grey tick,
   then two blue. Without the script, or with reduced motion, the chat as painted: full, the last reply sent. */
/* the placeholder leaves before the typed words arrive (and the other way round): never two texts over each other
   (craft.md › Color "Nothing translucent overlaps") */
.wa__ph,.wa__typed{transition:opacity .14s linear}
.wa__mic,.wa__send{transition:opacity .3s var(--ease),transform .35s var(--ease)}
.hp3:not(.c-typed) .wa__ph,.hp3.c-typed .wa__typed{transition-delay:.15s}
.hp3.c-typed .wa__typed{opacity:1}
.hp3.c-typed .wa__ph{opacity:0}
.hp3.c-typed .wa__send{opacity:1;transform:none}
.hp3.c-typed .wa__mic{opacity:0;transform:scale(.6)}
.motion .hp3.c-tap .wa__tap{animation:tap .75s ease-out}
.motion .hp3.c-tap .wa__send{animation:press .5s var(--ease)}
@keyframes press{0%,100%{transform:none}40%{transform:scale(.82)}}
.motion .hp3.t-think .hp3__ai-h .dots i{animation:dot 1.2s infinite}
.motion .hp3.t-think .hp3__ai-h .dots i:nth-child(2){animation-delay:.15s}
.motion .hp3.t-think .hp3__ai-h .dots i:nth-child(3){animation-delay:.3s}

.av{position:relative;display:flex;align-items:center;justify-content:center;flex:none;width:40px;height:40px;overflow:hidden;border-radius:50%;font-size:13px;font-weight:700;line-height:1}
.av svg{width:100%;height:100%;margin-top:22%}
.av--blue{background:#dbe7ff;color:#1e6fe0}.av--pink{background:#fbd5e3;color:#e0457b}.av--tan{background:#f1e2cc;color:#c07a1c}

/* -------------------------------------------------------------- logo wall */
/* 14 logos at equal optical weight (tools/make-assets.py), grey, no boxes. A phone shows one slow row that loops (the list
   twice, transform only, only while on screen); from 760 px the copy is hidden and the 14 sit in a calm two-row grid. */
.used3{margin-top:56px}
.used3__title{font-family:var(--f-head);font-size:15px;font-weight:600;line-height:1.4;letter-spacing:.01em;text-align:center;color:rgba(var(--fg-rgb),.55)}
.used3__wall{overflow:hidden;margin-top:18px;-webkit-mask-image:linear-gradient(90deg,transparent 10%,#000 34%,#000 66%,transparent 90%);mask-image:linear-gradient(90deg,transparent 10%,#000 34%,#000 66%,transparent 90%)}
.logos__track{display:flex;width:max-content}
.logos{--s:.72;display:flex;align-items:center;gap:0;padding-right:0}
.logos__i{display:flex;align-items:center;justify-content:center;height:44px;padding:0 18px}
.logos__i img{width:calc(var(--w) * var(--s));height:auto;filter:grayscale(1);opacity:.7;transition:filter .25s,opacity .25s}
@media (hover:hover){.logos__i:hover img{filter:none;opacity:1}}
.motion .used3__wall.is-inview .logos__track{animation:logos-row 48s linear infinite}
@keyframes logos-row{to{transform:translateX(-50%)}}
@media (min-width:760px){
  .used3__wall{-webkit-mask-image:none;mask-image:none}
  .logos__track{display:block;width:auto}
  .logos__track .logos[aria-hidden]{display:none}
  .motion .used3__wall.is-inview .logos__track{animation:none}
  .logos{--s:.78;display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:10px 8px}
  .logos__i{height:56px;padding:0 6px}
}
@media (min-width:1060px){.logos{--s:1;gap:14px 12px}.logos__i{height:64px}}

/* a short phone screen (360 x 640): tighter, so the words and the top of the picture share the first screen */
@media (max-width:899px) and (max-height:700px){
  .hero3{padding-top:10px}
  .hero3__slogan{margin-bottom:8px;font-size:1.1rem}
  .hero3__rot{margin-top:12px;font-size:16px}
  .hero3__cta{margin-top:18px}
  .hero3__proof{margin-top:14px}
  .hp3{margin-top:18px}
}

/* ------------------------------------------------------------ hero, laptop */
@media (min-width:640px){
  .hero3__title{font-size:clamp(2.7rem,6.6vw,3.6rem)}
}
@media (min-width:900px){
  .main{padding-top:84px;padding-bottom:56px}
  .hero3{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);align-items:center;gap:32px;padding-top:24px}
  .hero3__title{font-size:clamp(3rem,4.4vw,4rem);line-height:1.03}
  .hero3__slogan{margin-bottom:16px;font-size:1.45rem}
  .hero3__rot{margin-top:22px;font-size:20px}
  .hero3__cta{margin-top:28px;gap:12px}
  .hero3__proof{margin-top:22px}
  .hp3{justify-self:end;width:100%;margin-top:0;padding:0}
  /* round 14: the whole phone, a gutter above and below, the marks in the side gutters */
  .stage{--g:30px;border-radius:28px}
  .hp3__stage{width:min(100%,43em);max-width:none;margin:0 0 0 auto;font-size:10px}
  .hp3__toppie--wide{display:block;left:calc(100% - min(100%,43 * 10px) - 84px);bottom:-14px;width:150px} /* straddles the stage's lower-left corner, about half outside (framing.md rule 7), over the gutter and the phone's bezel (chrome, not content: rule 18) */
}
@media (min-width:1200px){.hp3__stage{font-size:10.6px}.hp3__toppie--wide{left:calc(100% - min(100%,43 * 10.6px) - 92px);width:166px}}

/* ------------------------------------------------------ first-screen motion */
.motion [data-enter]{animation:rise .7s var(--ease) both;animation-delay:calc(var(--e,0) * 1s)}
.motion [data-enter="solid"]{animation-name:rise-solid}
.motion [data-reveal]:not(.is-done){opacity:0;transform:translateY(22px);transition:opacity .6s var(--ease) var(--d,0s),transform .6s var(--ease) var(--d,0s)}
.motion [data-reveal].is-in:not(.is-done){opacity:1;transform:none}
@keyframes rise{from{opacity:0;transform:translateY(24px)}}
@keyframes rise-solid{from{transform:translateY(14px)}}
@keyframes fab-ring{0%{opacity:.6;transform:scale(1)}100%{opacity:0;transform:scale(1.5)}}
@keyframes dot{0%,60%,100%{opacity:.4;transform:none}30%{opacity:1;transform:translateY(-2px)}}
@keyframes tap{from{opacity:1;transform:scale(.3)}to{opacity:0;transform:scale(1.6)}}
@keyframes skel{from{opacity:.55}to{opacity:1}}
@keyframes bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-6px)}}
.motion .bob.is-inview{animation:bob 6s ease-in-out infinite}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation:none!important;transition:none!important}
}

/*@critical-end*/

/* ------------------------------------------------------------------- menu */
/* CY 4 Nov: one list on one left edge (icon tile · label), the four languages, two buttons. craft.md › Spacing: "columns
   line up", "hover and selection fills are inset and rounded"; motion.md › Things that appear: "an open surface holds its
   anchor": the laptop panel is pinned under the menu button by its top-right corner. Phones: a full-height sheet. */
.menu{position:fixed;inset:0;width:100%;height:100%;max-width:none;max-height:none;margin:0;padding:0;border:0;overflow-y:auto;overscroll-behavior:contain;background:var(--bg);color:var(--fg)}
.menu:not([open]){display:none}
.menu::backdrop{background:rgba(6,24,18,.28)}
.menu__in{display:flex;flex-direction:column;gap:20px;max-width:560px;margin-inline:auto;padding:8px 16px 32px}
.menu__top{display:flex;align-items:center;justify-content:space-between;min-height:56px;padding-left:6px}
.menu__close{display:flex;align-items:center;justify-content:center;width:44px;height:44px;border-radius:14px;background:rgba(var(--fg-rgb),.06);font-size:21px}
.menu__list{display:grid;gap:2px;margin-inline:-8px} /* round 19: the rows' hover fill bleeds into the gutter, so the icons share the left edge of the languages and the button (craft.md › Spacing "negative margins go on the list, not the row") */
.mrow{display:flex;align-items:center;gap:14px;width:100%;min-height:56px;padding:6px 12px 6px 8px;border-radius:14px;font-family:var(--f-head);font-size:18px;font-weight:700;letter-spacing:-.01em;color:var(--fg);text-align:left;transition:background-color .15s}
.mrow:hover{background:rgba(var(--accent-rgb),.07)}
.mrow__ico{display:flex;flex:none;align-items:center;justify-content:center;width:40px;height:40px;border-radius:12px;background:var(--t1);color:var(--accent);font-size:18px}
.mrow__t{flex:1;min-width:0}
.mrow__meta{flex:none;font-family:var(--f-body);font-size:13px;font-style:normal;font-weight:600;color:rgba(var(--fg-rgb),.5)}
.menu__langs{display:grid;grid-template-columns:repeat(4,1fr);gap:4px;padding:4px;border-radius:14px;background:rgba(var(--fg-rgb),.05)}
.menu__langs button{min-height:40px;border-radius:10px;font-size:14px;font-weight:600;color:rgba(var(--fg-rgb),.7);transition:background-color .15s,color .15s}
.menu__langs button:hover{color:var(--fg)}
.menu__langs [aria-pressed="true"]{background:#fff;color:var(--fg);box-shadow:0 1px 2px rgba(7,19,15,.08),0 0 0 1px rgba(7,19,15,.06)}
.menu__btns{display:grid;gap:8px}
.menu__btns .btn{width:100%}
.motion .menu[open]{animation:menu-in .24s var(--ease)}
.motion .menu[open]::backdrop{animation:fade-in .24s}
@media (min-width:900px){
  .menu{inset:84px max(24px,calc((100% - 1120px) / 2 + 8px)) auto auto;width:360px;height:auto;max-height:calc(100dvh - 104px);border-radius:22px;background:#fff;box-shadow:0 40px 80px -30px rgba(8,40,30,.4),0 0 0 1px rgba(7,19,15,.07);transform-origin:100% 0}
  .menu::backdrop{background:rgba(6,24,18,.12)}
  .menu__in{gap:14px;padding:12px}
  .menu__top{display:none}
  .mrow{min-height:48px;font-size:16px}
  .mrow__ico{width:34px;height:34px;border-radius:10px;font-size:16px}
  .menu__inbar{display:none} /* already in the laptop bar */
  .menu__btns .btn{min-height:46px;padding:0 12px;font-size:15px}
}

/* --------------------------------------------------------- sections, bands */
.section{margin-top:44px}
.band{position:relative;margin-top:44px;padding-block:44px}
.band+.band{margin-top:0}
.band>.wrap{position:relative}
.band--white{background:#fff;box-shadow:inset 0 1px 0 rgba(7,19,15,.05),inset 0 -1px 0 rgba(7,19,15,.05)}
.band--mint{background:linear-gradient(180deg,#e7f4ee 0%,#eff8f4 100%)}
.band--mint::before{content:"";position:absolute;inset:0;background-image:linear-gradient(rgba(var(--accent-rgb),.07) 1px,transparent 1px),linear-gradient(90deg,rgba(var(--accent-rgb),.07) 1px,transparent 1px);background-size:46px 46px;-webkit-mask-image:linear-gradient(180deg,#000,transparent 460px);mask-image:linear-gradient(180deg,#000,transparent 460px);pointer-events:none}
/* the chat-wallpaper doodle, very faint. The picture is asked for only when the band is on screen. */
.band--doodle{background:linear-gradient(180deg,#e4f3ec 0%,#edf7f3 100%)}
.band--doodle::before,.cta::before{content:"";position:absolute;inset:0;background-repeat:repeat;background-size:300px auto;opacity:.085;pointer-events:none}
.band--doodle.is-inview::before,.cta.is-inview::before{background-image:url(assets/brand/wa-doodle-bg.webp)}
.head{display:flex;flex-direction:column;gap:20px}
.head--split .btn{align-self:flex-start}
.head--center{align-items:center;gap:0;text-align:center}
.h2{max-width:700px;font-family:var(--f-head);font-size:clamp(1.8rem,7.6vw,2.75rem);font-weight:600;line-height:1.12;letter-spacing:-.03em;text-wrap:balance}
.h2 b{font-weight:700}
.h2--lg{font-size:clamp(1.9rem,8vw,3rem);font-weight:700}
.h2--xl{font-size:clamp(1.9rem,8.4vw,3.6rem);font-weight:700;line-height:1.04;letter-spacing:-.04em}
.kicker{font-size:15px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:var(--accent)}
.kicker+.h2{margin-top:12px}
.lead{max-width:580px;margin-top:14px;font-size:16.5px;line-height:1.55;color:rgba(var(--fg-rgb),.64);text-wrap:pretty}
.head--center .lead,.faq .lead{text-wrap:balance}
.lead b{font-weight:600;color:var(--fg)}
.head--center .lead{margin-inline:auto}
.grid{display:grid;gap:16px;margin-top:16px}
.head+.grid{margin-top:32px}
@media (min-width:760px){.grid--2{grid-template-columns:1fr 1fr}.grid{gap:20px;margin-top:20px}}
@media (min-width:960px){.grid--3{grid-template-columns:repeat(3,1fr)}}
@media (min-width:900px){
  .section{margin-top:120px}
  .band{margin-top:120px;padding-block:104px}
  .h2{font-size:clamp(2rem,3.6vw,2.75rem)}
  .h2--lg{font-size:clamp(2.2rem,4.2vw,3.2rem)}
  .h2--xl{font-size:clamp(2.6rem,5.2vw,4rem)}
  .lead{font-size:17.5px}
  .head--split{flex-direction:row;align-items:flex-end;justify-content:space-between;gap:32px}
  .head--split .btn{flex:none;align-self:auto}
  .head--top{align-items:flex-start}
  .head+.grid{margin-top:44px}
}

/* ========================================================== V3 home sections */
/* Mobile polish (round 3): plain white ground, one left edge per section, a 1 px line between sections, air around
   everything, two chips on the whole page (problem, AI). A section: heading (about 6 words) -> one line -> its picture. */
.sec{margin-top:var(--sec)}
.sec::before{content:"";display:block;order:-2;grid-column:1/-1;width:100%;height:1px;margin-bottom:var(--sec);background:rgba(7,19,15,.08)} /* in a split (grid) section the line spans both columns and comes first */
.sec__head{display:flex;flex-direction:column;align-items:flex-start;max-width:620px}
.sec__head .chip{margin-bottom:14px}
.h2v{font-family:var(--f-head);font-size:clamp(1.75rem,7.4vw,2.1rem);font-weight:700;line-height:1.12;letter-spacing:-.03em;text-wrap:balance;color:#05140f}
.h2v--xl{font-size:clamp(1.9rem,8vw,2.25rem)}
.leadv{max-width:560px;margin-top:12px;font-size:17px;line-height:1.5;color:rgba(var(--fg-rgb),.66);text-wrap:pretty}
/* a quiet text link where a button would shout */
.tlink{display:inline-flex;align-items:center;gap:6px;min-height:44px;font-size:16px;font-weight:600;color:var(--accent)}
.tlink .ico{font-size:16px;transition:transform .2s}
.tlink:hover{color:var(--accent-hi)}
:lang(zh) .h2v,:lang(th) .h2v{line-height:1.25;letter-spacing:-.01em}
@media (max-width:899px){.h2v,.airow__t h3,.price3__sub{max-width:calc(100% - 56px)}} /* room at the right for the floating button (48 px + 16 px edge, measured from the 20 px page edge): never over a headline */
@media (min-width:900px){
  .h2v{font-size:clamp(2.2rem,3.3vw,2.9rem)}
  .h2v--xl{font-size:clamp(2.5rem,3.9vw,3.4rem)}
  .leadv{margin-top:16px;font-size:18.5px}
}

/* ------------------------------------------- AI · the Intelligent Reply System */
/* The biggest section, on plain ground: the chip, the slogan, one line, Uncle Tan, then three numbered rows. */
.ai3__top{display:grid;gap:22px}
.ai3__pic{position:relative;max-width:300px}
.ai3{position:relative;isolation:isolate}
.ai3__bg{position:absolute;z-index:-1;top:-20px;bottom:-20px;left:calc(50% - 50vw);width:100vw;overflow:hidden;pointer-events:none;background:radial-gradient(60% 55% at 78% 22%,rgba(var(--ai-rgb),.13),transparent 70%),radial-gradient(45% 50% at 10% 80%,rgba(217,70,239,.08),transparent 70%)}
.ai3__bg .grain{opacity:.14}
.airows{display:grid;grid-template-columns:minmax(0,1fr);margin-top:30px;padding:0;list-style:none;border-top:1px solid rgba(7,19,15,.08)} /* an <ol>: its default 40 px indent pushed the rows off the section's left edge (CY 4 Nov "alignment") */
.airow{display:flex;flex-direction:column;min-width:0;padding:14px 0 15px;border-bottom:1px solid rgba(7,19,15,.08)}
/* round 17 (CY 4 Nov "1, 2, 3, 4 with icons, no eyebrows"; reviewer 2): each step leads with a large number beside its
   icon, on one line across the row (craft.md › Spacing "Columns line up"). The four icon tiles are one family: emerald
   tint, emerald glyph (craft.md › Icons "One family, one stroke weight, one size", "Icons are one opaque color"); the
   AI colour stays on what the AI writes in the pictures (CY 7 Oct). */
.airow__head{display:flex;align-items:center;gap:12px;margin-bottom:12px}
.airow__n{min-width:.62em;font-family:var(--f-head);font-size:44px;font-weight:800;line-height:1;letter-spacing:-.04em;color:var(--accent-dk);font-variant-numeric:tabular-nums}
.airow__ico{display:flex;flex:none;align-items:center;justify-content:center;width:40px;height:40px;border-radius:12px;background:var(--t1);box-shadow:inset 0 0 0 1px rgba(var(--accent-rgb),.16);color:var(--accent);font-size:19px}
.airow__t h3{font-family:var(--f-head);font-size:19px;font-weight:700;line-height:1.3;letter-spacing:-.02em;color:#05140f}
.airow__t p{margin-top:4px;font-size:16px;line-height:1.5;color:rgba(var(--fg-rgb),.62)}
/* the two tiny moving pictures: one strip each, under the words */
.airow__art.wsn{position:relative;display:flex;flex-direction:column;align-items:flex-start;gap:7px;margin-top:12px;padding:11px 13px;overflow:hidden;border-radius:var(--r-in);background:#efeae2;box-shadow:var(--sh-panel);font-family:var(--f-app);font-size:13.5px;line-height:1.3;color:#111b21}
.wsn::before{content:"";position:absolute;inset:0;background:url(assets/brand/wa-doodle-tile-grey.webp) 0 0/200px auto repeat;mix-blend-mode:multiply;opacity:.16;pointer-events:none}
.wsn>*{position:relative}
.wsn__bub{display:block;max-width:92%;padding:6px 9px 5px 10px;font-size:1em;line-height:1.3;white-space:normal}
.wsn__bub.bub--out{align-self:flex-end}
.wsn__bub .bub__meta{float:right;display:inline-flex;align-items:center;gap:3px;margin:4px 0 -2px 6px;font-size:10px;line-height:1;color:#667781}
.wsn__bub .bub__meta:empty{display:none}
.wsn__bub .ticks{width:14px;height:10px;color:#53bdeb}
.wsn__auto .ico{display:inline-block;margin-right:4px;font-size:12px;color:var(--accent);vertical-align:-1px}
.wsn__ai{display:inline-flex;align-items:flex-start;gap:6px;max-width:92%;padding:6px 10px;border:1.5px solid transparent;border-radius:10px;background:linear-gradient(180deg,#fff,#fbf8ff) padding-box,var(--ai-grad) border-box;box-shadow:0 8px 16px -12px rgba(var(--ai-rgb),.55);font-size:1em;line-height:1.3;color:#111b21}
.wsn__ai .ico{flex:none;margin-top:2px;font-size:13px;color:var(--ai1)}
.wsn__taught{margin-right:4px;padding:1px 5px;border-radius:5px;background:var(--ai-tint);font-size:9.5px;font-style:normal;font-weight:700;color:var(--ai-ink)}
.motion .wsn.is-inview .wsn__step{animation:wsn-step 7s var(--ease) infinite}
@keyframes wsn-step{0%,8%{opacity:0;transform:translateY(6px)}20%,94%{opacity:1;transform:none}100%{opacity:1;transform:none}}
@media (min-width:760px){
  .airows{grid-template-columns:repeat(2,minmax(0,1fr));align-items:stretch;column-gap:32px;border-top:0}
  .airow{padding:24px 0;border-top:1px solid rgba(7,19,15,.08)}
  .airows{grid-template-rows:repeat(var(--rows,2),auto auto auto)}
  .airow{display:grid;grid-row:span 3;grid-template-rows:subgrid;row-gap:0} /* Benji r8: number, title and picture each share one line across the row ("columns line up") */
  .airow__art{align-self:start;margin-top:0}
  .airow__t{margin-bottom:14px}
  /* CY 4 Nov "improve alignment": icon, title and picture each share one track across the row (craft.md › Spacing
     "columns line up: every row shares one grid template"), so the pictures start on one line and end on one line */
  @supports (grid-template-rows:subgrid){
    .airow{display:grid;grid-row:span 3;grid-template-rows:subgrid;row-gap:0}
    .airow__art.wsn{margin-top:0;align-self:stretch;justify-content:flex-end}
  }
}
@media (min-width:900px){
  .ai3__top{grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);align-items:center;gap:48px}
  .ai3__pic{justify-self:end;width:100%;max-width:460px}
  .airows{margin-top:56px}
  .airow{padding:28px 0}
}
@media (min-width:1100px){
  .airows{--rows:1;grid-template-columns:repeat(4,minmax(0,1fr));column-gap:28px}
  .airow__t h3{font-size:21px}
  .ai3__soon{margin-top:24px;font-size:16.5px}
}

/* ------------------------------------------------------------- Ask Toppie */
/* V3.2: the chat is the phone component with Toppie's AI-coloured header; Aisyah asks from behind its top-left corner */
.ask__pic{position:relative;margin-top:-8px;padding-bottom:8px}
.ask__scene{position:relative;z-index:2;width:164px;margin:14px 0 0 4px}
.ask__cast{width:100%}
.askchat{font-size:11px}
/* CY 4 Nov: three plain facts under the line, each an icon and a word: what lives in ReplyBox (craft.md › Restraint
   "count the real strings"; one icon family and size) */
/* round 18 (reviewer 7): plain labels, not pills: a surface at rest says "press me" (craft.md › Spacing "a control gets a
   surface visible at rest"; these do nothing, so they get none) */
.ask__facts{display:flex;flex-wrap:wrap;gap:10px 22px;margin-top:20px;padding:0;list-style:none}
.ask__facts li{display:inline-flex;align-items:center;gap:8px;font-size:15px;font-weight:600;color:var(--fg)}
@media (max-width:767px){.ask__facts{display:none}} /* a phone: the line above names the same three things (round 27) */
@media (max-width:767px){#ask .leadv{display:none}} /* a phone: the heading and the Ask Toppie chat below show it; the line stays on the laptop (round 28) */
@media (max-width:767px){#pricing .leadv{display:none}} /* a phone: the price card right below says 3 lines RM250 and each extra line RM150 (round 28) */
.ask__play{gap:10px;min-height:48px;margin-top:22px;padding:0 18px 0 6px;font-weight:600}
.ask__fi{display:flex;flex:none;align-items:center;justify-content:center;width:28px;height:28px;border-radius:50%;background:var(--t1);color:var(--accent);font-size:15px}
/* the words in Aisyah's bubble (the picture's own bubble is blank): her question to Toppie */
.ask__say{position:absolute;left:34%;top:5%;width:34%;font-family:var(--f-app);font-size:11px;font-weight:600;line-height:1.2;text-align:center;color:#111b21}
.ask__stage{height:calc(46.3em + var(--g));max-width:37em;margin-inline:auto;font-size:11px}
@media (max-width:899px){
.voice__stage{overflow:visible;border-radius:0;background:none;box-shadow:none}.voice__stage::before{display:none}}
.ask__stage>.askchat{top:var(--g)}
.wa__head--ai{background:var(--ai-grad);color:#fff;box-shadow:none}
.wa__head--ai>.ico{color:#fff}
.wa__head--ai .wa__who small{color:rgba(255,255,255,.82)}
.wa__head--ai .wa__who b{display:inline-flex;align-items:flex-start}
.askchat__av{display:flex;flex:none;align-items:center;justify-content:center;width:3em;height:3em;border-radius:50%;background:#fff;color:var(--ai1)}
.askchat__av .ico{font-size:1.55em}
/* "Sample data": the picture's label, set like WhatsApp's day chip at the top of the chat */
.askchat__sample{justify-self:center;align-self:start;display:inline-flex;align-items:center;height:2.3em;margin-bottom:.8em;padding:0 1em;border-radius:.6em;background:#fff6d6;box-shadow:0 1px .5px rgba(11,20,26,.13);font-family:var(--f-body);font-size:1.05em;font-weight:700;letter-spacing:.01em;color:#5a4a00}
.askchat__wall{display:flex;flex-direction:column;align-items:stretch;min-height:0;gap:0}
.askqa{display:grid;gap:.5em;align-content:start}
.askq__t::before,.aska__t::before,.askbars__l span::before{content:attr(data-t)} /* not .askq::before: that is the bubble tail */ /* sample chat drawn by CSS: decorative, outside every word count (as the Bento) */
.askqa+.askqa{margin-top:.8em}
.askbars{display:flex;align-items:flex-end;gap:.5em;height:3.2em;margin:.5em 0 .2em;padding:.5em .6em .3em;border-radius:.6em;background:rgba(var(--ai-rgb),.06)}
.askbars i{flex:1;border-radius:.25em .25em 0 0;background:rgba(var(--ai-rgb),.28);height:calc(var(--h) * 100%)}
.askbars i+i{background:var(--ai-grad)}
.askbars__l{display:flex;justify-content:space-between;margin-top:-.1em;font-size:.85em;color:#667781}
.askq{justify-self:end}
.aska{justify-self:start}
.askdots{display:none;gap:3px;padding:5px 2px;color:var(--ai1)}
.askdots i{width:6px;height:6px;border-radius:50%;background:currentColor;opacity:.45}
/* with motion the three take turns in one place: the wall keeps the size of the tallest (landing.js 7) */
.motion .askqa{transition:opacity .35s var(--ease)}
.askchat.is-live .askqa:not(.is-on){opacity:0} /* r6: the exchanges stack up one by one and stay; the finished frame holds all three */
.askchat.is-live .askq,.askchat.is-live .aska{opacity:0;transform:translateY(8px);transition:opacity .35s var(--ease),transform .4s var(--ease)}
.askchat.is-live .s-q .askq{opacity:1;transform:none}
.askchat.is-live .s-dots .aska,.askchat.is-live .s-a .aska{opacity:1;transform:none}
.askchat.is-live .s-dots .askdots{display:inline-flex}
.askchat.is-live .s-dots .aska__t{display:none}
.askchat.is-out .askqa{opacity:0}
.motion .askdots i{animation:dot 1.2s infinite}
.motion .askdots i:nth-child(2){animation-delay:.15s}
.motion .askdots i:nth-child(3){animation-delay:.3s}
@media (min-width:900px){
  /* round 18 (reviewer 7): two columns on one grid, both as tall as the stage: the words at the top of the left column,
     the people standing on its foot, level with the stage's bottom edge (craft.md › Restraint "Space follows the story";
     framing.md rule 15 "No dead corners") */
  .ask{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);grid-template-rows:auto auto;align-items:stretch;column-gap:56px}
  .ask::before{grid-row:1}
  .ask .sec__head{display:flex;flex-direction:column;align-items:flex-start;grid-column:1;grid-row:2;padding-top:40px}
  .ask__pic{position:relative;grid-column:2;grid-row:2;margin:0;padding:0}
  .ask__stage{width:min(100%,37em);max-width:none;margin:0 0 0 auto;font-size:11.2px}
  .ask__scene{width:250px;margin:auto 0 0}
  .ask__say{font-size:15px}
}
@media (min-width:1200px){.ask__stage{font-size:12.4px}.ask__scene{width:270px}}

/* ---------------------------------------------------------- voice typing */
.voice__pic{position:relative;margin-top:24px;padding-top:112px} /* V3.1: Aisyah's head and shoulders (96 px) + 16 px */
/* V3.1: a person speaks. The cast picture is cut to her head and shoulders (the box shows its top part, faded at the foot);
   sound waves leave her mouth and her rojak words sit in a bubble while the capsule listens (landing.js 8 puts the phase
   classes on the figure). Her green bubble in the picture becomes the white chat bubble. */
.voice__who{position:absolute;right:-4px;top:0;z-index:2;width:170px;height:96px;overflow:hidden;-webkit-mask-image:linear-gradient(180deg,#000 80%,transparent);mask-image:linear-gradient(180deg,#000 80%,transparent)}
.voice__cast{position:absolute;left:-6%;top:0;width:100%}
.voice__waves{position:absolute;left:43%;top:66%;z-index:3;display:flex;align-items:center;gap:1px;transform:translateY(-50%)} /* at her mouth, the arcs open to the right */
.voice__waves i{display:block;border:3px solid transparent;border-right-color:var(--accent);border-radius:50%;opacity:0;transform:scale(.6);filter:drop-shadow(0 0 1.5px #fff) drop-shadow(0 0 1px #fff)}
.voice__waves i:nth-child(1){width:14px;height:14px}.voice__waves i:nth-child(2){width:24px;height:24px}.voice__waves i:nth-child(3){width:34px;height:34px}
.voice__say{position:absolute;right:2px;top:2px;max-width:104px;padding:6px 8px;border-radius:10px;border-bottom-left-radius:3px;background:#fff;box-shadow:0 8px 18px -10px rgba(8,40,30,.5),0 0 0 1px rgba(7,19,15,.06);font-family:var(--f-app);font-size:11px;line-height:1.25;color:#111b21;opacity:0;transform:translateY(4px);transition:opacity .3s var(--ease),transform .35s var(--ease)}
.voice__pic.v-listen .voice__say{opacity:1;transform:none}
.motion .voice__pic.v-listen .voice__waves i{animation:wavei 1.2s ease-out infinite}
.motion .voice__pic.v-listen .voice__waves i:nth-child(2){animation-delay:.2s}
.motion .voice__pic.v-listen .voice__waves i:nth-child(3){animation-delay:.4s}
@keyframes wavei{0%{opacity:0;transform:scale(.6)}20%,70%{opacity:1}100%{opacity:0;transform:scale(1.15)}}
/* the play button that opens the clip (voice and Ask Toppie): on the picture's corner, 44 px */
.voice__pop{position:absolute;right:10px;bottom:22px;z-index:4;display:flex;align-items:center;justify-content:center;width:44px;height:44px;border-radius:50%;background:#fff;box-shadow:0 10px 24px -8px rgba(0,0,0,.45),0 0 0 4px rgba(255,255,255,.55);font-size:17px;transition:scale .25s}
.voice__pop .ico{margin-left:2px;color:var(--accent)}
@media (hover:hover){.voice__pop:hover{scale:1.08}}
.lap{position:relative;max-width:560px;margin-inline:auto;font-family:var(--f-app);color:#111b21}
/* V3.2: real proportions at every width: a 16:10 screen inside a dark lid (camera dot, inner highlight), a base with its notch */
.lap__lid{position:relative;padding:12px 12px 14px;border-radius:18px 18px 6px 6px;background:linear-gradient(180deg,#2a2f36,#171b20);box-shadow:0 36px 70px -34px rgba(8,30,40,.65),0 0 0 1px rgba(0,0,0,.55),inset 0 1px 0 rgba(255,255,255,.14)}
.lap__lid::before{content:"";position:absolute;left:50%;top:4px;width:5px;height:5px;margin-left:-2.5px;border-radius:50%;background:#0a0c0f;box-shadow:inset 0 0 0 1px #3a4047}
.lap__screen{position:relative;display:flex;flex-direction:column;aspect-ratio:16/10;overflow:hidden;border-radius:6px;background:#f7f8f8}
.lap__chat{position:relative;display:flex;flex:1;flex-direction:column;justify-content:flex-start;min-height:0;padding:14px 12px;background:#efeae2}
.lap__chat::before{content:"";position:absolute;inset:0;background:url(assets/brand/wa-doodle-tile-grey.webp) 0 0/240px auto repeat;mix-blend-mode:multiply;opacity:.16;pointer-events:none}
.lap__chat>*{position:relative}
.lap__chat .bub{align-self:flex-start;width:fit-content;margin-bottom:6px}
.lap__chat .bub--out{align-self:flex-end}
.lap__chat .bub__meta{float:right;display:inline-flex;align-items:center;gap:3px;margin:4px 0 -2px 8px;font-size:10px;line-height:1;color:#667781}
.lap__chat .ticks{width:14px;height:10px;color:#53bdeb}
@media (max-width:899px){.lap__older{display:none}} /* a phone shows one message: the word budget */
@media (max-width:899px){.lap__chat .bub--in{max-width:56%}} /* on a phone Toppie stands at the right: the message ends before him */
.lap__cmp{position:relative;flex:none;padding:10px 10px 8px;background:#f7f8f8}
.lap__box{position:relative;display:flex;align-items:center;min-height:42px;padding:8px 12px;border-radius:10px;background:#fff;box-shadow:0 0 0 1px #e2e6e5;font-size:14px;line-height:1.35}
.lap__box::after{content:"";position:absolute;inset:0;border-radius:inherit;background:rgba(39,116,174,.18);opacity:0;pointer-events:none}
.lap__ph{position:absolute;left:12px;top:50%;transform:translateY(-50%);color:#8696a0;opacity:0}
.lap.is-live .lap__typed:empty+.lap__ph{opacity:1}
.lap__tools{display:flex;align-items:center;gap:12px;height:40px;padding:0 4px;font-size:18px;color:#54656f}
.lap__vtb{display:flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:50%;background:rgba(11,20,26,.06);color:#2774ae}
.lap__mic{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:50%;background:#1ba056;font-size:15px;color:#fff}
.lap__send{display:flex;align-items:center;justify-content:center;width:32px;height:32px;margin-left:auto;border-radius:50%;background:#1daa61;font-size:16px;color:#fff}
.lap__heard{margin-top:4px;padding:0 4px;font-size:12.5px;line-height:1.4;color:#5e6e76}
.lap__heard b{font-weight:700;color:#3d4b52}
.lap__base{position:relative;height:14px;margin:0 -6%;border-radius:0 0 12px 12px;background:linear-gradient(#e9edf0,#b9c0c6);box-shadow:0 16px 26px -14px rgba(8,30,40,.5)}
.lap__base::before{content:"";display:block;width:16%;height:5px;margin:0 auto;border-radius:0 0 6px 6px;background:#a6aeb5}
/* the capsule (R1 §5a): near-black, X · 16 bars blue -> red · red dot + timer · white stop, centred on the tool row */
.vtc{position:absolute;left:50%;top:34px;z-index:3;transform:translate(-50%,-50%)} /* over the message box it lands in; clear of the screen's bottom edge at every width */
.vtc__glow{position:absolute;inset:-8px -12px;border-radius:999px;background:radial-gradient(55% 95% at 28% 55%,rgba(39,116,174,.75),transparent 72%),radial-gradient(55% 95% at 72% 55%,rgba(215,38,56,.6),transparent 72%);filter:blur(14px);opacity:.42}
.vtc__pill{position:relative;display:inline-flex;align-items:center;gap:8px;height:38px;padding:0 6px;border-radius:999px;background:rgba(13,15,19,.97);box-shadow:inset 0 0 0 1px rgba(255,255,255,.09),inset 0 1px 0 rgba(255,255,255,.07),0 14px 34px -12px rgba(2,6,12,.6),0 2px 8px rgba(2,6,12,.28);color:#fff;white-space:nowrap}
.vtc__btn{display:flex;align-items:center;justify-content:center;width:26px;height:26px;border-radius:50%;font-size:16px;color:rgba(255,255,255,.85)}
.vtc__btn .ico{stroke-width:2.25}
.vtc__btn--stop{background:#fff}
.vtc__btn--stop b{width:9px;height:9px;border-radius:2px;background:#0d0f13}
.vtc__bars{display:flex;align-items:center;gap:3px;height:20px}
.vtc__bars i{display:block;width:3px;height:20px;border-radius:3px;transform:scaleY(calc(.15 + .75 * var(--h)))}
.vtc__time{display:inline-flex;align-items:center;gap:6px;min-width:40px;font-size:12px;font-weight:500;font-variant-numeric:tabular-nums;color:rgba(255,255,255,.9)}
.vtc__time b{font-weight:500}
.vtc__rec{width:6px;height:6px;border-radius:50%;background:#e5484d}
/* the loop (landing.js 8): listening -> writing it out -> the words land -> Heard: */
.lap__typed,.lap__heard,.vtc,.lap__box::after{transition:opacity .35s var(--ease),transform .35s var(--ease)}
.lap.is-live .vtc{opacity:0;transform:translate(-50%,-50%) scale(.9)}
/* round 5: the recorder or the tool row, never both: the icons fade while the capsule is up (and in the still frame) */
.lap__tools>*{transition:opacity .3s var(--ease)}
.lap:not(.is-live) .lap__tools>*,.lap.v-listen .lap__tools>*,.lap.v-think .lap__tools>*{opacity:0}
.lap.is-live .lap__heard{opacity:0;transform:translateY(-4px)}
.lap.is-live .lap__vtb{background:none;color:#54656f}
.lap.v-listen .vtc,.lap.v-think .vtc{opacity:1;transform:translate(-50%,-50%)}
.lap.v-listen .lap__vtb,.lap.v-think .lap__vtb{background:rgba(11,20,26,.06);color:#2774ae}
.lap.v-land .vtc{opacity:0;transform:translate(-50%,calc(-50% - 6px)) scale(.86);transition-duration:.24s}
.lap.v-land .lap__box::after{animation:wash .9s ease-out}
.lap.v-heard .lap__heard{opacity:1;transform:none}
.lap.is-out .lap__typed,.lap.is-out .lap__heard{opacity:0}
.motion .lap.v-listen .vtc__bars i{animation:vtbar calc(.38s + var(--h) * .5s) ease-in-out infinite alternate;animation-delay:calc(var(--i) * -70ms)}
.motion .lap.v-think .vtc__bars i{animation:vtflow 1.05s ease-in-out infinite;animation-delay:calc(var(--i) * -65ms)}
.motion .lap.v-listen .vtc__rec{animation:vtrec 1.6s ease-in-out infinite}
@keyframes vtbar{from{transform:scaleY(.14)}to{transform:scaleY(calc(.3 + .65 * var(--h)))}}
@keyframes vtflow{0%,100%{transform:scaleY(.14);opacity:.55}50%{transform:scaleY(.5);opacity:1}}
@keyframes vtrec{0%,100%{opacity:1}50%{opacity:.35}}
@keyframes wash{0%{opacity:0}20%{opacity:1}100%{opacity:0}}
@media (min-width:900px){
  .voice{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,.8fr);align-items:center;gap:56px}
  .voice__pic{order:-1;margin-top:70px;padding-top:0} /* room for the half of Aisyah above the stage */
  .voice__stage{padding:64px 8.5% 0;background:radial-gradient(120% 80% at 50% 0%,#21927a 0%,#13705c 45%,#0c5244 100%);border-radius:28px;box-shadow:inset 0 0 0 1px rgba(255,255,255,.07),0 30px 60px -36px rgba(6,40,32,.55);overflow:hidden}
  .voice__stage::before{display:block}
  .voice__stage .lap{max-width:none;margin-bottom:-28px} /* the base (14 px) and the lid's lower bezel (14 px) run off: framing.md rule 11, "a full gutter or well past" (>= 24 px) */
  .voice__who{right:48px;top:-70px;width:250px;height:140px} /* half above the stage, half on its top gutter */
  .voice__pop{left:14px;top:14px;right:auto;bottom:auto} /* in the stage's top-left gutter, clear of the screen */
  .voice__say{max-width:150px;padding:8px 10px;font-size:13px}
  .voice__pop{bottom:26px}
  .lap__chat{padding:18px 16px}
  .lap__box{font-size:15px;min-height:46px}
  .vtc{top:38px}
  .lap__heard{font-size:13px}
}

/* ------------------------------------------------- Bento (V3.1) + all features */
/* Nine tiles, each a button: a live mini-UI (CSS loops, only while on screen: core.js is-inview on the art) and a title of
   at most four words. Phone: two columns, the inbox across both. Laptop: four columns, three rows, the inbox 2 x 2.
   Mini-UIs carry only the words that matter; names and messages are grey bars. Only transform and opacity move; a
   "typing" text is uncovered by a cover that shrinks (transform), never a clip-path. */
.inbox3{position:relative}
.inbox3__bg{position:absolute;z-index:-1;top:30%;bottom:-10px;left:calc(50% - 50vw);width:100vw;background:linear-gradient(180deg,transparent,rgba(var(--glow-rgb),.16) 25%,rgba(var(--glow-rgb),.16) 85%,transparent);pointer-events:none}
.bento{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin-top:18px}
.bt{min-width:0}
.bt--inbox{grid-column:1/-1}
@media (max-width:639px){#bt-drafts,#bt-teach{display:none}} /* a phone: the AI steps above already show drafts and teaching; both stay in "See all features" (round 24) */
@media (max-width:639px){#bt-calls,#bt-auto{display:none}} /* a phone: four tiles under the inbox, two even rows; keyword replies are AI step 4, missed calls stay in "See all features" (round 28) */
.bt__btn{display:flex;flex-direction:column;width:100%;height:100%;padding:7px 7px 9px;border-radius:var(--r-panel);background:#fff;box-shadow:var(--sh-panel);text-align:left;transition:box-shadow .25s,translate .25s}
@media (hover:hover){.bt__btn:hover{translate:0 -3px;box-shadow:var(--sh-float)}}
.bt__art{position:relative;display:flex;flex:1;flex-direction:column;min-height:128px;overflow:hidden;border-radius:var(--r-in);background:radial-gradient(90% 70% at 15% 0%,rgba(255,255,255,.95),rgba(255,255,255,0) 60%),linear-gradient(180deg,var(--t1),var(--t2));box-shadow:inset 0 0 0 1px rgba(7,19,15,.04),inset 0 1px 0 #fff;font-family:var(--f-app);font-size:12px;line-height:1.3;color:#111b21;text-align:left}
.bt__art::before{content:"";position:absolute;inset:0;background-image:radial-gradient(circle at 1px 1px,rgba(var(--accent-rgb),.14) 1px,transparent 0);background-size:16px 16px;pointer-events:none}
.bt--inbox .bt__art{min-height:164px}
.bt__t{display:flex;align-items:center;gap:8px;min-height:26px;margin-top:8px;padding:0 2px 0 5px;font-family:var(--f-head);font-size:15px;font-weight:700;line-height:1.25;letter-spacing:-.01em;color:#05140f}
.bt__t .aisup{margin-left:-2px}
.bt__tt{min-width:0} /* the AI badge flows after the title's last word; as a separate flex item it was left stranded at the far edge when the title wrapped */
.bt__tt .aisup{margin-left:.3em}
/* the play mark at the end of the title row: "tap to see it work" (never over the mini-UI) */
.bt__t::after{content:"";flex:none;width:26px;height:26px;margin-left:auto;border-radius:50%;background:var(--t1) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M8 5v14l11-7z' fill='%23116956'/%3E%3C/svg%3E") 56% 50%/12px no-repeat}
/* round 15 (reviewer 1): the mini-UI is in the flow and the art grows to hold it, so every tile shows its rows whole at
   their own pitch (framing.md rule 4 "Crop only filler ... every real word stay[s] whole"); a row of tiles takes the
   tallest one's height. Each flex child keeps its size (flex:none): a squeezed card was what clipped its own rows. */
.mu{position:relative;flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;padding:10px}
.mu>*{flex:none}
.sheet{display:block;border-radius:12px;background:#fff;box-shadow:0 8px 20px -12px rgba(8,45,35,.35),0 0 0 1px rgba(7,19,15,.05)}
.mrow{position:relative;display:flex;align-items:center;gap:8px;height:32px;padding:0 8px;border-radius:9px}
.mrow .av{width:22px;height:22px}
.mrow>.bars{flex:1}
.mrow__hi{position:absolute;inset:0;border-radius:inherit;background:var(--t3);opacity:0}
.mrow__t{display:flex;flex:1;flex-direction:column;gap:3px;min-width:0}
.mu .bars{gap:4px}
.mu .bars i{height:7px}
.mu .bars--name i{width:54px;height:7px}
.mu .bars--row i{width:68%}.mu .bars--row i+i{width:42%}
.tagd{flex:none;width:8px;height:8px;margin-left:auto;border-radius:50%}
/* the mini-UIs carry real names and short previews on every width (r5); the grey bars are gone; the art is aria-hidden, outside the word budget */
  .mu .mtx{display:flex;flex:1;flex-direction:column;justify-content:center;gap:1px;min-width:0;line-height:1.15;text-align:left;font-family:var(--f-app)}
  .mu .mtx b::before,.mu .mtx small::before{content:attr(data-t)} /* decorative mock text drawn by CSS: outside innerText, so no word counter reads it */
  .mu .mtx b{font-size:11px;font-weight:600;color:#111b21;white-space:nowrap}
  .mu .mtx small{font-size:10.5px;color:#667781;white-space:nowrap}
  .mu .mtx--l{display:inline;flex:none;font-size:12px;line-height:1.3;color:#111b21}
  .mu .mtx--l b{font-size:inherit;font-weight:500}
  .mu .bars--row,.mu .bars--name,.mu .bars--draft,.mu .md__d .bars--draft,.mu .mt__draft .bars--draft,.mu .ma__out .bars--draft{display:none}
@media (max-width:599px){
  .mu .mtx [data-s]::before{content:attr(data-s)}
  .mn__rows .mtx small,.mc__card .mtx small{display:none} /* narrow phone tiles: names only */
  .ms__item .mtx{overflow:hidden}.ms__item .mtx b{overflow:hidden;text-overflow:ellipsis} /* the "/" items keep a short text (data-s) */
  .mc__miss,.mu-call .mc__r3,.mu-drafts .md__d2{display:none} /* the 128 px phone tiles hold two rows: the red icon says "missed", one draft is enough */
  .mu-auto .ma__out{width:auto;max-width:100%} /* hug the reply: at 68% its ticks ran 12-22 px past the tile (Benji r3) */
  .mt__rule .ico{display:none} /* the label says it; "Teach a rule" stays on one line */
}
.mrow>:not(.mrow__hi){position:relative} /* the row highlight is absolute: the text must paint above it */
.mn__rows .mtx{flex:1 1 auto;min-width:34px} /* the hot row squeezed its name to 7 px at 360: a floor the short names fit */
.tagd--sales{background:#1e6fe0}.tagd--shop{background:#e0457b}.tagd--service{background:#2a8a3c}
.av--green{background:#d5ecd9;color:#2a8a3c}.av--orange{background:#fde3c8;color:#ea7a0c}.av--call{background:#fde2e2;color:#d93025}
.av--call .ico{width:55%;height:55%;margin:0;stroke-width:2.2}
.msend{display:flex;align-items:center;justify-content:center;flex:none;width:26px;height:26px;border-radius:50%;background:#1daa61;color:#fff;font-size:12px}
.mu .bub{max-width:82%;padding:6px 9px;font-size:12px}
/* a word that "types": the cover shrinks from the right (transform only) */
.typew{position:relative;display:inline-block;white-space:nowrap}
.typew>em{position:absolute;inset:-1px -2px;background:var(--cov,#fff);transform:scaleX(0);transform-origin:100% 50%} /* at rest (reduced motion, off screen) the words are typed; the loop's wipe draws the cover */
/* 1 · one inbox */
.mi__nums{display:grid;grid-template-columns:repeat(3,1fr);width:min(100%,300px)}
.mi__num{display:flex;flex-direction:column;align-items:center;gap:4px;font-size:11px;font-weight:600;color:#33434d}
.mi__tile{display:flex;align-items:center;justify-content:center;width:34px;height:34px;border-radius:10px;background:#fff;box-shadow:0 6px 14px -6px rgba(8,45,35,.3),0 0 0 1px rgba(0,0,0,.05);color:#25d366}
.mi__tile svg{width:19px;height:19px}
.mi__lines{width:min(100%,300px);height:18px}
.mi__lines path{stroke:var(--line);stroke-width:1.5;stroke-dasharray:3 3;vector-effect:non-scaling-stroke}
.mi__box{width:min(100%,300px);padding:4px}
.motion .is-inview .mi__num:nth-child(1) .mi__tile{animation:bump 6s infinite}
.motion .is-inview .mi__num:nth-child(2) .mi__tile{animation:bump 6s 2s infinite}
.motion .is-inview .mi__num:nth-child(3) .mi__tile{animation:bump 6s 4s infinite}
.motion .is-inview .mrow--1 .mrow__hi{animation:rowhi 6s .3s infinite}
.motion .is-inview .mrow--2 .mrow__hi{animation:rowhi 6s 2.3s infinite}
.motion .is-inview .mrow--3 .mrow__hi{animation:rowhi 6s 4.3s infinite}
@keyframes bump{0%,14%,100%{transform:none}5%{transform:translateY(-4px) scale(1.08)}}
@keyframes rowhi{0%,18%,100%{opacity:0}4%,11%{opacity:1}}
/* 2 · who's replying: Siva's list shows "Aina is typing" while Aina types on her screen */
.mu-rep{align-items:stretch;gap:6px}
.mu-rep .mrow{height:30px}
.mr__list{align-self:flex-start;width:100%;padding:3px}
.mr__who{display:inline-flex;align-items:center;gap:4px;min-width:0;font-size:11.5px;font-weight:600;white-space:nowrap;color:var(--accent)}
.mr__who .dots{color:var(--accent)}
.mr__who .dots i{width:4px;height:4px}
.mr__chat{align-self:flex-end;width:86%;padding:5px;box-shadow:0 14px 26px -14px rgba(8,45,35,.45),0 0 0 1px rgba(7,19,15,.05)}
.mr__box{display:flex;align-items:center;gap:6px;height:32px;padding:0 4px 0 10px;border-radius:10px;background:#f1f5f4;box-shadow:inset 0 0 0 1px #e4e9e7}
.mr__typing{flex:1;min-width:0;overflow:hidden;font-size:11.5px;--cov:#f1f5f4}
.mr__typing::after{content:"";display:inline-block;width:1.5px;height:12px;margin-left:1px;background:var(--accent);vertical-align:-2px}
.motion .is-inview .mr__typing .typew>em{animation:wipe-mr 6s steps(10,end) infinite}
.motion .is-inview .mr__hot .mrow__hi{animation:rowhi-mr 6s infinite}
.motion .is-inview .mr__typing::after{animation:caret 1s steps(1) infinite}
@keyframes wipe-mr{0%,12%{transform:scaleX(1)}50%,100%{transform:scaleX(0)}}
@keyframes rowhi-mr{0%,4%{opacity:0}10%,96%{opacity:1}100%{opacity:0}}
@keyframes caret{50%{opacity:0}}
/* 3 · not-replied list: the oldest wait is answered, the count goes 3 -> 2, the rest move up */
.mn__card{width:min(100%,232px);padding:6px 4px 4px}
.mn__tab{display:inline-flex;align-items:center;gap:5px;height:22px;margin:0 4px 4px;padding:0 8px;border-radius:999px;background:var(--t1);font-size:11px;font-weight:600;color:var(--accent-dk)}
.mn__tab .ico{font-size:12px}
.mn__n{position:relative;display:inline-flex;align-items:center;justify-content:center;min-width:16px;height:16px;padding:0 4px;border-radius:8px;background:var(--accent);color:#fff;font-size:10px}
.mn__n i{font-style:normal}
.mn__n i+i{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;opacity:0}
.mn__rows{position:relative;display:block}
.mn__wait{flex:none;margin-left:auto;padding:2px 6px;border-radius:6px;background:#fdecc8;font-size:10.5px;font-weight:700;color:#9a4a07;white-space:nowrap}
.mn__wait--hot{background:#fde2e2;color:#c62828}
.mn__done{position:absolute;right:10px;top:50%;display:flex;transform:translateY(-50%);opacity:0}
.mn__done .ticks{width:18px;height:13px}
.motion .is-inview .mn__r1{animation:a7out 7s infinite}
.motion .is-inview .mn__r1 .mn__wait{animation:a7wait 7s infinite}
.motion .is-inview .mn__done{animation:a7done 7s infinite}
.motion .is-inview .mn__r2,.motion .is-inview .mn__r3{animation:a7up 7s infinite}
.motion .is-inview .mn__n i:first-child{animation:a7n1 7s infinite}
.motion .is-inview .mn__n i+i{animation:a7n2 7s infinite}
@keyframes a7out{0%,54%{opacity:1;transform:none}62%,92%{opacity:0;transform:translateX(-24px)}100%{opacity:1;transform:none}}
@keyframes a7wait{0%,38%{opacity:1}42%,96%{opacity:0}100%{opacity:1}}
@keyframes a7done{0%,40%{opacity:0;transform:translateY(-50%) scale(.6)}45%,56%{opacity:1;transform:translateY(-50%)}62%,100%{opacity:0;transform:translateY(-50%)}}
@keyframes a7up{0%,58%{transform:none}66%,92%{transform:translateY(-32px)}100%{transform:none}}
@keyframes a7n1{0%,58%{opacity:1}62%,94%{opacity:0}100%{opacity:1}}
@keyframes a7n2{0%,58%{opacity:0}62%,94%{opacity:1}100%{opacity:0}}
/* 4 · missed calls become chats: the call drops into the list, "Call back 1" appears */
.mc__card{width:min(100%,232px);padding:4px;overflow:hidden}
.mc__miss{font-size:11px;font-weight:600;color:#d93025}
.mc__wait{flex:none;padding:2px 6px;border-radius:6px;background:#fde2e2;font-size:10.5px;font-weight:700;color:#c62828}
.mc__cb{display:inline-flex;align-items:center;gap:6px;height:28px;padding:0 9px 0 11px;border-radius:999px;background:#fff;box-shadow:0 8px 16px -8px rgba(8,45,35,.4),0 0 0 1px rgba(0,0,0,.05);font-size:11.5px;font-weight:600}
.mc__cb .ico{font-size:12px;color:#d93025}
.mc__cb b{display:inline-flex;align-items:center;justify-content:center;min-width:16px;height:16px;border-radius:8px;background:#d93025;color:#fff;font-size:10px}
.motion .is-inview .mc__call{animation:a4call 6.5s infinite}
.motion .is-inview .mc__r2,.motion .is-inview .mc__r3{animation:a4push 6.5s infinite}
.motion .is-inview .mc__cb{animation:a4cb 6.5s infinite}
@keyframes a4call{0%,8%{opacity:0;transform:translateY(-32px)}16%,94%{opacity:1;transform:none}100%{opacity:0;transform:none}}
@keyframes a4push{0%,8%{transform:translateY(-32px)}16%,94%{transform:none}100%{transform:translateY(-32px)}}
@keyframes a4cb{0%,26%{opacity:0;transform:translateY(8px) scale(.96)}34%,92%{opacity:1;transform:none}100%{opacity:0;transform:none}}
/* 5 · saved replies: type "/", pick one, it fills the box, send */
.ms__menu{width:min(100%,222px);padding:4px}
.ms__item{display:flex;align-items:center;gap:8px;height:28px;padding:0 8px;border-radius:8px;font-size:12px}
.ms__item b{flex:none;font-weight:700;color:var(--accent)}
.ms__item .bars{flex:1}
.ms__item--on{background:#e8f5f1;box-shadow:inset 0 0 0 1.5px var(--accent)}
.ms__box{display:flex;align-items:center;gap:6px;width:min(100%,222px);height:34px;padding:0 4px 0 10px;border-radius:10px;background:#fff;box-shadow:0 1px 2px rgba(11,20,26,.1),0 0 0 1px rgba(0,0,0,.03)}
.ms__typed{position:relative;flex:1;min-width:0;height:18px;overflow:hidden;font-size:12px;line-height:18px;white-space:nowrap}
.ms__typed>i{position:absolute;left:0;top:0;font-style:normal}
.ms__slash{opacity:0;font-weight:600;color:var(--accent)}
.ms__full{opacity:1} /* at rest the picked reply is in the box */
.ms__send{background:var(--accent)}
/* round 15: the list of saved replies stays on screen the whole loop (a tile never rests on an empty box) */
.motion .is-inview .ms__slash{animation:a9slash 7s infinite}
.motion .is-inview .ms__full{animation:a9full 7s infinite}
.motion .is-inview .ms__full .typew>em{animation:wipe-ms 7s steps(10,end) infinite}
.motion .is-inview .ms__send{animation:a9send 7s infinite}
@keyframes a9slash{0%,4%{opacity:0}8%,44%{opacity:1}48%,100%{opacity:0}}
@keyframes a9full{0%,47%{opacity:0}50%,96%{opacity:1}100%{opacity:0}}
@keyframes wipe-ms{0%,50%{transform:scaleX(1)}66%,100%{transform:scaleX(0)}}
@keyframes a9send{0%,82%{transform:none}86%{transform:scale(.84)}90%,100%{transform:none}}
/* 6 · keyword auto-reply: "harga?" comes in, the rule fires, the reply goes out on its own (R10 §2) */
.mu-auto{align-items:stretch;gap:8px;padding:12px 14px}
.ma__in{align-self:flex-start}
.ma__badge{align-self:center;display:inline-flex;align-items:center;gap:5px;height:24px;padding:0 9px;border-radius:999px;background:#fff;box-shadow:0 0 0 1px rgba(var(--accent-rgb),.35),0 6px 14px -8px rgba(8,45,35,.4);font-size:11px;font-weight:700;color:var(--accent)}
.ma__badge .ico{font-size:12px}
.ma__out{align-self:flex-end;align-items:center;gap:8px;width:68%}
.ma__out .bars{flex:1}
.ma__out .bars i{width:88%}.ma__out .bars i+i{width:56%}
.motion .is-inview .ma__in{animation:ma-in 7s infinite}
.motion .is-inview .ma__badge{animation:ma-badge 7s infinite}
.motion .is-inview .ma__out{animation:ma-out 7s infinite}
@keyframes ma-in{0%,2%{opacity:0;transform:translateY(6px)}7%,96%{opacity:1;transform:none}100%{opacity:0;transform:none}}
@keyframes ma-badge{0%,8%{opacity:0;transform:scale(.7)}13%{opacity:1;transform:scale(1.1)}16%,96%{opacity:1;transform:none}100%{opacity:0;transform:none}}
@keyframes ma-out{0%,14%{opacity:0;transform:translateY(8px)}20%,96%{opacity:1;transform:none}100%{opacity:0;transform:none}} /* r6: the reply is on screen for ~76% of the loop; the tile rests on the full exchange */
/* 7 · broadcast + scheduled: one message to many, sent at a set time */
.mb__card{width:min(100%,232px);padding:8px 8px 6px}
.mb__head{display:flex;align-items:center;gap:5px;font-size:11.5px;font-weight:700}
.mb__head .ico{font-size:13px;color:var(--accent)}
@media (max-width:399px){.mb__head>.ico,.mn__tab>.ico{display:none}.mr__who{gap:2px;font-size:11px;letter-spacing:-.01em}.mr__who .dots,.mr__list .mtx small{display:none}.mr__list{padding-inline:2px}.mu-auto .ma__out .mtx--l{flex:0 1 auto;min-width:0}.mu-auto .ma__out .mtx b{white-space:normal}} /* a 360 phone: room for the 9:00 state, the "Not replied" tab and the typing line */
.mb__state{display:inline-flex;align-items:center;gap:4px;margin-left:auto;padding:2px 7px;border-radius:6px;background:var(--t1);font-size:10px;font-weight:600;color:var(--accent-dk)}
.mb__state i{width:5px;height:5px;border-radius:50%;background:var(--accent)}
.mb__msg{display:block;margin-top:6px;padding:5px 8px;border-radius:8px;background:#d9fdd3;font-size:11.5px;line-height:1.3}
.mb__msg mark{padding:0 3px;border-radius:4px;background:rgba(var(--accent-rgb),.16);font-weight:600;color:var(--accent)}
.mb__bar{display:block;height:4px;margin-top:7px;overflow:hidden;border-radius:2px;background:#e6ecea}
.mb__bar i{display:block;height:100%;border-radius:2px;background:linear-gradient(90deg,var(--accent-lt),var(--accent));transform-origin:0 50%}
.mb__rows{display:grid;gap:2px;margin-top:5px}
.mb__row{display:flex;align-items:center;gap:6px;height:22px}
.mb__row .av{width:18px;height:18px}
.mb__row .bars{flex:1}
.mb__row .ticks{flex:none;width:15px;height:11px}
.mb__sched{display:inline-flex;align-items:center;gap:5px;height:26px;padding:0 9px;border-radius:999px;background:#fff;box-shadow:0 6px 14px -8px rgba(8,45,35,.4),0 0 0 1px rgba(0,0,0,.05);font-size:11px;font-weight:600}
.mb__sched .ico{font-size:12px;color:var(--accent)}
.motion .is-inview .mb__state i{animation:vtrec 1.2s ease-in-out infinite}
.motion .is-inview .mb__bar i{animation:a8bar 7s linear infinite}
.motion .is-inview .mb__row{animation:a8row 7s infinite both}
.motion .is-inview .mb__row .ticks{animation:a8tick 7s infinite both}
.motion .is-inview .mb__row--2,.motion .is-inview .mb__row--2 .ticks{animation-delay:1.4s}
.motion .is-inview .mb__row--3,.motion .is-inview .mb__row--3 .ticks{animation-delay:2.8s}
@keyframes a8bar{0%{transform:scaleX(.04)}60%,92%{transform:scaleX(1)}100%{transform:scaleX(.04)}}
@keyframes a8row{0%,6%{opacity:.35}12%,100%{opacity:1}}
@keyframes a8tick{0%,10%{opacity:0;transform:scale(.5)}16%,100%{opacity:1;transform:none}}
/* 8 · Toppie drafts (AI): two drafts rise in, one is tapped, sent */
.mu-drafts{align-items:stretch;gap:4px;padding:6px 10px}
@media (min-width:900px){.mu-drafts{gap:5px;padding:9px 10px}}
.md__in{align-self:flex-start}
.md__strip{display:block;padding:6px 8px 8px;border:1.5px solid transparent;border-radius:12px;background:linear-gradient(180deg,#fff,#fbf8ff) padding-box,var(--ai-grad) border-box;box-shadow:0 10px 22px -16px rgba(var(--ai-rgb),.7)}
.md__h{display:flex;align-items:center;gap:5px;font-size:11px;font-weight:700;color:var(--ai-ink)}
.md__h .ico{font-size:12px;color:var(--ai1)}
.md__d{position:relative;display:block;margin-top:5px;padding:7px 8px;border-radius:8px;background:var(--ai-tint);box-shadow:inset 0 0 0 1px rgba(var(--ai-rgb),.14)}
.md__d .bars{display:flex;width:100%}
.md__d .bars i{width:74%;background:rgba(var(--ai-rgb),.22)}
.md__d2 .bars i{width:52%}
.md__d1{box-shadow:inset 0 0 0 2px rgba(var(--ai-rgb),.75)}
.md__tap{position:absolute;right:10px;top:50%;width:20px;height:20px;margin-top:-10px;border-radius:50%;background:rgba(var(--ai-rgb),.3);opacity:0}
.md__sent{align-self:flex-end;display:inline-flex;margin-right:4px;align-items:center;gap:4px;font-size:11px;font-weight:700;color:var(--accent)}
.motion .is-inview .md__d1{animation:md-d1 8s infinite}
.motion .is-inview .md__d2{animation:md-d2 8s infinite}
.motion .is-inview .md__tap{animation:md-tap 8s infinite}
.motion .is-inview .md__sent{animation:md-sent 8s infinite}
@keyframes md-d1{0%,8%{opacity:0;transform:translateY(8px)}16%,100%{opacity:1;transform:none}}
@keyframes md-d2{0%,14%{opacity:0;transform:translateY(8px)}22%,100%{opacity:1;transform:none}}
@keyframes md-tap{0%,44%{opacity:0;transform:scale(.3)}47%{opacity:1;transform:scale(.6)}56%,100%{opacity:0;transform:scale(1.6)}}
@keyframes md-sent{0%,54%{opacity:0;transform:translateY(4px)}60%,96%{opacity:1;transform:none}100%{opacity:0;transform:none}}
/* 9 · teach a rule (AI): a 👍, then a rule typed in plain words */
.mu-teach{align-items:stretch;gap:7px;padding:12px}
.mt__draft{display:flex;align-items:center;gap:6px;padding:7px 9px;border-radius:10px;background:var(--ai-tint);box-shadow:inset 0 0 0 1px rgba(var(--ai-rgb),.2)}
.mt__draft .ico{flex:none;font-size:12px;color:var(--ai1)}
.mt__draft .bars{flex:1;display:flex}
.mt__draft .bars i{width:70%;background:rgba(var(--ai-rgb),.22)}
.mt__fb{display:flex;gap:6px}
.mt__up{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:999px;background:#fff;box-shadow:0 0 0 1.5px rgba(var(--ai-rgb),.6);font-size:13px;color:var(--ai1)}
.mt__rule{display:inline-flex;flex:none;align-items:center;gap:5px;height:28px;padding:0 9px;white-space:nowrap;border-radius:999px;background:var(--ai-tint);box-shadow:0 0 0 1.5px rgba(var(--ai-rgb),.55);font-size:11.5px;font-weight:600;color:var(--ai-ink)}
.mt__rule .ico{font-size:13px}
.mt__box{display:flex;align-items:center;height:32px;padding:0 10px;border-radius:10px;background:#fff;box-shadow:0 0 0 1px rgba(7,19,15,.1);font-size:12px}
.mt__typed{--cov:#fff}
.motion .is-inview .mt__up{animation:mt-up 8s infinite}
.motion .is-inview .mt__rule{animation:mt-rule 8s infinite}
.motion .is-inview .mt__box{animation:mt-box 8s infinite}
.motion .is-inview .mt__typed .typew>em{animation:wipe-mt 8s steps(12,end) infinite}
@keyframes mt-up{0%,10%{transform:none}14%{transform:scale(1.3)}20%,100%{transform:none}}
@keyframes mt-rule{0%,34%{transform:none}38%{transform:scale(1.08)}44%,100%{transform:none}}
@keyframes mt-box{0%,40%{opacity:0;transform:translateY(6px)}46%,100%{opacity:1;transform:none}}
@keyframes wipe-mt{0%,48%{transform:scaleX(1)}68%,100%{transform:scaleX(0)}}
/* "See all features": one small text control that opens the V2 grid */
.allf{margin-top:14px}
.allf__btn[aria-expanded="true"] .ico{transform:rotate(180deg)}
.allf__panel[hidden]{display:none}
.allf__panel .box{margin-top:16px}
@media (max-width:899px){
  .bt--inbox .mrow--3{display:none}
  .mb__row--3{display:none}
}
@media (min-width:640px){
  .bento{grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}
  .bt--inbox{grid-column:span 2}
  .bt__art,.bt--inbox .bt__art{min-height:150px}
}
@media (min-width:900px){
  .bento{grid-template-columns:repeat(4,minmax(0,1fr));grid-auto-rows:minmax(234px,auto);gap:14px;margin-top:30px}
  .bt--inbox{grid-column:span 2;grid-row:span 2}
  .bt__btn{padding:9px 9px 11px}
  .bt__art,.bt--inbox .bt__art{min-height:0;font-size:12.5px}
  .bt--inbox .mrow--3{display:flex}
  .bt--inbox .mu{gap:10px;transform:scale(1.42);transform-origin:50% 50%} /* the 2 x 2 tile: the same picture, larger */
  .bt--inbox .mi__box{padding:5px}
  .mb__row--3{display:flex}
  .bt__t{min-height:28px;margin-top:10px;font-size:17px}
  .allf{margin-top:18px}
}

/* --------------------------------------------------------------- numbers */
/* three big numbers on plain ground, short labels, the period once in small print */
.nums3__list{display:grid;gap:16px}
.nstat3{display:flex;flex-direction:column;gap:4px}
.nstat3__v{align-self:flex-start;font-family:var(--f-head);font-size:34px;font-weight:700;line-height:1.05;letter-spacing:-.03em;font-variant-numeric:tabular-nums;color:#05140f}
.nstat3__v small{font-size:1em;font-weight:700;letter-spacing:inherit;color:inherit}
.nstat3__l{font-size:16px;line-height:1.4;color:rgba(var(--fg-rgb),.64)}
.nums3{padding-bottom:8px} /* air after the study line, before the Watch block (a phone screen never holds both whole) */
.nums3__study{max-width:640px;margin-top:22px;padding-top:16px;border-top:1px solid rgba(7,19,15,.08);font-size:15.5px;line-height:1.5;color:rgba(var(--fg-rgb),.74)}
.nums3__study cite{font-style:normal;font-weight:600;white-space:nowrap;color:rgba(var(--fg-rgb),.8)}
.nums3__study cite::before{content:"— "}
@media (min-width:760px){.nums3__list{grid-template-columns:repeat(3,minmax(0,1fr));gap:32px}}
@media (min-width:900px){.nstat3__v{font-size:44px}.nstat3__l{font-size:17px}.nums3__study{margin-top:32px;font-size:16.5px}}

/* ------------------------------------------------------------- proof (CY 4 Nov) */
/* The Malaysia line, three numbers, four short quotes with faces. Each quote card is one object: the words first (they
   are the subject), then face, name and business on one row (craft.md › Restraint "in a small surface a row is one
   line: avatar, name, value"; › Spacing "12px word inset", "a title over its subtitle reads as one item"). */
.proof__nums{margin-top:24px}
.tsm{display:grid;gap:12px;margin-top:28px}
.tsm__c{display:flex;flex-direction:column;justify-content:space-between;gap:18px;padding:20px;border-radius:var(--r-panel);background:#fff;box-shadow:var(--sh-panel)}
.tsm__q{font-size:16px;line-height:1.5;color:var(--fg);text-wrap:pretty}
.tsm__q::before{content:"\201C"}.tsm__q::after{content:"\201D"}
.tsm__who{display:flex;align-items:center;gap:12px}
.tsm__face{flex:none;width:44px;height:44px;border-radius:50%;object-fit:cover;box-shadow:0 0 0 2px #fff,0 0 0 3px rgba(var(--accent-rgb),.25)}
.tsm__id{display:flex;flex-direction:column;gap:2px;min-width:0;line-height:1.3}
.tsm__id b{font-size:15px;font-weight:700}
.tsm__id small{font-size:13px;color:rgba(var(--fg-rgb),.6)}
/* a phone: one row that scrolls sideways, whole cards that snap, the next card's edge showing so the row is found
   (motion.md › Scrolling "scrolling starts with whole rows"); saves about 450 px of page (CY item 9) */
@media (max-width:639px){
  .tsm{grid-auto-flow:column;grid-auto-columns:84%;margin-inline:-20px;padding:4px 20px 14px;overflow-x:auto;scroll-snap-type:x mandatory;scroll-padding-inline:20px;scrollbar-width:none;overscroll-behavior-x:contain}
  .tsm::-webkit-scrollbar{display:none}
  .tsm__c{scroll-snap-align:start}
}
@media (min-width:640px){.tsm{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (min-width:900px){.proof__nums{margin-top:36px}.tsm{gap:16px;margin-top:40px}}
@media (min-width:1100px){.tsm{grid-template-columns:repeat(4,minmax(0,1fr))}.tsm__c{padding:22px}}
.film-park{display:contents}

/* --------------------------------------------------------- pricing teaser */
/* CY 4 Nov: both plans as two cards, the same on the home page and the pricing page (partials/plans.html).
   The new price is the heaviest mark (craft.md › Restraint "one number gets to be big"; "the heaviest marks sit on what
   the story is about"); the struck "was" price is quiet grey with a thin line (craft.md › Color "quiet is not faint");
   "Save 58%" is one small emerald chip. The 6-month card is lifted the way the product would (its own surface, the raised
   shadow, a label in the accent), not outlined (craft.md › Color "the hero isn't outlined to point at it"). */
.price3__link{display:inline-flex;margin-top:20px}
.plans{display:grid;gap:14px;margin-top:28px}
.plan{position:relative;display:flex;flex-direction:column;padding:22px;border-radius:var(--r-panel);background:#fff;box-shadow:var(--sh-panel)}
.plan--best{background:linear-gradient(180deg,#f4fbf8,#fff 46%);box-shadow:0 1px 2px rgba(7,19,15,.04),0 30px 60px -28px rgba(8,60,44,.45),0 0 0 1px rgba(var(--accent-rgb),.16)}
.plan__top{display:flex;align-items:center;justify-content:space-between;gap:10px;min-height:28px}
.plan__name{font-family:var(--f-head);font-size:18px;font-weight:700;letter-spacing:-.01em;color:var(--fg)}
.plan__badge{flex:none;height:26px;padding:0 10px;border-radius:999px;background:var(--accent);font-size:12.5px;font-weight:700;line-height:26px;color:#fff;white-space:nowrap}
.plan__price{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 10px;margin-top:16px}
.plan__was{font-size:22px;font-weight:600;color:rgba(var(--fg-rgb),.42);text-decoration:line-through;text-decoration-thickness:1.5px;text-decoration-color:rgba(var(--fg-rgb),.5)}
.plan__was--sm{font-size:inherit;font-weight:500}
.plan__now{font-family:var(--f-head);font-size:48px;font-weight:800;line-height:1;letter-spacing:-.04em;color:#05140f}
.plan__per{font-size:16px;color:rgba(var(--fg-rgb),.6)}
.plan__for{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:8px;font-size:16px;font-weight:600;color:var(--fg)}
.plan__bill{margin-top:4px;font-size:14px;color:rgba(var(--fg-rgb),.6)}
.plan__list{display:grid;gap:10px;margin:18px 0 22px;padding-top:18px;border-top:1px solid rgba(7,19,15,.08)}
.plan__list li{display:flex;align-items:flex-start;gap:10px;font-size:15.5px;line-height:1.4;color:var(--fg)}
.plan__list .ico{flex:none;margin-top:2px;font-size:17px;color:var(--accent)}
.plan__list b{font-weight:700}
.plan__cta{width:100%;margin-top:auto;padding-inline:14px;white-space:nowrap;text-align:center} /* round 19: the label is short enough in every language to stay on one line beside its icon (craft.md › Type "Fit the text before fixing the box") */
@media (max-width:420px){.plan__cta{gap:7px;font-size:15px}}
.plan__list li>span{min-width:0}
.plan{min-width:0}
.plan__xp{white-space:nowrap} /* the struck price, the new one and its period stay together (verify.md "unit wrapped") */
@media (max-width:420px){.plan__now{font-size:42px}.plan__was{font-size:18px}.plan__price{column-gap:8px}}
.plan .btn--white .ico--wa{color:#1fb955}
@media (min-width:700px){.plans{grid-template-columns:repeat(2,minmax(0,1fr));gap:18px}.plan{padding:28px}}
/* round 16: one row grid for both cards (craft.md › Spacing "Columns line up: every row shares one grid template ... optional
   content keeps its track empty"): name, price, "for 3 lines", how it is paid, the list, the button share rows, so the
   cards are one height and their buttons sit on one line */
@supports (grid-template-rows:subgrid){@media (min-width:700px){.plans{row-gap:0}.plan{display:grid;grid-row:span 6;grid-template-rows:subgrid;align-content:start}.plan__list{align-content:start}.plan__cta{align-self:end}}}
@media (min-width:900px){
  .price3 .plans{margin-top:36px} /* the heading over both cards, the cards at full width: nothing in them wraps (r11) */
  .price3__link{margin-top:20px}
  .plan__now{font-size:52px}
}

/* ----------------------------------------------------------- questions */
/* four questions with 1 px lines, no boxes */
.faq3__list{display:grid;margin-top:16px;border-top:1px solid rgba(7,19,15,.08)}
.faq3 .faq__item{border-radius:0;background:none;box-shadow:none;border-bottom:1px solid rgba(7,19,15,.08)}
.faq3 .faq__item button{min-height:52px;padding:11px 0;font-size:17px}
.faq3{padding-bottom:20px} /* air after the questions, before the line */
.faq3 .faq__panel p{padding:0 0 18px;font-size:16px}
@media (min-width:900px){
  .faq3{display:grid;grid-template-columns:minmax(0,.8fr) minmax(0,1.6fr);gap:56px;align-items:start}
  .faq3 .h2v{margin-top:0}
  .faq3__list{margin-top:0}
  .faq3{padding-bottom:0}
  .faq3 .faq__item button{min-height:64px;font-size:18px}
}

/* ------------------------------------------------------------ final call */
/* plain: the team, one line, the green button and the number once */
.end3{display:flex;flex-direction:column}
.end3__pic{width:100%;max-width:300px;margin:0 auto}
.end3__copy{display:flex;flex-direction:column;align-items:flex-start;margin-top:22px}
.end3__row{display:flex;flex-wrap:wrap;align-items:center;gap:8px 18px;margin-top:16px}
.end3__num{display:inline-flex;align-items:center;min-height:44px;font-family:var(--f-head);font-size:20px;font-weight:700;letter-spacing:-.01em;color:#062019}
@media (min-width:900px){
  .end3{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,.9fr);align-items:center;gap:48px}
  .end3__pic{order:2;max-width:440px;margin:0}
  .end3__copy{margin-top:0}
  .end3__num{font-size:24px}
}

/* ------------------------------------------------- the lightbox: film + tour; the tour cover's play mark */
.film{position:relative}
.film__frame{position:relative}
.film__video{display:block;width:100%;aspect-ratio:16/9;background:#07130f}
.film__video[hidden]{display:none}
.film__play{position:absolute;left:4%;bottom:7%;display:flex;align-items:center;justify-content:center;width:56px;height:56px;border-radius:50%;background:#fff;box-shadow:0 12px 28px -8px rgba(0,0,0,.5),0 0 0 5px rgba(255,255,255,.6);font-size:22px;transition:scale .25s}
.film__play .ico{margin-left:3px;font-size:inherit;color:var(--accent)}
.film__sep{margin:0 .4em}
.film__meta{position:absolute;left:calc(4% + 70px);bottom:calc(7% + 8px);display:inline-flex;align-items:center;height:40px;padding:0 16px;border-radius:999px;background:#fff;box-shadow:0 10px 24px -8px rgba(0,0,0,.45);font-size:15px;font-weight:600;color:var(--fg);white-space:nowrap}
@media (max-width:420px){.film__play{width:46px;height:46px;font-size:18px}.film__meta{left:calc(4% + 56px);bottom:calc(7% + 3px);height:36px;font-size:14px}}
@media (min-width:641px){.film__play{width:64px;height:64px;font-size:25px}.film__meta{left:calc(4% + 80px);bottom:calc(7% + 10px);height:44px;padding:0 20px;font-size:16.5px}}
.lightbox{width:min(1100px,calc(100vw - 24px));max-width:none;max-height:none;overflow:visible;padding:0;border:0;background:transparent}
.lightbox::backdrop{background:rgba(4,16,12,.9);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)} /* round 20: a real dim: the page behind reads as ground, not as a second picture */
.lightbox__stage{overflow:hidden;border-radius:18px;background:#000;box-shadow:0 40px 100px -20px rgba(0,0,0,.6)}
.lightbox__stage video,.lightbox__yt{display:block;width:100%;max-height:calc(100vh - 120px);max-height:calc(100dvh - 120px);aspect-ratio:16/9;border:0;border-radius:0;background:#000}
.lightbox__close{position:absolute;right:0;top:-52px;display:flex;align-items:center;justify-content:center;width:44px;height:44px;border-radius:50%;background:rgba(255,255,255,.16);font-size:22px;color:#fff}
.lightbox.is-tall{width:min(380px,calc(100vw - 24px))}
/* round 20: the tour's own cover and a spinner until YouTube's player has loaded (motion.md "The poster is the frame most
   people see"; never a black box) */
.lightbox.is-yt .lightbox__stage{position:relative;background:#06231b url(assets/tour/tour-cover.webp) center/cover no-repeat}
.lightbox__stage.is-loading .lightbox__yt{opacity:0}
.lightbox__stage.is-loading::after{content:"";position:absolute;left:50%;top:50%;width:44px;height:44px;margin:-22px 0 0 -22px;border-radius:50%;border:3px solid rgba(255,255,255,.3);border-top-color:#fff;background:rgba(4,16,12,.6);box-shadow:0 0 0 10px rgba(4,16,12,.6);animation:spin .9s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.lightbox__yt{transition:opacity .3s}
@media (min-width:1220px){.lightbox__close{right:-58px;top:0}} /* beside the frame, clear of the header's menu button */
.lightbox.is-tall .lightbox__stage video{aspect-ratio:9/16}

/* ------------------------------------------------- everything in the box */
/* A phone shows the five groups as tabs, one group at a time (build.mjs, landing.js); a laptop shows every group. */
.box{display:grid;gap:12px;margin-top:28px}
.box__group{padding:16px 16px 6px;border-radius:22px;background:var(--bg);box-shadow:0 0 0 1px rgba(7,19,15,.05)}
.box__gt{display:flex;align-items:center;gap:10px;font-family:var(--f-head);font-size:19px;font-weight:700;letter-spacing:-.01em}
.box__gi{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:10px;background:linear-gradient(135deg,var(--accent-lt),var(--accent));box-shadow:0 6px 12px -6px rgba(var(--accent-rgb),.7);font-size:16px;color:#fff}
.box__list{display:grid;margin-top:8px}
.box__item{display:grid;grid-template-columns:36px minmax(0,1fr);gap:12px;padding:11px 0;border-top:1px solid rgba(7,19,15,.07)}
.box__ico{display:flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:10px;background:#fff;box-shadow:0 0 0 1px rgba(7,19,15,.07);font-size:17px;color:var(--accent)}
.box__name{display:flex;flex-wrap:wrap;align-items:center;gap:5px 8px;min-height:22px}
.box__name b{font-size:15.5px;font-weight:600;line-height:1.3}
.box__item p{margin-top:2px;font-size:15px;line-height:1.45;color:rgba(var(--fg-rgb),.64);text-wrap:pretty}
.box__tabs{display:none}
.box__item--note{display:block}
.box__more{display:inline-flex;align-items:center;gap:7px;min-height:44px;font-size:15px;font-weight:600;line-height:1.35;color:var(--accent)}
.box__more .ico{flex:none;font-size:15px;stroke-width:2.4}
.box__note{margin-top:16px;font-size:15px;line-height:1.4;text-align:center;color:rgba(var(--fg-rgb),.64)}
@media (max-width:767px){
  .js .box__tabs{display:flex;flex-wrap:wrap;justify-content:center;gap:8px}
  .box__tabs button{display:inline-flex;align-items:center;gap:7px;min-height:44px;padding:0 15px 0 13px;border-radius:999px;background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.05),0 0 0 1px rgba(7,19,15,.1);font-size:15px;font-weight:600;color:rgba(var(--fg-rgb),.78);transition:background-color .2s,color .2s}
  .box__tabs .ico{font-size:16px;color:var(--accent)}
  .box__tabs [aria-selected="true"]{background:var(--accent);box-shadow:0 8px 18px -8px rgba(var(--accent-rgb),.7);color:#fff}
  .box__tabs [aria-selected="true"] .ico{color:#fff}
  .js .box__group.is-off{display:none}
  .js .box__gt{display:none}
  .js .box__group{padding-top:4px}
  .js .box__list{margin-top:0}
  .js .box__item:first-child{border-top:0}
}
@media (min-width:700px){
  .box{grid-template-columns:repeat(2,1fr)}
}
@media (min-width:1000px){
  .box{grid-template-columns:repeat(6,1fr);gap:16px;margin-top:36px}
  .box__group{grid-column:span 2;padding:18px 20px 6px}
  .box__item{padding:9px 0}
  /* row 1: Inbox · Team · Speed tools (6 · 5 · 5 items). Row 2: AI (2 items + its note) beside Boss view (5 items in two
     columns, so three rows each): no group is left with a large empty block */
  .box__group:nth-child(5){grid-column:span 2}
  .box__group:nth-child(6){grid-column:span 4}
  .box__group:nth-child(6) .box__list{grid-template-columns:1fr 1fr;column-gap:32px}
}


/* -------------------------------------------------------------------- faq */
.section--band{padding-inline:12px}
.faq{max-width:1152px;margin-inline:auto;padding:44px 16px;border-radius:28px;background:linear-gradient(180deg,var(--t1),var(--t2));text-align:center}
.faq .h2,.faq .lead{margin-inline:auto}
.faq__list{display:grid;gap:10px;max-width:672px;margin:28px auto 0;text-align:left}
.faq__item{overflow:hidden;border-radius:18px;background:#fff;box-shadow:0 4px 20px -10px rgba(8,40,30,.1),0 0 0 1px rgba(0,0,0,.03)}
.faq__item button{display:flex;width:100%;align-items:center;justify-content:space-between;gap:12px;min-height:62px;padding:14px 20px;font-family:var(--f-head);font-size:16px;font-weight:600;line-height:1.3;text-align:left}
.faq__item button>span{display:flex;gap:8px}
.faq__item button i{font-style:normal;color:rgba(var(--fg-rgb),.64)}
.faq__item button .ico{font-size:16px;color:rgba(var(--fg-rgb),.5);transition:transform .2s}
.faq__item.is-open button .ico{transform:rotate(180deg)}
.faq__panel{display:grid;grid-template-rows:0fr;transition:grid-template-rows .3s var(--ease)}
.faq__panel>div{min-height:0;overflow:hidden;visibility:hidden;transition:visibility 0s .3s}
.faq__item.is-open .faq__panel{grid-template-rows:1fr}
.faq__item.is-open .faq__panel>div{visibility:visible;transition-delay:0s}
.faq__panel p{padding:0 20px 20px;font-size:15px;line-height:1.6;color:rgba(var(--fg-rgb),.62)}
@media (min-width:900px){.section--band{padding-inline:24px}.faq{padding:80px 24px;border-radius:40px}}
.faq__panel p+p{margin-top:-8px}

/* -------------------------------------------------------------- final call */
.cta{position:relative;overflow:hidden;padding:54px 20px 40px;border-radius:28px;background:radial-gradient(70% 90% at 50% 0%,#fff 0%,rgba(255,255,255,0) 70%),linear-gradient(140deg,#e6f6ef 0%,#cfeee2 55%,#dff4ec 100%);box-shadow:0 0 0 1px rgba(var(--accent-rgb),.1),0 40px 80px -50px rgba(var(--accent-rgb),.6);text-align:center}
.cta>*{position:relative}
.cta__dots{position:absolute;inset:0;background-image:radial-gradient(circle at 1px 1px,rgba(var(--accent-rgb),.2) 1px,transparent 0);background-size:24px 24px;opacity:.4;pointer-events:none}
.cta__shape{display:none}
.cta__title{max-width:820px;margin-inline:auto;font-family:var(--f-head);font-size:clamp(2.1rem,9.2vw,3.6rem);font-weight:700;line-height:1.04;letter-spacing:-.04em;text-wrap:balance;color:#062019}
.cta__sub{max-width:576px;margin:16px auto 0;font-size:17px;line-height:1.5;color:rgba(6,32,25,.7);text-wrap:balance}
.cta__row{display:flex;flex-direction:column;align-items:center;gap:12px;margin-top:28px}
.cta__num{margin-top:16px;font-size:15.5px;line-height:1.4;color:rgba(6,32,25,.7)}
.cta__num a{display:inline-flex;align-items:center;min-height:44px;padding:0 4px;font-family:var(--f-head);font-size:22px;font-weight:700;letter-spacing:-.01em;color:#062019}
.cta__stat{max-width:560px;margin:22px auto 0;padding-top:20px;border-top:1px solid rgba(var(--accent-rgb),.16);font-size:15px;line-height:1.45;color:rgba(6,32,25,.72)}
.cta__stat cite{font-style:normal;font-weight:600;white-space:nowrap;color:rgba(6,32,25,.8)}
.cta__stat cite::before{content:"— "}
@media (min-width:560px){.cta__row{flex-direction:row;justify-content:center}}
@media (min-width:900px){.cta{padding:84px 32px 56px;border-radius:40px}.cta__num a{font-size:26px}}

/* ------------------------------------------------------- the pop-out (V3.1) */
/* One <dialog> for every clip (landing.js 10): the title, the clip (or the opener's mini-UI enlarged until its clip
   lands), one line, the X. Esc, the X and the backdrop close it; focus returns to the opener.
   Every clip is 1080x1350 (4:5), so the stage is a 4:5 box (reserved before the video loads: no shift, no bars) on the
   page's light tint, never black. Phone: the clip fills the dialog's width; on a short screen it shrinks by height
   (--pop-rest = the room the head and the line need), keeping 4:5, so the whole dialog fits. Laptop (or a wide short
   screen): the clip on the left at min(70vh, 600px) tall, the title, the X and the line on the right. */
.pop{--pop-rest:164px;width:min(calc(100vw - 24px),560px,calc((100dvh - 24px - var(--pop-rest)) * .8));max-width:none;max-height:calc(100vh - 24px);max-height:calc(100dvh - 24px);margin:auto;padding:0;border:0;border-radius:22px;background:#fff;box-shadow:0 40px 100px -20px rgba(0,0,0,.5),0 0 0 1px rgba(7,19,15,.06);overflow:hidden;color:var(--fg)}
.pop:not([open]){display:none}
.pop::backdrop{background:rgba(4,16,12,.72)}
.pop__in{display:flex;flex-direction:column}
.pop__head{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 10px 8px 18px}
.pop__t{font-family:var(--f-head);font-size:19px;font-weight:700;line-height:1.25;letter-spacing:-.02em}
.pop__t--ai{color:var(--ai-ink)} /* an AI feature's title, the colour of its chip */
.pop__close{display:flex;flex:none;align-items:center;justify-content:center;width:44px;height:44px;border-radius:14px;background:rgba(var(--fg-rgb),.06);font-size:20px}
.pop__stage{position:relative;width:100%;aspect-ratio:4/5;overflow:hidden;background:linear-gradient(180deg,var(--t1),var(--t2))}
.pop__video{display:block;width:100%;height:100%;object-fit:contain;background:var(--t1)}
.pop__video[hidden]{display:none}
.pop__fallback{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;padding:10px}
.pop__fallback[hidden]{display:none}
/* the enlarged mini-UI: a copy of the tile's art, 1.4x on a laptop, its own size on a phone */
.pop__clone{position:relative;flex:none;width:300px;height:auto;min-height:170px;background:none;font-size:13px}
.pop__clone .bt__t{display:none}
.pop__clone.lap,.pop__clone.askchat{width:min(100%,520px);height:auto}
.pop__clone.askchat .askqa{opacity:1}
.pop__d{padding:12px 18px 18px;font-size:16px;line-height:1.5;color:rgba(var(--fg-rgb),.74);text-wrap:pretty}
.motion .pop[open]{animation:pop-in .28s var(--ease)}
.motion .pop[open]::backdrop{animation:fade-in .25s}
@keyframes pop-in{from{opacity:0;transform:translateY(10px) scale(.98)}}
@media (min-width:640px){
  .pop__head{padding:14px 14px 10px 24px}
  .pop__t{font-size:22px}
  .pop__clone{transform:scale(1.4)}
  .pop__clone.lap,.pop__clone.askchat{transform:none} /* already full width: scaling would push them past the 4:5 stage */
  .pop__d{padding:14px 24px 22px;font-size:17px}
}
/* side by side: a laptop, or a wide screen too short for the column (a phone held sideways) */
@media (min-width:900px),(min-width:640px) and (max-height:640px){
  .pop{width:fit-content;max-width:calc(100vw - 48px)}
  .pop__in{display:grid;grid-template-columns:auto minmax(240px,320px);grid-template-rows:auto 1fr;grid-template-areas:"stage head" "stage desc"}
  .pop__head{grid-area:head;align-items:flex-start;padding:18px 14px 0 24px}
  .pop__t{padding-top:7px;font-size:24px}
  .pop__stage{grid-area:stage;width:auto;height:min(70vh,600px);height:min(70dvh,600px)}
  .pop__clone{transform:scale(1.25)} /* a tile's art at 1.25x fits the narrowest side stage (a 720 px tall screen: 403 px wide) */
  .pop__d{grid-area:desc;align-self:start;padding:10px 24px 24px}
}

/* ------------------------------------------------- own it outright (V3.2) */
/* a dark emerald strip near the price: one line, one white WhatsApp button (white on the dark ground: 13:1 and more) */
.own{position:relative;margin-top:var(--sec);padding:34px 0;color:#fff}
.own__bg{position:absolute;inset:0;z-index:-1;overflow:hidden;background:radial-gradient(60% 90% at 88% 50%,rgba(37,211,102,.22),transparent 70%),radial-gradient(40% 70% at 8% 0%,rgba(63,174,150,.2),transparent 70%),linear-gradient(180deg,#07241c,#051410)}
.own__in{display:flex;flex-direction:column;align-items:flex-start;gap:18px}
.own__t{font-family:var(--f-head);font-size:clamp(1.5rem,6.4vw,1.9rem);font-weight:700;line-height:1.15;letter-spacing:-.02em;color:rgba(255,255,255,.82);text-wrap:balance}
.own__t b{display:block;font-weight:800;color:#fff}
.own__btn{color:#07241c}
@media (min-width:900px){
  .own{padding:52px 0}
  .own__in{flex-direction:row;align-items:center;justify-content:space-between;gap:32px}
  .own__t{font-size:clamp(1.8rem,2.8vw,2.3rem)}
  .own__t b{display:inline}
}

/* ----------------------------------------------------------------- footer */
/* V3.2: big and plain: the logo, one promise line, the number once, "Built in Malaysia"; four link columns; one legal line.
   No language switcher (the header's is the page's one). Phone: the brand on top, the columns two by two. */
.footer{position:relative;margin-top:var(--sec);background:linear-gradient(180deg,#0a2d24,#041911 70%,#03120d);color:#fff}
.footer__in{padding-block:22px 22px}
.footer__bar{display:flex;flex-direction:column;align-items:flex-start;gap:14px;padding-bottom:22px;border-bottom:1px solid rgba(255,255,255,.12)}
.footer__btn{flex:none}
@media (max-width:767px){.footer__btn{display:none}} /* a phone: the final call's WhatsApp button and number sit one screen above (round 25) */
.footer__grid{display:grid;grid-template-columns:1fr 1fr;gap:16px 20px;margin-top:20px}
.footer__brandcol{grid-column:1/-1;display:flex;flex-direction:column;align-items:flex-start;gap:10px}
.footer__brand{display:inline-flex;align-items:center;min-height:44px}
.footer__brand img{width:auto;height:38px}
.footer__promise{max-width:420px;font-size:16px;line-height:1.5;color:rgba(255,255,255,.78);text-wrap:pretty}
.footer__wa{display:inline-flex;align-items:center;gap:8px;min-height:44px;font-family:var(--f-head);font-size:19px;font-weight:700;letter-spacing:-.01em;color:#fff}
.footer__wa .ico--wa{font-size:20px;color:#4ed19a}
.footer__built{display:inline-flex;align-items:center;gap:8px;font-size:14.5px;font-weight:600;color:rgba(255,255,255,.72)}
.footer__flag{position:relative;display:grid;grid-template-rows:repeat(4,1fr);flex:none;width:22px;height:14px;overflow:hidden;border-radius:2px;box-shadow:0 0 0 1px rgba(255,255,255,.18)}
.footer__flag i{background:#cc0001}
.footer__flag i:nth-child(even){background:#fff}
.footer__flag::before{content:"";position:absolute;left:0;top:0;width:50%;height:50%;background:#010066}
.footer__h{font-family:var(--f-head);font-size:14.5px;font-weight:700;letter-spacing:.01em;color:#fff}
.footer__col ul{display:grid;gap:0;margin-top:6px}
.footer__col a{display:inline-flex;align-items:center;min-height:44px;padding:8px 0;font-size:15px;line-height:1.45;color:rgba(255,255,255,.68);transition:color .2s}
.footer__col a:hover{color:#fff}
.footer__col .aisup{font-size:9px}
@media (max-width:767px){.footer__col[aria-labelledby="ft-product"],.footer__col[aria-labelledby="ft-ai"]{display:none}} /* a phone: those links repeat the page above and the menu; Company and Legal stay (round 28) */
.footer__base{margin-top:14px;padding-top:14px;border-top:1px solid rgba(255,255,255,.12)}
.footer__legal{font-size:12.5px;line-height:1.5;color:rgba(255,255,255,.5)}
.footer__dot,.footer__addr,.footer__co{display:none} /* a phone shows "© 2026 Utopia Accelerator Sdn Bhd"; the registration and address return on a laptop */
.footer__copy{font-weight:600;color:rgba(255,255,255,.72)}
@media (min-width:640px){
  .footer__bar{flex-direction:row;align-items:center;justify-content:space-between}
  .footer__grid{grid-template-columns:repeat(4,1fr);gap:28px 24px}
}
@media (min-width:900px){
  .airow__art.wsn{min-height:96px}
  .footer__in{padding-block:34px 30px}
  .footer__bar{padding-bottom:28px}
  .footer__grid{grid-template-columns:1.7fr 1fr 1fr 1fr 1fr;gap:32px;margin-top:48px}
  .footer__brandcol{grid-column:auto}
  .footer__brand img{height:44px}
  .footer__base{margin-top:52px}
  .footer__dot,.footer__addr,.footer__co{display:inline}
  .footer__co-s{display:none}
}


/* ----------------------------------------------------------------- motion */
@keyframes fade-in{from{opacity:0}}
@keyframes menu-in{from{opacity:0;transform:translateY(-10px)}}

/* ---- the billing toggle (CY 5 Nov 2026; core.js 8): one card, "6 months | Monthly". The thumb slides on the travel curve
   (motion.md travel curve); each value (.bv) keeps one slot sized to its widest option, so switching moves nothing */
.plans--one{grid-template-columns:minmax(0,520px)}
.plans--one .plan{display:flex;grid-row:auto}
.bill__tg{position:relative;display:inline-flex;align-self:flex-start;padding:4px;border-radius:999px;background:rgba(var(--accent-rgb),.08);box-shadow:inset 0 0 0 1px rgba(var(--accent-rgb),.14)}
.bill__tg::before{content:"";position:absolute;top:4px;bottom:4px;left:0;width:var(--tw,0);translate:var(--tx,0) 0;border-radius:999px;background:var(--accent);box-shadow:0 6px 14px -8px rgba(var(--accent-rgb),.9);transition:translate .35s cubic-bezier(.45,0,.1,1),width .35s cubic-bezier(.45,0,.1,1)}
.bill__tg:not(.is-ready) button[aria-checked="true"]{background:var(--accent)} /* before core.js measures the thumb */
.bill__tg button{position:relative;z-index:1;display:inline-flex;align-items:center;gap:7px;min-height:40px;padding:0 16px;border-radius:999px;font-size:15px;font-weight:600;line-height:1.2;white-space:nowrap;color:rgba(var(--fg-rgb),.72);transition:color .2s}
.bill__tg button[aria-checked="true"]{color:#fff}
.bill__save{padding:3px 7px;border-radius:999px;background:#d9f2e6;font-size:12px;font-style:normal;font-weight:700;line-height:1.2;color:#0b6b45;transition:background .2s,color .2s}
.bill__tg button[aria-checked="true"] .bill__save{background:rgba(255,255,255,.22);color:#fff}
.bill__tg button:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.bv{display:inline-grid;justify-items:start;vertical-align:baseline}
.bv>*{grid-area:1/1;transition:opacity .2s var(--ease),transform .25s var(--ease)}
[data-bill="p6"] .bv>[data-v="mo"],[data-bill="mo"] .bv>[data-v="p6"]{visibility:hidden;opacity:0;transform:translateY(.3em);transition:opacity .12s,transform .2s,visibility 0s .2s}
html:not(.motion) .bv>*,html:not(.motion) .bill__tg::before{transition:none}
.bv--flow{display:inline}
.bv--flow>*{display:inline}
[data-bill="p6"] .bv--flow>[data-v="mo"],[data-bill="mo"] .bv--flow>[data-v="p6"]{display:none}
.plan__price{flex-wrap:nowrap;white-space:nowrap}
@media (max-width:340px){.plan__price{flex-wrap:wrap}} /* the smallest phones: the period ("sebulan") takes the next line, never past the card */
@media (max-width:360px){.bill__tg button{padding:0 12px}}
/* one card (CY 5 Nov): on a laptop the words sit left and the card right, so the section has no empty half
   (craft.md › A page of demos: a figure fills its column) */
@media (min-width:900px){
  .price3{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,500px);grid-template-rows:auto auto;column-gap:64px;align-items:end}
  .price3>.sec__head{grid-column:1;grid-row:1}
  .price3>.price3__link{grid-column:1;grid-row:2;align-self:start;justify-self:start}
  .price3 .plans--one{grid-column:2;grid-row:1/3;align-self:center;margin-top:0;grid-template-columns:minmax(0,1fr)}
}
