/* LSS.works v5 - "Quiet chrome, loud work".
   Built from Simon's own reference set (garri.design, aaronjames.design,
   benshih.design, fiordaliso.io, jamesfinch.co.uk):
   the page frame stays restrained and ALL visual weight sits in the product
   visuals, which animate to show what each product actually does. No screenshots
   needed - every visual is drawn in code, NDA-safe, and loops. */

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{margin:0}
img{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}

:root{
  --bg:#FAFAF9; --surface:#F1F1EF; --surface-2:#E7E7E4; --chrome:#FFFFFF;
  --ink:#111113; --muted:#6B6B70; --faint:#6E6E73; --line:#E4E4E1; --line-2:#D2D2CE;
  --p-brand:#E60A14; --accent:var(--p-brand); --accent-soft:color-mix(in srgb,var(--p-brand) 12%,transparent); --cta-brand:#E60A14; --cta-brand-hover:#B80404;
  --ok:#1F7A4C;
  --font:'Barlow',system-ui,-apple-system,sans-serif;
  --wrap:1280px;
  --ease:cubic-bezier(.4,0,.2,1);
  --ease-out:cubic-bezier(.16,1,.3,1);
}
:root[data-theme="dark"]{
  --bg:#0D0D0E; --surface:#151517; --surface-2:#1D1D20; --chrome:#191A1C;
  --ink:#EDEDEE; --muted:#8C8C92; --faint:#85858C; --line:#232326; --line-2:#2E2E33;
  --p-brand:#E60A14; --accent:var(--p-brand); --accent-soft:color-mix(in srgb,var(--p-brand) 16%,transparent); --cta-brand:#E60A14; --cta-brand-hover:#FF1E28;
  --ok:#3FBF7F;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --bg:#0D0D0E; --surface:#151517; --surface-2:#1D1D20; --chrome:#191A1C;
    --ink:#EDEDEE; --muted:#8C8C92; --faint:#85858C; --line:#232326; --line-2:#2E2E33;
    --p-brand:#E60A14; --accent:var(--p-brand); --accent-soft:color-mix(in srgb,var(--p-brand) 16%,transparent); --cta-brand:#E60A14; --cta-brand-hover:#FF1E28; --ok:#3FBF7F;
  }
}

body{background:var(--bg);color:var(--ink);font-family:var(--font);font-weight:400;
  font-size:15px;line-height:1.6;transition:background-color .4s var(--ease),color .4s var(--ease)}
.wrap{max-width:var(--wrap);margin:0 auto;padding:0 40px}
@media (max-width:760px){ .wrap{padding:0 20px} }

.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.sr-only:focus{position:fixed;top:12px;left:12px;width:auto;height:auto;padding:10px 16px;margin:0;clip:auto;background:var(--cta-brand);color:#fff;z-index:200}

/* ---------- nav: deliberately small and quiet ---------- */
.nav{display:flex;align-items:flex-start;justify-content:space-between;padding:28px 40px 0}
@media (max-width:760px){ .nav{padding:20px 20px 0} }
.nav .logo{height:18px;width:auto}
.nav .logo-dark{display:none} :root[data-theme="dark"] .nav .logo-light{display:none} :root[data-theme="dark"] .nav .logo-dark{display:block}
.nav-links{display:flex;align-items:center;gap:22px}
.nav-links a:not(.toggle){font-size:13px;color:var(--muted);transition:color .18s var(--ease)}
.nav-links a:not(.toggle):hover{color:var(--ink)}
.burger{display:none;place-items:center;width:40px;height:40px;margin:-10px -10px 0 0}
.burger svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.burger .bi-close,.burger[aria-expanded="true"] .bi-open{display:none}
.burger[aria-expanded="true"] .bi-close{display:block}
.toggle{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--muted)}
.toggle .sw{width:26px;height:15px;border-radius:99px;border:1px solid var(--line-2);position:relative;flex:none}
.toggle .sw::after{content:'';position:absolute;top:2px;left:2px;width:9px;height:9px;border-radius:99px;background:var(--faint);transition:transform .2s var(--ease),background .2s var(--ease)}
.theme-toggle[aria-checked="true"] .sw::after{transform:translateX(11px);background:var(--accent)}
.lang-toggle{position:relative;display:flex;border:1px solid var(--line-2);border-radius:99px;padding:2px}
.lang-toggle .lang-pill{position:absolute;top:2px;left:2px;width:26px;height:calc(100% - 4px);border-radius:99px;background:var(--ink);transition:left .2s var(--ease)}
.lang-opt{position:relative;z-index:1;width:26px;height:18px;font-size:10px;font-weight:600;color:var(--faint)}
.lang-opt[aria-pressed="true"]{color:var(--bg)}
.lang-toggle:has([data-lang-opt="en"][aria-pressed="true"]) .lang-pill{left:calc(100% - 28px)}
@media (max-width:760px){
  .burger{display:grid}
  .nav-links{position:fixed;inset:56px 0 0 0;flex-direction:column;justify-content:flex-start;gap:0;
    background:var(--bg);z-index:90;transform:translateX(100%);transition:transform .3s var(--ease-out);padding:12px 20px}
  .nav-links.open{transform:translateX(0)}
  .nav-links a:not(.toggle){width:100%;padding:16px 0;border-bottom:1px solid var(--line);font-size:18px}
  .toggle{margin-top:18px}
}

/* ---------- intro: two lines, no hero theatre ---------- */
.intro{padding-block:96px 20px}
@media (max-width:760px){ .intro{padding-block:56px 12px} }
.intro h1{margin:0;font-size:clamp(19px,2.1vw,26px);font-weight:500;line-height:1.45;letter-spacing:-.01em;max-width:44ch}
.intro h1 .dim{color:var(--muted)}
.intro .meta{display:flex;flex-wrap:wrap;gap:8px 20px;margin:22px 0 0;font-size:13px;color:var(--muted)}
.intro .avail{display:inline-flex;align-items:center;gap:8px}
.intro .avail .dot{width:6px;height:6px;border-radius:99px;background:var(--accent);flex:none;animation:breathe 2.4s ease-in-out infinite}
@keyframes breathe{0%,100%{opacity:1}50%{opacity:.35}}
.intro .meta a{border-bottom:1px solid var(--line-2);transition:border-color .18s,color .18s}
.intro .meta a:hover{color:var(--ink);border-color:var(--accent)}

/* ---------- work ---------- */
.work{padding-block:64px 40px}
.label{font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:var(--faint);
  padding-bottom:12px;border-bottom:1px solid var(--line);margin:0 0 0}

.case{display:grid;grid-template-columns:56px 1fr 1.32fr;gap:0 40px;align-items:center;
  padding:52px 0;border-bottom:1px solid var(--line)}
@media (max-width:980px){ .case{grid-template-columns:44px 1fr;gap:0 20px;padding:36px 0} }

.case .year{font-size:12px;color:var(--faint);font-variant-numeric:tabular-nums;align-self:start;padding-top:4px}
.case .txt{min-width:0}
.case .kicker{font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--faint);margin:0 0 10px}
.case h2{margin:0 0 10px;font-size:clamp(22px,2.5vw,30px);font-weight:600;letter-spacing:-.015em;line-height:1.15}
.case p{margin:0;color:var(--muted);font-size:15px;line-height:1.62;max-width:46ch}
.case .out{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px;margin:18px 0 0}
.case .out .fig{font-size:20px;font-weight:600;color:var(--accent);font-variant-numeric:tabular-nums;letter-spacing:-.01em}
.case .out .cap{font-size:13px;color:var(--muted)}
.case .go{display:inline-flex;align-items:center;gap:7px;margin:18px 0 0;font-size:13px;font-weight:500;
  border-bottom:1px solid var(--line-2);padding-bottom:2px;transition:border-color .2s var(--ease)}
.case .go svg{width:13px;height:13px;transition:transform .25s var(--ease-out)}
.case:hover .go{border-color:var(--accent)}
.case:hover .go svg{transform:translateX(3px)}

/* ---------- the product frame: shared chrome for every visual ---------- */
.frame{position:relative;background:var(--chrome);border:1px solid var(--line);border-radius:7px;
  overflow:hidden;aspect-ratio:16/10;box-shadow:0 1px 2px rgba(0,0,0,.04),0 12px 28px -18px rgba(0,0,0,.28)}
@media (max-width:980px){ .frame{grid-column:2;margin-top:24px} }
.frame .bar{height:26px;background:var(--surface);border-bottom:1px solid var(--line);
  display:flex;align-items:center;gap:5px;padding:0 10px}
.frame .bar i{width:6px;height:6px;border-radius:99px;background:var(--line-2)}
.frame .bar i:first-child{background:var(--accent);opacity:.7}
.frame .bar span{margin-left:8px;font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
.stage{position:absolute;inset:26px 0 0 0;padding:14px}

/* ---- visual palette: deliberately higher contrast than the page chrome,
       because the whole point of this design is that the WORK is the loud part ---- */
.frame{
  --v-bg:#FFFFFF; --v-bg-2:#F0F0EE; --v-el:#DCDCD8; --v-el-2:#B8B8B2; --v-ink:#636368;
  --v-line:#E6E6E2; --v-accent:var(--accent);
  background:var(--v-bg);
}
:root[data-theme="dark"] .frame{
  --v-bg:#1B1C1F; --v-bg-2:#232429; --v-el:#33353C; --v-el-2:#4E5158; --v-ink:#9AA0A8;
  --v-line:#2C2E34; --v-accent:#FF3B44;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .frame{
    --v-bg:#1B1C1F; --v-bg-2:#232429; --v-el:#33353C; --v-el-2:#4E5158; --v-ink:#9AA0A8;
    --v-line:#2C2E34; --v-accent:#FF3B44;
  }
}
.frame .bar{background:var(--v-bg-2);border-bottom:1px solid var(--v-line)}
.frame .bar i{background:var(--v-el-2)}
.frame .bar i:first-child{background:var(--v-accent);opacity:.85}
.frame .bar span{color:var(--v-ink)}
.stage{display:flex;flex-direction:column;justify-content:center;gap:clamp(8px,1.6cqw,14px);
  padding:clamp(14px,3cqw,26px)}
.frame{container-type:inline-size}

/* 1 - Budzetowka: two people, shared categories, bars settling */
.v-budget .pair{display:flex;gap:7px}
.v-budget .pair b{width:26px;height:26px;border-radius:99px;background:var(--v-el);display:block}
.v-budget .pair b:nth-child(2){background:var(--v-accent);opacity:.45}
.v-budget .cat{display:grid;grid-template-columns:64px 1fr 42px;gap:12px;align-items:center}
.v-budget .cat .n{height:7px;border-radius:3px;background:var(--v-el)}
.v-budget .cat .track{height:12px;border-radius:99px;background:var(--v-bg-2);overflow:hidden}
.v-budget .cat .fill{display:block;height:100%;background:var(--v-el-2);border-radius:99px;width:0;
  animation:fillbar 4.2s var(--ease-out) infinite}
.v-budget .cat:nth-child(2) .fill{--w:72%;animation-delay:.1s}
.v-budget .cat:nth-child(3) .fill{--w:44%;animation-delay:.35s}
.v-budget .cat:nth-child(4) .fill{--w:88%;background:var(--v-accent);animation-delay:.6s}
.v-budget .cat:nth-child(5) .fill{--w:31%;animation-delay:.85s}
.v-budget .cat .amt{height:7px;border-radius:3px;background:var(--v-el)}
@keyframes fillbar{0%{width:0}28%,88%{width:var(--w,60%)}100%{width:var(--w,60%)}}

/* 2 - QYVO: claims advancing through recovery states */
.v-claims .claim{display:grid;grid-template-columns:1fr 78px;gap:12px;align-items:center;
  padding:9px 0;border-bottom:1px solid var(--v-line)}
.v-claims .claim .id{height:8px;border-radius:3px;background:var(--v-el);width:62%}
.v-claims .claim .st{height:18px;border-radius:99px;background:var(--v-el);position:relative;overflow:hidden}
.v-claims .claim .st::after{content:'';position:absolute;inset:0;background:var(--v-accent);opacity:0;
  animation:settle 5s var(--ease) infinite}
.v-claims .claim:nth-child(1) .st::after{animation-delay:.2s}
.v-claims .claim:nth-child(2) .st::after{animation-delay:1s}
.v-claims .claim:nth-child(3) .st::after{animation-delay:1.8s}
.v-claims .claim:nth-child(4) .st::after{animation-delay:2.6s}
@keyframes settle{0%,10%{opacity:0}22%{opacity:.9}70%{opacity:.9}88%,100%{opacity:0}}
.v-claims .total{display:flex;align-items:center;justify-content:space-between;padding-top:6px}
.v-claims .total .k{height:8px;width:64px;border-radius:3px;background:var(--v-el)}
.v-claims .total .v{height:14px;width:84px;border-radius:3px;background:var(--v-accent);opacity:.9;
  animation:grow 5s var(--ease-out) infinite}
@keyframes grow{0%{width:22px}45%,100%{width:84px}}

/* 3 - Data Market Point: search -> results -> request basket */
.v-market .search{height:28px;border-radius:6px;background:var(--v-bg-2);border:1px solid var(--v-line);
  position:relative;overflow:hidden;flex:none}
.v-market .search::after{content:'';position:absolute;left:10px;top:10px;height:8px;width:0;border-radius:3px;
  background:var(--v-el-2);animation:typing 5.5s steps(16,end) infinite}
@keyframes typing{0%{width:0}25%,88%{width:128px}100%{width:0}}
.v-market .grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
.v-market .card{height:52px;border:1px solid var(--v-line);border-radius:6px;background:var(--v-bg-2);
  opacity:0;animation:pop 5.5s var(--ease-out) infinite}
.v-market .card:nth-child(1){animation-delay:1.5s}
.v-market .card:nth-child(2){animation-delay:1.68s}
.v-market .card:nth-child(3){animation-delay:1.86s}
.v-market .card:nth-child(4){animation-delay:2.04s}
.v-market .card:nth-child(5){animation-delay:2.22s}
.v-market .card:nth-child(6){animation-delay:2.4s}
.v-market .card.picked{border-color:var(--v-accent);background:var(--accent-soft)}
@keyframes pop{0%,20%{opacity:0;transform:translateY(6px)}32%,88%{opacity:1;transform:none}100%{opacity:0}}
.v-market .basket{display:flex;align-items:center;gap:8px}
.v-market .basket .b{height:22px;width:64px;border-radius:99px;background:var(--v-el)}
.v-market .basket .b.on{background:var(--v-accent);width:92px;animation:blink 5.5s var(--ease) infinite}
@keyframes blink{0%,55%{opacity:.3}62%,90%{opacity:1}100%{opacity:.3}}

/* 4 - E-mobility: charging estate switching state, multi-role */
.v-charge .roles{display:flex;gap:7px}
.v-charge .roles i{height:18px;width:52px;border-radius:99px;background:var(--v-el)}
.v-charge .roles i.on{background:var(--v-accent);animation:roleswap 6s steps(1) infinite}
@keyframes roleswap{0%,32%{opacity:.9}33%,65%{opacity:.3}66%,100%{opacity:.9}}
.v-charge .estate{display:grid;grid-template-columns:repeat(8,1fr);gap:7px}
.v-charge .estate i{aspect-ratio:1;border-radius:4px;background:var(--v-el);
  animation:statecycle 4.6s steps(1) infinite}
.v-charge .estate i:nth-child(3n){animation-delay:.5s}
.v-charge .estate i:nth-child(3n+1){animation-delay:1.4s}
.v-charge .estate i:nth-child(5n){animation-delay:2.2s}
.v-charge .estate i:nth-child(7n){animation-delay:3s}
@keyframes statecycle{0%,40%{background:var(--v-el)}41%,72%{background:var(--v-accent)}73%,100%{background:var(--v-el-2)}}

/* 5 - Self-serve ad platform: wizard advancing + white-label reskin */
.v-wizard .steps{display:flex;align-items:center;gap:8px}
.v-wizard .steps i{height:8px;flex:1;border-radius:99px;background:var(--v-el);position:relative;overflow:hidden}
.v-wizard .steps i::after{content:'';position:absolute;inset:0;width:0;background:var(--v-accent);border-radius:99px;
  animation:stepfill 6s var(--ease) infinite}
.v-wizard .steps i:nth-child(2)::after{animation-delay:1.6s}
.v-wizard .steps i:nth-child(3)::after{animation-delay:3.2s}
@keyframes stepfill{0%{width:0}18%,92%{width:100%}100%{width:0}}
.v-wizard .canvas{border:1px solid var(--v-line);border-radius:7px;padding:14px;background:var(--v-bg-2)}
.v-wizard .canvas .hd{height:10px;width:46%;border-radius:3px;background:var(--v-el-2);margin-bottom:11px}
.v-wizard .canvas .row{display:flex;gap:8px;margin-bottom:8px}
.v-wizard .canvas .row:last-child{margin-bottom:0}
.v-wizard .canvas .row i{height:24px;flex:1;border-radius:4px;background:var(--v-el)}
.v-wizard .brands{display:flex;gap:7px}
.v-wizard .brands i{width:32px;height:12px;border-radius:3px;background:var(--v-el-2);
  animation:reskin 6s steps(1) infinite}
.v-wizard .brands i:nth-child(2){animation-delay:2s}
.v-wizard .brands i:nth-child(3){animation-delay:4s}
@keyframes reskin{0%,30%{background:var(--v-accent)}31%,100%{background:var(--v-el-2)}}

/* 6 - Patient journey: global framework -> local stages -> steps */
.v-journey .tier .tl{height:6px;width:46px;border-radius:3px;background:var(--v-el);margin-bottom:9px;display:block}
.v-journey .nodes{display:flex;align-items:center;gap:0}
.v-journey .nodes i{width:18px;height:18px;border-radius:99px;border:2px solid var(--v-el-2);
  background:var(--v-bg);flex:none;opacity:0;animation:node 5.4s var(--ease-out) infinite}
.v-journey .nodes s{flex:1;height:2px;background:var(--v-el-2);display:block;transform:scaleX(0);
  transform-origin:left;animation:link 5.4s var(--ease-out) infinite}
.v-journey .tier:nth-child(2) i{animation-delay:.2s} .v-journey .tier:nth-child(2) s{animation-delay:.45s}
.v-journey .tier:nth-child(3) i{animation-delay:.9s} .v-journey .tier:nth-child(3) s{animation-delay:1.15s}
.v-journey .tier:nth-child(4) i{animation-delay:1.6s;border-color:var(--v-accent)}
.v-journey .tier:nth-child(4) s{animation-delay:1.85s;background:var(--v-accent);opacity:.75}
@keyframes node{0%,4%{opacity:0;transform:scale(.6)}14%,88%{opacity:1;transform:none}100%{opacity:0}}
@keyframes link{0%,8%{transform:scaleX(0)}22%,88%{transform:scaleX(1)}100%{transform:scaleX(0)}}

/* 7 - Startup brand & design system: tokens assembling into components */
.v-brand .swatches{display:flex;gap:8px}
.v-brand .swatches i{width:38px;height:38px;border-radius:6px;background:var(--v-el);
  opacity:0;animation:pop 5s var(--ease-out) infinite}
.v-brand .swatches i:nth-child(1){animation-delay:.1s;background:var(--v-accent)}
.v-brand .swatches i:nth-child(2){animation-delay:.24s}
.v-brand .swatches i:nth-child(3){animation-delay:.38s;background:var(--v-el-2)}
.v-brand .swatches i:nth-child(4){animation-delay:.52s}
.v-brand .swatches i:nth-child(5){animation-delay:.66s;background:var(--v-el-2)}
.v-brand .spec{height:22px;width:60%;border-radius:3px;background:var(--v-el-2);
  opacity:0;animation:pop 5s var(--ease-out) infinite;animation-delay:.9s}
.v-brand .spec2{height:10px;width:38%;border-radius:3px;background:var(--v-el);
  opacity:0;animation:pop 5s var(--ease-out) infinite;animation-delay:1.05s}
.v-brand .comps{display:flex;flex-wrap:wrap;gap:8px}
.v-brand .comps i{height:26px;border-radius:99px;background:var(--v-el);opacity:0;
  animation:pop 5s var(--ease-out) infinite}
.v-brand .comps i:nth-child(1){width:72px;animation-delay:1.4s;background:var(--v-accent)}
.v-brand .comps i:nth-child(2){width:52px;animation-delay:1.55s}
.v-brand .comps i:nth-child(3){width:86px;animation-delay:1.7s}
.v-brand .comps i:nth-child(4){width:40px;animation-delay:1.85s}
.v-brand .comps i:nth-child(5){width:62px;animation-delay:2s}

/* 8 - ChargeOps: depot readiness at a glance */
.v-fleet{flex-direction:row;align-items:stretch;gap:18px}
.v-fleet .chart{flex:1;display:flex;align-items:flex-end;gap:8px}
.v-fleet .chart i{flex:1;border-radius:3px 3px 0 0;background:var(--v-el);height:10%;
  animation:column 4.8s var(--ease-out) infinite}
.v-fleet .chart i:nth-child(1){--h:46%;animation-delay:.05s}
.v-fleet .chart i:nth-child(2){--h:68%;animation-delay:.16s}
.v-fleet .chart i:nth-child(3){--h:38%;animation-delay:.27s}
.v-fleet .chart i:nth-child(4){--h:84%;background:var(--v-accent);animation-delay:.38s}
.v-fleet .chart i:nth-child(5){--h:57%;animation-delay:.49s}
.v-fleet .chart i:nth-child(6){--h:72%;animation-delay:.6s}
.v-fleet .chart i:nth-child(7){--h:29%;animation-delay:.71s}
@keyframes column{0%{height:8%}30%,88%{height:var(--h,50%)}100%{height:8%}}
.v-fleet .side{width:104px;display:flex;flex-direction:column;justify-content:center;gap:12px;flex:none}
.v-fleet .side .k{height:8px;border-radius:3px;background:var(--v-el);display:block}
.v-fleet .side .ring{width:62px;height:62px;border-radius:99px;border:7px solid var(--v-el);
  border-top-color:var(--v-accent);border-right-color:var(--v-accent);display:block;
  animation:spinup 4.8s var(--ease-out) infinite}
@keyframes spinup{0%{transform:rotate(-120deg)}34%,88%{transform:rotate(48deg)}100%{transform:rotate(-120deg)}}
.v-fleet .side .bus{display:flex;gap:6px}
.v-fleet .side .bus i{width:18px;height:11px;border-radius:2px;background:var(--v-el);
  animation:statecycle 4.8s steps(1) infinite}
.v-fleet .side .bus i:nth-child(2){animation-delay:.9s}
.v-fleet .side .bus i:nth-child(3){animation-delay:1.8s}
.v-fleet .side .bus i:nth-child(4){animation-delay:2.7s}

/* 9 - LiftSystem: a lift car between floors, two doors beside it */
.v-lift{flex-direction:row;align-items:stretch;gap:24px}
.v-lift .shaft{position:relative;width:64px;flex:none;border:2px solid var(--v-el-2);border-radius:4px;display:flex;flex-direction:column;justify-content:space-between;padding:8px 0}
.v-lift .shaft i{display:block;height:2px;background:var(--v-el);margin:0 8px}
.v-lift .shaft .car{position:absolute;left:8px;right:8px;bottom:8px;height:24px;border-radius:3px;background:var(--v-accent);
  animation:rideup 5.2s var(--ease-out) infinite}
@keyframes rideup{0%,8%{transform:translateY(0)}46%,60%{transform:translateY(calc(-1 * var(--ride,88px)))}100%{transform:translateY(0)}}
.v-lift .shaft{--ride:88px}
.v-lift .doors{flex:1;display:flex;flex-direction:column;justify-content:center;gap:12px}
.v-lift .doors .btn{height:28px;border-radius:99px;background:var(--v-el);width:62%;display:block}
.v-lift .doors .btn.hot{background:var(--v-accent);width:48%;animation:statecycle 5.2s steps(1) infinite}
.v-lift .doors .line{height:8px;border-radius:3px;background:var(--v-el);display:block;width:90%}
.v-lift .doors .line.short{width:54%;background:var(--v-el-2)}

/* every looping visual holds a readable resting state when motion is unwanted */
@media (prefers-reduced-motion:reduce){
  .stage *{animation:none!important}
  .v-budget .cat .fill{width:var(--w,60%)}
  .v-claims .claim .st::after{opacity:.9}
  .v-claims .total .v{width:84px}
  .v-market .search::after{width:128px}
  .v-market .card{opacity:1}
  .v-market .basket .b.on{opacity:1}
  .v-journey .nodes i{opacity:1} .v-journey .nodes s{transform:scaleX(1)}
  .v-brand .swatches i,.v-brand .spec,.v-brand .spec2,.v-brand .comps i{opacity:1}
  .v-wizard .steps i::after{width:100%}
  .v-fleet .chart i{height:var(--h,50%)}
  .v-lift .shaft .car{transform:translateY(calc(-1 * var(--ride,88px)))}
  .v-fleet .side .ring{transform:rotate(48deg)}
  .intro .avail .dot{animation:none}
}

.foot{display:flex;justify-content:space-between;gap:14px;flex-wrap:wrap;padding:22px 0 40px;
  font-size:12px;color:var(--faint)}

/* ═══════════════════════════════════════════════════════════════════════
   MOTION
   The page should feel alive without ever asking for attention. Three rules
   this whole block obeys:
     1. transform and opacity only - nothing here can cause layout or paint;
     2. UI feedback stays under 300ms, editorial reveals may run longer;
     3. every hiding rule sits behind `html.motion`, a class the head script
        adds ONLY when IntersectionObserver exists - so without JS, or on an
        old engine, the page renders fully visible and nothing is lost.
   ═══════════════════════════════════════════════════════════════════════ */
:root{
  --ease-out-strong:cubic-bezier(.23,1,.32,1);   /* entrances, exits */
  --ease-inout-strong:cubic-bezier(.77,0,.175,1);/* things already on screen */
  --dur-press:150ms; --dur-ui:220ms; --dur-reveal:620ms;
  --rise:14px;
}

/* page to page: the browser cross-fades same-origin navigations where it can
   (cross-document view transitions); elsewhere pages simply load */
@media (prefers-reduced-motion:no-preference){ @view-transition{navigation:auto} }

/* ---------- scroll reveal ----------
   The selector list below is mirrored verbatim in app-v5.js (REVEAL). Keep
   the two in sync: CSS provides a readable fallback, JS enhances it. */
html.motion :where(
  .intro h1, .intro .meta,
  .work > .label, .work > .case,
  .contact h2, .contact .mail, .contact .foot > *,
  .case-hero > .tagrow, .case-hero > h1, .case-hero > .lede,
  .factbar > .f > *,
  .sec-head > .sec-num, .sec-head > .sub,
  .intro-grid > *, .intro-layout > .intro-copy, .intro-layout > .glance,
  .rules > .r, .roles > .r > *, .cards > .card,
  .spine > .step,
  .diagrams > .plate, .diagrams-lead,
  .scr > .scr-head, .scr > .scr-copy,
  .sec > .plate, .sec > .wt
){
  /* Content must stay readable if an observer is paused in a background tab,
     during a screenshot, or on a constrained mobile browser. */
  opacity:1; transform:none;
  transition:opacity var(--dur-reveal) var(--ease-out-strong) var(--rd,0ms),
             transform var(--dur-reveal) var(--ease-out-strong) var(--rd,0ms);
}
html.motion .in{opacity:1;transform:none}

/* siblings that come into view together arrive as a short cascade, not a wall */
html.motion :where(.factbar,.sec-head,.rules,.roles,.cards,.diagrams,
                   .intro-grid,.scr,.foot) > :nth-child(2){--rd:70ms}
html.motion :where(.factbar,.sec-head,.rules,.roles,.cards,.diagrams,
                   .intro-grid,.scr,.foot) > :nth-child(3){--rd:140ms}
html.motion :where(.factbar,.sec-head,.rules,.roles,.cards,.diagrams,
                   .intro-grid,.scr,.foot) > :nth-child(4){--rd:210ms}
html.motion :where(.factbar,.sec-head,.rules,.roles,.cards,.diagrams,
                   .intro-grid,.scr,.foot) > :nth-child(n+5){--rd:260ms}
html.motion .intro .meta{--rd:90ms}
html.motion .case-hero > h1{--rd:60ms}
html.motion .case-hero > .lede{--rd:130ms}
/* the factbar's hairlines are the grid gap showing through, so its cells
   fade without moving - otherwise the rules would appear to slide */
html.motion .factbar > .f{--rise:0px}

/* ---------- press feedback: pressable things give a little ---------- */
.toggle,.lang-opt,.burger,.wt-tab,.wt-btn,.case,.contact .mail{
  -webkit-tap-highlight-color:transparent;
  transition:transform var(--dur-press) var(--ease-out-strong)}
.toggle:active,.lang-opt:active,.burger:active,.wt-btn:active{transform:scale(.94)}
.wt-tab:active{transform:scale(.97)}

/* ---------- hover: the product frame lifts toward the cursor ---------- */
@media (hover:hover) and (pointer:fine){
  .case .frame{transition:transform var(--dur-ui) var(--ease-out-strong),
                          box-shadow var(--dur-ui) var(--ease)}
  .case:hover .frame{transform:translate3d(0,-4px,0);
    box-shadow:0 1px 2px rgba(0,0,0,.05),0 22px 44px -22px rgba(0,0,0,.36)}
  .case:hover h2{color:var(--ink)}
}
.case h2{transition:color var(--dur-ui) var(--ease)}

/* ---------- looping product visuals only run while you can see them ----
   Paused CSS animations hold at 0%, so the first time a visual scrolls into
   view its story plays from the beginning instead of being caught mid-cycle
   - and eight parallel loops stop burning frames off-screen. */
html.motion .frame .stage *{animation-play-state:paused}
html.motion .frame.live .stage *{animation-play-state:running}

/* ---------- reduced motion: fewer and gentler, never zero ---------- */
@media (prefers-reduced-motion:reduce){
  /* the crossfades and colour transitions stay - they explain a change.
     What goes is everything that moves a thing through space. */
  html.motion .in,html.motion :where(
    .intro h1,.intro .meta,.work > .label,.work > .case,
    .contact h2,.contact .mail,.contact .foot > *,
    .case-hero > .tagrow,.case-hero > h1,.case-hero > .lede,
    .factbar > .f > *,.sec-head > .sec-num, .sec-head > .sub,.intro-grid > *, .intro-layout > .intro-copy, .intro-layout > .glance,
    .rules > .r,.roles > .r > *,.cards > .card,.spine > .step,
    .diagrams > .plate,.diagrams-lead,.scr > .scr-head, .scr > .scr-copy,
    .sec > .plate,.sec > .wt
  ){opacity:1;transform:none}
  html.motion .frame .stage *{animation-play-state:running}
}

/* reading position on a long case study - orientation, not decoration */
.nav-progress{position:absolute;left:0;right:0;bottom:0;height:2px;
  background:var(--accent);transform:scaleX(0);transform-origin:0 50%;
  opacity:.85;pointer-events:none}
html.motion .intro-layout > .glance{--rd:120ms}

/* touch targets: at least 24px square (WCAG 2.5.8). The visible control stays the same
   size; the hit area grows through padding-free min-height and a pseudo-element. */
.toggle{min-height:24px}
.lang-opt::after{content:"";position:absolute;inset:-3px 0}

/* keyboard focus: one visible, branded ring for every link and button of the shell */
a:focus-visible,button:focus-visible{outline:2px solid var(--accent);outline-offset:4px}

/* the last card sits directly above the footer, which draws its own top rule */
.work > .case:last-of-type{border-bottom:0}

/* keyboard parity: what hover shows, focus-visible shows too */
.nav-links a:not(.toggle):focus-visible{color:var(--ink)}
.intro .meta a:focus-visible{color:var(--ink);border-color:var(--accent)}
.case:focus-visible .go{border-color:var(--accent)}
.case:focus-visible .go svg{transform:translateX(4px)}
.case:focus-visible h2{color:var(--ink)}

/* ---------- home hero: one full screen, driven by the scroll position ----------
   --p runs 0..1 while the hero scrolls away (home-v5.js). Without the script, or with reduced
   motion, --p stays 0 and the hero is simply a full-screen statement. */
.hero{--p:0;position:relative;min-height:calc(100svh - var(--nav-h,52px));padding-block:0;display:flex;flex-direction:column;justify-content:center;overflow:hidden;isolation:isolate}
.hero-inner{position:relative;z-index:2;padding-block:40px 168px;transform:translate3d(0,calc(var(--p) * -64px),0);opacity:calc(1 - var(--p) * 1.15)}
.hero-kicker{margin:0 0 24px;font-size:12px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.hero .hero-title{max-width:26ch;font-size:clamp(30px,4.6vw,64px);font-weight:700;line-height:1.12;letter-spacing:-.025em}
.hero .meta{margin-top:32px;font-size:14px}
.hero-bands{position:absolute;left:0;right:0;bottom:56px;z-index:1;pointer-events:none;user-select:none}
.band{display:flex;gap:.45em;width:max-content;white-space:nowrap;font-size:clamp(56px,12vw,176px);font-weight:900;letter-spacing:-.04em;line-height:1.02;color:transparent;-webkit-text-stroke:1px color-mix(in srgb,var(--faint) 38%,transparent)}
.band span::after{content:"/";margin-left:.45em;opacity:.7}
.band.b1{transform:translate3d(calc(var(--p) * -26%),0,0)}
.band.b2{transform:translate3d(calc(-22% + var(--p) * 26%),0,0)}
.hero-cue{position:absolute;left:50%;bottom:16px;z-index:3;display:flex;flex-direction:column;align-items:center;gap:6px;
  margin-left:-28px;width:56px;font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);opacity:calc(1 - var(--p) * 4)}
.hero-cue svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;animation:cue 1.8s ease-in-out infinite}
@keyframes cue{0%,100%{transform:translateY(0)}50%{transform:translateY(5px)}}
@media (prefers-reduced-motion:reduce){ .hero-cue svg{animation:none} }
