/* ------------------------------------------------------------------
   Self-hosted, subsetted fonts.

   These were loaded from fonts.googleapis.com, which put a render-blocking
   stylesheet on a third-party origin in front of every page: the browser had
   to resolve and handshake googleapis, parse its CSS, then resolve and
   handshake gstatic before any text could render. Measured on a throttled
   mobile connection that was the single worst thing on the page.

   Subsetted to the 166 characters the site actually uses, which is why 278KB
   of Google's files became 98KB of ours. The rupee sign lives in latin-ext,
   not latin, so both subsets are kept — every price on the site needs it.
   ------------------------------------------------------------------ */
@font-face{font-family:'Archivo';font-style:normal;font-weight:400;
  font-display:swap;src:url('fonts/archivo-400-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Archivo';font-style:normal;font-weight:400;
  font-display:swap;src:url('fonts/archivo-400-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:'Archivo';font-style:normal;font-weight:500;
  font-display:swap;src:url('fonts/archivo-500-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Archivo';font-style:normal;font-weight:500;
  font-display:swap;src:url('fonts/archivo-500-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:'Archivo';font-style:normal;font-weight:600;
  font-display:swap;src:url('fonts/archivo-600-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Archivo';font-style:normal;font-weight:600;
  font-display:swap;src:url('fonts/archivo-600-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:'Archivo';font-style:normal;font-weight:700;
  font-display:swap;src:url('fonts/archivo-700-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Archivo';font-style:normal;font-weight:700;
  font-display:swap;src:url('fonts/archivo-700-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 Mono';font-style:normal;font-weight:400;
  font-display:swap;src:url('fonts/dm-mono-400-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'DM Mono';font-style:normal;font-weight:400;
  font-display:swap;src:url('fonts/dm-mono-400-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}

/* ==========================================================================
   SKYSTRIDE — panel system
   Floating panels over a photographic ground. Colours sampled from the
   reference dashboards; brand navy #0A2F4C stays the deepest ground.
   ========================================================================== */

:root{
  --ground:#0C1428;
  --panel:rgba(27,36,67,.54);
  --panel-solid:#1B2443;
  --raised:rgba(31,44,79,.62);
  --edge:rgba(255,255,255,.09);
  --edge-2:rgba(255,255,255,.16);
  --ink:#EFECE4;
  --dim:rgba(239,236,228,.72);
  --dimmer:rgba(239,236,228,.66);
  --accent:#7B72F0;
  --accent-text:#ABA4FF;
  --accent-2:#6A5FE6;
  --btn:#6259E2;
  --glow:rgba(106,95,230,.42);
  --ok:#5BD6A0;
  --star:#F5B942;

  --r-panel:22px; --r-card:16px; --r-chip:8px; --r-pill:100px;
  --shadow:0 2px 6px -2px rgba(0,0,0,.34), 0 12px 28px -12px rgba(0,0,0,.46),
           0 40px 80px -32px rgba(0,0,0,.60);
  --shadow-lg:0 4px 10px -2px rgba(0,0,0,.38), 0 22px 46px -14px rgba(0,0,0,.52),
           0 64px 120px -40px rgba(0,0,0,.72);
  --blur:blur(30px) saturate(180%);
  /* glass catches light on its top edge and shades on its bottom — an inset
     ring reads as a lit edge, a 1px border reads as an outlined box */
  --ring:inset 0 1px 0 rgba(255,255,255,.16), inset 0 -1px 0 rgba(0,0,0,.22);
  /* the tile: dark at the top, light pooling at the bottom, glow escaping
     past the bottom edge onto the page behind it */
  --tile-top:rgba(5,9,22,.66);
  --tile-bot:rgba(96,84,224,.62);
  --tile-bloom:rgba(168,160,255,1);
  --tile-rim:rgba(203,197,255,.72);
  --tile-cast:rgba(108,96,236,.60);
  --rim:linear-gradient(180deg,rgba(198,224,255,.60) 0%,rgba(150,138,242,.18) 44%,
        rgba(186,178,255,.95) 100%);
  --rim-soft:linear-gradient(180deg,rgba(198,224,255,.40) 0%,rgba(150,138,242,.12) 46%,
        rgba(186,178,255,.62) 100%);
  --halo:0 0 30px -8px var(--glow);
  --glass:rgba(22,32,60,.42);
  --chrome:rgba(13,21,44,.92);
  --field-edge:rgba(239,236,228,.46);
  --field-edge-2:rgba(239,236,228,.66);
  --fill:rgba(255,255,255,.045);
  --fill-2:rgba(255,255,255,.08);

  /* --- real frosted glass, the way Apple builds it ---------------------
     Three things separate Apple's glass from the template version:
     the tint is NEUTRAL (white at low alpha, never a coloured gradient),
     the top edge carries a specular hairline, and the panel does not glow.
     Glass refracts what is behind it — it is not a light source. Every
     blue bloom we had inside a tile was the thing making it read as a
     downloaded component. */
  --glass-a:rgba(255,255,255,.075);
  --glass-b:rgba(255,255,255,.022);
  --glass-line:rgba(255,255,255,.13);
  --glass-spec:rgba(255,255,255,.34);
  --glass-frost:blur(44px) saturate(185%);
  --glass-shadow:0 1px 2px rgba(0,0,0,.22), 0 10px 26px -10px rgba(0,0,0,.46),
                 0 34px 66px -30px rgba(0,0,0,.60);
  /* what the glass sits on, so every tile refracts the same thing */
  --glass-ground:rgba(7,13,28,.90);

  --pad:clamp(20px,4.5vw,64px);
  --col:1280px;
  --sec:clamp(72px,9vw,132px);
  --mono:'DM Mono',ui-monospace,monospace;
  --spring:cubic-bezier(.34,1.3,.5,1);
  --spring-soft:cubic-bezier(.28,1.14,.4,1);
  --ease:cubic-bezier(.22,1,.36,1);
}

html[data-theme="light"]{
  --btn:#584ED2;
  --ground:#DCE3EC;
  --panel:rgba(255,255,255,.74);
  --panel-solid:#FFFFFF;
  --raised:rgba(255,255,255,.80);
  --ring:inset 0 1px 0 rgba(255,255,255,.90), inset 0 -1px 0 rgba(16,38,74,.10);
  --tile-top:rgba(255,255,255,.50);
  --tile-bot:rgba(146,136,246,.34);
  --tile-bloom:rgba(186,180,255,.92);
  --tile-rim:rgba(255,255,255,.92);
  --tile-cast:rgba(130,118,238,.44);
  --rim:linear-gradient(180deg,rgba(255,255,255,1) 0%,rgba(255,255,255,.52) 46%,
        rgba(166,156,246,.88) 100%);
  --rim-soft:linear-gradient(180deg,rgba(255,255,255,.92) 0%,rgba(255,255,255,.42) 48%,
        rgba(166,156,246,.60) 100%);
  --halo:0 0 30px -8px rgba(150,138,242,.55);
  --glass:rgba(255,255,255,.58);
  --chrome:rgba(244,246,252,.94);
  --star:#8A5C04;
  --field-edge:rgba(10,47,76,.62);
  --field-edge-2:rgba(10,47,76,.82);
  --fill:rgba(16,38,74,.035);
  --fill-2:rgba(16,38,74,.06);
  --glass-a:rgba(255,255,255,.62);
  --glass-b:rgba(255,255,255,.40);
  --glass-line:rgba(16,38,74,.11);
  --glass-spec:rgba(255,255,255,.95);
  --glass-frost:blur(44px) saturate(180%);
  --glass-shadow:0 1px 2px rgba(16,38,74,.06), 0 10px 26px -10px rgba(16,38,74,.14),
                 0 34px 66px -30px rgba(16,38,74,.20);
  --glass-ground:rgba(221,227,238,.88);
  --edge:rgba(16,38,74,.14);
  --edge-2:rgba(16,38,74,.24);
  --ink:#0A2F4C;
  --dim:rgba(10,47,76,.72);
  --dimmer:rgba(10,47,76,.80);
  --accent:#5B7CFF;
  --accent-text:#2E4CC4;
  --accent-2:#6C8BFF;
  --glow:rgba(120,140,255,.34);
  --shadow:0 2px 6px -2px rgba(16,38,74,.10), 0 12px 28px -12px rgba(16,38,74,.16),
           0 40px 80px -32px rgba(16,38,74,.22);
  --shadow-lg:0 4px 10px -2px rgba(16,38,74,.12), 0 22px 46px -14px rgba(16,38,74,.20),
           0 64px 120px -40px rgba(16,38,74,.28);
  --shadow-lg:0 40px 90px -38px rgba(16,38,74,.32);
}

*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;background:var(--ground)}
body{background:transparent;color:var(--ink);
  font-family:'Archivo','Helvetica Neue',Arial,sans-serif;
  font-size:1.0625rem;line-height:1.6;letter-spacing:-0.011em;
  -webkit-font-smoothing:antialiased;overflow-x:hidden;
  transition:color 400ms var(--ease)}
img{display:block;max-width:100%;height:auto}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
::selection{background:var(--accent);color:#fff}
:focus-visible{outline:2px solid var(--ink);outline-offset:3px;border-radius:6px;
  box-shadow:0 0 0 5px var(--ground)}

.wrap{max-width:var(--col);margin:0 auto;padding-inline:var(--pad)}
.sec{padding-block:var(--sec)}

/* ---------- the ground ---------- */
.ground{position:fixed;inset:0;z-index:0;overflow:hidden;background:var(--ground)}
.ground img{width:100%;height:100%;object-fit:cover;object-position:center 30%;
  transition:opacity 700ms var(--ease)}
.ground .night{opacity:1}
.ground .day{position:absolute;inset:0;opacity:0}
html[data-theme="light"] .ground .night{opacity:0}
html[data-theme="light"] .ground .day{opacity:1}
.ground::after{content:"";position:absolute;inset:0;
  background:radial-gradient(120% 80% at 50% 0%,transparent 30%,rgba(12,20,40,.55) 100%)}
html[data-theme="light"] .ground::after{
  background:radial-gradient(120% 80% at 50% 0%,transparent 40%,rgba(231,236,242,.6) 100%)}
main,footer{position:relative;z-index:2}

/* ---------- type ---------- */
h1{font-size:clamp(2.5rem,5.2vw,4.25rem);line-height:1.08;text-wrap:balance;letter-spacing:-0.038em;font-weight:600}
h2{font-size:clamp(1.75rem,3.2vw,2.75rem);line-height:1.1;letter-spacing:-0.03em;font-weight:600}
h3{font-size:clamp(1.0625rem,1.5vw,1.375rem);line-height:1.3;letter-spacing:-0.02em;font-weight:600}
p{max-width:62ch}
.lead{font-size:clamp(1rem,1.3vw,1.1875rem);line-height:1.55;color:var(--dim);max-width:46ch}
.dim{color:var(--dim)}
.eyebrow{font-family:var(--mono);font-size:.75rem;letter-spacing:.10em;text-transform:uppercase;
  color:var(--dimmer);display:block}
.grad{background:linear-gradient(96deg,var(--accent),#8FB4FF 60%,var(--ink));
  -webkit-background-clip:text;background-clip:text;color:transparent}
.head{max-width:46ch;margin-bottom:clamp(28px,3.6vw,48px);
  margin-inline:auto;text-align:center}
.head h2{margin-top:14px}
.head p{margin-top:16px;color:var(--dim)}

/* ---------- panels ---------- */
.panel{position:relative;border-radius:var(--r-panel);border:1px solid transparent;
  background:linear-gradient(180deg,var(--tile-top) 0%,transparent 38%,var(--tile-bot) 100%) padding-box,
             var(--panel) padding-box,
             var(--rim) border-box;
  -webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.12),var(--shadow),
             0 30px 72px -18px var(--tile-cast),var(--halo);
  overflow:hidden}
/* the light pooling at the bottom of the tile — clipped by the panel, so it
   reads as light gathering inside the glass rather than a shape sitting on it */
.panel::after{content:"";position:absolute;z-index:0;pointer-events:none;
  left:50%;bottom:-40%;translate:-50% 0;width:136%;aspect-ratio:2/1;border-radius:50%;
  background:radial-gradient(closest-side,var(--tile-bloom),transparent 76%);
  filter:blur(30px);opacity:.85}
.panel::before{content:"";position:absolute;inset:0 0 auto 0;height:1px;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.28),transparent)}
.panel-pad{padding:clamp(20px,2.4vw,30px)}
.panel.grid::before{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background-image:linear-gradient(rgba(255,255,255,.05) 1px,transparent 1px),
    linear-gradient(90deg,rgba(255,255,255,.05) 1px,transparent 1px);
  background-size:52px 52px;
  -webkit-mask-image:linear-gradient(180deg,transparent 30%,#000 100%);
  mask-image:linear-gradient(180deg,transparent 30%,#000 100%);height:auto}
/* the signature move: a soft glow inside the panel, behind content */
.panel .bloom{position:absolute;width:60%;aspect-ratio:1;border-radius:50%;
  background:var(--glow);filter:blur(60px);pointer-events:none;z-index:0;
  transition:transform 900ms var(--ease),opacity 600ms var(--ease)}
.panel > *:not(.bloom){position:relative;z-index:1}
.panel.lift{transition:transform 220ms var(--ease),box-shadow 300ms var(--ease)}
.panel.lift:hover{transform:translateY(-6px);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.16),var(--shadow-lg),
             0 34px 74px -22px var(--tile-cast),0 0 44px -6px var(--glow)}
.panel.lift{--tile-cast-t:1}
.panel.lift::after{transition:opacity 320ms var(--ease)}
.panel.lift:hover::after{opacity:1}
.panel.lift:active{transform:translateY(-2px) scale(.996)}

/* ---------- buttons, chips ---------- */
.btn{position:relative;display:inline-flex;align-items:center;gap:9px;border-radius:var(--r-pill);
  padding:14px 26px;font-size:.9375rem;font-weight:500;
  background:linear-gradient(180deg,color-mix(in srgb,var(--btn) 95%,white),var(--btn));
  color:#fff;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.34),inset 0 -1px 0 rgba(0,0,0,.20),
             0 10px 26px -12px var(--btn),0 18px 44px -18px var(--glow);
  transition:transform 140ms var(--ease),box-shadow 200ms var(--ease),background 200ms var(--ease)}
.btn:hover{transform:translateY(-2px);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.40),inset 0 -1px 0 rgba(0,0,0,.20),
             0 18px 38px -14px var(--accent),0 30px 66px -18px var(--glow)}
.btn:active{transform:translateY(0) scale(.98)}
.btn:focus-visible,.btn-ghost:focus-visible{box-shadow:0 0 0 5px var(--ground)}
.btn-lg{padding:17px 32px;font-size:1rem}
.btn-ghost{color:var(--ink)}
/* ---------- pills: soft, translucent, lit on the top edge ---------- */
.btn-ghost,.chip,.wall-track span,.tag{
  background:linear-gradient(180deg,rgba(255,255,255,.11),rgba(255,255,255,.03));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.20),inset 0 -1px 0 rgba(0,0,0,.16),
             0 6px 16px -8px rgba(0,0,0,.44);
  border:0;transition:background 260ms var(--ease),box-shadow 260ms var(--ease),
    color 260ms var(--ease),transform 200ms var(--ease)}
html[data-theme="light"] .btn-ghost,html[data-theme="light"] .chip,
html[data-theme="light"] .wall-track span,
html[data-theme="light"] .tag{
  background:linear-gradient(180deg,rgba(255,255,255,.95),rgba(255,255,255,.62));
  box-shadow:inset 0 1px 0 rgba(255,255,255,1),inset 0 -1px 0 rgba(16,38,74,.10),
             0 6px 16px -8px rgba(16,38,74,.18)}
.btn-ghost:hover{
  background:linear-gradient(180deg,rgba(255,255,255,.17),rgba(255,255,255,.06));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.28),inset 0 -1px 0 rgba(0,0,0,.16),
             0 12px 30px -10px var(--glow);transform:translateY(-1px)}
.chip.on{color:var(--accent-text);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.24),inset 0 0 0 1px rgba(79,139,255,.34),
             0 8px 24px -10px var(--glow)}

.btn-row{display:flex;flex-wrap:wrap;gap:12px;align-items:center}
.chip{display:inline-flex;align-items:center;gap:7px;border-radius:var(--r-pill);
  padding:7px 13px;font-family:var(--mono);font-size:.75rem;letter-spacing:.08em;
  text-transform:uppercase;color:var(--dim)}
.chip .dot{width:6px;height:6px;border-radius:50%;background:currentColor}
.under{display:block;font-family:var(--mono);font-size:.75rem;letter-spacing:.08em;
  text-transform:uppercase;color:var(--dimmer);margin-top:14px}

/* ---------- nav ---------- */
.nav{position:fixed;top:14px;left:0;right:0;z-index:60;display:flex;justify-content:center;
  padding-inline:var(--pad)}
.nav-in{display:flex;align-items:center;gap:clamp(10px,1.8vw,22px);
  padding:8px 8px 8px 18px;border-radius:var(--r-pill);
  border:1px solid transparent;
  background:var(--panel) padding-box,var(--rim) border-box;
  -webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.14),var(--shadow),var(--halo)}
.brand{display:flex;align-items:center;gap:9px;font-weight:700;letter-spacing:.02em;
  text-transform:uppercase;font-size:.9375rem}
.brand img{width:22px}
.nlinks{display:flex;gap:2px}
.nlinks a{padding:12px 14px;border-radius:var(--r-pill);font-size:.875rem;color:var(--dim);
  transition:background 280ms var(--ease),color 280ms var(--ease)}
.nlinks a:hover,.nlinks a[aria-current]{background:rgba(255,255,255,.09);color:var(--ink)}
html[data-theme="light"] .nlinks a:hover,html[data-theme="light"] .nlinks a[aria-current]{background:rgba(16,38,74,.07)}
/* The theme toggle is inverted against the page on purpose: it shows you
   the mode you are about to get rather than the one you are already in. A
   dark button on a light page reads as "tap for dark" without needing a
   label. The old translucent-white fill was built for the dark theme and
   was close to invisible once light became the default. */
.tbtn{width:44px;height:44px;border-radius:50%;
  background:var(--ink);color:var(--ground);
  box-shadow:0 1px 2px rgba(0,0,0,.18),0 6px 16px -8px rgba(0,0,0,.35);
  display:grid;place-items:center;flex:none;border:0;
  transition:background 260ms var(--ease),color 260ms var(--ease),
             transform 160ms var(--ease),box-shadow 200ms var(--ease)}
.tbtn:hover{transform:translateY(-1px);
  box-shadow:0 2px 4px rgba(0,0,0,.20),0 10px 22px -10px rgba(0,0,0,.45)}
.tbtn:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
@media (prefers-reduced-motion:reduce){
  .tbtn{transition:none}.tbtn:hover{transform:none}
}
.tbtn .moon{display:none}
html[data-theme="light"] .tbtn .sun{display:none}
html[data-theme="light"] .tbtn .moon{display:block}
.burger{display:none;min-height:44px;padding:12px 8px;align-items:center;font-family:var(--mono);font-size:.75rem;letter-spacing:.12em;text-transform:uppercase}
.menu{position:fixed;inset:0;z-index:70;background:var(--ground);padding:var(--pad);
  display:flex;flex-direction:column;justify-content:center;gap:2px;
  transform:translateY(-101%);visibility:hidden;
  transition:transform 600ms var(--ease),visibility 0s linear 600ms}
.menu.open{transform:none;visibility:visible;transition-delay:0s}
.menu a{font-size:clamp(1.75rem,7vw,2.5rem);font-weight:600;letter-spacing:-0.03em;
  padding-block:13px;border-bottom:1px solid var(--edge)}

/* ---------- hero ---------- */
.hero{padding-block:clamp(148px,16vw,208px) clamp(24px,3vw,40px)}
.hero h1{max-width:14ch}
.hero .lead{margin-top:20px}
.hero .btn-row{margin-top:clamp(30px,4vw,44px)}

/* ---------- tier cards ---------- */
.tiers{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(12px,1.4vw,18px)}
.tier{display:flex;flex-direction:column;min-height:340px;padding:clamp(20px,2.2vw,28px)}
.tier .price{font-size:clamp(1.75rem,2.8vw,2.375rem);font-weight:600;letter-spacing:-0.035em;
  line-height:1;margin-top:14px}
.tier .price small{display:block;font-family:var(--mono);font-size:.75rem;letter-spacing:.08em;
  text-transform:uppercase;color:var(--dimmer);font-weight:400;margin-bottom:8px}
.tier ul{list-style:none;display:grid;gap:9px;margin-top:20px;font-size:.9375rem;color:var(--dim)}
.tier li{display:grid;grid-template-columns:18px 1fr;gap:9px}
.tier li svg{margin-top:6px;color:var(--accent)}
.tier .go{margin-top:auto;padding-top:22px;display:flex;align-items:center;justify-content:space-between;
  font-size:.9375rem}
.tier .arrow{width:32px;height:32px;border-radius:50%;
  background:linear-gradient(180deg,rgba(255,255,255,.12),rgba(255,255,255,.03));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.22),inset 0 -1px 0 rgba(0,0,0,.16);
  display:grid;place-items:center;transition:background 340ms var(--spring),color 340ms var(--ease),
  transform 420ms var(--spring)}
.tier:hover .arrow{background:var(--accent);color:#fff;border-color:var(--accent);transform:rotate(45deg)}
.tier.featured{box-shadow:inset 0 1px 0 rgba(255,255,255,.22),inset 0 0 0 1px rgba(79,139,255,.30),
  var(--shadow-lg),0 30px 66px -20px var(--tile-cast),0 0 46px -6px var(--glow)}
.tier.featured::after{opacity:.7}
.tier.featured .bloom{opacity:.85}

/* ---------- work ---------- */
.work-row{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,.9fr);
  gap:clamp(20px,3vw,44px);align-items:center;padding:clamp(16px,2vw,22px)}
.work-row:nth-child(even){grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr)}
.tagrow{display:flex;flex-wrap:wrap;gap:7px;margin-top:16px}
.step{position:relative;overflow:hidden;padding:clamp(18px,2vw,24px);
  border-radius:var(--r-card);border:1px solid transparent;
  background:linear-gradient(180deg,transparent 50%,color-mix(in srgb,var(--tile-bot) 44%,transparent) 100%) padding-box,
             var(--panel) padding-box,var(--rim-soft) border-box;
  -webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.10),var(--shadow),
             0 16px 40px -24px var(--tile-cast);}
.step > *{position:relative;z-index:1}
.step .n{font-family:var(--mono);font-size:.75rem;letter-spacing:.14em;color:var(--accent-text)}
.step h3{margin-block:12px 7px}
.step p{font-size:.875rem;color:var(--dim)}
.faq details{position:relative;border-radius:var(--r-card);margin-bottom:10px;overflow:hidden;
  border:1px solid transparent;
  background:linear-gradient(180deg,transparent 55%,color-mix(in srgb,var(--tile-bot) 34%,transparent) 100%) padding-box,
             var(--panel) padding-box,var(--rim-soft) border-box;
  -webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.10),var(--shadow),
             0 14px 34px -24px var(--tile-cast);
  transition:box-shadow 320ms var(--ease),background 320ms var(--ease)}
.faq details::after{content:"";position:absolute;z-index:0;pointer-events:none;
  left:50%;bottom:-74%;translate:-50% 0;width:108%;aspect-ratio:5/1;border-radius:50%;
  background:radial-gradient(closest-side,var(--tile-bloom),transparent 78%);
  filter:blur(26px);opacity:.16;transition:opacity 320ms var(--ease)}
/* an open answer is tall enough to carry the full treatment */
.faq details:hover::after{opacity:.30}
.faq details.is-open::after{opacity:.62;bottom:-40%;aspect-ratio:2.4/1}
.faq details.is-open{
  background:linear-gradient(180deg,var(--tile-top) 0%,transparent 44%,var(--tile-bot) 100%) padding-box,
             var(--panel) padding-box,var(--rim) border-box;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.12),var(--shadow-lg),
  0 26px 56px -20px var(--tile-cast),var(--halo)}
.faq summary,.faq p{position:relative;z-index:1;padding-inline:clamp(18px,2vw,24px)}
.faq summary{list-style:none;cursor:pointer;padding-block:19px;display:flex;gap:20px;
  justify-content:space-between;align-items:baseline;font-size:clamp(.9375rem,1.2vw,1.0625rem);font-weight:500}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";font-family:var(--mono);color:var(--accent-text);flex:none}
.faq details.is-open summary::after{content:"\2013"}
.faq p{padding-bottom:19px;color:var(--dim);max-width:70ch;font-size:.9375rem}

/* ---------- footer ---------- */
footer{margin-top:var(--sec);box-shadow:inset 0 1px 0 rgba(255,255,255,.10);padding-block:clamp(36px,4.4vw,60px);
  background:var(--panel);-webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur)}
.foot{display:grid;grid-template-columns:minmax(0,1.5fr) repeat(3,minmax(0,1fr));gap:28px}
.foot a{display:block;color:var(--dim);font-size:.9375rem;padding-block:11px}
.foot a:hover{color:var(--ink)}
.foot-base{display:flex;justify-content:space-between;flex-wrap:wrap;gap:12px;margin-top:32px;
  padding-top:18px;border-top:1px solid var(--edge);font-family:var(--mono);font-size:.75rem;
  letter-spacing:.1em;text-transform:uppercase;color:var(--dimmer)}
.wa{position:fixed;right:16px;bottom:16px;z-index:50;display:none;align-items:center;gap:8px;
  background:var(--accent);color:#fff;border-radius:var(--r-pill);padding:12px 18px;font-size:.9375rem}
@media (max-width:820px){.wa{display:inline-flex}}

/* ---------- entrance ---------- */
.rv{opacity:0;transform:translateY(16px) scale(.985);
  transition:opacity 420ms var(--ease),transform 420ms var(--ease)}
.rv.in{opacity:1;transform:none}

/* ---------- page loader ----------
   Plays on every load — softer and warmer in light theme (a muted bloom
   and the unbrightened mark, which already reads dark-on-cream) than in
   dark theme (the mark needs lifting off a near-black ground). */
#pageload{position:fixed;inset:0;z-index:9999;display:flex;align-items:center;
  justify-content:center;background:var(--ground);
  transition:opacity 480ms var(--ease),transform 480ms var(--ease)}
#pageload.gone{opacity:0;transform:scale(1.035);pointer-events:none}
html.no-loader #pageload{display:none}
#pageload .pl-in{display:flex;flex-direction:column;align-items:center}
#pageload .mk{position:relative;width:clamp(52px,8vw,76px);aspect-ratio:99/96}
#pageload .mk::before{content:"";position:absolute;inset:-85%;border-radius:50%;
  background:radial-gradient(circle,var(--accent) 0%,transparent 64%);
  opacity:0;filter:blur(10px);animation:pl-glow 900ms var(--ease) 60ms forwards}
#pageload .mk img{position:absolute;inset:0;width:100%;height:100%;display:block;
  clip-path:polygon(-20% -20%,-20% -20%,-40% 120%,-40% 120%);
  animation:pl-draw 620ms var(--ease) 140ms forwards}
#pageload .mk img.mk-light{display:none}
html[data-theme="light"] #pageload .mk img.mk-dark{display:none}
html[data-theme="light"] #pageload .mk img.mk-light{display:block}
#pageload .pl-word{margin-top:16px;font-weight:700;letter-spacing:.16em;
  text-transform:uppercase;font-size:.75rem;color:var(--dim);text-align:center;
  opacity:0;transform:translateY(7px);animation:pl-word 480ms var(--ease) 640ms forwards}
@keyframes pl-glow{0%{opacity:0}50%{opacity:.34}100%{opacity:.14}}
html[data-theme="light"] #pageload .mk::before{animation-name:pl-glow-light}
@keyframes pl-glow-light{0%{opacity:0}50%{opacity:.22}100%{opacity:.09}}
@keyframes pl-draw{to{clip-path:polygon(-20% -20%,140% -20%,120% 120%,-40% 120%)}}
@keyframes pl-word{to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){#pageload{display:none}}

/* ---------- blog ---------- */
.blog-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:20px}
.blog-card{display:flex;flex-direction:column;padding:26px}
.blog-card .eyebrow{color:var(--accent-text)}
.blog-card h2{margin-top:12px;font-size:1.1875rem;letter-spacing:normal}
.blog-card p{margin-top:10px;color:var(--dim);font-size:.9375rem;line-height:1.55;flex-grow:1}
.blog-card .blog-meta{margin-top:18px;display:flex;gap:10px;align-items:center;
  font-family:var(--mono);font-size:.75rem;color:var(--dimmer)}
.blog-card .blog-meta i{width:3px;height:3px;border-radius:50%;background:currentColor;flex:none}

.article-head{max-width:66ch;margin-inline:auto;text-align:center}
.article-head h1{font-size:clamp(2rem,4.2vw,3.25rem);text-wrap:balance}
.article-head .dek{margin-top:16px;font-size:clamp(1.0625rem,1.6vw,1.25rem);line-height:1.55;
  color:var(--dim);max-width:52ch;margin-inline:auto}
.article-meta{margin-top:20px;display:flex;justify-content:center;gap:10px;align-items:center;
  font-family:var(--mono);font-size:.75rem;color:var(--dimmer)}
.article-meta i{width:3px;height:3px;border-radius:50%;background:currentColor;flex:none}

.article-body{max-width:64ch;margin:0 auto}
.article-body h2{margin-top:2.4em;font-size:clamp(1.375rem,2.2vw,1.75rem)}
.article-body h3{margin-top:1.8em}
.article-body p{margin-top:1.05em;line-height:1.7;color:var(--dim)}
.article-body p:first-of-type{margin-top:0}
.article-body ul,.article-body ol{margin-top:1.05em;padding-left:1.3em;color:var(--dim);line-height:1.65}
.article-body li+li{margin-top:.5em}
.article-body strong{color:var(--ink);font-weight:600}
.article-body p a,.article-body .article-callout a{color:var(--ink);text-decoration:underline;
  text-decoration-color:var(--edge);text-underline-offset:3px}
.article-callout{margin-top:1.8em;padding:20px 24px;border-radius:var(--r-panel);
  border-left:3px solid var(--accent);background:var(--panel-solid)}
.article-callout p{margin-top:0}
.article-callout p+p{margin-top:.7em}
.article-embed{margin-top:2.4em}
.article-embed .tiers{margin-top:0}

/* ---------- responsive ---------- */
@media (max-width:1000px){.work-row,.work-row:nth-child(even){grid-template-columns:1fr}
  .foot{grid-template-columns:1fr 1fr}
}
@media (max-width:660px){
  .nlinks{display:none}.burger{display:block}.nav .btn{display:none}
  /* same desktop grid, scaled as one piece — see .bento in the homepage
     bento-grid rules for why zoom rather than a narrower grid */
  .tiers{zoom:.5;grid-template-columns:repeat(3,minmax(0,1fr))}
  .foot{grid-template-columns:1fr}
  :root{--blur:blur(12px) saturate(140%)}
}
@media (prefers-reduced-motion:reduce){
  /* Reduced motion means gentler, not none. What goes is TRAVEL — slides,
     lifts, parallax, scale. What stays is colour and opacity, because those
     are how a control tells you it answered. The rule that used to live here
     was *{animation:none!important;transition-duration:1ms!important}, which
     also silenced every hover and focus response on the site. */
  *,*::before,*::after{animation-duration:.01ms!important;animation-delay:0s!important;
    animation-iteration-count:1!important;scroll-behavior:auto!important}
  .rv{opacity:1;transform:none;transition:opacity 200ms var(--ease)}
  /* arrive, do not travel */
  .panel.lift:hover,.panel.lift:active,.btn:hover,.btn:active,.rnav:hover,
  .bento-bar:hover,.bento-bar:hover .btn,.step:hover,.tier:hover .arrow{transform:none}.work-row:hover .work-media img,
  .step:hover .step-art img{transform:none}
  .nav,.nav.nav-off{transition:opacity 200ms var(--ease)}
  .nav.nav-off{transform:none}
}

/* Apple ships two more of these, and this site is mostly glass and a
   photographic ground, so both are load-bearing rather than decorative. */
@media (prefers-reduced-transparency:reduce){.panel,.nav-in{-webkit-backdrop-filter:none;backdrop-filter:none;
    background:var(--panel-solid)}
  .ground{background-image:none}
}
@media (prefers-contrast:more){.panel{border-color:var(--ink);
    background:var(--panel-solid)}
  :root{--dim:rgba(239,236,228,.94);--dimmer:rgba(239,236,228,.88);
        --faint:rgba(239,236,228,.78)}
  html[data-theme="light"]{--dim:#12203C;--dimmer:#1B2A46;--faint:#33405C}
}

/* ---------- H6: one ground image per theme, via CSS so the other never downloads ---------- */
.ground{background:var(--ground) url("bg-night-sm.webp") center 30%/cover no-repeat}
html[data-theme="light"] .ground{background-image:url("bg-day-sm.webp")}
@media (min-width:901px){
  .ground{background-image:url("bg-night.webp")}
  html[data-theme="light"] .ground{background-image:url("bg-day.webp")}
}
/* fewer compositing layers: blur only where it overlaps moving content */

.panel{-webkit-backdrop-filter:none;backdrop-filter:none;background:var(--panel-solid)}
.nav-in{-webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);background:var(--panel)}
/* single-column page heroes (work, contact) — the homepage hero stays left,
   it is balanced by the price tile beside it */
.hero-solo{text-align:center}
.hero-solo h1{margin-inline:auto}
.hero-solo .lead{max-width:58ch;margin-inline:auto}
.hero-solo .btn-row,.hero-solo .cta-row{justify-content:center}

/* what's-included list + price box */
.two{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(24px,4vw,64px);align-items:start}
.scrub-note{font-family:var(--mono);font-size:.75rem;letter-spacing:.08em;text-transform:uppercase;
  color:var(--dimmer);margin-top:14px}

/* misc */
.dimtext{color:var(--dim)}
.glowline{height:1px;background:linear-gradient(to right,var(--edge-2),transparent);
  margin-top:clamp(40px,5vw,64px)}
.cta-row{display:flex;flex-wrap:wrap;gap:12px;align-items:center}
/* the sections above already carry ~130px of bottom padding; matching it
   here stacked two gaps into one 260px void */
.closing{text-align:center;padding-block:0 clamp(56px,7vw,96px)}
.closing-panel{position:relative;overflow:hidden;border-radius:var(--r-panel);
  border:1px solid transparent;padding:clamp(40px,6vw,76px) clamp(24px,4vw,56px);
  background:linear-gradient(180deg,var(--tile-top) 0%,transparent 42%,var(--tile-bot) 100%) padding-box,
             var(--panel) padding-box,var(--rim) border-box;
  -webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.14),var(--shadow-lg),
             0 40px 90px -24px var(--tile-cast),var(--halo)}
.closing-panel::after{content:"";position:absolute;z-index:0;pointer-events:none;
  left:50%;bottom:-40%;translate:-50% 0;width:120%;aspect-ratio:2.4/1;border-radius:50%;
  background:radial-gradient(closest-side,var(--tile-bloom),transparent 76%);
  filter:blur(32px);opacity:.8}
.closing-panel > *{position:relative;z-index:1}
.closing h2{max-width:17ch;margin-inline:auto}
.closing .lead{margin:18px auto 0}
.closing .cta-row{justify-content:center;margin-top:30px}
.closing .under{text-align:center}
.tag{display:inline-flex;align-items:center;font-family:var(--mono);font-size:.75rem;
  letter-spacing:.08em;text-transform:uppercase;
  border-radius:var(--r-pill);padding:6px 12px;color:var(--dimmer)}
.tag.is-concept{border-color:var(--accent);color:var(--accent)}
.work-media img{width:100%;aspect-ratio:16/10;object-fit:cover;object-position:top center;
  transition:transform 500ms var(--ease)}
.work-row:hover .work-media img{transform:scale(1.03)}

/* form — the conversion surface, built as a real form */
label{display:block;font-size:.75rem;font-weight:500;letter-spacing:.01em;
  color:var(--dim);margin-bottom:8px;text-transform:none;font-family:inherit}
input,select,textarea{width:100%;font:inherit;font-size:1rem;color:var(--ink);
  background:var(--fill-2);border:0;border-radius:var(--r-chip);
  box-shadow:inset 0 0 0 1px var(--field-edge),inset 0 1px 0 rgba(255,255,255,.10);
  padding:13px 14px;transition:box-shadow 200ms var(--ease)}
input:hover,select:hover,textarea:hover{
  box-shadow:inset 0 0 0 1px var(--field-edge-2),inset 0 1px 0 rgba(255,255,255,.12)}
input::placeholder,textarea::placeholder{color:var(--dimmer)}
select option{background:var(--panel-solid);color:var(--ink)}
textarea{resize:vertical;min-height:104px}
.field{margin-bottom:22px}
.grid2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 clamp(18px,2.6vw,32px)}
input:focus-visible,select:focus-visible,textarea:focus-visible{
  outline:2px solid var(--ink);outline-offset:2px;border-color:var(--ink)}

@media (max-width:1000px){
  .two,.grid2{grid-template-columns:1fr}
}

/* trade finder — puts the buyer's own industry in front of him at screen 1 */
/* Its own band between the reel and the bento: who this is for reads before
   what they get, and the pricing heading no longer has an unrelated wall
   wedged between it and its own cards. */
.trades-sec{padding-block:clamp(46px,6vw,88px) clamp(34px,4.4vw,62px)}
.trades{max-width:none;text-align:center}
.trades-lead{display:block;font-family:var(--mono);font-size:.75rem;letter-spacing:.12em;
  text-transform:uppercase;color:var(--dimmer);margin-bottom:14px}
/* an endless wall: three rows drifting, the middle one against the others */
.wall{display:grid;gap:8px}
.wall-row{overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 12%,#000 88%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 12%,#000 88%,transparent)}
/* margin, not gap: a flex gap puts an odd number of gaps in the track, so
   -50% lands half a gap short and the loop visibly jumps once per cycle.
   With a trailing margin on every pill the two halves are exactly equal. */
.wall-track{display:flex;width:max-content;
  animation:wallRun linear infinite;will-change:transform}
.wall-0{animation-duration:78s}
.wall-1{animation-duration:66s;animation-direction:reverse}
.wall-2{animation-duration:88s}
.wall-track span{flex:none;margin-right:8px;padding:8px 16px;border-radius:var(--r-pill);
  color:var(--dim);font-size:.875rem;line-height:1.2;white-space:nowrap}
/* two identical copies sit in the track, so -50% is exactly one copy along */
@keyframes wallRun{from{transform:translate3d(0,0,0)}to{transform:translate3d(-50%,0,0)}}
@media (prefers-reduced-motion:reduce){
  .wall-track{animation:none;flex-wrap:wrap;justify-content:center;width:auto;gap:8px}
  .wall-row{mask-image:none;-webkit-mask-image:none}
}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);
  clip-path:inset(50%);white-space:nowrap}
/* upkeep: a thing you decline, not a thing you're buying */
.upkeep{font-size:.8125rem;color:var(--dimmer);margin-top:16px;padding-top:14px;
  border-top:1px solid var(--edge);max-width:none}

/* ==========================================================================
   GLASS WINDOWS
   Images sit inside a pane of glass rather than behind an outline: a lit rim
   on all four edges, a sheen across the top, and the picture inset so the
   glass reads as a frame around it.
   ========================================================================== */
.work-media{
  position:relative;overflow:hidden;padding:6px;border-radius:20px;
  border:1px solid transparent;
  background:var(--glass) padding-box,var(--rim) border-box;
  -webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.16),var(--shadow),
             0 24px 56px -22px var(--tile-cast),var(--halo);
  transition:box-shadow 340ms var(--ease),transform 340ms var(--ease)}
.work-media img{
  display:block;border-radius:14px}
/* the sheen: light raking across the top of the pane */
.work-media::after{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;z-index:3;
  /* a thin rake of light across the top of the pane only — a wash over the
     bottom of the picture degrades the photograph, which is the product */
  background:linear-gradient(180deg,rgba(255,255,255,.20) 0%,rgba(255,255,255,.05) 9%,
    transparent 24%);
  opacity:.85}
.work-row:hover .work-media{
  box-shadow:inset 0 1px 0 rgba(255,255,255,.22),var(--shadow-lg),
             0 34px 72px -20px var(--tile-cast),0 0 46px -6px var(--glow)}
@media (max-width:560px){
  .work-media{padding:5px;border-radius:16px}
  .work-media img{border-radius:11px}
}

/* ==========================================================================
   DESIGN REEL — a spatial coverflow. The active card faces you; its
   neighbours rotate away into depth, scaled down and dimmed.
   ========================================================================== */
/* The hero and the reel are one section now. Two stacked headings — an h1
   and then "The look / Point at a direction" — ate the whole first screen and
   left nothing to look at, so the reel's heading was demoted to the hero's
   supporting line. The space that bought is spent on letting the top of the
   first card sit above the fold: something half-seen is what makes a person
   scroll, and a page that ends flush at the fold reads as the whole page.
   The vh units are deliberate — this has to hold on a laptop, not just at a
   design width. */
.hero-reel{padding-top:clamp(100px,15vh,158px)}
.hero-reel .hero{padding-block:0}
/* smaller than a standalone hero h1: it is sharing the screen with the reel
   now, and at the full size it wrapped to four lines and took the fold */
.hero-reel h1{margin-top:clamp(12px,1.8vh,20px);
  font-size:clamp(2.125rem,4.1vw,3.375rem);max-width:22ch}
.hero-sub{margin-top:clamp(12px,2vh,20px);text-align:center;
  font-size:clamp(1rem,1.35vw,1.1875rem);line-height:1.5;color:var(--dim);
  max-width:42ch;margin-inline:auto}
.hero-reel .reel{margin-top:clamp(26px,4.6vh,58px)}
.reel{position:relative;margin-top:clamp(20px,3vw,36px);
  /* the off-stage cards sit outside the viewport; without this they widen
     the page and the whole document scrolls sideways on a phone */
  overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 9%,#000 91%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 9%,#000 91%,transparent)}
.reel-stage{position:relative;height:clamp(330px,31vw,440px);padding-block:26px;
  perspective:1600px;perspective-origin:50% 45%;
  transform-style:preserve-3d;display:grid;place-items:center}

.rcard{position:absolute;width:clamp(280px,36vw,520px);
  border-radius:20px;overflow:hidden;border:1px solid transparent;
  background:var(--glass) padding-box,var(--rim) border-box;
  -webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.16),var(--shadow),
             0 30px 70px -24px var(--tile-cast),var(--halo);
  transform-origin:50% 50%;will-change:transform;
  transition:box-shadow 300ms var(--ease);
  padding:6px}
.rcard-img{border-radius:14px;overflow:hidden;position:relative}
.rcard-img img{display:block;width:100%;aspect-ratio:16/9;object-fit:cover}
.rcard-body{padding:14px 12px 12px}
.rcard-body h3{font-size:1.0625rem;font-weight:600;letter-spacing:-.01em}
.rcard-body p{margin-top:5px;font-size:.8125rem;line-height:1.45;color:var(--dim)}
/* only the card in front is a tab stop and readable to a screen reader */
.rcard[aria-hidden="true"]{pointer-events:none}
/* only the card in front shows its caption: the neighbours' captions overlap
   each other and, dimmed, would sit below the contrast floor anyway */
.rcard-body{transition:opacity 420ms var(--ease)}
.rcard[aria-hidden="true"] .rcard-body{opacity:0}

.reel-ctl{display:flex;align-items:center;justify-content:center;gap:14px;
  margin-top:clamp(18px,2.4vw,28px)}
.rnav{width:42px;height:42px;border-radius:50%;display:grid;place-items:center;
  color:var(--ink);border:1px solid transparent;
  background:linear-gradient(180deg,rgba(255,255,255,.11),rgba(255,255,255,.03)) padding-box,
             var(--rim-soft) border-box;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.18);
  transition:background 240ms var(--ease),box-shadow 240ms var(--ease),transform 200ms var(--ease)}
.rnav:hover{transform:translateY(-1px);box-shadow:inset 0 1px 0 rgba(255,255,255,.26),
  0 12px 28px -10px var(--glow)}
html[data-theme="light"] .rnav{
  background:linear-gradient(180deg,rgba(255,255,255,.95),rgba(255,255,255,.62)) padding-box,
             var(--rim-soft) border-box}
.rdots{display:flex;gap:7px}
.rdot{position:relative;width:7px;height:7px;border-radius:50%;
  background:var(--edge-2);
  transition:background 260ms var(--ease),transform 260ms var(--ease)}
/* the dot stays 7px; the finger gets 44 */
.rdot::after{content:"";position:absolute;inset:-18px}
.rdot[aria-current="true"]{background:var(--accent);transform:scale(1.5)}

/* above the carousel, not below it: a disclaimer a phone user never reaches
   is not a disclaimer */
.reel-note-top{margin-top:14px;margin-bottom:0;font-size:.8125rem;
  color:var(--dim);text-align:center;max-width:46ch;margin-inline:auto}
.reel-note{font-size:.8125rem;color:var(--dimmer);text-align:center;
  max-width:56ch;margin-inline:auto;margin-top:clamp(22px,3vw,34px)}
.reel-note a{color:var(--accent-text);text-decoration:underline;text-underline-offset:3px}

@media (max-width:700px){
  .reel-stage{height:clamp(300px,86vw,400px)}
  /* one card, near full width. The neighbours were rendering ~290px wide —
     a website screenshot at that size is texture, not a design direction. */
  .rcard{width:min(88vw,360px)}
  .rcard-body p{font-size:.78125rem}
  .reel{-webkit-mask-image:none;mask-image:none}
}
/* no depth illusion without motion — fall back to a plain scroller */
@media (prefers-reduced-motion:reduce){
  .reel-stage{position:static;height:auto;perspective:none;display:flex;
    gap:16px;overflow-x:auto;padding-bottom:8px;place-items:stretch}
  .rcard{position:static;transform:none!important;opacity:1!important;flex:0 0 300px}
  .reel-ctl{display:none}
}

/* ==========================================================================
   HERO -> REEL HANDOFF
   The headline falls away into depth while the reel stands up out of it —
   one continuous move in a shared space, scrubbed to scroll position rather
   than triggered at a threshold. Driven by a scroll timeline, so it runs on
   the compositor and cannot stutter against the main thread.
   ========================================================================== */
@keyframes heroRecede{
  from{transform:none;filter:blur(0);opacity:1}
  to{transform:translateY(-34px) scale(.93);filter:blur(6px);opacity:.12}
}
/* blur repaints a full-width element every frame — too costly on a phone,
   and the transform and fade alone carry the move */
@keyframes heroRecedeLite{
  from{transform:none;opacity:1}
  to{transform:translateY(-28px) scale(.94);opacity:.12}
}

@media (prefers-reduced-motion:no-preference){
  @supports (animation-timeline:view()){
    .hero-solo{
      animation:heroRecede linear both;
      animation-timeline:view();
      animation-range:exit -5% exit 85%}
    @media (max-width:820px){
      .hero-solo{animation-name:heroRecedeLite}
    }
    /* The stage used to rise and stand up as it entered from below, because
       it was a separate section being handed off to. It is part of the first
       screen now, so a scroll-driven entrance would leave it faded and tilted
       at rest — the one thing on the page inviting a scroll would arrive
       looking unfinished. It simply sits there. */
  }
  /* browsers without scroll timelines get the same move, driven from rAF */
  @supports not (animation-timeline:view()){
    .js-scrub .hero-solo{transform:translateY(calc(var(--p,0) * -34px)) scale(calc(1 - var(--p,0) * .07));
      opacity:calc(1 - var(--p,0) * .88)}
  }
}
/* nav hides on the way down, returns on the way up.
   Coming back it overshoots very slightly and settles; going away it just
   leaves — a bounce on the way out would draw the eye to the thing that is
   trying to get out of the way. */
.nav{transition:transform 560ms var(--spring-soft),opacity 240ms var(--ease)}
.nav.nav-off{transform:translateY(-150%);opacity:0;pointer-events:none;
  transition:transform 300ms cubic-bezier(.5,0,.75,0),opacity 220ms var(--ease)}
@media (prefers-reduced-motion:reduce){
  .nav,.nav.nav-off{transition:none}
}

/* ==========================================================================
   The bento arrives the way a home screen does when the lock screen lifts:
   the tiles start slightly zoomed IN and settle out to size, overshooting a
   touch on the way. Time-based and fired once on entry, not scrubbed to
   scroll — a bounce needs time to happen in, and scrubbing ties it to how
   fast the wheel is turning, which is what made it feel mechanical.
   Transform and opacity only: both composite, so this stays off the paint
   path entirely.
   ========================================================================== */
@keyframes unlockPop{
  from{opacity:0;transform:scale(1.085)}
  to  {opacity:1;transform:scale(1)}
}
html.js .bento-cell{opacity:0}
@media (prefers-reduced-motion:no-preference){
  html.js .bento-cell.lit{
    animation:unlockPop 620ms var(--spring) both;
    will-change:transform,opacity}
  /* dealt out in reading order rather than all at once */
  html.js .bento-cell.lit:nth-child(2){animation-delay:60ms}
  html.js .bento-cell.lit:nth-child(3){animation-delay:120ms}
  html.js .bento-cell.lit:nth-child(4){animation-delay:180ms}
  html.js .bento-cell.lit:nth-child(5){animation-delay:225ms}
  html.js .bento-cell.lit:nth-child(6){animation-delay:270ms}
}
@media (prefers-reduced-motion:reduce){
  html.js .bento-cell.lit{opacity:1}
}

/* ==========================================================================
   BENTO — one idea per tile, a picture that explains it, and a short label.
   Every visual is markup, so it stays sharp, follows the theme and weighs
   nothing.
   ========================================================================== */
/* Apple's grids are uneven on the inside and perfectly square on the outside.
   Four columns, every row filled edge to edge. Source order is the placement:
   any reshuffle has to keep each row summing to four.

   Six tiles, not nine. Nine equal arguments dilute the three that actually
   close a sale, and two of the nine (page speed, works on phones) were table
   stakes — naming them only plants the doubt that they might not be true. */
.bento{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  grid-auto-rows:minmax(clamp(150px,23vh,196px),auto);
  gap:clamp(9px,1vw,14px);max-width:1060px;margin-inline:auto}

/* Frosted glass, not a glowing panel. Neutral white tint over a heavy frost,
   a hairline rim, and a specular highlight along the top edge only — the way
   light actually catches the lip of a pane. No radial bloom inside, no
   coloured cast underneath: glass refracts, it does not emit. */
.bento-cell{position:relative;overflow:hidden;min-width:0;
  padding:clamp(16px,1.7vw,24px);
  border-radius:var(--r-panel);
  border:1px solid var(--glass-line);
  background:linear-gradient(180deg,var(--glass-a) 0%,var(--glass-b) 62%);
  -webkit-backdrop-filter:var(--glass-frost);backdrop-filter:var(--glass-frost);
  box-shadow:var(--glass-shadow);
  display:flex;flex-direction:column}
/* the specular lip — 1px, neutral, and only across the top third of the width
   where a real highlight would fall off */
.bento-cell::before{content:"";position:absolute;z-index:2;pointer-events:none;
  left:0;right:0;top:0;height:1px;
  background:linear-gradient(90deg,transparent,var(--glass-spec) 22%,
             var(--glass-spec) 58%,transparent)}
.bento-cell > *{position:relative;z-index:1}
.bento-cell h3{font-size:1rem;font-weight:600;letter-spacing:-.014em;
  margin-top:auto;padding-top:14px;line-height:1.32}
/* sentence case in the body face. The mono uppercase read as a developer
   tool; the person buying this runs a salon. */
.bento-cell .fine{font-size:.8125rem;letter-spacing:0;color:var(--dim);
  margin-top:5px;line-height:1.4}
.b-span2{grid-column:span 2}
.b-demo{grid-column:span 2;grid-row:span 2}

/* Translucent tiles show whatever is behind them, so the photographic ground
   was tinting each tile a different colour — the bottom row went warm from
   the sunset while the top row stayed navy. Same class, different colour,
   which reads as amateur faster than anything else on the page. A full-bleed
   scrim gives every tile the same thing to refract without flattening the
   section to a solid block. */
.bento-sec{position:relative;z-index:0}
.bento-sec::before{content:"";position:absolute;z-index:-1;pointer-events:none;
    /* starts in the gap below the trades band, not part-way up through the
     pills, where its top edge dimmed the last row */
  left:calc(50% - 50vw);width:100vw;top:calc(var(--sec) * -.34);bottom:calc(var(--sec) * -.5);
  /* faded at both ends so the scrim never shows an edge against the photograph */
  background:linear-gradient(180deg,transparent 0,var(--glass-ground) 7%,
             var(--glass-ground) 92%,transparent 100%)}

/* the visual fills the tile above the label */
.vis{flex:1;min-width:0;min-height:52px;display:flex;align-items:center;
  justify-content:center;position:relative}

/* --- 1. a real page, in a browser frame --- */
/* This was a drawn wireframe: a blue rectangle and some grey bars. It proved
   nothing. The same space showing a page we actually designed is the whole
   argument the tile is making, so it holds a screenshot instead. Labelled
   Concept, because Meher is one — swap to the Kareizma capture and the label
   becomes Client. */
.vis-browser{align-items:stretch;padding:0;width:100%;min-width:0;
  flex-direction:column;border-radius:12px;overflow:hidden;
  box-shadow:0 1px 0 var(--glass-spec) inset,
             0 18px 40px -18px rgba(0,0,0,.6);
  border:1px solid var(--glass-line)}
.vis-browser .bw-bar{display:flex;align-items:center;gap:5px;flex:none;
  padding:8px 11px;background:var(--fill-2)}
.bw-bar i{width:7px;height:7px;border-radius:50%;background:var(--edge-2)}
.bw-bar span{margin-left:9px;font-family:var(--mono);font-size:.6875rem;color:var(--dimmer)}
.bw-shot{flex:1;min-height:0;overflow:hidden;background:var(--panel-solid)}
/* top-anchored: the fold of the page is the part worth showing */
.bw-shot img{width:100%;height:100%;object-fit:cover;object-position:top center}
.bw-chip{position:absolute;right:11px;bottom:11px;padding:5px 11px;border-radius:100px;
  font-family:var(--mono);font-size:.6875rem;letter-spacing:.04em;
  background:var(--ok);color:#062018;font-weight:600}
.bw-tag{position:absolute;left:11px;bottom:11px;padding:5px 11px;border-radius:100px;
  font-size:.6875rem;font-weight:500;letter-spacing:.02em;color:var(--ink);
  background:rgba(10,16,32,.62);border:1px solid var(--glass-line);
  -webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px)}
html[data-theme="light"] .bw-tag{background:rgba(255,255,255,.72)}

/* --- 2. a Google result for the business --- */
.vis-serp{flex-direction:column;align-items:flex-start;justify-content:center;
  gap:6px;padding:2px}
.sr{display:flex;align-items:center;gap:8px}
.sr-fav{width:17px;height:17px;border-radius:50%;background:var(--edge-2);flex:none}
.sr-name{font-size:.75rem;color:var(--dim)}
.sr-title{font-size:1.0625rem;color:var(--accent-text);font-weight:500;line-height:1.2}
.sr-meta{font-size:.75rem;color:var(--dimmer)}
.sr-meta b{color:var(--star);letter-spacing:-1px}

/* --- 3. an enquiry arriving as a chat --- */
.vis-chat{flex-direction:column;align-items:stretch;justify-content:center;gap:8px}
.ch{max-width:min(72%,34ch);padding:9px 13px;font-size:.8125rem;line-height:1.4;
  border-radius:14px}
.ch-in{align-self:flex-start;background:var(--fill-2);border-bottom-left-radius:4px;color:var(--ink)}
.ch-out{align-self:flex-end;background:#1C7F53;color:#fff;border-bottom-right-radius:4px}
html[data-theme="light"] .ch-out{background:#16794E}

/* --- 4. what upkeep costs in a quiet month --- */
.vis-fee{flex-direction:column;gap:5px}
.fee-new{font-size:clamp(2rem,3.2vw,2.625rem);font-weight:600;letter-spacing:-.04em;
  color:var(--ink);line-height:1}

/* --- 7. the address bar, in your name --- */
/* this element is the .vis container itself, so it has to opt out of the
   flex:1 and min-height that make the other visuals fill their tile */
.vis-addr{flex:none;min-height:0;height:auto;width:auto;max-width:100%;
  align-self:center;margin:auto;
  gap:9px;padding:13px 20px;border-radius:100px;background:var(--fill-2);
  box-shadow:var(--ring)}
.vis-addr .lock{font-size:.75rem;opacity:.75}
.addr-url{font-family:var(--mono);font-size:.9375rem;color:var(--ink);letter-spacing:.01em}
.caret{width:1.5px;height:15px;background:var(--accent);animation:blink 1.1s steps(1) infinite}
@keyframes blink{50%{opacity:0}}

/* --- 7. four days, on a calendar --- */
/* Four lit dots carried no meaning on their own. Days numbered on a page,
   counting to a lit fourth, need no caption at all. */
.vis-cal{align-items:center;justify-content:center}
.cal{width:min(100%,148px);border-radius:10px;overflow:hidden;
  background:var(--panel-solid);box-shadow:var(--ring),0 14px 30px -18px rgba(0,0,0,.65)}
.cal-top{display:flex;align-items:center;justify-content:center;gap:24px;
  height:16px;background:var(--fill-2)}
.cal-top i{width:4px;height:4px;border-radius:50%;background:var(--edge-2)}
.cal-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:6px;padding:8px}
.cal-grid b{aspect-ratio:1;border-radius:5px;background:var(--edge);
  display:flex;align-items:center;justify-content:center;font-weight:500;
  font-family:var(--mono);font-size:.75rem;color:var(--dimmer)}
.cal-grid b.on{background:color-mix(in srgb,var(--accent) 24%,transparent);color:var(--ink)}
.cal-grid b.live{background:var(--accent);color:#fff;
  box-shadow:0 0 16px -3px var(--glow)}

/* --- the ask, as a bar under the grid --- */
/* A CTA squeezed into a grid cell had to fight the cell's proportions. Given
   its own full-width bar it can breathe, and it reads as the conclusion of
   the argument above rather than as one more feature. */
.bento-bar{display:flex;align-items:center;justify-content:space-between;
  gap:clamp(18px,3vw,40px);text-decoration:none;color:inherit;
  max-width:1060px;margin:clamp(10px,1vw,14px) auto 0;
  padding:clamp(20px,2.4vw,30px) clamp(20px,2.6vw,34px);
  border-radius:var(--r-panel);border:1px solid var(--glass-line);
  background:linear-gradient(180deg,var(--glass-a) 0%,var(--glass-b) 62%);
  -webkit-backdrop-filter:var(--glass-frost);backdrop-filter:var(--glass-frost);
  box-shadow:var(--glass-shadow);position:relative;overflow:hidden;
  transition:transform .35s var(--ease)}
.bento-bar::before{content:"";position:absolute;left:0;right:0;top:0;height:1px;
  background:linear-gradient(90deg,transparent,var(--glass-spec) 22%,
             var(--glass-spec) 58%,transparent)}
.bb-said{min-width:0}
.bb-said strong{display:block;font-size:clamp(1.0625rem,1.5vw,1.3125rem);
  font-weight:600;letter-spacing:-.02em}
.bb-said span{display:block;margin-top:5px;font-size:.9375rem;color:var(--dim);
  max-width:52ch;line-height:1.45}
.bento-bar .btn{flex:none}
.bento-bar:hover{transform:translateY(-2px)}
.bento-bar:hover .btn{transform:translateY(-2px)}

@media (max-width:1000px){
  .bento{grid-template-columns:repeat(2,minmax(0,1fr))}
  .b-span2{grid-column:span 2}
  /* two columns leaves no room beside a double-height tile */
  .b-demo{grid-column:span 2;grid-row:span 1}
}
@media (max-width:560px){
  /* Still the bento — tiles, not a stack — but two columns rather than four.
     Four columns scaled to fit 390px put body text at about 6.7px, which is
     not small, it is unreadable. Two columns hold the grid's character at a
     zoom the type survives. The wide tiles stay wide so the rhythm is still
     uneven the way the desktop grid is. */
  .bento{zoom:.78;grid-template-columns:repeat(2,minmax(0,1fr))}
  .b-span2,.b-demo{grid-column:span 2;grid-row:auto}
}

/* ==========================================================================
   COMPARISON — three columns, ours lit. Was a table, which read as a
   spreadsheet on a page arguing that we design things.
   ========================================================================== */
.cmp-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(10px,1.2vw,16px);align-items:start;max-width:1060px;margin-inline:auto}
/* Same frosted material as the bento and the steps. These columns were the
   last thing on the site still wearing the old glowing treatment — a blue
   bloom under each one and a coloured rim — which on a product page put the
   loudest object next to the price. */
.cmp-col{position:relative;overflow:hidden;border-radius:var(--r-panel);
  border:1px solid var(--glass-line);padding:clamp(18px,2vw,26px);
  background:linear-gradient(180deg,var(--glass-a) 0%,var(--glass-b) 62%);
  -webkit-backdrop-filter:var(--glass-frost);backdrop-filter:var(--glass-frost);
  box-shadow:var(--glass-shadow)}
.cmp-col::before{content:"";position:absolute;z-index:2;pointer-events:none;
  left:0;right:0;top:0;height:1px;
  background:linear-gradient(90deg,transparent,var(--glass-spec) 22%,
             var(--glass-spec) 58%,transparent)}
/* the option we are selling sits forward and takes a trace of the accent —
   enough to be the one you read first, not enough to glow */
.cmp-col.is-us{transform:translateY(-10px);
  border-color:color-mix(in srgb,var(--accent) 34%,var(--glass-line));
  background:linear-gradient(180deg,
    color-mix(in srgb,var(--accent) 13%,var(--glass-a)) 0%,var(--glass-b) 66%)}
.cmp-col > *{position:relative;z-index:1}

.cmp-head{padding-bottom:14px;margin-bottom:6px;
  border-bottom:1px solid var(--glass-line)}
.cmp-head h3{font-size:1.0625rem;font-weight:600;letter-spacing:-.015em}
.cmp-head p{font-size:.8125rem;color:var(--dimmer);margin-top:3px}
.cmp-badge{display:inline-block;margin-top:10px;padding:4px 10px;border-radius:100px;
  font-family:var(--mono);font-size:.625rem;letter-spacing:.09em;text-transform:uppercase;
  background:var(--btn);color:#fff}

.cmp-rows{list-style:none;display:grid}
.cmp-rows li{display:grid;gap:3px;padding:11px 0;border-bottom:1px solid var(--glass-line)}
.cmp-rows li:last-child{border-bottom:0;padding-bottom:0}
.ck{font-family:var(--mono);font-size:.625rem;letter-spacing:.09em;
  text-transform:uppercase;color:var(--dimmer)}
.cv{font-size:.875rem;line-height:1.4;color:var(--dim)}
.is-us .cv{color:var(--ink)}
.cmp-note{font-size:.8125rem;color:var(--dimmer);text-align:center;
  max-width:60ch;margin:clamp(22px,3vw,32px) auto 0}

@media (max-width:900px){
  .cmp-grid{grid-template-columns:1fr;max-width:520px}
  .cmp-col.is-us{transform:none;order:-1}
}

/* ==========================================================================
   THE WAY WE WORK — four steps, each carrying its own illustration.
   Same glass as the bento so the two sections read as one material, and the
   arrival is the only place on the page allowed to be showy: a rail that
   draws itself as you reach the section, then the cards landing one after
   another, each with a single specular sweep across the pane. Transform and
   opacity only — both composite, so none of this touches paint.
   ========================================================================== */
.rail{position:relative;max-width:1060px;margin:0 auto clamp(20px,2.4vw,32px);
  height:1px;background:var(--glass-line)}
.rail i{position:absolute;left:0;top:-1px;height:3px;width:100%;border-radius:2px;
  transform-origin:left center;transform:scaleX(0);
  background:linear-gradient(90deg,transparent,var(--accent) 22%,var(--accent));
  box-shadow:0 0 14px -2px var(--glow)}
html.js .rail.lit i{animation:railDraw 1400ms var(--ease) 120ms both}
@keyframes railDraw{to{transform:scaleX(1)}}

.steps4{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:clamp(10px,1.2vw,16px);max-width:1060px;margin-inline:auto;list-style:none}
.step{position:relative;overflow:hidden;min-width:0;
  border-radius:var(--r-panel);border:1px solid var(--glass-line);
  background:linear-gradient(180deg,var(--glass-a) 0%,var(--glass-b) 62%);
  -webkit-backdrop-filter:var(--glass-frost);backdrop-filter:var(--glass-frost);
  box-shadow:var(--glass-shadow);
  padding:clamp(13px,1.4vw,17px);display:flex;flex-direction:column;
  transition:transform .4s var(--ease),box-shadow .4s var(--ease)}
/* the specular lip, same as the bento tiles */
.step::before{content:"";position:absolute;z-index:3;pointer-events:none;
  left:0;right:0;top:0;height:1px;
  background:linear-gradient(90deg,transparent,var(--glass-spec) 22%,
             var(--glass-spec) 58%,transparent)}
/* and a single band of light crossing the pane, once, on arrival */
.step::after{content:"";position:absolute;z-index:2;pointer-events:none;
  top:-60%;bottom:-60%;width:42%;left:-60%;
  background:linear-gradient(100deg,transparent,var(--glass-spec),transparent);
  opacity:0;transform:skewX(-18deg)}
html.js .step.lit::after{animation:paneSweep 900ms var(--ease) both}
@keyframes paneSweep{
  0%{opacity:0;left:-60%}
  22%{opacity:.5}
  100%{opacity:0;left:118%}
}

.step-art{display:block;position:relative;overflow:hidden;border-radius:14px;
  border:1px solid var(--glass-line);background:rgba(255,255,255,.05)}
.step-art img{display:block;width:100%;height:auto;aspect-ratio:522/348;
  object-fit:cover;transition:transform .6s var(--ease)}
.step:hover .step-art img{transform:scale(1.045)}
.step-n{display:block;margin-top:15px;font-family:var(--mono);font-size:.6875rem;
  letter-spacing:.14em;color:var(--accent-text)}
.step h3{margin-top:6px;font-size:1rem;font-weight:600;letter-spacing:-.014em;
  line-height:1.3}
.step p{margin-top:7px;font-size:.8125rem;line-height:1.5;color:var(--dim)}
.step:hover{transform:translateY(-4px)}
.how-cta{justify-content:center;margin-top:clamp(26px,3vw,40px)}

/* the cards land one after another, each settling out of a slight zoom the
   way the bento tiles do — same gesture, so the page has one arrival, not two */
html.js .steps4 .step{opacity:0}
@media (prefers-reduced-motion:no-preference){
  html.js .step.lit{animation:unlockPop 620ms var(--spring-soft) both}
  html.js .step.lit:nth-child(2){animation-delay:90ms}
  html.js .step.lit:nth-child(3){animation-delay:180ms}
  html.js .step.lit:nth-child(4){animation-delay:270ms}
  html.js .step.lit:nth-child(2)::after{animation-delay:90ms}
  html.js .step.lit:nth-child(3)::after{animation-delay:180ms}
  html.js .step.lit:nth-child(4)::after{animation-delay:270ms}
}
@media (prefers-reduced-motion:reduce){
  html.js .step.lit{opacity:1}
  html.js .step.lit::after,html.js .rail.lit i{animation:none}
  .rail i{transform:scaleX(1)}
}

@media (max-width:960px){
  .steps4{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:560px){
  /* same desktop grid, scaled as one piece — see .bento above */
  .steps4{zoom:.55;grid-template-columns:repeat(4,minmax(0,1fr))}
  .rail{display:none}
}

/* 2 · the lid ----------------------------------------------------------- */
/* Apple's pin geometry, measured off their iPhone page: an outer track taller
   than the viewport wrapping a sticky child exactly one viewport tall. Their
   videos play once on entry; ours scrubs, because the lid has to answer where
   the reader is rather than how long they have been there.

   The track is taller than it was because the scroll now does two jobs in
   sequence — the lid opens over the first third, then the client's site tours
   inside the screen over the remaining two. data-open-end in the markup is the
   split, and app.js reads it from there rather than duplicating the number. */
.lid-sec{position:relative}
.lid-track{height:420svh}

/* The stage is sized by the canvas; the screen overlay is positioned against
   it in canvas pixels and scaled down by the same factor the canvas is. */
.lid-stage{position:relative;width:min(100%,980px);line-height:0}
.lid-canvas{display:block;width:100%;height:auto}

/* The real page, laid over the rendered screen on the quad exported by
   render_lid.py. Sized in CANVAS pixels — app.js applies the matrix3d that maps
   this box onto the quad and scales it to the canvas's displayed size, so the
   numbers here must match data-screen-w / data-screen-h. */
.lid-screen{position:absolute;top:0;left:0;overflow:hidden;
  transform-origin:0 0;will-change:transform;opacity:0;
  backface-visibility:hidden}
.lid-page{display:block;width:100%;height:auto;will-change:transform}

.lid-say{text-align:center;max-width:46ch}
.lid-say h2{font-size:clamp(1.5rem,2.6vw,2.25rem)}
.lid-say p{margin-top:10px;color:var(--dim);font-size:.9375rem}
.beat{display:grid;grid-template-columns:auto 1fr;gap:clamp(16px,2.4vw,34px);
  align-items:start;padding-top:clamp(20px,2.6vw,30px);border-top:1px solid var(--edge)}
.beat h3{font-size:clamp(1.25rem,2.2vw,1.75rem);letter-spacing:-.02em}
.beat p{margin-top:10px;color:var(--dim);max-width:58ch}
@media (max-width:700px){
  .lid-track{height:340svh}
  .lid-stage{width:100%}
  .beat{grid-template-columns:1fr;gap:8px}
}

/* A scrub has nothing to show if it cannot scrub, so reduced motion gets the
   END of the story as a still — the lid open and the site on the screen — not
   the beginning. A closed laptop showing nothing is the one state that tells
   the reader less than a plain screenshot would. */
@media (prefers-reduced-motion:reduce){
  .lid-track{height:auto}
  .lid-say [data-at]{opacity:0}
  .lid-say [data-at]:last-child{opacity:1}
}

/* ---------- breadcrumb ---------- */
.crumbs{display:flex;align-items:center;gap:9px;padding-top:clamp(96px,10vh,124px);
  padding-bottom:14px;font-size:.8125rem;color:var(--dimmer)}
.crumbs a{display:inline-block;color:var(--dimmer);transition:color 150ms var(--ease);
  padding:10px 2px;margin:-10px -2px}
.crumbs a:hover{color:var(--ink)}
.crumbs svg{opacity:.5;flex:none}
.crumbs [aria-current]{color:var(--ink)}

/* the fullscreen view: full-bleed, on top of everything, frosted ground so
   the photo is unmistakably the whole point of being here */
.pdp-lightbox{position:fixed;inset:0;z-index:200;display:grid;place-items:center;
  padding:clamp(20px,5vw,64px);background:rgba(6,10,20,.92);overflow:hidden;
  -webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);
  opacity:0;pointer-events:none;transition:opacity 220ms var(--ease)}
.pdp-lightbox.on{opacity:1;pointer-events:auto}
/* touch-action:none hands every pointer/touch gesture on the photo to our
   own pinch-and-drag wiring instead of the browser's native scroll/zoom */
/* max-height:100% here would resolve against an indefinite basis — a grid
   item centered rather than stretched (place-items:center) sizes to its own
   content, so the percentage computes to none and the image ignores it
   entirely. vh sidesteps that: it is never a percentage of the item itself. */
.pdp-lightbox img{max-width:100%;
  max-height:calc(100vh - clamp(40px,10vw,128px));border-radius:12px;
  box-shadow:0 40px 100px -30px rgba(0,0,0,.7);touch-action:none;
  cursor:zoom-in;-webkit-user-drag:none;user-select:none}
.pdp-lightbox-close{position:absolute;top:clamp(14px,3vw,28px);
  right:clamp(14px,3vw,28px);width:44px;height:44px;border-radius:50%;
  display:grid;place-items:center;font-size:1.5rem;line-height:1;color:#fff;
  background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.16);
  -webkit-tap-highlight-color:transparent;touch-action:manipulation;
  cursor:pointer;transition:background 200ms var(--ease),transform 120ms var(--ease)}
.pdp-lightbox-close:active{transform:scale(.92)}
@media (hover:hover) and (pointer:fine){
  .pdp-lightbox-close:hover{background:rgba(255,255,255,.16)}
}


/* ==========================================================================
   TOUCH, PRESS, AND THE THINGS A STILL CANNOT SHOW
   ========================================================================== */

/* A tap on a touchscreen fires a hover, and it STAYS fired until you tap
   something else — so every hover-lift on this site left the tapped card
   floating. Hover effects belong to devices that actually have a pointer. */
@media (hover:none),(pointer:coarse){
  .panel.lift:hover,.btn:hover,.rnav:hover,.bento-bar:hover,.bento-bar:hover .btn,
  .step:hover{transform:none}.work-row:hover .work-media img,
  .step:hover .step-art img{transform:none}
  .tier:hover .arrow{transform:none}
}.rnav,.bento-bar{-webkit-tap-highlight-color:transparent}
.crumbs a:active{opacity:.7}

/* ---------- the FAQ opens instead of teleporting ---------- */
/* grid-template-rows 0fr -> 1fr animates to the content's own height with no
   measured pixel value anywhere, so it survives any answer length. */
.faq details{border-bottom:1px solid var(--edge)}
.faq summary{cursor:pointer;list-style:none}
.faq summary::-webkit-details-marker{display:none}
/* A closed <details> renders its children display:none, so CSS has nothing to
   transition and JS has nothing to measure. app.js therefore pins `open` on
   permanently — content always laid out — and moves the visual state to
   .is-open, which CSS can animate. Without JS it stays a native <details> and
   still collapses, which is why the markup is <details> and these rules are
   gated on [data-js].

   The height comes from --faq-h, measured once per answer by app.js. The
   grid-template-rows 0fr->1fr trick would avoid measuring, and it is what this
   should have been, but inside a <details> the 1fr row resolves to 0px in
   Chrome no matter what min-height the item carries — tested directly.

   Height is a layout property, which this codebase otherwise avoids animating.
   That rule is about continuous and frequently-hit motion; a 280ms accordion on
   a deliberate click is the accepted trade, and it is a transition, so a second
   click retargets it from wherever it currently is. */
.faq-a a{color:var(--ink);text-decoration:underline;text-decoration-color:var(--edge);
  text-underline-offset:3px}
.faq details[data-js] .faq-a{overflow:hidden;height:0;opacity:0;
  transition:height 280ms var(--ease),opacity 190ms var(--ease)}
.faq details[data-js].is-open .faq-a{height:var(--faq-h,auto);opacity:1}
@media (prefers-reduced-motion:reduce){
  .faq details[data-js] .faq-a{transition:opacity 190ms var(--ease)}
}

/* ---------- the lid captions retarget instead of restarting ---------- */
/* They were @keyframes. Keyframes restart from zero every time they retrigger,
   so scrubbing back over a caption boundary stuttered. Both captions now sit
   stacked in the same grid cell and cross-fade with a transition, which
   retargets from wherever it currently is. */
.lid-say{display:grid}
.lid-say [data-at]{grid-area:1/1;display:block;opacity:0;transform:translateY(8px);
  transition:opacity 260ms var(--ease),transform 260ms var(--ease);
  pointer-events:none}
.lid-say [data-at].on{opacity:1;transform:none;pointer-events:auto}
@media (prefers-reduced-motion:reduce){
  .lid-say [data-at]{transform:none;transition:opacity 200ms var(--ease)}
}

/* ---------- theme change ---------- */
/* Every colour on the page eases at once, so dark<->light reads as one move
   rather than the ground changing and the type catching up a frame later.
   Scoped to .theme-x, which app.js adds only for the length of the change —
   a permanent transition here would put a 300ms lag on every hover on the
   site. img/video are excluded: they have nothing to interpolate and would
   only cost compositing. */
html.theme-x,
html.theme-x *:not(img):not(video):not(svg):not(path){
  transition:background-color 300ms var(--ease),
             border-color 300ms var(--ease),
             color 300ms var(--ease),
             fill 300ms var(--ease),
             box-shadow 300ms var(--ease) !important;
}

/* the icon turns over as the palette swaps, so the button reads as the thing
   that did it */
/* a keyframe, not a transition: the icon is swapped out (sun <-> moon) in the
   same frame the class lands, so a transition has no stable start value to
   move from and simply never runs. An animation always plays. */
@keyframes ss-flip{from{transform:rotate(-90deg);opacity:0}
                   to  {transform:rotate(0);opacity:1}}
.tbtn.spin svg{animation:ss-flip 420ms var(--spring) both}
.tbtn:active{transform:scale(.9);transition:transform 120ms var(--ease)}

@media (prefers-reduced-motion:reduce){
  html.theme-x,
  html.theme-x *:not(img):not(video):not(svg):not(path){
    transition-duration:160ms !important}
  .tbtn.spin svg{animation:none}
}

/* ==========================================================================
   THE STARTER PAGE
   A product page. Scoped under .st so Signature and Booking are untouched.

   Three rules, in priority order:
   1. The website preview is the largest thing in any section that has one.
      Diagrams, icons and lists are supporting evidence and are sized under it.
   2. Nothing is drawn on top of a screenshot. The warm cream-and-gold of the
      website against this dark ground IS the contrast; a tint or a gradient
      over it would flatten the one thing doing the work.
   3. Purple points at what to click. It is not the surface of every section —
      no glowing cards, no lit panels, no halos except on the primary button.
   ========================================================================== */
.st{--st-gap:clamp(44px,5.8vw,96px)}         /* the whole page rhythm */
.st .st-sec{padding-block:var(--st-gap)}
.st .st-sec + .st-sec{padding-top:0}
/* the one doubled boundary on the page: the hero already ends with its own
   breathing room, so the section after it must not add a second helping */
.st .st-hero + .st-sec{padding-top:0}

.st-head{max-width:52ch;margin:0 auto clamp(20px,2.4vw,34px);text-align:center}
.st-head-left{margin-inline:0;text-align:left}
/* sizing was a near-duplicate of the global h2 rule with a 3.2→3.3vw typo —
   dropped so every h2 on the site, hero included, resolves to one value */
.st-head h2{margin-top:12px}
.st-head p{margin-top:14px;color:var(--dim);font-size:1.0625rem;line-height:1.6}
.st-head-left p{max-width:42ch}

/* ---------- the browser frame ------------------------------------------- */
/* Punctuation, not furniture: a hairline, a 28px bar, three dots, the domain.
   The screenshot carries no chrome of its own so this is never drawn twice. */
.st-frame{position:relative;border-radius:11px;overflow:hidden;
  border:1px solid var(--edge);background:var(--panel-solid);
  box-shadow:0 1px 2px rgba(0,0,0,.28),0 20px 44px -26px rgba(0,0,0,.7)}
html[data-theme="light"] .st-frame{
  box-shadow:0 1px 2px rgba(22,30,60,.07),0 20px 44px -26px rgba(22,30,60,.26)}
.st-bar{display:flex;align-items:center;gap:5px;height:28px;padding:0 12px;
  background:var(--panel-solid);border-bottom:1px solid var(--edge)}
.st-bar i{width:7px;height:7px;border-radius:50%;background:var(--edge-2);flex:none}
/* flex:1 + centered text, not margin-inline:auto — auto-margin centering
   only balances when the domain is the LAST thing in the bar, and breaks
   the moment a zoom button follows it */
.st-bar em{flex:1;font-style:normal;font-family:var(--mono);font-size:.5625rem;
  letter-spacing:.06em;color:var(--faint);text-align:center;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.st-frame img{display:block;width:100%;height:auto}
.st-frame-sm .st-bar{height:22px}
@media (pointer:coarse){
  .st-hero-stage .st-bar{height:44px}
  .st-hero-zoom::before{inset:-14px}
}

/* the hero stage: three real pages cross-fading in one frame, driven by the
   "three pages" cards below acting as thumbnails — the frame chrome (bar,
   dots, domain) is identical on every slide, so the swap reads as the page
   changing, not the whole picture */
.st-hero-stage{position:relative}
.st-hero-stage .st-frame.st-hero-slide{position:absolute;inset:0;opacity:0;
  pointer-events:none;transition:opacity 320ms var(--ease)}
.st-hero-stage .st-frame.st-hero-slide.on{opacity:1;pointer-events:auto;
  position:relative}
/* 28px accounts for the chrome bar sitting above the image inside the
   frame — matches .st-bar's fixed height, not the sm variant's 22px, since
   every hero slide uses st-frame-lg */
.st-hero-stage .st-frame.st-hero-slide img{width:100%;
  height:calc(100% - 28px);object-fit:cover}
/* Lives in the chrome bar rather than floating over the screenshot. These
   previews are full pages with real content flush to every edge — a corner
   overlay circle had nowhere clean to sit and landed on top of a product
   photo once the frame was cropped down to phone width. A 44px touch target
   here would swallow the whole 28px bar, so the target grows with padding
   (::before) instead of the visible glyph, same trick as the nav's icon
   buttons use to stay tappable without looking oversized. */
.st-hero-zoom{position:relative;flex:none;width:16px;height:16px;
  display:grid;place-items:center;color:var(--faint);
  -webkit-tap-highlight-color:transparent;touch-action:manipulation;
  cursor:zoom-in;transition:color 160ms var(--ease)}
/* the glyph stays small so it sits in the chrome bar, but the target does
   not — 44px is the floor for a finger */
.st-hero-zoom::before{content:"";position:absolute;inset:-14px}
.st-hero-zoom:active{color:var(--ink)}
@media (hover:hover) and (pointer:fine){
  .st-hero-zoom:hover{color:var(--ink)}
}

/* the big preview settles rather than slides — the one entrance the bible
   allows, and it suits a photograph arriving */
.st-hero-shot.rv{opacity:0;transform:scale(1.022)}
.st-hero-shot.rv.in{opacity:1;transform:none}
.st-hero-shot.rv{
  transition:opacity 640ms cubic-bezier(.16,1,.3,1),
             transform 760ms cubic-bezier(.16,1,.3,1)}

/* ---------- 01 · hero ---------------------------------------------------- */
/* 38/62 — the preview takes the larger share on purpose. */
.st-hero{display:grid;grid-template-columns:minmax(0,.78fr) minmax(0,1.22fr);
  gap:clamp(26px,3.6vw,58px);align-items:center;
  padding-top:clamp(10px,1.6vw,22px);padding-bottom:clamp(34px,4.6vw,72px)}
.st-hero h1{font-size:clamp(2rem,4.1vw,3.25rem);line-height:1.05;
  letter-spacing:-.034em;margin-top:14px}
.st-hero h1 em{font-style:normal;color:var(--accent-text)}
.st-hero .lead{margin-top:16px;max-width:38ch;font-size:1.0625rem}
.st-buy{display:flex;align-items:center;gap:clamp(18px,2.4vw,30px);flex-wrap:wrap;
  margin-top:clamp(22px,2.8vw,32px)}
.st-price-mini b{display:block;margin-top:5px;font-size:clamp(1.5rem,2.3vw,1.875rem);
  font-weight:600;letter-spacing:-.03em;line-height:1}
.st-hero .st-link{margin-top:18px}

.st-link{display:inline-flex;align-items:center;gap:8px;font-size:.9375rem;
  min-height:44px;color:var(--ink);border-bottom:1px solid var(--edge-2);
  padding-bottom:3px;
  transition:border-color 160ms var(--ease)}
.st-link svg{transition:transform 200ms var(--ease)}
@media (hover:hover) and (pointer:fine){
  .st-link:hover{border-color:var(--accent-text)}
  .st-link:hover svg{transform:translateX(3px)}
}
.st-cta{display:flex;align-items:center;gap:clamp(16px,2.2vw,28px);flex-wrap:wrap}

/* the tag under the hero frame: says whether the preview is a concept or a
   real client site, and links to the thing itself. The browser chrome shows a
   domain, which invites people to type it — this tells them what they'd find. */
.st-frame-tag{display:inline-flex;align-items:center;gap:7px;margin-top:12px;
  font-family:var(--mono);font-size:.6875rem;letter-spacing:.06em;
  text-transform:uppercase;color:var(--dimmer);min-height:44px;
  transition:color 160ms var(--ease)}
.st-frame-tag svg{transition:transform 200ms var(--ease)}
.st-frame-tag-static{cursor:default}
@media (hover:hover) and (pointer:fine){
  .st-frame-tag:not(.st-frame-tag-static):hover{color:var(--accent-text)}
  .st-frame-tag:not(.st-frame-tag-static):hover svg{transform:translateX(3px)}
}

/* the step-up band: the one place a tier page names the tier above it */
.st-step{display:flex;align-items:center;justify-content:space-between;
  gap:clamp(16px,2.4vw,32px);flex-wrap:wrap;
  padding:clamp(20px,2.4vw,30px) clamp(20px,2.6vw,34px);
  border-radius:var(--r-panel);border:1px solid var(--edge);
  background:var(--fill)}
.st-step p{color:var(--dim);font-size:.9375rem;line-height:1.6;max-width:62ch}
.st-step .st-link{flex:none}

/* ---------- 02 · the three pages ----------------------------------------- */
/* A fixed three across on every tier, whatever the card count. auto-fit sized
   the cards to how many there happened to be, so Booking's four came out as a
   2x2 of 560px cards while Starter's three were 3-across — the same component
   at two different sizes on sibling pages. A ragged last row is normal; cards
   that change size between pages are not. */
.st-pages{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(16px,2.2vw,30px)}
.st-page-cap{margin-top:16px;display:grid;grid-template-columns:auto 1fr;
  gap:2px 12px;align-items:baseline}
.st-num{grid-row:1/3;font-family:var(--mono);font-size:.75rem;color:var(--accent-text)}
.st-page-cap h3{font-size:1.0625rem;letter-spacing:-.012em}
.st-page-cap p{color:var(--dimmer);font-size:.9375rem;line-height:1.5}
/* each card is also a thumbnail for the hero stage — a visible focus/active
   state is the only way that is discoverable before the first click */
.st-page{cursor:pointer;border-radius:var(--r-card);
  -webkit-tap-highlight-color:transparent;touch-action:manipulation;
  transition:transform 160ms var(--ease)}
.st-page .st-frame{transition:border-color 200ms var(--ease),
  box-shadow 200ms var(--ease)}
.st-page.on .st-frame{border-color:color-mix(in srgb,var(--accent) 55%,transparent);
  box-shadow:0 1px 2px rgba(0,0,0,.28),0 20px 44px -26px rgba(0,0,0,.7),
             0 0 0 3px color-mix(in srgb,var(--accent) 30%,transparent)}
.st-page:focus-visible{outline:none}
.st-page:focus-visible .st-frame{border-color:var(--accent-text)}
.st-page:active{transform:scale(.98)}
@media (hover:hover) and (pointer:fine){
  .st-page:hover{transform:translateY(-3px)}
}

/* ---------- 02b · the booking flow (Booking tier only) ------------------- */
/* Three beats, left to right, because that is the order it happens in. The
   third is wider than the other two on purpose: a booking landing in three
   places at once is the whole argument for the tier, so it gets the room. */
.bk-flow{list-style:none;display:grid;
  grid-template-columns:minmax(0,.8fr) minmax(0,.8fr) minmax(0,1.25fr);
  gap:clamp(14px,2vw,26px);align-items:start;counter-reset:bk}
.bk-step{display:flex;flex-direction:column;gap:14px;position:relative}
/* the connector: a hairline into the next beat, never drawn after the last */
.bk-step:not(:last-child)::after{content:"";position:absolute;z-index:1;
  top:64px;right:calc(clamp(14px,2vw,26px) / -2 - 3px);width:6px;height:6px;
  border-top:1px solid var(--edge-2);border-right:1px solid var(--edge-2);
  rotate:45deg}
.bk-num{font-family:var(--mono);font-size:.75rem;color:var(--accent-text)}
.bk-step > p{color:var(--dimmer);font-size:.9375rem;line-height:1.55}

.bk-card{border-radius:var(--r-card);padding:14px;
  background:var(--panel-solid);border:1px solid var(--edge-2);
  box-shadow:0 16px 34px -18px rgba(0,0,0,.66)}
html[data-theme="light"] .bk-card{box-shadow:0 16px 34px -18px rgba(16,38,74,.26)}
.bk-card-top{display:flex;align-items:center;gap:9px;margin-bottom:12px}
.bk-card-top b{font-size:.8125rem;font-weight:600}
.bk-ic{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;
  flex:none;color:var(--accent-text);
  background:color-mix(in srgb,var(--accent) 16%,transparent)}

/* a month, abstracted — squares, never a believable real calendar */
.bk-cal{display:grid;grid-template-columns:repeat(7,1fr);gap:4px}
.bk-cal i{aspect-ratio:1;border-radius:3px;background:var(--fill-2)}
.bk-cal i.on{background:var(--accent);box-shadow:0 0 0 3px
  color-mix(in srgb,var(--accent) 26%,transparent)}
.bk-slots{display:flex;gap:6px;margin-top:12px}
.bk-slots span{flex:1;text-align:center;padding:6px 0;border-radius:7px;
  font-size:.6875rem;color:var(--dim);background:var(--fill);
  border:1px solid var(--edge)}
.bk-slots span.on{color:#fff;background:var(--accent);border-color:transparent}

.bk-card-ok{display:grid;justify-items:center;text-align:center;gap:5px;
  padding-block:24px;
  border-color:color-mix(in srgb,var(--ok) 42%,transparent)}
.bk-ok{width:34px;height:34px;border-radius:50%;display:grid;place-items:center;
  color:var(--ok);background:color-mix(in srgb,var(--ok) 16%,transparent);
  margin-bottom:4px}
.bk-ok svg{width:15px;height:12px}
.bk-card-ok b{font-size:.9375rem}
.bk-card-ok em{font-style:normal;font-size:.8125rem;color:var(--dim)}

.bk-outs{display:grid;gap:8px}
.bk-out{display:grid;grid-template-columns:auto 1fr;gap:2px 11px;
  align-items:center;padding:12px 13px;border-radius:var(--r-card);
  background:var(--fill);border:1px solid var(--edge)}
.bk-out .bk-ic{grid-row:1/3}
.bk-out b{font-size:.875rem;font-weight:600;letter-spacing:-.01em}
.bk-out i{font-style:normal;font-size:.8125rem;color:var(--dimmer);
  line-height:1.45}

@media (max-width:900px){
  .bk-flow{grid-template-columns:minmax(0,1fr);gap:22px}
  .bk-step:not(:last-child)::after{top:auto;right:auto;left:16px;
    bottom:-15px;rotate:135deg}
}

/* ---------- 03 · the flow: supporting, so it is small -------------------- */
.st-trust{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,.58fr);
  gap:clamp(28px,4.5vw,72px);align-items:center}
/* capped rather than width:100% — at wide columns the diagram was floating
   in space it did not need, reading as a gap instead of a companion piece */
.st-flow{display:grid;justify-items:center;gap:8px;width:100%;max-width:320px;
  margin-inline:auto}
.st-flow-row{display:flex;gap:8px;flex-wrap:wrap;justify-content:center}
.st-node{display:inline-flex;align-items:center;gap:9px;padding:11px 15px;
  border-radius:var(--r-chip);border:1px solid var(--edge);
  font-size:.875rem;color:var(--dim);background:var(--fill)}
.st-node svg{color:var(--faint);flex:none}
/* The whole point of this diagram is one node. It spans the full width of the
   flow, carries the only accent border on the page outside the button, and its
   icon sits in a tinted square — so the eye lands on it first and the three
   sources above read as feeding into it. No gradient, no glow. */
.st-node-key{display:grid;grid-template-columns:auto 1fr;gap:2px 14px;
  justify-self:stretch;align-items:center;padding:18px 20px;
  border-color:color-mix(in srgb,var(--accent) 52%,transparent);
  background:color-mix(in srgb,var(--accent) 10%,transparent)}
.st-node-key svg{grid-row:1/3;width:34px;height:34px;padding:8px;border-radius:9px;
  color:var(--accent-text);background:color-mix(in srgb,var(--accent) 20%,transparent)}
.st-node-key b{font-size:1.0625rem;color:var(--ink);letter-spacing:-.012em}
.st-node-key i{font-style:normal;font-size:.875rem;color:var(--dim)}
.st-tick{position:relative;width:1px;height:26px;background:var(--edge-2)}
.st-tick::after{content:"";position:absolute;left:50%;bottom:-1px;translate:-50% 0;
  border-left:4px solid transparent;border-right:4px solid transparent;
  border-top:5px solid var(--edge-2)}

/* ---------- 04 · the difference ------------------------------------------ */
/* Coded, not a supplied graphic: a quiet list on the left (the problem stays
   flat and dim), a raised glass tile on the right (the answer gets the
   elevation and the glow) — the hierarchy makes the argument before either
   line of copy is read. */
/* the "with" tile sizes to its own content and centers beside the taller
   list+scatter column — stretching it to match left the tile with a huge
   empty top (align-items:end inside meant only the bottom half ever had
   anything in it) */
.st-diff{display:grid;grid-template-columns:minmax(0,.86fr) minmax(0,1.14fr);
  gap:clamp(20px,3vw,40px);align-items:start}
.st-diff-without{padding:clamp(20px,2.4vw,30px) 4px;display:flex;
  flex-direction:column;justify-content:flex-start}
/* the two eyebrows were reading as fine print on a section whose whole job is
   a one-glance contrast — promoted to a pill big enough to anchor each side */
.st-diff-tag{display:inline-flex;align-items:center;align-self:flex-start;
  padding:8px 16px;border-radius:var(--r-pill);font-size:.8125rem;font-weight:600;
  letter-spacing:-.005em}
.st-diff-tag-off{color:var(--dim);background:var(--fill);border:1px solid var(--edge)}
.st-diff-tag-on{color:var(--accent-text);
  background:color-mix(in srgb,var(--accent) 16%,transparent);
  border:1px solid color-mix(in srgb,var(--accent) 42%,transparent)}
.st-diff-list{list-style:none;margin-top:clamp(18px,2.2vw,26px)}
.st-diff-list li{display:grid;grid-template-columns:34px 1fr;gap:14px;
  align-items:center;padding-block:15px;border-top:1px solid var(--edge);
  font-size:.9375rem;color:var(--dim);line-height:1.5}
.st-diff-list li:first-child{border-top:0;padding-top:0}
.st-diff-list li:last-child{padding-bottom:0}
.st-diff-list b{color:var(--ink);font-weight:600}
.st-diff-list .ic{width:34px;height:34px;padding:8px;border-radius:9px;
  color:var(--dimmer);background:var(--fill);flex:none}

/* the scatter: illustrative UI chrome only — a generic handle, placeholder
   numbers, shapes for photos. Never a real conversation or a real review. */
.st-scatter{position:relative;margin-top:clamp(34px,4vw,48px);
  height:clamp(260px,26vw,320px)}
.sc-card{position:absolute;width:190px;border-radius:14px;padding:12px 13px;
  background:var(--panel-solid);border:1px solid var(--edge-2);
  box-shadow:0 16px 34px -16px rgba(0,0,0,.7)}
html[data-theme="light"] .sc-card{box-shadow:0 16px 34px -16px rgba(16,38,74,.28)}
.sc-wa{left:0;top:6px;rotate:-4deg;z-index:2}
.sc-ig{left:47%;top:-10px;rotate:3deg;z-index:3;width:170px}
.sc-g{left:2%;top:52%;rotate:-2deg;z-index:1}
.sc-ask{left:49%;top:46%;rotate:4deg;z-index:2;width:175px}
.sc-top{display:flex;align-items:center;gap:8px;margin-bottom:10px}
.sc-top b{font-size:.75rem;font-weight:600;color:var(--ink);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.sc-ic{width:26px;height:26px;border-radius:8px;display:grid;place-items:center;
  flex:none}
.sc-ic svg{width:14px;height:14px}
/* the only place brand color is allowed into an otherwise all-violet
   system — it is borrowing WhatsApp/Instagram/Google's own recognition to
   speed up parsing a chaotic cluster of unrelated apps. Do not reuse these
   tints outside .st-scatter; anywhere else, color carries emphasis, not a
   brand's identity. */
.sc-ic-wa{background:rgba(53,199,116,.20);color:#3ED17A}
.sc-ic-ig{background:linear-gradient(135deg,rgba(240,92,150,.30),rgba(150,100,230,.28));
  color:#E97FAE}
.sc-ic-g{background:rgba(66,133,244,.20);color:#6FA1FF}
.sc-ic-ask{background:var(--fill);color:var(--dimmer)}
.sc-bub{border-radius:9px 9px 9px 3px;padding:7px 10px;font-size:.6875rem;
  line-height:1.4;background:var(--fill-2);color:var(--dim);max-width:94%}
.sc-bub-out{margin-left:auto;margin-top:6px;border-radius:9px 9px 3px 9px;
  background:rgba(53,199,116,.16);color:var(--ink)}
.sc-ig-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:4px}
.sc-ig-grid i{aspect-ratio:1;border-radius:4px;
  background:linear-gradient(150deg,rgba(233,127,174,.32),rgba(123,114,240,.26))}
.sc-ig-grid i:nth-child(3n+2){opacity:.8}
.sc-ig-grid i:nth-child(3n){opacity:.62}
.sc-g-stars{display:flex;gap:2px;color:var(--star);margin-bottom:9px}
.sc-g-stars svg{width:11px;height:11px;fill:currentColor;stroke:none}
.sc-star-off{opacity:.32}
.sc-g-row{display:flex;align-items:center;gap:7px}
.sc-g-row .ic{width:20px;height:20px;padding:0;border-radius:0;
  background:transparent;color:var(--dimmer);flex:none}
.sc-g-row em{height:6px;border-radius:3px;background:var(--edge-2);flex:1}
.sc-g-row em.sh{flex:.55;opacity:.6}
.sc-lines{display:grid;gap:6px}
.sc-lines i{display:block;height:6px;width:64px;border-radius:3px;
  background:var(--edge-2)}
.sc-lines i.sh{width:38px;opacity:.6}

.st-diff-with{display:grid;grid-template-columns:minmax(0,1fr) minmax(150px,.62fr);
  align-items:end;align-self:center;gap:clamp(10px,1.6vw,20px);
  border-color:color-mix(in srgb,var(--accent) 30%,transparent)}
.st-diff-with-text{padding-block:clamp(6px,1vw,10px)}
.st-diff-with h3{margin-top:12px;font-size:clamp(1.375rem,2vw,1.75rem);
  letter-spacing:-.026em;line-height:1.14}
.st-diff-with-list{list-style:none;margin-top:clamp(18px,2vw,24px);
  display:grid;gap:12px}
.st-diff-with-list li{display:grid;grid-template-columns:18px 1fr;gap:10px;
  align-items:start;font-size:.9375rem;color:var(--dim);line-height:1.4}
.st-diff-with-list li svg{margin-top:5px;color:var(--accent-text)}
/* the phone rides at the tile's own edge, not framed — the device art
   already carries its own shadow and glass would double-frame it */
.st-diff-phone{align-self:end;justify-self:end;margin:-30px -14px -30px 0;
  max-width:220px}
/* The device is drawn rather than baked into the image, so swapping the tier
   only means swapping the screenshot. The old composited PNG carried one
   client's phone onto all three pages, which put a jeweller's gold CTA on the
   bridal page. */
.st-device{position:relative;border-radius:30px;padding:22px 7px 7px;
  background:linear-gradient(160deg,#3d4358,#171a24 42%,#2a2f3e);
  box-shadow:0 0 0 1px rgba(255,255,255,.10) inset,
             0 24px 44px -18px rgba(0,0,0,.6)}
.st-device img{display:block;width:100%;height:auto;border-radius:24px}
/* the dynamic island, so the screenshot reads as a phone and not a card */
.st-device-bar{position:absolute;z-index:2;top:7px;left:50%;translate:-50% 0;
  width:26%;height:8px;border-radius:99px;background:#0b0d13}

/* ---------- 05 · included: editorial, no cards --------------------------- */
/* Three of the six are worth SHOWING, and they are shown with the real site.
   The other three are facts, and a fact reads faster as a line of text than as
   a card with an icon on it. */
.st-show{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(16px,2.2vw,30px)}
.st-show-c b{display:block;margin-top:18px;font-size:1.0625rem;letter-spacing:-.012em}
.st-show-c p{margin-top:7px;color:var(--dimmer);font-size:.9375rem;line-height:1.55}
.st-show-vis{position:relative;aspect-ratio:4/3;border-radius:var(--r-card);
  overflow:hidden;border:1px solid var(--edge);background:var(--panel-solid)}

/* three real pages, fanned — the product, not an icon of it */
.st-show-stack img{position:absolute;width:78%;height:auto;aspect-ratio:16/10;
  object-fit:cover;border-radius:6px;
  border:1px solid var(--edge-2);box-shadow:0 10px 26px -12px rgba(0,0,0,.8)}
.st-show-stack img:nth-child(1){left:4%;top:10%;rotate:-4deg}
.st-show-stack img:nth-child(2){left:11%;top:30%;rotate:-1deg}
.st-show-stack img:nth-child(3){left:18%;top:50%;rotate:2.5deg}

/* the site's own enquiry button, cropped from the real capture */
.st-show-cta{display:grid;place-items:center;padding:clamp(12px,1.6vw,20px)}
/* drawn, not a crop of one client's button — the card is on all three tiers */
.st-cta-btn{display:inline-flex;align-items:center;gap:9px;border-radius:var(--r-pill);
  padding:12px 20px;font-size:.875rem;font-weight:500;color:#fff;
  background:linear-gradient(180deg,color-mix(in srgb,var(--btn) 95%,white),var(--btn));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.32),
             0 10px 24px -12px var(--btn)}
.st-chat{margin-top:14px;align-self:end;justify-self:end;max-width:82%;
  padding:9px 12px;border-radius:10px 10px 3px 10px;font-size:.75rem;
  color:var(--dim);background:var(--fill-2);border:1px solid var(--edge)}

/* a generic search abstraction — shapes, never a believable result page */
.st-show-serp{display:grid;align-content:center;gap:12px;
  padding:clamp(14px,1.8vw,22px)}

/* the remaining three, as a quiet typographic row */
.st-incs-rest{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(20px,2.8vw,44px);margin-top:clamp(30px,3.6vw,52px);
  border-top:1px solid var(--edge);padding-top:clamp(22px,2.6vw,34px)}
.st-inc b{display:block;font-size:1rem;letter-spacing:-.01em}
.st-inc p{margin-top:6px;color:var(--dimmer);font-size:.875rem;line-height:1.5}

/* ---------- 06 · delivery: quiet ---------------------------------------- */
.st-speed{text-align:center;max-width:48ch;margin-inline:auto}
/* Large and elegant, but deliberately a step below the price — the delivery
   number was out-shouting the commercial moment. */
.st-days{font-size:clamp(2.375rem,6vw,4.5rem);font-weight:600;letter-spacing:-.05em;
  line-height:.98}
.st-speed h2{font-size:clamp(1.375rem,2.3vw,1.875rem);margin-top:14px;
  letter-spacing:-.026em}
.st-speed-body{margin-top:12px;color:var(--dim);line-height:1.62;font-size:.9375rem}

/* ---------- 07 · price --------------------------------------------------- */
.st-price{text-align:center;max-width:56ch;margin-inline:auto}
/* The strongest number in the lower half of the page. Still a reveal, not a
   pricing card: no border, no fill, no badge — just scale and air. */
.st-amt{font-size:clamp(3.25rem,9vw,7rem);font-weight:600;letter-spacing:-.055em;
  line-height:.96;margin-top:14px}
.st-amt-sub{margin-top:10px;color:var(--dim)}
.st-summary{list-style:none;display:flex;flex-wrap:wrap;justify-content:center;
  gap:9px 22px;margin-top:clamp(16px,1.9vw,24px);font-size:.9375rem;color:var(--dim)}
.st-summary li{position:relative}
.st-summary li + li::before{content:"";position:absolute;left:-12px;top:.55em;
  width:3px;height:3px;border-radius:50%;background:var(--edge-2)}
.st-reassure{margin-top:clamp(14px,1.6vw,18px);color:var(--dimmer);
  font-size:.875rem;max-width:44ch;margin-inline:auto}
.st-price .st-cta{justify-content:center;margin-top:clamp(20px,2.4vw,28px)}
.st-upkeep{margin-top:18px;color:var(--dimmer);font-size:.875rem;line-height:1.6;
  max-width:50ch;margin-inline:auto}

/* ---------- the FAQ, de-glowed on this page only ------------------------ */
/* The shared FAQ tile carries a lit gradient and a halo. On a page whose whole
   argument is restraint, six glowing bars at the bottom undo it. */
/* The FAQ sits INSIDE main.st, so this is a descendant selector — a sibling
   one silently matched nothing and the tiles kept their glow. */
/* the FAQ still ran on the shared --sec rhythm, which is wider than this
   page's. One page, one beat. */
.st .faq.sec{padding-bottom:var(--st-gap)}
.st .faq details{margin-bottom:7px;background:transparent;box-shadow:none;
  border:1px solid var(--edge);-webkit-backdrop-filter:none;backdrop-filter:none}
.st .faq details::after{display:none}
.st .faq details.is-open{background:var(--fill);box-shadow:none;
  border-color:var(--edge-2)}

/* ---------- responsive: designed, not stacked --------------------------- */
@media (max-width:1000px){
  .st-hero,.st-trust{grid-template-columns:minmax(0,1fr);
    gap:clamp(24px,4.5vw,40px)}
  .st-hero{padding-bottom:clamp(26px,4vw,44px)}
  .st-diff{grid-template-columns:minmax(0,1fr)}
  .st-diff-with{grid-template-columns:minmax(0,1fr);justify-items:center;text-align:center}
  .st-diff-with-list{justify-items:start;text-align:left}
  .st-diff-phone{margin:6px 0 0;max-width:170px;justify-self:center}
  .st-head-left p{max-width:none}
}
@media (max-width:1000px){
  .st-show{grid-template-columns:repeat(3,minmax(0,1fr))}
}
@media (max-width:760px){
  /* the same desktop grid, scaled as one piece rather than reflowed — zoom
     scales the *rendered* pixels after every clamp() has resolved, so the
     three cards keep their desktop proportions instead of hitting their
     clamped floors and going cramped. Same technique as the homepage's
     bento grid and pricing tiers. */
  /* one card per row, near full size: these are the proof the page rests
     on, and at three-across they render about 109px wide on a phone */
  .st-pages{zoom:1;grid-template-columns:minmax(0,1fr);gap:22px}
  .st-diff{gap:18px}
  /* the scattered cluster keeps its exact desktop arrangement — rotation,
     overlap, absolute positions — just smaller. That scatter IS the point
     of this cluster, so scaling it down whole reads truer than un-scattering
     it into a list. */
  .st-scatter{zoom:.6}
  .st-show{grid-template-columns:minmax(0,1fr);gap:24px}
  .st-show-vis{aspect-ratio:16/10}
  .st-incs-rest{grid-template-columns:minmax(0,1fr);gap:18px}
  .st-head,.st-head-left{text-align:left;margin-inline:0}
  .st-buy{gap:16px}
  .st-buy .btn,.st-cta .btn{width:100%;justify-content:center}
  .st-cta{gap:14px}
  .st-summary{gap:8px 18px;font-size:.875rem}
}

@media (prefers-reduced-motion:reduce){
  .st-hero-shot.rv{opacity:1;transform:none;transition:opacity 200ms var(--ease)}
}


/* ------------------------------------------------------------------
   Blog body furniture.

   The first seven posts were 350 words of unbroken paragraphs with no
   images, which is thin-content territory and reads as filler. Longer
   pieces need somewhere for a diagram, a comparison and a rule to sit, or
   they become a wall of grey.
   ------------------------------------------------------------------ */
.post-fig{margin:var(--sp-7) 0;max-width:100%}
.post-fig figcaption{margin-top:14px;font-size:15px;line-height:1.55;
  color:var(--dimmer)}
.post-fig img{display:block;width:100%;height:auto;border-radius:var(--r);
  border:1px solid var(--line)}
.post-fig svg{display:block;width:100%;height:auto;border-radius:var(--r);
  background:var(--ground-2);border:1px solid var(--line)}

/* a photo the owner still has to supply — visible in the build, obvious in
   review, impossible to ship by accident */
.post-slot{display:flex;align-items:center;justify-content:center;
  min-height:230px;border-radius:var(--r);border:2px dashed var(--accent);
  background:var(--ground-2);padding:28px;text-align:center;
  font-family:var(--mono);font-size:14px;letter-spacing:.04em;
  color:var(--dimmer);line-height:1.6}

.post-table{width:100%;border-collapse:collapse;margin:var(--sp-6) 0;
  font-size:16px}
.post-table th,.post-table td{text-align:left;padding:14px 16px;
  border-bottom:1px solid var(--line);vertical-align:top}
.post-table th{font-size:13px;letter-spacing:.10em;text-transform:uppercase;
  color:var(--dimmer);font-weight:500}
.post-table td:first-child{font-weight:600;white-space:nowrap}
.post-table-wrap{overflow-x:auto;margin:var(--sp-6) 0}
.post-table-wrap .post-table{margin:0}

.post-rule{margin:var(--sp-6) 0;padding:22px 26px;border-radius:var(--r);
  background:var(--ground-2);border-left:3px solid var(--accent)}
.post-rule p{margin:0}
.post-rule strong{color:var(--ink)}

.post-list{margin:var(--sp-5) 0;padding:0;list-style:none}
.post-list li{position:relative;padding-left:34px;margin-bottom:16px;
  line-height:1.65}
.post-list li:before{content:"";position:absolute;left:0;top:.62em;
  width:16px;height:2px;background:var(--accent);border-radius:2px}
.post-list li strong{color:var(--ink)}

.post-nots li:before{background:#C4452F;height:2px;top:.62em;
  transform:rotate(0)}


/* ------------------------------------------------------------------
   The design reel is draggable.

   On a phone the cards looked swipeable and were not — people dragged,
   nothing happened, and they left. touch-action: pan-y keeps vertical page
   scrolling working while the horizontal axis belongs to the reel.
   ------------------------------------------------------------------ */
.reel-stage{touch-action:pan-y;cursor:grab;-webkit-user-select:none;
  user-select:none;-webkit-tap-highlight-color:transparent}
.reel-stage.dragging{cursor:grabbing}
.reel-stage img{-webkit-user-drag:none;user-drag:none;pointer-events:none}

/* a hint that it can be dragged, on touch only — a mouse user has the
   controls and hover to tell them */
@media (hover:none){
  .reel-hint{display:block;margin-top:14px;text-align:center;
    font-family:var(--mono);font-size:12px;letter-spacing:.14em;
    text-transform:uppercase;color:var(--dimmer);opacity:.75}
}
.reel-hint{display:none}


/* ------------------------------------------------------------------
   The opening film.

   Shown once per visitor, never again — a splash screen on every load is
   the fastest way to make a returning customer hate a site. The video is
   not in the markup and is not fetched at all unless the overlay is
   actually going to run, so a repeat visitor pays nothing for it.

   Controls sit ON the video, not around it. The first version floated them
   58px above the frame, which is fine on a tall monitor and completely off
   the top of the screen on a laptop — the place a control cannot go is
   outside the thing it controls.
   ------------------------------------------------------------------ */
#intro{position:fixed;inset:0;z-index:9998;display:none;
  align-items:center;justify-content:center;padding:24px;
  background:rgba(8,12,22,.82);
  backdrop-filter:blur(30px) saturate(130%);
  -webkit-backdrop-filter:blur(30px) saturate(130%);
  opacity:0;transition:opacity 620ms var(--ease)}
#intro.on{display:flex;opacity:1}
#intro.out{opacity:0;pointer-events:none}
html.intro-lock,html.intro-lock body{overflow:hidden}

#intro-stage{position:relative;width:min(100%,1180px);
  max-height:calc(100vh - 48px);aspect-ratio:16/9;
  border-radius:18px;overflow:hidden;
  transform:scale(.965);opacity:0;
  box-shadow:0 40px 120px -30px rgba(0,0,0,.85),
             0 0 0 1px rgba(255,255,255,.10);
  transition:transform 760ms var(--spring),opacity 560ms var(--ease)}
#intro.on #intro-stage{transform:scale(1);opacity:1}
#intro.out #intro-stage{transform:scale(1.035);opacity:0;
  transition:transform 620ms var(--ease),opacity 480ms var(--ease)}

#intro video{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;background:#0C1428;display:block}

#intro-hello{position:absolute;inset:0;display:grid;place-items:center;
  text-align:center;pointer-events:none;color:#EFECE4;
  opacity:0;transition:opacity 700ms var(--ease)}
#intro-hello.show{opacity:1}
#intro-hello .hi{font-size:clamp(1.7rem,3.6vw,2.8rem);font-weight:700;
  letter-spacing:-.03em;text-shadow:0 2px 34px rgba(0,0,0,.65)}
#intro-hello .sub{margin-top:10px;font-family:var(--mono);font-size:.76rem;
  letter-spacing:.24em;text-transform:uppercase;opacity:.74}

/* ---- the control bar, over the film ---- */
#intro-ui{position:absolute;left:0;right:0;bottom:0;padding:54px 18px 16px;
  display:flex;align-items:center;gap:12px;
  background:linear-gradient(to top,rgba(6,9,16,.86),rgba(6,9,16,.45) 52%,transparent);
  opacity:1;transition:opacity 420ms var(--ease)}
/* kept so the class is harmless if it is ever set, but nothing sets it */
#intro.idle #intro-ui{opacity:1}

.intro-ctl{display:inline-flex;align-items:center;justify-content:center;gap:8px;
  min-height:42px;min-width:42px;padding:0 15px;border-radius:99px;border:0;
  cursor:pointer;font:inherit;font-size:.84rem;font-weight:600;
  letter-spacing:-.01em;color:#0E1422;background:rgba(255,255,255,.94);
  box-shadow:0 2px 10px rgba(0,0,0,.3);
  transition:transform 160ms var(--ease),background 200ms var(--ease)}
.intro-ctl:hover{transform:translateY(-1px);background:#fff}
.intro-ctl:focus-visible{outline:2px solid #fff;outline-offset:3px}
.intro-ctl.ghost{background:rgba(255,255,255,.16);color:#fff;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.28)}
.intro-ctl.ghost:hover{background:rgba(255,255,255,.26)}
.intro-ctl svg{width:17px;height:17px;flex:none}
#intro-skip{margin-left:auto}

/* ---- scrub line ---- */
#intro-bar{position:absolute;left:18px;right:18px;bottom:70px;height:4px;
  border-radius:99px;background:rgba(255,255,255,.22);overflow:hidden}
#intro-bar i{display:block;height:100%;width:0;background:#fff;
  border-radius:99px;transition:width 140ms linear}
#intro-time{font-family:var(--mono);font-size:.74rem;color:rgba(255,255,255,.82);
  letter-spacing:.06em;font-variant-numeric:tabular-nums;min-width:74px}

@media (max-width:700px){
  #intro{padding:12px}
  #intro-ui{padding:46px 12px 12px;gap:8px}
  .intro-ctl{padding:0 12px;font-size:.8rem}
  .intro-ctl .lbl{display:none}
  #intro-skip .lbl{display:inline}
  #intro-bar{left:12px;right:12px;bottom:64px}
  #intro-time{display:none}
}

@media (prefers-reduced-motion:reduce){
  #intro{display:none !important}
}


/* ------------------------------------------------------------------
   The helper.

   Real frosted glass, not a flat pill: a blurred, saturated backdrop with a
   bright top edge where light would catch and a darker bottom edge where it
   would not. That top-edge highlight is most of what separates glass from a
   translucent rectangle.

   Answers everything it can from a written knowledge base, and hands over to
   WhatsApp when it cannot. Nothing is generated.
   ------------------------------------------------------------------ */
:root{
  --hg:rgba(255,255,255,.62);
  --hg-edge:rgba(255,255,255,.85);
  --hg-line:rgba(16,24,44,.10);
}
html[data-theme="dark"]{
  --hg:rgba(26,32,52,.58);
  --hg-edge:rgba(255,255,255,.22);
  --hg-line:rgba(255,255,255,.12);
}

#helper{position:fixed;right:22px;bottom:22px;z-index:9990;
  display:flex;flex-direction:column;align-items:flex-end;gap:12px;font-size:15px}
@media (max-width:700px){#helper{right:14px;bottom:14px;left:14px;align-items:flex-end}}

/* ---- the mascot ----
   No button chrome at all: he floats. A container would make him look like
   a sticker pasted into a circle, and the whole point of a character is that
   he is a character.

   He is mostly white, so on light paper he needs a shadow to separate him
   and on navy he needs a faint halo. Both are theme-aware — the same glow
   would either vanish or glare. */
#helper-tab{position:relative;width:104px;height:104px;border:0;padding:0;
  background:none;cursor:pointer;display:grid;place-items:center;
  -webkit-tap-highlight-color:transparent;
  transition:transform 320ms var(--spring)}
#helper-tab::before{content:"";position:absolute;left:50%;top:54%;
  width:86%;height:86%;transform:translate(-50%,-50%);border-radius:50%;
  background:radial-gradient(circle,rgba(123,114,240,.26),transparent 68%);
  filter:blur(14px);pointer-events:none;
  transition:opacity 300ms var(--ease)}
html[data-theme="dark"] #helper-tab::before{
  background:radial-gradient(circle,rgba(160,178,255,.34),transparent 70%)}
#helper-tab img{position:relative;width:100%;height:100%;display:block;
  object-fit:contain;pointer-events:none;
  filter:drop-shadow(0 8px 16px rgba(24,32,64,.34))
         drop-shadow(0 2px 4px rgba(24,32,64,.20));
  animation:hbob 5.2s ease-in-out infinite}
html[data-theme="dark"] #helper-tab img{
  filter:drop-shadow(0 8px 22px rgba(0,0,0,.55))
         drop-shadow(0 0 14px rgba(150,170,255,.22))}
@keyframes hbob{
  0%,100%{transform:translateY(0) rotate(0deg)}
  50%{transform:translateY(-7px) rotate(-1.6deg)}}
#helper-tab:hover{transform:translateY(-4px) scale(1.06)}
#helper-tab:hover::before{opacity:1.35}
#helper-tab:active{transform:translateY(-1px) scale(.98)}
#helper-tab:focus-visible{outline:2px solid var(--accent);outline-offset:6px;
  border-radius:20px}
#helper-tab .pulse{position:absolute;inset:8%;border-radius:50%;
  border:1.5px solid var(--accent);opacity:0;pointer-events:none;
  animation:hpulse 5.2s var(--ease) infinite}
@keyframes hpulse{
  0%,74%{transform:scale(.88);opacity:0}
  82%{opacity:.26}
  100%{transform:scale(1.22);opacity:0}}
#helper.open #helper-tab{display:none}
@media (max-width:700px){#helper-tab{width:88px;height:88px}}

/* ---- the hello ---- */
#helper-nudge{position:relative;max-width:252px;padding:14px 30px 14px 16px;
  border-radius:18px 18px 5px 18px;line-height:1.45;color:var(--ink);
  background:var(--hg);
  backdrop-filter:blur(22px) saturate(190%);
  -webkit-backdrop-filter:blur(22px) saturate(190%);
  border:1px solid var(--hg-line);cursor:pointer;
  box-shadow:inset 0 1px 0 var(--hg-edge),0 14px 36px -14px rgba(16,24,44,.34);
  opacity:0;transform:translateY(8px) scale(.96);transform-origin:bottom right;
  transition:opacity 420ms var(--ease),transform 520ms var(--spring)}
#helper-nudge.show{opacity:1;transform:none}
#helper-nudge b{display:block;font-weight:700;margin-bottom:2px}
html[data-theme="dark"] #helper-nudge{color:var(--ink)}
#helper-nudge .x{position:absolute;top:7px;right:8px;border:0;background:none;
  cursor:pointer;color:var(--dimmer);font-size:17px;line-height:1;padding:3px}
#helper.open #helper-nudge,#helper-nudge.gone{display:none}

/* ---- the panel ---- */
#helper-panel{width:min(382px,calc(100vw - 28px));max-height:min(600px,80vh);
  display:none;flex-direction:column;overflow:hidden;border-radius:24px;
  background:var(--hg);
  backdrop-filter:blur(30px) saturate(190%);
  -webkit-backdrop-filter:blur(30px) saturate(190%);
  border:1px solid var(--hg-line);
  box-shadow:inset 0 1px 0 var(--hg-edge),
             0 4px 14px rgba(16,24,44,.10),
             0 34px 80px -26px rgba(16,24,44,.48);
  opacity:0;transform:translateY(12px) scale(.97);transform-origin:bottom right;
  transition:opacity 320ms var(--ease),transform 480ms var(--spring)}
#helper.open #helper-panel{display:flex}
#helper.open.ready #helper-panel{opacity:1;transform:none}

#helper-top{display:flex;align-items:center;gap:11px;padding:15px 16px;
  border-bottom:1px solid var(--hg-line);flex:none}
#helper-top img{width:40px;height:40px;object-fit:contain;
  filter:drop-shadow(0 3px 7px rgba(24,32,64,.28))}
html[data-theme="dark"] #helper-top img{
  filter:drop-shadow(0 3px 9px rgba(0,0,0,.55))}
#helper-top .who{flex:1;line-height:1.25}
#helper-top .who b{display:block;font-weight:700;font-size:15px}
#helper-top .who span{font-size:12.5px;color:var(--dimmer)}
#helper-close{border:0;background:none;cursor:pointer;color:var(--dimmer);
  font-size:22px;line-height:1;padding:6px;border-radius:9px}
#helper-close:hover{background:rgba(127,127,127,.14);color:var(--ink)}

#helper-log{flex:1;overflow-y:auto;padding:16px;display:flex;
  flex-direction:column;gap:11px;-webkit-overflow-scrolling:touch}
.hmsg{max-width:89%;padding:12px 15px;border-radius:17px;line-height:1.5;
  font-size:14.5px;animation:hmsg-in 420ms var(--spring) both}
.hmsg.them{align-self:flex-start;background:rgba(255,255,255,.72);color:var(--ink);
  border-bottom-left-radius:5px;border:1px solid var(--hg-line)}
html[data-theme="dark"] .hmsg.them{background:rgba(255,255,255,.09)}
.hmsg.me{align-self:flex-end;background:var(--ink);color:var(--ground);
  border-bottom-right-radius:5px}
.hmsg a{color:inherit;text-decoration:underline;text-underline-offset:2px}
.hmsg ul{margin:8px 0 0;padding-left:17px}
.hmsg li{margin-bottom:4px}
.hmsg.typing{display:flex;gap:4px;padding:15px}
.hmsg.typing i{width:6px;height:6px;border-radius:50%;background:var(--dimmer);
  animation:hdot 1.2s infinite}
.hmsg.typing i:nth-child(2){animation-delay:.16s}
.hmsg.typing i:nth-child(3){animation-delay:.32s}
@keyframes hdot{0%,60%,100%{opacity:.25;transform:translateY(0)}
  30%{opacity:.9;transform:translateY(-3px)}}
@keyframes hmsg-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}

#helper-opts{flex:none;padding:10px 16px 0;display:flex;flex-wrap:wrap;gap:7px}
.hopt{border:1px solid var(--hg-line);background:rgba(255,255,255,.55);
  color:var(--ink);border-radius:99px;padding:8px 13px;font:inherit;
  font-size:13.5px;font-weight:500;cursor:pointer;line-height:1.2;
  transition:background 180ms var(--ease),transform 160ms var(--ease)}
html[data-theme="dark"] .hopt{background:rgba(255,255,255,.09)}
.hopt:hover{background:var(--ink);color:var(--ground);transform:translateY(-1px)}
.hopt:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.hopt.go{background:var(--accent);border-color:var(--accent);color:#fff;font-weight:600}
.hopt.go:hover{filter:brightness(1.1);background:var(--accent);color:#fff}

/* ---- typing ---- */
#helper-ask{flex:none;display:flex;gap:8px;align-items:center;
  padding:12px 14px 14px;border-top:1px solid var(--hg-line);margin-top:10px}
#helper-in{flex:1;min-width:0;border:1px solid var(--hg-line);
  background:rgba(255,255,255,.62);color:var(--ink);
  border-radius:99px;padding:11px 16px;font:inherit;font-size:14.5px;
  transition:border-color 180ms var(--ease),background 180ms var(--ease)}
html[data-theme="dark"] #helper-in{background:rgba(255,255,255,.08)}
#helper-in::placeholder{color:var(--dimmer)}
#helper-in:focus{outline:0;border-color:var(--accent);
  background:rgba(255,255,255,.86)}
#helper-send{flex:none;width:40px;height:40px;border-radius:50%;border:0;
  cursor:pointer;background:var(--accent);color:#fff;display:grid;
  place-items:center;transition:transform 160ms var(--ease),opacity 160ms var(--ease)}
#helper-send:hover{transform:scale(1.06)}
#helper-send:disabled{opacity:.4;cursor:default;transform:none}
#helper-send svg{width:17px;height:17px}

@media (prefers-reduced-motion:reduce){
  #helper-tab,#helper-nudge,#helper-panel,.hmsg,.hopt,#helper-send{
    transition:none;animation:none}
  /* it still appears, it just does not travel to get there */
  #helper-nudge{opacity:1;transform:none}
  #helper-tab img{animation:none}
  #helper-tab .pulse{display:none}
  #helper-tab:hover,.hopt:hover,#helper-send:hover{transform:none}
}

/* The glass is built from white by default, which disappears on a dark
   ground — these re-tint the same material rather than restyling it. */
html[data-theme="dark"] #helper-panel,
html[data-theme="dark"] #helper-nudge{
  background:rgba(22,28,46,.72)}
html[data-theme="dark"] #helper-in:focus{background:rgba(255,255,255,.14)}
html[data-theme="dark"] .hopt:hover{background:var(--ink);color:var(--ground)}
