/* Home page only. Editorial: white, big type, one idea per screen, photos between statements. */
:root{--gutter:clamp(1.25rem,5vw,7rem)}
.bar{padding-left:var(--gutter);padding-right:var(--gutter)}
body{background:#fff}

.hero{position:relative;min-height:100vh;min-height:100dvh;display:flex;align-items:flex-end;overflow:hidden;
      isolation:isolate;background:#0e1a24}
.hero .media{position:absolute;inset:0;z-index:-2}
.hero video,.hero img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:50% 40%}
.hero .scrim{position:absolute;inset:0;z-index:-1;background:linear-gradient(0deg,rgba(6,18,28,.6) 0%,rgba(6,18,28,.15) 45%,rgba(6,18,28,0) 70%)}
.hero .copy{width:100%;padding:6rem var(--gutter) 7rem;color:#fff;text-align:center;display:flex;flex-direction:column;align-items:center}
.hero h1{font-weight:600;font-size:clamp(2.4rem,5.2vw,5.6rem);letter-spacing:-.035em;line-height:1.08;margin:0 0 1.2rem;max-width:20ch;
         text-shadow:0 2px 24px rgba(0,0,0,.25)}
.hero .lede{font-size:clamp(1.1rem,1.5vw,1.6rem);max-width:48ch;color:#e6edf2;margin:0 auto;text-shadow:0 1px 12px rgba(0,0,0,.35)}
.actions{display:flex;gap:.8rem;flex-wrap:wrap;justify-content:center;margin-top:2rem}
.btn{display:inline-block;text-decoration:none;padding:.9rem 1.6rem;border-radius:999px;font-weight:500;font-size:1rem;
     transition:transform .15s ease,background .15s ease}
.btn:active{transform:translateY(1px)}
.btn.primary{background:var(--accent);color:#fff}
.btn.primary:hover{background:var(--steel)}
.btn.quiet{border:1px solid var(--line);color:var(--ink);background:#fff}
.hero .btn.quiet{background:rgba(255,255,255,.14);border-color:rgba(255,255,255,.5);color:#fff;backdrop-filter:blur(6px)}
.hero .btn.quiet:hover{background:rgba(255,255,255,.24)}

/* Statements */
section{padding:clamp(6rem,12vw,11rem) var(--gutter)}
section h2{font-weight:600;font-size:clamp(2.2rem,5vw,5.2rem);letter-spacing:-.03em;line-height:1.04;margin:0 0 1.4rem;max-width:20ch}
section > p{font-size:clamp(1.1rem,1.4vw,1.5rem);color:var(--soft);max-width:44ch;margin:0}
/* Statement: centred, big */
.statement{text-align:center;padding-top:clamp(6rem,12vw,11rem)}
.statement h2{font-size:clamp(2.6rem,6vw,6.4rem);letter-spacing:-.035em;line-height:1.02;max-width:none;margin:0 auto 1.6rem}
.statement > p{font-size:clamp(1.15rem,1.6vw,1.7rem);margin:0 auto;max-width:46ch}
.numbers{list-style:none;padding:0;margin:clamp(3rem,6vw,5rem) auto 0;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:2rem;max-width:80rem}
.numbers b{display:block;font-weight:600;font-size:clamp(3rem,6.5vw,6.5rem);letter-spacing:-.04em;line-height:1}
.numbers span{display:block;color:var(--soft);margin-top:.6rem;font-size:1.05rem}

/* Full-bleed photos */
.bleed{position:relative;margin:0;aspect-ratio:16/8;min-height:24rem;max-height:90vh;overflow:hidden;background:#0e1a24}
.bleed img,.bleed video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.bleed figcaption{position:absolute;left:0;right:0;bottom:0;padding:1.6rem var(--gutter);color:#fff;font-weight:600;letter-spacing:-.02em;
  font-size:clamp(1.3rem,2.4vw,2.4rem);max-width:none;
  background:rgba(10,14,20,.28);border-top:1px solid rgba(255,255,255,.35);box-shadow:inset 0 1px 0 rgba(255,255,255,.25);
  -webkit-backdrop-filter:blur(12px) saturate(1.4);backdrop-filter:blur(12px) saturate(1.4)}
@supports (backdrop-filter:url(#glass-distort)) and (not (background:-webkit-named-image(apple-pay-logo-black))){
  .bleed figcaption{backdrop-filter:url(#glass-distort) blur(4px) saturate(1.4)}
}
.bleed figcaption span{display:block;font-weight:400;font-size:.55em;letter-spacing:0;color:#dbe5ec;margin-top:.2em}

/* Plans: rows, not cards */
.planlist{margin-top:clamp(2.5rem,4vw,4rem)}
.plan-row{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr) minmax(0,.8fr) minmax(0,2.2fr);gap:1rem 2.5rem;align-items:baseline;
          padding:1.8rem 0;border-top:1px solid var(--line)}
.plan-row:last-child{border-bottom:1px solid var(--line)}
.plan-row h3{font-weight:600;font-size:clamp(1.4rem,2.2vw,2rem);letter-spacing:-.02em;margin:0}
.plan-row .price{font-weight:500;font-size:clamp(1.3rem,2vw,1.8rem);letter-spacing:-.02em;white-space:nowrap}
.plan-row .price small{font-size:.85rem;color:var(--soft);font-weight:400}
.plan-row .sla{font-family:var(--mono);font-size:.78rem;letter-spacing:.08em;color:var(--accent)}
.plan-row p{color:var(--soft);font-size:.95rem;margin:0}
.plan-row.hi h3::after{content:"Most popular";display:inline-block;margin-left:.7rem;font-family:var(--mono);font-size:.62rem;
  letter-spacing:.12em;text-transform:uppercase;color:#2a1f05;background:var(--gold);padding:.2rem .5rem;border-radius:999px;vertical-align:middle}

.contact-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:4rem;margin-top:clamp(2rem,4vw,3.5rem);max-width:70rem}
.form button{background:var(--accent)}

/* Reveal */
.reveal{opacity:0;transform:translateY(16px);transition:opacity .7s ease,transform .7s cubic-bezier(.16,1,.3,1)}
.reveal.in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){ .reveal{opacity:1;transform:none;transition:none} video{display:none} }

@media (max-width:900px){
  .numbers{grid-template-columns:repeat(2,minmax(0,1fr))}
  .plan-row{grid-template-columns:minmax(0,1fr) auto;gap:.4rem 1.5rem}
  .plan-row p{grid-column:1 / 3}
  .contact-grid{grid-template-columns:1fr;gap:2.5rem}
  .bleed{aspect-ratio:4/3;min-height:0}
  .hero{min-height:100dvh}
}

/* Human / AI agent switch: bottom centre of the hero */
.mode{position:absolute;left:50%;bottom:1.4rem;transform:translateX(-50%);z-index:2;display:inline-flex;
      border:1px solid rgba(255,255,255,.45);border-radius:999px;padding:.2rem;background:rgba(6,18,28,.35);
      backdrop-filter:blur(8px)}
.mode button{border:0;background:none;font:inherit;font-size:.82rem;font-weight:500;color:#fff;padding:.45rem .95rem;
             border-radius:999px;cursor:pointer;white-space:nowrap}
.mode button.on{background:#fff;color:var(--accent)}
/* It sits on the hero's faded bottom edge, so once the page moves it read as a stray
   pill floating over the next section. It belongs to the hero only. */
.mode{transition:opacity .3s ease}
body.scrolled:not(.agent) .mode{opacity:0;pointer-events:none}
.hero .copy{padding-bottom:7rem}

/* Agent mode: the whole page becomes a document. */
body.agent{background:#0b1016;color:#d7e0e8}
body.agent .bar,body.agent .foot,body.agent main > :not(#agent-view){display:none}
body.agent #agent-view{display:block}
#agent-view{font-family:var(--mono);font-size:.86rem;line-height:1.55;max-width:none;margin:0;padding:1.2rem var(--gutter) 4rem}
.agent-top{display:flex;justify-content:space-between;align-items:center;gap:1rem;flex-wrap:wrap;color:#7f8f9d;
           border-bottom:1px solid #1f2a35;padding:.4rem 0 .8rem;margin-bottom:1.2rem;font-size:.76rem}
.agent-top a{color:#a9d6f5}
.agent-top button{border:1px solid #2b3946;background:none;color:#d7e0e8;font:inherit;padding:.35rem .7rem;border-radius:6px;cursor:pointer}
.agent-doc,.agent-json{white-space:pre-wrap;word-break:break-word;margin:0;font:inherit;color:#d7e0e8}
.agent-json{background:#0f161e;border:1px solid #1f2a35;border-radius:8px;padding:1rem;color:#a9d6f5}
@media (max-width:860px){
  .mode{bottom:1rem}
  .mode button{font-size:.76rem;padding:.4rem .7rem}
  #agent-view{font-size:.8rem;padding:1rem 1rem 3rem}
}

/* Wide screens: let the grids use the room. */
@media (min-width:1500px){
  .apps{grid-template-columns:repeat(6,minmax(0,1fr))}
  .split{gap:5rem}
}

/* Screenshot helper, see home.js */
.shot .hero{min-height:560px}
.shot .reveal,.shot .reveal .pills li,.shot .pills li{opacity:1;transform:none;transition:none}

/* Statement assembly */
.statement h2.split .ch{display:inline-block;opacity:0;filter:blur(6px);
  transform:translate(var(--dx),var(--dy)) rotate(var(--rot));
  transition:opacity .7s ease,filter .7s ease,transform .9s cubic-bezier(.16,1,.3,1);transition-delay:var(--d)}
.statement.go h2.split .ch{opacity:1;filter:none;transform:none}
.statement .numbers b{font-variant-numeric:tabular-nums}
.statement .numbers li{opacity:0;transform:translateY(14px);transition:opacity .6s ease,transform .7s cubic-bezier(.16,1,.3,1)}
.statement.go .numbers li{opacity:1;transform:none}
.statement.go .numbers li:nth-child(1){transition-delay:.5s}.statement.go .numbers li:nth-child(2){transition-delay:.62s}
.statement.go .numbers li:nth-child(3){transition-delay:.74s}.statement.go .numbers li:nth-child(4){transition-delay:.86s}
.shot .statement h2.split .ch,.shot .statement .numbers li{opacity:1;transform:none;filter:none;transition:none}
@media (prefers-reduced-motion:reduce){ .statement h2.split .ch,.statement .numbers li{opacity:1;transform:none;filter:none;transition:none} }

/* "And yours." the Apple way: vivid gradient ink, revealed by a soft wipe while the tracking tightens,
   then the gradient drifts slowly. No bounce, no blur. */
.statement .pop{display:inline-block;padding-right:.06em;
  background:linear-gradient(90deg,#0a84ff 0%,#5ac8fa 30%,#bf5af2 62%,#ff375f 100%);
  background-size:300% 100%;background-position:0% 50%;
  -webkit-background-clip:text;background-clip:text;color:transparent;-webkit-text-fill-color:transparent;
  opacity:0;letter-spacing:.06em;clip-path:inset(0 100% 0 0)}
.statement.go .pop{animation:
  pop-reveal 1.4s cubic-bezier(.2,.8,.2,1) 1.7s forwards,
  pop-drift 9s ease-in-out 3.1s infinite alternate}
@keyframes pop-reveal{0%{opacity:0;letter-spacing:.06em;clip-path:inset(0 100% 0 0)}
  30%{opacity:1}100%{opacity:1;letter-spacing:-.035em;clip-path:inset(0 -2% 0 0)}}
@keyframes pop-drift{0%{background-position:0% 50%}100%{background-position:100% 50%}}
.shot .statement .pop{animation:none;opacity:1;letter-spacing:-.035em;clip-path:none}
@media (prefers-reduced-motion:reduce){ .statement .pop{opacity:1;letter-spacing:-.035em;clip-path:none} .statement.go .pop{animation:none} }

/* Distorted glass: the bar and the switch refract whatever scrolls behind them
   (SVG fractal noise through backdrop-filter; Chrome and Edge. Others get plain frosted glass). */
.glass-defs{position:absolute;width:0;height:0;overflow:hidden}
.bar{background:rgba(247,249,251,.42);border-bottom:1px solid rgba(255,255,255,.55);
     box-shadow:inset 0 1px 0 rgba(255,255,255,.6),0 1px 0 rgba(0,63,97,.06);
     -webkit-backdrop-filter:blur(14px) saturate(1.5);backdrop-filter:blur(14px) saturate(1.5)}
@supports (backdrop-filter:url(#glass-distort)) and (not (background:-webkit-named-image(apple-pay-logo-black))){
  .bar{backdrop-filter:url(#glass-distort) blur(5px) saturate(1.5)}
}
.mode{-webkit-backdrop-filter:blur(10px) saturate(1.4);backdrop-filter:blur(10px) saturate(1.4);
      box-shadow:inset 0 1px 0 rgba(255,255,255,.35)}
@supports (backdrop-filter:url(#glass-distort)) and (not (background:-webkit-named-image(apple-pay-logo-black))){
  .mode{backdrop-filter:url(#glass-distort) blur(3px) saturate(1.4)}
}
body.agent .glass-defs{display:none}
/* The bar floats over the hero so the video refracts through it from the first frame. */
body:not(.agent) .bar{position:fixed;top:0;left:0;right:0}
body.agent .bar{position:sticky}

/* Dynamic island: full bar at the top; once scrolled, a dark pill that keeps the mark, the current
   section, the three links that matter and the button. On hover or tap the rest come back. */
#top-sentinel{position:absolute;top:0;left:0;width:1px;height:48px;pointer-events:none}
.island-now{display:none;border:0;background:none;font:inherit;font-size:.82rem;font-weight:500;color:#fff;
            padding:.35rem .2rem;cursor:pointer;white-space:nowrap;align-items:center;gap:.5rem}
.island-now .dot{width:.5rem;height:.5rem;border-radius:50%;background:#2ecc71;box-shadow:0 0 0 3px rgba(46,204,113,.25)}
body:not(.agent) .bar{transition:top .5s cubic-bezier(.2,.8,.2,1),left .5s cubic-bezier(.2,.8,.2,1),width .5s cubic-bezier(.2,.8,.2,1),
  padding .5s cubic-bezier(.2,.8,.2,1),border-radius .5s cubic-bezier(.2,.8,.2,1),transform .5s cubic-bezier(.2,.8,.2,1),
  background .5s ease,box-shadow .5s ease,gap .5s ease}
body.scrolled:not(.agent) .bar{top:.8rem;left:50%;right:auto;width:auto;max-width:calc(100vw - 2rem);transform:translateX(-50%);
  padding:.4rem .5rem .4rem .9rem;border-radius:999px;gap:1rem;background:rgba(10,14,20,.78);border:1px solid rgba(255,255,255,.14);
  box-shadow:0 14px 44px rgba(0,0,0,.35),inset 0 1px 0 rgba(255,255,255,.12)}
body.scrolled:not(.agent) .bar .brand b{display:none}
body.scrolled:not(.agent) .bar .brand img{filter:brightness(0) invert(1)}
body.scrolled:not(.agent) .bar .island-now{display:inline-flex}
body.scrolled:not(.agent) .bar .burger{display:none}
body.scrolled:not(.agent) .bar nav{flex:0 0 auto;gap:.95rem}
body.scrolled:not(.agent) .bar nav a{font-size:.82rem;color:#c9d3dc}
body.scrolled:not(.agent) .bar nav a:hover{color:#fff}
/* the ones that go: About and Contact (the button covers contact) */
/* About used to be dropped from the collapsed island to keep it short, back when the nav
   carried four items. The nav is Services, Plans, About now, so all three fit and hiding one
   only made the island look truncated. */
body.scrolled:not(.agent) .bar.open nav a[href="/about"]{animation:island-in .35s cubic-bezier(.2,.8,.2,1) both}
body.scrolled:not(.agent) .bar .cta{padding:.42rem .9rem;font-size:.8rem;background:#fff;color:var(--accent)}
@keyframes island-in{from{opacity:0;transform:translateX(-6px)}to{opacity:1;transform:none}}
@media (max-width:860px){
  body.scrolled:not(.agent) .bar nav{display:none}
  body.scrolled:not(.agent) .bar.open nav{display:flex;position:absolute;top:calc(100% + .5rem);left:0;right:0;flex-direction:column;gap:.2rem;
    background:#0a0e14;border:1px solid rgba(255,255,255,.14);border-radius:18px;padding:.8rem 1rem;box-shadow:0 14px 44px rgba(0,0,0,.35)}
  body.scrolled:not(.agent) .bar.open nav a{padding:.5rem 0;display:block}
}

/* here. / now. glitch: two offset colour copies slice and jitter, the colours change every time,
   with a white flash and a scanline band */
.hero h1 .gl{position:relative;display:inline-block;--g1:#1ac6ff;--g2:#ff375f}
.hero h1 .gl.go{animation:gl-base .6s steps(2,end) both}
.hero h1 .gl.go::before,.hero h1 .gl.go::after{content:attr(data-text);position:absolute;left:0;top:0;width:100%;overflow:hidden;pointer-events:none;mix-blend-mode:screen}
.hero h1 .gl.go::before{color:var(--g1);animation:gl-a .6s steps(4,end) both}
.hero h1 .gl.go::after{color:var(--g2);animation:gl-b .6s steps(4,end) both}
.hero h1 .gl.go .band{content:"";position:absolute;left:-.1em;right:-.1em;top:40%;height:.12em;background:linear-gradient(90deg,transparent,var(--g1),#fff,var(--g2),transparent);
  mix-blend-mode:screen;pointer-events:none;animation:gl-band .6s linear both}
@keyframes gl-base{0%,100%{transform:none;opacity:1;filter:none}15%{color:var(--g1);transform:translateX(-.03em) skewX(-6deg)}30%{color:#fff;opacity:.85;filter:brightness(1.6)}
  50%{color:var(--g2);transform:translateX(.03em) skewX(5deg)}70%{color:#fff;opacity:.9;filter:brightness(1.3)}}
@keyframes gl-a{0%{clip-path:inset(10% 0 60% 0);transform:translate(-.08em,-.02em)}25%{clip-path:inset(40% 0 20% 0);transform:translate(.06em,.02em)}
  50%{clip-path:inset(70% 0 5% 0);transform:translate(-.05em,0)}75%{clip-path:inset(20% 0 50% 0);transform:translate(.07em,-.02em)}100%{clip-path:inset(0 0 100% 0);transform:none}}
@keyframes gl-b{0%{clip-path:inset(60% 0 10% 0);transform:translate(.08em,.02em)}25%{clip-path:inset(5% 0 75% 0);transform:translate(-.06em,-.02em)}
  50%{clip-path:inset(30% 0 40% 0);transform:translate(.05em,0)}75%{clip-path:inset(80% 0 0 0);transform:translate(-.07em,.02em)}100%{clip-path:inset(0 0 100% 0);transform:none}}
@keyframes gl-band{0%{top:-10%;opacity:0}10%{opacity:1}90%{opacity:1}100%{top:110%;opacity:0}}
@media (prefers-reduced-motion:reduce){ .hero h1 .gl.go,.hero h1 .gl.go::before,.hero h1 .gl.go::after,.hero h1 .gl.go .band{animation:none} .hero h1 .gl.go::before,.hero h1 .gl.go::after,.hero h1 .gl .band{display:none} }

/* ---- restored 2026-09-21: blocks lost in the island rewrite ---- */
/* Shutter text on the hero tagline. Wrappers get padding so no glyph is cut; no blur, so
   nothing is soft; and the plain text is restored when the sweep ends (see home.js). */
.hero h1{cursor:default}
.hero h1.shutter .sh{position:relative;display:inline-block;clip-path:inset(-.25em -.02em)}
.hero h1.shutter .c{display:inline-block;opacity:0;transform:translateY(.12em);
  animation:sh-in .55s cubic-bezier(.2,.8,.2,1) forwards;animation-delay:calc(var(--i) * 40ms + .25s)}
.hero h1.shutter .s{position:absolute;inset:0;pointer-events:none;opacity:0;
  animation:sh-sweep .7s ease-in-out forwards}
.hero h1.shutter .s.t{color:#1ac6ff;clip-path:polygon(0 0,100% 0,100% 35%,0 35%);animation-delay:calc(var(--i) * 40ms)}
.hero h1.shutter .s.m{color:#fff;clip-path:polygon(0 35%,100% 35%,100% 65%,0 65%);animation-name:sh-sweep-back;animation-delay:calc(var(--i) * 40ms + .1s)}
.hero h1.shutter .s.b{color:#d9a520;clip-path:polygon(0 65%,100% 65%,100% 100%,0 100%);animation-delay:calc(var(--i) * 40ms + .2s)}
@keyframes sh-in{to{opacity:1;transform:none}}
@keyframes sh-sweep{0%{transform:translateX(-100%);opacity:0}50%{opacity:1}100%{transform:translateX(100%);opacity:0}}
@keyframes sh-sweep-back{0%{transform:translateX(100%);opacity:0}50%{opacity:1}100%{transform:translateX(-100%);opacity:0}}
.shot .hero h1.shutter .c{opacity:1;transform:none;animation:none}
.shot .hero h1.shutter .s{display:none}

/* The tablet (Aceternity ContainerScroll, ported): the title drifts up and the card tilts
   from 20 degrees to flat and settles from 1.05 to 1 as it scrolls into view. Scroll-driven
   CSS animations. The resting state is flat, so a browser without them shows the card flat;
   the tilt is applied by the animation's from-keyframe during its before-phase. */
.statement{padding-bottom:clamp(4rem,8vw,7rem);overflow-x:clip}
.statement .title{text-align:center;max-width:none;margin:0 auto}
.statement .title h2{margin-left:auto;margin-right:auto}
.statement .title > p{margin:0 auto;max-width:46ch;font-size:clamp(1.15rem,1.6vw,1.7rem);color:var(--soft)}
.statement .tablet{perspective:1000px;max-width:64rem;margin:clamp(2rem,4vw,3rem) auto 0}
.statement .card{transform:none;transform-origin:50% 0;
  border:4px solid #6c6c6c;background:#222;border-radius:30px;padding:clamp(.5rem,1.5vw,1.5rem);
  box-shadow:0 0 #0000004d,0 9px 20px #0000004a,0 37px 37px #00000042,0 84px 50px #00000026,0 149px 60px #0000000a,0 233px 65px #00000003}
.statement .screen{height:auto;min-height:clamp(24rem,42vw,40rem);overflow:hidden;border-radius:16px;background:#f3f4f6;padding:clamp(1.2rem,3vw,2.5rem);
  display:flex;flex-direction:column;gap:clamp(1.2rem,2.5vw,2rem);text-align:center}
.statement .numbers{margin:0 auto;max-width:none;width:100%}
.statement .numbers b{font-size:clamp(2.4rem,5vw,4.6rem)}
.statement .board-note{margin:0;font-size:.82rem;color:var(--soft);text-align:left}
@supports (animation-timeline: view()){
  .statement .card{animation:card-flatten linear both;animation-timeline:view();animation-range:entry 0% cover 45%}
  .statement .title{animation:title-drift linear both;animation-timeline:view();animation-range:exit 0% exit 100%}
}
@keyframes card-flatten{from{transform:rotateX(20deg) scale(1.05)}to{transform:rotateX(0deg) scale(1)}}
@keyframes title-drift{from{transform:translateY(0)}to{transform:translateY(-100px)}}
@media (max-width:768px){
  .statement .card{transform:none}
  /* The resting frame must end at scale(1). A transform scale shrinks what is painted
     but NOT the layout box, so ending at scale(.9) left the tablet reserving its full
     unscaled height and put ~275px of dead whitespace under the device on a phone.
     The 90% inset the scale was there to give is now real width on .tablet instead. */
  @keyframes card-flatten{from{transform:rotateX(20deg) scale(.78)}to{transform:rotateX(0deg) scale(1)}}
  .statement .tablet{width:90%;margin-inline:auto}
  .statement .screen{height:auto;min-height:22rem}
  .statement .numbers{grid-template-columns:repeat(2,minmax(0,1fr));gap:1.2rem}
  /* The whole dashboard stacked into one column made the device ~2,500px tall. On a
     phone the screen is a window onto it: the figures and the first cards, then a fade. */
  .statement .screen{position:relative;max-height:34rem}
  .statement .screen::after{content:"";position:absolute;left:0;right:0;bottom:0;height:7rem;pointer-events:none;
    background:linear-gradient(rgba(243,244,246,0),#f3f4f6 85%)}
}
@media (prefers-reduced-motion:reduce){ .statement .card,.statement .title{animation:none;transform:none} }

/* Cutout cards (cult-ui CutoutCard, ported): image, inset label with inverted corners, hover motion, action reveals */
.offer h2{max-width:none}
.cuts{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1.25rem;margin-top:clamp(2rem,4vw,3.5rem)}
.cut{position:relative;background:#fff;border:1px solid var(--line);border-radius:22px;overflow:hidden;
     transition:transform .5s cubic-bezier(.16,1,.3,1),box-shadow .5s ease,border-color .3s ease}
.cut:hover{transform:translateY(-6px);box-shadow:0 24px 60px rgba(0,63,97,.16);border-color:transparent}
.cut-link{position:absolute;inset:0;z-index:3}
.cut-media{position:relative;aspect-ratio:4/3;overflow:hidden;background:#0e1a24}
.cut-media img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .9s cubic-bezier(.16,1,.3,1)}
.cut:hover .cut-media img{transform:scale(1.06)}
.cut-media::after{content:"";position:absolute;inset:0;background:linear-gradient(0deg,rgba(6,18,28,.25),rgba(6,18,28,0) 50%)}
.cut-label{position:absolute;left:0;bottom:0;z-index:2;background:#fff;padding:.7rem 1.1rem .5rem 1.25rem;border-top-right-radius:20px}
.cut-label span{font-family:var(--mono);font-size:.66rem;letter-spacing:.16em;text-transform:uppercase;color:var(--soft);font-weight:500}
/* the two inverted corners that make the label look cut out of the card */
.cut-label::before,.cut-label::after{content:"";position:absolute;width:20px;height:20px;background:radial-gradient(circle at 100% 0,transparent 19.5px,#fff 20px)}
.cut-label::before{left:0;top:-20px;background:radial-gradient(circle at 100% 0,transparent 19.5px,#fff 20px)}
.cut-label::after{right:-20px;bottom:0;background:radial-gradient(circle at 100% 0,transparent 19.5px,#fff 20px)}
.cut-body{padding:1.2rem 1.25rem 3.4rem}
/* The /services copies are generated without .cut-link and .cut-action. Reclaim the band the
   arrow reserved, and drop the hover lift, shadow and image push-in so a card that goes
   nowhere stops advertising a click. Home cards still have .cut-action and keep both. */
.cut:not(:has(.cut-action)) .cut-body{padding-bottom:1.35rem}
.cut:not(:has(.cut-action)):hover{transform:none;box-shadow:none;border-color:var(--line)}
.cut:not(:has(.cut-action)):hover .cut-media img{transform:none}
.cut-body h3{font-weight:600;font-size:1.08rem;letter-spacing:-.01em;margin:0 0 .45rem}
.cut-body p{font-size:.9rem;color:var(--soft);margin:0;max-width:none}
.cut-action{position:absolute;right:1.1rem;bottom:1rem;z-index:2;width:2.4rem;height:2.4rem;border-radius:50%;background:var(--accent);color:#fff;
  display:grid;place-items:center;font-size:1.1rem;opacity:0;transform:translateY(8px) scale(.9);transition:opacity .35s ease,transform .5s cubic-bezier(.16,1,.3,1)}
.cut:hover .cut-action,.cut:focus-within .cut-action{opacity:1;transform:none}
@media (max-width:1200px){ .cuts{grid-template-columns:repeat(3,minmax(0,1fr))} }
@media (max-width:900px){ .cuts{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (max-width:560px){ .cuts{grid-template-columns:1fr} .cut-action{opacity:1;transform:none} }

/* Bar: Client Portal sits beside the button; Contact is an envelope icon */
.bar .portal{text-decoration:none;color:var(--ink);font-size:.88rem;font-weight:500;white-space:nowrap;margin-left:auto}
.bar .cta{margin-left:0}
body.scrolled:not(.agent) .bar .portal{color:#c9d3dc;font-size:.82rem}
body.scrolled:not(.agent) .bar .portal:hover{color:#fff}
@media (max-width:860px){ .bar .portal{display:none} body.scrolled:not(.agent) .bar.open .portal{display:block} }
/* Phone, top of page: the mark on the left, the button and the burger together on the
   right. .portal carried margin-left:auto and is hidden here, so nothing pushed right. */
@media (max-width:860px){
  body:not(.scrolled) .bar .cta{margin-left:auto}
  .bar .burger{order:10;padding:.3rem .2rem}
  /* the island's section name is the menu button on a phone, so it gets a chevron */
  body.scrolled:not(.agent) .bar .island-now::after{content:"";width:.42rem;height:.42rem;margin-left:.15rem;
    border-right:1.6px solid currentColor;border-bottom:1.6px solid currentColor;transform:translateY(-2px) rotate(45deg);opacity:.75}
  body.scrolled:not(.agent) .bar.open .island-now::after{transform:translateY(1px) rotate(-135deg)}
}

/* Family button (cult-ui, ported): a round contact icon that springs open into a card */
.fam{position:relative}
.fam-btn{width:2.4rem;height:2.4rem;border-radius:50%;border:1px solid var(--line);background:#fff;color:var(--ink);cursor:pointer;
  display:grid;place-items:center;transition:transform .35s cubic-bezier(.34,1.56,.64,1),background .2s ease,color .2s ease}
.fam-btn svg{grid-area:1/1;transition:opacity .2s ease,transform .3s cubic-bezier(.34,1.56,.64,1)}
.fam-btn .i-x{opacity:0;transform:rotate(-90deg) scale(.6)}
.fam.open .fam-btn{background:var(--accent);color:#fff;border-color:var(--accent);transform:rotate(90deg)}
.fam.open .fam-btn .i-mail{opacity:0;transform:scale(.6)}
.fam.open .fam-btn .i-x{opacity:1;transform:rotate(0) scale(1)}
.fam-card{position:absolute;top:calc(100% + .7rem);right:0;width:17rem;background:#fff;color:var(--ink);border:1px solid var(--line);border-radius:20px;
  box-shadow:0 24px 60px rgba(0,63,97,.18);padding:.5rem;transform-origin:top right;
  animation:fam-in .45s cubic-bezier(.34,1.4,.64,1) both}
@keyframes fam-in{from{opacity:0;transform:scale(.6) translateY(-8px)}to{opacity:1;transform:none}}
.fam-title{margin:.5rem .7rem .4rem;font-size:.72rem;letter-spacing:.12em;text-transform:uppercase;color:var(--soft);font-weight:500}
.fam-row{display:flex;align-items:center;gap:.8rem;padding:.6rem .7rem;border-radius:14px;text-decoration:none;color:var(--ink);transition:background .15s ease}
.fam-row:hover{background:#f1f5f8}
.fam-row b{display:block;font-weight:600;font-size:.95rem}
.fam-row small{display:block;color:var(--soft);font-size:.78rem}
/* The Call row goes live: green while open, so the popover answers "is anyone there" rather
   than only "what are the hours". */
.fam-row small#fam-hours{font-variant-numeric:tabular-nums}
.fam-row small#fam-hours.is-open{color:#12986a;font-weight:600}
.fam-ico{width:2.2rem;height:2.2rem;border-radius:50%;background:#0e1a24;color:#fff;display:grid;place-items:center;flex:0 0 auto}
.fam-ico.wa{background:#25d366}
.fam-foot{margin:.4rem 0 0;padding:.7rem .7rem .5rem;border-top:1px solid var(--line);font-size:.78rem;color:var(--soft);
  background:#f7f9fb;border-radius:0 0 16px 16px}
body.scrolled:not(.agent) .bar .fam-btn{background:transparent;border-color:rgba(255,255,255,.25);color:#fff;width:2.1rem;height:2.1rem}
body.scrolled:not(.agent) .bar .fam.open .fam-btn{background:#fff;color:var(--accent)}
@media (max-width:860px){ .fam{display:none} }

/* Expandable product cards (cult-ui Expandable, ported): compact rows that open in place */
.xps{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1rem;margin-top:clamp(2rem,4vw,3.5rem);align-items:start}
.xp{background:#fff;border:1px solid var(--line);border-radius:20px;overflow:hidden;
    transition:box-shadow .4s ease,border-color .3s ease,transform .4s cubic-bezier(.16,1,.3,1)}
.xp:hover{border-color:#c5d0d9}
/* focus sits on .xp-head (role=button, tabindex=0); .xp itself is not focusable.
   .xp has overflow:hidden, so the ring is inset rather than offset outwards.
   The ring has to follow whatever shape the head actually has. Collapsed, the head
   IS the card, so all four corners are round; open, the head is only the card's top
   slab and the bottom two have to be square or the ring cuts across the body. */
.xp-head:focus-visible{outline:2px solid var(--accent);outline-offset:-3px;border-radius:17px}
.xp.open .xp-head:focus-visible{border-radius:17px 17px 0 0}
.xp.open{box-shadow:0 24px 60px rgba(0,63,97,.14);border-color:transparent}
.xp-head{display:grid;grid-template-columns:auto minmax(0,1fr) auto auto;grid-template-areas:"dot name status plus" "dot tag status plus";
         align-items:center;column-gap:.9rem;padding:1.1rem 1.25rem;cursor:pointer;user-select:none}
.xp-dot{grid-area:dot;width:.6rem;height:.6rem;border-radius:50%;background:#2ecc71;box-shadow:0 0 0 4px rgba(46,204,113,.18)}
.xp-dot.beta{background:var(--gold);box-shadow:0 0 0 4px rgba(217,165,32,.2)}
.xp-dot.soon{background:#b5c2cc;box-shadow:0 0 0 4px rgba(181,194,204,.25)}
.xp-dot.custom{background:var(--accent);box-shadow:0 0 0 4px rgba(0,63,97,.18)}
.xp-head h3{grid-area:name;font-weight:600;font-size:1.15rem;letter-spacing:-.01em;margin:0}
.xp-tag{grid-area:tag;font-size:.88rem;color:var(--soft)}
.xp-status{grid-area:status;font-family:var(--mono);font-size:.66rem;letter-spacing:.14em;text-transform:uppercase;color:var(--soft)}
.xp-plus{grid-area:plus;position:relative;width:1.9rem;height:1.9rem;border-radius:50%;border:1px solid var(--line);transition:transform .45s cubic-bezier(.34,1.56,.64,1),background .2s ease,border-color .2s ease}
.xp-plus::before,.xp-plus::after{content:"";position:absolute;left:50%;top:50%;background:var(--ink);transform:translate(-50%,-50%);width:.8rem;height:1.5px}
.xp-plus::after{width:1.5px;height:.8rem}
.xp.open .xp-plus{transform:rotate(45deg);background:var(--accent);border-color:var(--accent)}
.xp.open .xp-plus::before,.xp.open .xp-plus::after{background:#fff}
.xp-body{display:grid;grid-template-rows:0fr;transition:grid-template-rows .5s cubic-bezier(.2,.8,.2,1)}
.xp.open .xp-body{grid-template-rows:1fr}
.xp-inner{overflow:hidden;min-height:0;padding:0 1.25rem;opacity:0;transform:translateY(-6px);transition:opacity .35s ease .1s,transform .45s cubic-bezier(.2,.8,.2,1) .1s}
.xp.open .xp-inner{opacity:1;transform:none;padding-bottom:1.4rem}
.xp-inner p{color:var(--soft);font-size:.98rem;margin:.2rem 0 .9rem;max-width:60ch}
.xp-inner ul{list-style:none;padding:0;margin:0 0 1.2rem;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.5rem 1.5rem}
.xp-inner li{position:relative;padding-left:1.1rem;font-size:.92rem}
.xp-inner li::before{content:"";position:absolute;left:0;top:.55rem;width:.4rem;height:.4rem;border-radius:1px;background:var(--accent)}
.xp-inner .btn{font-size:.9rem;padding:.65rem 1.2rem}
.xp-yours{background:var(--accent);border-color:var(--accent);color:#fff}
.xp-yours .xp-tag,.xp-yours .xp-status,.xp-yours .xp-inner p{color:#cfe0ea}
.xp-yours .xp-plus{border-color:rgba(255,255,255,.4)}
.xp-yours .xp-plus::before,.xp-yours .xp-plus::after{background:#fff}
.xp-yours.open .xp-plus{background:#fff}
.xp-yours.open .xp-plus::before,.xp-yours.open .xp-plus::after{background:var(--accent)}
.xp-yours .xp-inner li::before{background:#fff}
.xp-yours .xp-inner .btn{background:#fff;color:var(--accent)}
@media (max-width:900px){ .xps{grid-template-columns:1fr} .xp-inner ul{grid-template-columns:1fr} }
@media (prefers-reduced-motion:reduce){ .xp-body,.xp-inner,.xp-plus{transition:none} }

/* ---- Subpages: built by pages/_build_pages.py from the home page's pieces ---- */
body.sub main{padding-top:0}
/* Privacy and Terms have no .sub-hero to carry the bar clearance, so without this their
   first heading renders underneath the fixed header. Same offset .sub-hero uses. */
body.sub main.legal{padding-top:calc(4.5rem + 3.6rem);padding-bottom:4rem}
.sub-hero{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,6fr);gap:3rem;align-items:center;
  padding:calc(4.5rem + 3.6rem) var(--gutter) 3.5rem}
.sub-hero h1{font-weight:600;font-size:clamp(2.2rem,4.4vw,4.4rem);letter-spacing:-.03em;line-height:1.02;margin:0 0 1.2rem;max-width:16ch}
.sub-hero .lede{font-size:clamp(1.05rem,1.3vw,1.35rem);color:var(--soft);max-width:46ch;margin:0}
.sub-hero-media{margin:0;aspect-ratio:16/10;border-radius:20px;overflow:hidden;box-shadow:0 30px 80px rgba(0,63,97,.16)}
.sub-hero-media img{width:100%;height:100%;object-fit:cover;display:block}
.sub-tier{padding-top:clamp(3rem,6vw,5rem);padding-bottom:clamp(2rem,4vw,3rem)}
.sub-tier h2{font-size:clamp(1.8rem,3.4vw,3rem)}
.sub-tier .cuts{margin-top:clamp(1.5rem,3vw,2.5rem)}
.sub-note{padding-top:clamp(3rem,6vw,5rem);padding-bottom:clamp(3rem,6vw,5rem)}

/* ---- Service detail pages ----
   /services/<slug>. Almost all of these pages is existing furniture: .sub-hero, .sub-why,
   .sub-note, .sub-cta and the .cut grid. Only three things needed writing. */

/* The tier the visitor clicked on the card, repeated at the top of the page they landed
   on, in the same mono treatment .cut-label uses. Doubles as the only "up" link that is
   not the bar. .tier carries vertical margin, which an inline <a> would drop. */
.sub-hero .tier{display:inline-block;margin:0 0 1rem;text-decoration:none;
  transition:color .2s ease}
.sub-hero .tier:hover{color:var(--accent)}

/* What is included. A scope list rendered as a scope list: one column, one line each, no
   cards and no disclosure. The marker is the same .4rem accent square .xp-inner already
   uses, so it is an existing idiom rather than a new one. */
.inc{list-style:none;padding:0;margin:0;display:grid;gap:.75rem}
.inc li{position:relative;padding-left:1.25rem;font-size:1.02rem;line-height:1.5}
.inc li::before{content:"";position:absolute;left:0;top:.62rem;width:.4rem;height:.4rem;
  border-radius:1px;background:var(--accent)}
/* The two-column spine is .qa-grid, borrowed from the FAQ without .qa-sec, which carries
   the tint and the border. The sticky heading barely pays at three items and earns its
   keep at eight on a short viewport; it is here for the split, not for the pinning. */
.svc-inc .qa-head p{margin-bottom:0}

/* How it works. Same cell anatomy as .why, three across, with the step number set in the
   mono face above a hairline so the sequence reads without numbering the headings. An <ol>
   so the order is in the markup and not only in the numerals. The hairline is the device
   .plan-row already uses to rule a horizontal series. */
.flow{list-style:none;padding:0;margin:clamp(1.5rem,3vw,2.5rem) 0 0;counter-reset:flow;
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:2rem 3rem;max-width:70rem}
.flow li{counter-increment:flow;padding-top:1.5rem;border-top:1px solid var(--line)}
.flow li::before{content:"0" counter(flow);display:block;font-family:var(--mono);
  font-size:.7rem;letter-spacing:.16em;color:var(--accent);margin-bottom:.7rem}

/* The related row is three cards, not four. Below 1200px .cuts already steps down. */
.svc-rel .cuts{grid-template-columns:repeat(3,minmax(0,1fr))}

@media (max-width:760px){ .flow{grid-template-columns:1fr;gap:1.6rem} }
.sub-note h2{font-size:clamp(1.5rem,2.6vw,2.2rem)}
.sub-note p{max-width:64ch}
.sub-cta{text-align:center;background:var(--accent);color:#fff}
.sub-cta h2{color:#fff;margin-left:auto;margin-right:auto}
.sub-cta > p{color:#cfe0ea;margin:0 auto}
.sub-cta .btn.quiet{background:transparent;border-color:rgba(255,255,255,.5);color:#fff}
.sub-cta .btn.primary{background:#fff;color:var(--accent)}
.sub-cta .btn.primary:hover{background:#e8f0f5;color:var(--accent)}
.sub-apps{padding-top:clamp(2rem,4vw,3rem)}
.sub-apps .xps{margin-top:0}
.sub-plans{padding-top:clamp(2rem,4vw,3rem)}
.sub-plans .planlist{margin-top:0}
.sub-fine{color:var(--soft);font-size:.86rem;margin-top:1.4rem;max-width:64ch}
.sub-fine a{color:var(--accent)}
.sub-compare{padding-top:0}
.cmp-wrap{overflow-x:auto;margin-top:clamp(1.5rem,3vw,2.5rem)}
.cmp{border-collapse:collapse;width:100%;min-width:56rem;font-size:.92rem}
.cmp th,.cmp td{text-align:left;padding:.8rem .9rem;border-bottom:1px solid var(--line);vertical-align:top}
.cmp thead th{font-weight:600;font-size:1rem;border-bottom:2px solid var(--line)}
.cmp tbody th{font-weight:500;color:var(--soft);width:16rem}
.cmp .hi{background:rgba(0,63,97,.05);font-weight:500}
.cmp thead th:first-child,.cmp tbody th{position:sticky;left:0;background:#fff;z-index:1}
.cmp-wrap{position:relative;background-color:#fff;
  background-image:linear-gradient(90deg,#fff 30%,rgba(255,255,255,0)),linear-gradient(270deg,#fff 30%,rgba(255,255,255,0)),
    radial-gradient(farthest-side at 0 50%,rgba(0,63,97,.22),rgba(0,63,97,0)),radial-gradient(farthest-side at 100% 50%,rgba(0,63,97,.22),rgba(0,63,97,0));
  background-repeat:no-repeat;background-size:2.5rem 100%,2.5rem 100%,1rem 100%,1rem 100%;
  background-position:0 0,100% 0,0 0,100% 0;background-attachment:local,local,scroll,scroll}
@media (max-width:700px){
  .cmp{min-width:40rem;font-size:.82rem}
  .cmp tbody th{width:9rem}
  .cmp th,.cmp td{padding:.6rem .55rem}
}
.sub-board{padding-top:0}
.board-wrap{margin-top:clamp(1.5rem,3vw,2.5rem);background:#f3f4f6;border:1px solid var(--line);border-radius:20px;padding:1.2rem}
.sub-statement{padding-top:clamp(4rem,8vw,7rem)}
.sub-statement .numbers{max-width:70rem}
.proof .proof-list{list-style:none;margin:0;padding:1.1rem var(--gutter);display:flex;flex-wrap:wrap;gap:.5rem 2.4rem;justify-content:space-between;font-size:.86rem;color:var(--soft);font-weight:500}
.sub-statement h2{font-size:clamp(2.2rem,5vw,5rem)}
.sub-why h2,.svc-flow h2,.svc-inc h2{font-size:clamp(1.8rem,3.4vw,3rem)}
.why{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:2rem 3rem;margin-top:clamp(1.5rem,3vw,2.5rem);max-width:70rem}
.why h3,.flow h3{font-weight:600;font-size:1.2rem;margin:0 0 .4rem}
.why p,.flow p{color:var(--soft);margin:0;max-width:none}
.sub-contact{padding-top:clamp(1rem,3vw,2rem)}
.sub-contact .contact-grid{max-width:none}
.direct{background:#fff;border:1px solid var(--line);border-radius:20px;padding:.5rem;box-shadow:0 24px 60px rgba(0,63,97,.08)}
.direct .fam-row b{font-size:1.05rem}
@media (max-width:900px){
  .sub-hero{grid-template-columns:1fr;padding-top:calc(3rem + 3.6rem);gap:1.6rem}
  .why{grid-template-columns:1fr}
}

/* ---- The client's day: full-screen chapters on our own footage ---- */
main > section,main > figure,main > div{scroll-margin-top:5rem}
.day,.wall,.contact-glass,.slider-sec,.statement,.offer,.faq-ed{padding-top:max(clamp(4rem,8vw,7rem),6.5rem)}
.day,.wall,.contact-glass{position:relative;min-height:100vh;min-height:100dvh;display:grid;align-items:center;overflow:hidden;isolation:isolate;
  padding:clamp(4rem,8vw,7rem) var(--gutter);color:#fff;background:#0e1a24}
.day-media,.wall-media{position:absolute;inset:0;z-index:-2}
.day-media img,.day-media video,.wall-media img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.day::after,.wall::after,.contact-glass::after{content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(90deg,rgba(6,18,28,.78) 0%,rgba(6,18,28,.45) 50%,rgba(6,18,28,.25) 100%)}
.clock{display:inline-block;font-family:var(--mono);font-size:.9rem;letter-spacing:.14em;color:#1ac6ff;margin-bottom:1rem}
.day-copy h2,.wall-copy h2,.contact-glass h2{font-weight:600;font-size:clamp(2rem,4.2vw,4.2rem);letter-spacing:-.03em;line-height:1.02;margin:0 0 1rem;max-width:14ch;color:#fff}
.day-copy p,.wall-copy p{font-size:clamp(1.05rem,1.35vw,1.4rem);color:#dbe5ec;max-width:40ch;margin:0}
.day-screen{margin:0;border-radius:14px;overflow:hidden;border:1px solid rgba(255,255,255,.18);
  box-shadow:0 40px 100px rgba(0,0,0,.5);transform:perspective(1200px) rotateY(-6deg);transform-origin:left center}
.day-screen img{width:100%;height:auto;display:block}
.ticket{background:#fff;color:var(--ink);border-radius:20px;padding:1.4rem 1.5rem;max-width:30rem;justify-self:end;width:100%;box-shadow:0 40px 100px rgba(0,0,0,.45)}
.t-head{display:flex;justify-content:space-between;font-family:var(--mono);font-size:.72rem;letter-spacing:.1em;color:var(--soft)}
.t-sla{color:var(--accent)}
.t-title{font-weight:600;font-size:1.15rem;margin:.5rem 0 1rem}
.t-steps{list-style:none;padding:0;margin:0 0 1rem;display:grid;gap:.6rem}
.t-steps li{display:flex;flex-wrap:wrap;gap:0 .6rem;align-items:baseline;opacity:.25;transition:opacity .4s ease}
.t-steps li::before{content:attr(data-t);font-family:var(--mono);font-size:.78rem;color:var(--soft);flex:0 0 3.2rem}
.t-steps li b{display:block;font-weight:600}
.t-steps li span{display:block;font-size:.85rem;color:var(--soft)}
.reveal.in .t-steps li{opacity:1}
.reveal.in .t-steps li:nth-child(1){transition-delay:.4s}.reveal.in .t-steps li:nth-child(2){transition-delay:1s}
.reveal.in .t-steps li:nth-child(3){transition-delay:1.8s}.reveal.in .t-steps li:nth-child(4){transition-delay:2.6s}
.t-foot{display:flex;align-items:baseline;gap:.5rem;border-top:1px solid var(--line);padding-top:.9rem;color:var(--soft);font-size:.85rem}
.t-foot b{font-size:1.6rem;font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums}
.report{background:rgba(255,255,255,.96);color:var(--ink);border-radius:20px;padding:1.4rem 1.5rem;max-width:32rem;justify-self:end;width:100%;box-shadow:0 40px 100px rgba(0,0,0,.45)}
.r-head{display:flex;justify-content:space-between;font-weight:600;border-bottom:1px solid var(--line);padding-bottom:.8rem;margin-bottom:.8rem}
.r-head span{font-family:var(--mono);font-size:.7rem;letter-spacing:.12em;color:var(--soft);font-weight:500}
.report ul{list-style:none;padding:0;margin:0;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.9rem 1.5rem}
.report li b{display:block;font-weight:600;font-size:1.9rem;letter-spacing:-.03em;line-height:1;font-variant-numeric:tabular-nums}
.report li span{display:block;font-size:.82rem;color:var(--soft);margin-top:.2rem}
.contact-glass{grid-template-columns:1fr}
.contact-glass::after{background:linear-gradient(90deg,rgba(6,18,28,.5) 0%,rgba(6,18,28,.15) 40%,rgba(6,18,28,0) 60%)}
.contact-glass{align-items:start;padding-top:clamp(6rem,10vw,8rem)}
.contact-glass .day-media img{object-position:50% 40%;transform:scale(1.28) translateX(10%);transform-origin:50% 50%}
.contact-glass{background:#0e1a24;padding-top:max(clamp(5rem,9vw,7rem),6.5rem);padding-bottom:clamp(3rem,6vw,5rem);min-height:100vh;min-height:100dvh}
.glass-panel .direct{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:.3rem;padding:.6rem}
.glass-panel .direct .fam-title{grid-column:1/-1;margin:.2rem .4rem .2rem}
.glass-panel .direct .fam-row{flex-direction:column;align-items:flex-start;gap:.5rem;padding:.6rem}
.glass-panel .direct .fam-foot{grid-column:1/-1}
.glass-panel .form{max-width:none}
.glass-panel .form textarea{min-height:5rem}
.glass-panel{justify-self:start;width:min(100%,42rem);display:grid;grid-template-columns:1fr;gap:1.4rem;
  padding:clamp(1.6rem,3vw,2.6rem);border-radius:28px;position:relative;isolation:isolate;
  background:linear-gradient(135deg,rgba(255,255,255,.22) 0%,rgba(255,255,255,.06) 45%,rgba(255,255,255,.12) 100%);
  border:1px solid rgba(255,255,255,.7);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.85),inset 0 -1px 0 rgba(255,255,255,.25),inset 0 0 0 1px rgba(255,255,255,.15),0 40px 100px rgba(0,0,0,.45);
  -webkit-backdrop-filter:blur(10px) saturate(1.5) brightness(1.08);backdrop-filter:blur(10px) saturate(1.5) brightness(1.08)}
@supports (backdrop-filter:url(#glass-distort)) and (not (background:-webkit-named-image(apple-pay-logo-black))){ .glass-panel{backdrop-filter:url(#glass-distort) blur(5px) saturate(1.5) brightness(1.08)} }
/* the sheen: a soft highlight that sweeps across the glass */
.glass-panel::before{content:"";position:absolute;inset:0;border-radius:inherit;z-index:-1;pointer-events:none;
  background:linear-gradient(115deg,transparent 30%,rgba(255,255,255,.35) 45%,rgba(255,255,255,.08) 52%,transparent 60%);
  background-size:250% 100%;animation:sheen 7s ease-in-out infinite}
@keyframes sheen{0%,20%{background-position:120% 0}60%,100%{background-position:-40% 0}}
/* the edge: a second, thinner frame just inside, like real glass */
.glass-panel::after{content:"";position:absolute;inset:6px;border-radius:22px;pointer-events:none;border:1px solid rgba(255,255,255,.28)}
.glass-panel h2{font-size:clamp(1.8rem,3.2vw,2.8rem)}
.glass-panel > div > p{color:#e6edf2;margin:0 0 1.4rem;max-width:40ch}
/* ---- Inside the glass panel ----
   The fields used to be opaque white slabs and the contact routes a second white card nested
   inside the first, so the panel read as three different materials stacked on a photograph.
   Everything in here is now the same frosted glass: the fields are translucent with white
   text, and the contact routes sit directly on the panel behind a hairline instead of in a
   card of their own. */
.glass-panel .form{gap:1.05rem}
.glass-panel .form label{color:rgba(232,240,246,.72);font-size:.78rem;letter-spacing:.01em;
  text-transform:none;font-weight:500;margin-bottom:.45rem}
/* A dark well, not a light slab. The panel brightens whatever is behind it, so a light
   translucent field picked up the bright foliage and left white text sitting on a moving,
   variegated background. Recessing the field is also what an input actually is. */
.glass-panel .form input,.glass-panel .form textarea{
  background:rgba(10,20,28,.42);border:1px solid rgba(255,255,255,.26);color:#fff;
  border-radius:12px;padding:.82rem 1rem;font-size:1rem;
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  transition:background .22s ease,border-color .22s ease,box-shadow .22s ease}
.glass-panel .form input::placeholder,.glass-panel .form textarea::placeholder{color:rgba(255,255,255,.5)}
.glass-panel .form input:hover,.glass-panel .form textarea:hover{background:rgba(10,20,28,.48);border-color:rgba(255,255,255,.4)}
.glass-panel .form input:focus,.glass-panel .form textarea:focus{
  background:rgba(10,20,28,.56);border-color:rgba(255,255,255,.72);
  box-shadow:0 0 0 3px rgba(255,255,255,.16)}
/* Chrome paints its own pale background and dark text on an autofilled field, which would
   punch a white hole through the glass. The inset shadow is the only way to override it. */
.glass-panel .form input:-webkit-autofill,
.glass-panel .form input:-webkit-autofill:hover,
.glass-panel .form input:-webkit-autofill:focus{
  -webkit-box-shadow:0 0 0 1000px rgba(34,52,64,.96) inset;-webkit-text-fill-color:#fff;
  caret-color:#fff;border-color:rgba(255,255,255,.3)}
.glass-panel .form textarea{min-height:6.5rem;resize:vertical}
.glass-panel .form button{padding:.85rem 2.4rem;font-size:1rem;font-weight:600;margin-top:.2rem}

.glass-panel .direct{background:transparent;border:0;box-shadow:none;border-radius:0;
  padding:1.4rem 0 0;border-top:1px solid rgba(255,255,255,.18);gap:.2rem}
.glass-panel .direct .fam-title{color:rgba(232,240,246,.62);margin:0 0 .9rem;letter-spacing:.14em}
.glass-panel .direct .fam-row{color:#fff;border-radius:12px;padding:.7rem .6rem}
.glass-panel .direct .fam-row:hover{background:rgba(255,255,255,.10)}
.glass-panel .direct .fam-row b{color:#fff;font-size:1rem}
.glass-panel .direct .fam-row small{color:rgba(232,240,246,.72);font-size:.84rem}
.glass-panel .direct .fam-ico{width:2rem;height:2rem;background:rgba(255,255,255,.14);
  border:1px solid rgba(255,255,255,.22);color:#fff}
.glass-panel .direct .fam-ico.wa{background:#25d366;border-color:transparent}
/* The base rule gives this a #f7f9fb pill, which belongs to the nav popover. On the glass it
   printed a white bar and the text vanished into it. */
.glass-panel .direct .fam-foot{background:transparent;border-radius:0;
  border-top:1px solid rgba(255,255,255,.14);
  color:rgba(232,240,246,.72);margin:.9rem 0 0;padding:.9rem .6rem 0}
.glass-panel .direct .fam-foot a{color:#fff;text-underline-offset:3px}
@media (max-width:900px){
  .ticket,.report{justify-self:stretch;max-width:none}
  .day-screen{transform:none}
  .glass-panel{grid-template-columns:1fr;gap:1.6rem}
  .contact-glass .day-media img{transform:none}
  .glass-panel .direct{grid-template-columns:1fr}
}
@media (prefers-reduced-motion:reduce){ .t-steps li{opacity:1;transition:none} .plan-out.flash *{animation:none} }
.shot .contact-glass{min-height:720px}
/* fixes after the first look */
.t-steps li span{display:inline;margin-left:.4rem}
.t-steps li b{display:inline}
.glass-panel .fam-title{color:var(--soft)}
.glass-panel .direct{align-self:start}

/* ---- Chapter transitions: off. Mihai did not like the card deck. Chapters scroll plainly;
   only the copy and cards reveal (the .reveal class) and the glass panel does its thing. ---- */
.shot .contact-glass,.shot .glass-panel::before,.shot .d-live i{animation:none !important}
.shot .glass-panel::before{background-position:-40% 0 !important}
@media (prefers-reduced-motion:reduce){
  .contact-glass,.timeline,.timeline *{animation:none !important;transition:none !important}
  .d-live i{animation:none !important}
  .glass-panel::before{animation:none !important;background-position:-40% 0}
}

/* IT Desk dashboard on the tablet screen */
.dash{background:#f7f9fb;border:1px solid var(--line);border-radius:14px;overflow:hidden;text-align:left;flex:1;display:flex;flex-direction:column;font-size:.8rem}
/* The tab strip sits on its own line at every width. Inline it left roughly 800px of empty
   chrome between the last tab and the Live badge, and the floating site nav lands on top
   of it as you scroll past. */
.d-top{display:flex;flex-wrap:wrap;align-items:center;gap:.45rem .8rem;
  padding:.6rem .9rem 0;background:#fff;border-bottom:1px solid var(--line)}
.d-brand{font-weight:600;color:var(--accent)}
.d-tabs{display:flex;order:3;width:100%;gap:.2rem;color:var(--soft);
  overflow-x:auto;scrollbar-width:none;scroll-snap-type:x proximity}
.d-tabs::-webkit-scrollbar{display:none}
.d-tabs button{font:inherit;color:inherit;background:none;border:0;cursor:pointer;
  padding:.3rem .55rem .5rem;margin-bottom:-1px;white-space:nowrap;scroll-snap-align:start;
  border-radius:7px 7px 0 0;border-bottom:2px solid transparent;
  transition:color .18s ease,background .18s ease,border-color .18s ease}
.d-tabs button:hover{color:var(--ink);background:#f2f6f9}
.d-tabs button[aria-selected="true"]{color:var(--ink);font-weight:600;border-bottom-color:var(--accent)}
.d-tabs button:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.d-live{margin-left:auto;display:inline-flex;align-items:center;gap:.4rem;color:#157f47;font-weight:500}
.d-live i{width:.5rem;height:.5rem;border-radius:50%;background:#2ecc71;box-shadow:0 0 0 3px rgba(46,204,113,.25);animation:pulse 1.6s ease-in-out infinite}
@keyframes pulse{50%{box-shadow:0 0 0 6px rgba(46,204,113,.08)}}
.d-panels{flex:1;display:flex;flex-direction:column;min-height:0}
/* One rule, not two: the split invited a min-height that equalised nothing. */
.d-panel{flex:1;display:flex;flex-direction:column;min-height:30rem}
.d-panel.is-live{animation:d-fade .34s ease both}
.d-panel:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.d-panel[hidden]{display:none}
@keyframes d-fade{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
.d-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.6rem;padding:.7rem;flex:1;align-content:start}
/* The tablet frame is a fixed height, so a short view would leave a band of empty grey at
   the foot. The slack goes to the card row, never to the tile row. */
.d-grid.rows2{grid-template-rows:auto minmax(0,1fr);align-content:stretch}
.d-grid.rows4{grid-template-rows:auto auto minmax(0,1fr) auto;align-content:stretch}
.d-solo{display:flex;padding:.7rem;flex:1}
.d-solo > .d-card{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:center}
.d-note{margin:.6rem 0 0;font-size:.72rem;color:var(--soft);line-height:1.5}
.d-note b{color:var(--ink);font-weight:600}
.d-grid > .d-note{grid-column:1/-1;margin-top:.1rem}
/* Rows whose label is a sentence rather than a name: let it wrap instead of clipping. */
.d-list.d-wrap li b{white-space:normal;overflow:visible;text-overflow:clip}
.d-kpi,.d-card{background:#fff;border:1px solid var(--line);border-radius:10px;padding:.7rem .8rem}
.d-kpi span{display:block;color:var(--soft);font-size:.72rem}
.d-kpi > b{display:block;font-size:1.5rem;font-weight:600;letter-spacing:-.02em;line-height:1.15;margin:.1rem 0}
.d-kpi small{font-size:.7rem;line-height:1.4;color:var(--soft)}.d-kpi small.ok{color:#157f47}
.d-kpi small b{color:var(--ink);font-weight:600}
.d-wide{grid-column:span 2}
h3.d-h,.d-h{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:baseline;
  gap:0 .6rem;font:inherit;font-weight:600;font-size:.78rem;margin:0 0 .4rem}
.d-h span{color:var(--soft);font-weight:400}
.d-trend{display:flex;flex-direction:column}
.d-chart{width:100%;height:5.2rem;display:block;overflow:visible}
/* Fixed to the viewBox ratio. Left to flex, the same fifteen points rendered 47% steeper
   on a phone than on a desktop, which is a slope the data never had. */
.d-trend .d-chart{flex:none;height:auto;aspect-ratio:320/90}
.d-trend .d-note{margin-top:auto}
.d-trend .d-axis{margin-top:.2rem}
.d-axis{display:flex;justify-content:space-between;color:var(--soft);font-size:.62rem;margin-top:.2rem}
.d-list{grid-column:span 2}
.d-grid > .d-card:not(.d-wide):not(.d-list){grid-column:span 2}
.d-list ul{list-style:none;padding:0;margin:0}
.d-list li{display:grid;grid-template-columns:auto minmax(0,1fr) auto auto;gap:.6rem;align-items:center;padding:.35rem 0;border-top:1px solid #eef2f5}
.d-list li:first-child{border-top:0}
.d-list li i{width:.5rem;height:.5rem;border-radius:50%;background:#157f47}
/* Status is not carried by colour alone: the warning dot is also a diamond, the pending
   one a hollow ring, so the three states differ in shape as well as hue. */
.d-list li i.warn{background:#a87b10;border-radius:2px;transform:rotate(45deg)}
.d-list li i.due{background:#fff;border:1.5px solid var(--soft)}
.d-list li b{font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.d-list li span{color:var(--soft);font-size:.7rem}
.d-list li em{font-style:normal;font-family:var(--mono);font-size:.68rem;color:var(--soft)}
/* pathLength normalises the path to 100, which is the only length that survives both the
   non-uniform viewBox and vector-effect:non-scaling-stroke. The old 600 was set against a
   user-space length of 346, and .reveal.in never matched at all because .dash sits inside
   .tablet, so this line had never once drawn on the home page. */
.d-panel.is-live .d-line{stroke-dasharray:100;stroke-dashoffset:100;
  animation:draw 1.05s cubic-bezier(.22,1,.3,1) .12s forwards}
.d-panel.is-live .d-area{opacity:0;animation:fade .7s ease .5s forwards}
@keyframes draw{to{stroke-dashoffset:0}}@keyframes fade{to{opacity:1}}
.shot .d-line,.shot .d-area{animation:none;stroke-dashoffset:0;opacity:1}
@media (max-width:900px){
  /* Two columns reflows the rows, so the explicit row track no longer maps to the cards. */
  .d-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .d-grid.rows2,.d-grid.rows4{grid-template-rows:none;align-content:start}
  .d-tabs{gap:0;font-size:.74rem} .d-tabs button{padding:.3rem .35rem .5rem}
}
@media (max-width:560px){
  /* Tiles pair up; charts and lists still run the full width. */
  .d-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .d-wide,.d-list,.d-grid > .d-card:not(.d-wide):not(.d-list){grid-column:1/-1}
  .d-list li{grid-template-columns:auto minmax(0,1fr) auto;column-gap:.6rem;row-gap:.1rem;align-items:center}
  .d-list li i{grid-row:1 / span 2;align-self:center}
  .d-list li b{grid-column:2 / -1;grid-row:1;white-space:normal;overflow:visible;text-overflow:clip}
  .d-list li span{grid-column:2;grid-row:2}
  .d-list li em{grid-column:3;grid-row:2;justify-self:end}
  .d-q li{grid-template-rows:auto auto auto}
  .d-q .sla{grid-column:2/-1;grid-row:3}
  .nt-row{grid-template-columns:minmax(0,1fr)}
  .nt{grid-row:2}
  .nt-x{grid-row:3;justify-self:start;white-space:normal}
  .d-kpi small{line-height:1.35}
}

/* Service filters: one grid of twelve icon tiles, equal width, wraps evenly */
.filters{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:.6rem;margin:1.8rem 0 0}
.f{display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:.5rem;min-height:5.6rem;padding:.8rem .4rem;
   border:1px solid var(--line);background:#fff;color:var(--ink);font:inherit;font-size:.76rem;font-weight:500;line-height:1.2;text-align:center;border-radius:16px;cursor:pointer;
   transition:background .25s ease,color .25s ease,border-color .25s ease,transform .35s cubic-bezier(.34,1.56,.64,1),box-shadow .25s ease}
.f svg{width:1.6rem;height:1.6rem;transition:transform .35s cubic-bezier(.34,1.56,.64,1)}
.f:hover{border-color:var(--accent);transform:translateY(-3px);box-shadow:0 12px 30px rgba(0,63,97,.12)}
.f:hover svg{transform:scale(1.12)}
.f:active{transform:scale(.96)}
.f.on{background:var(--accent);border-color:var(--accent);color:#fff;box-shadow:0 12px 30px rgba(0,63,97,.25)}
.f-sep{display:none}
.f-count{grid-column:1/-1;color:var(--soft);font-size:.9rem;margin:.2rem 0 0}
.cuts .cut.in{animation:cut-in .5s cubic-bezier(.16,1,.3,1) both;animation-delay:calc(var(--i,1) * 40ms)}
@keyframes cut-in{from{opacity:0;transform:translateY(14px) scale(.98)}to{opacity:1;transform:none}}
@media (max-width:1200px){ .filters{grid-template-columns:repeat(6,minmax(0,1fr))} }
@media (max-width:700px){ .filters{grid-template-columns:repeat(4,minmax(0,1fr))} .f{min-height:5rem;font-size:.7rem} }
@media (max-width:460px){ .filters{grid-template-columns:repeat(3,minmax(0,1fr))} }
/* bar legibility over the hero video */
body:not(.scrolled):not(.agent) .bar{background:rgba(247,249,251,.68);border-bottom:1px solid rgba(255,255,255,.7)}
body:not(.scrolled):not(.agent) .bar nav a{color:var(--ink);opacity:.8;font-weight:500}
body:not(.scrolled):not(.agent) .bar nav a:hover,body:not(.scrolled):not(.agent) .bar nav a[aria-current]{opacity:1}
body:not(.scrolled):not(.agent) .bar .portal{color:var(--ink)}

/* ---- A day with CarpaTech: one pinned stage, four stops driven by scroll ---- */
.timeline{position:relative;height:1200vh;padding:0;background:#0e1a24;color:#fff}
.tl-sticky{position:sticky;top:0;height:100vh;height:100dvh;overflow:hidden;isolation:isolate;display:grid;grid-template-rows:auto 1fr;padding:6.5rem var(--gutter) 3rem}
.tl-media{position:absolute;inset:0;z-index:-2}
.tl-bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;transform:scale(1.06);transition:opacity 1s ease,transform 6s ease-out}
.tl-bg.on{opacity:1;transform:scale(1)}
.tl-sticky::after{content:"";position:absolute;inset:0;z-index:-1;background:linear-gradient(90deg,rgba(6,18,28,.8) 0%,rgba(6,18,28,.5) 50%,rgba(6,18,28,.3) 100%)}
.tl-head{display:flex;align-items:flex-end;justify-content:space-between;gap:2rem;flex-wrap:wrap;margin-bottom:1.5rem}
.tl-head h2{font-weight:600;font-size:clamp(1.6rem,2.6vw,2.4rem);letter-spacing:-.02em;margin:0;color:#fff}
.tl-track{list-style:none;padding:0;margin:0;display:flex;gap:2.2rem;position:relative}
.tl-track::before{content:"";position:absolute;left:0;right:0;top:.35rem;height:2px;background:rgba(255,255,255,.2)}
.tl-track li{position:relative;padding-top:1.1rem;color:rgba(255,255,255,.5);transition:color .4s ease}
.tl-track li::before{content:"";position:absolute;left:0;top:0;width:.7rem;height:.7rem;border-radius:50%;background:rgba(255,255,255,.35);transition:background .4s ease,box-shadow .4s ease}
.tl-track li.on{color:#fff}
.tl-track li.on::before{background:#1ac6ff;box-shadow:0 0 0 5px rgba(26,198,255,.25)}
.tl-track b{display:block;font-family:var(--mono);font-size:.8rem;letter-spacing:.1em}
.tl-track span{font-size:.8rem}
.tl-stage{position:relative}
.tl-stop{position:absolute;inset:0;display:grid;grid-template-columns:minmax(0,5fr) minmax(0,6fr);gap:3rem;align-items:center;opacity:0;pointer-events:none;
  transition:opacity .6s ease}
.tl-stop.on{opacity:1;pointer-events:auto}
.tl-stop .day-copy{transform:translateX(-30px);transition:transform .7s cubic-bezier(.2,.8,.2,1)}
.tl-stop > :last-child{transform:translateX(40px) scale(.97);transition:transform .8s cubic-bezier(.2,.8,.2,1)}
.tl-stop.on .day-copy,.tl-stop.on > :last-child{transform:none}
.tl-stop h3{font-weight:600;font-size:clamp(1.8rem,3.6vw,3.6rem);letter-spacing:-.03em;line-height:1.02;margin:0 0 1rem;max-width:14ch;color:#fff}
.tl-stop .day-copy p{font-size:clamp(1rem,1.25vw,1.3rem);color:#dbe5ec;max-width:40ch;margin:0}
.tl-sentinels{position:absolute;inset:0;pointer-events:none}
.tl-sentinels i{position:absolute;left:0;right:0;height:calc(100% / 12);top:calc(var(--k) * 100% / 12)}
.tl-stop.on .t-steps li{opacity:1}
.tl-stop.on .t-steps li:nth-child(1){transition-delay:.4s}.tl-stop.on .t-steps li:nth-child(2){transition-delay:1s}
.tl-stop.on .t-steps li:nth-child(3){transition-delay:1.8s}.tl-stop.on .t-steps li:nth-child(4){transition-delay:2.6s}
.qcard{background:rgba(255,255,255,.96);color:var(--ink);border-radius:20px;padding:1.4rem 1.5rem;max-width:32rem;justify-self:end;width:100%;box-shadow:0 40px 100px rgba(0,0,0,.45)}
.q-head{display:flex;justify-content:space-between;font-weight:600;border-bottom:1px solid var(--line);padding-bottom:.8rem;margin-bottom:.4rem}
.q-head span{font-family:var(--mono);font-size:.7rem;letter-spacing:.12em;color:var(--soft);font-weight:500}
.q-rows{list-style:none;padding:0;margin:0}
.q-rows li{padding:.7rem 0;border-top:1px solid #eef2f5}
.q-rows li:first-child{border-top:0}
.q-rows b{display:block;font-weight:600;font-size:.95rem}
.q-rows span{display:block;color:var(--soft);font-size:.82rem;margin:.15rem 0 .4rem}
.q-rows i{display:block;height:6px;border-radius:999px;background:#e6ebf0;position:relative;overflow:hidden}
.q-rows i::after{content:"";position:absolute;left:0;top:0;bottom:0;width:0;background:var(--accent);border-radius:999px;transition:width 1.2s cubic-bezier(.2,.8,.2,1) .3s}
.tl-stop.on .q-rows i::after{width:var(--w)}
@media (max-width:900px){
  .tl-stop{grid-template-columns:1fr;gap:1.2rem;align-content:start}
  .tl-stop .ticket,.tl-stop .report,.tl-stop .qcard{justify-self:stretch;max-width:none}
  .tl-stop h3{font-size:1.7rem}
  .tl-track{gap:1rem}.tl-track span{display:none}
}
.shot .timeline{height:auto}.shot .tl-sticky{position:relative;height:auto;min-height:0}.shot .tl-stage{display:grid;gap:2rem}.shot .tl-stop{position:relative;opacity:1;transform:none}.shot .tl-stop *{transform:none !important}.shot .tl-bg:first-child{opacity:1}

/* twelve stops */
.tl-head > div{display:flex;align-items:baseline;gap:1.2rem}
.tl-track{gap:.5rem;overflow-x:auto;scrollbar-width:none;padding-top:0;max-width:100%}
.tl-track::-webkit-scrollbar{display:none}
.tl-track::before{display:none}
.tl-track li{padding:0;flex:0 0 auto;width:4.6rem;cursor:pointer;transition:opacity .3s ease,transform .3s ease}
.tl-track li::before{display:none}
.tl-track li img{width:100%;aspect-ratio:16/9;object-fit:cover;border-radius:6px;display:block;border:2px solid transparent;opacity:.55;transition:opacity .3s ease,border-color .3s ease;background:#1b2833}
.tl-track li b{font-size:.68rem;margin-top:.25rem;text-align:center;color:rgba(255,255,255,.92);text-shadow:0 1px 3px rgba(6,18,28,.95),0 0 2px rgba(6,18,28,.8)}
.tl-track li.on{transform:translateY(-3px)}
.tl-track li.on img{opacity:1}
.tl-track li.on b{color:#fff}
.tl-track li.on img{border-color:#1ac6ff}
.tl-track li:hover img{opacity:1}
.quote{display:block;margin-top:1.2rem;font-style:italic;color:#9fb3c2;font-size:.95rem;max-width:40ch;quotes:none}
@media (max-width:900px){ .tl-track li{width:3.4rem} .tl-track li b{font-size:.6rem} .tl-head > div{flex-wrap:wrap;gap:.4rem 1rem} .tl-stop .dcard{justify-self:stretch;max-width:none} }

/* mobile pass */
.statement h2 .w{display:inline-block;white-space:nowrap}
.tl-head > *{min-width:0}
.tl-track{min-width:0;width:100%}
.tl-sticky{max-width:100vw;overflow:hidden}
@media (max-width:900px){
  .tl-sticky{padding:5.2rem 1rem 1.2rem;grid-template-rows:auto 1fr}
  .tl-head{margin-bottom:.8rem;gap:.6rem}
  .tl-head h2{font-size:1.15rem}
  .tl-track li{width:2.9rem}
  .tl-track li b{font-size:.55rem}
  .tl-stop{grid-template-columns:1fr;gap:.9rem;align-content:start;overflow:hidden}
  .tl-stop h3{font-size:1.45rem;margin-bottom:.4rem}
  .tl-stop .day-copy p{font-size:.9rem}
  .tl-stop .clock{margin-bottom:.4rem;font-size:.75rem}
  .tl-stop .quote{display:none}
  .tl-stop .dcard,.tl-stop .ticket,.tl-stop .report,.tl-stop .qcard{padding:.9rem 1rem;border-radius:14px;font-size:.9rem}
  .tl-stop .day-screen{transform:none}
  .report li b{font-size:1.4rem}
  .t-steps{gap:.3rem}
}
.tl-stop > *{min-width:0}
.ticket,.dcard,.report,.qcard{min-width:0;box-sizing:border-box}
.t-steps li{min-width:0}
.t-steps li b,.t-steps li span{white-space:normal}
.tl-sticky{grid-template-columns:minmax(0,1fr)}
.tl-head,.tl-stage{min-width:0;max-width:100%}
.tl-track{max-width:100%;overflow-x:auto}

/* ---- Evidence cards on the timeline: each one looks like the real screen it would be ---- */
.ev{background:#fff;color:var(--ink);border-radius:18px;padding:1.1rem 1.25rem;max-width:32rem;justify-self:end;width:100%;box-shadow:0 40px 100px rgba(0,0,0,.45);font-size:.9rem;min-width:0}
.ev-top{display:flex;align-items:center;gap:.8rem;padding-bottom:.8rem;border-bottom:1px solid var(--line);margin-bottom:.8rem}
.ev-top > div{flex:1;min-width:0}
.ev-top b{display:block;font-weight:600;font-size:1rem}
.ev-top small{display:block;color:var(--soft);font-size:.78rem}
.av{width:2.2rem;height:2.2rem;border-radius:50%;background:var(--accent);color:#fff;display:grid;place-items:center;font-weight:600;font-size:.8rem;flex:0 0 auto}
.av.red{background:#e0323b}
.ev-badge{font-family:var(--mono);font-size:.66rem;letter-spacing:.12em;text-transform:uppercase;padding:.3rem .6rem;border-radius:999px;background:#eef2f5;color:var(--soft);white-space:nowrap}
.ev-badge.ok{background:#e3f7ec;color:#1e9e5a}
.ev-badge.warn{background:#fff3d6;color:#9a6b00}
.ev-badge.flip{background:#fde3e4;color:#c0262d}
.tl-stop.on .ev-badge.flip{animation:badge-flip .4s ease 2.6s forwards}
@keyframes badge-flip{to{background:#e3f7ec;color:#1e9e5a}}
.ev-msg{line-height:1.5;color:var(--ink)}
.ev-stats{list-style:none;padding:0;margin:.9rem 0 0;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.5rem}
.ev-stats li{background:#f3f6f8;border-radius:10px;padding:.5rem .6rem;text-align:center}
.ev-stats b{display:block;font-weight:600;font-size:1.15rem;letter-spacing:-.02em}
.ev-stats span{font-size:.7rem;color:var(--soft)}
.ev-foot{display:flex;justify-content:space-between;gap:1rem;align-items:baseline;border-top:1px solid var(--line);margin-top:.9rem;padding-top:.7rem;font-size:.8rem;color:var(--soft)}
.ev-foot em{font-style:normal;font-family:var(--mono);font-size:.62rem;letter-spacing:.14em;text-transform:uppercase;flex:0 0 auto}
.ev-hero{margin:.2rem 0 .9rem}
.ev-hero b{display:block;font-weight:600;font-size:2.2rem;letter-spacing:-.03em;line-height:1;color:var(--accent)}
.ev-hero span{display:block;color:var(--soft);font-size:.85rem;margin-top:.3rem}
.ev-hero.small b{font-size:1.7rem}
.ev-bar{height:8px;border-radius:999px;background:#e6ebf0;overflow:hidden;margin:.7rem 0 0}
.ev-bar i{display:block;height:100%;width:0;background:linear-gradient(90deg,var(--accent),#1ac6ff);border-radius:999px;transition:width 1.4s cubic-bezier(.2,.8,.2,1) .4s}
.tl-stop.on .ev-bar i{width:var(--w)}
/* ring gauges */
.rg-track{fill:none;stroke:#e6ebf0;stroke-width:9}
.rg-fill{fill:none;stroke:#1e9e5a;stroke-width:9;stroke-linecap:round;stroke-dasharray:100;stroke-dashoffset:100;transform:rotate(-90deg);transform-origin:center;transition:stroke-dashoffset 1.4s cubic-bezier(.2,.8,.2,1) var(--d,.3s)}
.tl-stop.on .rg-fill{stroke-dashoffset:calc(100 - var(--p))}
.rg-big{font:600 26px var(--font);fill:var(--ink);letter-spacing:-.02em}
.rg-sub{font:500 10px var(--font);fill:var(--soft)}
.ev-ring-row{display:grid;grid-template-columns:7rem minmax(0,1fr);gap:1rem;align-items:center}
.ev-ring-row svg{width:100%}
.ev-chips{list-style:none;padding:0;margin:0;display:grid;gap:.4rem}
.ev-chips li{font-size:.85rem;color:var(--soft);padding-left:1.2rem;position:relative}
.ev-chips li::before{content:"";position:absolute;left:0;top:.42rem;width:.5rem;height:.5rem;border-radius:50%;background:#c9d3dc}
.ev-chips li.ok::before{background:#2ecc71}
.ev-chips b{color:var(--ink);font-weight:600}
/* checklist */
.ev-steps{list-style:none;padding:0;margin:0;counter-reset:s}
.ev-steps li{display:grid;grid-template-columns:1.5rem minmax(0,1fr) auto;gap:.2rem .6rem;padding:.45rem 0;align-items:baseline;opacity:.35;transform:translateX(-6px);transition:opacity .4s ease,transform .4s ease}
.ev-steps li::before{content:"";grid-row:1/3;width:1.1rem;height:1.1rem;border-radius:50%;background:#2ecc71;align-self:start;margin-top:.15rem;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='12' fill='%23000'/%3E%3Cpath d='M7 12.5l3.2 3.2L17 9' stroke='%23fff' stroke-width='2.4' fill='none'/%3E%3C/svg%3E") center/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='12' fill='%23000'/%3E%3Cpath d='M7 12.5l3.2 3.2L17 9' stroke='%23fff' stroke-width='2.4' fill='none'/%3E%3C/svg%3E") center/contain no-repeat}
.ev-steps b{font-weight:600;font-size:.9rem}
.ev-steps span{grid-column:2;color:var(--soft);font-size:.78rem}
.ev-steps em{grid-row:1/3;font-style:normal;font-family:var(--mono);font-size:.68rem;color:var(--soft)}
.tl-stop.on .ev-steps li{opacity:1;transform:none}
.tl-stop.on .ev-steps li:nth-child(1){transition-delay:.3s}.tl-stop.on .ev-steps li:nth-child(2){transition-delay:.8s}
.tl-stop.on .ev-steps li:nth-child(3){transition-delay:1.3s}.tl-stop.on .ev-steps li:nth-child(4){transition-delay:1.8s}
/* seats */
.seat-grid{display:grid;grid-template-columns:repeat(20,minmax(0,1fr));gap:.3rem;margin:.2rem 0 .7rem}
.seat-grid i{aspect-ratio:1;border-radius:3px;background:var(--accent);transition:background .5s ease,transform .5s ease}
.tl-stop.on .seat-grid i.x{background:#d7dee4;transform:scale(.7);transition-delay:calc(.8s + (var(--n,0)) * 0s)}
.tl-stop.on .seat-grid i.x{transition-delay:1s}
.ev-legend{display:flex;gap:1.2rem;font-size:.78rem;color:var(--soft);flex-wrap:wrap}
.ev-legend i{display:inline-block;width:.6rem;height:.6rem;border-radius:2px;background:var(--accent);margin-right:.4rem;vertical-align:-.05em}
.ev-legend i.x{background:#d7dee4}
/* terminal */
.term{margin:0;background:#0e1a24;color:#c9d6df;border-radius:12px;padding:.9rem 1rem;font:500 .74rem/1.7 var(--mono);white-space:pre-wrap;word-break:break-word}
.term span{display:block;opacity:0;transform:translateY(4px);transition:opacity .3s ease,transform .3s ease}
.term span.ok{color:#2ecc71;font-weight:600;margin-top:.4rem}
.tl-stop.on .term span{opacity:1;transform:none}
.tl-stop.on .term span:nth-child(1){transition-delay:.2s}.tl-stop.on .term span:nth-child(2){transition-delay:.7s}.tl-stop.on .term span:nth-child(3){transition-delay:1.2s}
.tl-stop.on .term span:nth-child(4){transition-delay:1.7s}.tl-stop.on .term span:nth-child(5){transition-delay:2.2s}.tl-stop.on .term span:nth-child(6){transition-delay:2.8s}
/* inbox */
.inbox{list-style:none;padding:0;margin:0}
.inbox li{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:.1rem .8rem;padding:.45rem 0;border-top:1px solid #eef2f5;align-items:center;opacity:0;transform:translateY(6px);transition:opacity .4s ease,transform .4s ease}
.inbox li:first-child{border-top:0}
.inbox b{font-weight:600;font-size:.88rem}
.inbox span{grid-column:1;color:var(--soft);font-size:.76rem}
.inbox em{grid-row:1/3;font-style:normal;font-family:var(--mono);font-size:.62rem;letter-spacing:.1em;text-transform:uppercase;padding:.25rem .5rem;border-radius:999px;background:#e3f7ec;color:#1e9e5a}
.inbox em.warn{background:#fff3d6;color:#9a6b00}
.tl-stop.on .inbox li{opacity:1;transform:none}
.tl-stop.on .inbox li:nth-child(1){transition-delay:.3s}.tl-stop.on .inbox li:nth-child(2){transition-delay:.6s}.tl-stop.on .inbox li:nth-child(3){transition-delay:.9s}.tl-stop.on .inbox li:nth-child(4){transition-delay:1.2s}
/* rings */
.rings{list-style:none;padding:0;margin:0;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:.8rem;text-align:center}
.rings svg{width:70%;display:block;margin:0 auto .3rem}
.rings b{display:block;font-weight:600;font-size:1.3rem;letter-spacing:-.02em;line-height:1}
.rings span{display:block;font-size:.74rem;color:var(--soft);margin-top:.2rem}
.rings em{display:block;font-style:normal;font-family:var(--mono);font-size:.64rem;color:var(--soft);margin-top:.15rem}
/* trail */
.ev-trail{list-style:none;padding:0 0 0 .5rem;margin:0 0 .6rem;position:relative}
.ev-trail::before{content:"";position:absolute;left:.5rem;top:.6rem;bottom:.6rem;width:2px;background:#e6ebf0}
.ev-trail li{position:relative;padding:.35rem 0 .35rem 1.4rem;opacity:0;transform:translateX(-6px);transition:opacity .4s ease,transform .4s ease}
.ev-trail li::before{content:"";position:absolute;left:-.3rem;top:.62rem;width:.85rem;height:.85rem;border-radius:50%;background:#e0323b;border:2px solid #fff;box-shadow:0 0 0 2px #e0323b}
.ev-trail li:nth-child(n+2)::before{background:#2ecc71;box-shadow:0 0 0 2px #2ecc71}
.ev-trail em{display:block;font-style:normal;font-family:var(--mono);font-size:.64rem;color:var(--soft)}
.ev-trail b{display:block;font-weight:600;font-size:.88rem}
.ev-trail span{display:block;color:var(--soft);font-size:.76rem}
.tl-stop.on .ev-trail li{opacity:1;transform:none}
.tl-stop.on .ev-trail li:nth-child(1){transition-delay:.3s}.tl-stop.on .ev-trail li:nth-child(2){transition-delay:.9s}.tl-stop.on .ev-trail li:nth-child(3){transition-delay:1.5s}.tl-stop.on .ev-trail li:nth-child(4){transition-delay:2.1s}
.shot .ev-steps li,.shot .term span,.shot .inbox li,.shot .ev-trail li{opacity:1;transform:none}
.shot .ev-bar i{width:var(--w)}.shot .rg-fill{stroke-dashoffset:calc(100 - var(--p))}.shot .seat-grid i.x{background:#d7dee4;transform:scale(.7)}
@media (max-width:900px){ .ev{justify-self:stretch;max-width:none;padding:.9rem 1rem} .ev-stats{grid-template-columns:repeat(2,minmax(0,1fr))} .ev-ring-row{grid-template-columns:5.5rem minmax(0,1fr)} .seat-grid{grid-template-columns:repeat(10,minmax(0,1fr))} .term{font-size:.68rem} }
.ev-steps b{grid-column:2;grid-row:1}.ev-steps span{grid-column:2;grid-row:2}.ev-steps em{grid-column:3;grid-row:1/3;text-align:right}
.inbox b{grid-column:1;grid-row:1}.inbox span{grid-column:1;grid-row:2}.inbox em{grid-column:2;grid-row:1/3;align-self:center}

/* timeline video loops: sit over the still, fade in when loaded and the stop is on */
.tl-vid{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;transition:opacity 1s ease;pointer-events:none}
.tl-vid.on.ready{opacity:1}
@media (prefers-reduced-motion:reduce){ .tl-vid{display:none} }

.pg-head{text-align:center;margin-bottom:clamp(2rem,4vw,3.5rem)}
.pg-head h2{font-weight:600;font-size:clamp(2rem,4vw,3.6rem);letter-spacing:-.03em;line-height:1.02;margin:0 auto .7rem;max-width:18ch;color:#fff}
.pg-head p{color:#dbe5ec;font-size:clamp(1.05rem,1.3vw,1.3rem);margin:0 auto;max-width:44ch}
.pg-row{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1rem;align-items:stretch}
.pg-pop{position:absolute;top:-.7rem;left:1.4rem;background:var(--gold);color:#2a1f05;font-family:var(--mono);font-size:.62rem;letter-spacing:.12em;text-transform:uppercase;font-weight:600;padding:.3rem .6rem;border-radius:999px}
.pg-time{display:flex;align-items:baseline;gap:.5rem}
.pg-time b{font-weight:600;font-size:clamp(2.6rem,4vw,3.6rem);letter-spacing:-.04em;line-height:1}
.pg-time span{font-family:var(--mono);font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;opacity:.8}
.pg-price{font-weight:500;font-size:1.25rem;letter-spacing:-.02em}
.pg-price small{font-size:.8rem;opacity:.75;font-weight:400}
.pg-foot{text-align:center;color:#c9d6df;font-size:.9rem;margin:clamp(1.6rem,3vw,2.5rem) auto 0;max-width:70ch}
.pg-foot a{color:#fff}
@media (max-width:1100px){ .pg-row{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (max-width:600px){ .pg-row{grid-template-columns:1fr} }

/* ---- Plans, clean: white, big response times, hairlines, one highlighted card ---- */
.plans-clean{padding:clamp(6rem,10vw,9rem) var(--gutter);background:#fff;border-top:1px solid var(--line)}
.plans-clean .pg-head h2{color:var(--ink)}
.plans-clean .pg-head p{color:var(--soft)}
.plans-clean .pg-row{gap:0;border:1px solid var(--line);border-radius:24px;overflow:hidden;background:#fff}
.pc{position:relative;display:flex;flex-direction:column;gap:.5rem;padding:2.2rem 1.8rem 1.8rem;border-left:1px solid var(--line);color:var(--ink);transition:background .3s ease}
.pc:first-child{border-left:0}
.pc:hover{background:#f7f9fb}
.pc .pg-time{align-items:baseline}
.pc .pg-time b{font-weight:600;font-size:clamp(2.8rem,4.4vw,4.2rem);letter-spacing:-.045em;line-height:1;color:var(--ink)}
.pc .pg-time span{color:var(--soft)}
.pc h3{font-weight:600;font-size:1.2rem;margin:.2rem 0 0}
.pc .pg-price{color:var(--ink)}
.pc .pg-price small{color:var(--soft)}
.pc ul{list-style:none;padding:0;margin:.8rem 0 1.4rem;display:grid;gap:.5rem;flex:1}
.pc li{position:relative;padding-left:1.25rem;font-size:.9rem;line-height:1.45;color:#3b4b58}
.pc li::before{content:"";position:absolute;left:0;top:.5rem;width:.5rem;height:.5rem;border-radius:50%;background:var(--accent)}
.pc .btn{align-self:flex-start}
.pc .btn.quiet{background:#fff;border:1px solid var(--line);color:var(--ink)}
.pc .btn.quiet:hover{border-color:var(--accent)}
.pc-hi{background:var(--accent);color:#fff}
.pc-hi:hover{background:#00466c}
.pc-hi .pg-time b,.pc-hi .pg-price,.pc-hi h3{color:#fff}
.pc-hi .pg-time span,.pc-hi .pg-price small{color:#cfe0ea}
.pc-hi li{color:#e6eef4}
.pc-hi li::before{background:#1ac6ff}
.pc-hi .pg-pop{top:1.1rem;left:auto;right:1.4rem}
.pc-hi .btn.primary{background:#fff;color:var(--accent)}
.plans-clean .pg-foot{color:var(--soft)}
.plans-clean .pg-foot a{color:var(--accent)}
@media (max-width:1100px){ .pc:nth-child(3){border-left:0} .pc:nth-child(n+3){border-top:1px solid var(--line)} }
@media (max-width:600px){ .pc{border-left:0;border-top:1px solid var(--line)} .pc:first-child{border-top:0} }

/* ---- Why CarpaTech, as art: four portrait prints, words on the print ---- */
.art{padding:clamp(5rem,9vw,8rem) var(--gutter);background:#0e1a24;color:#fff}
.art-head h2{font-weight:600;font-size:clamp(2rem,4vw,3.6rem);letter-spacing:-.03em;margin:0 0 clamp(1.6rem,3vw,2.6rem);color:#fff}
.art-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.8rem}
.art-tile{position:relative;margin:0;aspect-ratio:4/5;overflow:hidden;border-radius:16px;background:#0b1520;isolation:isolate}
.art-tile img{width:100%;height:100%;object-fit:cover;display:block;transition:transform 1.4s cubic-bezier(.16,1,.3,1),filter .6s ease}
.art-tile:hover img{transform:scale(1.05)}
.art-tile figcaption{position:absolute;inset:auto 0 0 0;padding:1.6rem 1.4rem 1.4rem;
  background:linear-gradient(0deg,rgba(6,18,28,.85) 0%,rgba(6,18,28,.45) 60%,rgba(6,18,28,0) 100%)}
.art-tile b{display:block;font-weight:600;font-size:clamp(1.15rem,1.6vw,1.5rem);letter-spacing:-.02em;line-height:1.1;margin-bottom:.4rem}
.art-tile span{display:block;color:#c9d6df;font-size:.86rem;line-height:1.45;max-height:0;opacity:0;overflow:hidden;transition:max-height .6s cubic-bezier(.2,.8,.2,1),opacity .5s ease}
.art-tile:hover span,.art-tile:focus-within span{max-height:8rem;opacity:1}
.art-grid .art-tile:nth-child(2){transition-delay:.08s}.art-grid .art-tile:nth-child(3){transition-delay:.16s}.art-grid .art-tile:nth-child(4){transition-delay:.24s}
@media (max-width:1000px){ .art-grid{grid-template-columns:repeat(2,minmax(0,1fr))} .art-tile span{max-height:8rem;opacity:1} }
@media (max-width:520px){ .art-grid{grid-template-columns:1fr} .art-tile{aspect-ratio:4/4} }
/* art tiles on phones: taller portrait, larger words, always-on captions */
@media (max-width:520px){
  .art{padding:3.5rem var(--gutter)}
  .art-head h2{font-size:1.9rem}
  .art-grid{gap:.6rem}
  .art-tile{aspect-ratio:4/5;border-radius:14px}
  .art-tile figcaption{padding:1.2rem 1rem 1rem}
  .art-tile b{font-size:1.15rem}
  .art-tile span{font-size:.82rem}
}

/* the day, as a story: bigger words, a chapter number, a skip button that floats */
.tl-head{margin-bottom:1rem}
.tl-head h2{font-size:clamp(1.9rem,3.4vw,3.2rem);letter-spacing:-.03em;max-width:none}
.tl-sub{margin:.4rem 0 0;color:#9fb3c2;font-size:clamp(.95rem,1.1vw,1.15rem)}
.tl-stop h3{font-size:clamp(2.2rem,4.6vw,5rem);max-width:12ch;line-height:.98}
.tl-stop .day-copy p{font-size:clamp(1.1rem,1.5vw,1.55rem);max-width:36ch;line-height:1.45}
.tl-stop .clock{font-size:1.1rem;letter-spacing:.2em;color:#1ac6ff;margin-bottom:.8rem}
.tl-stop .clock::before{content:counter(chapter,decimal-leading-zero) " / 12";counter-increment:chapter;display:block;font-size:.66rem;letter-spacing:.24em;color:#7f93a3;margin-bottom:.5rem}
.tl-stage{counter-reset:chapter}
.tl-stop .quote{font-size:1.05rem;margin-top:1.4rem;color:#c9d6df}
.tl-skipbtn{position:fixed;right:clamp(1rem,3vw,2.5rem);bottom:clamp(1rem,3vw,2rem);z-index:40;display:none;align-items:center;gap:.5rem;
  padding:.7rem 1.1rem;border-radius:999px;background:rgba(10,14,20,.7);color:#fff;text-decoration:none;font-size:.88rem;font-weight:500;
  border:1px solid rgba(255,255,255,.3);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);box-shadow:0 12px 40px rgba(0,0,0,.35);
  transition:transform .3s cubic-bezier(.34,1.56,.64,1),background .2s ease}
.tl-skipbtn:hover{transform:translateY(-2px);background:rgba(10,14,20,.9)}
body.in-day .tl-skipbtn{display:inline-flex}
@media (max-width:900px){
  .tl-stop h3{font-size:1.75rem}
  .tl-stop .day-copy p{font-size:.95rem}
  .tl-stop .clock{font-size:.85rem}
  .tl-head h2{font-size:1.35rem}
  .tl-sub{font-size:.8rem}
  .tl-skipbtn{font-size:.8rem;padding:.6rem .9rem}
}
.tl-head > div{flex-direction:column;align-items:flex-start;gap:.2rem}
.tl-head{align-items:flex-start}
/* skip button: springs up from below, breathes, arrow nudges, and it retreats when you leave */
.tl-skipbtn{display:inline-flex;opacity:0;transform:translateY(40px) scale(.7);pointer-events:none;
  transition:transform .55s cubic-bezier(.34,1.56,.64,1),opacity .35s ease,background .2s ease}
body.in-day .tl-skipbtn{opacity:1;transform:none;pointer-events:auto;animation:skip-breathe 3.2s ease-in-out 1.2s infinite}
body.in-day .tl-skipbtn span{display:inline-block;animation:skip-nudge 1.6s ease-in-out .8s infinite}
.tl-skipbtn::before{content:"";position:absolute;inset:-6px;border-radius:999px;border:1px solid rgba(26,198,255,.55);opacity:0}
body.in-day .tl-skipbtn::before{animation:skip-ring 2.4s ease-out 1.2s infinite}
.tl-skipbtn:hover{transform:translateY(-3px) scale(1.04);animation:none}
@keyframes skip-breathe{0%,100%{box-shadow:0 12px 40px rgba(0,0,0,.35),0 0 0 0 rgba(26,198,255,.35)}50%{box-shadow:0 16px 50px rgba(0,0,0,.4),0 0 0 8px rgba(26,198,255,0)}}
@keyframes skip-nudge{0%,100%{transform:translateX(0)}50%{transform:translateX(5px)}}
@keyframes skip-ring{0%{opacity:.8;transform:scale(1)}100%{opacity:0;transform:scale(1.35)}}
@media (prefers-reduced-motion:reduce){ body.in-day .tl-skipbtn,body.in-day .tl-skipbtn span,body.in-day .tl-skipbtn::before{animation:none} }

/* ---- The day on a short desktop window: buy vertical budget back so the whole
   evidence card, its footer line and its Sample mark stay inside the pinned stage.
   Desktop only (min-width:901px); the phone budget is handled by its own block. ---- */
@media (min-width:901px) and (max-height:1000px){
  .tl-sticky{padding:5rem var(--gutter) 3.25rem}
  .tl-head{margin-bottom:.5rem}
  .tl-head h2{font-size:clamp(1.4rem,2.2vw,2.1rem)}
  .tl-sub{font-size:.95rem;margin-top:.25rem}
  .tl-track li{width:3.8rem}
  .tl-track li b{font-size:.6rem}
  .tl-stop h3{font-size:clamp(1.9rem,3.4vw,3rem);margin-bottom:.7rem}
  .tl-stop .clock{font-size:.95rem;margin-bottom:.5rem}
  .tl-stop .day-copy p{font-size:clamp(1rem,1.2vw,1.2rem)}
  .tl-stop .quote{margin-top:.8rem;font-size:.92rem}
  .tl-skipbtn{bottom:.7rem;padding:.55rem .9rem;font-size:.8rem}
}
/* zoom, not transform:scale, because .tl-stop.on > :last-child{transform:none} wins over any
   transform we could set on the evidence column. */
@media (min-width:901px) and (max-height:880px){
  .ev,.qcard,.report,.ticket,.day-screen{zoom:.88}
}
@media (min-width:901px) and (max-height:810px){
  .ev,.qcard,.report,.ticket,.day-screen{zoom:.78}
  .tl-stop .quote{display:none}
}
@media (min-width:901px) and (max-height:750px){
  .ev,.qcard,.report,.ticket,.day-screen{zoom:.66}
}

/* ---- The day on a phone: the same budget problem, solved by reclaiming the header and
   tightening the card, and by reserving a band for the floating Skip pill. This block sits
   after every other max-width:900px block so it is not re-inflated by one of them. ---- */
@media (max-width:900px){
  .tl-sticky{padding:4.3rem 1rem 3.1rem}
  .tl-head{margin-bottom:.4rem;gap:.4rem}
  .tl-stop{gap:.7rem}
  .ev-trail{margin-bottom:.35rem}
  .tl-sub{display:none}
  .tl-track li img{height:2.6rem}
  .tl-stop h3{font-size:1.35rem;margin-bottom:.3rem;line-height:1.06}
  .tl-stop .clock{font-size:.72rem;margin-bottom:.3rem}
  .tl-stop .day-copy p{font-size:.82rem;line-height:1.35}
  .ev{font-size:.8rem;padding:.7rem .85rem}
  .ev-top{padding-bottom:.5rem;margin-bottom:.5rem}
  .av{width:1.9rem;height:1.9rem;font-size:.72rem}
  .ev-hero{margin:.15rem 0 .55rem}
  .ev-hero b{font-size:1.45rem}
  .ev-hero span{font-size:.76rem;margin-top:.2rem}
  .ev-hero.small b{font-size:1.15rem}
  .ev-stats b{font-size:1rem}
  .ev-bar{margin-top:.5rem}
  .ev-foot{margin-top:.5rem;padding-top:.45rem;font-size:.68rem}
  .inbox li,.ev-trail li,.ev-steps li,.q-rows li{padding-top:.2rem;padding-bottom:.2rem}
  .inbox b,.ev-trail b,.ev-steps b{font-size:.8rem}
  .inbox span,.ev-trail span,.ev-steps span{font-size:.68rem}
  .ev-trail em,.inbox em{font-size:.6rem}
  .tl-skipbtn{padding:.5rem .85rem;font-size:.76rem;bottom:.6rem}
  .tl-skipbtn::before{display:none}
}
/* ---- Shorter phone windows (small handsets, or any phone with the browser toolbar showing,
   where 100dvh is well under 844). Everything from here to the end of the day section is sorted
   shortest-last, so the last tier a viewport matches is the one that wins.

   Two of the twelve evidence cards cannot be shrunk by zoom at all, because their height is a
   fraction of their own width rather than of their type size: the 12:00 seat grid (square cells,
   ten per row) and the 07:30 screenshot (16:9). They are handled first, on their own terms. */
@media (max-width:900px) and (max-height:720px){
  /* forty seats in twenty columns is two rows instead of four */
  .seat-grid{grid-template-columns:repeat(20,minmax(0,1fr));gap:.22rem}
}
@media (max-width:900px) and (max-height:700px){
  .tl-head h2{font-size:1.1rem}
  .tl-track li img{height:2rem}
  .tl-stop h3{font-size:1.15rem}
  .tl-stop .day-copy p{font-size:.76rem}
}
@media (max-width:900px) and (max-height:660px){
  /* narrow the 16:9 figure and it comes down proportionally, uncropped */
  .tl-stop .day-screen{max-width:88%;margin-inline:auto}
}
/* Under ~620 of viewport height the copy block alone (rail + clock + headline + paragraph)
   eats the whole stage, and no amount of card zoom keeps the card off the Skip pill. Buy the
   last ~45px back from the furniture instead. Nothing above the h2 moves: the nav island still
   needs the 4.3rem of padding-top. */
@media (max-width:900px) and (max-height:620px){
  .tl-head h2{font-size:.95rem}
  .tl-head{margin-bottom:.25rem}
  .tl-track li img{height:1.5rem}
  .tl-track li b{font-size:.5rem;margin-top:.1rem}
  .tl-stop{gap:.5rem}
  .tl-stop .clock{font-size:.66rem;margin-bottom:.2rem}
  .tl-stop h3{font-size:1rem;margin-bottom:.2rem}
  .tl-stop .day-copy p{font-size:.7rem;line-height:1.28}
  .ev-trail{margin-bottom:.2rem}
  .tl-stop .day-screen{max-width:76%;margin-inline:auto}
}
/* ---- The evidence-card zoom ladder.
   Three coarse steps (.85 / .72 / .56) left cliffs: just above a boundary the card was still
   sized for the tier above it and ran past the bottom of the pinned stage, where it was clipped
   and the fixed "Skip the day" pill landed on its cut edge. Worst case measured at 390x705:
   the card ran 17px past the pill's top edge and lost its footer line and Sample mark.
   The stage gives the card (viewport height - header - copy - the 3.1rem Skip band), which grows
   1px per 1px of viewport height, so the steps are ~20-40px apart and each one is chosen to keep
   the tallest stop (12:00, and 02:00 above 700) clear of the pill at the SHORT end of its band. */
@media (max-width:900px) and (max-height:900px){ .ev,.qcard,.ticket,.report,.day-screen{zoom:.85} }
@media (max-width:900px) and (max-height:820px){ .ev,.qcard,.ticket,.report,.day-screen{zoom:.78} }
@media (max-width:900px) and (max-height:780px){ .ev,.qcard,.ticket,.report,.day-screen{zoom:.68} }
@media (max-width:900px) and (max-height:740px){ .ev,.qcard,.ticket,.report,.day-screen{zoom:.63} }
@media (max-width:900px) and (max-height:720px){ .ev,.qcard,.ticket,.report,.day-screen{zoom:.57} }
@media (max-width:900px) and (max-height:700px){ .ev,.qcard,.ticket,.report,.day-screen{zoom:.61} }
@media (max-width:900px) and (max-height:680px){ .ev,.qcard,.ticket,.report,.day-screen{zoom:.57} }
@media (max-width:900px) and (max-height:660px){ .ev,.qcard,.ticket,.report,.day-screen{zoom:.52} }
@media (max-width:900px) and (max-height:640px){ .ev,.qcard,.ticket,.report,.day-screen{zoom:.48} }
@media (max-width:900px) and (max-height:620px){ .ev,.qcard,.ticket,.report,.day-screen{zoom:.50} }
@media (max-width:900px) and (max-height:600px){ .ev,.qcard,.ticket,.report,.day-screen{zoom:.46} }
@media (max-width:900px) and (max-height:580px){ .ev,.qcard,.ticket,.report,.day-screen{zoom:.43} }
@media (max-width:900px) and (max-height:570px){ .ev,.qcard,.ticket,.report,.day-screen{zoom:.40} }

/* The badge eases out of its crop as the contact section leaves, so the last thing you see is
   the NEW CLIENT badge settling rather than sliding away. The footer below is dark, so there is
   no seam left to hide and nothing needs to be pinned or uncovered. */
@supports (animation-timeline:view()){
  @media (prefers-reduced-motion:no-preference){
    .contact-glass .day-media img{
      animation:badge-settle linear both;
      animation-timeline:view();
      animation-range:exit 0% exit 100%}
  }
}
@keyframes badge-settle{
  from{transform:scale(1.28) translateX(10%)}
  to{transform:scale(1.12) translateX(4%)}
}

/* ---- General questions: an editorial index. Questions on the left, the chosen answer
   large on a navy panel to the right. Every answer is in the markup for search. ---- */
.faq-sec{padding:clamp(6rem,10vw,9rem) var(--gutter);background:#f2f6f9;border-top:1px solid var(--line)}
.faq-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.15fr);gap:clamp(2rem,6vw,7rem);align-items:start;max-width:84rem;margin:0 auto}
.faq-left h2{font-weight:300;font-size:clamp(2.2rem,4.4vw,3.6rem);line-height:1.06;letter-spacing:-.015em;margin:0 0 1rem;max-width:12ch;text-wrap:balance}
.faq-sub{color:var(--soft);margin:0 0 1.8rem}
.faq-foot{display:flex;align-items:center;flex-wrap:wrap;gap:1.2rem;margin:0}
.faq-list{list-style:none;margin:2.6rem 0 0;padding:0}
.faq-list button{all:unset;box-sizing:border-box;cursor:pointer;display:grid;grid-template-columns:3.2rem 1fr;width:100%;padding:1.05rem 0;border-top:1px solid var(--line);font-size:1.1rem;line-height:1.4;color:var(--soft);transition:color .25s}
.faq-list li:last-child button{border-bottom:1px solid var(--line)}
.faq-list i{font:500 .78rem/1.8 var(--mono);font-style:normal;color:#9fb0bd;transition:color .25s}
.faq-list button:hover,.faq-list button[aria-selected=true]{color:var(--ink)}
.faq-list button[aria-selected=true] i{color:var(--accent)}
.faq-list button[aria-selected=true] span{background:linear-gradient(var(--accent),var(--accent)) 0 100%/100% 2px no-repeat}
.faq-list button:focus-visible{outline:2px solid var(--accent);outline-offset:4px;border-radius:4px}
.faq-stage{position:sticky;top:7rem;min-height:22rem;background:var(--accent);color:#fff;border-radius:28px;padding:clamp(2rem,4vw,3.4rem);overflow:hidden}
.faq-stage::after{content:"";position:absolute;right:-6rem;bottom:-6rem;width:20rem;height:20rem;border-radius:50%;background:radial-gradient(circle,rgba(255,255,255,.14),transparent 70%);pointer-events:none}
.faq-num{font:500 .8rem var(--mono);opacity:.6;letter-spacing:.1em}
.faq-panel h3{font-weight:400;font-size:clamp(1.3rem,2.2vw,1.75rem);line-height:1.25;margin:1.2rem 0}
.faq-panel p{font-size:1.08rem;line-height:1.7;opacity:.88;margin:0;max-width:34rem}
.faq-panel.in{animation:faq-in .45s cubic-bezier(.2,.7,.2,1)}
@keyframes faq-in{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
@media (max-width:860px){
  .faq-grid{grid-template-columns:1fr;gap:2rem}
  .faq-stage{position:relative;top:0;min-height:0;margin:.4rem 0 1.2rem;border-radius:20px;padding:1.6rem 1.4rem}
  .faq-stage .faq-num,.faq-stage h3{display:none}
  .faq-panel p{font-size:1rem}
}
@media (prefers-reduced-motion:reduce){.faq-panel.in{animation:none}.faq-list button,.faq-list i{transition:none}}
@media (scripting:none){.faq-panel[hidden]{display:block;margin-top:2rem}}

/* ---- General questions: Apple's pill-that-opens pattern ----
   Closed, each question is a pill that hugs its own label, so the column reads as a row of
   topics rather than a table. Open, the pill becomes the card it always was. The answers are
   byte-identical to the FAQPage structured data in index.html, and they stay in the DOM when
   closed rather than being display:none, so a crawler and a screen reader both still get them. */
.qa-sec{background:#f2f6f9;border-top:1px solid var(--line)}
.qa-sec .wrap{max-width:82rem;padding-block:0}
/* The section used to run down the left with the right half empty, because the layout still
   assumed the device that used to sit there. The heading now holds the left column and stays
   with you while the questions scroll, so the width is used and the section has a spine. */
.qa-grid{display:grid;grid-template-columns:minmax(17rem,.86fr) minmax(0,1.14fr);
  column-gap:clamp(2rem,6vw,6.5rem);align-items:start}
.qa-head{margin:0;position:sticky;top:7rem}
.qa-col{min-width:0}
/* No ch cap: the column already sets the measure, and 14ch broke 'General questions' across
   two lines at desktop for no reason. */
.qa-head h2{font-weight:600;font-size:clamp(1.9rem,3.7vw,3.5rem);letter-spacing:-.035em;line-height:1.04;margin:0 0 .9rem;max-width:none;text-wrap:balance}
.qa-head p{color:var(--soft);font-size:clamp(.98rem,1.15vw,1.12rem);margin:0;max-width:34ch;line-height:1.6}

.qa-stack{display:flex;flex-direction:column;align-items:stretch;gap:.6rem;max-width:none}
/* The pill has to hug its own label when closed. The row cannot do that: the answer is still
   in the DOM below it, and a collapsed grid row loses its HEIGHT, not its width, so the hidden
   paragraph was setting every pill to the same 640px. So the pill surface lives on the BUTTON
   while closed, where it sizes to its text, and moves up onto the row when open, where it
   becomes the full-width card. */
.qa-x{align-self:stretch;background:transparent;border-radius:1.5rem;
  transition:background .3s ease,box-shadow .35s ease}
.qa-x-btn{align-self:flex-start;background:var(--panel);border-radius:999px;
  box-shadow:0 1px 2px rgba(14,26,36,.05),0 6px 18px rgba(14,26,36,.04);
  transition:background .3s ease,box-shadow .3s ease,border-radius .45s cubic-bezier(.16,1,.3,1)}
.qa-x.open{background:var(--panel);box-shadow:0 2px 4px rgba(14,26,36,.06),0 14px 40px rgba(14,26,36,.07)}
.qa-x.open .qa-x-btn{background:transparent;box-shadow:none;border-radius:1.5rem 1.5rem 0 0}
.qa-x-h{margin:0;font-size:inherit;font-weight:inherit;display:flex}
.qa-x-btn{display:flex;align-items:center;gap:.85rem;width:auto;max-width:100%;text-align:left;
  padding:.95rem 1.6rem .95rem 1.05rem;border:0;cursor:pointer;
  font:600 clamp(1rem,1.25vw,1.15rem)/1.2 var(--font);color:var(--ink)}
.qa-x.open .qa-x-btn{width:100%}
.qa-x-h{display:flex}
.qa-x-btn:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.qa-x-label{flex:0 1 auto}

/* The plus turns into a close mark on the same stroke, which is cheaper and steadier than
   swapping two icons. */
.qa-x-ico{position:relative;flex:0 0 auto;width:1.55rem;height:1.55rem;border-radius:50%;
  border:1.5px solid rgba(14,26,36,.28);transition:border-color .3s ease,background .3s ease,transform .45s cubic-bezier(.16,1,.3,1)}
.qa-x-ico::before,.qa-x-ico::after{content:"";position:absolute;left:50%;top:50%;background:var(--ink);
  border-radius:1px;transition:background .3s ease,opacity .3s ease}
.qa-x-ico::before{width:.66rem;height:1.5px;transform:translate(-50%,-50%)}
.qa-x-ico::after{width:1.5px;height:.66rem;transform:translate(-50%,-50%)}
.qa-x.open .qa-x-ico{transform:rotate(135deg);border-color:var(--accent)}
.qa-x.open .qa-x-ico::before,.qa-x.open .qa-x-ico::after{background:var(--accent)}
.qa-x-btn:hover .qa-x-ico{border-color:rgba(14,26,36,.5)}

/* 0fr to 1fr animates a height the browser works out itself, so nothing has to be measured
   in JS and the panel stays in the DOM while it is closed. */
.qa-x-panel{display:grid;grid-template-rows:0fr;transition:grid-template-rows .45s cubic-bezier(.16,1,.3,1)}
.qa-x.open .qa-x-panel{grid-template-rows:1fr}
.qa-x-inner{overflow:hidden}
.qa-x-inner p{margin:0;padding:0 1.9rem 1.5rem 3.5rem;color:var(--soft);
  font-size:clamp(.98rem,1.08vw,1.08rem);line-height:1.66;max-width:62ch}
.qa-x-inner b{color:var(--ink);font-weight:600}
.qa-x-inner a{color:var(--accent);font-weight:600;text-underline-offset:3px}

.qa-foot{max-width:none;display:flex;align-items:center;gap:clamp(1rem,2.5vw,2rem);flex-wrap:wrap;margin:clamp(2.2rem,4.5vw,3.4rem) 0 0}
.qa-mail{color:var(--soft);text-decoration:none;font-size:.95rem;border-bottom:1px solid transparent;transition:color .2s ease,border-color .2s ease}
.qa-mail:hover{color:var(--ink);border-bottom-color:var(--line)}
.qa-mail:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:4px}

@media (max-width:900px){
  /* One column on a phone, and the heading stops sticking: a pinned heading on a short
     screen just eats the space the answers need. */
  .qa-grid{grid-template-columns:1fr;row-gap:clamp(1.8rem,4.5vw,2.8rem)}
  .qa-head{position:static}
}
@media (max-width:700px){
  .qa-stack{gap:.55rem}
  .qa-x-btn{padding:.85rem 1.2rem .85rem .9rem;gap:.7rem}
  .qa-x-inner p{padding:0 1.3rem 1.3rem 3.1rem}
}
@media (prefers-reduced-motion:reduce){
  .qa-x,.qa-x-panel,.qa-x-ico{transition:none}
}
/* Without script every panel is open, so the answers are never trapped behind a button
   that cannot be pressed. */
@media (scripting:none){
  .qa-x{align-self:stretch;border-radius:1.5rem}
  .qa-x-panel{grid-template-rows:1fr}
  .qa-x-ico{display:none}
}

/* ---- Thirty nights ----
   The ring chart this replaced drew three arcs at 99.2, 100 and 99.2 per cent. With an 11px
   stroke and a round linecap, gaps of 2.8px and 4.5px were swallowed whole, so it rendered as
   a closed bullseye that would have looked identical at 100/100/100, and its three legend rows
   restated three of the four KPI tiles directly above it. Thirty cells show the one thing a
   tile cannot: consistency. One amber cell in thirty reads as "one night" instantly. */
.d-nights{display:flex;flex-direction:column;justify-content:center}
.nt-row{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:baseline;
  gap:.3rem .7rem;padding:.6rem 0;border-top:1px solid #eef2f5}
.nt-row:first-of-type{border-top:0}
.nt-lab{font-size:.74rem;font-weight:500;color:var(--ink)}
.nt{display:block;width:100%;height:auto;grid-column:1/-1;grid-row:2}
.nt-x{font-size:.72rem;color:var(--soft);white-space:nowrap;justify-self:end}
.d-panel.is-live .nt,.shot .nt{clip-path:inset(0 100% 0 0);
  animation:nt-wipe .75s cubic-bezier(.22,1,.3,1) var(--d) forwards}
.shot .nt{animation-delay:0s}
@keyframes nt-wipe{to{clip-path:inset(0 0 0 0)}}

/* ---- SLA rule ----
   "38 min of the 2 hour promise" is the only mark on the panel that measures a promise against
   a clock, which is the whole product, so it gets drawn as well as written. */
.d-q li{grid-template-rows:auto auto}
.d-q li b{white-space:normal;overflow:visible;text-overflow:clip}
.d-q li > i,.d-q li > b,.d-q li > span,.d-q li > em{grid-row:1}
.d-q .sla{grid-column:2/-1;grid-row:2;height:3px;border-radius:2px;background:#eef2f5;margin-top:.35rem}
.d-q .sla::before{content:"";display:block;height:100%;width:0;border-radius:2px;background:#157f47;
  transition:width .9s cubic-bezier(.22,1,.3,1) .35s}
.d-q li.warn .sla::before{background:#a87b10}
.d-panel.is-live .d-q .sla::before,.shot .d-q .sla::before{width:var(--p)}

/* ---- Sankey ----
   Ported from a React/visx component. Each ribbon is a constant-width stroke rather than a
   filled shape, because a sankey link carries the same value at both ends, so the geometry is
   a centreline. pathLength="100" normalises every path so one dash animation draws them all. */
.d-sankey{display:flex;flex-direction:column}
.sk{display:block;width:100%;max-width:46rem;height:auto;margin:.4rem auto 0;overflow:visible}
.sk-head{font-size:10px;fill:var(--soft);letter-spacing:.08em;text-transform:uppercase}
.sk-link{fill:none;opacity:.34;stroke-dasharray:100;stroke-dashoffset:100;
  transition:opacity .25s ease}
.d-panel.is-live .sk-link,.shot .sk-link{animation:sk-draw 1.1s cubic-bezier(.3,.9,.3,1) var(--d) forwards}
@keyframes sk-draw{to{stroke-dashoffset:0}}
.sk-node{opacity:0;animation:none}
.d-panel.is-live .sk-node,.shot .sk-node{animation:sk-pop .5s ease .1s forwards}
@keyframes sk-pop{to{opacity:1}}
.sk-lab{font-size:11px;fill:var(--ink);paint-order:stroke;stroke:#fff;stroke-width:3.5px;
  stroke-linejoin:round;opacity:0;cursor:default}
.d-panel.is-live .sk-lab,.shot .sk-lab{animation:sk-pop .5s ease .35s forwards}
.sk-num{fill:var(--soft);font-family:var(--mono);font-size:10px;stroke-width:3px}
/* Hovering a node follows its bands through the diagram: everything else steps back. */
.sk.is-focus .sk-link{opacity:.07}
.sk.is-focus .sk-link.on{opacity:.72}
.sk.is-focus .sk-lab{opacity:.3}
.sk.is-focus .sk-lab.on{opacity:1}
.sk-node{cursor:default}

/* ---- Sunburst ----
   Two rings, inner by platform and outer by model. Segments are filled arc paths that scale up
   out of the centre on a stagger; the centre label follows the pointer. */
.d-sun{display:flex;flex-direction:column;align-items:center;justify-content:center}
.d-sun .d-h{align-self:stretch}
.d-h2{margin-top:.9rem;padding-top:.7rem;border-top:1px solid var(--line)}
.sb{position:relative;display:grid;place-items:center;width:min(100%,16rem);aspect-ratio:1;margin:.3rem auto 0}
.sb-svg{display:block;width:100%;height:auto;overflow:visible}
.sb-seg{opacity:0;transform-box:fill-box;transform-origin:center;
  transition:opacity .25s ease,filter .25s ease;cursor:default}
.d-panel.is-live .sb-seg,.shot .sb-seg{animation:sb-in .7s cubic-bezier(.22,1,.3,1) var(--d) forwards}
@keyframes sb-in{from{opacity:0;transform:scale(.55)}to{opacity:1;transform:none}}
.sb.is-focus .sb-seg{opacity:.22}
.sb.is-focus .sb-seg.on{opacity:1;filter:drop-shadow(0 2px 6px rgba(0,63,97,.28))}
.sb-mid{position:absolute;text-align:center;pointer-events:none;line-height:1.15;max-width:7.5rem}
.sb-mid b{display:block;font-size:1.5rem;font-weight:600;letter-spacing:-.02em;color:var(--ink);
  font-variant-numeric:tabular-nums}
.sb-mid small{display:block;font-size:.72rem;color:var(--soft);margin-top:.15rem}
.d-endp-list li{cursor:default}
.d-endp-list li.on{background:#f2f6f9;border-radius:8px}

@media (max-width:900px){
  .d-endp .d-sun,.d-endp .d-endp-list{grid-column:span 2}
}
.sk-wrap{position:relative;min-width:0}
.d-swipe{display:none}
@media (max-width:640px){
  .d-brand{white-space:nowrap}
  /* The strip runs off the edge here, so it fades rather than cutting a label in half. */
  .d-tabs{gap:.1rem;padding-right:1.8rem;-webkit-overflow-scrolling:touch;
    -webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 2.2rem),transparent);
    mask-image:linear-gradient(90deg,#000 calc(100% - 2.2rem),transparent)}
  .d-panel{min-height:0}
  .d-endp .d-sun,.d-endp .d-endp-list{grid-column:1/-1}
  /* The sankey does not usefully compress to phone width, so it scrolls behind a fade. */
  .sk-head{font-size:13px}
  .sk-lab{font-size:14px;stroke-width:4px}
  .sk-num{font-size:13px}
  .sk-wrap{overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch;
    -webkit-mask-image:linear-gradient(90deg,#000 88%,transparent);mask-image:linear-gradient(90deg,#000 88%,transparent)}
  .sk-wrap::-webkit-scrollbar{display:none}
  .sk{min-width:31rem;max-width:none}
  .d-swipe{display:block;margin:.4rem 0 0;font-size:.7rem;color:var(--soft)}
}
@media (prefers-reduced-motion:reduce){
  .sk-link{animation:none;stroke-dashoffset:0}
  .sk-node,.sk-lab,.sb-seg{animation:none;opacity:1;transform:none}
  .d-panel,.d-panel.is-live{animation:none}
  .nt{animation:none;clip-path:none}
  .d-line,.d-area{animation:none;stroke-dashoffset:0;opacity:1}
  .d-q .sla::before{transition:none;width:var(--p)}
}

/* ================================================================
   THE SERVICE SPLIT. One shell, twelve panels.  /services/<slug>.

   The photograph stays, and it loses. That is the idea. It sits full
   bleed behind a navy wash in a pinned left column, and a dark console
   plate floats in front of it. As the right column is read, the wash
   deepens and the photograph pushes in, so it recedes from subject to
   texture while the plate advances through four states. The page starts
   as a photograph and ends as a diagram, and the reader did that with
   the scrollbar.

   Stage detection is an IntersectionObserver in home.js, not a CSS
   scroll timeline: stages are discrete and latched, animation-range
   cannot express "hold until the next block", and Firefox has no
   animation-timeline at all, so a stage machine built on one would look
   finished while never advancing. Scroll-driven animation is still used
   for the two things it is best at, the lede ink sweep and the block
   entrances, both of which REST in their finished state and so degrade
   to a complete page.
   ================================================================ */

.sv{
  --sv-pad:clamp(1.5rem,2.6vw,2.75rem);
  --sv-top:4.6rem;
  --sv-head:9.5rem;
  --sv-bar:3.6rem;
  --sv-pinned:1;
  --sv-plate:#0b1620;
  --sv-hair:rgba(255,255,255,.13);
  --sv-ink:#e8eff4;
  --sv-mute:#8fa3b3;
  --sv-cyan:#1ac6ff;
  --sv-ok:#2ecc71;
  --sv-warn:#d9a520;
  --sv-dur:520ms;
  --sv-ease:cubic-bezier(.22,1,.3,1);
  display:grid;
  grid-template-columns:minmax(0,44fr) minmax(0,56fr);
  /* clip, never hidden: overflow:hidden on a sticky ancestor kills the pin
     silently and the page still looks plausible in a screenshot. */
  overflow-x:clip;
  isolation:isolate;
  background:#fff;
}

/* Column one, layer one: the photograph. */
/* CHANGED: span 99, not 1/-1. -1 counts from the end of the EXPLICIT grid, so the
   draft needed grid-template-rows kept in step with the block count in two places.
   span 99 cannot be got wrong. */
.sv-side{
  grid-column:1;grid-row:1 / span 99;align-self:start;
  position:sticky;top:0;height:100svh;overflow:hidden;
  background:var(--ink);z-index:0;
}
.sv-photo{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  transform:scale(var(--sv-z,1.04));transform-origin:50% 42%;
  transition:transform 900ms var(--sv-ease);
}
/* The clip. The photograph underneath is its poster and its fallback, so the
   panel is never empty: home.js attaches the src only after a real interaction
   signal, skips it entirely on saveData or 2g, and pauses it off screen, which
   means an unwatched page downloads nothing. It carries the same --sv-z as the
   photograph so the recede applies to whichever layer is showing. */
.sv-vid{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:0;transition:opacity 1100ms ease;
  transform:scale(var(--sv-z,1.04));transform-origin:50% 42%;
  transition-property:opacity,transform;
  transition-duration:1100ms,900ms;
  transition-timing-function:ease,var(--sv-ease)}
.sv-vid.on{opacity:1}
.sv-side:has(.sv-vid.on) .sv-wash{opacity:calc(var(--sv-wash-o,.72) * .62)}
@media (prefers-reduced-motion:reduce){ .sv-vid{display:none} }
/* sv-film: the column is the service's own film, not a backdrop for a plate, so it
   shows at full strength. Only a top shade stays, for the tier label and the h1. */
.sv-film .sv-side{background:#ecf0f3}
.sv-film .sv-wash,.sv-film .sv-side:has(.sv-vid.on) .sv-wash{opacity:1;
  background:linear-gradient(180deg,rgba(6,18,28,.62) 0%,rgba(6,18,28,.22) 26%,rgba(6,18,28,0) 44%)}
.sv-film[data-stage]{--sv-z:1}

.sv-wash{
  position:absolute;inset:0;pointer-events:none;
  background:
    linear-gradient(180deg,rgba(6,18,28,.58) 0%,rgba(6,18,28,.26) 34%,rgba(6,18,28,.88) 100%),
    linear-gradient(90deg,rgba(6,18,28,0) 52%,rgba(6,18,28,.55) 100%);
  opacity:var(--sv-wash-o,.72);
  transition:opacity 700ms ease;
}
.sv[data-stage="0"]{--sv-z:1.04;--sv-wash-o:.72}
.sv[data-stage="1"]{--sv-z:1.08;--sv-wash-o:.86}
.sv[data-stage="2"]{--sv-z:1.11;--sv-wash-o:.91}
.sv[data-stage="3"]{--sv-z:1.14;--sv-wash-o:.93}

.sv-head{position:absolute;left:0;top:0;right:0;z-index:2;
  padding:var(--sv-top) var(--sv-pad) 0;pointer-events:none}
.sv-tier{margin:0 0 .85rem;font:600 .68rem/1 var(--mono);
  letter-spacing:.2em;text-transform:uppercase;color:rgba(255,255,255,.62)}
.sv-h1{margin:0;color:#fff;font-weight:600;
  font-size:clamp(1.4rem,1.95vw,2.1rem);line-height:1.04;letter-spacing:-.03em;
  max-width:15ch;text-wrap:balance}

/* Column one, layer two: the plate. */
.sv-port{
  grid-column:1;grid-row:1 / span 99;align-self:start;
  position:sticky;top:0;height:100svh;z-index:2;
  display:grid;grid-template-rows:minmax(0,1fr) auto;justify-items:center;
  padding:calc(var(--sv-top) + var(--sv-head)) var(--sv-pad) var(--sv-pad);
}
/* CHANGED: 24rem, not 22rem. The shell's own vertical furniture measures 23.05rem;
   at 1440x900 the old constant overflowed the caption by about 17px. */
.sv-stage{
  --sv-i:0;
  position:relative;
  width:min(100%,36rem,(100svh - 24rem) * 1.3333);
  aspect-ratio:4 / 3;
  container-type:inline-size;
  background:var(--sv-plate);
  border:1px solid var(--sv-hair);
  border-radius:18px;
  overflow:hidden;
  color:var(--sv-ink);
  box-shadow:0 34px 76px rgba(2,10,18,.52),inset 0 1px 0 rgba(255,255,255,.06);
  align-self:center;
}
/* The handover flash. CHANGED in step 3: two alternating classes instead of one,
   so home.js never has to read offsetWidth to retrigger it. */
.sv-stage::after{content:"";position:absolute;inset:0;border-radius:inherit;
  pointer-events:none;z-index:9;box-shadow:inset 0 0 0 1px rgba(26,198,255,.75);opacity:0}
@media (prefers-reduced-motion:no-preference){
  .sv:not(.sv-still) .sv-stage.sv-fa::after,
  .sv:not(.sv-still) .sv-stage.sv-fb::after{animation:sv-ping 900ms ease-out}
}
@keyframes sv-ping{0%{opacity:0}16%{opacity:1}100%{opacity:0}}

/* Off screen, nothing inside the plate ticks. One rule, so twelve authors cannot
   each forget it. Transitions are untouched, which is fine: they are cheap. */
.sv:not(.sv-live) .sv-stage *{animation-play-state:paused}

/* The rail and the caption. */
.sv-foot{width:min(100%,36rem);align-self:end;margin-top:1.4rem}
.sv-rail{list-style:none;display:grid;grid-template-columns:repeat(4,1fr);
  gap:.45rem;margin:0 0 .95rem;padding:0}
.sv-rail li{position:relative;height:2px;border-radius:2px;
  background:rgba(255,255,255,.2);overflow:hidden}
.sv-rail li::after{content:"";position:absolute;inset:0;background:var(--sv-cyan);
  transform:scaleX(0);transform-origin:0 50%;
  transition:transform 620ms var(--sv-ease)}
.sv[data-stage="0"] .sv-rail li:nth-child(1)::after,
.sv[data-stage="1"] .sv-rail li:nth-child(-n+2)::after,
.sv[data-stage="2"] .sv-rail li:nth-child(-n+3)::after,
.sv[data-stage="3"] .sv-rail li::after{transform:none}

/* CHANGED: 4.5em, not 4.3em. */
.sv-cap{position:relative;margin:0;min-height:4.5em;max-width:34ch;
  color:rgba(255,255,255,.78);font-size:clamp(.86rem,1vw,1rem);line-height:1.45}
.sv-cap-l{position:absolute;inset:0;opacity:0;transform:translateY(.5em);
  transition:opacity 340ms ease,transform 560ms var(--sv-ease)}
.sv[data-stage="0"] .sv-cap-l[data-k="0"],
.sv[data-stage="1"] .sv-cap-l[data-k="1"],
.sv[data-stage="2"] .sv-cap-l[data-k="2"],
.sv[data-stage="3"] .sv-cap-l[data-k="3"]{opacity:1;transform:none}

/* Column two: the words. */
.sv-b{grid-column:2;
  padding:clamp(3.5rem,6vw,7rem) clamp(2rem,4.5vw,5rem);
  border-bottom:1px solid var(--line);
  /* Each block must own a screen, or the reading band never sits on it alone
     and the stage flickers between two values. */
  min-height:66svh;display:flex;flex-direction:column;justify-content:center}
.sv-b:last-of-type{border-bottom:0}
.sv-b-lede{min-height:82svh}
.sv-b h2{font-size:clamp(1.5rem,2.6vw,2.3rem);letter-spacing:-.02em;margin:0 0 1rem;max-width:18ch}
.sv-b > p{font-size:1.05rem;color:var(--soft);max-width:52ch;margin:0}
/* CHANGED: inc_intro. The real page has it and the draft dropped it. */
.sv-b-inc > p.sv-intro{margin:0 0 .4rem}
.sv-fine{font-size:.9rem;color:var(--soft);max-width:52ch;margin:1.4rem 0 0}
.sv-fine a{color:var(--accent)}

.sv-list{counter-reset:s;list-style:none;padding:0;margin:1.6rem 0 0;display:grid;gap:0}
.sv-list li{padding:.9rem 0;border-top:1px solid var(--line);font-size:1rem;
  display:grid;grid-template-columns:2.2rem minmax(0,1fr);align-items:baseline}
.sv-list li::before{content:counter(s,decimal-leading-zero);counter-increment:s;
  font:600 .68rem var(--mono);color:var(--accent);letter-spacing:.1em}
.sv-steps{counter-reset:t;list-style:none;padding:0;margin:1.6rem 0 0;display:grid;gap:1.3rem}
.sv-steps li{counter-increment:t;display:grid;grid-template-columns:2.6rem minmax(0,1fr);gap:.4rem 1rem}
.sv-steps li::before{content:"0" counter(t);font:600 .7rem var(--mono);
  color:var(--accent);letter-spacing:.14em;padding-top:.25rem}
.sv-steps h3{grid-column:2;font-size:1.05rem;margin:0 0 .3rem}
.sv-steps p{grid-column:2;font-size:.95rem;color:var(--soft);margin:0}

/* The lede, inked word by word. The words are wrapped at build time, each carrying
   its index, the paragraph carrying the count, so one rule serves a lede of any
   length, nothing is measured, and a resize re-resolves the percentages for free.
   Resting state is full ink, so Firefox, no JavaScript and reduced motion all get
   a finished paragraph. */
.sv-lede{font-size:clamp(1.25rem,1.85vw,1.8rem);line-height:1.34;font-weight:300;
  letter-spacing:-.012em;color:var(--ink);max-width:30ch;margin:0}
.sv-lede .w{display:inline-block;color:var(--ink)}
@supports (animation-timeline:view()){
  @media (prefers-reduced-motion:no-preference){
    .sv-b-lede{view-timeline-name:--sv-lede;view-timeline-axis:block}
    .sv-lede .w{color:#b8c5d0;animation:sv-ink linear both;animation-timeline:--sv-lede;
      animation-range:cover calc(14% + (var(--i) / var(--n)) * 46%)
                      cover calc(27% + (var(--i) / var(--n)) * 46%)}
  }
}
@keyframes sv-ink{to{color:var(--ink)}}

@supports (animation-timeline:view()){
  @media (prefers-reduced-motion:no-preference){
    .sv-b > h2,.sv-b > p:not(.sv-lede),.sv-b > .sv-list,.sv-b > .sv-steps{
      animation:sv-rise linear both;animation-timeline:view();animation-range:entry 16% entry 94%}
    .sv-b > .sv-list{animation-range:entry 22% cover 8%}
  }
}
@keyframes sv-rise{from{opacity:0;transform:translate3d(0,26px,0)}to{opacity:1;transform:none}}

@media (min-width:901px) and (max-height:700px){
  .sv{--sv-head:7rem;--sv-top:4.2rem}
  .sv-h1{font-size:clamp(1.25rem,1.7vw,1.6rem)}
  .sv-cap{min-height:3.1em;font-size:.84rem}
}

/* 900px and under: the split comes apart. The photograph and the h1 become the hero
   the prototype already had; the plate detaches into its own short sticky card and
   is the only thing that pins. Same plate, same 4:3, same data-stage. */
@media (max-width:900px){
  .sv{grid-template-columns:minmax(0,1fr)}
  .sv-side{grid-column:1;grid-row:1;position:relative;top:auto;height:auto;
    min-height:58svh;display:flex;align-items:flex-end}
  .sv-head{position:static;padding:clamp(5rem,13vh,7.5rem) 1.25rem 1.6rem;width:100%}
  .sv-h1{font-size:clamp(2rem,8.4vw,2.9rem);max-width:none}
  .sv[data-stage]{--sv-z:1.04;--sv-wash-o:.72}
  .sv-port{grid-column:1;grid-row:2;position:sticky;top:calc(var(--sv-bar) + .4rem);
    height:auto;z-index:3;display:block;padding:.5rem .75rem .65rem;
    background:rgba(247,249,251,.92);
    -webkit-backdrop-filter:blur(12px) saturate(1.3);backdrop-filter:blur(12px) saturate(1.3);
    border-bottom:1px solid var(--line)}
  .sv-stage{width:min(100%,21rem,(100svh - 26rem) * 1.3333);margin-inline:auto}
  .sv-foot{width:100%;margin-top:.55rem}
  .sv-rail{margin-bottom:.5rem}
  .sv-rail li{background:var(--line)}
  .sv-cap{color:var(--soft);font-size:.84rem;min-height:2.9em;max-width:none;
    text-align:center;margin-inline:auto}
  .sv-b{grid-column:1;padding:clamp(2.6rem,9vw,3.6rem) 1.25rem;min-height:70svh}
  .sv-b-lede{min-height:78svh}
  .sv-lede{font-size:1.2rem;max-width:none}
  .sv-b h2{font-size:1.5rem;max-width:none}
}

/* Viewports where pinning is hostile. CSS decides, home.js reads --sv-pinned back
   and freezes the machine at its resolved stage. */
@media (max-width:900px) and (max-height:620px),
       (max-width:900px) and (orientation:landscape){
  .sv{--sv-pinned:0}
  .sv-port{position:relative;top:auto;background:none;border-bottom:0;
    -webkit-backdrop-filter:none;backdrop-filter:none;padding:1.25rem}
  .sv-stage{width:min(100%,26rem)}
}

@media (prefers-reduced-motion:reduce){
  .sv{--sv-dur:0ms}
  .sv-photo,.sv-wash,.sv-cap-l,.sv-rail li::after{transition:none}
  .sv-lede .w{animation:none;color:var(--ink)}
  .sv-b > *{animation:none;opacity:1;transform:none}
  .sv-stage::after{animation:none;opacity:0}
}
.sv-still{--sv-dur:0ms}
.sv-still .sv-photo,.sv-still .sv-wash,.sv-still .sv-cap-l,
.sv-still .sv-rail li::after{transition:none}

/* tools/shot.py reviews all twelve on every pass and a half assembled page
   poisons the loop. */
.shot .sv-lede .w{animation:none;color:var(--ink)}
.shot .sv-b > *{animation:none;opacity:1;transform:none}
.shot .sv-stage::after{animation:none;opacity:0}

/* Shared plate furniture. Every panel's SVG uses these and declares none of them.
   One coordinate system: viewBox 0 0 640 480, margin 24, content 24 to 616.
   The 24px type floor is the contract's legibility rule: at the narrowest real
   stage (336 CSS px) a 24-unit glyph renders at 12.6px. */
.sv-stage svg{display:block;width:100%;height:auto;font-variant-numeric:tabular-nums}
.sv-stage .sg-k{font:600 24px var(--mono);fill:var(--sv-ink);letter-spacing:.16em}
.sv-stage .sg-v{font:600 24px var(--mono);fill:var(--sv-mute);letter-spacing:.16em;
  text-anchor:end;transition:fill var(--sv-dur) linear}
.sv-stage .sg-chip{fill:none;stroke:var(--sv-hair);stroke-width:1.4}
.sv-stage .sg-chipt{font:600 20px var(--mono);fill:var(--sv-mute);
  letter-spacing:.16em;text-anchor:middle}
.sv-stage .sg-hair{stroke:var(--sv-hair);stroke-width:1}
.sv-stage .sg-t{font:400 24px var(--font);fill:var(--sv-ink)}
.sv-stage .sg-lab{font:600 24px var(--mono);fill:var(--sv-mute);letter-spacing:.16em}
.sv-stage .sg-m{fill:var(--sv-mute)}
.sv-stage .sg-cy{fill:var(--sv-cyan)}
.sv-stage .sg-ok{fill:var(--sv-ok)}
.sv-stage .sg-warn{fill:var(--sv-warn)}
/* Anything that belongs to one stage carries .sg-s plus .sg-s0 to .sg-s3.
   One rule, never repeated inside a panel. */
.sv-stage .sg-s{opacity:0;transition:opacity calc(var(--sv-dur) * .7) linear}
.sv-stage[data-stage="0"] .sg-s0,.sv-stage[data-stage="1"] .sg-s1,
.sv-stage[data-stage="2"] .sg-s2,.sv-stage[data-stage="3"] .sg-s3{opacity:1}

The matching Python helper, in the new site/pages/_panels.py (step 9), so no panel emits chrome by hand:

    M, W = 24.0, 592.0          # content box 24 to 616
    VB = 'viewBox="0 0 640 480" preserveAspectRatio="xMidYMid meet"'

    def chrome(heads, reads, chip='SAMPLE'):
        """heads: four (kicker, value) pairs, one per stage.
           reads: four readout lines, one per stage. '' emits nothing."""
        o = ['<rect class="sg-chip" x="516" y="32" width="100" height="28" rx="14"/>',
             '<text class="sg-chipt" x="566" y="51">%s</text>' % chip,
             '<line class="sg-hair" x1="24" y1="78" x2="616" y2="78"/>',
             '<line class="sg-hair" x1="24" y1="424" x2="616" y2="424"/>']
        for i, (k, v) in enumerate(heads):
            o.append('<g class="sg-s sg-s%d"><text class="sg-k" x="24" y="52">%s</text>'
                     '<text class="sg-v" x="500" y="52">%s</text></g>' % (i, k, v))
        for i, r in enumerate(reads):
            if r:
                o.append('<text class="sg-s sg-s%d sg-t sg-m" x="24" y="456">%s</text>'
                         % (i, r))
        return ''.join(o)
