/* ---------------------------------------------------------------------------
   Barreleye OpEx product page: styles.

   One deliberate look, in the brochure's colours: deep-water dark bands, white
   and mist sections, one orange accent. It does not follow the viewer's dark
   mode, so every colour below is set explicitly. The fun lives in a few
   places on purpose: BOpEx Bob and the bubbles in the dark water, the
   pain points as a broken workbook, the questions typed into an AI agent's
   ask box, "What if?" as a chat with Claude, quotes as sticky notes, and
   buttons you can press. Everything decorative is aria-hidden and holds
   still for readers who ask for less motion.

   Every band keeps a 20px side gutter, and nothing may be wider than a 320px
   phone; check.mjs fails the page if anything scrolls sideways.
   --------------------------------------------------------------------------- */

@font-face{font-family:"Poppins";font-weight:400;font-display:swap;src:url(assets/Poppins-400.woff2) format("woff2")}
@font-face{font-family:"Poppins";font-weight:500;font-display:swap;src:url(assets/Poppins-500.woff2) format("woff2")}
@font-face{font-family:"Poppins";font-weight:600;font-display:swap;src:url(assets/Poppins-600.woff2) format("woff2")}
/* Raleway is two static weights, not the variable font they were cut from:
   that file's default instance is Thin, so any browser that missed the weight
   axis (Safari's engine did, on test) drew hairline body text and no bold. */
@font-face{font-family:"Raleway";font-weight:400;font-display:swap;src:url(assets/Raleway-400.woff2) format("woff2")}
@font-face{font-family:"Raleway";font-weight:700;font-display:swap;src:url(assets/Raleway-700.woff2) format("woff2")}

/* Layout: one 1200px column; dark "deep water" bands alternate with white and
   mist; the hero screenshot overlaps into the section below it. */
:root{
  --ink:#141416;           /* deep water: hero, how-it-works, outcomes, CTA */
  --ink-2:#1D1E22;         /* cards on deep water */
  --ink-3:#2A2C31;         /* window chrome */
  --ink-line:#34363C;
  --paper:#FFFFFF;
  --mist:#EEF2F3;
  --line:#D9E0E3;
  --text:#24262A;
  --soft:#5B626B;
  --on-dark:#F2F3F4;
  --on-dark-soft:#A9AEB5;
  --accent:#F97316;
  --accent-deep:#C2410C;   /* orange text on white: 5.2:1 */
  --accent-wash:#FFF1E6;
  --accent-tint:rgba(249,115,22,.14);
  --accent-glow:rgba(249,115,22,.38);
  --error:#D94848;         /* the spreadsheet's #REF! red */
  --sticky:#FFE7CF;        /* sticky notes, an orange-tinted paper */

  --display:"Poppins","Trebuchet MS",system-ui,sans-serif;
  --body:"Raleway","Segoe UI",system-ui,sans-serif;
  --mono:ui-monospace,"Cascadia Mono","Consolas",monospace;

  --overlap:clamp(48px,11vw,150px);   /* how far the hero shot hangs below the hero */
  --radius:20px;
  color-scheme:light;
}

/* --- Base ----------------------------------------------------------------- */
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;background:var(--paper);color:var(--text);font-family:var(--body);font-size:17px;line-height:1.65;-webkit-text-size-adjust:100%}
img{max-width:100%;height:auto;display:block}
a{color:inherit}
h1,h2,h3{font-family:var(--display);line-height:1.15;margin:0;text-wrap:balance}
p,figure,blockquote,ul,ol{margin:0}
p{text-wrap:pretty}
:focus-visible{outline:3px solid var(--accent);outline-offset:3px;border-radius:6px}
.sprite{position:absolute;width:0;height:0;overflow:hidden}
.icon{width:1.25em;height:1.25em;flex-shrink:0;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.nowrap{white-space:nowrap}
/* Every :hover effect below sits in @media (hover:hover). A phone counts a tap
   as a hover and keeps it until the next tap, so a card would stay lifted, or
   a note straightened, after the reader had moved on. */

.skip{position:absolute;left:16px;top:-60px;z-index:50;background:var(--accent);color:var(--ink);padding:10px 16px;border-radius:10px;font-family:var(--display);text-decoration:none}
.skip:focus{top:16px}

/* --- Layout --------------------------------------------------------------- */
/* The page is drawn edge to edge (viewport-fit=cover), so on a phone held
   sideways the gutter grows to clear the notch and the rounded corners. */
.wrap{max-width:1200px;margin:0 auto;padding-inline:20px;padding-left:max(20px,env(safe-area-inset-left));padding-right:max(20px,env(safe-area-inset-right))}
section{padding-block:96px}
section[id]{scroll-margin-top:72px}
.dark{background:var(--ink);color:var(--on-dark)}
.grey{background:var(--mist)}
.split{display:grid;grid-template-columns:1fr 1fr;gap:56px;align-items:start}
.split > *{min-width:0}
.split.centred{align-items:center}
/* Running copy keeps a readable measure. Desktop columns are already
   narrower than this; it matters once a tablet stacks them full width. */
.problem-copy p,.why-item p,.feature .copy p{max-width:62ch}
@media (max-width:860px){
  section{padding-block:72px}
  .split{grid-template-columns:1fr;gap:40px}
}

/* Decoration layer: glows and bubbles, clipped to their section so nothing
   they do can widen the page. */
.deco{position:absolute;inset:0;overflow:hidden;pointer-events:none;z-index:-1;container-type:size}
.glow{position:absolute;border-radius:50%;filter:blur(70px);background:var(--accent-glow)}
.glow-a{width:520px;height:520px;right:-140px;top:-180px;opacity:.55}
.glow-b{width:380px;height:380px;left:-160px;bottom:12%;opacity:.25}
.glow-c{width:460px;height:460px;right:-200px;bottom:-160px;opacity:.35}
.glow-d{width:420px;height:420px;right:-120px;top:-160px;opacity:.6}
.bubble{position:absolute;left:var(--x);bottom:-24px;width:var(--s);height:var(--s);border-radius:50%;border:1.5px solid rgba(242,243,244,.35);background:radial-gradient(circle at 30% 30%,rgba(255,255,255,.35),rgba(255,255,255,.04) 60%);animation:rise var(--d) linear var(--t) infinite}
@keyframes rise{
  0%{transform:translate(0,0);opacity:0}
  10%{opacity:.9}
  50%{transform:translate(12px,-55cqh)}
  100%{transform:translate(-6px,-110cqh);opacity:0}
}

/* --- Type ----------------------------------------------------------------- */
.title{font-weight:600;font-size:clamp(30px,4.4vw,48px);letter-spacing:-.025em;color:var(--ink);margin-top:14px;max-width:22ch}
.dark .title{color:var(--on-dark)}
.eyebrow,.badge{display:inline-flex;align-items:center;gap:8px;padding:6px 14px 6px 10px;border-radius:999px;font-family:var(--display);font-weight:600;font-size:12px;line-height:1.4;letter-spacing:.14em;text-transform:uppercase;background:var(--accent-wash);color:var(--accent-deep)}
.eyebrow::before,.badge::before{content:"";width:7px;height:7px;border-radius:50%;background:currentColor}
.dark .eyebrow,.dark .badge{background:var(--accent-tint);color:var(--accent)}
.lede{font-size:19px;max-width:60ch;margin-top:18px;color:var(--soft)}
.dark .lede{color:var(--on-dark-soft)}
.num{font-family:var(--display);font-weight:600;font-size:15px;letter-spacing:.06em;color:var(--accent-deep)}
.dark .num{color:var(--accent)}

/* --- Buttons: pills you can press ----------------------------------------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;font-family:var(--display);font-weight:600;font-size:16px;line-height:1.3;text-align:center;text-decoration:none;border-radius:999px;padding:14px 26px;transition:transform .15s ease,box-shadow .15s ease,background-color .15s ease,border-color .15s ease}
.btn .icon{width:20px;height:20px;transition:transform .2s ease}
.btn-primary{background:var(--accent);color:var(--ink);box-shadow:0 4px 0 var(--accent-deep),0 14px 28px -12px var(--accent-glow)}
@media (hover:hover){.btn-primary:hover{transform:translateY(-2px);box-shadow:0 6px 0 var(--accent-deep),0 20px 36px -12px var(--accent-glow)}}
@media (hover:hover){.btn-primary:hover .icon{transform:translateX(4px)}}
.btn-primary:active{transform:translateY(3px);box-shadow:0 1px 0 var(--accent-deep),0 6px 14px -8px var(--accent-glow)}
.btn-ghost{border:1.5px solid rgba(242,243,244,.32);color:var(--on-dark);background:rgba(255,255,255,.03)}
@media (hover:hover){.btn-ghost:hover{border-color:var(--on-dark);background:rgba(255,255,255,.08)}}
@media (hover:hover){.btn-ghost:hover .icon{transform:translateY(2px)}}
/* 36px tall to sit right in the header, 44px to a thumb: the hit area reaches
   past the pill without drawing anything. */
.btn-sm{position:relative;font-size:14px;padding:9px 18px;box-shadow:0 3px 0 var(--accent-deep)}
.btn-sm::after{content:"";position:absolute;inset:-5px -2px}
@media (hover:hover){.btn-sm:hover{box-shadow:0 5px 0 var(--accent-deep)}}
.actions{display:flex;flex-wrap:wrap;gap:16px}
/* On a phone the pills stack full width, so the brochure's label stays on one line. */
@media (max-width:480px){
  .actions{flex-direction:column;align-items:stretch}
  .actions .btn{width:100%;font-size:15px;padding-inline:18px}
}

/* --- Header: sticky, frosted ---------------------------------------------- */
.site-header{position:sticky;top:env(safe-area-inset-top,0px);z-index:20;background:rgba(20,20,22,.94);-webkit-backdrop-filter:saturate(1.4) blur(14px);backdrop-filter:saturate(1.4) blur(14px);border-bottom:1px solid rgba(255,255,255,.07)}
.top{display:flex;align-items:center;justify-content:space-between;gap:12px;padding-block:14px}
/* The logo and the nav links get 44px-tall hit areas from padding, taken
   back by a negative margin so the bar stays the same height. */
.brand{flex-shrink:1;min-width:0;display:block;padding-block:10px;margin-block:-10px}
/* The Barreleye OpEx logo is 8.3:1, so at its full 34px it is 283px wide:
   wider than the room beside the button on a phone, and 1px wider than the
   room beside the links at 761px. So it is sized by width, and the link
   shrinks to the room there is: the logo (max-width:100%, height:auto)
   shrinks with it, to 139px at 320px, and is never squashed. */
.brand img{width:283px}
.top nav{display:flex;flex-shrink:0;gap:26px;align-items:center;font-family:var(--display);font-size:15px}
.top nav .link{text-decoration:none;color:var(--on-dark-soft);transition:color .15s;padding-block:10px;margin-block:-10px}
@media (hover:hover){.top nav .link:hover{color:var(--accent)}}
@media (max-width:760px){.top nav .link{display:none}}

/* --- Hero ----------------------------------------------------------------- */
.hero{position:relative;z-index:1;isolation:isolate;padding-block:72px 0;--bob-width:clamp(150px,17vw,200px)}
/* The column gap is Bob's clear space from the copy: .29 of his width, less
   the .02 his outline sits inside his SVG's box, rounded up. */
.hero-grid{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:32px calc(var(--bob-width) * .28);align-items:center}
/* The heading is the Barreleye OpEx logo, the one in the navbar, at 720px
   (87px tall) or the column's width if that is less. The logo is cropped
   to its ink, so it gets the room a line of type would have had round it. */
.hero-logo{margin-block:28px 4px}
.hero-logo img{width:min(100%,720px)}
.hero .sub{font-family:var(--display);font-weight:400;font-size:clamp(19px,2.4vw,24px);color:var(--on-dark-soft);margin-top:22px}
.hero .hook{font-size:19px;max-width:58ch;margin-top:20px;color:var(--on-dark)}
.hero .actions{margin-top:34px}
/* "Watch the video" sits beside the two pills without becoming a third: a
   plain link behind a ring with the play mark. */
.watch{display:inline-flex;align-items:center;gap:12px;font-family:var(--display);font-weight:600;font-size:16px;color:var(--on-dark);text-decoration:none;padding-right:6px}
.watch-play{display:grid;place-items:center;width:52px;height:52px;border-radius:50%;border:1.5px solid rgba(242,243,244,.32);color:var(--accent);transition:transform .2s ease,border-color .2s ease,background-color .2s ease}
.watch-play .icon{width:21px;height:21px;fill:currentColor;stroke:none;margin-left:3px}
.watch-time{font-weight:400;color:var(--on-dark-soft)}
@media (hover:hover){.watch:hover .watch-play{transform:scale(1.08);border-color:var(--accent);background:var(--accent-tint)}}
@media (max-width:480px){.actions .watch{justify-content:center}}
.hero-shot{margin-top:64px;margin-bottom:calc(-1 * var(--overlap));position:relative;z-index:2;box-shadow:0 60px 120px -40px rgba(0,0,0,.75),0 0 0 1px rgba(255,255,255,.06),0 0 160px -30px var(--accent-glow)}
/* A narrow shot gets a shadow to match: the full one spreads 120px and lays a
   grey haze across the white section below. */
@media (max-width:860px){.hero-shot{margin-top:48px;box-shadow:0 24px 48px -24px rgba(0,0,0,.6),0 0 0 1px rgba(255,255,255,.06),0 0 80px -30px var(--accent-glow)}}

/* BOpEx Bob, the mascot (brand/BOpEx-Bob_mascot-guidelines.pdf). The page
   carries his master SVG unchanged, so everything he does is done here. Each
   pose in the guide is the master with one part moved, and these moves match
   the guide's own pictures of him to the pixel:
     looking ahead  each eye tilts 22deg on the foot of its tube, and its
                    pupil slides 17 units up the tube to the tip;
     looking up     the pupils slide 18 units up, the tubes upright;
     fin flap       the side fin gives way to the pose's own fin, .fin-flap.
   By the guide: the white-line version only ever sits on the dark water, and
   he keeps clear space of half his height round him. Drawn, fin flapped, he
   is .585 of his width tall, so that is .29 of his width. */
.bob{display:block;height:auto;overflow:visible}
.bob .eye{transform-box:fill-box;transform-origin:50% 100%}
.bob .fin-flap{opacity:0}
/* His fin flaps as he swims: twice, quickly, every six seconds. It swaps
   whole, as the guide draws it, rather than tweening through shapes he never
   takes. */
.bob .fin{animation:fin-rest 6s step-end 1.2s infinite}
.bob .fin-flap{animation:fin-flap 6s step-end 1.2s infinite}
@keyframes fin-rest{0%{opacity:0}5%{opacity:1}10%{opacity:0}15%{opacity:1}}
@keyframes fin-flap{0%{opacity:1}5%{opacity:0}10%{opacity:1}15%{opacity:0}}
/* In the hero he bobs beside the headline, and every twelve seconds looks
   ahead at it for a few seconds: his signature move. */
.hero-bob{width:var(--bob-width);margin-top:-40px;animation:bob 6s ease-in-out infinite}
.hero-bob .eye{animation:look-ahead 12s ease-in-out infinite}
.hero-bob .ball{animation:look-ahead-pupil 12s ease-in-out infinite}
@keyframes look-ahead{0%,40%,80%,100%{transform:none}46%,74%{transform:rotate(-22deg)}}
@keyframes look-ahead-pupil{0%,40%,80%,100%{transform:none}46%,74%{transform:translateY(-17px)}}
@keyframes bob{50%{transform:translateY(-12px) rotate(-3deg)}}
@media (max-width:860px){.hero-grid{grid-template-columns:1fr}.hero-bob{display:none}}

/* --- Problem: the workbook ------------------------------------------------ */
.problem{padding-top:calc(var(--overlap) + 96px)}
@media (max-width:860px){.problem{padding-top:calc(var(--overlap) + 72px)}}
.problem-copy{display:flex;flex-direction:column;gap:18px;align-items:flex-start}
.problem-copy .title{margin-top:0}
.lead{font-family:var(--display);font-size:21px;line-height:1.5;color:var(--ink)}
.sheet{border-radius:16px;background:var(--paper);border:1.5px solid var(--line);box-shadow:0 24px 48px -24px rgba(20,20,22,.28);overflow:hidden;transform:rotate(1.2deg);transition:transform .4s ease}
@media (hover:hover){.sheet:hover{transform:rotate(0)}}
.sheet-tab{display:flex;align-items:center;gap:8px;padding:10px 16px;background:var(--mist);border-bottom:1.5px solid var(--line);font-family:var(--mono);font-size:13px;color:var(--soft);overflow-wrap:anywhere}
.sheet-tab .icon{color:var(--accent-deep);width:18px;height:18px}
.sheet-body{padding:22px 24px 26px}
.sheet-title{font-family:var(--display);font-weight:600;font-size:13px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink)}
.pains{list-style:none;padding:0;margin-top:14px;display:flex;flex-direction:column;counter-reset:row}
.pains li{display:grid;grid-template-columns:auto 1fr;gap:6px 14px;align-items:start;padding-block:14px;border-top:1px dashed var(--line);counter-increment:row}
.pains li > span:last-child{min-width:0}
.pains b{color:var(--ink)}
.err{display:inline-block;min-width:72px;text-align:center;font-family:var(--mono);font-size:12.5px;font-weight:700;color:var(--error);background:#FDECEC;border:1px solid #F4C7C7;border-radius:6px;padding:2px 8px;margin-top:3px}
/* Centred on the ink, not the glyph boxes. A monospace "!" is a thin stroke in
   the middle of a full cell, so a code ending in one reads 1-1.5px left of
   centre in every font; .bang moves it back by a share of a cell. Trimmed to
   the capitals, the code sits mid-height whatever the font's line metrics;
   without text-box it is within a pixel anyway. */
.err.bang{padding-inline:calc(8px + .15ch) calc(8px - .15ch)}
@supports (text-box:trim-both cap alphabetic){.err{text-box:trim-both cap alphabetic;padding-block:8px}}
@media (max-width:860px){.sheet{transform:none}}
@media (max-width:420px){.pains li{grid-template-columns:1fr}.err{justify-self:start}}

/* The video card: the explainer's cover in a sticker frame, like the feature
   screenshots but square to the page, with a play button you can press. The
   whole card is the link. */
.video-card{display:grid;grid-template-columns:7fr 5fr;gap:56px;align-items:center;margin-top:88px;color:inherit;text-decoration:none}
.video-card > *{min-width:0}
.video-thumb{position:relative;display:block;border-radius:16px;overflow:hidden;border:2px solid var(--ink);box-shadow:12px 12px 0 var(--accent);transition:transform .3s ease}
.video-thumb img{width:100%;aspect-ratio:16/9;object-fit:cover}
/* Centred in the open water above the engineers' heads, not on them. */
.play-button{position:absolute;left:50%;top:35%;display:grid;place-items:center;width:clamp(64px,9vw,92px);aspect-ratio:1;border-radius:50%;background:var(--accent);color:var(--ink);transform:translate(-50%,-50%);box-shadow:0 6px 0 var(--accent-deep),0 18px 36px -12px rgba(20,20,22,.5);transition:transform .2s ease}
.play-button .icon{width:42%;height:42%;fill:currentColor;stroke:none;margin-left:6%}
/* A ring ripples out from the button; it holds still for less motion. */
.play-button::after{content:"";position:absolute;inset:-2px;border-radius:50%;border:3px solid var(--accent);animation:ripple 2.4s ease-out infinite}
@keyframes ripple{from{transform:scale(1);opacity:.8}to{transform:scale(1.6);opacity:0}}
.video-length{position:absolute;right:12px;bottom:12px;padding:3px 9px;border-radius:6px;background:rgba(20,20,22,.85);color:var(--on-dark);font-family:var(--mono);font-size:13px;font-weight:700}
.video-card-copy{display:flex;flex-direction:column;gap:16px;align-items:flex-start}
.video-card-title{font-family:var(--display);font-weight:600;font-size:clamp(26px,3.2vw,36px);line-height:1.15;letter-spacing:-.02em;color:var(--ink);text-wrap:balance}
.video-card-cta{display:inline-flex;align-items:center;gap:10px;font-family:var(--display);font-weight:600;font-size:16px;color:var(--accent-deep)}
.video-card-cta .icon{width:18px;height:18px;fill:currentColor;stroke:none}
@media (hover:hover){.video-card:hover .video-thumb{transform:translateY(-4px)}}
@media (hover:hover){.video-card:hover .play-button{transform:translate(-50%,-50%) scale(1.08)}}
@media (hover:hover){.video-card:hover .video-card-cta{text-decoration:underline;text-underline-offset:4px}}
/* It keeps its two columns down to 640px: stacked on a tablet or a phone held
   sideways, the cover alone filled the screen. */
@media (max-width:860px){
  .video-card{gap:32px;margin-top:64px}
  .video-thumb{box-shadow:8px 8px 0 var(--accent)}
}
@media (max-width:640px){.video-card{grid-template-columns:1fr;gap:28px}}

/* --- The sticker strip ---------------------------------------------------- */
.band-wrap{overflow:hidden;padding-block:28px}
.band{background:linear-gradient(100deg,var(--accent),#FB8A3C);color:var(--ink);transform:rotate(-1.6deg);margin-inline:-24px;box-shadow:0 10px 0 var(--ink)}
/* The strip overhangs the page by 24px a side, so its content is inset 44px
   to keep the page's 20px gutter. The wrapped lines are spaced for the circle,
   which reaches above "Completely." into the line over it. */
.band-inner{display:flex;align-items:center;justify-content:space-between;gap:24px;padding-block:34px;padding-inline:44px;padding-left:max(44px,calc(env(safe-area-inset-left) + 24px));padding-right:max(44px,calc(env(safe-area-inset-right) + 24px))}
.band p{font-family:var(--display);font-weight:500;font-size:clamp(20px,2.8vw,30px);line-height:1.7;min-width:0;text-wrap:balance}
.circled{position:relative;font-weight:700;white-space:nowrap;margin-left:.25em}
.circled svg{position:absolute;left:-7%;top:-18%;width:114%;height:144%;fill:none;stroke:var(--ink);stroke-width:2.5;stroke-linecap:round;overflow:visible}
.band-fish{height:56px;width:auto;flex-shrink:0;filter:brightness(0);animation:bob 5s ease-in-out infinite}
/* On a phone the fish swims above the sentence rather than beside it, which
   took a third of the width and squeezed the line to a word or two. */
@media (max-width:560px){
  .band-inner{flex-direction:column;align-items:flex-start;gap:12px}
  .band-fish{order:-1;height:40px}
}
/* From 1060px the sentence stays on one line beside the fish, never leaving
   "game. Completely." on a line of its own. It is 42.4em long, plus the
   circle's overhang, so the type scales with the window to leave room for the
   insets, the fish and the gap (20px at 1060px, 30px from 1490px), and the
   pair is centred in the strip's full width rather than held to the page
   column. Narrower, the lines are balanced instead. */
@media (min-width:1060px){
  .band-inner{max-width:none;justify-content:center}
  .band p{white-space:nowrap;line-height:1.3;font-size:min(30px,calc((100vw - 200px) / 43))}
}

/* --- Questions: an ask box, and the questions put to it ------------------- */
/* The box is an AI agent's ask box, held in focus, that ask.js types each
   question into in turn; the cards under it are the questions themselves.
   It starts hidden, so without the script the cards stand alone. */
.ask{display:flex;gap:14px;margin-top:44px;padding:12px;background:var(--paper);border:1.5px solid var(--accent);border-radius:30px;box-shadow:0 0 0 5px var(--accent-tint),0 20px 40px -24px rgba(20,20,22,.35)}
.ask[hidden]{display:none}
.ask-mark,.ask-send{flex-shrink:0;display:grid;place-items:center;width:46px;height:46px;border-radius:50%}
.ask-mark{background:var(--ink);color:var(--accent)}
.ask-mark .icon{width:24px;height:24px}
/* Send waits greyed out until a question is written, then lights up like the
   page's buttons, and is pressed as the question goes. */
.ask-send{align-self:flex-end;background:var(--mist);color:var(--soft);transition:background-color .2s ease,color .2s ease,box-shadow .2s ease,transform .12s ease}
.ask-send .icon{width:22px;height:22px;transform:rotate(-90deg)}
.ask.is-ready .ask-send{background:var(--accent);color:var(--ink);box-shadow:0 3px 0 var(--accent-deep)}
.ask.is-sent .ask-send{transform:translateY(3px);box-shadow:0 0 0 var(--accent-deep)}
/* Every question sits invisibly in the typed text's grid cell, so the box is
   as tall as the longest of them at any width and the cards never move as it
   types. Each carries the caret's width too, so a caret at the end of a full
   line wraps in the box only if it would have wrapped there. check.mjs holds
   the box to one height through every letter of every question. */
.ask-field{flex:1;min-width:0;display:grid;align-items:start;padding:8px 4px;font-family:var(--display);font-size:19px;line-height:1.55;color:var(--ink)}
.ask-field > *{grid-area:1/1}
.ask-sizer{visibility:hidden}
.ask-typed{transition:opacity .3s ease,transform .3s ease}
.ask-typed::after,.ask-sizer::after{content:"";display:inline-block;width:2px;height:1.1em;margin-left:3px;vertical-align:-.18em;background:var(--accent)}
/* The caret blinks while it waits, never while it types. */
.ask-typed::after{animation:caret 1.1s step-end infinite}
.ask.is-typing .ask-typed::after{animation:none}
@keyframes caret{50%{opacity:0}}
/* Sent, the question floats up out of the box. */
.ask.is-sent .ask-typed{opacity:0;transform:translateY(-8px)}
.prompts{list-style:none;padding:0;margin-top:30px;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px}
.prompt{display:flex;flex-direction:column;align-items:center;gap:14px;padding:24px 22px 26px;text-align:center;background:var(--paper);border:1.5px solid var(--line);border-radius:20px;font-family:var(--display);font-size:16.5px;line-height:1.5;color:var(--ink);transition:transform .3s ease,border-color .3s ease,background-color .3s ease,box-shadow .3s ease}
.prompt::before{content:"?";display:grid;place-items:center;width:46px;height:46px;border-radius:50%;background:var(--ink);color:var(--accent);font-weight:600;font-size:22px;transition:background-color .3s ease,color .3s ease}
/* The question in the box: its card lifts and turns orange. */
.prompt.is-asked{transform:translateY(-4px);border-color:var(--accent);background:var(--accent-wash);box-shadow:0 16px 30px -20px var(--accent-glow)}
.prompt.is-asked::before{background:var(--accent);color:var(--ink)}
@media (max-width:960px){.prompts{grid-template-columns:repeat(2,minmax(0,1fr))}}
/* On a phone the question gets the box's full width, with the sparkle and
   Send in a row under it, as a phone's own ask boxes have them: beside it,
   they left the longest question six lines in a column half the screen wide. */
@media (max-width:560px){
  .ask{flex-wrap:wrap;justify-content:space-between;gap:6px;padding:12px;border-radius:24px}
  .ask-field{order:-1;flex-basis:100%;font-size:16.5px;padding:2px 6px}
  .ask-mark,.ask-send{width:40px;height:40px}
  .ask-mark .icon{width:21px;height:21px}
  .ask-send .icon{width:19px;height:19px}
  /* Stacked in one column the six cards run long, and the box above already
     says these are questions, so the cards lose their "?" here. */
  .prompts{grid-template-columns:1fr;gap:12px}
  .prompt{padding:16px 18px}
  .prompt::before{display:none}
}

/* --- How it works: three joined steps ------------------------------------- */
/* Clipped so the screenshot's shadow ends at the section's edge instead of
   greying the top of the white section after it. */
.glance{position:relative;isolation:isolate;overflow:hidden}
.steps{list-style:none;padding:0;margin-top:48px;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:28px;counter-reset:step}
.step{position:relative;background:var(--ink-2);border:1px solid var(--ink-line);border-radius:var(--radius);padding:26px 26px 28px;transition:border-color .2s,transform .2s}
@media (hover:hover){.step:hover{border-color:rgba(249,115,22,.55);transform:translateY(-3px)}}
/* The arrow between steps: they are a real sequence, load then write then get. */
.step:not(:last-child)::after{content:"";position:absolute;top:50%;right:-22px;width:16px;height:16px;border-top:2.5px solid var(--accent);border-right:2.5px solid var(--accent);transform:translateY(-50%) rotate(45deg);z-index:1}
.step h3{font-weight:600;font-size:21px;color:var(--on-dark);margin-top:18px}
.step p{margin-top:8px;color:var(--on-dark-soft)}
/* The steps, the feature cards and the outcomes centre everything in them
   under the icon. */
.step,.card,.outcome{text-align:center}
.icon-badge{display:inline-grid;place-items:center;width:52px;height:52px;border-radius:15px;background:var(--accent-wash);color:var(--accent-deep)}
.icon-badge .icon{width:26px;height:26px}
.dark .icon-badge{background:var(--accent-tint);color:var(--accent)}
.glance-shot{margin-top:56px;box-shadow:0 50px 100px -40px rgba(0,0,0,.8),0 0 0 1px rgba(255,255,255,.06),0 0 140px -40px var(--accent-glow)}
@media (max-width:860px){
  .steps{grid-template-columns:1fr;gap:30px}
  /* Stacked, the arrow points down from the middle of each step to the next. */
  .step:not(:last-child)::after{top:auto;right:auto;left:calc(50% - 8px);bottom:-24px;transform:rotate(135deg)}
}

/* Screenshots sit in an app window; each opens full size in the viewer. */
.frame{border-radius:16px;overflow:hidden;background:var(--ink-3);border:1px solid var(--ink-line);min-width:0}
.frame .bar{display:flex;gap:7px;padding:11px 14px;background:var(--ink-3)}
.frame .bar i{width:10px;height:10px;border-radius:50%;background:#55585e}
.frame .bar i:first-child{background:var(--accent)}
.frame a{display:block;cursor:zoom-in}
/* The frame clips to its rounded corners, which clipped a focus ring drawn
   outside the link to a sliver, so the ring is drawn just inside instead. */
.frame a:focus-visible{outline-offset:-3px;border-radius:0 0 14px 14px}

/* --- Ask Claude: the conversation ----------------------------------------- */
.convo{border-radius:24px;background:var(--mist);border:1.5px solid var(--line);overflow:hidden;box-shadow:0 30px 60px -30px rgba(20,20,22,.35)}
.convo-bar{display:flex;gap:7px;padding:12px 16px;background:var(--paper);border-bottom:1.5px solid var(--line)}
.convo-bar i{width:10px;height:10px;border-radius:50%;background:var(--line)}
.convo-body{display:flex;flex-direction:column;gap:18px;padding:28px clamp(18px,4vw,32px) 32px}
.you-say{align-self:flex-end;background:var(--accent);color:var(--ink);border-radius:26px 26px 8px 26px;padding:20px 28px 22px 40px;box-shadow:0 5px 0 var(--accent-deep)}
.you-say h2{font-weight:600;font-size:clamp(38px,5vw,56px);line-height:1;letter-spacing:-.02em}
.you-say .hang{margin-left:-.46em}
.claude-says{display:flex;gap:12px;align-items:flex-end}
.claude-mark{flex-shrink:0;display:grid;place-items:center;width:46px;height:46px;border-radius:50%;background:var(--ink);color:var(--accent)}
.claude-mark .icon{width:24px;height:24px}
.claude-text{background:var(--paper);border-radius:22px 22px 22px 8px;padding:18px 22px 20px;box-shadow:0 10px 24px -16px rgba(20,20,22,.35);min-width:0}
.claude-text .small{font-family:var(--display);font-weight:600;font-size:24px;color:var(--ink)}
.claude-text p + p{margin-top:8px;color:var(--text)}
/* On a phone the chat gives its padding to Claude's reply, which otherwise
   runs ten lines in a column half the screen wide. */
@media (max-width:480px){
  .convo-body{padding:22px 14px 24px;gap:14px}
  .you-say{padding:16px 22px 18px 34px}
  .claude-says{gap:8px}
  .claude-mark{width:36px;height:36px}
  .claude-mark .icon{width:20px;height:20px}
  .claude-text{padding:16px 18px 18px}
}
.why{display:flex;flex-direction:column;gap:28px;align-items:flex-start}
.why-item{display:grid;grid-template-columns:auto 1fr;gap:18px}
.why-item .num{display:grid;place-items:center;width:46px;height:46px;border-radius:14px;background:var(--ink);color:var(--accent);font-size:16px}
.why-item h3{font-weight:600;font-size:22px;color:var(--ink)}
.why-item p{color:var(--soft);margin-top:8px}

/* --- Quotes: sticky notes on a board -------------------------------------- */
.board{background-color:var(--mist);background-image:radial-gradient(rgba(20,20,22,.1) 1.2px,transparent 1.6px);background-size:22px 22px}
.notes{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:28px;margin-top:44px;align-items:start}
.sticky{position:relative;background:var(--sticky);padding:34px 24px 26px;border-radius:4px 4px 18px 4px;font-family:var(--display);font-size:18px;line-height:1.45;color:var(--ink);box-shadow:0 1px 1px rgba(20,20,22,.08),0 18px 30px -18px rgba(20,20,22,.45);transform:rotate(var(--tilt,-2deg));transition:transform .3s cubic-bezier(.2,.7,.2,1)}
.sticky:nth-child(2){--tilt:1.6deg;background:var(--paper)}
.sticky:nth-child(3){--tilt:-1deg}
.sticky:nth-child(4){--tilt:2.2deg;background:var(--paper)}
@media (hover:hover){.sticky:hover{transform:rotate(0) scale(1.03)}}
.sticky::before{content:"\201C";display:block;font-size:60px;line-height:.5;margin-bottom:10px;color:var(--accent-deep)}
/* A strip of orange tape holding each note up. */
.sticky::after{content:"";position:absolute;top:-11px;left:50%;width:86px;height:24px;transform:translateX(-50%) rotate(-4deg);background:rgba(249,115,22,.35);border-radius:2px}
.note{font-style:italic;color:var(--soft);font-size:14px;margin-top:36px}
@media (max-width:960px){.notes{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:560px){.notes{grid-template-columns:1fr;gap:34px}}

/* --- Features ------------------------------------------------------------- */
.feature{display:grid;grid-template-columns:5fr 7fr;gap:64px;align-items:center;margin-top:88px}
.feature > *{min-width:0}
.feature.flip{grid-template-columns:7fr 5fr}
.feature.flip .copy{order:2}
.feature .copy{display:flex;flex-direction:column;gap:14px;align-items:flex-start}
.feature h3{font-weight:600;font-size:clamp(24px,3vw,32px);letter-spacing:-.015em;color:var(--ink)}
.feature .copy p{color:var(--soft)}
/* Light-section screenshots get a sticker's offset shadow, and sit a little
   crooked until you look at them. */
.pop{border:2px solid var(--ink);box-shadow:12px 12px 0 var(--accent);transform:rotate(-1deg);transition:transform .3s ease,box-shadow .3s ease}
.flip .pop{transform:rotate(1deg);box-shadow:-12px 12px 0 var(--ink)}
@media (hover:hover){.pop:hover,.flip .pop:hover{transform:rotate(0) translateY(-4px)}}
.pop .bar{background:var(--ink)}
@media (max-width:860px){
  .feature,.feature.flip{grid-template-columns:1fr;gap:28px;margin-top:64px}
  .feature.flip .copy{order:0}
  .pop,.flip .pop{transform:none;box-shadow:8px 8px 0 var(--accent)}
}
.extras{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:22px;margin-top:96px}
.card{background:var(--paper);border:1.5px solid var(--line);border-radius:var(--radius);padding:26px;transition:transform .2s ease,border-color .2s ease,box-shadow .2s ease}
@media (hover:hover){.card:hover{transform:translateY(-4px);border-color:var(--accent);box-shadow:0 18px 36px -24px var(--accent-glow)}}
.card h3{font-weight:600;font-size:20px;color:var(--ink);margin-top:16px}
.card p{margin-top:8px;color:var(--soft)}
@media (hover:hover){.card:hover .icon-badge,.outcome:hover .icon-badge{animation:wiggle .5s ease}}
@keyframes wiggle{25%{transform:rotate(-10deg)}75%{transform:rotate(8deg)}}
@media (max-width:860px){.extras{grid-template-columns:1fr;margin-top:64px}}

/* --- Four things change --------------------------------------------------- */
.outcome-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:20px;margin-top:48px}
.outcome{background:var(--ink-2);border:1px solid var(--ink-line);border-radius:var(--radius);padding:24px;transition:transform .2s ease,border-color .2s ease}
@media (hover:hover){.outcome:hover{transform:translateY(-4px);border-color:rgba(249,115,22,.55)}}
/* The icon is centred over the text and the number keeps the top-right
   corner: three columns, the outer two equal, so the middle is the card's. */
.outcome-top{display:grid;grid-template-columns:1fr auto 1fr;align-items:center}
.outcome-top .icon-badge{grid-column:2}
.outcome-top .num{grid-column:3;justify-self:end}
.outcome h3{font-weight:600;font-size:19px;color:var(--on-dark);margin-top:18px}
.outcome p{margin-top:8px;color:var(--on-dark-soft)}
@media (max-width:1000px){.outcome-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:560px){.outcome-grid{grid-template-columns:1fr}}

/* --- Closing: the CTA panel, with a visitor ------------------------------- */
/* The bottom padding is Bob's room under the copy, all of it in units of his
   width: his clear space (.29) between the panel's floor and him, the .59
   from the foot of his SVG to the top of his bubble, his clear space again
   above that, and the 12px he bobs, rounded up. */
.cta-panel{--bob-width:clamp(110px,14vw,160px);position:relative;isolation:isolate;overflow:hidden;border-radius:32px;padding:64px clamp(24px,5vw,64px) calc(var(--bob-width) * 1.18 + 12px)}
.closing{display:grid;grid-template-columns:3fr 2fr;gap:48px;align-items:center}
.closing > *{min-width:0}
.closing .lede{color:var(--on-dark)}
.closing .lede b{color:var(--accent)}
.closing .actions{flex-direction:column;align-items:flex-start}
/* The two addresses sit side by side, parted by a gap rather than a dot, and
   stack when they don't fit: a separator ended up dangling at the end of the
   first line at whatever width they wrapped. */
.contact{display:flex;flex-wrap:wrap;column-gap:24px;row-gap:4px;font-family:var(--display);color:var(--on-dark-soft);font-size:15px;overflow-wrap:anywhere}
.contact a{text-decoration-color:rgba(242,243,244,.35);text-underline-offset:3px}
@media (hover:hover){.contact a:hover{color:var(--accent)}}
/* Under a finger each address is tall enough to tap. */
@media (pointer:coarse){.contact{row-gap:0}.contact a{padding-block:11px}}
/* Bob swims up under the buttons and looks up at them: his looking-up pose,
   held, so it stays when motion is turned down. The panel is his frame, so
   he keeps his clear space from its floor and its side too, rather than
   resting on the edge: .29 of his width below him, and .25 at the side,
   where his tail sits .04 inside his SVG's box. */
.cta-bob{position:absolute;right:max(clamp(16px,8%,96px),var(--bob-width) * .25);bottom:calc(var(--bob-width) * .29);width:var(--bob-width);animation:bob 6s ease-in-out infinite}
.cta-bob .ball{transform:translateY(-18px)}
@media (max-width:860px){.closing{grid-template-columns:1fr;gap:32px}}
/* A phone needs the panel's width for the brochure button's one-line label. */
@media (max-width:480px){
  .cta-panel{padding-inline:18px;border-radius:24px}
  .cta-panel .actions .btn{padding-inline:14px;gap:8px}
}
/* Below 360px (the first iPhone SE) the hero's tag and the brochure label
   step down a notch, which keeps each on one line. */
@media (max-width:359px){
  .hero .badge{font-size:11px;letter-spacing:.1em}
  .closing-section .wrap{padding-inline:12px}
  .cta-panel{padding-inline:14px}
  .actions .btn,.cta-panel .actions .btn{font-size:14px;padding-inline:10px;gap:7px}
  .actions .btn .icon{width:18px;height:18px}
}

.site-footer{background:var(--ink);color:var(--on-dark-soft);padding-block:28px;padding-bottom:max(28px,env(safe-area-inset-bottom));font-size:14px}
.site-footer .wrap{display:flex;justify-content:space-between;flex-wrap:wrap;gap:10px}
/* On a phone the tagline takes its own line rather than breaking mid-phrase. */
@media (max-width:480px){
  .site-footer .sep{display:none}
  .site-footer .tagline{display:block}
}
.site-footer b{color:var(--on-dark)}

/* --- Screenshot viewer (viewer.js) ---------------------------------------- */
/* Full screen over a dark backdrop. On a large screen the shot fits the
   window; below 900px it opens at its 1x size (1280px) and pans, because
   fitted to a phone it is no more readable than the copy on the page. */
.viewer,.video-viewer{width:100%;height:100%;max-width:none;max-height:none;margin:0;padding:0;border:0;background:transparent;overflow:hidden;color:var(--on-dark)}
.viewer::backdrop,.video-viewer::backdrop{background:rgba(10,10,12,.96)}
html:has(.viewer[open]),html:has(.video-viewer[open]){overflow:hidden}
.viewer-scroll{display:flex;width:100%;height:100%;overflow:auto;padding:72px 16px 16px;padding:72px max(16px,env(safe-area-inset-right)) max(16px,env(safe-area-inset-bottom)) max(16px,env(safe-area-inset-left));overscroll-behavior:contain}
/* margin:auto (not centring on the container) keeps an over-wide shot's left
   edge reachable by scrolling. */
.viewer-scroll img{margin:auto;max-width:100%;max-height:100%;width:auto;height:auto;border-radius:8px;box-shadow:0 20px 50px rgba(0,0,0,.5);cursor:default}
@media (max-width:900px){.viewer-scroll img{max-width:none;max-height:none;width:1280px}}
.viewer-close{position:absolute;top:14px;right:16px;top:max(14px,env(safe-area-inset-top));right:max(16px,env(safe-area-inset-right));z-index:1;display:inline-flex;align-items:center;gap:8px;min-height:44px;padding:8px 18px 8px 14px;border-radius:999px;border:1.5px solid rgba(255,255,255,.35);background:rgba(20,20,22,.85);color:var(--on-dark);font-family:var(--display);font-weight:500;font-size:15px;cursor:pointer}
.viewer-close span{font-size:27px;line-height:1}
@media (hover:hover){.viewer-close:hover{border-color:var(--on-dark);background:var(--ink-2)}}

/* The video player: the video as large as the window allows at 16:9, leaving
   room for the Close button above and Book a Demo below, which answers the
   video's last line ("we should talk"). Phones get the full width and can go
   full screen from the controls. */
/* --stage-h is the window's height: the dynamic one where the browser has it,
   so a phone's collapsing toolbar is not counted as room for the video. */
.video-viewer{--stage-h:100vh}
@supports (height:100dvh){.video-viewer{--stage-h:100dvh}}
.video-stage{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:22px;height:100%;padding:72px 16px 24px;padding:72px max(16px,env(safe-area-inset-right)) max(24px,env(safe-area-inset-bottom)) max(16px,env(safe-area-inset-left))}
.video-stage video{display:block;width:min(1280px,100%,calc((var(--stage-h) - 190px) * 16 / 9));height:auto;aspect-ratio:16/9;border-radius:12px;background:#000;box-shadow:0 20px 50px rgba(0,0,0,.5)}
/* A phone held sideways has the width but not the height: room above and
   below for the buttons would leave the video a 355x200 strip. Book a Demo
   moves beside it instead (216px is its width plus the gap), so the video
   takes the full height, short of the home indicator. */
@media (orientation:landscape) and (max-height:520px){
  .video-stage{flex-direction:row;gap:16px;padding-top:16px;padding-bottom:max(16px,env(safe-area-inset-bottom))}
  .video-stage video{width:min(calc(100% - 216px),calc((var(--stage-h) - 16px - max(16px,env(safe-area-inset-bottom))) * 16 / 9))}
  .video-stage .btn{flex-shrink:0}
}

/* --- Less motion, when asked ---------------------------------------------- */
/* The bubbles stay, scattered and still; nothing bobs, rises or wiggles.
   Bob holds a pose: resting in the hero, looking up in the closing panel. */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation:none!important;transition:none!important}
  .bubble{bottom:var(--y);opacity:.6}
}
