/* Instrument Sans from this site (the variable font, Latin), preloaded in each page's head: on a slow
   connection that is two round trips fewer than Google Fonts, so the text is in its own font before the
   arrival plays and never swaps under a moving headline. */
@font-face{font-family:"Instrument Sans";src:url(../fonts/InstrumentSans-wght.woff2?v=1) format("woff2");font-weight:400 700;font-style:normal;font-display:swap}
:root{--orb-fill:radial-gradient(circle at 76% 80%,rgba(176,64,56,.14) 0,rgba(176,64,56,0) 42%),
    radial-gradient(circle at 22% 18%,#8fb0d8 0%,#7ea3cf 20%,#8fcaa6 36%,#e6bb77 50%,#dc9068 61%,#c96a5c 72%);
  --font:"Inter",system-ui,sans-serif;--gut:clamp(16px,4vw,56px);--ease:cubic-bezier(.2,.7,.1,1)}
html[data-theme="dark"]{--bg:#09090b;--ink:#f6f6f7;--ink-2:#c5c5ca;--ink-3:#8d8d93;--line:rgba(255,255,255,.14);--glass:rgba(22,22,26,.34);--glass-edge:rgba(255,255,255,.16);--glass-body:linear-gradient(180deg,#1c1c21,#111114);--glass-bar:linear-gradient(180deg,#1b1b20,#121215);--glass-rim:rgba(255,255,255,.2);--glass-spec:rgba(255,255,255,.7);--glass-spec2:rgba(255,255,255,.3);--glass-gloss:rgba(255,255,255,.13);--glass-bounce:rgba(255,255,255,.07)}
html[data-theme="light"]{--bg:#f2f2f0;--ink:#0c0c0d;--ink-2:#3a3a3e;--ink-3:#69696e;--line:rgba(0,0,0,.12);--glass:rgba(255,255,255,.42);--glass-edge:rgba(255,255,255,.8);--glass-body:linear-gradient(180deg,#ffffff,#f1f1ef);--glass-bar:linear-gradient(180deg,#ffffff,#f6f6f5);--glass-rim:rgba(255,255,255,.9);--glass-spec:#fff;--glass-spec2:rgba(0,0,0,.08);--glass-gloss:rgba(255,255,255,.9);--glass-bounce:rgba(0,0,0,.035)}
*,*::before,*::after{box-sizing:border-box}
html,body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--font);font-weight:300;-webkit-font-smoothing:antialiased}
body{overflow-x:clip}
a{color:inherit}
h1,h2,h3,p,ul,ol{margin:0}
/* Type: 200 headlines, 300 body, 400 labels. Line-height stays >= 1 so descenders (g, y, j, p) never clip. */
.d1{font-size:clamp(3rem,8.6vw,9rem);font-weight:200;letter-spacing:-.05em;line-height:1.02}
.d2{font-size:clamp(2.2rem,5vw,5rem);font-weight:200;letter-spacing:-.04em;line-height:1.06}
.d3{font-size:clamp(1.4rem,2.2vw,2.1rem);font-weight:200;letter-spacing:-.02em;line-height:1.2}
.soft{color:var(--ink-3)}
.body{font-size:clamp(1rem,1.1vw,1.15rem);line-height:1.65;color:var(--ink-2);max-width:38ch}
.label{font-size:.72rem;font-weight:400;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-3);font-variant-numeric:tabular-nums}
/* Liquid glass (iOS 26 style). A solid body, so nothing behind a card (the card
   under it in the deck, a heading scrolling past) ever reads through; the glass
   is in the light: a rim that catches it at two corners, a broad gloss across
   the top and a bounce along the bottom edge (no thin streaks: they read as ripples). All static
   gradients drawn under the text; no backdrop blur on cards (that cost ~1 in 6
   frames while scrolling). The nav and menu are solid too: text scrolling under
   them must never show. */
.glass{position:relative;isolation:isolate;border-radius:48px;border:0;background:var(--glass-body);
  box-shadow:inset 0 1px 1px var(--glass-spec),inset 0 -10px 24px -14px var(--glass-bounce),0 1px 2px rgba(0,0,0,.14),0 34px 70px -38px rgba(0,0,0,.55)}
.glass::before,.glass::after{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;z-index:-1}
.glass::before{padding:1.5px;background:linear-gradient(135deg,var(--glass-spec) 0%,var(--glass-rim) 22%,transparent 46%,transparent 58%,var(--glass-rim) 80%,var(--glass-spec2) 100%);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask:linear-gradient(#000 0 0) content-box exclude,linear-gradient(#000 0 0)}
/* The grain is a dither: it breaks the 8-bit steps of these dark gradients, which otherwise show as bands. */
.glass::after{background:
  url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.06'/%3E%3C/svg%3E") 0 0/160px 160px,
  radial-gradient(140% 90% at 22% -30%,var(--glass-gloss) 0%,transparent 62%),
  radial-gradient(100% 70% at 85% 125%,var(--glass-bounce) 0%,transparent 72%)}
.nav.glass,.menu-sheet.glass{background:var(--glass-bar)}
.nav.glass::after,.chip.glass::after{background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.06'/%3E%3C/svg%3E") 0 0/160px 160px,radial-gradient(120% 90% at 30% -40%,var(--glass-gloss) 0%,transparent 60%)}
.nav{position:fixed;inset:14px var(--gut) auto;display:flex;justify-content:space-between;align-items:center;padding:12px 14px 12px 22px;z-index:10;border-radius:99px}
.nav a{text-decoration:none;font-weight:400;font-size:.88rem;color:var(--ink-2)}
.nav .brand{color:var(--ink)}
.nav .links{display:flex;gap:24px;align-items:center}
.theme-btn,.seg button{background:none;border:1px solid var(--line);color:var(--ink-2);border-radius:99px;padding:6px 12px;font:400 .78rem var(--font);cursor:pointer}
.pill{display:inline-block;padding:14px 26px;border-radius:99px;border:1px solid var(--ink);text-decoration:none;font-weight:400;will-change:transform}
.pill.solid{background:var(--ink);color:var(--bg)}
main{position:relative;z-index:1}
section{position:relative;padding:0 var(--gut)}
.scene{min-height:100vh;display:grid;align-content:center;padding-top:110px;padding-bottom:60px}
.footer{padding:48px var(--gut);border-top:1px solid var(--line);color:var(--ink-3);font-size:.85rem;position:relative;z-index:1}
/* Hero */
.hero h1{max-width:12ch;font-size:clamp(3rem,8.4vw,9rem)}
.hero .body{margin:2rem 0}
.hero-actions{display:flex;gap:12px;flex-wrap:wrap}
.char{display:inline-block;will-change:transform}
.word{display:inline-block}
/* Deck */
.deck-pin{min-height:100vh;display:grid;place-items:center;position:relative;overflow-x:clip}
.deck-head{position:absolute;top:clamp(96px,14vh,130px);left:0;right:0;text-align:center;display:grid;gap:.8rem;justify-items:center;padding:0 var(--gut)}
.deck-stack{position:relative;width:min(660px,88vw);height:min(440px,62vh);margin-top:90px}
.deck-card{position:absolute;inset:0;padding:clamp(28px,4vw,48px);display:grid;align-content:space-between;gap:1rem;will-change:transform}
.deck-card:nth-child(1){z-index:4}.deck-card:nth-child(2){z-index:3;transform:translateY(18px) scale(.96)}
.deck-card:nth-child(3){z-index:2;transform:translateY(36px) scale(.92)}.deck-card:nth-child(4){z-index:1;transform:translateY(54px) scale(.88)}
/* Process */
.steps{list-style:none;padding:0 0 0 clamp(40px,6vw,90px);margin:2.4rem 0 0 12px;display:grid;gap:clamp(48px,9vh,110px);border-left:1px solid var(--line)}
.steps li{display:grid;gap:.5rem}
/* Work */
.work-in{display:grid;grid-template-columns:minmax(220px,1fr) 2.4fr;gap:clamp(24px,4vw,64px);align-items:center}
.sites{list-style:none;padding:0;display:grid;gap:4px}
.sites button{width:100%;text-align:left;background:none;border:0;border-left:1px solid var(--line);padding:14px 18px;color:var(--ink-3);font:200 clamp(1.2rem,1.8vw,1.7rem)/1.25 var(--font);letter-spacing:-.02em;cursor:pointer;transition:color .3s,border-color .3s}
.sites button[aria-pressed="true"]{color:var(--ink);border-left-color:var(--ink)}
.sites small{display:block;font:400 .68rem/1.5 var(--font);letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3);margin-top:4px}
.seg{display:flex;gap:6px;margin-bottom:18px;justify-content:flex-end}
.seg button[aria-pressed="true"]{background:var(--ink);color:var(--bg);border-color:var(--ink)}
.stage{display:grid;justify-items:center}
.device{width:100%;max-width:900px;padding:14px;border-radius:44px;transition:max-width .7s var(--ease)}
.device.phone{max-width:300px}
.screen{position:relative;aspect-ratio:16/10;border-radius:30px;overflow:hidden;background:var(--bg)}
.device.phone .screen{aspect-ratio:9/19.5;border-radius:34px}
.screen iframe{position:absolute;top:0;left:0;width:var(--vw,1280px);height:calc(100% / var(--k,.5));border:0;transform-origin:0 0;transform:scale(var(--k,.5))}
/* Who */
.chips{display:flex;flex-wrap:wrap;gap:12px;margin-top:2.5rem}
.chip{padding:14px 22px;border-radius:99px;font-size:clamp(1rem,1.5vw,1.3rem)}
/* CTA */
.cta{place-items:center}
.cta-card{padding:clamp(40px,7vw,96px);text-align:center;display:grid;gap:1.6rem;justify-items:center;max-width:980px}
/* Orb: the logo as polished glass. No dark layers at all; depth comes from light.
   Wrapper .orb is moved by scroll, .orb-in leans toward the cursor, .orb-hl is the specular. */
.orb{--orb:min(60vmin,600px);position:fixed;left:0;top:0;width:var(--orb);height:var(--orb);z-index:0;pointer-events:none;transform:translate(calc(100vw - var(--orb)*1.04),calc(50vh - var(--orb)/2));will-change:transform}
.orb-in{position:absolute;inset:0;border-radius:50%;will-change:transform;
  background:
    radial-gradient(circle at 50% 110%,rgba(255,255,255,.2) 0,rgba(255,255,255,0) 30%),
    var(--orb-fill);
  box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.4),inset 0 0 26px rgba(255,255,255,.22),0 40px 110px -50px rgba(200,110,80,.28)}
.orb-in::after{content:"";position:absolute;inset:0;border-radius:50%;background:radial-gradient(circle,rgba(255,255,255,0) 66%,rgba(255,255,255,.4) 72%,rgba(255,255,255,0) 75%)}
/* Specular: a broad soft sheen with one small hot point inside it, the way a
   polished sphere reflects a softbox. No hard-edged oval. */
.orb-hl{position:absolute;left:13%;top:7%;width:52%;height:36%;border-radius:50%;will-change:transform;transform:rotate(-22deg);
  background:radial-gradient(ellipse at 50% 42%,rgba(255,255,255,.5) 0,rgba(255,255,255,.2) 38%,rgba(255,255,255,.06) 58%,rgba(255,255,255,0) 74%)}
.orb-hl::after{content:"";position:absolute;left:34%;top:30%;width:15%;height:11%;border-radius:50%;
  background:radial-gradient(ellipse,rgba(255,255,255,.95) 0,rgba(255,255,255,.55) 32%,rgba(255,255,255,0) 72%)}
/* Environment: the sky half of the room reflected across the upper sphere, lighter, never darker. */
.orb-in::before{content:"";position:absolute;inset:0;border-radius:50%;
  background:linear-gradient(172deg,rgba(255,255,255,.16) 0,rgba(255,255,255,.1) 40%,rgba(255,255,255,0) 50%)}
/* The orb always stays behind the page: while the page is hidden the order is
   invisible, and while it fades the text fades over the orb instead of popping. */
/* Arrival pose: identical to the JS "stage" state so the hand-over is seamless. */
/* svh, not vh: on load the visible height (what fusion.js centres on) is the small viewport; vh dropped the orb ~40px on iPhone. */
.is-covered .orb{transform:translate(calc(50vw - var(--orb)/2),calc(50vh - var(--orb)/2)) scale(1.2)}
@supports (height:1svh){.is-covered .orb{transform:translate(calc(50vw - var(--orb)/2),calc(50svh - var(--orb)/2)) scale(1.2)}}
.is-covered body>*:not(.orb){opacity:0}
@media (prefers-reduced-motion:reduce){
  .orb{transform:translate(calc(100vw - var(--orb)*.7),calc(100vh - var(--orb)*.8)) scale(.8)}
  .deck-stack{height:auto;display:grid;gap:20px}.deck-card{position:relative;transform:none!important}
}
@media (max-width:767px){
  .work-in{grid-template-columns:1fr}
  .sites{grid-auto-flow:column;grid-auto-columns:minmax(150px,1fr);overflow-x:auto;padding-bottom:6px}
  .nav{inset:10px 10px auto}.nav .links{gap:12px}
  .orb{--orb:80vw}
}
/* ---------------------------------------------------------- inner pages */
.intro{min-height:74vh}
.intro .body{margin-top:2rem}
.panels{display:grid;grid-template-columns:repeat(2,1fr);gap:clamp(16px,2vw,24px)}
.panel{padding:clamp(26px,3.4vw,44px);display:grid;gap:1.2rem;align-content:start}
.panel h3{margin-top:.2rem}
.tags{display:flex;flex-wrap:wrap;gap:8px}
.tag{padding:7px 13px;border-radius:99px;border:1px solid var(--line);font-size:.8rem;font-weight:400;color:var(--ink-2)}
.promise{min-height:80vh}
.promise .d2{max-width:18ch}
.timeline{list-style:none;padding:0 0 0 clamp(40px,6vw,90px);margin:2.4rem 0 0 12px;display:grid;gap:clamp(40px,8vh,96px);border-left:1px solid var(--line)}
.timeline li{display:grid;gap:.5rem;max-width:44ch}
/* Work details */
.projects{display:grid;grid-template-columns:repeat(2,1fr);gap:clamp(16px,2vw,24px);margin-top:clamp(48px,8vh,96px)}
.project-head{display:flex;justify-content:space-between;align-items:baseline;gap:1rem;flex-wrap:wrap}
.link{font-size:.9rem;font-weight:400;color:var(--ink-2);text-underline-offset:4px}
/* Estimate */
.split{display:grid;grid-template-columns:1.1fr 1fr;gap:clamp(16px,2vw,24px);align-items:start}
.readout{display:flex;justify-content:space-between;align-items:flex-end;gap:1rem;flex-wrap:wrap}
.figure{font-size:clamp(3.6rem,8vw,7rem);font-weight:200;letter-spacing:-.05em;line-height:1;font-variant-numeric:tabular-nums}
.figure sup{font-size:.4em;vertical-align:.9em;margin-right:.08em;color:var(--ink-3)}
input[type=range]{-webkit-appearance:none;appearance:none;width:100%;height:28px;background:transparent;cursor:pointer}
input[type=range]::-webkit-slider-runnable-track{height:2px;border-radius:2px;background:linear-gradient(90deg,var(--ink) var(--fill,25%),var(--line) var(--fill,25%))}
input[type=range]::-moz-range-track{height:2px;background:var(--line)}
input[type=range]::-moz-range-progress{height:2px;background:var(--ink)}
input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:22px;height:22px;margin-top:-10px;border-radius:50%;background:var(--bg);border:1px solid var(--ink);box-shadow:0 4px 14px rgba(0,0,0,.25)}
input[type=range]::-moz-range-thumb{width:22px;height:22px;border-radius:50%;background:var(--bg);border:1px solid var(--ink)}
.scale{display:flex;justify-content:space-between;font-size:.78rem;color:var(--ink-3);font-variant-numeric:tabular-nums}
.options{display:grid;gap:8px}
.option{display:grid;grid-template-columns:auto 1fr auto;gap:14px;align-items:center;padding:14px 16px;border:1px solid var(--line);border-radius:20px;cursor:pointer;transition:border-color .3s,background .3s}
.option:has(input:checked){border-color:var(--ink);background:color-mix(in srgb,var(--ink) 6%,transparent)}
.option input{width:18px;height:18px;accent-color:var(--ink);margin:0}
.option b{display:block;font-weight:400}
.option small{display:block;color:var(--ink-3);font-size:.82rem;line-height:1.5}
.option .price{font-variant-numeric:tabular-nums;color:var(--ink-2)}
.hint{font-size:.85rem;line-height:1.55;color:var(--ink-3)}
.hint b{font-weight:400;color:var(--ink-2)}
.actions{display:flex;gap:10px;flex-wrap:wrap}
.field{display:grid;gap:.55rem}
.field>label{font-size:.85rem;font-weight:400;color:var(--ink-2)}
.choices{display:flex;flex-wrap:wrap;gap:8px}
.choice{background:none;border:1px solid var(--line);color:var(--ink-2);border-radius:14px;padding:10px 14px;font:300 .92rem/1.3 var(--font);cursor:pointer;display:grid;justify-items:center;gap:2px;min-width:64px}
.choice b{font-weight:300;font-size:1.3rem;color:var(--ink)}
.choice small{font-size:.7rem;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3)}
.choice[aria-pressed="true"]{border-color:var(--ink);background:var(--ink);color:var(--bg)}
.choice[aria-pressed="true"] b,.choice[aria-pressed="true"] small{color:var(--bg)}
.choice:disabled{opacity:.35;cursor:not-allowed;text-decoration:line-through}
.summary{display:grid;gap:.2rem;font-size:.95rem;color:var(--ink-2)}
.summary b{font-weight:400;color:var(--ink)}
.input{width:100%;background:transparent;border:1px solid var(--line);border-radius:14px;padding:13px 15px;color:var(--ink);font:300 1rem var(--font)}
.input:focus{outline:none;border-color:var(--ink)}
textarea.input{min-height:110px;resize:vertical}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.pill:disabled{opacity:.4;cursor:not-allowed}
button.pill{font:400 1rem var(--font);cursor:pointer}
.map svg{width:100%;height:auto;display:block}
.map-land{fill:color-mix(in srgb,var(--ink) 5%,transparent);stroke:var(--ink-3);stroke-width:1}
.map-pin circle{fill:var(--ink-3)}
.map-core{fill:var(--ink)}
.map-label{fill:var(--ink-3);font:300 10px var(--font)}
.map-embed{width:100%;aspect-ratio:560/380;border:0;border-radius:16px}
.map-foot{display:flex;justify-content:space-between;align-items:center;gap:1rem;flex-wrap:wrap;margin-top:1rem}
dialog.sheet{border:1px solid var(--glass-edge);border-radius:48px;padding:0;color:var(--ink);width:min(540px,calc(100vw - 32px));background:var(--glass);backdrop-filter:blur(28px) saturate(1.4);-webkit-backdrop-filter:blur(28px) saturate(1.4)}
dialog.sheet::backdrop{background:color-mix(in srgb,var(--bg) 55%,transparent);backdrop-filter:blur(6px)}
.sheet-in{padding:clamp(28px,4vw,44px);display:grid;gap:1.1rem}
.sheet-close{position:absolute;top:14px;right:14px;background:none;border:0;color:var(--ink-2);width:36px;height:36px;cursor:pointer}
.sheet-close svg{width:22px;height:22px}
.sheet-actions{display:flex;flex-wrap:wrap;gap:.7rem;margin-top:.4rem}
.sheet-actions .pill{min-height:44px;text-align:center}
.demo-note{margin:1.1rem 0 0;max-width:62ch}
@media (max-width:900px){.panels,.projects,.split{grid-template-columns:1fr}}

/* Mini orb: beside the wordmark and as the estimate slider handle. */
.mark-orb{display:inline-block;width:16px;height:16px;border-radius:50%;margin-right:10px;vertical-align:-2px;
  background:radial-gradient(ellipse at 36% 28%,rgba(255,255,255,.7) 0,rgba(255,255,255,0) 38%),var(--orb-fill);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.35)}
.nav .brand{display:inline-flex;align-items:center}
input[type=range]::-webkit-slider-thumb{width:30px;height:30px;margin-top:-14px;border:0;
  background:radial-gradient(ellipse at 36% 28%,rgba(255,255,255,.75) 0,rgba(255,255,255,0) 38%),var(--orb-fill);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.4),0 6px 18px -4px rgba(200,110,80,.45)}
input[type=range]::-moz-range-thumb{width:30px;height:30px;border:0;
  background:radial-gradient(ellipse at 36% 28%,rgba(255,255,255,.75) 0,rgba(255,255,255,0) 38%),var(--orb-fill);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.4),0 6px 18px -4px rgba(200,110,80,.45)}
/* Footer */
.footer{padding:clamp(56px,9vh,96px) var(--gut) 32px}
.footer-grid{display:grid;grid-template-columns:2fr 1fr 1.4fr;gap:clamp(28px,4vw,64px)}
.footer .brand{display:inline-flex;align-items:center;text-decoration:none;color:var(--ink);font-weight:400;font-size:1.05rem}
.footer .body{margin-top:1rem;max-width:32ch}
.footer h4{margin:0 0 1rem;font:400 .72rem var(--font);letter-spacing:.16em;text-transform:uppercase;color:var(--ink-3)}
.footer-links{display:grid;gap:.6rem}
.footer-links a{color:var(--ink-2);text-decoration:none;font-size:.95rem;width:fit-content}
.footer-links a:hover{color:var(--ink)}
.footer-base{display:flex;justify-content:space-between;gap:1rem;flex-wrap:wrap;margin-top:clamp(40px,7vh,72px);padding-top:20px;border-top:1px solid var(--line);font-size:.82rem;color:var(--ink-3)}
@media (max-width:767px){.footer-grid{grid-template-columns:1fr}}

/* First-visit intro: small, faint, centred; the page waits underneath. Pose must match fusion.js. */
.booting body{overflow:hidden}
.booting .orb{opacity:.16;transform:translate(calc(50vw - var(--orb)/2),calc(50vh - var(--orb)/2)) scale(.14)}
@supports (height:1svh){.booting .orb{transform:translate(calc(50vw - var(--orb)/2),calc(50svh - var(--orb)/2)) scale(.14)}}
.booting body>*:not(.orb){opacity:0}

/* Showcase: tabs and device switch in one bar, the preview full width, the chosen project's story below. */
.work-intro{max-width:62ch;margin-bottom:clamp(28px,5vh,48px)}
.work-in{display:grid;grid-template-columns:1fr;gap:clamp(16px,2.4vh,24px)}
.work-bar{display:flex;justify-content:space-between;align-items:flex-end;gap:16px;flex-wrap:wrap;min-width:0}
.work-bar .sites{grid-auto-flow:column;grid-auto-columns:max-content;gap:4px;max-width:100%}
@media (max-width:900px){.work-bar .sites{overflow-x:auto;padding-bottom:8px}}
.work-bar .sites button{border-left:0;border-bottom:1px solid var(--line);padding:10px 16px 12px;font-size:clamp(1rem,1.3vw,1.3rem);white-space:nowrap}
.work-bar .sites button[aria-pressed="true"]{border-bottom-color:var(--ink)}
.work-bar .sites small{display:none}
.work-bar .seg{margin:0}
.device{max-width:1280px}
.stage{justify-items:stretch;min-width:0}
.device.phone{justify-self:center}
.site-infos{max-width:760px}
.site-info{display:grid;gap:.9rem}
.site-info[hidden]{display:none}
.site-info .project-head{justify-content:flex-start;gap:1rem}
.map-dc{fill:color-mix(in srgb,var(--ink) 9%,transparent);stroke:var(--ink-3);stroke-width:1;stroke-dasharray:3 3}
.map-label .map-dc-label{fill:var(--ink-2)}
/* Coverage map: service area filled, nearby Maryland tinted, surroundings as faint context. */
.map-county{fill:none;stroke:var(--line);stroke-width:.8;stroke-linejoin:round}
.map-county.near{fill:color-mix(in srgb,var(--ink) 5%,transparent);stroke:var(--ink-3);stroke-width:.9;stroke-dasharray:4 3}
.map-county.core{fill:color-mix(in srgb,var(--ink) 11%,transparent);stroke:var(--ink-2);stroke-width:1.1;stroke-dasharray:none}
.map-county-label{font:400 9px var(--font);letter-spacing:.18em;text-transform:uppercase;fill:var(--ink-3)}
.map-county-label.core{fill:var(--ink-2)}
.map-county-label.ctx{opacity:.55}
.map-ring{fill:none;stroke:var(--ink);stroke-width:1;opacity:.35}
.map-label .map-studio{fill:var(--ink);font-weight:400}
.map-legend text,.map-scale text{font:300 10px var(--font);fill:var(--ink-2)}
.map-legend-bg{fill:color-mix(in srgb,var(--bg) 82%,transparent);stroke:var(--line)}
.map-scale path{stroke:var(--ink-2);stroke-width:1;fill:none}
.map-embed{aspect-ratio:600/738}
/* Cartographic halo: labels stay legible where they cross a border. */
.map-label text,.map-county-label,.map-legend text,.map-scale text{paint-order:stroke;stroke:var(--bg);stroke-width:3px;stroke-linejoin:round}

/* ---------------------------------------------------------------- phone */
.mark-orb{flex:none}
.nav .brand{white-space:nowrap}
.menu-btn{display:none;width:40px;height:40px;border-radius:50%;border:1px solid var(--line);background:none;cursor:pointer;place-content:center;gap:5px;padding:0}
.menu-btn span{display:block;width:16px;height:1px;background:var(--ink);transition:transform .3s var(--ease)}
.menu-btn[aria-expanded="true"] span:first-child{transform:translateY(3px) rotate(45deg)}
.menu-btn[aria-expanded="true"] span:last-child{transform:translateY(-3px) rotate(-45deg)}
.menu-sheet{position:fixed;top:74px;left:12px;right:12px;z-index:11;padding:12px;display:grid;gap:2px;border-radius:40px}
.menu-sheet[hidden]{display:none}
.menu-sheet a{padding:12px 14px;font:200 1.7rem/1.2 var(--font);letter-spacing:-.02em;text-decoration:none;color:var(--ink);border-radius:14px}
.menu-sheet a:active{background:color-mix(in srgb,var(--ink) 6%,transparent)}
@media (max-width:767px){
  .nav{inset:12px 12px auto;padding:7px 7px 7px 16px}
  .nav .brand{font-size:.95rem}
  .nav .links{gap:8px}
  .nav .links a:not(.lang){display:none}
  .nav .lang{display:grid;place-items:center;width:40px;height:40px;border:1px solid var(--line);border-radius:50%;font-size:.8rem}
  .theme-btn{width:40px;height:40px;padding:0;font-size:0;display:grid;place-items:center}
  .theme-btn::before{content:"";width:16px;height:16px;border-radius:50%;border:1px solid var(--ink-2);background:linear-gradient(90deg,var(--ink-2) 50%,transparent 50%)}
  .menu-btn{display:grid}
  .scene{min-height:auto;padding-top:clamp(64px,10vh,96px);padding-bottom:clamp(56px,8vh,80px)}
  .hero.scene{padding-top:104px;min-height:88vh;align-content:start}
  .promise,.intro{min-height:auto}
}
@media (max-width:767px){
  .nav{gap:8px}
  .nav .links{margin-left:auto}
  /* Solid enough that the page behind never reads through the menu. */
  .menu-sheet{background:var(--bg);backdrop-filter:none;-webkit-backdrop-filter:none}
}
/* Deck cards: content centred with even spacing, and solid enough that the
   card behind never reads through. */
.deck-card{align-content:center;gap:clamp(18px,3vh,28px)}
/* Theme icon: positioned on its own so the hidden button text can't push it off-centre. */
@media (max-width:767px){
  .theme-btn{position:relative}
  .theme-btn::before{position:absolute;inset:0;margin:auto}
}
@media (max-width:767px){.deck-stack{height:330px}}
/* Flat orb, drawn like the business card: one diagonal wash in the brand
   colours (brand/card-front.svg) and a soft bloom from the top-left. No
   specular spot, no rim, no edge line. */
:root{--orb-fill:radial-gradient(circle at 34% 26%,rgba(255,255,255,.3) 0,rgba(255,255,255,.05) 42%,rgba(255,255,255,0) 64%),
  linear-gradient(135deg,#96BEEE 10%,#68EC9B 40%,#FFA212 64%,#E2362C 90%)}
.orb-in{box-shadow:0 40px 120px -60px rgba(226,54,44,.3)}
.orb-in::before,.orb-in::after,.orb-hl{display:none}
.mark-orb{background:var(--orb-fill);box-shadow:none}
input[type=range]::-webkit-slider-thumb{background:var(--orb-fill);box-shadow:0 6px 18px -6px rgba(226,54,44,.4)}
input[type=range]::-moz-range-thumb{background:var(--orb-fill);box-shadow:0 6px 18px -6px rgba(226,54,44,.4)}
.deck-head{z-index:5}

/* Legibility the way the original site did it (live-before-fusion css/style.css):
   high-contrast ink and a faint full-screen veil of page colour over the orb. */
/* Same lightness as the originals (#CBD1DA, #23262E, #363B44), kept neutral per the grey-only type rule. */
html[data-theme="dark"]{--ink:#FFFFFF;--ink-2:#E5E5E5;--ink-3:#D0D0D2}
html[data-theme="light"]{--ink:#131315;--ink-2:#262628;--ink-3:#3B3B3F}
main::before{content:"";position:fixed;inset:0;z-index:-1;background:var(--bg);opacity:.04;pointer-events:none}
/* Minimal reflection, like the business card: a soft top-left bloom, one small
   blurred highlight and a gentle fall-off to the lower right. Enough to read as
   a sphere, not a flat disc. */
.orb-in{background:
  radial-gradient(115% 115% at 28% 20%,rgba(255,255,255,.3) 0%,rgba(255,255,255,.04) 22%,rgba(0,0,0,0) 50%,rgba(0,0,0,.14) 80%,rgba(0,0,0,.22) 100%),
  linear-gradient(135deg,#96BEEE 10%,#68EC9B 40%,#FFA212 64%,#E2362C 90%)}
.orb-hl{display:block;left:18%;top:12%;width:26%;height:15%;background:radial-gradient(ellipse at center,rgba(255,255,255,.7),rgba(255,255,255,0) 70%);filter:blur(5px);transform:rotate(-24deg)}
.orb-hl::after{display:none}

/* Theme switch: the theme's colours themselves cross-fade while html.shifting is set (fusion.js), so
   everything drawn with them changes together. They are registered as colours so the browser can blend
   them; one that cannot simply switches at once. The old way put a transition on every element, and
   text that takes its colour from a parent then chased the parent's fading colour: in Safari a headline
   stayed light on the light page for over a second, then snapped. While the colours blend, elements'
   own transitions are off, or they would chase them the same way. */
@property --bg{syntax:"<color>";inherits:true;initial-value:transparent}
@property --panel{syntax:"<color>";inherits:true;initial-value:transparent}
@property --ink{syntax:"<color>";inherits:true;initial-value:transparent}
@property --ink-2{syntax:"<color>";inherits:true;initial-value:transparent}
@property --ink-3{syntax:"<color>";inherits:true;initial-value:transparent}
@property --dim{syntax:"<color>";inherits:true;initial-value:transparent}
@property --line{syntax:"<color>";inherits:true;initial-value:transparent}
@property --line-2{syntax:"<color>";inherits:true;initial-value:transparent}
@property --drop{syntax:"<color>";inherits:true;initial-value:transparent}
@property --glass{syntax:"<color>";inherits:true;initial-value:transparent}
@property --glass-edge{syntax:"<color>";inherits:true;initial-value:transparent}
@property --glass-rim{syntax:"<color>";inherits:true;initial-value:transparent}
@property --glass-spec{syntax:"<color>";inherits:true;initial-value:transparent}
@property --glass-spec2{syntax:"<color>";inherits:true;initial-value:transparent}
@property --glass-gloss{syntax:"<color>";inherits:true;initial-value:transparent}
@property --glass-bounce{syntax:"<color>";inherits:true;initial-value:transparent}
html.shifting{transition:--bg .6s ease,--panel .6s ease,--ink .6s ease,--ink-2 .6s ease,--ink-3 .6s ease,--dim .6s ease,--line .6s ease,--line-2 .6s ease,--drop .6s ease,--glass .6s ease,--glass-edge .6s ease,--glass-rim .6s ease,--glass-spec .6s ease,--glass-spec2 .6s ease,--glass-gloss .6s ease,--glass-bounce .6s ease}
html.shifting *,html.shifting *::before,html.shifting *::after{transition:none!important}
.build{display:flex;flex-wrap:wrap;gap:1.6rem;margin:.2rem 0 0}
.build div{display:grid;gap:.15rem}
.build dt{font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-2)}
.build dd{margin:0;font-size:1.15rem;font-weight:400;color:var(--ink)}
.build-scope{margin:0;font-size:.92rem;line-height:1.55;color:var(--ink-2)}
.details{padding-block:clamp(4rem,10vw,8rem)}
.facts{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,340px),1fr));gap:16px}
.fact{padding:clamp(1.5rem,3.2vw,2rem);border-radius:42px;display:grid;gap:.7rem;align-content:start}
.fact .label{margin:0}
.fact .body{margin:0}
.build-what,.see-work{padding-block:clamp(4rem,10vw,8rem)}

/* ======================================================================
   One system (2026-10): the same width, rhythm, card and motion on every
   page. Three radii (pill, card, inner), one section spacing, one card
   padding. Later rules win, so this block sits last on purpose.
   ====================================================================== */
:root{--r-pill:99px;--r-card:32px;--r-in:16px;--wrap:1240px;--sec:clamp(88px,13vh,160px);--pad:clamp(24px,2.6vw,36px);
  --out:cubic-bezier(.16,1,.3,1);--spring:linear(0,.36 8%,.82 19%,1.03 29%,1.07 37%,1.03 50%,1 68%,1)}
section,.footer{padding-inline:max(var(--gut),calc((100vw - var(--wrap))/2))}
.d1,.d2,.d3{text-wrap:balance}
.body{text-wrap:pretty}
.d2{font-size:clamp(2rem,4.2vw,4rem)}
b,strong{font-weight:400;color:var(--ink)}

/* Sections: the hero fills the screen, everything after it shares one gap. */
.scene{min-height:auto;padding-block:calc(var(--sec)/2)}
.hero.scene{min-height:100svh;padding-top:120px;padding-bottom:64px}
.hero.intro{min-height:min(70svh,680px)}
.hero h1{margin-top:1.6rem}
.band,.calc,.more,.offer,.details,.build-what,.see-work{padding-block:calc(var(--sec)/2)}
.cta.scene{padding-block:var(--sec)}
.promise{min-height:auto;padding-block:var(--sec)}
.sec-head{display:grid;gap:1rem;margin-bottom:clamp(32px,5vh,56px)}
.sec-head .d2{max-width:18ch}
.sec-head .body{max-width:50ch}
.process .label + .d2,.promise .label + .d2{margin-top:1rem;max-width:20ch}
.sec-foot{display:flex;flex-wrap:wrap;align-items:center;gap:14px 28px;margin-top:clamp(28px,4vh,44px)}
.textlink{display:inline-block;font-weight:400;color:var(--ink-2);text-decoration:none;padding-block:12px;line-height:20px;background:linear-gradient(currentColor,currentColor) 0 calc(100% - 9px)/100% 1px no-repeat;transition:background-size .5s var(--out),color .3s}
.textlink:hover{color:var(--ink);background-size:0 1px;background-position:100% calc(100% - 9px)}

/* One card. */
.glass{border-radius:var(--r-card)}
.nav.glass,.chip.glass{border-radius:var(--r-pill)}
.fact,.panel,.plan{padding:var(--pad);border-radius:var(--r-card);display:grid;gap:.8rem;align-content:start}
.facts{grid-template-columns:repeat(3,minmax(0,1fr));gap:16px}
.panels{gap:16px}
.cta-card{border-radius:var(--r-card)}
.chips{margin-top:0}
.steps{gap:clamp(32px,5vh,56px)}
.glow{position:absolute;inset:0;z-index:-1;border-radius:inherit;pointer-events:none;opacity:0;transition:opacity .5s ease;
  background:radial-gradient(380px circle at var(--mx,50%) var(--my,50%),color-mix(in srgb,var(--ink) 10%,transparent),transparent 62%)}
.fact:hover .glow,.panel:hover .glow,.plan:hover .glow{opacity:1}

/* Four short claims on a hairline, in place of the old pinned stack. */
.proof{list-style:none;padding:0;margin:0;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(20px,3vw,48px)}
.proof li{display:grid;gap:.7rem;align-content:start;padding-top:22px;border-top:1px solid var(--line)}
.proof-n{font-size:.72rem;font-weight:400;letter-spacing:.16em;color:var(--ink-3);font-variant-numeric:tabular-nums}

/* Prices side by side: name, price, one line, what is in it. Rows line up across the cards. */
.plans{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:16px}
.plans--3{grid-template-columns:repeat(3,minmax(0,1fr))}
.plan{grid-template-rows:auto auto minmax(3.3em,auto) 1fr}
.plan .body{max-width:none;font-size:1rem;line-height:1.5}
.plan-price{display:grid;gap:2px;font-size:.9rem;font-weight:400;color:var(--ink-3)}
.plan-price b{font-size:clamp(2rem,3vw,2.9rem);font-weight:200;letter-spacing:-.04em;line-height:1.05;color:var(--ink);font-variant-numeric:tabular-nums}
.ticks{list-style:none;margin:.4rem 0 0;padding:1rem 0 0;border-top:1px solid var(--line);display:grid;gap:.6rem;align-content:start;font-size:.95rem;line-height:1.4;color:var(--ink-2)}
.ticks li{position:relative;padding-left:1.6em}
.ticks li::before{content:"";position:absolute;left:.1em;top:.3em;width:.72em;height:.36em;border-left:1.5px solid var(--ink-3);border-bottom:1.5px solid var(--ink-3);rotate:-45deg}

/* A plain list with the price at the end of each line. */
.rows{list-style:none;margin:0;padding:0;border-top:1px solid var(--line)}
.rows li{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.25fr) auto;gap:6px 32px;align-items:baseline;padding:22px 0;border-bottom:1px solid var(--line)}
.rows .body{max-width:none}
.rows li > *{transition:translate .6s var(--out)}
.row-price{font-size:clamp(1.4rem,2.2vw,2.1rem);font-weight:200;letter-spacing:-.02em;font-variant-numeric:tabular-nums}

/* Estimate panels use the same spacing. */
.panel .d3 + .body,.readout .figure + .body{margin-top:.6rem}
.panel .body + .body{margin-top:.5rem}
#tier-list{margin-top:1rem}
.stack-form{display:grid;gap:1rem}
dialog .label + .d2{margin-top:.4rem}

/* Words that rise out of a mask (fusion.js splits [data-words]). */
.wd{display:inline-block;overflow:hidden;vertical-align:top;padding-bottom:.14em;margin-bottom:-.14em}
.wd > i{display:inline-block;font-style:normal;will-change:transform}

@media (max-width:1000px){.facts,.plans,.plans--3,.proof{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:640px){
  .facts,.plans,.plans--3,.proof{grid-template-columns:minmax(0,1fr)}
  .plan{grid-template-rows:none}
  .rows li{grid-template-columns:minmax(0,1fr) auto}
  .rows .body{grid-column:1 / -1;grid-row:2}
  .hero.scene{min-height:88svh;padding-top:104px;align-content:start}
  .hero.intro{min-height:auto}
}

/* Motion that needs no script: a springy press, a fill on hover, the bar that steps aside. */
@media (prefers-reduced-motion:no-preference){
  .pill{transition:scale .55s var(--spring),background-color .35s ease,color .35s ease,box-shadow .45s ease}
  .pill:active{scale:.95}
  .nav{transition:translate .7s var(--out)}
  html.nav-away .nav{translate:0 -160%}
  .chip{transition:scale .55s var(--spring)}
  .chip:hover{scale:1.04}
  .option{transition:scale .5s var(--spring)}
  .option:active{scale:.985}
}
@media (hover:hover){
  .pill:not(.solid):hover{background:var(--ink);color:var(--bg)}
  .pill.solid:hover{box-shadow:0 14px 34px -14px color-mix(in srgb,var(--ink) 60%,transparent)}
  .rows li:hover > :first-child{translate:10px 0}
  .rows li:hover > .row-price{translate:-10px 0}
  .nav .links a:not(.lang){background:linear-gradient(currentColor,currentColor) 0 100%/0 1px no-repeat;transition:background-size .45s var(--out),color .3s;padding-block:4px}
  .nav .links a:not(.lang):hover{background-size:100% 1px;color:var(--ink)}
}

/* ======================================================================
   Gallery (2026-10, chosen by Santi from drafts/home-oct, draft 2B).
   Greys only, Instrument Sans at one weight, sentence case, 5px corners,
   no glass. The orb and the logo mark are the only colour. This block
   sits last and overrides everything above it.
   ====================================================================== */
:root{--font:"Instrument Sans",system-ui,sans-serif;--gut:clamp(20px,4vw,56px);--gutw:max(var(--gut),calc((100vw - var(--wrap))/2));
  --r-pill:5px;--r-card:5px;--r-in:5px;--sec:clamp(140px,22vh,240px);--pad:clamp(24px,2.4vw,32px);
  --orb:min(375px,42vh);--orb-s:min(210px,25vh);--orb-fill:linear-gradient(139deg,#96BEEE 8%,#68EC9B 36%,#FFA212 64%,#E2362C 94%)}
html[data-theme="dark"]{--bg:#0e0e0d;--panel:#171716;--ink:#e9e8e4;--ink-2:#b4b3ae;--ink-3:#8a8983;--dim:#8a8983;--line:rgba(255,255,255,.08);--line-2:rgba(255,255,255,.34);--drop:rgba(0,0,0,.55)}
html[data-theme="light"]{--bg:#f4f3f1;--panel:#eceae6;--ink:#262626;--ink-2:#4d4d4d;--ink-3:#6c6b67;--dim:#6c6b67;--line:rgba(0,0,0,.08);--line-2:rgba(0,0,0,.38);--drop:rgba(90,50,40,.22)}
html,body{font-weight:400}
main::before,.glass::before,.glass::after,.glow{display:none}
:focus-visible,.input:focus-visible{outline:2px solid var(--ink);outline-offset:3px}
.skip{position:fixed;left:12px;top:-80px;z-index:30;padding:12px 16px;border-radius:5px;background:var(--ink);color:var(--bg);text-decoration:none}
.skip:focus{top:12px}

/* Type: one weight, small sizes, hierarchy from size and grey. */
.d1,.hero h1{font-size:clamp(26px,1.2rem + 1.2vw,36px);font-weight:400;letter-spacing:-.02em;line-height:1.3}
.d2{font-size:clamp(24px,1.2rem + .8vw,30px);font-weight:400;letter-spacing:-.02em;line-height:1.25}
.d3{font-size:clamp(18px,1rem + .3vw,20px);font-weight:400;letter-spacing:-.01em;line-height:1.3}
.body{font-size:clamp(16px,.96rem + .15vw,17px);line-height:1.6}
.label,.footer h4,.build dt,.proof-n{font-size:14px;font-weight:400;letter-spacing:0;line-height:1.5;text-transform:none;color:var(--ink-3)}
.choice small,.sites small{font-size:12px;letter-spacing:0;text-transform:none}
.figure,.plan-price b,.row-price,.sites button,.choice b,.menu-sheet a{font-weight:400}
.figure{font-size:clamp(3rem,6vw,4.6rem);letter-spacing:-.03em}
.plan-price b{font-size:32px;letter-spacing:-.03em}
.row-price{font-size:clamp(20px,1.1rem + .5vw,24px)}
.menu-sheet a{font-size:22px}
.hint,.option small,.scale,.tag,.footer-base,.link,.ticks{font-size:14px;font-weight:400}

/* Surfaces: flat panels with a hairline. */
.glass,.fact,.panel,.plan,.cta-card,dialog.sheet{background:var(--panel);border:1px solid var(--line);border-radius:5px;box-shadow:none}
dialog.sheet{-webkit-backdrop-filter:none;backdrop-filter:none}
dialog.sheet::backdrop{-webkit-backdrop-filter:none;backdrop-filter:none;background:color-mix(in srgb,var(--bg) 78%,transparent)}
.nav,.nav.glass{inset:0 0 auto;padding:12px var(--gutw);border:0;border-radius:0;background:var(--bg);gap:16px}
.nav .brand{min-height:44px;font-size:16px}
.nav .links a:not(.lang){position:relative;display:inline-flex;align-items:center;min-height:44px;font-size:15px}
/* Short words (Work, Log in) are narrower than a fingertip: the tap area is widened to 44px around them, unseen. */
.nav .links a:not(.lang)::after{content:"";position:absolute;top:0;bottom:0;left:50%;min-width:max(100%,44px);transform:translateX(-50%)}
.nav .lang,.theme-btn,.menu-btn{display:grid;place-items:center;width:44px;height:44px;padding:0;border:1px solid var(--line-2);border-radius:5px;font-size:14px;color:var(--ink)}
.menu-btn{display:none}
.theme-btn{position:relative;font-size:0}
.theme-btn::before{content:"";position:absolute;inset:0;margin:auto;width:14px;height:14px;border-radius:50%;border:1.5px solid var(--ink);background:linear-gradient(90deg,var(--ink) 50%,transparent 50%)}
.menu-sheet,.menu-sheet.glass{top:68px;left:0;right:0;padding:8px var(--gutw) 20px;border:0;border-bottom:1px solid var(--line);border-radius:0;background:var(--bg)}
.menu-sheet a{display:flex;align-items:center;min-height:52px;padding:0;border-radius:0}
.pill,button.pill{display:inline-flex;align-items:center;justify-content:center;min-height:48px;padding:0 22px;border:1px solid var(--line-2);border-radius:5px;color:var(--ink);font-weight:400}
.pill.solid{background:var(--ink);border-color:var(--ink);color:var(--bg)}
.seg button,.tag,.option,.choice,.input,.device,.map-embed{border-radius:5px}
.seg button,.option,.choice,.input{border-color:var(--line-2)}
.seg button,.choice{min-height:44px}
.seg button{padding-inline:16px;font-size:14px}
.screen,.device.phone .screen{border-radius:3px}
.sites button{min-height:48px}
.link{display:inline-flex;align-items:center;min-height:44px}
.sheet-close{width:44px;height:44px}
input[type=range]{height:44px}
.footer-links{gap:0}
.footer-links a{display:inline-flex;align-items:center;min-height:44px;min-width:44px}
.footer .brand{min-height:44px}
.chips{gap:0;margin-top:32px}
.chip,.chip.glass{padding:0;border:0;background:none;font-size:14px;color:var(--ink-3)}
.chip + .chip::before{content:"·";margin:0 .6em}

/* Sections: centred headline, then quiet bands with a lot of air. */
.band,.calc,.more,.offer,.details,.build-what,.see-work{padding-block:calc(var(--sec)/2)}
.hero.scene,.hero.intro{display:grid;gap:20px;justify-items:center;align-content:start;min-height:auto;padding-top:clamp(112px,16vh,168px);padding-bottom:calc(var(--sec)/2);text-align:center}
.hero h1{max-width:24ch;margin:0}
.hero .body,.intro .body{max-width:34em;margin:0}
.hero-actions{justify-content:center}
.sec-head{gap:12px}
.sec-head .d2{max-width:26ch}
.cta-card{padding:clamp(24px,5vw,72px)}

/* The orb. One fixed element that fusion.js moves between the empty .orb-slot spaces;
   it is never placed over text. Colour (.orb-c) sits under silver (.orb-m), whose
   opacity is how far the colour has drained. Images come from tools/bake-orb-metal.mjs. */
.orb-slot{display:block;width:var(--orb-s);height:var(--orb-s);margin:0 0 28px var(--at,0%)}
.hero .orb-slot{width:var(--orb);height:var(--orb);margin:0 0 20px}
.cta-card .orb-slot{margin:0 auto 8px}
.footer .orb-slot{margin-bottom:20px}
.at-a{--at:8%}.at-b{--at:22%}.at-c{--at:0%}.at-d{--at:0%}
.orb{--orb:min(375px,42vh);z-index:2;width:var(--orb);height:var(--orb);transform:none;opacity:0}
.orb-ball,.orb-c,.orb-m{position:absolute;inset:0;border-radius:50%}
.orb-ball{will-change:transform;filter:saturate(1.2) contrast(1.03)}
.orb-c,.orb-m{background:url(../img/orb/color-dark.webp?v=2) center/100% 100% no-repeat}
.orb-m{display:none}
html[data-theme="light"] .orb-c{background-image:url(../img/orb/color-light.webp?v=2)}
.orb-hl{position:absolute;left:20%;top:13%;width:36%;height:28%;border-radius:50%;background:radial-gradient(closest-side,rgba(255,255,255,.42),rgba(255,255,255,0));display:block;filter:none;transform:none}
.orb-shadow{position:absolute;left:10%;right:10%;top:88%;height:20%;border-radius:50%;background:radial-gradient(closest-side,var(--drop),transparent)}
html.orb-front .orb{z-index:20}
/* Arriving from another page: the orb is already lit in its place at the top, and the page is dark
   until fusion.js brings it up. The top offset must match .hero's padding-top. */
/* Centred with left, not 50vw: vw counts a scrollbar that is always drawn (a Mac with a mouse), which put
   the orb half a scrollbar to the right of its space, so it stepped sideways as each page took over. */
.is-covered .orb,.booting .orb{left:calc(50% - var(--orb)/2)}
.is-covered .orb{opacity:1;transform:translate(0,clamp(112px,16vh,168px))}
.is-covered body>*:not(.orb){opacity:1}
/* :not(.orb) is here for weight: without it the line above wins and the text shows until fusion.js runs. */
.is-covered body>main:not(.orb),.is-covered body>.footer:not(.orb){opacity:0}
.booting .orb{opacity:.16;transform:translate(0,calc(50vh - var(--orb)/2)) scale(.3)}
@supports (height:1svh){.booting .orb{transform:translate(0,calc(50svh - var(--orb)/2)) scale(.3)}}
/* First visit on a slow connection: until the scripts arrive the dim orb breathes (a browser animation, no
   script needed), so the page never looks frozen. A quick page never shows it; fusion.js eases it back to size. */
@keyframes orb-wait{to{transform:scale(1.08)}}
.booting .orb-ball{animation:orb-wait 1.1s ease-in-out .4s infinite alternate}
/* No script, or reduced motion: nothing travels. Each space shows a still orb. */
.no-js .orb{display:none}
.no-js .orb-slot{background:url(../img/orb/color-dark.webp?v=2) center/contain no-repeat}
.no-js .hero .orb-slot{background-image:url(../img/orb/color-dark.webp?v=2)}
@media (prefers-reduced-motion:reduce){
  .orb{display:none;transform:none}
  .orb-slot{background:url(../img/orb/color-dark.webp?v=2) center/contain no-repeat}
  .hero .orb-slot{background-image:url(../img/orb/color-dark.webp?v=2)}
  html[data-theme="light"] .orb-slot{background-image:url(../img/orb/color-light.webp?v=2)}
  html[data-theme="light"] .hero .orb-slot{background-image:url(../img/orb/color-light.webp?v=2)}
}

/* Text is lit by the orb: a section's copy sits one step dimmer until the orb reaches it. */
.motion main section :is(.body,.ticks,.frame-cap span){transition:color 1.4s var(--out)}
.motion main section:not(.lit) :is(.body,.ticks,.frame-cap span){color:var(--dim)}

/* Client sites as framed pieces. */
.frames{display:grid;gap:20px}
.frame{display:block;padding:12% 10% 0;border-radius:5px;background:var(--panel);text-decoration:none;transition:translate .6s var(--out)}
.frame-in{display:block;overflow:hidden;border-radius:3px;box-shadow:0 18px 40px var(--drop)}
.frame img{display:block;width:100%;height:auto;aspect-ratio:16/9;object-fit:cover;object-position:top}
.frame-cap{display:flex;justify-content:space-between;gap:12px;margin:10% -4% 0;padding-bottom:16px;font-size:14px}
.frame-cap b{font-weight:400;color:var(--ink)}
.frame-cap span{color:var(--ink-3)}
@media (hover:hover){.frame:hover{translate:0 -6px}}

/* Rows that travel sideways. Phones and reduced motion: a swipe row. Desktop with motion
   (html.hz-on, set by fusion.js): the section holds and the row slides as the page scrolls. */
.sum{margin:0 0 16px;font-size:14px;color:var(--ink-3);font-variant-numeric:tabular-nums}
.hz-view{margin-inline:calc(var(--gutw)*-1);padding-inline:var(--gutw);overflow-x:auto;scroll-snap-type:x mandatory;scroll-padding-inline:var(--gutw);overscroll-behavior-x:contain;scrollbar-width:none}
.hz-view::-webkit-scrollbar{display:none}
.facts.track,.plans.track{display:flex;gap:12px;width:max-content}
.track > *{flex:0 0 min(82vw,340px);scroll-snap-align:start}
.facts.track .fact{min-height:200px;align-content:end}
.plan{grid-template-rows:auto auto auto 1fr}
.plan-price{overflow:hidden}
.hz-on .hz{--orb-s:min(160px,18vh);padding-block:0;overflow-x:clip}
.hz-on .hz .orb-slot{margin-bottom:16px}
.hz-on .hz-pin{position:sticky;top:0;display:grid;grid-template-columns:minmax(0,1fr);align-content:safe center;height:100vh;padding-top:68px}
@supports (height:1svh){.hz-on .hz-pin{height:100svh}}
.hz-on .hz-view{overflow:visible;scroll-snap-type:none}
.hz-on .track{gap:16px;will-change:transform}
.hz-on .track > *{flex-basis:340px}
.hz-on .hz .sec-head{margin-bottom:32px}
.hz-on .hz .sec-foot{margin-top:28px}

/* Headline words rise out of their own masks, a line at a time (fusion.js). */
.wd{padding-bottom:.18em;margin-bottom:-.18em}

@media (min-width:900px){
  .frames{grid-template-columns:repeat(4,minmax(0,1fr))}
}
@media (min-width:600px) and (max-width:899px){.frames{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:767px){
  :root{--orb:238px;--orb-s:150px;--sec:140px}
  .orb{--orb:238px}
  .nav,.nav.glass{inset:0 0 auto;padding:12px var(--gut)}
  .nav .links{gap:8px}
  .nav .links a:not(.lang){display:none}
  .menu-btn{display:grid;gap:5px;align-content:center}
  .menu-btn span{width:18px;height:1.5px}
  .hero.scene,.hero.intro{padding-top:96px;min-height:auto}
  .cta.scene{padding-block:calc(var(--sec)*.75)}
}
@media (prefers-reduced-motion:no-preference){
  .nav{transition:none}
  html.nav-away .nav{translate:none}
}
@media (hover:hover){
  .pill:not(.solid):hover{background:var(--ink);color:var(--bg)}
  .pill.solid:hover{box-shadow:none;background:var(--ink-2);border-color:var(--ink-2)}
}
@media (max-width:767px){.is-covered .orb{transform:translate(0,96px)}}

/* ---- Estimate: four named stops, an orb for a thumb, figures that count ---- */
.figure .fromword{font-size:14px;font-weight:400;letter-spacing:0;margin-right:.7rem;color:var(--ink-3);vertical-align:.9em}
.reach{margin:.4rem 0 .6rem;font-size:14px;color:var(--ink-3);font-variant-numeric:tabular-nums}
.pick{display:grid;gap:4px}
.pick input[type=range]{height:44px}
.pick input[type=range]::-webkit-slider-runnable-track{height:2px;border-radius:2px;background:linear-gradient(90deg,var(--ink) var(--fill,33%),var(--line-2) var(--fill,33%))}
.pick input[type=range]::-webkit-slider-thumb{width:34px;height:34px;margin-top:-16px;border:0;border-radius:50%;
  background:url(../img/orb/color-dark.webp?v=2) center/100% 100% no-repeat;box-shadow:0 8px 14px -8px var(--drop);transition:transform .35s var(--spring)}
.pick input[type=range]::-moz-range-thumb{width:34px;height:34px;border:0;border-radius:50%;background:url(../img/orb/color-dark.webp?v=2) center/100% 100% no-repeat}
html[data-theme="light"] .pick input[type=range]::-webkit-slider-thumb,html[data-theme="light"] .pick input[type=range]::-moz-range-thumb{background-image:url(../img/orb/color-light.webp?v=2)}
.pick input[type=range]:active::-webkit-slider-thumb{transform:scale(1.18)}
.stops{position:relative;height:60px;margin:0 17px}
.stops button{position:absolute;top:0;left:0;width:25%;min-height:44px;padding:4px 0 0;border:0;background:none;color:var(--ink-3);font:400 14px/1.35 var(--font);text-align:center;cursor:pointer;transform:translateX(-50%)}
.stops button:nth-child(1){left:0;text-align:left;transform:none}
.stops button:nth-child(2){left:33.333%}
.stops button:nth-child(3){left:66.667%}
.stops button:nth-child(4){left:auto;right:0;text-align:right;transform:none}
.stops b{display:block;font-weight:400;transition:color .3s}
.stops span{display:block;font-variant-numeric:tabular-nums}
.stops .on b{color:var(--ink)}
.stops .on{color:var(--ink-2)}
.option.included{border-color:var(--line);background:color-mix(in srgb,var(--ink) 4%,transparent);cursor:default}
.option.included .price{color:var(--ink-3)}
.option .price{transition:color .3s}
.choice{transition:scale .5s var(--spring),background-color .3s,border-color .3s,color .3s}
.choice:active{scale:.95}
@keyframes rise{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:no-preference){
  .tags .tag,.summary > *,#days .choice,#slots .choice{animation:rise .55s var(--out) both}
  .tags .tag:nth-child(2),#days .choice:nth-child(2),#slots .choice:nth-child(2){animation-delay:.05s}
  .tags .tag:nth-child(3),#days .choice:nth-child(3),#slots .choice:nth-child(3){animation-delay:.1s}
  .tags .tag:nth-child(4),#days .choice:nth-child(4),#slots .choice:nth-child(4){animation-delay:.15s}
  .tags .tag:nth-child(5),#days .choice:nth-child(5),#slots .choice:nth-child(5){animation-delay:.2s}
  .tags .tag:nth-child(6){animation-delay:.25s}
}
.stops .fr{display:inline}
@media (max-width:767px){
  .stops{height:92px;margin-inline:17px}
  .stops button{font-size:13px}
  .stops b{width:min-content;margin:0 auto}
  .stops button:nth-child(1) b{margin:0 auto 0 0}
  .stops button:nth-child(4) b{margin:0 0 0 auto}
  .stops button:nth-child(4){width:30%}
}
@media (max-width:767px){.stops .fr{display:none}.stops{height:80px}}
/* Stop labels: each one gets its own column, names wrap instead of touching. */
.stops{height:auto;margin:0 17px;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;position:static}
.stops button{position:static;width:auto;transform:none;text-align:left;min-height:0;padding:8px 0 0;border-top:1px solid var(--line-2)}
.stops button:nth-child(4){width:auto;text-align:right}   /* the older 30% made it 18px wide inside its column */
.stops button:nth-child(n){left:auto;right:auto}
.stops b{font-size:14px;line-height:1.3;margin:0}
.stops .fr{display:none}
.stops button:not(.on){color:var(--ink-3)}
.stops .on{color:var(--ink)}
.stops span{font-size:14px;color:inherit}
@media (min-width:768px){.stops{gap:16px}}

/* ---- Pills for every button, tag and choice; cards and fields stay square-cornered. ---- */
:root{--r-pill:999px}
.pill,button.pill,.choice,.tag,.theme-btn,.seg button,.nav .lang,.chip,.tags .tag,.map-foot .pill{border-radius:999px}
.nav .lang,.theme-btn,.menu-btn{border-radius:999px}
.choice{min-height:44px}
.tag{padding:8px 16px}
/* ZIP check */
.zip-row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px}
.zip-row .input{border-radius:999px;padding-inline:20px}
.zip-row .pill{min-height:48px}
.zip .hint{margin-top:2px}
.estimate-more{margin-top:0}
/* Estimate: consistent spacing between the parts of each panel */
.calc .panel,.more .panel{padding:var(--pad)}
.calc .panel > *,.more .panel > *{margin:0}
.calc .panel > * + *,.more .panel > * + *{margin-top:24px}
.options,.tags,.choices{gap:8px}
.field{gap:10px}
.hint{line-height:1.5}
.calc .panel .readout + *{margin-top:24px}
/* Orb spaces on the estimate page */
.calc .orb-slot,.more .orb-slot{display:block;width:var(--orb-s);height:var(--orb-s);margin:0 0 20px var(--at,0%)}
.at-e{--at:0%}.at-f{--at:0%}
.more .orb-slot{margin-top:0}

/* Plain text pages (Privacy) and the page-not-found screen */
.doc{padding-top:0}
.doc-in{max-width:40em;margin-inline:auto}
.doc-in h2{margin:44px 0 12px}
.doc-in h2:first-child{margin-top:0}
.doc-in .body{max-width:none;margin:0 0 12px}
.doc-links{display:flex;flex-wrap:wrap;gap:4px 28px;margin:4px 0 0}
.doc-links .textlink{color:var(--ink)}
.doc-date{margin:44px 0 0;padding-top:20px;border-top:1px solid var(--line);font-size:14px;color:var(--ink-3)}
.hero.lost{min-height:calc(100svh - 40px);align-content:center}
.steps-note{max-width:34em;margin-top:28px;color:var(--ink-3)}
/* Who you're hiring (Home) */
.at-g{--at:14%}
.who-text{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20px clamp(32px,5vw,72px);max-width:64em}
.who-text .body{max-width:none;margin:0;padding-top:20px;border-top:1px solid var(--line)}
@media (max-width:760px){.who-text{grid-template-columns:1fr}}
/* The orb at rest scrolls with the page (see flow in fusion.js) */
html.orb-flow .orb{position:absolute}
/* As part of the page, the orb made the page wider than the screen each time it left past the right edge
   (240px at phone size), so the page could slide sideways. The body is now the box it is placed in and
   cuts it off at the sides. html needs the same rule: without it the body's is handed to the window
   and the body itself cuts nothing. */
html{overflow-x:clip}
body{position:relative}
/* What we build (Home): every card on the same three lines. The label sits at the top, the
   titles end on one line and the text starts on one line, however long each is. The thin line
   along the top is one slice of the orb's colours per card, so the row reads as one piece. */
.facts.track .fact{position:relative;min-height:232px;grid-template-rows:auto auto auto 1fr;align-content:stretch;gap:0;padding-top:28px;overflow:hidden}
.facts.track .fact .label{grid-row:1;margin-bottom:22px;color:var(--ink-2)}
.facts.track .fact .d3{grid-row:2;display:flex;align-items:flex-end;min-height:2.6em;margin:0 0 10px;font-size:clamp(20px,1.1rem + .35vw,23px);line-height:1.3;color:var(--ink)}
.facts.track .fact .body{grid-row:3;max-width:none}
/* ---------- Device frames (Home pair, Work stage) ----------
   A picture of the device with its screen cut out lies over the real page (tools/bake-devices.py).
   .dev-screen sits exactly where the hole is; the picture lets clicks through to the page. */
.dev{position:relative;width:100%;isolation:isolate}
.dev--mac{aspect-ratio:1258/747}
.dev--phone{aspect-ratio:1368/2730}
.dev-frame{position:absolute;inset:0;z-index:1;width:100%;height:100%;pointer-events:none;user-select:none} /* always above everything in the screen, island included */
/* The shadow is its own shape behind the device. Cast from the picture, it also fell through the
   hole onto the top of the screen and read as a dark line under the bezel. */
.dev::before{content:"";position:absolute;z-index:-1;pointer-events:none}
.dev--mac::before{left:3%;right:3%;bottom:-3.5%;height:9%;border-radius:50%;background:radial-gradient(closest-side,var(--drop),transparent)}
.dev--phone::before{inset:3% 7% 1%;border-radius:15%/7%;box-shadow:0 20px 34px var(--drop)}
.dev-screen{position:absolute;z-index:0;overflow:hidden;background:#000} /* its own layer: nothing inside it can rise above the picture */
/* The laptop's screen box reaches four pixels under the bezel on every side, with the hole's own
   rounded top corners: the hole's soft edge then always has the screen behind it, never the page. */
.dev--mac .dev-screen{left:9.46%;top:1.2%;width:81.08%;height:87.82%;border-radius:1.08% 1.08% .2% .2% / 1.68% 1.68% .3% .3%}
.dev--phone .dev-screen{left:5.921%;top:1.978%;width:88.158%;height:96.044%;border-radius:15.4%/7.1%}
.dev-screen iframe{position:absolute;left:0;top:0;border:0;transform-origin:0 0;background:#fff}
/* The phone's page starts below the island, as it does on a real phone; the strip beside the
   island is the page's own top colour and overlaps the page by a pixel so no seam shows. */
.dev-bar{position:absolute;left:0;top:0;z-index:1;width:100%;height:calc(6.18% + 1px);background:var(--page-glow,none) no-repeat var(--page,#000);transition:background-color .5s ease}
.dev--phone .dev-screen iframe{top:6.18%}
/* Above a photo the strip's lower edge melts into the picture instead of ending in a line. */
.dev.is-photo .dev-bar{height:calc(6.18% + 14px);background:linear-gradient(to bottom,var(--page,#000) calc(100% - 14px),transparent)}
.dev-off{position:absolute;inset:0;z-index:2;background:#000;pointer-events:none;transition:opacity .6s ease} /* above the island strip, so a dark screen is dark all over */
.dev.is-lit .dev-off{opacity:0}
/* Touch screens: a framed page would take every swipe that starts on it, and going down this page a thumb
   lands on the laptop or the phone. There a frame sleeps (swipes pass through to this page) until it is
   tapped; fusion.js puts it back to sleep. The sentence above the stage says so. */
.by-touch{display:none}
@media (pointer:coarse){
  .by-mouse{display:none}
  .by-touch{display:inline}
  .dev:not(.is-awake) .dev-screen iframe{pointer-events:none}
}
.motion .dev{opacity:0;transform:translateY(34px) scale(.985);transition:opacity .9s var(--out),transform 1.1s var(--out)}
.motion .dev.is-in{opacity:1;transform:none}
/* Home: laptop and phone together */
.pair{position:relative;max-width:1060px;margin-inline:auto;padding:0 9% 5% 0}
.pair .dev--phone{position:absolute;right:0;bottom:0;width:21%}
.motion .pair .dev--phone{transition-delay:.22s}
.show-sites{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;list-style:none;padding:0;margin:clamp(28px,5vh,48px) 0 0}
.show-sites button{min-height:44px;padding:0 18px;border:1px solid var(--line-2);border-radius:999px;background:none;color:var(--ink-2);font:400 14px/1 var(--font);cursor:pointer;transition:background .3s,color .3s,border-color .3s,scale .25s var(--out)}
.show-sites button:active{scale:.96}
.show-sites button[aria-pressed="true"]{background:var(--ink);color:var(--bg);border-color:var(--ink)}
@media (hover:hover){.show-sites button:not([aria-pressed="true"]):hover{color:var(--ink);border-color:var(--ink)}}
.show-note{max-width:62ch;margin:18px auto 0;text-align:center}
/* Work: one device at a time */
.devstage{position:relative;display:grid;justify-items:center;align-items:center;width:100%;max-width:1080px;margin-inline:auto}
.devstage .dev{grid-area:1/1}
.devstage .dev--phone{width:min(330px,74%)}
.motion .devstage .dev.is-in{transition:opacity .45s var(--out),transform .7s var(--out),visibility 0s}
.devstage[data-mode="mac"] .dev--phone,.devstage[data-mode="phone"] .dev--mac{position:absolute;opacity:0;visibility:hidden;pointer-events:none}
.motion .devstage[data-mode="mac"] .dev--phone,.motion .devstage[data-mode="phone"] .dev--mac{transform:translateY(18px) scale(.94);transition:opacity .3s ease,transform .45s ease,visibility 0s .45s}
@media (max-width:640px){
  .pair{padding:0 0 16% 0}
  .pair .dev--mac{width:112%;margin-left:-6%}
  .pair .dev--phone{width:30%;right:2%}
}
/* ---------- One block style for every card (asked for by Santi after the What we build row) ----------
   Label at the top, a brighter title, and a 2px line along the top edge that is one slice of the
   orb's colours: a row of cards shares the whole run, blue to red; a card on its own carries all of it. */
.fact,.plan,.panel,.cta-card{position:relative}
.fact::before,.plan::before,.panel::before,.cta-card::before{content:"";display:block;position:absolute;inset:-1px -1px auto -1px;z-index:1;height:2px;padding:0;border-radius:5px 5px 0 0;-webkit-mask:none;mask:none;pointer-events:none;opacity:.85;
  background:linear-gradient(90deg,#96BEEE 8%,#68EC9B 36%,#FFA212 64%,#E2362C 94%) calc(var(--i,0) / max(var(--n,1) - 1, 1) * 100%) 0 / calc(var(--n,1) * 100%) 100% no-repeat}
.facts{--n:6}.plans{--n:4}.plans--3{--n:3}.panels{--n:4}
.facts > :nth-child(2),.plans > :nth-child(2),.panels > :nth-child(2){--i:1}
.facts > :nth-child(3),.plans > :nth-child(3),.panels > :nth-child(3){--i:2}
.facts > :nth-child(4),.plans > :nth-child(4),.panels > :nth-child(4){--i:3}
.facts > :nth-child(5){--i:4}.facts > :nth-child(6){--i:5}
/* Estimate: the two panels in each row share one run */
.calc .panel,.more .panel{--n:2}
.calc .panel ~ .panel,.more .panel ~ .panel{--i:1}
.plan > .label,.panel > .label{color:var(--ink-2)}
.panels .panel{padding-top:28px}
.panels .panel > .label{margin-bottom:10px}
.panels .panel > .d3{display:flex;align-items:flex-end;min-height:2.6em;font-size:clamp(20px,1.1rem + .35vw,23px);line-height:1.3;color:var(--ink)}
.plan{padding-top:28px}
/* ---------- Who we build for: one line of trades drifting across the page (Home) ----------
   Three copies of the list sit in a row and each slides one full length, so the line never ends.
   It stops under the pointer; with reduced motion it is a plain wrapped list. */
.ticker{display:flex;overflow:hidden;margin:clamp(36px,6vh,64px) calc(var(--gutw)*-1) 0;-webkit-mask-image:linear-gradient(90deg,transparent,#000 9%,#000 91%,transparent);mask-image:linear-gradient(90deg,transparent,#000 9%,#000 91%,transparent)}
.ticker-row{display:flex;flex:none;margin:0;padding:0;list-style:none;animation:ticker 70s linear infinite}
.ticker-row li{white-space:nowrap;font-size:clamp(15px,.9rem + .25vw,18px);color:var(--ink-2)}
.ticker-row li::after{content:"·";margin-inline:1.1em;color:var(--ink-3)}
@media (hover:hover){.ticker:hover .ticker-row{animation-play-state:paused}}
@keyframes ticker{to{transform:translateX(-100%)}}
@media (prefers-reduced-motion:reduce){
  .ticker{flex-wrap:wrap;margin-inline:0;-webkit-mask-image:none;mask-image:none}
  .ticker-row{flex-wrap:wrap;gap:6px 0;animation:none}
  .ticker-row[aria-hidden]{display:none}
}

/* ---------- Scroll reveals ----------
   Hidden from the first paint and brought in by fusion.js (the same list is there: LABELS, SOLO,
   CARDS, BLOCKS), so nothing shows, vanishes and then animates. .in is put on as each one starts.
   Reduced motion, no script or no GSAP (.no-js): none of this applies and the page is plain. */
@media (prefers-reduced-motion:no-preference){
  html.js:not(.no-js) main :is(.sec-head > .label,.scene:not(.hero) > .label,
    .sec-head > .body,.sum,.sec-foot,.chips,.cta-card > p,.who-text > .body,.show-sites,.show-note,.ticker,.steps-note,.work-intro,.work-bar,.demo-note,.site-infos,
    .proof > li,.track > *,.plans > .plan,.panels > *,.rows > li,.steps > li,
    .cta-card,.device,[data-rise],.split > .panel):not(.in){opacity:0}
  html.js:not(.no-js) main :is([data-lines],[data-split],[data-words]){visibility:hidden}
}

/* ---------- The orb's turn between pages ----------
   fusion.js plays 24 pictures of the colour orb going round with its light and reflection held still
   (img/orb/turn-{dark,light}.webp, a 6 by 4 sheet, baked by tools/bake-orb-metal.mjs). While it plays
   (html.orb-turn) .orb-t shows one frame at a time and the single picture steps aside; frame 0 is that
   picture, so nothing changes at the hand-over. The silver layer stays above, as always. */
.orb-t{position:absolute;inset:0;border-radius:50%;opacity:0;background:url(../img/orb/turn-dark.webp?v=1) 0 0/600% 400% no-repeat}
html.orb-turn .orb-t{opacity:1}
html.orb-turn .orb-c{opacity:0}
.orb-m,.orb-hl{z-index:1}
/* Both change while the page scrolls: as layers of their own they are moved and faded without the ball being repainted. */
.orb-m{will-change:opacity}
.orb-shadow{will-change:transform,opacity}
