@font-face{font-family:"Albert Sans";font-style:normal;font-weight:100 900;font-display:swap;
  src:url("../fonts/albert-sans-bMjUEdu.woff2") format("woff2")}

:root{
  --ground:#111217;         /* page and hero background */
  --surface:#1C1E25;        /* cards and footer, one step above the ground */
  --accent:#EF233C;         /* fills, rules, large figures: 4.4:1 on the ground, just short of small-text AA */
  --on-accent:#fff;         /* 4.2:1 on the accent, where --text only reaches 3.3:1 */
  --text:#DFE5EB;
  --bar:10px;               /* the frost bar's margin */
  --page:1180px;            /* content box, shared by the bar and every section */
  --gut:clamp(22px,3.6vw,56px);
  --expo:cubic-bezier(.87,0,.13,1);   /* CSS stand-in for GSAP's expo.inOut */
}
*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;background:var(--ground);color:var(--text);
  font:400 17px/1.55 "Albert Sans","Segoe UI",system-ui,sans-serif;
  -webkit-font-smoothing:antialiased;overflow-x:hidden}
h1,h2,h3{margin:0;font-weight:600;letter-spacing:-.035em;line-height:1.02;text-wrap:balance}
p{margin:0}
a{color:inherit}
:focus-visible{outline:2px solid var(--text);outline-offset:3px;border-radius:4px}
::selection{background:var(--accent);color:var(--on-accent)}

/* ---------- the canvas sits behind the first screen ---------- */
#stage{position:absolute;inset:0;z-index:0;pointer-events:none}
#gl{display:block;width:100%;height:100%}

/* ---------- frosted navbar ---------- */
.bar{position:fixed;top:var(--bar);left:var(--bar);right:var(--bar);z-index:30;
  max-width:calc(var(--page) * 1.2);margin-inline:auto;   /* bar runs 20% wider than the content box */
  border-radius:8px;display:flex;align-items:center;gap:clamp(14px,2.6vw,34px);
  padding-inline:var(--gut);height:64px}
/* the frost lives on its own layer and fades in by opacity — browsers interpolate
   opacity reliably, backdrop-filter they mostly don't */
.bar::before{content:"";position:absolute;inset:0;border-radius:inherit;z-index:-1;
  background:rgba(17,18,23,.62);
  -webkit-backdrop-filter:blur(16px) saturate(160%);
  backdrop-filter:blur(16px) saturate(160%);
  box-shadow:inset 0 0 0 1px rgba(223,229,235,.16),0 6px 22px -14px rgba(0,0,0,.4);
  opacity:0;transition:opacity .5s cubic-bezier(.22,.61,.36,1)}
.bar.frosted::before{opacity:1}
@supports not (backdrop-filter:blur(2px)){
  .bar::before{background:rgba(17,18,23,.94)}
}
.brand{font-weight:600;font-size:18px;letter-spacing:-.05em;text-decoration:none;
  margin-right:auto;white-space:nowrap}
.brand em{font-style:normal;color:var(--accent)}
.bar nav{display:flex;gap:clamp(12px,1.8vw,26px)}
.bar nav a{font-size:14.5px;text-decoration:none;color:var(--text);white-space:nowrap}
.bar nav a:hover{text-decoration:underline}
.bar .cta{font-size:14px;font-weight:600;text-decoration:none;white-space:nowrap;
  padding:9px 18px;border-radius:999px;background:var(--accent);color:var(--on-accent);
  transition:background .18s}
.bar .cta:hover{background:var(--text);color:var(--ground)}
@media(max-width:860px){.bar nav{display:none}}

/* ---------- hero ---------- */
main{position:relative;z-index:10}
/* Dark, warm ground. Bottom to top: the blood flow, the heart, the word over it.
   Its run sits above the beats, and its opaque ground hides the sticky valve until
   the hero fades out, one screen after scene 1. heart.js sets --heart-bottom: the word sits on the heart's lowest point and
   the hook hangs just under it. */
.hero-run{position:relative;z-index:3;height:300svh;margin-bottom:-100svh;
  pointer-events:none}   /* its empty lower half lies over the first beat */
.hero-run .hero{pointer-events:auto}
.hero{position:sticky;top:0;min-height:100svh;overflow:hidden;
  background:var(--ground);display:grid;place-items:center;--heart-bottom:75%;
  will-change:opacity}
.hero #stage{z-index:0}
#heart{position:absolute;inset:0;z-index:1;width:100%;height:100%;display:block;pointer-events:none}
.hero .word{position:absolute;left:0;right:0;top:0;height:var(--heart-bottom);z-index:2;
  display:grid;place-items:end center;padding-inline:var(--gut);
  font:400 16.5vw/1 "Cal Sans",sans-serif;letter-spacing:-.04em;color:var(--text);
  white-space:nowrap;text-transform:uppercase}
/* the grid item: its baseline, not its line box, lands on the line */
.hero .word span{text-box:trim-both cap alphabetic}
.hook{position:absolute;right:calc(50% + 56px);top:calc(var(--heart-bottom) + clamp(18px,2.6vw,34px));z-index:3;
  max-width:30ch;text-align:right;font-size:clamp(1rem,1.3vw,1.2rem);line-height:1.45;
  color:var(--text)}
/* ---------- scene 1: the heart cut open on its failing mitral valve ----------
   It lives in the pinned hero so it shares the heart's canvas. hero-shader.js sets
   --scene (0..1) as the zoom lands; heart.js sets --mx/--my, the valve on screen. */
.scene{position:absolute;inset:0;z-index:3;pointer-events:none;
  width:100%;max-width:var(--page);margin-inline:auto;padding-inline:var(--gut);
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));align-items:center;
  opacity:var(--scene,0)}
/* no card: the text sits straight on a dark veil drawn over the left of the screen */
.scene::before{content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;
  background:linear-gradient(90deg,rgba(17,18,23,.92) 0%,rgba(17,18,23,.78) 28%,
    rgba(17,18,23,.35) 48%,rgba(17,18,23,0) 62%)}
.scene .card{grid-column:1;max-width:30rem;color:var(--text);
  text-shadow:0 1px 18px rgba(17,18,23,.6);
  transform:translateY(calc((1 - var(--scene,0)) * 24px))}
.scene .kicker{color:var(--text);margin-bottom:12px}
.scene h3{font-size:clamp(1.3rem,2.2vw,1.75rem);letter-spacing:-.025em;line-height:1.15}
.scene .card p:not(.kicker){margin-top:14px;font-size:16.5px;line-height:1.6;
  color:var(--text);max-width:34ch}
/* the label stands beside the valve on a short rule, clear of the jet above it */
.tag{position:absolute;left:var(--mx,66.667%);top:var(--my,50%);z-index:3;
  transform:translate(96px,-50%);opacity:var(--scene,0);pointer-events:none;
  padding:6px 10px;border-radius:4px;background:var(--ground);
  font-size:12px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;
  color:var(--text);white-space:nowrap}
.tag::after{content:"";position:absolute;right:100%;top:50%;width:52px;height:1px;background:var(--text)}
@media(max-width:900px){
  .tag{display:none}   /* no room beside the valve */
  .scene{grid-template-columns:1fr;align-items:end;padding-bottom:clamp(24px,6vh,56px)}
  /* one column: the text is at the bottom, so the veil rises from there */
  .scene::before{background:linear-gradient(0deg,rgba(17,18,23,.92) 0%,rgba(17,18,23,.7) 32%,
    rgba(17,18,23,0) 58%)}
}

.kicker{font-size:13.5px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;
  color:var(--text);margin-bottom:22px}
.act{font-size:15px;font-weight:600;text-decoration:none;padding:13px 26px;border-radius:999px;
  background:var(--accent);color:var(--on-accent);transition:background .18s,transform .18s}
.act:hover{background:var(--text);color:var(--ground);transform:translateY(-2px)}
.act--ghost{background:transparent;color:var(--text);box-shadow:inset 0 0 0 1.5px var(--accent)}
.act--ghost:hover{background:var(--accent);color:var(--on-accent)}

/* ---------- the scrollytelling stage ----------
   One sticky layer holds the valve for the whole run. The negative margin takes it
   back out of the flow, so the hero and the beats scroll over it instead of after it. */
.story{position:relative}
.story-stage{position:sticky;top:0;height:100svh;margin-bottom:-100svh;
  z-index:1;pointer-events:none;display:grid;place-items:center}
/* the exploded implant: valve.js slides it over the column opposite the cards and pins
   each label at its part's edge, the leader (--lead px) running out to a shared column */
.explode{position:relative;width:min(46vw,600px);height:100svh;will-change:transform}
.explode canvas{display:block;width:100%;height:100%}
.note{position:absolute;left:0;top:0;display:flex;align-items:center;gap:10px;margin:0;
  font-size:13px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;white-space:nowrap;
  color:var(--text);opacity:0;transition:color .3s}
.note i{display:block;width:var(--lead,40px);height:1px;background:currentColor;position:relative}
.note i::before{content:"";position:absolute;left:-3px;top:-3px;width:7px;height:7px;border-radius:50%;
  background:currentColor}
.note b{color:var(--accent);font-weight:700}
.note.on{color:var(--accent)}
@media(max-width:900px){.story-stage{display:none}}   /* one column: the text wins */

/* ---------- beats: the scroll interruptions ---------- */
.beat{position:relative;z-index:2;
  max-width:var(--page);margin-inline:auto;padding-inline:var(--gut);
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(24px,4vw,64px);align-items:start}
.beat-col{grid-column:1;display:grid}
.beat--right .beat-col{grid-column:2}

/* Each text gets its own slot of scroll distance, and is the only sticky child of it —
   so its hold is the full slot minus its own height, not a range shared with siblings.
   Pinned at 50svh then pulled back by half its height, it lands exactly on the viewport
   centre, where the valve also sits, whatever the text's length. */
.slot{height:110svh}
.say{position:sticky;top:50svh;transform:translateY(-50%);
  opacity:0;will-change:opacity,transform}
.say .kicker{margin-bottom:12px}
.say h3{font-size:clamp(1.3rem,2.2vw,1.75rem);letter-spacing:-.025em;line-height:1.15}
.say p{margin-top:14px;font-size:16.5px;line-height:1.6;color:var(--text);max-width:42ch}

@media(max-width:900px){
  .beat{grid-template-columns:1fr}
  .beat-col,.beat--right .beat-col{grid-column:1}
  .slot{height:auto}
  .say{position:static;transform:none;opacity:1;margin-block:clamp(20px,4vw,40px)}
}

/* ---------- scroll cue ---------- */
.cue{position:absolute;left:50%;bottom:clamp(24px,4.5vh,48px);transform:translateX(-50%);z-index:3;
  display:flex;flex-direction:column;align-items:center;gap:9px;
  font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--text);
  text-decoration:none;transition:opacity .3s}
.cue .rail{width:1px;height:38px;background:rgba(223,229,235,.18);overflow:hidden;position:relative}
.cue .rail i{position:absolute;inset:0;background:var(--accent);
  animation:fall 1.9s cubic-bezier(.65,0,.35,1) infinite}
@keyframes fall{0%{transform:translateY(-100%)}60%,100%{transform:translateY(100%)}}
.cue.gone{opacity:0;pointer-events:none}
.cue .rail{height:clamp(30px,4.5vh,44px)}

/* ---------- the page that covers the canvas ---------- */
.sheet{background:var(--ground);position:relative;z-index:10}
.sheet{padding-inline:var(--bar)}
.sheet section{padding-block:clamp(64px,7vw,120px);padding-inline:var(--gut);
  max-width:var(--page);margin-inline:auto}
.sheet :is(h2,.h2){font-size:clamp(1.9rem,3.4vw,3rem);max-width:18ch}
.cols{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(22px,3vw,52px);
  margin-top:clamp(26px,3vw,44px)}
@media(max-width:760px){.cols{grid-template-columns:1fr}}
.cols p{color:var(--text);font-size:16.5px;line-height:1.6}
.slab{background:var(--surface);border-radius:8px;padding:clamp(24px,3vw,44px);
  margin-top:clamp(26px,3vw,44px)}
.slab p{color:var(--text);max-width:70ch}
.lorem-note{margin-top:14px;font-size:13.5px;color:var(--text);font-weight:600}
.sheet section + section{border-top:1px solid rgba(223,229,235,.16)}
.sheet .kicker{margin-bottom:16px}
.lede{margin-top:clamp(18px,2.2vw,28px);font-size:clamp(1.0625rem,1.25vw,1.25rem);
  line-height:1.5;color:var(--text);max-width:52ch}

/* the headline figure — one number, nothing competing with it */
.stat{display:flex;align-items:baseline;gap:clamp(16px,2.4vw,30px);flex-wrap:wrap;
  margin-top:clamp(26px,3vw,44px)}
.stat b{font-size:clamp(3.4rem,9vw,6.5rem);font-weight:600;letter-spacing:-.05em;
  line-height:.86;color:var(--accent)}
.stat span{font-size:16.5px;line-height:1.5;color:var(--text);max-width:32ch}

/* the ribbon, told in three states */
.steps{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(16px,2.2vw,30px);margin-top:clamp(28px,3.4vw,48px);counter-reset:s}
@media(max-width:760px){.steps{grid-template-columns:1fr}}
.step{background:var(--surface);border-radius:8px;padding:clamp(20px,2.4vw,30px)}
.step svg{display:block;width:100%;height:76px;margin-bottom:18px;color:var(--accent)}
.step h3{font-size:1.0625rem;letter-spacing:-.02em;line-height:1.25}
.step h3::before{counter-increment:s;content:counter(s) " — ";color:var(--text)}
.step p{margin-top:9px;font-size:15.5px;line-height:1.55;color:var(--text)}

/* where we are — reached steps filled, the rest hollow and unmistakably not done */
.track{list-style:none;margin:clamp(28px,3.4vw,46px) 0 0;padding:0}
.track li{display:grid;grid-template-columns:14px 1fr;gap:18px;padding:17px 0}
.track li + li{border-top:1px solid rgba(223,229,235,.16)}
.track .pin{width:13px;height:13px;border-radius:50%;margin-top:6px;
  background:var(--accent);box-shadow:0 0 0 4px rgba(239,35,60,.22)}
.track .todo .pin{background:transparent;box-shadow:inset 0 0 0 1.5px rgba(223,229,235,.28)}
.track .tag{font-size:12px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;
  color:var(--text)}
.track .todo .tag{color:var(--text)}
.track b{display:block;margin-top:3px;font-weight:600;letter-spacing:-.015em;font-size:17px}
.track .todo b{color:var(--text)}
.track p{margin-top:6px;font-size:15.5px;line-height:1.55;color:var(--text);max-width:62ch}
.notice{margin-top:clamp(26px,3vw,40px);border-radius:8px;padding:clamp(20px,2.4vw,30px);
  background:var(--surface);box-shadow:inset 3px 0 0 var(--accent)}
.notice p{color:var(--text);max-width:68ch;font-size:16px}

/* team */
.team{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);
  gap:clamp(24px,3.4vw,56px);align-items:center;margin-top:clamp(26px,3vw,44px)}
@media(max-width:760px){.team{grid-template-columns:1fr}}
.team figure{margin:0;border-radius:8px;overflow:hidden;background:var(--surface)}
/* width/height are on the <img> too, so the box is reserved before the file lands */
.team img{display:block;width:100%;height:auto;aspect-ratio:3/2;object-fit:cover}
.team p{color:var(--text);font-size:16.5px;line-height:1.6;max-width:40ch}
.team .act{display:inline-block;margin-top:clamp(18px,2.2vw,28px)}

.crew{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));
  gap:clamp(16px,2.2vw,28px);margin-top:clamp(28px,3.4vw,46px)}
.crew > div{background:var(--surface);border-radius:8px;padding:clamp(18px,2vw,24px)}
.crew b{display:block;font-weight:600;letter-spacing:-.015em}
.crew span{display:block;margin-top:5px;font-size:14.5px;color:var(--text)}

/* the only centred section on the page: a two-word title has nothing to align to */
#partenaires{text-align:center}
#partenaires h2{max-width:none;margin-inline:auto}
#partenaires .partners{justify-content:center}

/* partners — logos vary wildly in aspect, so height is the only shared measure */
.partners{list-style:none;margin:clamp(28px,3.4vw,46px) 0 0;padding:0;
  display:flex;flex-wrap:wrap;align-items:center;gap:clamp(26px,4vw,64px)}
/* three of the five logos ship on an opaque white plate; inverted it turns black and screen drops it into
   the ground instead of leaving pale rectangles on the page */
.partners img{display:block;height:clamp(40px,4.4vw,58px);width:auto;
  filter:grayscale(1) invert(1) brightness(.9);mix-blend-mode:screen}

/* news lead — thumbnail on the right, mirroring .team which puts it on the left */
.lead{display:grid;grid-template-columns:minmax(0,6fr) minmax(0,5fr);
  gap:clamp(24px,3.4vw,56px);align-items:center;
  margin-top:clamp(28px,3.4vw,46px);padding-bottom:clamp(28px,3.4vw,46px);
  border-bottom:1px solid rgba(223,229,235,.16)}
@media(max-width:760px){.lead{grid-template-columns:1fr}}
.lead time{display:block;font-size:13.5px;font-weight:600;letter-spacing:.07em;
  text-transform:uppercase;color:var(--text);font-variant-numeric:tabular-nums}
.lead h3{margin-top:12px;font-size:clamp(1.35rem,2.4vw,1.95rem);
  letter-spacing:-.025em;line-height:1.14;max-width:20ch}
.lead p{margin-top:14px;font-size:16.5px;line-height:1.6;color:var(--text);max-width:46ch}
.lead .more{margin-top:20px}
/* hatched so an empty slot reads as "image pending", not as a broken box */
.thumb{aspect-ratio:3/2;border-radius:8px;background:var(--surface);
  background-image:repeating-linear-gradient(45deg,
    rgba(223,229,235,.05) 0 10px,transparent 10px 20px)}

/* "see more" — the same affordance on the lead and on every feed entry */
.more{display:inline-flex;align-items:center;gap:.4em;
  font-size:14px;font-weight:600;color:var(--text);text-decoration:none;
  white-space:nowrap}
.more span{transition:transform .18s}
.more:hover{text-decoration:underline;text-underline-offset:3px}
.more:hover span{transform:translateX(3px)}
.feed .more{margin-top:12px}

/* news — newest first, dates doing the talking */
.feed{list-style:none;margin:clamp(28px,3.4vw,46px) 0 0;padding:0}
/* the three previews share the lead's grid, so their text block is exactly the
   width of the lead's — same left edge, same measure, one rail down the section */
.feed li{display:grid;grid-template-columns:minmax(0,6fr) minmax(0,5fr);
  gap:10px clamp(24px,3.4vw,56px);   /* row gap tight: the date sits on the title */
  padding:clamp(20px,2.4vw,30px) 0}
.feed li > *{grid-column:1}
.feed li + li{border-top:1px solid rgba(223,229,235,.16)}
@media(max-width:760px){.feed li{grid-template-columns:1fr}}
.feed time{display:block;font-size:13.5px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;
  color:var(--text);font-variant-numeric:tabular-nums}
.feed b{font-weight:600;letter-spacing:-.015em;font-size:17.5px}
.feed p{margin-top:6px;font-size:15.5px;line-height:1.55;color:var(--text);max-width:46ch}

/* FAQ — native <details>, no script */
.qa{margin-top:clamp(28px,3.4vw,46px);border-top:1px solid rgba(223,229,235,.16)}
.qa details{border-bottom:1px solid rgba(223,229,235,.16)}
.qa summary{cursor:pointer;list-style:none;padding:19px 44px 19px 0;position:relative;
  font-weight:600;font-size:17.5px;letter-spacing:-.015em}
.qa summary::-webkit-details-marker{display:none}
.qa summary::after{content:"";position:absolute;right:8px;top:50%;width:11px;height:11px;
  margin-top:-7px;border-right:1.5px solid var(--accent);border-bottom:1.5px solid var(--accent);
  transform:rotate(45deg);transition:transform .2s}
.qa details[open] summary::after{transform:rotate(-135deg);margin-top:-2px}
.qa p{padding:0 0 20px;font-size:16px;line-height:1.6;color:var(--text);max-width:66ch}

/* ---------- footer: the page's only point of contact ----------
   Full bleed: it is the one band that runs edge to edge, so the form and the
   three link columns sit side by side instead of stacking down the page. */
.foot{background:var(--surface);color:var(--text);padding-inline:var(--bar)}
.foot .in{padding:clamp(52px,5.5vw,88px) var(--gut)}
.foot code{font:inherit;font-size:.95em;font-family:ui-monospace,Consolas,monospace}

.foot-top{display:grid;
  grid-template-columns:minmax(360px,1.3fr) repeat(3,minmax(150px,.6fr));
  gap:clamp(30px,3.6vw,72px)}
@media(max-width:1080px){
  .foot-top{grid-template-columns:repeat(3,minmax(0,1fr))}
  .foot-form{grid-column:1/-1}
}
@media(max-width:640px){.foot-top{grid-template-columns:1fr}}

/* compact: one column so every field is the textarea's width, 3-row textarea */
.form{display:grid;grid-template-columns:minmax(0,1fr);
  gap:12px;margin-top:clamp(20px,2.2vw,28px)}
.form label{display:flex;flex-direction:column;gap:6px;font-size:12px;font-weight:600;
  letter-spacing:.08em;text-transform:uppercase;color:var(--text)}
.form .wide{grid-column:1/-1}
.form input,.form select,.form textarea{font:inherit;font-size:15px;color:var(--text);
  background:rgba(223,229,235,.07);border:0;box-shadow:inset 0 0 0 1px rgba(223,229,235,.2);
  border-radius:6px;padding:10px 12px;width:100%}
.form textarea{resize:vertical;min-height:76px}
.form select{appearance:none;cursor:pointer}
.form option{color:var(--ground)}
.form :focus-visible{outline:2px solid var(--text);outline-offset:2px}
.form button{grid-column:1/-1;justify-self:start;font:inherit;font-size:14.5px;font-weight:600;
  border:0;cursor:pointer;padding:11px 24px;border-radius:999px;
  background:var(--accent);color:var(--on-accent);transition:background .18s}
.form button:hover{background:var(--text);color:var(--ground)}

.foot-col h3{font-size:13px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;
  color:var(--text)}
.foot-col ul{list-style:none;margin:16px 0 0;padding:0;display:grid;gap:10px}
.foot-col a{font-size:15px;color:var(--text);text-decoration:none;opacity:.82}
.foot-col a:hover{opacity:1;text-decoration:underline;text-underline-offset:3px}
.foot-col .lorem-note{margin-top:14px;font-size:12.5px}

.foot-end{display:flex;flex-wrap:wrap;gap:14px 28px;align-items:center;
  margin-top:clamp(40px,5vw,72px);padding-top:24px;
  border-top:1px solid rgba(223,229,235,.16);font-size:14px;color:var(--text)}
.foot-end span{margin-right:auto}
.foot-end a{text-decoration:none}
.foot-end a:hover{text-decoration:underline}


/* ---------- page transition: slide-over ----------
   The effect from codrops/interlude's slide-over.ts, rebuilt on the View
   Transitions API. Interlude is an Astro + GSAP starter; here the browser owns
   the snapshots and the timing, so none of that is needed.
   Forward: the incoming page rides up over the outgoing one, which steps back
   to .9 and dims. Back: the reverse, driven by a view-transition type. */
@view-transition{navigation:auto}

::view-transition-group(root){animation-duration:1.1s}

/* The UA default for these two is mix-blend-mode:plus-lighter, meant for
   cross-fades. Here the snapshots overlap fully, and two dark pages added
   together go white — a slide-over needs one opaque page over another. */
::view-transition-old(root),
::view-transition-new(root){mix-blend-mode:normal;backface-visibility:hidden}

::view-transition-old(root){z-index:0;animation:1.1s var(--expo) both so-back}
::view-transition-new(root){z-index:1;animation:1.1s var(--expo) both so-up}

/* The bar gets its own name, so it is captured as a separate group instead of
   being part of the page snapshot — it holds still while the pages slide under
   it. Both documents carry the same bar, so the group has nothing to animate. */
.bar{view-transition-name:navbar}
::view-transition-group(navbar){z-index:20}
::view-transition-old(navbar),
::view-transition-new(navbar){animation:none;mix-blend-mode:normal}

@keyframes so-up{from{transform:translateY(100%)}to{transform:none}}
@keyframes so-back{
  from{transform:scale(1);filter:brightness(1)}
  /* brightness .4 is the 60%-black veil they overlay, one layer cheaper */
  to{transform:scale(.9);filter:brightness(.4)}}

/* going back: the top page slides away downwards and the one beneath returns */
:root:active-view-transition-type(back)::view-transition-old(root){
  z-index:1;animation-name:so-down}
:root:active-view-transition-type(back)::view-transition-new(root){
  z-index:0;animation-name:so-forward}

@keyframes so-down{from{transform:none}to{transform:translateY(100%)}}
@keyframes so-forward{
  from{transform:scale(.9);filter:brightness(.4)}
  to{transform:scale(1);filter:brightness(1)}}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *{animation:none!important;transition:none!important}
  /* `*` does not match the view-transition pseudo-elements */
  ::view-transition-group(*),::view-transition-old(*),
  ::view-transition-new(*){animation:none!important}
}


/* ================= additions that test_openstent does not have ================= */
/* sub-pages have no hero: the fixed bar needs room */
.page-top{padding-top:calc(64px + var(--bar))}

/* the page's own ground carries on over the footer seam */
.sheet h1.h2 + p{margin-top:clamp(18px,2vw,26px)}
.lorem-note{margin-top:14px;font-size:13.5px;color:var(--text);opacity:.7}

/* ---------- contact / admin forms (the .form block above is the dark theme's) ---------- */
.form{max-width:560px;gap:14px;margin-top:clamp(22px,2.6vw,34px)}
.form-error{margin:18px 0 0;color:#ff8a94;font-weight:600}
.form .help-text,.form small{font-weight:400;letter-spacing:0;text-transform:none;font-size:13px;opacity:.7}
.form ul{margin:0;padding-left:18px;color:#ff8a94;font-size:13px;list-style:disc}
.form input[type=file]{padding:8px 12px}

/* ---------- team ---------- */
.crew{grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(20px,2.6vw,36px);align-items:stretch}
@media(max-width:620px){.crew{grid-template-columns:1fr}}
.member{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,6fr);align-items:center;
  background:var(--surface);border-radius:8px;overflow:hidden}
.member > img{display:block;width:100%;height:100%;aspect-ratio:4/5;object-fit:cover;object-position:top}
.member-text{padding:clamp(22px,2.8vw,40px) clamp(20px,2.4vw,36px)}
.sheet .member h2{font-size:1.25rem;letter-spacing:-.015em;line-height:1.25;max-width:none;color:var(--accent)}
.role{margin-top:8px;font-size:14.5px;line-height:1.45;opacity:.72}
.member .more{margin-top:clamp(16px,2vw,24px);border:0;background:none;padding:0;font:inherit;cursor:pointer}
.member-nophoto{display:block;min-height:160px;background:var(--ground)}

/* the biography opens in a native modal <dialog> */
.modal{width:min(980px,calc(100vw - 48px));max-height:calc(100vh - 56px);padding:0;border:0;
  border-radius:12px;background:var(--surface);color:var(--text);overflow:auto}
.modal::backdrop{background:rgba(0,0,0,.7)}
.modal[open]{display:grid;grid-template-columns:minmax(0,4fr) minmax(0,7fr)}
.modal img{display:block;width:100%;height:100%;object-fit:cover;object-position:top}
.modal-body{padding:clamp(32px,4.8vw,68px) clamp(28px,4.4vw,64px)}
.modal-body h3{font-size:clamp(1.6rem,2.4vw,2.1rem);letter-spacing:-.025em;line-height:1.1;color:var(--accent)}
.modal-body .role{margin-top:12px;font-size:15px}
.modal-body p:not(.role){margin-top:clamp(16px,1.8vw,22px);font-size:16.5px;line-height:1.75;max-width:60ch}
.modal-body p:not(.role) + p:not(.role){margin-top:1.3em}
.modal-close{position:absolute;top:16px;right:18px;width:36px;height:36px;border:0;border-radius:50%;
  background:var(--ground);color:var(--text);font-size:24px;line-height:1;cursor:pointer}
@media(max-width:620px){.modal[open]{grid-template-columns:1fr}.modal img{max-height:260px}}

/* ---------- admin ---------- */
.admin-nav{display:flex;gap:20px;align-items:center;margin-bottom:clamp(24px,3vw,40px);
  padding-bottom:14px;border-bottom:1px solid rgba(223,229,235,.16);font-weight:600;font-size:15px}
.admin-nav a{text-decoration:none}
.admin-nav a:hover{text-decoration:underline;text-underline-offset:3px}
.admin-logout{margin-left:auto;opacity:.7}
.flash{margin:0 0 20px;padding:10px 14px;border-radius:6px;background:var(--surface)}
.admin-table{width:100%;margin-top:28px;border-collapse:collapse;font-size:15px}
.admin-table th{text-align:left;font-size:12px;letter-spacing:.08em;text-transform:uppercase;opacity:.7}
.admin-table th,.admin-table td{padding:10px 12px 10px 0;border-bottom:1px solid rgba(223,229,235,.12);vertical-align:middle}
.admin-table td:last-child{width:1%;white-space:nowrap}
.admin-actions{display:flex;gap:16px;align-items:center;justify-content:flex-end}
.admin-actions form{margin:0}
.admin-actions button{border:0;background:none;padding:0;font:inherit;color:#ff8a94;cursor:pointer;text-decoration:underline}
.admin-thumb{display:block;object-fit:cover;border-radius:4px}
.faq-title{margin-top:clamp(44px,5vw,72px)}

/* ---------- footer: a LinkedIn band easing into three columns ---------- */
.foot{position:relative;z-index:11;margin-top:-2px;background:none;padding-inline:0;color:var(--text)}
.foot-main{background:linear-gradient(180deg,var(--ground),var(--surface) 140px);padding:clamp(110px,9vw,140px) var(--gut) clamp(18px,2vw,28px)}
.foot-linkedin-row{display:flex;align-items:center;gap:12px;margin-top:18px}
.foot-cols .foot-linkedin{opacity:1}
.foot-cols .foot-linkedin-icon{display:inline-grid;place-items:center;width:26px;height:26px;border-radius:3px;background:var(--text);color:var(--ground)}
.foot-cols .foot-linkedin-icon svg{width:18px;height:18px;fill:currentColor}
.foot-cols{display:grid;grid-template-columns:repeat(3,auto);justify-content:center;
  gap:0 clamp(24px,4vw,56px)}
.foot-cols > div{padding-inline:clamp(0px,2vw,28px)}
.foot-cols > div + div{border-left:1px solid rgba(223,229,235,.2)}
.foot-cols h3{font-size:1.25rem;font-weight:600;letter-spacing:-.01em}
.foot-cols h3 span{font-weight:300}
.foot-cols .brand-line{font-size:1.4rem;font-weight:600;letter-spacing:-.04em;margin-bottom:12px}
.foot-cols .brand-line em{font-style:normal;color:var(--accent)}
.foot-cols p,.foot-cols li{font-size:15px;line-height:1.5;opacity:.78}
.foot-cols ul{list-style:none;margin:14px 0 0;padding:0}
.foot-cols a{color:inherit;text-decoration:none}
.foot-cols a:hover{text-decoration:underline;text-underline-offset:3px}
.foot-cols address{font-style:normal;margin-top:14px;font-size:15px;line-height:1.5;opacity:.78}
.foot-cols address b{font-weight:500}
.foot-legal{display:flex;flex-wrap:wrap;justify-content:space-between;max-width:70%;margin-inline:auto;
  gap:6px clamp(20px,3vw,40px);margin-top:clamp(18px,2vw,28px);font-size:15px}
.foot-legal a{opacity:.78;text-decoration:none}
.foot-legal a:hover{text-decoration:underline;text-underline-offset:3px}
@media(max-width:760px){
  .foot-cols{grid-template-columns:1fr;gap:28px}
  .foot-cols > div + div{border-left:0;border-top:1px solid rgba(223,229,235,.2);padding-top:24px}
}

/* ---------- checklist ---------- */
.progress{height:8px;margin-top:clamp(18px,2vw,26px);border-radius:999px;background:var(--surface);overflow:hidden}
.progress span{display:block;width:var(--w,0%);height:100%;border-radius:inherit;background:var(--accent)}
.checklist{list-style:none;margin:clamp(10px,2vh,22px) 0 0;padding:0}
.checklist li{display:grid;grid-template-columns:1fr 34px;gap:14px;padding:clamp(5px,1vh,10px) 0;border-top:1px solid rgba(223,229,235,.12)}
.checklist b{font-weight:600;letter-spacing:-.015em;font-size:16.5px}
.checklist p{margin-top:2px;font-size:clamp(13px,1.75vh,14.5px);line-height:1.4;opacity:.78;max-width:62ch}
.checklist .todo b{opacity:1}   /* upcoming steps are white like the others */

/* ---------- team page: the intro as a mini hero ---------- */
.more-row{margin-top:clamp(18px,2vw,26px)}

/* ---------- vertical nav of the solution ---------- */
.vnav{position:fixed;right:clamp(14px,2vw,28px);top:50%;transform:translateY(-50%);z-index:20;
  display:flex;flex-direction:column;gap:6px;opacity:0;pointer-events:none;transition:opacity .3s}
.vnav.on{opacity:1;pointer-events:auto}
.vnav button{position:relative;display:block;width:22px;height:22px;padding:0;border:0;background:none;cursor:pointer}
.vnav button::before{content:"";position:absolute;left:50%;top:50%;width:8px;height:8px;margin:-4px 0 0 -4px;
  border-radius:50%;background:rgba(223,229,235,.35);transition:background .2s,transform .2s}
.vnav button:hover::before{background:var(--text)}
.vnav button.active::before{background:var(--accent);transform:scale(1.5)}
.vnav button span{position:absolute;right:30px;top:50%;transform:translateY(-50%);white-space:nowrap;
  font-size:12px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--text);
  opacity:0;pointer-events:none;transition:opacity .2s}
.vnav button:hover span,.vnav button:focus-visible span,.vnav button.active span{opacity:1}
@media(max-width:900px){.vnav{display:none}}


/* ---------- checklist: fits in one screen, then plays step by step ---------- */
/* the first line clears the fixed bar, because the auto-scroll stops on the top of this section */
#checklist{padding-top:calc(64px + var(--bar) + clamp(10px,2vh,24px));padding-bottom:clamp(12px,2.5vh,32px)}
#checklist .lede{margin-top:clamp(8px,1.4vh,16px)}
#checklist .progress{margin-top:clamp(12px,2vh,20px)}


/* checklist.js adds .anim, then .shown on each step in turn, then .checked on the validated
   ones in turn (the bar follows), then .pulse on the current one. Without the script the
   final state shows as is. */
#checklist.anim .progress span{width:var(--w,0%);transition:width .5s cubic-bezier(.22,.61,.36,1)}
#checklist.anim .checklist li{opacity:0;transform:translateY(12px);
  transition:opacity .4s ease,transform .4s cubic-bezier(.22,.61,.36,1)}
#checklist.anim .checklist li.shown{opacity:1;transform:none}

/* ---------- checklist toggles (display only: nothing to click) ---------- */
.checklist .mark{position:relative;width:34px;height:20px;margin-top:2px;border-radius:999px;
  background:rgba(223,229,235,.16);transition:background .3s;pointer-events:none}
.checklist .mark::after{content:"";position:absolute;left:3px;top:3px;width:14px;height:14px;border-radius:50%;
  background:var(--text);transition:transform .35s cubic-bezier(.34,1.56,.64,1)}
.checklist .done .mark{background:var(--accent)}
.checklist .done .mark::after{transform:translateX(14px);background:#fff}
/* the current step: a switch still off, glowing */
.checklist .current .mark{box-shadow:0 0 0 3px rgba(239,35,60,.25)}
/* while the script plays, a validated step starts off and flips when it is ticked */
#checklist.anim .done .mark{background:rgba(223,229,235,.16)}
#checklist.anim .done .mark::after{transform:none;background:var(--text)}
#checklist.anim .done.checked .mark{background:var(--accent)}
#checklist.anim .done.checked .mark::after{transform:translateX(14px);background:#fff}
#checklist.anim .current .mark{box-shadow:none}
#checklist.anim .current.pulse .mark{animation:toggle-glow 2.2s ease-in-out infinite}
@keyframes toggle-glow{
  0%,100%{box-shadow:0 0 0 3px rgba(239,35,60,.25)}
  50%{box-shadow:0 0 0 8px rgba(239,35,60,0)}}

/* the checklist runs straight into the contact section: no rule between them */
#contact-teaser{border-top:0}

/* the toggle sits on the right of its step */
.checklist li > div{grid-column:1;grid-row:1}
.checklist li > .mark{grid-column:2;grid-row:1;align-self:start}

/* ---------- page hero (team): a small banner under the bar ---------- */
.page-hero{position:relative;display:grid;align-items:end;overflow:hidden;
  min-height:clamp(420px,68svh,640px);padding-top:calc(64px + var(--bar));background:var(--ground)}
.page-hero img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center 62%;
  filter:grayscale(1) brightness(.65)}
.page-hero::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(90deg,rgba(0,0,0,.82) 0%,rgba(0,0,0,.45) 55%,rgba(0,0,0,0) 100%),
             linear-gradient(0deg,var(--ground) 0%,rgba(0,0,0,0) 38%)}
.page-hero-in{position:relative;z-index:1;width:100%;max-width:var(--page);margin-inline:auto;
  padding:clamp(28px,5vw,56px) var(--gut) clamp(28px,4vw,56px)}
.page-hero h1{font-size:clamp(2.6rem,7vw,5.5rem);letter-spacing:-.045em;line-height:.95}
.page-hero h1 strong{font-weight:700}
.page-hero .lede{margin-top:clamp(14px,2vw,22px);max-width:46ch}

/* news: red titles, and the link to the archives sits on the right in red */
.feed b{color:var(--accent)}
.more-row{text-align:right}
.more-row .more{color:var(--accent)}

/* ---------- checklist + team callout on its right ---------- */
#checklist{display:grid;grid-template-columns:minmax(0,1fr) minmax(340px,440px);
  gap:clamp(28px,5vw,72px);align-items:start}
.encart{position:sticky;top:calc(64px + var(--bar) + 24px)}
.checklist-main{padding:clamp(22px,2.4vw,32px);border-radius:12px;background:var(--surface)}
.checklist-main .progress{background:rgba(223,229,235,.12)}
.encart h3{margin-top:4px;font-size:clamp(1.7rem,2.8vw,2.6rem);letter-spacing:-.03em;line-height:1.08}
.encart p:not(.kicker){margin-top:20px;font-size:16.5px;line-height:1.65;opacity:.85;max-width:52ch}
.encart .kicker{margin-bottom:10px}
.encart-photo{display:block;width:100%;height:auto;aspect-ratio:3/2;margin-top:22px;border-radius:12px;object-fit:cover;filter:grayscale(1)}
.encart .act{display:inline-block;margin-top:20px}
/* the team callout is on the left, the checklist on the right */
#checklist .encart{grid-column:1;grid-row:1}
#checklist .checklist-main{grid-column:2;grid-row:1}
@media(max-width:900px){#checklist{grid-template-columns:1fr}.encart{position:static}#checklist .encart,#checklist .checklist-main{grid-column:auto;grid-row:auto}}

/* the callout fades in when the checklist plays */
#checklist.anim .encart{opacity:0;transform:translateY(14px);transition:opacity .6s ease .3s,transform .6s ease .3s}
#checklist.anim.in .encart{opacity:1;transform:none}

/* the checklist card is narrow: tighter title and rows so the section still fits one screen */
#checklist{grid-template-columns:minmax(0,1fr) minmax(360px,480px)}
.checklist-main h2{font-size:clamp(1.6rem,2.3vw,2.1rem)}
.checklist-main .checklist li{padding:clamp(4px,.8vh,8px) 0}

/* the checklist block runs wider than the usual column so the team photo can grow */
#checklist{max-width:min(1500px,100%);padding-inline:var(--gut)}
#checklist .encart-photo{aspect-ratio:16/10}

/* both sides share the same height: the team photo takes whatever the checklist card leaves */
#checklist{align-items:stretch}
#checklist .encart{position:static;display:flex;flex-direction:column}
#checklist .encart-photo{flex:1 1 0;min-height:240px;height:0;aspect-ratio:auto}
@media(max-width:900px){#checklist .encart-photo{flex:none;height:auto;aspect-ratio:16/10}}
#checklist .encart .act{align-self:flex-start}

/* the team photo keeps its own proportions (no crop); the checklist card grows to match the
   height of the team column and spreads its steps over it */
#checklist{grid-template-columns:minmax(0,1fr) minmax(420px,540px)}
#checklist .encart-photo{flex:none;height:auto;min-height:0;aspect-ratio:3840/2554}
#checklist .checklist-main{display:flex;flex-direction:column}
#checklist .checklist{flex:1;display:flex;flex-direction:column;margin-top:clamp(14px,2vh,24px)}
#checklist .checklist li{flex:1 1 auto;align-content:center}
.checklist-main .checklist b{font-size:17px}
.checklist-main .checklist p{font-size:15px}
@media(max-width:900px){#checklist .encart-photo{aspect-ratio:3840/2554}}
