/* Generated by tools/story/export.mjs from tools/story (page.html, form/try-form.css). Edit those, then re-export. */
/* Layout: a slim header, then the scroll story (one full-screen stage pinned while you scroll through four steps:
   Google, website, calls, try it), then the demo form, which rises into the stage at the last step. The 3D phone and
   every motion are drawn on the canvas; the words beside it are normal text the engine moves. */
#story,.sheet{
  --bg:#0a0a0f;--text:#f3f6f9;--soft:#d2dae2;--muted:#95a3b0;--primary:#35c7ff;--primary-hover:#6ad6ff;--ink:#04121c;
  --font-d:"Inter",system-ui,-apple-system,"Segoe UI",sans-serif;--font-b:"Inter",system-ui,-apple-system,"Segoe UI",sans-serif;
  color-scheme:dark;color:var(--text);font-family:var(--font-b);font-optical-sizing:auto;-webkit-font-smoothing:antialiased
}
#story *,#story *::before,#story *::after,.sheet *{box-sizing:border-box}
:is(#story,.sheet) :is(a,button,input,summary):focus-visible{outline:2px solid #e8f8ff;outline-offset:3px;border-radius:8px}


/* Story */
#story{position:relative;height:calc(10 * var(--hs-step, 100vh) + 100vh)}
@supports (height:100svh){#story{height:calc(10 * var(--hs-step, 100svh) + 100lvh)}}
#stage{position:sticky;top:0;height:100vh;height:100lvh;overflow:hidden;overflow:clip;background:var(--bg);will-change:transform}
#gl{position:absolute;inset:0;width:100%;height:100%;display:block}
#poster{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:1;transition:opacity .3s}
#poster.off{opacity:0;visibility:hidden}
#txt{position:absolute;inset:0;pointer-events:none;contain:layout paint}
.beat{position:absolute;opacity:0;visibility:hidden;will-change:opacity,transform}
.beat a,.beat button{pointer-events:auto}
.kick{margin:0 0 16px;font:600 13px/1.2 var(--font-b);letter-spacing:.1em;text-transform:uppercase;color:var(--primary)}
.hl{margin:0;font-family:var(--font-d);font-weight:700;letter-spacing:-.032em;line-height:1.06;color:var(--text);text-wrap:balance}
.b0 .hl{letter-spacing:-.036em;line-height:1.04}
.wm{display:inline-block;overflow:hidden;vertical-align:top;padding-bottom:.06em;margin-bottom:-.06em}
.w{display:inline-block}
/* Warm-up at load: everything is painted once, invisibly, so nothing paints for the first time mid-move. */
html.hs-warm .beat,html.hs-warm .pov,html.hs-warm .rail,html.hs-warm .beat *{visibility:visible!important;opacity:.01!important}
html.hs-warm .w{transform:none!important}
html.hs-warm .pform{visibility:visible!important;opacity:.01!important;width:340px;height:620px}
.sub{margin:22px 0 0;color:var(--soft);line-height:1.55;max-width:28em;text-wrap:pretty}
/* The opening says what we do: one line per service, its name then its best points. */
.b0 .sub{max-width:34em}
.b0 .sub .sl{display:block}
.b0 .sub .sl+.sl{margin-top:.4em}
.b0 .sub b{color:var(--text);font-weight:650;margin-right:.3em}
.b0 .sub b::after{content:" —";color:var(--muted);font-weight:400}
.cue{margin:26px 0 0;font:600 15px/1 var(--font-b);font-size:max(15px,.8em);color:var(--soft);letter-spacing:.01em}
/* "Skip to the demo": a quiet text button under the opening line */
.skipdemo{display:inline-flex;align-items:center;min-height:44px;padding:0 18px;border:1px solid rgba(255,255,255,.22);border-radius:999px;background:rgba(255,255,255,.04);color:var(--text);cursor:pointer;pointer-events:auto}
@media (hover:hover){.skipdemo:hover{border-color:var(--primary);color:var(--primary)}}
html.hs-stacked .skipdemo{min-height:38px;padding:0 14px}
.tail{margin-top:26px}
/* One point at a time: a thin bar per point fills while it is shown (click one to see it again). */
.bars{display:flex;gap:6px;width:min(100%,250px);margin:0 0 14px}
.bar{flex:1;height:24px;padding:0;border:0;background:none;cursor:pointer;display:flex;align-items:center}
.bar i{display:block;width:100%;height:3px;border-radius:3px;background:rgba(255,255,255,.18);overflow:hidden}
.bar b{display:block;height:100%;background:var(--primary);transform-origin:left;transform:scaleX(0);will-change:transform}
.bar:hover i{background:rgba(255,255,255,.3)}
.feat{position:relative}
.pt{position:absolute;left:0;top:0;width:100%;opacity:0;visibility:hidden}
.pt-t{margin:0 0 .45em;font-family:var(--font-d);font-weight:650;font-size:1.3em;line-height:1.2;letter-spacing:-.018em;color:var(--text)}
.pt-d{margin:0;max-width:26em;color:var(--soft);line-height:1.6;text-wrap:pretty}
.more{display:inline-flex;align-items:center;gap:.45em;margin:12px 0 0;min-height:44px;padding:0;border:0;background:none;color:var(--primary);font:600 15px/1.2 var(--font-b);font-size:max(15px,.8em);cursor:pointer}
.more:hover{color:var(--primary-hover)}
.more span{display:inline-block;transition:transform .2s}
.more:hover span{transform:translateX(3px)}
.ex{margin:6px 0 0;font:400 13px/1.4 var(--font-b);font-size:max(13px,.66em);color:var(--muted)}
/* The last step: the phone grows and becomes the demo; the words say what to do and how the call is going. */
.cue4{display:flex;align-items:center;gap:10px;margin:26px 0 0;font:700 17px/1.2 var(--font-b);color:var(--primary)}
.cue4 svg{width:34px;height:14px;flex:none;animation:cue-nudge 1.6s ease-in-out infinite}
.cue4[hidden]{display:none}
.flow-try{display:none}
@keyframes cue-nudge{0%,100%{translate:0 0}50%{translate:6px 0}}
html.hs-stacked .cue4 svg{animation-name:cue-nudge-down}
@keyframes cue-nudge-down{0%,100%{translate:0 0}50%{translate:0 4px}}
@media (prefers-reduced-motion:reduce){.cue4 svg{animation:none}}
.hud{margin:24px 0 0}
.hud[hidden]{display:none}
.hud-msg{margin:0;font:600 17px/1.4 var(--font-b);color:var(--text)}
.hud-note{margin:6px 0 0;font:500 13px/1.4 var(--font-b);color:var(--muted)}
.hud-again{margin:14px 0 0;min-height:44px;padding:0 18px;border:1px solid rgba(255,255,255,.22);border-radius:10px;background:none;color:var(--text);font:600 15px/1 var(--font-b);cursor:pointer}
.hud-again:hover{border-color:var(--primary);color:var(--primary)}
.hud-again[hidden]{display:none}
/* The form, in the phone: a DOM layer laid exactly over the phone's screen once the phone has settled. */
.pform{position:absolute;left:0;top:0;z-index:2;opacity:0;visibility:hidden;overflow:hidden;transform-origin:50% 22%;container-type:size}
.pform-in,.pform-in.tf{position:absolute;inset:0;overflow-y:auto;overscroll-behavior:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none}
.pform-in::-webkit-scrollbar{display:none}
.pform.pf-more .pform-in{-webkit-mask-image:linear-gradient(#000 calc(100% - 44px),transparent);mask-image:linear-gradient(#000 calc(100% - 44px),transparent)}
/* The form, styled as the phone's app screen (the page's own form component, in its "phone" layout). */
.pform-in{padding:6px 6.5cqi 18px}
/* The app's own header (the page heading beside the phone already says "Hear it for yourself"). */
.papp{display:flex;align-items:center;gap:10px;padding:4px 0 14px;border-bottom:1px solid rgba(255,255,255,.08)}
.papp img{display:block;height:20px;width:auto}
.papp-s{margin:0 0 0 auto;padding:4px 8px;border-radius:999px;background:rgba(53,199,255,.12);color:var(--primary);font:700 10.5px/1 var(--font-b);letter-spacing:.08em;text-transform:uppercase}
.papp-h{margin:16px 0 0;font:700 clamp(21px,7cqi,26px)/1.12 var(--font-d);letter-spacing:-.025em;color:#fff}
.papp-p{text-wrap:pretty;margin:8px 0 0;font:500 clamp(13.5px,4.3cqi,15px)/1.45 var(--font-b);color:var(--soft)}
.pform .tf-kicker,.pform .tf-h2,.pform .tf-sub{display:none}
.pform .tf{font-size:15px;--tf-sans:"Inter",system-ui,-apple-system,sans-serif;--tf-head:"Inter",system-ui,-apple-system,sans-serif}
.pform .tf-kicker{margin:6px 0 8px;font:700 11px/1 var(--font-b);letter-spacing:.14em;text-transform:uppercase;color:var(--primary)}
.pform .tf-h2{font-size:clamp(21px,7.6cqi,28px);white-space:normal;line-height:1.08}
.pform .tf-sub{margin-top:8px;font-size:clamp(13.5px,4.4cqi,15.5px);line-height:1.45}
.pform .tf-sub>span{display:inline}
.pform .tf-trust{display:none}
.pform .tf-notice{margin-top:12px;padding:8px 10px;gap:8px;font-size:12px;line-height:1.35}
.pform .tf-notice svg{width:15px;height:15px}
.pform .tf-card{margin-top:14px;padding:0;background:none;border:0;border-radius:0;box-shadow:none;gap:14px}
.pform .tf-grid{grid-template-columns:1fr!important;gap:14px}
.pform .tf-label{margin-bottom:6px;font-size:clamp(13px,3.9cqi,15px);line-height:1.35}
.pform .tf{--tf-field-h:clamp(46px,13.5cqi,56px)}
.pform .tf-input{border-radius:12px;font-size:max(16px,4.6cqi)}
.pform .tf-cc{font-size:max(15px,4.3cqi);line-height:calc(var(--tf-field-h) - 2px);border-radius:12px 0 0 12px}
.pform .tf-tel .tf-input{border-radius:0 12px 12px 0}
.pform .tf-biz:not(.is-open) .tf-bizwrap{display:none}
.pform .tf-biz:not(.is-open) .tf-addbiz{display:inline-flex;align-items:center;gap:6px;min-height:36px;margin:-6px 0 -6px -2px;padding:0 6px 0 2px;border:0;background:none;color:var(--primary);font:600 13px/1.2 var(--font-b);cursor:pointer}
.pform .tf-addbiz svg{width:14px;height:14px}
.pform .tf-addbiz{text-align:left;white-space:normal}
.pform .tf-consent{padding:10px 12px;column-gap:10px;row-gap:4px;border-radius:12px}
.pform .tf-consent__main{font-size:clamp(12.5px,3.8cqi,14.5px);line-height:1.42}
.pform .tf-consent__detail{font-size:clamp(11px,3.3cqi,13px);line-height:1.42}
.pform .tf-btn{height:clamp(48px,14cqi,58px);border-radius:14px;font-size:max(16px,4.6cqi)}
.pform .tf-under{margin-top:0;font-size:clamp(12px,3.6cqi,13.5px)}
.pform .tf-notice{font-size:clamp(12px,3.6cqi,13.5px)}
.pform .tf-notice,.pform .tf-consent__detail:empty{display:none}
@container (max-width:270px){.papp-s{display:none}.pform-in{padding-left:4.5cqi;padding-right:4.5cqi}}
@container (max-width:300px){.papp{display:none}.papp-h{margin-top:6px;font-size:20px}.papp-p{margin-top:6px}.pform .tf-card{margin-top:10px;gap:10px}.pform .tf-grid{gap:10px}.pform .tf{--tf-field-h:44px}.pform .tf-label{margin-bottom:4px}.pform .tf-consent{padding:8px 10px}.pform .tf-btn{height:48px}.pform-in{padding-bottom:10px}}
@container (max-width:262px){.papp-p{display:none}.pform .tf-under{display:none}.pform .tf-consent__main{font-size:12px}}
@container (max-height:470px){.papp{display:none}.papp-h{margin-top:4px;font-size:19px}.papp-p{display:none}.pform .tf-card{margin-top:8px;gap:8px}.pform .tf-grid{gap:8px}.pform .tf{--tf-field-h:40px}.pform .tf-label{margin-bottom:3px;font-size:12.5px}.pform .tf-consent{padding:7px 9px}.pform .tf-consent__main{font-size:11.5px;line-height:1.35}.pform .tf-btn{height:44px}.pform .tf-under{display:none}.pform-in{padding-top:2px;padding-bottom:8px}}
@container (max-height:390px){.papp-h{font-size:17px;line-height:1.15}.pform .tf-biz{display:none}.pform .tf{--tf-field-h:38px}.pform .tf-card{gap:6px}.pform .tf-grid{gap:6px}}
@container (max-width:270px){.pform .tf-input::placeholder{font-size:14px}}
@container (max-width:236px){.papp-h{font-size:18px}.pform .tf{--tf-field-h:40px}.pform .tf-btn{height:44px}.pform .tf-card{gap:8px}.pform .tf-grid{gap:8px}.pform .tf-label{font-size:12.5px}}
/* The first field asks to be filled in until the visitor touches the form. */
.pform:not(.touched) [data-f="name"] .tf-input{animation:pf-ask 2.2s ease-in-out infinite}
@keyframes pf-ask{0%,100%{box-shadow:0 0 0 0 rgba(53,199,255,0)}50%{box-shadow:0 0 0 4px rgba(53,199,255,.5)}}
@media (prefers-reduced-motion:reduce){.pform:not(.touched) [data-f="name"] .tf-input{animation:none;box-shadow:0 0 0 3px rgba(53,199,255,.45)}}
/* "See everything" sheets */
.sheet{position:fixed;inset:0 0 0 auto;margin:0;width:min(560px,100vw);max-width:none;height:100%;max-height:none;padding:0;border:0;border-left:1px solid rgba(255,255,255,.08);background:#0d1b25;color:var(--text);overflow-y:auto;overscroll-behavior:contain}
.sheet::backdrop{background:rgba(3,9,14,.62)}
.sheet[open]{animation:sheetIn .32s cubic-bezier(.2,.8,.2,1)}
@keyframes sheetIn{from{transform:translateX(40px);opacity:0}}
@keyframes sheetUp{from{transform:translateY(40px);opacity:0}}
.sheet-in{position:relative;padding:clamp(28px,4vw,48px) clamp(22px,3.4vw,44px) 40px}
.sheet-x{position:sticky;top:0;float:right;z-index:1;width:44px;height:44px;margin:-14px -10px 0 12px;border:0;border-radius:12px;background:#1a2a36;color:var(--text);font:400 28px/1 var(--font-b);cursor:pointer}
.sheet-x:hover{background:rgba(255,255,255,.12)}
.sheet .kick{margin-bottom:12px}
.sheet-h{margin:0 0 22px;font:700 clamp(26px,3vw,34px)/1.12 var(--font-d);letter-spacing:-.02em}
.sheet-l{list-style:none;margin:0;padding:0;counter-reset:n}
.sheet-l li{counter-increment:n;position:relative;padding:20px 0 20px 46px;border-top:1px solid rgba(255,255,255,.08)}
.sheet-l li::before{content:counter(n,decimal-leading-zero);position:absolute;left:0;top:23px;font:700 13px/1 var(--font-b);color:var(--primary);letter-spacing:.06em}
.sheet-l h3{margin:0 0 6px;font:700 19px/1.25 var(--font-d);letter-spacing:-.01em}
.sheet-l p{margin:0;color:var(--soft);font-size:16px;line-height:1.55}
@media (max-width:600px){.sheet-l{padding-right:30px}}
@media (max-width:700px){.sheet{inset:auto 0 0 0;width:100%;height:auto;max-height:88vh;max-height:88dvh;border-left:0;border-top:1px solid rgba(255,255,255,.1);border-radius:20px 20px 0 0}.sheet[open]{animation-name:sheetUp}}
@media (prefers-reduced-motion:reduce){.sheet[open]{animation:none}}
/* Stacked (phones, tablets in portrait): rail row + one-line headline at the top, points at the bottom. */
.rail{position:absolute;display:none;align-items:center;gap:12px;pointer-events:none;opacity:0;visibility:hidden}
.rail-l{font:600 12px/1 var(--font-b);letter-spacing:.12em;text-transform:uppercase;color:var(--primary);white-space:nowrap}
.rail-s{display:flex;gap:4px;flex:1}
.rail-s i{flex:1;height:3px;border-radius:3px;background:rgba(255,255,255,.16);overflow:hidden}
.rail-s b{display:block;height:100%;background:var(--primary);transform-origin:left;transform:scaleX(0)}
html.hs-stacked .rail{display:flex}
html.hs-stacked .pov{display:none}
html.hs-stacked .beat .kick{display:none}
html.hs-stacked .beat:not(.b0) .hl{white-space:nowrap}
html.hs-stacked .tail{margin-top:0}
html.hs-stacked .bars{width:150px;margin-bottom:6px}
html.hs-stacked .pt-t{font-size:1.16em;margin-bottom:.3em}
html.hs-stacked .more{margin-top:4px;min-height:40px;font-size:14px}
html.hs-stacked .ex{margin-top:0}
/* Phones: the point's details as a column beside the phone (the phone stands to the right; the engine sets top/width). */
html.hs-col .pt-d{position:absolute;left:0;max-width:none;font-size:0;line-height:0}
html.hs-col #story .pt-d .it{display:block;white-space:normal;margin:0 0 18px;font-size:15px;line-height:1.4;color:var(--text)}
html.hs-col #story .pt-d .it::before{content:"";display:block;width:18px;height:2px;margin:0 0 8px;border-radius:2px;background:var(--primary)}
html.hs-stacked .b4 .sub{display:none}
html.hs-stacked .b4 .cue4{margin:8px 0 0;font-size:15px}
html.hs-stacked .b4 .cue4 svg{transform:rotate(90deg);width:22px}
html.hs-stacked .b4 .hl{white-space:nowrap}
html.hs-stacked.hs-calling .b4 .hl{font-size:.74em;white-space:normal}
html.hs-stacked .hud{margin:6px 0 0;display:flex;flex-wrap:nowrap;align-items:center;gap:10px;min-height:34px}
html.hs-stacked .hud[hidden]{display:none}
html.hs-stacked .hud-msg{flex:0 1 auto;min-width:0;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
html.hs-stacked .hud-note{display:none}
html.hs-stacked .hud-again{flex:none;margin:0;min-height:34px;padding:0 12px;font-size:13px}
/* Point-of-view chip on the stage */
.pov{position:absolute;display:grid;pointer-events:none;perspective:300px;opacity:0;visibility:hidden}
.pov span{grid-area:1/1;justify-self:start;padding:6px 10px;border-radius:999px;background:rgba(0,0,0,.5);color:rgba(255,255,255,.72);font:700 11px/1 var(--font-b);letter-spacing:.12em;text-transform:uppercase;backface-visibility:hidden;white-space:nowrap}
.pov-b{transform:rotateX(180deg)}
/* Progress dots (side layouts) */
.dots{position:absolute;display:grid;gap:4px;z-index:3;opacity:0;transition:opacity .5s}
html.hs-ready .dots{opacity:1}
.dots button{width:44px;height:44px;border:0;padding:0;background:none;cursor:pointer;display:grid;place-items:center}
.dots button::after{content:"";width:8px;height:8px;border-radius:50%;background:rgba(255,255,255,.28);transition:background-color .3s,transform .3s}
.dots button.on::after{background:var(--primary);transform:scale(1.35)}
html.hs-stacked .dots{display:none}
html.hs-shortside .dots{display:none}
/* Phones held sideways: the phone is too small to type in, so the form gets the column and the call status shows there later. */
html.hs-shortside .b4 .kick,html.hs-shortside .b4 .hl,html.hs-shortside .b4 .sub,html.hs-shortside .b4 .cue4{display:none}
html.hs-shortside .pform{background:#0b1118;border:1px solid rgba(255,255,255,.08);border-radius:16px!important}


/* Touch screens: snap points for the page's own scrolling (see p2b-playhead.js). */
.hs-snap{position:absolute;left:0;top:0;width:1px;height:1px;opacity:0;pointer-events:none;scroll-snap-align:start;scroll-snap-stop:always}
.hs-snap-rest{scroll-margin-top:var(--header-h,64px)}
html.hs-snapping{scroll-snap-type:y mandatory;scroll-padding-top:0}
/* Items in a line of points never break inside; a line never starts with the dot. */
#story .it{white-space:nowrap}
/* Form errors in the phone: small, so the button stays on its screen. */
.pform .tf-err{font-size:12px;line-height:1.3;margin-top:3px}
.pform .tf-err svg{width:13px;height:13px}
/* With error lines showing, the app's header lines give them room, so 'Call me now' stays on the phone's screen. */
.pform:has(.tf-err:not([hidden])) :is(.papp,.papp-h,.papp-p){display:none}
.pform:has(.tf-err:not([hidden])) .tf-card{margin-top:0}
.pform:has(.tf-err:not([hidden])) .tf-biz:not(.is-open) .tf-addbiz{display:none}
.pform:has(.tf-err:not([hidden])) .tf-err{font-size:11.5px;line-height:1.25;margin-top:2px}
.pform:has(.tf-err:not([hidden])) .tf-grid{gap:6px}
.pform:has(.tf-err:not([hidden])) .tf-label{margin-bottom:2px}
.pform:has(.tf-err:not([hidden])) .tf-consent{padding-top:6px;padding-bottom:6px}
/* The phone's form never shows the preview status line (the words beside the phone follow the call). */
.pform:not(.is-notcalled) .tf-status{display:none!important}
.pform.is-notcalled .tf-again{display:none}   /* ("Start over" is beside the phone) */
/* No WebGL: the poster, the words and the form still work. */
html.hs-nogl #gl{display:none}
/* No 3D at all (no WebGL, or the 3D code could not load): the story becomes a plain section, its words in order. */
html.hs-flow #story{height:auto}
html.hs-flow #stage{position:relative;height:auto;overflow:visible;padding:40px 0 24px}
html.hs-flow :is(#gl,#poster,.rail,.pov,.dots,.skipdemo,.pform,.cue4,.hud){display:none!important}
html.hs-flow .flow-try{display:inline-flex;align-items:center;min-height:48px;margin:20px 0 0;padding:0 22px;border-radius:12px;background:var(--primary);color:#03141c;font:700 16px/1.2 var(--font-b);text-decoration:none}
html.hs-flow #txt{position:relative;inset:auto;contain:none;pointer-events:auto;max-width:760px;margin:0 auto;padding:0 20px}
html.hs-flow .beat{position:relative!important;left:auto!important;top:auto!important;width:auto!important;opacity:1!important;visibility:visible!important;transform:none!important;margin:0 0 44px}
html.hs-flow :is(.w,.tail,.pt-d,.kick,.sub,.cue){opacity:1!important;visibility:visible!important;transform:none!important}
html.hs-flow .beat .kick{display:block!important}
html.hs-flow .feat{height:auto!important}
html.hs-flow .pt{position:relative;opacity:1!important;visibility:visible!important;margin:0 0 16px}

/* ---------- On the homepage ---------- */
/* While the story is on screen, the sticky header drops its blur (a blur over the 3D canvas costs every frame). */
html.hs-in-story .site-header{-webkit-backdrop-filter:none;backdrop-filter:none;background:rgba(10,10,15,.97)}
/* The next section peeks in under the demo (the story leaves --hs-peek free at the bottom of its last step; the extra
   lvh-svh keeps the strip in view while a phone's toolbars show). */
#what-we-do[data-hs-peek]{position:relative;z-index:3;will-change:opacity;margin-top:calc(-1 * var(--hs-peek, 0px) - (100lvh - 100svh));padding-top:28px;background:#0a0a0f}
#what-we-do[data-hs-peek]::before{content:"";position:absolute;left:0;right:0;top:-36px;height:36px;background:linear-gradient(rgba(10,10,15,0),#0a0a0f);pointer-events:none}
@supports not (height:100svh){#what-we-do[data-hs-peek]{margin-top:calc(-1 * var(--hs-peek, 0px))}}
/* A compact heading, so the section itself shows in the strip. */
#what-we-do[data-hs-peek] .section__head{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 22px;max-width:none;margin-bottom:18px}
#what-we-do[data-hs-peek] .section__head h2{margin:0}
#what-we-do[data-hs-peek] .section__head .lead{margin:0}
@media(max-width:719px){#what-we-do[data-hs-peek]{padding-top:20px}#what-we-do[data-hs-peek] .section__head{margin-bottom:12px}}
/* Touch screens snap the page's own scrolling to the story's steps (html.hs-snapping, see the engine). Around it:
   the hero can still be read to its end, and the next section is the next stop after the demo (below its top the
   snapping lets go). The header is sticky, so that section's snap position leaves room for it. */
html.hs-snapping .home-hero{scroll-snap-align:end}
html.hs-snapping #what-we-do[data-hs-peek]{scroll-snap-align:start}
#what-we-do[data-hs-peek]{scroll-margin-top:var(--header-h,64px)}
/* Focusing a header link inside the 5rem scroll padding scrolls the page, which would move the story a step. */
html.hs-in-story{scroll-padding-top:0}
/* The phone menu and the dialogs lock scrolling on the page itself. (The site locks <body>, which - with
   overflow-x:clip on the page - turns <body> into its own scroller and unpins the sticky header and the story.) */
html:has(body.menu-open),html.hcdf-dialog-open,html.ai-demo-open{overflow:hidden}
body.menu-open,html.hcdf-dialog-open body,html.ai-demo-open body{overflow:visible;overflow-x:clip}

/* ---------- The demo form ---------- */
/* Haven City Digital: "Hear it for yourself" demo form (story v6, SPEC 7). Pairs with try-form.js.
   Everything is scoped under .tf. The host loads the fonts (Space Grotesk 700, Plus Jakarta Sans 400–700)
   and sets the column width; data-layout="side" | "tight" | "stacked" picks the variant. */

.tf {
  --tf-page: #0a0a0f;
  --tf-card: #12161d;
  --tf-line: rgba(255, 255, 255, .10);
  --tf-text: #eceef3;
  --tf-text-2: rgba(236, 238, 243, .78);
  --tf-muted: rgba(236, 238, 243, .64);
  --tf-primary: #35c7ff;
  --tf-primary-hover: #6ad6ff;
  --tf-primary-press: #22b4ee;
  --tf-on-primary: #04121c;
  --tf-ring: rgba(53, 199, 255, .42);
  --tf-err: #ff9b9b;
  --tf-err-line: #ef5f5f;
  --tf-amber: #ffd28a;
  --tf-field-h: 52px;
  --tf-btn-h: 56px;
  --tf-pad: 24px;
  --tf-gap: 18px;
  --tf-sans: 'Plus Jakarta Sans', system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --tf-head: 'Space Grotesk', 'Plus Jakarta Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;

  position: relative;
  color: var(--tf-text);
  font-family: var(--tf-sans);
  font-size: 16px;
  line-height: 1.45;
  word-spacing: .04em; /* Plus Jakarta's word space is narrow at small sizes */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}
/* Resets use :where() so they never outrank the component's own classes. */
:where(.tf) *, :where(.tf) *::before, :where(.tf) *::after { box-sizing: border-box; }
:where(.tf) :where(p, h2, ol) { margin: 0; padding: 0; }
:where(.tf) svg { display: block; flex: none; }
.tf [hidden] { display: none !important; }
.tf-sr {
  position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.tf-nb { white-space: nowrap; }

/* ---------- Heading block ---------- */
.tf-kicker {
  font: 600 14px/1.3 var(--tf-sans);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--tf-primary);
  margin-bottom: 14px;
}
@media (min-width: 1600px) { .tf-kicker { font-size: 15px; } }
.tf-h2 {
  font-family: var(--tf-head);
  font-weight: 700;
  font-size: clamp(40px, 3.2vw, 64px);
  line-height: 1.04;
  letter-spacing: -.03em;
  word-spacing: 0;
  color: #fff;
  white-space: nowrap;
}
.tf-sub {
  margin-top: 14px;
  font-size: 18px;
  line-height: 1.5;
  color: var(--tf-text-2);
  max-width: 34em;
  text-wrap: pretty;
}
/* Side layouts: one sentence per line */
.tf:not([data-layout="stacked"]) .tf-sub > span { display: block; }
.tf-trust {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
  margin-top: 14px;
  font: 500 14px/1.4 var(--tf-sans);
  color: var(--tf-muted);
}
.tf-stars { display: inline-flex; gap: 1px; color: #f7b928; }
.tf-stars svg { width: 15px; height: 15px; }
.tf-trust > span:nth-child(2) { color: var(--tf-text); font-weight: 600; }
.tf-dot { color: rgba(236, 238, 243, .38); }

/* ---------- Preview notice (above the button on side, above the card on phones, a line in tight) ---------- */
.tf-notice {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 11px 14px;
  border-radius: 10px;
  background: rgba(255, 190, 90, .10);
  border: 1px solid rgba(255, 190, 90, .36);
  color: var(--tf-amber);
  font: 600 14px/1.45 var(--tf-sans);
}
.tf-notice svg { width: 17px; height: 17px; margin-top: 1.5px; }
/* After a valid submit the status says "Preview", so the in-card notice and its slot step aside */
.tf.has-status .tf-card .tf-slot { display: none; }

/* ---------- Card ---------- */
.tf-card {
  container: tfcard / inline-size;
  display: flex;
  flex-direction: column;
  gap: var(--tf-gap);
  margin-top: 28px;
  padding: var(--tf-pad);
  background: var(--tf-card);
  border: 1px solid var(--tf-line);
  border-radius: 16px;
  box-shadow: 0 1px 0 rgba(255, 255, 255, .04) inset, 0 24px 48px -28px rgba(0, 0, 0, .75);
}
.tf-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--tf-gap); }
@container tfcard (min-width: 380px) {
  .tf-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: 14px; }
}
.tf-slot:empty { display: none; }

/* ---------- Fields ---------- */
.tf-label {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 8px;
  font: 600 14px/20px var(--tf-sans);
  color: var(--tf-text);
}
.tf-opt { font-weight: 500; font-size: 13px; color: var(--tf-muted); }

.tf-control { position: relative; display: flex; border-radius: 10px; }
.tf-input {
  display: block;
  flex: 1 1 auto;
  width: 100%;
  min-width: 0;
  height: var(--tf-field-h);
  margin: 0;
  padding: 0 14px;
  border: 1px solid #cfd6e0;
  border-radius: 10px;
  background: #fff;
  color: #0b1220;
  font: 500 16px/1.25 var(--tf-sans);
  letter-spacing: 0;
  color-scheme: light;
  caret-color: #0b1220;
  outline: none;
  -webkit-appearance: none;
  appearance: none;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .18);
  transition: border-color .15s ease, box-shadow .15s ease, background-color .15s ease;
}
.tf-input::placeholder { color: #6b7588; opacity: 1; font-weight: 400; }
.tf-input:hover { border-color: #aeb8c6; }
.tf-input:focus { border-color: var(--tf-primary); box-shadow: 0 0 0 3px var(--tf-ring); }
.tf-input:-webkit-autofill { -webkit-text-fill-color: #0b1220; box-shadow: 0 0 0 40px #eef8ff inset; }
.tf-input:-webkit-autofill:focus { box-shadow: 0 0 0 40px #eef8ff inset, 0 0 0 3px var(--tf-ring); }
.tf-input[readonly] { background: #f3f5f8; color: #3a4456; }
.tf-input[readonly]:focus { border-color: #cfd6e0; box-shadow: none; }

/* Mobile number: a fixed +1 segment joined to the input */
.tf-tel { box-shadow: 0 1px 2px rgba(0, 0, 0, .18); transition: box-shadow .15s ease; }
.tf-cc {
  flex: none;
  display: flex;
  align-items: center;
  height: var(--tf-field-h);
  padding: 0 12px 0 14px;
  border: 1px solid #cfd6e0;
  border-right: 0;
  border-radius: 10px 0 0 10px;
  background: #f1f4f8;
  color: #0b1220;
  font: 600 16px/1 var(--tf-sans);
  cursor: text;
  user-select: none;
  transition: border-color .15s ease;
}
.tf-tel .tf-input {
  border-radius: 0 10px 10px 0;
  border-left-color: #dfe4eb;
  box-shadow: none;
  padding-left: 12px;
  font-variant-numeric: tabular-nums;
}
.tf-tel:hover .tf-cc, .tf-tel:hover .tf-input { border-color: #aeb8c6; border-left-color: #dfe4eb; }
.tf-tel:hover .tf-cc { border-left-color: #aeb8c6; }
.tf-tel:focus-within { box-shadow: 0 0 0 3px var(--tf-ring); }
.tf-tel:focus-within .tf-cc,
.tf-tel .tf-input:focus { border-color: var(--tf-primary); }
.tf-tel .tf-input:focus { border-left-color: #dfe4eb; box-shadow: none; }
.tf.is-locked .tf-tel:focus-within { box-shadow: none; }
.tf.is-locked .tf-tel:focus-within .tf-cc { border-color: #cfd6e0; }

/* Invalid */
.tf-field.is-invalid .tf-input,
.tf-field.is-invalid .tf-cc { border-color: var(--tf-err-line); }
.tf-field.is-invalid .tf-tel .tf-input { border-left-color: #f3c4c4; }
.tf-field.is-invalid .tf-input:focus,
.tf-field.is-invalid .tf-tel:focus-within { box-shadow: 0 0 0 3px rgba(239, 95, 95, .32); }
.tf-field.is-invalid .tf-tel .tf-input:focus { box-shadow: none; }

.tf-err {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  margin-top: 8px;
  font: 500 13px/1.4 var(--tf-sans);
  color: var(--tf-err);
}
.tf-err svg { width: 15px; height: 15px; margin-top: 1px; }

/* Business name: always shown on side layouts, behind a text button on phones */
.tf-addbiz { display: none; }
.tf[data-layout="stacked"] .tf-biz:not(.is-open) .tf-bizwrap { display: none; }
.tf[data-layout="stacked"] .tf-biz:not(.is-open) .tf-addbiz {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  margin: -8px 0 -10px -2px;
  padding: 0 6px 0 2px;
  border: 0;
  border-radius: 8px;
  background: none;
  color: var(--tf-primary);
  font: 600 15px/1.3 var(--tf-sans);
  text-align: left;
  cursor: pointer;
}
.tf-addbiz svg { width: 16px; height: 16px; }
.tf-addbiz:hover { color: var(--tf-primary-hover); }
.tf-addbiz:focus-visible { outline: 2px solid var(--tf-primary); outline-offset: 2px; }

/* ---------- Consent ---------- */
.tf-consent {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr);
  column-gap: 12px;
  row-gap: 6px;
  padding: 14px 16px;
  border-radius: 12px;
  background: rgba(255, 255, 255, .035);
  border: 1px solid rgba(255, 255, 255, .07);
  transition: border-color .15s ease;
}
.tf-consent.is-invalid { border-color: rgba(255, 155, 155, .55); }
.tf-check {
  grid-column: 1;
  grid-row: 1;
  position: relative;
  width: 22px;
  height: 22px;
  cursor: pointer;
}
/* 44 px hit area around the 22 px box */
.tf-check::before { content: ''; position: absolute; inset: -11px; }
.tf-check input {
  position: relative;
  display: block;
  width: 22px;
  height: 22px;
  margin: 0;
  accent-color: var(--tf-primary);
  color-scheme: light;
  cursor: pointer;
}
.tf-check input:focus-visible { outline: 2px solid var(--tf-primary); outline-offset: 3px; }
.tf.is-locked .tf-check, .tf.is-locked .tf-check input, .tf.is-locked .tf-consent__main { cursor: default; }
.tf-consent__main {
  grid-column: 2;
  grid-row: 1;
  font: 400 15px/1.45 var(--tf-sans);
  color: rgba(255, 255, 255, .88);
  cursor: pointer;
}
.tf-consent__detail {
  grid-column: 2;
  font: 400 13px/1.45 var(--tf-sans);
  color: rgba(255, 255, 255, .62);
}
.tf-consent .tf-err { grid-column: 2; margin-top: 2px; }

/* ---------- Alert (live errors only) ---------- */
.tf-alert {
  display: flex;
  gap: 8px;
  padding: 11px 14px;
  border-radius: 10px;
  background: rgba(255, 110, 110, .10);
  border: 1px solid rgba(255, 130, 130, .38);
  color: #ffc2c2;
  font: 500 14px/1.45 var(--tf-sans);
}
.tf-alert svg { width: 17px; height: 17px; margin-top: 1.5px; }

/* ---------- Button ---------- */
.tf-btn {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  height: var(--tf-btn-h);
  margin: 0;
  padding: 0 20px;
  border: 0;
  border-radius: 12px;
  background: var(--tf-primary);
  color: var(--tf-on-primary);
  font: 700 17px/1 var(--tf-sans);
  letter-spacing: -.005em;
  cursor: pointer;
  box-shadow: 0 1px 0 rgba(255, 255, 255, .35) inset, 0 -1px 0 rgba(0, 0, 0, .14) inset, 0 8px 20px -12px rgba(0, 0, 0, .8);
  transition: background-color .15s ease, transform .08s ease;
  -webkit-tap-highlight-color: transparent;
}
.tf-btn:hover { background: var(--tf-primary-hover); }
.tf-btn:active { background: var(--tf-primary-press); transform: translateY(1px); }
.tf-btn:focus-visible { outline: 2px solid #e8f8ff; outline-offset: 2px; }
.tf-btn__ic { display: flex; }
.tf-btn__ic svg { width: 20px; height: 20px; }
.tf-spin {
  display: none;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2.5px solid rgba(4, 18, 28, .22);
  border-top-color: var(--tf-on-primary);
  animation: tf-spin .7s linear infinite;
}
.tf.is-busy .tf-btn { cursor: progress; }
.tf.is-busy .tf-btn:hover { background: var(--tf-primary); }
.tf.is-busy .tf-btn__ic { display: none; }
.tf.is-busy .tf-spin { display: block; }
@keyframes tf-spin { to { transform: rotate(360deg); } }

/* ---------- In-card status (replaces the button after a valid submit) ---------- */
.tf-status {
  display: grid;
  gap: 12px;
  padding: 14px 16px;
  border-radius: 12px;
  background: rgba(53, 199, 255, .07);
  border: 1px solid rgba(53, 199, 255, .36);
  outline: none;
}
.tf-status:focus-visible { outline: 2px solid #e8f8ff; outline-offset: 2px; }
.tf-status.is-in { animation: tf-in .26s cubic-bezier(.2, .8, .2, 1) both; }
@keyframes tf-in { from { opacity: 0; transform: translateY(6px); } }
.tf-status__top { display: flex; align-items: flex-start; gap: 12px; }
.tf-status__ic {
  position: relative;
  flex: none;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  margin-top: -3px;
  border-radius: 50%;
  background: var(--tf-primary);
  color: var(--tf-on-primary);
}
.tf-status__ic svg { width: 17px; height: 17px; }
.tf-status__ic [data-ic-check] { display: none; }
.tf-status[data-phase="booked"] .tf-status__ic [data-ic-phone] { display: none; }
.tf-status[data-phase="booked"] .tf-status__ic [data-ic-check] { display: block; }
.tf-status[data-phase="calling"] .tf-status__ic::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2px solid var(--tf-primary);
  animation: tf-ring 1.5s ease-out infinite;
}
@keyframes tf-ring { from { transform: scale(1); opacity: .7; } to { transform: scale(1.7); opacity: 0; } }
.tf-status__msg { font: 600 16px/1.45 var(--tf-sans); color: #fff; padding-top: 1px; }
.tf-status__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 16px;
  padding-left: 44px;
}
.tf-steps { display: flex; flex-wrap: wrap; gap: 6px 16px; list-style: none; }
.tf-steps li {
  display: flex;
  align-items: center;
  gap: 7px;
  font: 600 13px/1.3 var(--tf-sans);
  color: rgba(236, 238, 243, .5);
}
.tf-steps li::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(236, 238, 243, .28);
}
.tf-steps li.is-now { color: var(--tf-text); }
.tf-steps li.is-now::before { background: var(--tf-primary); box-shadow: 0 0 0 3px rgba(53, 199, 255, .25); }
.tf-steps li.is-done { color: var(--tf-text-2); }
.tf-steps li.is-done::before { background: var(--tf-primary); }
.tf-again {
  height: 40px;
  padding: 0 14px;
  margin: -2px 0;
  border: 1px solid rgba(255, 255, 255, .2);
  border-radius: 10px;
  background: transparent;
  color: var(--tf-text);
  font: 600 14px/1 var(--tf-sans);
  cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease;
}
.tf-again:hover { background: rgba(255, 255, 255, .06); border-color: rgba(255, 255, 255, .32); }
.tf-again:focus-visible { outline: 2px solid #e8f8ff; outline-offset: 2px; }

/* ---------- Under the button ---------- */
.tf-under {
  margin-top: -4px;
  font: 400 13px/1.45 var(--tf-sans);
  color: var(--tf-muted);
  text-align: center;
}
.tf-under .tf-dot { margin: 0 7px; }
.tf-under a {
  color: var(--tf-text);
  font-weight: 600;
  text-decoration: underline;
  text-decoration-color: rgba(236, 238, 243, .32);
  text-underline-offset: 3px;
  white-space: nowrap;
}
.tf-under a:hover { color: var(--tf-primary); text-decoration-color: currentColor; }
.tf-under a:focus-visible { outline: 2px solid var(--tf-primary); outline-offset: 2px; border-radius: 3px; }

/* ---------- Tight (side layouts under 720 px of usable height) ---------- */
.tf[data-layout="tight"] { --tf-field-h: 48px; --tf-btn-h: 52px; --tf-pad: 18px; --tf-gap: 14px; }
.tf[data-layout="tight"] .tf-kicker,
.tf[data-layout="tight"] .tf-trust { display: none; }
.tf[data-layout="tight"] .tf-sub { margin-top: 10px; }
.tf[data-layout="tight"] .tf-card { margin-top: 20px; }
.tf[data-layout="tight"] .tf-label { margin-bottom: 6px; }
.tf[data-layout="tight"] .tf-consent { padding: 12px 14px; }
.tf[data-layout="tight"] .tf-consent__main { font-size: 14.5px; }
/* The preview notice merges into the line under the button */
.tf[data-layout="tight"] .tf-slot .tf-notice {
  justify-content: center;
  gap: 7px;
  margin-top: -4px;
  padding: 0;
  border: 0;
  background: none;
  font-size: 13px;
  text-align: center;
}
.tf[data-layout="tight"] .tf-slot .tf-notice svg { width: 15px; height: 15px; margin-top: 1.5px; }
.tf[data-layout="tight"] .tf-slot + .tf-under { margin-top: -10px; }
.tf[data-layout="tight"] .tf-status { padding: 12px 14px; gap: 8px; }

/* ---------- Stacked (phones and tablets in portrait) ---------- */
.tf[data-layout="stacked"] { --tf-pad: 18px; --tf-gap: 16px; }
.tf[data-layout="stacked"] .tf-kicker,
.tf[data-layout="stacked"] .tf-trust { display: none; }
.tf[data-layout="stacked"] .tf-h2 { font-size: clamp(32px, 8.6vw, 34px); white-space: normal; }
.tf[data-layout="stacked"] .tf-sub { margin-top: 10px; font-size: 16px; }
.tf[data-layout="stacked"] > .tf-notice { margin-top: 16px; }
.tf[data-layout="stacked"] .tf-card { margin-top: 16px; }
.tf[data-layout="stacked"] .tf-status__row { padding-left: 0; }

@media (prefers-reduced-motion: reduce) {
  .tf-status.is-in, .tf-status[data-phase="calling"] .tf-status__ic::after { animation: none; }
  .tf-spin { animation-duration: 1.4s; }
  .tf-btn, .tf-input, .tf-tel, .tf-cc { transition: none; }
}
@media (forced-colors: active) {
  .tf-btn, .tf-again { border: 1px solid ButtonText; }
  .tf-input:focus, .tf-tel:focus-within { outline: 2px solid Highlight; }
}
