/* Det ene canvas ligger fast bag alt. Sektionerne maler oven på det, og
   headeren blender mod summen af begge dele. */
.stage {
  position: fixed;
  inset: 0;
  z-index: 0;
  display: block;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity 600ms var(--ease);
}
.stage[data-ready="true"] {
  opacity: 1;
}

/* ---------- 1 · hero ---------- */

/* Heroen har ingen egen baggrund: den lader canvasset stå frit igennem.
   Det er derfor sidens bund er --ink. */
.hero {
  position: relative;
  z-index: 2;
  min-height: 100svh;
  padding: calc(var(--hdr-h) + 0.5rem) var(--gut) clamp(2rem, 5vh, 3.5rem);
  display: grid;
  grid-template-rows: auto 1fr auto;
}

/* Overskriften klistres til toppen som hos tinywins, ikke centreres. */
.chiasmus {
  margin: 0;
  font-size: clamp(1.9rem, 5.1vw, 5.1rem);
  letter-spacing: -0.045em;
  line-height: 0.94;
  text-transform: uppercase;
  color: var(--on-dark);
}
.chiasmus__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  width: 100%;
  flex-wrap: nowrap;
}
.chiasmus__block {
  display: flex;
  flex-wrap: wrap;
  gap: 0 0.26em;
  min-width: 0;
}
.chiasmus__block[data-block="b"] {
  justify-content: flex-end;
  text-align: right;
}
/* Hvert ord ruller lodret i sit eget vindue. */
.word {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
}
.word > span {
  display: block;
  will-change: transform;
}

.hero__lead {
  align-self: start;
  margin-top: clamp(1.6rem, 4vh, 3rem);
  color: var(--on-dark);
}

.hero__meta {
  align-self: end;
  display: flex;
  justify-content: flex-end;
}
.hero__stamp {
  display: none;
}
.hero__desc {
  max-width: 34ch;
  color: var(--on-dark);
  text-align: right;
  margin: 0;
}

@media (min-width: 900px) {
  .hero__meta {
    display: grid;
    justify-content: end;
    justify-items: end;
    gap: 1.1rem;
  }
  .hero__stamp {
    display: grid;
    grid-auto-flow: column;
    border: 1px solid var(--hair-dark);
    border-radius: var(--r-sm);
  }
  .hero__stamp .label {
    padding: 0.9rem 1.2rem;
    color: var(--on-dark);
  }
  .hero__stamp .label + .label {
    border-left: 1px solid var(--hair-dark);
  }
}

.hero__hint {
  position: absolute;
  left: 50%;
  bottom: clamp(1.6rem, 4vh, 2.6rem);
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 0.9rem;
  background: none;
  border: 0;
  padding: 0.4rem;
  cursor: pointer;
  color: var(--on-dark);
  transition:
    color 220ms var(--ease),
    opacity 620ms var(--ease);
  white-space: nowrap;
}

/* Når sætningen i Om os begynder at tænde, er heroen ikke længere det man
   kigger på. Hintet fader blødt væk og tager sine pointer-events med sig, så
   opladningen ikke kan udløses bagfra. */
html[data-hero-locked] .hero__hint {
  opacity: 0;
  pointer-events: none;
}
.hero__hint:hover {
  color: var(--on-dark);
}

@media (max-width: 640px) {
  .chiasmus__row {
    flex-wrap: wrap;
  }
  .hero__desc {
    text-align: left;
  }
  .hero__meta {
    justify-content: flex-start;
  }
  .hero__hint {
    display: none;
  }
}

/* ---------- delt ---------- */

/* Én reveal for hele siden. */
[data-reveal] {
  opacity: 0;
  transform: translateY(22px);
  transition:
    opacity 900ms var(--ease),
    transform 900ms var(--ease);
  transition-delay: calc(var(--i, 0) * 110ms);
}
[data-reveal][data-shown="true"] {
  opacity: 1;
  transform: none;
}

/* ---------- 2 · om os ---------- */

/* Ingen egen baggrund og ingen lås: sektionen scroller som alt andet, og
   canvasset kører videre bag den. */
.about.section {
  background: transparent;
  /* Headeren er fixed og gennemsigtig, så sætningen skal begynde under den.
     Uden hdr-h i toppadding lægger den sig hen over logo og menu. */
  /* Ingen bundpolstring: hele afstanden ned til båndet ligger i .about-gap, og
     kun sådan kan citatet stå præcis midt i den. */
  padding-block: calc(var(--hdr-h) + clamp(5rem, 14vh, 10rem)) 0;
}
/* Ingen .wrap: sætningen skal gå helt ud til sidens egne marginer, altså
   præcis samme kant som logoet til venstre og menuknappen til højre. En
   centreret max-width ville trække den ind og bryde med headeren. */
.about__inner {
  position: relative;
  display: grid;
  gap: clamp(2.5rem, 7vh, 4.5rem);
}

/* Etiketten står ude i venstre margin, på linje med sætningens første linje. */
.about__eyebrow {
  position: absolute;
  top: 0.62em;
  left: 0;
  margin: 0;
  color: var(--on-dark);
}

.about__statement {
  margin: 0 0 0 var(--about-indent);
  /* Kun første linje forskydes, så den starter fri af etiketten. */
  text-indent: clamp(2rem, 7vw, 8rem);
  font-size: clamp(1.9rem, 4.2vw, 4.1rem);
  line-height: 1.06;
  letter-spacing: -0.045em;
  color: var(--on-dark);
  text-wrap: pretty;
}
/* Ordene tændes fra venstre. --w sættes af about-statement.js. */
.about__word {
  color: rgba(204, 204, 204, calc(0.16 + var(--w, 0) * 0.84));
  transition: color 120ms linear;
}

.about__rule {
  position: relative;
  display: flex;
  align-items: center;
  margin-left: var(--about-indent);
}
/* Tegnes fra venstre mod højre i takt med at ordene tændes. --rule sættes af
   about-statement.js, så streg og tekst kører på nøjagtig samme fremdrift og
   ikke på hver sin timing. */
.about__rule-line {
  flex: 1;
  height: 1px;
  background: var(--hair-dark);
  transform: scaleX(var(--rule, 0));
  transform-origin: left center;
}

.about__cols {
  display: grid;
  gap: clamp(2rem, 6vw, 4rem);
  grid-template-columns: 1fr;
  margin-left: var(--about-indent);
}
@media (min-width: 860px) {
  .about__cols {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
  .about__right {
    max-width: 27rem;
    margin-left: auto;
  }
}

.about__creed,
.about__coda {
  margin: 0;
  color: var(--on-dark);
  line-height: 1.85;
}
.about__creed span,
.about__coda span {
  display: block;
}
.about__coda {
  color: var(--on-dark);
}

/* Selve mellemrummet. Højden ER afstanden ned til båndet, og citatet centreres
   i den. Første forsøg hængte citatet på venstre spalte med en stor margin,
   men så lagde det ny luft til i stedet for at fylde den der var. */
.about-gap {
  position: relative;
  z-index: 2;
  min-height: clamp(13rem, 30vh, 22rem);
  display: grid;
  align-content: center;
  padding-inline: calc(var(--gut) + var(--about-indent)) var(--gut);
}
@media (max-width: 860px) {
  .about-gap {
    min-height: clamp(9rem, 22vh, 14rem);
    padding-inline: var(--gut);
  }
}
.about__mission {
  margin: 0;
  color: var(--on-dark);
  max-width: 34rem;
}
.about__cta {
  display: inline-flex;
  align-items: center;
  gap: 2.5rem;
  margin-top: clamp(1.6rem, 4vh, 2.6rem);
  padding-bottom: 0.5em;
  border-bottom: 1px solid var(--hair-dark);
  font-family: var(--sans);
  font-size: 0.6875rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--on-dark);
  transition: border-color 260ms var(--ease);
}
.about__cta:hover {
  border-color: var(--on-dark);
}
.about__cta-arrow {
  transition: transform 320ms var(--ease);
}
.about__cta:hover .about__cta-arrow {
  transform: translateX(6px);
}

/* På smalle skærme er der ikke margin nok til at stille etiketten ved siden af,
   og en indrykning ville æde linjelængden. Alt falder tilbage på én kant. */
@media (max-width: 860px) {
  .about__inner {
    --about-indent: 0rem;
  }
  .about__eyebrow {
    position: static;
    margin-bottom: clamp(1.5rem, 4vh, 2.5rem);
  }
  .about__statement {
    text-indent: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .about__word {
    transition: none;
  }
}

/* ---------- 2b · værdi-bånd + overgang ---------- */

/* Portens første halve skærmhøjde er tom: båndet er centreret i det låste
   vindue. Den luft trækkes ud her, så den synlige afstand op til Om os er
   .about-gap og kun den. --band-h sættes af marquee.js. */
.band-gate {
  margin-top: calc(var(--band-h, 16rem) / 2 - 50svh);
}
/* Højden er det låste vindue: 100vh til at stå stille i plus resten til hold
   og wipe. Ændres den, ændres både hvor længe båndet står og hvor lang
   overgangen er. */
/* Begge klasser skal med. .ink-wipe__track sætter samme egenskab længere nede
   i filen med lige specificitet, og så vinder den sidste regel: sporet var i
   virkeligheden 180vh hele tiden, uanset hvad der stod her. */
.band-gate .band-gate__track {
  /* Lås + wipe = to takter. 400vh giver samme tempo pr. takt som de øvrige
     låste afsnit; ved 250vh var det sidens hurtigste sted. */
  height: 400vh;
}
/* Ingen egen baggrund bag båndet — canvasset skal fortsætte hele vejen ind i
   låsen. Striberne har deres egen flade og dækker den når de kører.
   Begge klasser skal med: .ink-wipe--bone sætter samme egenskab længere nede i
   filen, og med lige specificitet vinder den sidste regel. */
.ink-wipe--bone.band-gate .ink-wipe__hold {
  background: transparent;
}
/* Striberne skal ligge OVER båndet, ellers vipes der bag om det. */
.band-gate .ink-wipe__bands {
  z-index: 2;
}

/* Fuld bredde, ingen gutter: båndet skal løbe ud over begge kanter, ellers er
   det en liste og ikke et bånd. Ingen baggrund — canvasset kører videre bagved. */
/* Båndet sidder centreret i det låste vindue: det stiger op med scrollen og
   står præcis midt på skærmen i det øjeblik porten låser. */
.marquee {
  position: absolute;
  inset: auto 0;
  top: 50%;
  transform: translateY(-50%);
  z-index: 1;
  overflow: hidden;
}
.marquee__viewport {
  overflow: hidden;
}
.marquee__track {
  display: flex;
  align-items: center;
  width: max-content;
  will-change: transform;
}

.marquee__word {
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(2.6rem, 8.5vw, 8rem);
  line-height: 1;
  letter-spacing: -0.04em;
  text-transform: uppercase;
  /* Samme grå som chiasmen. Hele den mørke strækning kører på én tekstfarve;
     --light er sidens LYSE flader og hører ikke hjemme her. */
  color: var(--on-dark);
  white-space: nowrap;
}

/* Stjernen som skilletegn, ikke et plus. Den er dæmpet, så den adskiller
   ordene uden at konkurrere med dem. */
.marquee__mark {
  display: inline-flex;
  align-items: center;
  flex: none;
  padding-inline: clamp(1.4rem, 3.5vw, 3.4rem);
}
.marquee__mark svg {
  display: block;
  width: clamp(1.1rem, 2.6vw, 2.4rem);
  height: auto;
  fill: var(--on-dark-dim);
}

@media (prefers-reduced-motion: reduce) {
  .marquee__track {
    /* Uden animation ville anden kopi blot være dubletter uden for skærmen. */
    transform: none;
  }
}

/* ---------- 3 · ventures (incredibles-agtig 3D stack) ---------- */

/* Sektionen lægges hen over portens låste vindue. Så stiger overskriften op
   nedefra MENS striberne kører, i stedet for at komme bagefter: uden overlappet
   skal man scrolle en hel skærm efter wipen før Ventures overhovedet begynder,
   og overskriften ville nå at forsvinde op og komme igen.
   Ingen toppolstring, så pinnet låser præcis når porten slipper.
   Over porten, ellers maler striberne hen over overskriften. */
.ventures.section {
  margin-top: -100svh;
  padding-top: 0;
  z-index: 4;
  /* Sektionsboksen selv er lys, og med overlappet dækker den porten. Fladen
     tændes derfor sammen med striberne, ikke før. --bone-in sættes af
     ventures-rise.js her på sektionen og arves ned til sticky'en. */
  background: rgb(241 241 241 / var(--bone-in, 1));
}

.ventures-pin__track {
  /* Sættes også i JS: intro + ~1vh pr. kort + cover. */
  height: 420vh;
}
.ventures-pin__sticky {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
  perspective: 1200px;
  perspective-origin: 50% 45%;
  /* --bone-in sættes af ventures-rise.js: fladen tændes først når striberne har
     dækket skærmen. Var den uigennemsigtig under overlappet, ville den dække
     porten, og hele den mørke strækning ville forsvinde for tidligt. */
  background: rgb(241 241 241 / var(--bone-in, 1));
}

.ventures__stage {
  position: relative;
  /* Over introen. Scenen stod på z-index: auto — det var .ventures__stack der
     havde 2 — så introens z-index: 1 vandt, og teksten blev malet hen over
     kortet. */
  z-index: 2;
  height: 100%;
  width: 100%;
  transform-style: preserve-3d;
}

/* Midtercentreret intro — scaler langsomt ned når kortene kommer (som incredibles). */
/* Ligger UDEN FOR .ventures__stage. Scenen er preserve-3d, og dér sorteres der
   efter dybde i stedet for z-index: kortet er midt i et flip når det passerer
   overskriften, så de to planer skærer hinanden, og browseren deler dem op.
   Den del af kortet der hælder bagud havnede bag teksten. Uden for 3D-rummet
   er introen en flad flade, og z-index gælder igen. */
.ventures__intro {
  position: absolute;
  left: 50%;
  top: 42%;
  z-index: 1;
  width: min(34rem, calc(100% - 2 * var(--gut)));
  /* --intro-y: exit-fase (stakken flyver op, header følger). */
  text-align: center;
  /* Ét fælles tal for "hvor fremme er introen". --intro kommer fra kort-stakken,
     --rise fra ventures-rise.js, og den forreste bestemmer. ALLE fire udtryk
     læser det samme: ellers står opaciteten på fuld mens forskydning, skalering
     og uskarphed stadig kører kort-stakkens værdi, og overleveringen ser ud som
     om overskriften bliver skiftet ud med en ny der fader ind. */
  --shown: max(var(--intro, 0), var(--rise, 0));
  transform: translate(
      -50%,
      calc(
        -50% + 16px * (1 - var(--shown)) + var(--intro-y, 0px) +
          var(--rise-y, 0px)
      )
    )
    scale(calc((0.96 + 0.04 * var(--shown)) * var(--intro-scale, 1)));
  opacity: var(--shown);
  filter: blur(calc((1 - var(--shown)) * 8px));
  pointer-events: none;
  will-change: transform, opacity, filter;
}
.ventures__title {
  margin: 0.45rem 0 0.85rem;
  color: var(--on-light);
}
.ventures__lead {
  margin: 0 auto;
  max-width: 28ch;
  color: var(--on-light-dim);
}

.ventures__stack {
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 2;
  width: min(calc(100% - 2 * var(--gut)), 22rem);
  height: min(64vh, 32rem);
  transform: translate(-50%, -46%);
  transform-style: preserve-3d;
  pointer-events: none;
}

/* Bone-veil ovenpå kort+intro under exit — dækker uden se-igennem mellem kort. */
.ventures__veil {
  position: absolute;
  inset: 0;
  z-index: 8;
  background: var(--bone);
  opacity: var(--exit-veil, 0);
  pointer-events: none;
  will-change: opacity;
}

.vcard {
  position: absolute;
  left: 50%;
  top: 0;
  width: 100%;
  display: grid;
  grid-template-rows: 1.05fr auto;
  /* incredibles: --color-white-dark */
  background: #fafafa;
  color: var(--on-light);
  border-radius: 1.5rem;
  box-shadow: 0 18px 50px rgba(17, 17, 17, 0.12);
  overflow: hidden;
  transform: translate3d(-50%, 95vh, 750px) rotateX(90deg);
  transform-origin: 50% 100%;
  transform-style: preserve-3d;
  backface-visibility: hidden;
  will-change: transform;
  pointer-events: auto;
}

.vcard__visual {
  position: relative;
  min-height: 11rem;
  /* Tyk hvid ramme (incredibles b__inner padding 1.5rem) */
  margin: 1.5rem 1.5rem 0;
  border-radius: 0.85rem;
  background: #f5f5f5;
  overflow: hidden;
}
.vcard__fluid {
  position: absolute;
  inset: 0;
  z-index: 0;
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
/* Fallback uden JS: samme to toner og samme 2,5px blokraster som canvas'et,
   bare uden noise — et rent skaktern i stedet for ditherets variation. */
.vcard__grid {
  position: absolute;
  inset: 0;
  z-index: 0;
  background-color: #f5f5f5;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='5' height='5' viewBox='0 0 5 5'%3E%3Crect width='5' height='5' fill='%23f5f5f5'/%3E%3Crect width='2.5' height='2.5' fill='%23e3e3e3'/%3E%3Crect x='2.5' y='2.5' width='2.5' height='2.5' fill='%23e3e3e3'/%3E%3C/svg%3E");
  background-size: 5px 5px;
}
.vcard__shape {
  position: absolute;
  inset: 18% 16% 14%;
  z-index: 2;
  background: var(--graphite);
  opacity: 0.88;
}
/* Payfriend: logomark i brand-rød gradient — SVG'en selv bærer farven. */
.vcard__visual[data-visual="payfriend"] .vcard__shape {
  inset: 22%;
  background: url("../assets/payfriend-mark-red.svg") center / contain no-repeat;
  opacity: 1;
}
/* Levano: logomark som maske i brand-navy. */
.vcard__visual[data-visual="levano"] .vcard__shape {
  background: #08161c;
  inset: 20% 22%;
  -webkit-mask: url("../assets/levano-mark.svg") center / contain no-repeat;
  mask: url("../assets/levano-mark.svg") center / contain no-repeat;
  opacity: 1;
}

.vcard__body {
  display: grid;
  gap: 0.7rem;
  /* Flugt med den tykke hvide ramme omkring det grå */
  padding: 1.75rem 1.5rem 1.65rem;
  justify-items: start;
}
.vcard__sector {
  opacity: 0.5;
}
.vcard__name {
  margin: 0;
}
.vcard__line {
  margin: 0 0 0.4rem;
  color: var(--on-light-dim);
  max-width: 28ch;
}

@media (min-width: 760px) {
  .ventures__stack {
    width: min(calc(100% - 2 * var(--gut)), 26rem);
    height: min(72vh, 38rem);
  }
  .vcard__visual {
    min-height: 14rem;
  }
}

/* ---------- 4 · proces (ponder.ai-agtig sticky stepper) ---------- */

.process.section {
  position: relative;
  z-index: 5;
  /* Desktop: trækker op over ventures-exit. Mobil: normalt flow (se min-width). */
  margin-top: 0;
  padding-block: 0;
  padding-inline: 0;
}
.process__head {
  max-width: 48rem;
  flex: 0 0 auto;
  padding: calc(var(--hdr-h) + clamp(1.25rem, 3vh, 2rem)) var(--gut) clamp(1rem, 2.5vh, 1.75rem);
}
.process__title {
  margin: 0 0 1rem;
  white-space: nowrap;
}
.process__lead {
  margin: 0;
  color: var(--on-dark-dim);
  max-width: 32rem;
}
.process-pin {
  --mkt: 0;
  --mkt-show: 0;
  --mkt-type: 0;
  --mkt-orbit: 0;
  --mkt-mid: 0;
  --mkt-in: 0;
}
.process-pin__track {
  /* Steps + cirkel-fly + type/helix + hold + cover (work-board glider op).
     1500 + 25 hold + 400 cover — matcher process-stepper. */
  height: 1925vh;
}
.process-pin__sticky {
  position: sticky;
  top: 0;
  z-index: 1;
  height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  box-sizing: border-box;
  /* Samme mørke som heroen (--ink), ikke --ink-2: afsnittet skal ligge i ét med
     resten af siden, bare uden partikler bag. --mkt blander over mod lyst når
     marketing-fasen tager over. */
  background: color-mix(
    in srgb,
    var(--ink) calc((1 - var(--mkt)) * 100%),
    var(--grey) calc(var(--mkt) * 100%)
  );
  overflow: hidden;
}
.process-pin.is-marketing .process__left,
.process-pin.is-marketing .process-visual {
  filter: blur(calc(var(--mkt) * 10px));
  opacity: calc(1 - var(--mkt) * 0.92);
  transition: none;
}
.process-pin.is-marketing .process-dots__item:not([data-process-mkt-dot]) {
  opacity: calc(1 - var(--mkt) * 0.95);
}
.process-pin.is-mkt-show .process__frame {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}
.process-pin.is-mkt-show .process-dots {
  opacity: 0;
  pointer-events: none;
}
/* Linjer skal kunne fortsætte under work-board-kortene — ikke klippes af sticky. */
.process-pin.is-mkt-show .process-pin__sticky,
.process-pin.is-mkt-cover .process-pin__sticky {
  overflow: visible;
}
.process-mkt-fly {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 5;
  display: grid;
  place-items: center;
  margin: 0;
  padding: 0;
  color: var(--on-dark);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  will-change: transform, opacity;
  transform-origin: center center;
}
.process-pin.is-marketing .process-mkt-fly {
  color: color-mix(
    in srgb,
    var(--on-dark) calc((1 - var(--mkt-flip, 0)) * 100%),
    var(--on-grey) calc(var(--mkt-flip, 0) * 100%)
  );
}
/* Loaderen: rattets otte håndtag, nu med en styrke-rampe rundt. Samme radier
   og vinkler som håndtagene, så skiftet mellem rat og loader ikke kan ses —
   det er den samme form der skifter karakter, ikke to former der afløser
   hinanden. Roterer om SIN EGEN midte, ikke om hver egers midte. */
.mkt-load {
  position: absolute;
  inset: 0;
  margin: auto;
  width: min(36%, 18rem);
  aspect-ratio: 1;
  fill: none;
  color: var(--on-dark);
  opacity: calc(var(--load, 0) * (1 - var(--helm-out, 0)));
  transform: rotate(var(--spin, 0deg));
  transform-origin: 50% 50%;
}
.mkt-load line {
  stroke: currentColor;
  stroke-width: 3.4;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}
.process-pin.is-marketing .mkt-load {
  color: color-mix(
    in srgb,
    var(--on-dark) calc((1 - var(--mkt-flip, 0)) * 100%),
    var(--on-grey) calc(var(--mkt-flip, 0) * 100%)
  );
}

.process-mkt-fly .process-dots__ring {
  width: 3.1rem;
  height: 3.1rem;
}
.process-mkt-fly .process-dots__n {
  font-size: 0.95rem;
}
.process-mkt-fly .process-dots__progress {
  /* Styres af --fill fra JS under hele marketing-outroen. */
  stroke-dashoffset: calc(1 - var(--fill, 0));
  transition: none;
}
.process-mkt-stage {
  position: absolute;
  inset: 0;
  z-index: 4;
  color: var(--on-grey);
  visibility: hidden;
  pointer-events: none;
  /* Aldrig blur på stage/type — kun visibility. */
  filter: none;
  opacity: 1;
}
.process-pin.is-mkt-show .process-mkt-stage {
  visibility: visible;
  pointer-events: auto;
}
.process__frame {
  /* Ponder-disposition: ~45/55, visual edge-høj, dots kun i venstre. */
  width: 100%;
  flex: 1 1 auto;
  height: auto;
  margin: 0;
  /* Desktop: head er uden for sticky — clear fixed header. Mobil override nedenfor. */
  padding: calc(var(--hdr-h) + 0.5rem) 0 0 var(--gut);
  box-sizing: border-box;
  display: grid;
  grid-template-columns: minmax(0, 45%) minmax(0, 55%);
  gap: 0;
  min-height: 0;
}
.process__left {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  min-height: 0;
  height: 100%;
  padding: 0.5rem clamp(1.5rem, 2.5vw, 2.5rem) 2rem 0;
  box-sizing: border-box;
}
.process-steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
}
.process-step {
  padding: 1.15rem 0;
  border-bottom: 1px dashed rgba(204, 204, 204, 0.22);
  cursor: pointer;
  color: rgba(204, 204, 204, 0.38);
  transition: color 500ms var(--ease);
}
.process-step:first-child {
  border-top: 1px dashed rgba(204, 204, 204, 0.22);
}
.process-step.is-active {
  color: var(--on-dark);
}
.process-step__row {
  display: grid;
  grid-template-columns: 2rem 1fr;
  gap: 0.85rem;
  align-items: baseline;
}
.process-step__n {
  font-family: var(--sans);
  font-size: 0.95rem;
  font-weight: 400;
  letter-spacing: 0.04em;
}
.process-step__title {
  margin: 0;
  font-family: var(--sans);
  font-size: clamp(1rem, 1.35vw, 1.2rem);
  font-weight: 400;
  letter-spacing: -0.02em;
}
.process-step__body-wrap {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 550ms var(--ease);
  padding-left: calc(2rem + 0.85rem);
}
.process-step.is-active .process-step__body-wrap {
  grid-template-rows: 1fr;
}
.process-step__body {
  margin: 0;
  overflow: hidden;
  padding-top: 0;
  color: var(--on-dark-dim);
  font-size: 0.95rem;
  max-width: 28rem;
  opacity: 0;
  transition:
    opacity 450ms var(--ease),
    padding-top 550ms var(--ease);
}
.process-step.is-active .process-step__body {
  opacity: 1;
  padding-top: 0.65rem;
}
/* Marketing er outro — ikke et accordion-trin med brødtekst. */
.process-step:last-child .process-step__body-wrap,
.process-step:last-child.is-active .process-step__body-wrap {
  grid-template-rows: 0fr;
}
.process-step:last-child .process-step__body,
.process-step:last-child.is-active .process-step__body {
  opacity: 0;
  padding-top: 0;
  visibility: hidden;
}
/* Ingen kant og ingen egen baggrund: de to halvdele skal læses som én flade,
   og skillelinjen var det eneste der delte dem op. */
.process-visual {
  position: relative;
  min-height: 0;
  height: 100%;
  border: 0;
  background: transparent;
  overflow: hidden;
}
.process-dots {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.85rem;
  flex-shrink: 0;
  padding-top: 1.5rem;
}
.process-dots__item {
  --fill: 0;
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: rgba(204, 204, 204, 0.38);
  cursor: pointer;
  font: inherit;
  transition: color 450ms var(--ease);
}
.process-dots__item.is-active {
  color: var(--on-dark);
}
.process-dots__item.is-done {
  /* Fuldt gennemført ring, men ikke solid fyld — som på ponder. */
  color: rgba(204, 204, 204, 0.72);
}
.process-dots__ring {
  position: relative;
  width: 3.1rem;
  height: 3.1rem;
  border-radius: 50%;
  display: grid;
  place-items: center;
  flex: 0 0 auto;
}
.process-dots__ring svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transform: rotate(-90deg);
  overflow: visible;
}
.process-dots__track,
.process-dots__progress {
  fill: none;
  stroke-width: 1.35;
}
.process-dots__track {
  stroke: rgba(204, 204, 204, 0.28);
}
.process-dots__progress {
  stroke: currentColor;
  stroke-linecap: round;
  stroke-dasharray: 1;
  stroke-dashoffset: calc(1 - var(--fill, 0));
  transition: stroke-dashoffset 80ms linear;
}
.process-dots__n {
  position: relative;
  z-index: 1;
  font-family: var(--sans);
  font-size: 0.95rem;
  font-weight: 400;
  letter-spacing: 0.04em;
}
.process-dots__label {
  font-family: var(--sans);
  font-size: 0.95rem;
  font-weight: 400;
  letter-spacing: 0.03em;
}
/* Panelerne skifter IKKE med et klasse-crossfade: de kører på scroll.
   --rel fortæller hvor langt vi er forbi netop dette panel, og derfra:
     rel < 0      panelet er på vej op nedefra
     rel 0–0,33   låst, animationen inde i det kører
     rel 0,33–1   det trækker op og ud mens det næste kommer ind
   Kun højre side flytter sig; listen til venstre står stille. */
.process-panel {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  pointer-events: none;
  --r: var(--rel, -9);
  --in: clamp(0, calc((var(--r) + 0.67) / 0.67), 1);
  --out: clamp(0, calc((var(--r) - 0.33) / 0.67), 1);
  opacity: calc(var(--in) * (1 - var(--out)));
  /* En hel skærmhøjde imellem: med kort afstand stod det udgående og det
     indkommende panel nærmest oven i hinanden midt i overgangen. */
  transform: translateY(calc((1 - var(--in)) * 88% - var(--out) * 84%))
    scale(calc(0.88 + 0.12 * var(--in) - 0.14 * var(--out)));
}
.process-panel.is-active {
  pointer-events: auto;
}
/* Sidste panel bliver stående: der er ikke noget efter det at rulle ud til. */
.process-panel.is-final {
  --out: 0;
}

@media (prefers-reduced-motion: reduce) {
  .process-panel {
    transform: none;
    opacity: 0;
  }
  .process-panel.is-active {
    opacity: 1;
  }
}
/* Prik-teksturen er væk: referencen har et stiplet gitter, ikke en flade med
   prikker, og de to sammen blev til støj. */
.process-panel__card {
  position: relative;
  z-index: 1;
  text-align: center;
  padding: 1.5rem;
}
.process-panel__n {
  display: block;
  margin-bottom: 0.75rem;
  opacity: 0.55;
}
.process-panel__label {
  margin: 0 0 0.65rem;
  font-size: clamp(2rem, 4vw, 3.2rem);
  letter-spacing: -0.04em;
  color: var(--white);
}
.process-panel__hint {
  margin: 0;
  color: var(--on-dark-dim);
  font-size: 0.9rem;
}

@media (max-width: 900px) {
  .process__title {
    white-space: normal;
  }

  .process__head {
    padding: calc(var(--hdr-h) + 0.65rem) var(--gut) 0.55rem;
  }
  .process__title {
    margin: 0 0 0.4rem;
    font-size: clamp(1.55rem, 7vw, 2.1rem);
  }
  .process__lead {
    font-size: 0.88rem;
    line-height: 1.4;
  }

  /* Sticky scrub: visual øverst, accordion under — track-højde sættes også i JS. */
  .process-pin__track {
    height: 760vh;
  }
  .process-pin__sticky {
    position: sticky;
    top: 0;
    height: 100svh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
  }
  .process__frame {
    flex: 1;
    min-height: 0;
    height: 100%;
    display: flex;
    flex-direction: column;
    grid-template-columns: none;
    /* Head er inde i sticky på mobil — ingen ekstra hdr-padding her. */
    padding: 0 var(--gut) 0.75rem;
    gap: 0.85rem;
  }
  .process-visual {
    order: -1;
    flex: 0 0 min(32svh, 13.5rem);
    height: min(32svh, 13.5rem);
    min-height: min(32svh, 13.5rem);
    border-left: 0;
    border: 1px solid var(--hair-dark);
    border-radius: var(--r-md);
  }
  .process__left {
    flex: 1;
    min-height: 0;
    height: auto;
    padding: 0;
    gap: 0;
    justify-content: flex-start;
    overflow: hidden;
  }
  .process-steps {
    flex: 1;
    min-height: 0;
    overflow: hidden;
  }
  .process-step {
    padding: 0.62rem 0;
  }
  .process-step__title {
    font-size: 0.92rem;
  }
  .process-step__body {
    font-size: 0.82rem;
  }
  .process-step.is-active .process-step__body {
    padding-top: 0.45rem;
  }
  .process-dots {
    display: none;
  }

  /* Accordion fader ud under morph — ingen translate-hak på mobil. */
  .process-pin.is-marketing .process__left {
    filter: none;
    opacity: 1;
  }
  .process-pin.is-marketing .process-visual {
    filter: none;
  }
  .process-pin.is-morphing .process-step:not(:last-child) {
    transform: none;
    opacity: calc(1 - var(--mkt-clear, 0));
  }
  .process-pin.is-morphing .process-step:last-child .process-step__row {
    transform: none;
    opacity: calc(1 - var(--mkt-travel, 0));
  }

  /* Marketing-fase: skjul sektions-head + trin 5 — scenen tager over. */
  .process-pin.is-marketing .process__head,
  .process-pin.is-mkt-show .process__head {
    opacity: calc(1 - var(--mkt, 0));
    visibility: visible;
    pointer-events: none;
  }
  .process-pin.is-marketing .process-step:last-child,
  .process-pin.is-mkt-show .process-step:last-child {
    opacity: calc(1 - max(var(--mkt-travel, 0), var(--mkt-frame-out, 0)));
    pointer-events: none;
    border-color: transparent;
  }

  /* Marketing-stage: fuld sticky-flade — type + helix skal have hele viewport. */
  .process-pin {
    --mkt-frame-out: 0;
  }
  .process-pin.is-mkt-show .process__frame,
  .process-pin.is-marketing .process__frame {
    opacity: calc(1 - var(--mkt-frame-out, 0));
    visibility: visible;
    pointer-events: none;
    transition: none;
  }
  .process-pin.is-mkt-show .process-visual {
    opacity: calc(1 - var(--mkt-frame-out, 0));
  }
  .process-mkt-stage {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border-radius: 0;
    overflow: hidden;
    opacity: 0;
    visibility: hidden;
    transition: none;
  }
  .process-pin.is-mkt-show .process-mkt-stage {
    visibility: visible;
    z-index: 6;
    /* frame-out åbner scenen; mkt-exit fader den ud uden at bakke orbit. */
    opacity: calc(
      clamp(0, var(--mkt-frame-out, 1), 1) * (1 - var(--mkt-exit, 0))
    );
  }
  .mkt-type__word {
    font-size: clamp(2.4rem, 13vw, 3.6rem);
    color: var(--ink);
    /* Fade ud med scenen — ikke slide (slide bakkede ved exit). */
    opacity: calc(1 - var(--mkt-exit, 0)) !important;
  }
  .mkt-type__mid {
    font-size: 0.72rem;
    max-width: 13rem;
    color: var(--ink);
    opacity: calc(1 - var(--mkt-exit, 0));
  }
  .mkt-carousel {
    opacity: min(
      1,
      calc(var(--mkt-orbit) * 16 * (1 - var(--mkt-exit, 0)))
    );
  }
  .mkt-foot {
    display: none;
  }

  /* Mobil: ALDRIG overflow:visible — helix lækker ellers ind over Se selv. */
  .process-pin.is-marketing .process-pin__sticky,
  .process-pin.is-mkt-show .process-pin__sticky,
  .process-pin.is-mkt-cover .process-pin__sticky {
    overflow: hidden;
  }

  .work-board.section {
    --wb-bg: 1;
  }

  /* Mobil: Proces glider op under ventures-exit (synces med COVER_VH_MOBILE 0.45). */
  .process.section {
    margin-top: -45vh;
  }

  /* Accordion fylder rest-plads under visual — undgår sort hul under listen. */
  .process__left {
    flex: 1 1 auto;
  }
  .process-steps {
    flex: 0 1 auto;
  }
}

/* ---------- 4b · verdenskort (trin 1) ---------- */

/* Stiplet gitter over hele panelet, som ponder. Linjerne står i markup frem for
   som ::before/::after, fordi der skal være flere end to, og fordi hver linje
   skal kunne placeres for sig. */
.process-panel__grid {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.process-panel__grid span,
.process-panel__grid i {
  position: absolute;
  display: block;
}
/* To lodrette og to vandrette linjer, som danner ÉN celle om pillen. Pillen står
   centreret inde i cellen og bliver ikke ramt af nogen linje: en linje gennem
   midten ville skære teksten over.
   Cellerne står bredere end høje, i samme forhold som referencen, og
   linjerne fader ud mod enderne i stedet for at ramme kanten. Uden udfadningen
   bliver gitteret en ramme om panelet frem for et felt der ligger under det. */
.process-panel__grid span {
  top: 0;
  bottom: 0;
  left: var(--x);
  border-left: 1px dashed rgba(204, 204, 204, 0.2);
  -webkit-mask-image: linear-gradient(
    to bottom,
    transparent,
    #000 26%,
    #000 74%,
    transparent
  );
  mask-image: linear-gradient(
    to bottom,
    transparent,
    #000 26%,
    #000 74%,
    transparent
  );
}
.process-panel__grid i {
  left: 0;
  right: 0;
  top: var(--y);
  border-top: 1px dashed rgba(204, 204, 204, 0.2);
  -webkit-mask-image: linear-gradient(
    to right,
    transparent,
    #000 22%,
    #000 78%,
    transparent
  );
  mask-image: linear-gradient(
    to right,
    transparent,
    #000 22%,
    #000 78%,
    transparent
  );
}

.wmap {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  /* Over pillen: kortet skal lægge sig hen over den, ikke omvendt. */
  z-index: 2;
  pointer-events: none;
}
.wmap__svg {
  width: min(78%, 46rem);
  height: auto;
  overflow: visible;
}

/* Hvert kontinent har sin egen forsinkelse og sin egen vej ind. --local er
   trinnets fremdrift og sættes af process-stepper.js, så kortet samler sig
   mens man scroller gennem trin 1 og ikke på en timer. */
.wmap__c {
  fill: var(--on-dark);
  /* Helt uigennemsigtig: med gennemsigtige flader kunne pillen bag kortet
     stadig ses gennem kontinenterne, og så lå den reelt ikke bagved. */
  fill-opacity: 1;
  /* Samme fremdrift for alle: de skal tone ind SAMTIDIG og ikke skiftevis.
     Forskellen ligger i hvor langt de kommer fra, ikke i hvornår de kommer. */
  --t: clamp(0, calc(var(--local, 0) / 0.9), 1);
  /* Ind mod sin plads fra sit eget tyngdepunkt, skudt udad fra kortets midte:
     hvert kontinent kommer fra den retning det hører hjemme i. Lodret er
     skubbet hårdere end vandret, så de nordlige kommer tydeligt oppefra og de
     sydlige nedefra. */
  transform: translate(
      calc((var(--cx) - 500) * 0.95px * (1 - var(--t))),
      calc((var(--cy) - 250) * 1.6px * (1 - var(--t)))
    )
    scale(calc(0.82 + 0.18 * var(--t)));
  transform-origin: calc(var(--cx) * 1px) calc(var(--cy) * 1px);
  transform-box: view-box;
  opacity: var(--t);
}

/* Kompasset er stjernen i en cirkel, samme mærke som resten af siden. */
.wmap__compass {
  position: absolute;
  left: clamp(1.5rem, 4%, 3rem);
  bottom: clamp(1.5rem, 6%, 3.5rem);
  display: grid;
  place-items: center;
  width: clamp(2.6rem, 6vw, 4rem);
  aspect-ratio: 1;
  border: 1px solid var(--hair-dark);
  border-radius: 50%;
  opacity: calc(0.25 + 0.75 * clamp(0, calc((var(--local, 0) - 0.5) / 0.3), 1));
}
.wmap__compass svg {
  width: 42%;
  height: auto;
  fill: var(--on-dark);
}

/* Pillen sidder i krydset, som ponders knap. */
.process-panel__pill {
  display: inline-flex;
  align-items: center;
  gap: 0.7em;
  padding: 0.85em 1.6em;
  border: 1px solid var(--hair-dark);
  border-radius: var(--r-pill);
  background: var(--ink-2);
  color: var(--on-dark);
  font-family: var(--sans);
  font-size: 0.8125rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
  .wmap__c {
    --t: 1;
  }
}

/* ---------- 4c · commit-log (trin 2) ---------- */

/* Kortet ligger PRÆCIS i den stiplede celle: det læser de samme fire tal som
   gitterets linjer, sat på panelet i sections.js. Dermed kan de to ikke drifte
   fra hinanden når cellen ændres.
   Formen følger kontaktformularen nederst på siden: --graphite flade, hårstreg,
   1,15rem radius. Det er sidens kort-sprog, og terminalen er ikke en undtagelse. */
/* Blokken sidder inde i cellen med luft til alle fire linjer. Gitteret er altså
   ikke en ramme klistret på kortet, men et felt kortet ligger i. Tallene er de
   samme som gitterets, plus en indrykning. */
.clog-block {
  position: absolute;
  left: calc(var(--gx1) + 1.9rem);
  right: calc(100% - var(--gx2) + 1.9rem);
  top: calc(var(--gy1) + 1.6rem);
  bottom: calc(100% - var(--gy2) + 1.6rem);
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.clog__head {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  flex: none;
}
/* Firkantet mærke-boks. Kun hårstregen, ingen flade: med --graphite blev det
   en grå klods ved siden af kortet i stedet for en ramme om mærket. */
.clog__mark {
  display: grid;
  place-items: center;
  width: 2.9rem;
  height: 2.9rem;
  flex: none;
  background: transparent;
  border: 1px solid var(--hair-dark);
  border-radius: 0.85rem;
}
.clog__mark svg {
  width: 56%;
  height: auto;
  fill: var(--on-dark);
}
.clog__claim {
  margin: 0;
  font-size: 0.9375rem;
  font-weight: 500;
  line-height: 1.35;
  color: var(--on-dark);
  text-wrap: balance;
}

.clog {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  background: var(--graphite);
  border: 1px solid var(--hair-dark);
  border-radius: 1.15rem;
  overflow: hidden;
}
.clog__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.9rem 1.15rem;
  border-bottom: 1px solid var(--hair-dark);
  color: var(--on-dark-dim);
  flex: none;
}
.clog__body {
  position: relative;
  flex: 1;
  min-height: 0;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(
    to bottom,
    transparent,
    #000 15%,
    #000 88%,
    transparent
  );
  mask-image: linear-gradient(
    to bottom,
    transparent,
    #000 15%,
    #000 88%,
    transparent
  );
}
.clog__list {
  --line: 1.85rem;
  list-style: none;
  margin: 0;
  padding: 0.55rem 1.15rem;
  /* Rullet opad følger fremdriften: nye lander nederst, gamle glider ud
     foroven, og listen føles uendelig frem for at fylde kortet op. */
  /* Boksen er fuld fra første øjeblik, og NYE commits kommer ind foroven og
     skubber de ældre ned, som i en rigtig log. Derfor står listen forskudt op
     ved start og glider ned mod nul: ved fremdrift 0 ser man de ældste linjer,
     ved 1 står "nu" øverst. */
  transform: translateY(calc((var(--local, 0) - 1) * var(--roll, 0px)));
}

/* Grafen: én skinne gennem hele listen, knuderne sidder på den. */
.clog__row {
  position: relative;
  display: grid;
  grid-template-columns: 1.4rem minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 0.7rem;
  height: var(--line);
  font-size: 0.78125rem;
}
.clog__row::before {
  content: "";
  position: absolute;
  left: 0.44rem;
  top: 0;
  bottom: 0;
  width: 1px;
  background: rgba(204, 204, 204, 0.18);
}
.clog__row:first-child::before {
  top: 50%;
}
.clog__row:last-child::before {
  bottom: 50%;
}
.clog__node {
  position: relative;
  width: 0.5rem;
  height: 0.5rem;
  margin-left: 0.19rem;
  border-radius: 50%;
  background: var(--c);
}
/* Merge tegnes som ring, ikke som prik: det er en samling af to spor, ikke et
   nyt stykke arbejde. */
.clog__row[data-type="merge"] .clog__node {
  background: transparent;
  border: 1.5px solid var(--c);
}

/* Farven siger HVAD der er sket. Dæmpede toner, så de kan aflæses uden at
   sætte sig imod resten af siden, som ellers er uden mættet farve. */
.clog__row[data-type="feat"] { --c: #6fae7d; }
.clog__row[data-type="fix"] { --c: #c9a35a; }
.clog__row[data-type="merge"] { --c: #6f96c4; }
.clog__row[data-type="docs"] { --c: #8d8d96; }
.clog__row[data-type="release"] { --c: #b5709f; }

.clog__msg {
  color: var(--on-dark);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Initialer, ikke fulde navne: fire bogstaver siger hvem uden at æde linjen. */
.clog__who {
  color: var(--c);
  opacity: 0.85;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.6875rem;
}
.clog__when {
  color: var(--on-dark-dim);
  text-align: right;
  white-space: nowrap;
  font-size: 0.6875rem;
}
.clog__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.85rem 1.15rem;
  border-top: 1px solid var(--hair-dark);
  color: var(--on-dark-dim);
  flex: none;
}
.clog__foot b {
  color: var(--on-dark);
  font-weight: 400;
  font-variant-numeric: tabular-nums;
}

@media (prefers-reduced-motion: reduce) {
  .clog__list {
    transform: none;
  }
}

/* ---------- 4d · kalender (trin 3) ---------- */

/* Ugen der bliver booket: dage som kolonner, timer nedad, som en almindelig
   ugekalender. Blokken sidder i den stiplede celle med samme luft som
   commit-loggen, så de to trin har samme indramning. */
.cal-block {
  position: absolute;
  left: calc(var(--gx1) + 1.9rem);
  right: calc(100% - var(--gx2) + 1.9rem);
  top: calc(var(--gy1) + 1.6rem);
  bottom: calc(100% - var(--gy2) + 1.6rem);
  z-index: 2;
  display: flex;
  flex-direction: column;
  --gutter: 3.2rem;
}

/* Dagene står øverst og lander først: de er rammen møderne aflæses i. */
.cal__days {
  display: grid;
  grid-template-columns: var(--gutter) repeat(var(--cols), minmax(0, 1fr));
  align-items: end;
  gap: 0.4rem;
  padding-bottom: 0.5rem;
  flex: none;
  border-bottom: 1px dashed rgba(204, 204, 204, 0.2);
  opacity: clamp(0, calc(var(--local, 0) / 0.12), 1);
}
.cal__day {
  color: var(--on-dark-dim);
}

.cal__body {
  display: grid;
  grid-template-columns: var(--gutter) minmax(0, 1fr);
  gap: 0.4rem;
  flex: 1;
  min-height: 0;
}
.cal__hours {
  position: relative;
  opacity: clamp(0, calc((var(--local, 0) - 0.04) / 0.12), 1);
}
.cal__tick {
  position: absolute;
  left: 0;
  top: calc(var(--t) / var(--rows) * 100%);
  transform: translateY(-0.35em);
  font-family: var(--sans);
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  color: var(--on-dark-dim);
}

.cal__grid {
  position: relative;
  min-height: 0;
}
/* Kun vandrette linjer: timerne. Lodrette ville slås med dagskolonnerne. */
.cal__line {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(var(--t) / var(--rows) * 100%);
  border-top: 1px dashed rgba(204, 204, 204, 0.13);
  opacity: clamp(0, calc((var(--local, 0) - 0.04) / 0.12), 1);
}

/* Møderne lander ét ad gangen, så ugen fyldes op mens man scroller. Dæmpet
   grønt, samme tone som feature-knuden i commit-loggen: en aftale i hus. */
.cal__meet {
  position: absolute;
  left: calc(var(--c) / var(--cols) * 100% + 0.15rem);
  width: calc(100% / var(--cols) - 0.3rem);
  top: calc(var(--s) / var(--rows) * 100%);
  height: calc(var(--len) / var(--rows) * 100% - 0.15rem);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.1rem;
  padding: 0.25rem 0.45rem;
  border: 1px solid rgba(111, 174, 125, 0.4);
  border-left: 2px solid rgba(111, 174, 125, 0.85);
  border-radius: 0.3rem;
  background: rgba(111, 174, 125, 0.12);
  color: var(--on-dark);
  font-size: 0.625rem;
  line-height: 1.25;
  overflow: hidden;
  --t: clamp(0, calc((var(--local, 0) - 0.16 - var(--i) * 0.045) / 0.08), 1);
  opacity: var(--t);
  transform: translateY(calc((1 - var(--t)) * 0.4rem));
}
.cal__meet b {
  font-weight: 400;
  color: rgba(111, 174, 125, 0.95);
}
.cal__meet em {
  font-style: normal;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
  .cal__meet {
    --t: 1;
    transform: none;
  }
  .cal__days,
  .cal__hours,
  .cal__line {
    opacity: 1;
  }
}

/* ---------- 4e · roret (trin 4) ---------- */

.helm {
  position: absolute;
  inset: 0;
  color: var(--on-dark);
  display: grid;
  place-items: center;
  z-index: 2;
  pointer-events: none;
}
.helm__wheel {
  position: relative;
  width: min(36%, 18rem);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  /* Langsomt med uret så længe man står i trinnet. Når forvandlingen begynder,
     overtager --spin fra scrollen, og rotationen accelererer i stedet. */
  animation: helm-spin 54s linear infinite;
  transform: rotate(var(--spin, 0deg));
  opacity: calc((1 - var(--load, 0)) * (1 - var(--helm-out, 0)));
}
.process-pin.is-marketing .helm__wheel {
  animation: none;
}
.process-pin.is-marketing .helm {
  color: color-mix(
    in srgb,
    var(--on-dark) calc((1 - var(--mkt-flip, 0)) * 100%),
    var(--on-grey) calc(var(--mkt-flip, 0) * 100%)
  );
}
@keyframes helm-spin {
  to {
    transform: rotate(360deg);
  }
}
.helm__svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  fill: none;
  stroke-linecap: round;
}
/* Randen er to ringe tæt på hinanden: det giver rattet en tykkelse, uden at
   tegne en tyk streg der ville stå tungt mod resten af siden. */
.helm__rim {
  stroke: currentColor;
  opacity: 0.6;
  stroke-width: 1.4;
  vector-effect: non-scaling-stroke;
}
.helm__rim--in {
  opacity: 0.3;
  stroke-width: 1;
}
.helm__spoke {
  stroke: currentColor;
  opacity: 0.34;
  stroke-width: 1.2;
  vector-effect: non-scaling-stroke;
}
/* Håndtagene stikker uden for randen med runde ender, som på et rigtigt rat. */
.helm__grip {
  stroke: currentColor;
  opacity: 0.62;
  stroke-width: 3.4;
  vector-effect: non-scaling-stroke;
}
.helm__hub {
  fill: var(--ink);
  stroke: rgba(204, 204, 204, 0.3);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}
/* Skal ligge OVER svg'en. Den er absolut placeret, og positionerede elementer
   males over statisk indhold uanset rækkefølgen i DOM'en — så navets fyld
   dækkede mærket, selvom stjernen stod korrekt og lys. */
.helm__star {
  position: relative;
  z-index: 1;
  display: block;
  width: 23%;
}
.helm__star svg {
  display: block;
  width: 100%;
  height: auto;
  fill: var(--on-dark);
}

@media (prefers-reduced-motion: reduce) {
  .helm__wheel {
    animation: none;
  }
}

/* ---------- 4f · overgangen fra roret til marketing ---------- */

/* Fase 1 (1/3 → 2/3): alt andet end roret forlader skærmen.
   Trinnene og deres stiplede linjer glider OP, fordi de hører til det man
   forlader. */
.process-pin.is-morphing .process-step:not(:last-child) {
  transform: translateY(calc(var(--mkt-clear, 0) * -34vh));
  opacity: calc(1 - var(--mkt-clear, 0));
}
/* Marketing-punktet bliver stående, men dets linje glider NED og ud, sammen
   med indikatorerne: de hører til det der kommer efter. */
.process-pin.is-morphing .process-step:last-child {
  border-bottom-color: rgba(204, 204, 204, calc(0.22 * (1 - var(--mkt-clear, 0))));
}
.process-pin.is-morphing .process-dots {
  transform: translateY(calc(var(--mkt-clear, 0) * 22vh));
  opacity: calc(1 - var(--mkt-clear, 0));
}
/* Gitteret om roret fader bare ud. Det er rammen om objektet, ikke en del af
   rejsen, så det skal ikke flytte sig. */
.process-pin.is-morphing .process-panel__grid,
.process-pin.is-morphing .process-panel__card {
  opacity: calc(1 - var(--mkt-clear, 0));
}

/* Fase 2 (2/3 → 1): ordet trækkes ud til venstre. */
.process-pin.is-morphing .process-step:last-child .process-step__row {
  transform: translateX(calc(var(--mkt-travel, 0) * -120%));
  opacity: calc(1 - var(--mkt-travel, 0));
}

/* ---------- 5 · marketing-stage (inde i process-pin, efter cirkel-load) ---------- */

.mkt-type {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  filter: none;
}
.mkt-type__word {
  position: absolute;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(3.2rem, 11vw, 8.5rem);
  letter-spacing: -0.06em;
  line-height: 0.9;
  text-transform: uppercase;
  color: var(--on-grey);
  white-space: nowrap;
  will-change: transform;
  filter: none !important;
  opacity: 1 !important;
  -webkit-font-smoothing: antialiased;
  text-rendering: geometricPrecision;
  backface-visibility: hidden;
}
/*
 * Type-blokken tæt om midten — mid-linjen er skærmens præcise centrum.
 *
 * Ordene hænger på afstand fra midten målt i em, ikke på faste procenter af
 * højden. Med procenter blev afstanden mellem dem mindre jo lavere skærmen
 * var, mens ordene selv beholdt deres størrelse, og på en bærbar lagde de sig
 * hen over midterteksten. I em følger luften skriften.
 */
.mkt-type__word--left {
  top: auto;
  bottom: calc(53% + 0.38em);
  left: var(--gut);
  transform: translate3d(calc(-120vw + var(--mkt-type) * 240vw), 0, 0);
}
.mkt-type__word--right {
  top: calc(47% + 0.38em);
  bottom: auto;
  right: var(--gut);
  transform: translate3d(calc(120vw - var(--mkt-type) * 240vw), 0, 0);
}
.mkt-type__mid {
  position: absolute;
  left: 50%;
  /* Følger ordblokkens anker, ikke skærmens midte: hele blokken ligger lidt
     over midten, så MARKETING ikke lander nede i kortbåndet. */
  top: 47%;
  transform: translate(-50%, -50%);
  margin: 0;
  max-width: 16rem;
  text-align: center;
  color: var(--on-grey);
  opacity: var(--mkt-mid);
  filter: none;
}
.mkt-carousel {
  position: absolute;
  inset: 0;
  z-index: 3;
  cursor: grab;
  touch-action: none;
  /* Kortene selv flyver ind/ud via helix — kun hurtig canvas-fade. */
  opacity: min(1, calc(var(--mkt-orbit) * 12));
  filter: none;
}
.mkt-carousel[data-dragging] {
  cursor: grabbing;
}
.mkt-carousel__canvas {
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.mkt-carousel.is-on .mkt-carousel__canvas {
  pointer-events: auto;
}
.mkt-foot {
  position: absolute;
  left: 0;
  bottom: 0;
  z-index: 3;
  margin: 0;
  padding: 0 var(--gut) 1.75rem;
  max-width: 28rem;
  font-size: 0.92rem;
  color: var(--on-grey);
  opacity: var(--mkt-mid);
  pointer-events: none;
  filter: none;
}

@media (max-width: 700px) {
  .mkt-type__word {
    font-size: clamp(2.4rem, 14vw, 3.8rem);
  }
  /* Placeringen følger nu skriftstørrelsen af sig selv; her skal der bare
     lidt mere luft, fordi midterteksten bryder over flere linjer. */
  .mkt-type__word--left {
    bottom: calc(50% + 0.85em);
  }
  .mkt-type__word--right {
    top: calc(50% + 0.85em);
  }
}

/* ---------- 6 · work-board (incredibles.dev s-work) ---------- */

.work-board.section {
  --wb-r: 1.5rem;
  --wb-r-sm: 0.75rem;
  --wb-gap: 1.1rem;
  --wb-line1: min(72vh, 40rem);
  --wb-line2: 15rem;
  /* Cover: 0 → linjer synlige mellem kort; 1 → lys flade når sektionen er oppe. */
  --wb-bg: 0;
  /* Trækker kort op under cover, så de møder helix-linjerne. */
  --wb-lift: 0vh;
  position: relative;
  z-index: 6;
  overflow: visible;
  /* Desktop: cover over marketing-pin. Mobil: normalt flow (se min-width). */
  margin-top: 0;
  /* Samme vandrette margin som header (.hdr padding-inline). */
  padding-block: 0;
  padding-inline: var(--gut);
  background: transparent;
  color: var(--on-light);
  isolation: auto;
  transform: translate3d(0, var(--wb-lift), 0);
  will-change: transform;
}
.work-board.section::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: var(--light);
  opacity: var(--wb-bg);
}
.work-board__grid {
  position: relative;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  justify-content: space-between;
  gap: var(--wb-gap);
  width: 100%;
  max-width: none;
  margin-inline: 0;
}

.wb-exec {
  position: relative;
  width: calc(58% - var(--wb-gap) * 0.5);
  height: var(--wb-line1);
  background: #fafafa;
  border-radius: var(--wb-r);
  overflow: hidden;
}
.wb-exec__title {
  position: absolute;
  top: 3rem;
  left: 3rem;
  z-index: 2;
  margin: 0;
  max-width: 4.1em;
  font-size: clamp(2.4rem, 4.5vw, 4.5rem);
  letter-spacing: -0.05em;
  line-height: 0.95;
  pointer-events: none;
}
.wb-exec__canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
/* incredibles accent-dot der følger musen */
.wb-exec__cursor {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 2;
  width: 8px;
  height: 8px;
  margin: -4px 0 0 -4px;
  border-radius: 50%;
  background: #fc4778;
  pointer-events: none;
  will-change: transform;
  transform: translate(-8px, -8px);
}
.wb-exec.is-exec-reduced .wb-exec__cursor {
  display: none;
}

.wb-quote {
  position: relative;
  width: calc(42% - var(--wb-gap) * 0.5);
  height: var(--wb-line1);
  margin: 0;
  /* Vandret padding sættes i JS til 12.86% af boksens egen bredde */
  padding: 2rem var(--wb-quote-pad-x, 3.75rem);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  background: #2b2b2b;
  color: #fafafa;
  border-radius: 1.5rem;
  overflow: hidden;
}
.wb-quote__canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  z-index: 1;
  pointer-events: none;
}
.wb-quote__cursor {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 3;
  width: 8px;
  height: 8px;
  margin: -4px 0 0 -4px;
  border-radius: 50%;
  background: #fc4778;
  pointer-events: none;
  will-change: transform;
  transform: translate(-100px, -100px);
}
/* Live: tekst tegnes på canvas — HTML kun til a11y / font-mål */
.wb-quote.is-quote-live .wb-quote__text,
.wb-quote.is-quote-live .wb-quote__author {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
  opacity: 0;
  pointer-events: none;
}
.wb-quote__text {
  /* Samme display-typografi som .wb-exec__title (“Se selv”) */
  position: relative;
  z-index: 2;
  margin: 0;
  padding-left: 0.55em;
  font-family: var(--display);
  font-size: clamp(2.4rem, 4.5vw, 4.5rem);
  font-weight: 400;
  letter-spacing: -0.05em;
  line-height: 0.95;
}
.wb-quote__text::before {
  content: "“";
  position: absolute;
  top: -0.55em;
  left: 0;
  font-size: 0.55em;
  line-height: 1;
  letter-spacing: 0;
}
.wb-quote__author {
  position: relative;
  z-index: 2;
  display: block;
  margin-top: 2rem;
  font-family: var(--sans);
  font-size: 0.875rem;
  font-weight: 300;
  letter-spacing: 0.01em;
  text-transform: none;
}
.wb-quote__author::before {
  content: "— ";
}
.wb-quote.is-quote-reduced .wb-quote__canvas,
.wb-quote.is-quote-reduced .wb-quote__cursor {
  display: none;
}
.wb-quote.is-quote-reduced .wb-quote__text,
.wb-quote.is-quote-reduced .wb-quote__author {
  position: relative;
  width: auto;
  height: auto;
  margin: 0 0 0.4em;
  clip: auto;
  overflow: visible;
  opacity: 1;
  white-space: normal;
}
.work-board.is-reduced .wb-quote__text,
.work-board.is-reduced .wb-quote__author {
  opacity: 1;
}

.wb-showreel {
  position: relative;
  width: calc(24.5% - var(--wb-gap) * 0.5);
  height: var(--wb-line2);
  border-radius: var(--wb-r);
  overflow: hidden;
  display: grid;
  place-items: center;
  text-decoration: none;
  color: var(--light);
  border: 0;
  padding: 0;
  margin: 0;
  cursor: pointer;
  font: inherit;
}
.wb-showreel__media {
  position: absolute;
  inset: 0;
  background: #0c0c0e;
  overflow: hidden;
}
.wb-showreel__video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  pointer-events: none;
}
.wb-showreel__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(43, 43, 43, 0.45);
  transition: background 0.35s var(--ease);
}
.wb-showreel:hover .wb-showreel__media::after {
  background: rgba(43, 43, 43, 0.25);
}

/* ---------- showreel lightbox ---------- */

.showreel-modal {
  position: fixed;
  inset: 0;
  z-index: 95;
  display: grid;
  place-items: center;
  padding: var(--gut);
}
.showreel-modal[hidden] {
  display: none;
}
.showreel-open {
  overflow: hidden;
}
.showreel-modal__backdrop {
  position: absolute;
  inset: 0;
  border: 0;
  background: rgba(12, 12, 14, 0.88);
  backdrop-filter: blur(8px);
  cursor: pointer;
}
.showreel-modal__panel {
  position: relative;
  z-index: 1;
  width: min(100%, 72rem);
  aspect-ratio: 16 / 9;
  max-height: min(86vh, 100%);
  background: #0c0c0e;
  border-radius: 0.75rem;
  overflow: hidden;
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.45);
}
.showreel-modal__video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: #0c0c0e;
}
.showreel-modal__close {
  position: absolute;
  top: max(1rem, env(safe-area-inset-top));
  right: max(1rem, env(safe-area-inset-right));
  z-index: 2;
  width: 2.5rem;
  height: 2.5rem;
  border: 0;
  border-radius: 50%;
  background: rgba(241, 241, 241, 0.92);
  color: #111;
  font-size: 1.55rem;
  line-height: 1;
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: transform 0.25s var(--ease), background 0.25s var(--ease);
}
.showreel-modal__close:hover {
  background: #fff;
  transform: scale(1.05);
}

.wb-delivery {
  width: calc(75.5% - var(--wb-gap) * 0.5);
  height: var(--wb-line2);
  display: flex;
  align-items: center;
  gap: clamp(0.85rem, 1.5vw, 1.5rem);
  padding: 1.1rem 1.25rem;
  background: #fafafa;
  border-radius: var(--wb-r);
}
.wb-delivery__head {
  flex: 0 0 clamp(10rem, 16vw, 13.5rem);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1rem;
}
.wb-delivery__title {
  margin: 0 0 0.35rem;
  font-family: var(--display);
  font-size: clamp(1.15rem, 1.6vw, 1.45rem);
  letter-spacing: -0.03em;
}
.wb-delivery__text {
  margin: 0;
  color: #656565;
  font-size: 0.85rem;
  line-height: 1.35;
  text-wrap: balance;
}
.wb-projects {
  list-style: none;
  margin: 0;
  padding: 0;
  flex: 1;
  display: flex;
  gap: 0.75rem;
  min-width: 0;
}
.wb-project {
  flex: 1 1 0;
  min-width: 0;
  height: 8.25rem;
  padding: 0.85rem;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  background: #fff;
  border-radius: var(--wb-r-sm);
  transition: transform 0.35s var(--ease), box-shadow 0.35s var(--ease);
}
.wb-project:hover {
  transform: translateY(-3px);
  box-shadow: 0 12px 28px rgba(43, 43, 43, 0.08);
}
.wb-project__desc {
  margin: 0;
  padding: 0.35rem;
  font-size: 0.9rem;
  line-height: 1.3;
  letter-spacing: -0.01em;
}
.wb-project__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}
.wb-project__meta {
  display: flex;
  gap: 0.4rem;
  min-width: 0;
}
.wb-project__pill {
  display: inline-flex;
  align-items: center;
  height: 1.45rem;
  padding: 0 0.7rem;
  border-radius: var(--r-pill);
  background: #f1f1f1;
  font-size: 0.72rem;
  letter-spacing: 0.03em;
  white-space: nowrap;
}
.wb-project__nda {
  color: #a2a2a2;
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.wb-project__link {
  position: relative;
  flex-shrink: 0;
  width: 0.85rem;
  height: 0.85rem;
}
.wb-project__link span {
  display: block;
  width: 100%;
  height: 100%;
  background: #a2a2a2;
  transition: background 0.25s var(--ease);
  mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='13' height='13' fill='none' viewBox='0 0 13 13'%3E%3Cpath fill='%23000' d='M6.4 11.7q-1.1 1.1-2.65 1.1A3.62 3.62 0 0 1 1.1 11.7 3.6 3.6 0 0 1 0 9.06q0-1.55 1.1-2.65l1.59-1.59a.73.73 0 0 1 1.06 0q.3.3.3.74 0 .44-.3.74L2.16 7.88A2.1 2.1 0 0 0 1.55 9.06q0 .84.6 1.43t1.43.6q.83 0 1.42-.6l1.59-1.58a.73.73 0 0 1 1.06 0q.3.3.3.74t-.3.74zm1.58-1.58a.73.73 0 0 1 0-1.06l1.59-1.59a2.1 2.1 0 0 0 .6-1.42 2.1 2.1 0 0 0-.6-1.43 2.1 2.1 0 0 0-1.42-.6 2.1 2.1 0 0 0-1.43.6L5.73 5.28a.73.73 0 0 1-1.06 0 .73.73 0 0 1 0-1.06l1.59-1.58A3.62 3.62 0 0 1 8.9.55q1.55 0 2.65 1.1T12.65 4.3q0 1.55-1.1 2.65z'/%3E%3C/svg%3E")
    center / contain no-repeat;
}
.wb-project__link:hover span {
  background: var(--on-light);
}

/* Knap — incredibles-agtig clip wipe */
.wb-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  text-decoration: none;
  font-family: var(--sans);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 1;
  color: inherit;
}
.wb-btn__outer {
  position: relative;
  display: block;
  overflow: hidden;
  padding: 0.625rem 0.85rem;
  border-radius: 0.375rem;
}

.wb-delivery .wb-btn--solid .wb-btn__outer {
  padding: 0.7rem 1.35rem;
  border-radius: var(--r-pill);
}

.wb-showreel .wb-btn--ghost .wb-btn__outer {
  padding: 0.7rem 1.35rem;
  border-radius: var(--r-pill);
}
.wb-btn__outer::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
  clip-path: inset(0);
  transition: clip-path 0.8s cubic-bezier(0.86, 0, 0.07, 1);
}
.wb-btn__outer::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 5;
  border-radius: inherit;
  border: 1px solid rgba(43, 43, 43, 0.17);
  pointer-events: none;
}
.wb-btn__inner,
.wb-btn__hover {
  display: flex;
  align-items: center;
  justify-content: center;
}
.wb-btn__inner {
  position: relative;
  z-index: 2;
}
.wb-btn__inner .wb-btn__label {
  transition: transform 0.8s cubic-bezier(0.23, 1, 0.32, 1);
  will-change: transform;
}
.wb-btn__hover {
  position: absolute;
  inset: 0;
  z-index: 3;
  border-radius: inherit;
  clip-path: ellipse(80% 50% at 50% 152%);
  transition: clip-path 0.6s cubic-bezier(0.19, 1, 0.22, 1);
  will-change: clip-path;
}
.wb-btn__hover .wb-btn__label {
  transform: translate3d(0, 0.5em, 0);
  transition: transform 0.8s cubic-bezier(0.23, 1, 0.32, 1);
}
.wb-btn:hover .wb-btn__outer::before,
.wb-showreel:hover .wb-btn .wb-btn__outer::before {
  clip-path: inset(0 0 110%);
}
.wb-btn:hover .wb-btn__inner .wb-btn__label,
.wb-showreel:hover .wb-btn .wb-btn__inner .wb-btn__label {
  transform: translate3d(0, -0.75em, 0);
  transition: transform 0.4s cubic-bezier(0.55, -0.61, 0.73, 0.04);
}
.wb-btn:hover .wb-btn__hover,
.wb-showreel:hover .wb-btn .wb-btn__hover {
  clip-path: ellipse(100% 70% at 50% 50%);
  transition: clip-path 0.8s cubic-bezier(0.86, 0, 0.07, 1);
}
.wb-btn:hover .wb-btn__hover .wb-btn__label,
.wb-showreel:hover .wb-btn .wb-btn__hover .wb-btn__label {
  transform: translateZ(0);
  transition: transform 0.8s cubic-bezier(0.19, 1, 0.22, 1) 0.35s;
}
.wb-btn--solid {
  color: var(--light);
}
.wb-btn--solid .wb-btn__outer::before {
  background: var(--on-light);
}
.wb-btn--solid .wb-btn__hover {
  background: #111;
  color: var(--light);
}
.wb-btn--solid .wb-btn__outer::after {
  border-color: transparent;
}
.wb-btn--ghost {
  color: var(--on-light);
  z-index: 3;
}
.wb-btn--ghost .wb-btn__outer::before {
  background: #fff;
}
.wb-btn--ghost .wb-btn__hover {
  background: var(--on-light);
  color: var(--light);
}
.wb-showreel .wb-btn--ghost {
  position: relative;
  z-index: 1;
  color: var(--on-light);
  pointer-events: none;
}

@media (max-width: 1100px) {
  .wb-exec,
  .wb-quote {
    width: 100%;
    height: min(56vh, 28rem);
  }
  .wb-showreel {
    width: 100%;
    height: 12rem;
  }
  .wb-delivery {
    width: 100%;
    height: auto;
    flex-direction: column;
    align-items: stretch;
  }
  .wb-delivery__head {
    flex: none;
    width: 100%;
    flex-direction: row;
    align-items: flex-end;
    justify-content: space-between;
  }
  .wb-projects {
    flex-wrap: wrap;
  }
  .wb-project {
    width: calc(50% - 0.4rem);
    flex: 1 1 calc(50% - 0.4rem);
  }
}
@media (max-width: 700px) {
  .work-board.section {
    --wb-r: 1rem;
    --wb-r-sm: 0.75rem;
  }
  .wb-projects {
    flex-direction: column;
  }
  .wb-project {
    width: 100%;
    flex: none;
  }
  .wb-exec__title {
    top: 1.5rem;
    left: 1.5rem;
  }
}

/* ---------- 7 · team (dragonfly.xyz layout · full-bleed · lyst) ---------- */

.team.section {
  position: relative;
  /* Over work-board under reveal (work-board er 6 under cover; catch ligger under
     kortene men over marketing-sticky). */
  z-index: 5;
  /* Desktop: overlap under work-board. Mobil: normalt flow. */
  margin-top: 0;
  padding-inline: 0;
  padding-top: 0;
  padding-bottom: clamp(2rem, 6vh, 4rem);
  background: var(--light);
}

/* Sticky titel midt på skærmen mens work-board flyver væk */
.team-catch__track {
  /* Sættes i JS (~1.85× viewport) */
  height: 185vh;
}
.team-catch__sticky {
  position: sticky;
  top: 50%;
  width: 100%;
  display: flex;
  justify-content: center;
  pointer-events: none;
  z-index: 2;
}
.team-catch__head {
  margin: 0;
  padding-inline: var(--gut);
  text-align: center;
}
.team-catch__title {
  margin: 0;
  font-size: clamp(3.25rem, 8.5vw, 6.8rem);
  font-weight: 400;
  text-transform: none;
  letter-spacing: -0.05em;
  line-height: 0.86;
  color: var(--on-light);
}
.team-catch__line {
  display: block;
  transform-origin: 50% 80%;
  color: rgb(200, 200, 200);
}

/* Frame: sticky bund-lås i team-pin track (top i JS) + wipe */
.team-pin {
  position: relative;
  z-index: 3;
}
.team-pin__track {
  min-height: 100vh;
}
.team-frame {
  position: sticky;
  top: 0;
  z-index: 3;
  background: var(--light);
  padding-bottom: clamp(0.85rem, 2vh, 1.5rem);
}
.team-frame .team-featured {
  /* Luft efter catchphrase — som før overlap-hacket */
  margin: clamp(2rem, 6vh, 4rem) 0 clamp(0.85rem, 2vh, 1.35rem);
}
.team-frame .team-grid {
  margin: 0;
}

/* Wipe: fixed til viewport — starter i skærmbund uanset frame-lås */
.team-pin__wipe {
  position: fixed;
  inset: 0;
  display: flex;
  flex-direction: column;
  z-index: 5;
  pointer-events: none;
}
.team-pin__wipe span {
  flex: 1 1 0;
  width: 100%;
  background: var(--ink);
  transform: scaleY(var(--s, 0));
  transform-origin: center bottom;
  will-change: transform;
  margin-top: -1px;
  padding-bottom: 1px;
}
.team-pin__wipe span:first-child {
  margin-top: 0;
}

.team__head {
  text-align: center;
  margin-bottom: clamp(1.5rem, 3.5vh, 2.5rem);
  padding-inline: var(--gut);
}
.team__head h2:not(.team-catch__title) {
  text-transform: uppercase;
  letter-spacing: -0.04em;
}

/* Featured: edge-to-edge, 4 portraits */
.team-featured {
  list-style: none;
  margin: 0 0 clamp(0.85rem, 2vh, 1.35rem);
  padding: 0 0.5rem;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.5rem;
  overflow: visible;
  position: relative;
  z-index: 1;
}
.team-card {
  position: relative;
  overflow: hidden;
  aspect-ratio: 0.87 / 1.11;
  background: rgba(17, 17, 17, 0.06);
  will-change: transform, opacity;
}
.team-card__hit {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
  text-align: left;
  font: inherit;
}
.team-card__media {
  position: absolute;
  inset: 0;
}
.team-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  display: block;
  filter: grayscale(1);
  transform: scale(1);
  transition: transform 700ms var(--ease);
}
.team-card:hover .team-card__media img,
.team-card:focus-within .team-card__media img {
  transform: scale(1.03);
}
.team-card__content {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: flex-end;
  height: 100%;
  padding: 0.85rem 0.85rem 0.95rem;
  background: linear-gradient(
    to top,
    rgba(17, 17, 17, 0.88) 0%,
    rgba(17, 17, 17, 0.45) 38%,
    transparent 68%
  );
  pointer-events: none;
}
.team-card__cta {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.55rem;
}
.team-card__mark {
  width: 1.15rem;
  height: 1.15rem;
  flex: 0 0 auto;
  transform: rotate(0deg);
  transition: transform 480ms var(--ease);
}
.team-card:hover .team-card__mark,
.team-card:focus-within .team-card__mark {
  transform: rotate(-90deg);
}
.team-card__mark svg {
  width: 100%;
  height: 100%;
  display: block;
  fill: #000;
}
.team-card__cta-label {
  font-family: var(--sans);
  font-size: 0.62rem;
  font-weight: 400;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #000;
  writing-mode: vertical-rl;
  transform: translateY(6px);
  opacity: 0;
  transition:
    opacity 420ms var(--ease),
    transform 420ms var(--ease);
}
.team-card:hover .team-card__cta-label,
.team-card:focus-within .team-card__cta-label {
  opacity: 1;
  transform: none;
}
.team-card__info {
  align-self: stretch;
  min-width: 0;
  transition: transform 420ms var(--ease);
}
.team-card:hover .team-card__info,
.team-card:focus-within .team-card__info {
  transform: translateY(-2px);
}
.team-card__name {
  margin: 0 0 0.25rem;
  font-family: var(--sans);
  font-size: clamp(0.85rem, 1.1vw, 1rem);
  font-weight: 400;
  letter-spacing: -0.01em;
  color: var(--white);
  transition: opacity 420ms var(--ease), letter-spacing 420ms var(--ease);
  opacity: 0.92;
}
.team-card:hover .team-card__name,
.team-card:focus-within .team-card__name {
  opacity: 1;
  letter-spacing: 0.01em;
}
.team-card__role {
  margin: 0;
  color: rgba(255, 255, 255, 0.55);
  transition: color 420ms var(--ease);
}
.team-card:hover .team-card__role,
.team-card:focus-within .team-card__role {
  color: rgba(255, 255, 255, 0.82);
}

/* Lite: 2×4 — kvadratisk thumb + navn/rolle, kun top-hairline */
.team-grid {
  list-style: none;
  margin: 0;
  padding: 0 0.5rem;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.5rem;
  overflow: visible;
}
.team-cell {
  border-top: 1px solid var(--hair-light);
  min-width: 0;
  will-change: transform, opacity;
}
.team-cell__hit {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  margin: 0;
  padding: 0.75rem;
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
  text-align: left;
  font: inherit;
  transition: background-color 700ms var(--ease);
}
.team-cell:hover .team-cell__hit,
.team-cell:focus-within .team-cell__hit {
  background: var(--ink);
}
.team-cell__photo {
  flex: 0 0 auto;
  width: 5.5rem;
  height: 5.5rem;
  overflow: hidden;
  background: rgba(17, 17, 17, 0.06);
  transform: translateX(0);
  transition: transform 700ms var(--ease);
}
.team-cell__meta {
  min-width: 0;
  flex: 1 1 auto;
  transform: translateX(0);
  transition: transform 700ms var(--ease);
}
.team-cell:hover .team-cell__photo,
.team-cell:focus-within .team-cell__photo,
.team-cell:hover .team-cell__meta,
.team-cell:focus-within .team-cell__meta {
  transform: translateX(6px);
}
.team-cell__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  display: block;
  filter: grayscale(1);
}
.team-cell__photo--empty {
  background:
    linear-gradient(135deg, rgba(17, 17, 17, 0.04) 0%, rgba(17, 17, 17, 0.12) 100%);
}
.team-cell__name {
  margin: 0 0 0.25rem;
  font-family: var(--sans);
  font-size: 0.92rem;
  font-weight: 400;
  letter-spacing: -0.01em;
  color: var(--on-light);
  transition: color 700ms var(--ease);
}
.team-cell:hover .team-cell__name,
.team-cell:focus-within .team-cell__name {
  color: var(--white);
}
.team-cell__role {
  margin: 0;
  opacity: 0.5;
  transition: color 700ms var(--ease), opacity 700ms var(--ease);
}
.team-cell:hover .team-cell__role,
.team-cell:focus-within .team-cell__role {
  color: rgba(255, 255, 255, 0.72);
  opacity: 1;
}
.team-cell__cta {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.45rem;
  opacity: 0;
  transform: translateY(4px);
  transition:
    opacity 700ms var(--ease),
    transform 700ms var(--ease);
}
.team-cell:hover .team-cell__cta,
.team-cell:focus-within .team-cell__cta {
  opacity: 1;
  transform: none;
}
.team-cell__mark {
  width: 0.95rem;
  height: 0.95rem;
  flex: 0 0 auto;
  transform: rotate(0deg);
  transition: transform 800ms var(--ease);
}
.team-cell:hover .team-cell__mark,
.team-cell:focus-within .team-cell__mark {
  transform: rotate(90deg);
}
.team-cell__mark svg {
  width: 100%;
  height: 100%;
  display: block;
  fill: #fff;
}
.team-cell__cta-label {
  font-family: var(--sans);
  font-size: 0.62rem;
  font-weight: 400;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: #fff;
}
.team-cell--empty {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem;
  opacity: 0.55;
}
.team-cell--empty .team-cell__name {
  opacity: 0.45;
}

@media (max-width: 900px) {
  .team-featured,
  .team-grid {
    grid-template-columns: repeat(2, 1fr);
  }
  .team-cell__photo {
    width: 4.5rem;
    height: 4.5rem;
  }
}
@media (max-width: 520px) {
  .team-featured {
    grid-template-columns: 1fr 1fr;
    gap: 0.35rem;
  }
  .team-grid {
    grid-template-columns: 1fr;
  }
  .team-card__name {
    font-size: 0.78rem;
  }
  .team-cell__photo {
    width: 4rem;
    height: 4rem;
  }
}

/* Stripe-wipe lyst → mørkt (ink-blinds over bone-hold) */
.ink-wipe {
  position: relative;
  z-index: 3;
  pointer-events: none;
}
.ink-wipe__track {
  /* Mere scroll-room til trionn-agtig cascade (stagger ~0.22 × 4). */
  height: 180vh;
}
.ink-wipe__sticky {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
}
.ink-wipe__hold {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--bone);
}
.ink-wipe__bands {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  z-index: 1;
}
.ink-wipe__bands span {
  flex: 1 1 0;
  width: 100%;
  background: var(--ink);
  transform: scaleY(var(--s, 0));
  transform-origin: center bottom;
  will-change: transform;
  margin-top: -1px;
  padding-bottom: 1px;
}
.ink-wipe__bands span:first-child {
  margin-top: 0;
}

/* Mørk → lys (retning → ventures): ink-hold + bone-blinds */
.ink-wipe--bone .ink-wipe__hold {
  background: var(--ink);
}
.ink-wipe--bone .ink-wipe__bands span {
  background: var(--bone);
}

/* ---------- 7 · proof (key facts på ink) ---------- */

/* Mobil: hele Nøgletal-sektionen + wipe skjules. */
@media (max-width: 900px) {
  .proof.section {
    display: none !important;
  }
  .team-pin__wipe {
    display: none !important;
  }
}

.proof.section {
  position: relative;
  /*
   * Desktop: overlap team-wipe. Mobil: normalt flow.
   */
  z-index: 6;
  margin-top: 0;
  padding: 0;
  background: transparent !important;
}
/* Fladen toner ud gennem exit: se noten ved .proof-hold__sticky-masken. Uden
   det ligger sektionens egen baggrund tilbage som et opakt lag under den
   maskede blok, og feltet kan ikke komme igennem. Alfaen følger samme kurve
   som masken, så der ikke er noget spring. rgb-værdien er --ink (#0c0c0c);
   den skrives ud fordi alfa skal kunne regnes ind. */
.proof.section.is-ink {
  background: rgba(12, 12, 12, calc(1 - var(--exit-mask, 0))) !important;
}

/* Sticky: kort hold → Kontakt glider op (cover). */
.proof-hold__track {
  /* Sættes i JS: 1 + HOLD(0.55) + COVER(1.7) ≈ 3.25vh */
  height: 325vh;
}
.proof-hold__sticky {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
  display: flex;
  align-items: flex-start;
  background: transparent;
  isolation: isolate;
}
/*
 * Fly-fase: fixed overlay ovenpå wipe.
 * Handoff til sticky når pinned — ingen hop.
 */
.proof-hold.is-flying .proof-hold__sticky {
  position: fixed;
  inset: 0;
  z-index: 7;
  height: 100svh;
  background: transparent;
  pointer-events: none;
}
.proof-hold.is-ink .proof-hold__sticky {
  background: var(--ink);
  pointer-events: auto;
}
/*
 * Blokken er et opakt sort lag med overflow:hidden, så dens egen underkant
 * tegner en knivskarp vandret streg tværs over billedet. Masken opløser den.
 *
 * Blødheden følger exit-forløbet glidende og er ikke bundet til en fase-klasse:
 * et 40%-gradientspring der slår til og fra ved en tærskel er synligt som et
 * flimmer, netop mens man scroller igennem overgangen. Ved --exit-mask 0 står
 * kun de nederste par procent blødt op, og det er der hele tiden.
 */
.proof-hold__sticky {
  -webkit-mask-image: linear-gradient(
    to bottom,
    #000 calc(96% - var(--exit-mask, 0) * 38%),
    transparent 100%
  );
  mask-image: linear-gradient(
    to bottom,
    #000 calc(96% - var(--exit-mask, 0) * 38%),
    transparent 100%
  );
}
/*
 * Bag den maskede blok ligger selve sektionens flade, og den er lige så opak.
 * Farven er den samme som body's, så der er intet at se på nær ét: feltet bag
 * canvasset kan ikke komme igennem. Den slukkes under exit — se undtagelsen i
 * .proof.section.is-ink ovenfor, hvor baggrunden sættes med !important.
 */
.proof-hold.is-flying.is-ink .proof-hold__sticky {
  background: var(--ink);
}
.proof-hold__inner {
  position: relative;
  z-index: 1;
  width: 100%;
  padding-block: calc(var(--hdr-h) + clamp(2.5rem, 8vh, 5rem)) 2rem;
  background: transparent;
}

/* Ink-veil under exit — slører/dækker mens Kontakt glider op. */
.proof__veil {
  display: block;
  position: absolute;
  inset: 0;
  z-index: 8;
  background: var(--ink);
  opacity: var(--exit-veil, 0);
  pointer-events: none;
  will-change: opacity;
}

.proof__head {
  text-align: center;
  margin: 0 0 clamp(2.5rem, 6vh, 4rem);
  transform: translate3d(0, var(--exit-y, 0px), 0)
    scale(var(--exit-scale, 1));
  transform-origin: 50% 40%;
  will-change: transform;
}
.proof__title {
  margin: 0 0 0.65rem;
  color: var(--on-dark);
}
.proof__lead {
  margin: 0 auto;
  max-width: 28rem;
  color: var(--on-dark-dim);
}

.proof-cards {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: clamp(0.85rem, 1.6vw, 1.25rem);
  grid-template-columns: 1fr;
  perspective: 1400px;
  transform-style: preserve-3d;
}
@media (min-width: 900px) {
  .proof-cards {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    align-items: stretch;
  }
}

.proof-card {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 1.5rem;
  min-height: min(52vh, 28rem);
  padding: 1.35rem 1.35rem 1.5rem;
  border-radius: 1.35rem;
  overflow: hidden;
  transform-style: preserve-3d;
  /* Ikke backface-hidden: WebKit cacher blankt canvas-lag under rotateX. */
  transform-origin: 50% 0%;
}
.proof-card--light {
  background: var(--light);
  color: var(--on-light);
}
.proof-card--dark {
  background: var(--graphite);
  color: var(--on-dark);
  border: 1px solid var(--hair-dark);
}
.proof-card__label {
  margin: 0;
  opacity: 0.55;
}
.proof-card--light .proof-card__label {
  color: var(--on-light);
}
.proof-card__stage {
  flex: 1;
  display: grid;
  place-items: center;
  min-height: 10rem;
}

/* Lyse kort: dither-felt med venture-mærke, som incredibles' USP-kort.
   Canvas'et lægges ind af mountDitherPanel() og fylder feltet. */
.proof-card__panel {
  position: relative;
  flex: 1;
  min-height: 10rem;
  border-radius: 0.85rem;
  background: #f5f5f5;
  overflow: hidden;
}
.proof-card__panel canvas {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
/* Venture-mærker: står side om side og deler feltets bredde. */
.proof-card__panel:has(.proof-card__mark) {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8%;
}
/* Begge mærker males i samme grafit som det mørke nøgletals-kort. Gælder kun
   her — venture-kortene beholder brandfarverne. */
.proof-card__mark {
  position: relative;
  z-index: 1;
  flex: 0 0 auto;
  width: 34%;
  aspect-ratio: 1;
  background: var(--graphite);
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: contain;
  mask-size: contain;
}
.proof-card__mark--payfriend {
  /* Den ensfarvede variant — -red bærer sin egen gradient og kan ikke maskes. */
  -webkit-mask-image: url("../assets/payfriend-mark.svg");
  mask-image: url("../assets/payfriend-mark.svg");
}
.proof-card__mark--levano {
  -webkit-mask-image: url("../assets/levano-mark.svg");
  mask-image: url("../assets/levano-mark.svg");
}
/* Fotopanel: canvas'et bærer både motivet og rasteret. */
.proof-card__panel--photo {
  background: var(--graphite);
}

/* Brødtekst til venstre, tallet ude i højre hjørne — de deler bundlinjen
   i stedet for at ligge oven på hinanden. */
.proof-card__foot {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
}
.proof-card__value {
  /* Tallet læses først, men står visuelt sidst. */
  order: 1;
  flex: 0 0 auto;
  font-size: clamp(2.6rem, 5vw, 4rem);
  letter-spacing: -0.06em;
  line-height: 0.95;
  color: inherit;
}
.proof-card__foot .proof-card__line {
  flex: 1 1 auto;
}
.proof-card__orb {
  width: min(72%, 15rem);
  aspect-ratio: 1;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--light);
  color: var(--on-light);
}
.proof-card__orb-n {
  font-size: clamp(2.4rem, 4.5vw, 3.6rem);
  letter-spacing: -0.055em;
  line-height: 1;
}
.proof-card__line {
  margin: 0;
  max-width: 18ch;
  font-size: clamp(0.92rem, 1.1vw, 1.05rem);
  font-weight: 300;
  line-height: 1.35;
  letter-spacing: -0.01em;
}
/* Det mørke kort har intet tal i foden — linjen står midt under orb'en. */
.proof-card--featured .proof-card__foot {
  justify-content: center;
}
.proof-card--featured .proof-card__line {
  max-width: 24ch;
  text-align: center;
}

.proof-press {
  margin-top: clamp(3.5rem, 8vh, 5.5rem);
  text-align: center;
  transform: translate3d(0, var(--exit-y, 0px), 0)
    scale(var(--exit-scale, 1));
  transform-origin: 50% 0%;
  will-change: transform;
}
.proof-press__label {
  margin: 0 0 clamp(1.4rem, 3vh, 2rem);
  opacity: 0.5;
}
.press {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: center;
  gap: clamp(1.2rem, 3vw, 2.4rem) clamp(1.8rem, 4vw, 3.6rem);
}
.press__item {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  line-height: 0;
}
/* Hvide silhuetter → samme tone som den gamle press-tekst (#ccc @ 38%). */
.press__logo {
  display: block;
  height: calc(clamp(1.05rem, 1.7vw, 1.4rem) * var(--press-scale, 1));
  width: auto;
  max-width: min(11rem, 36vw);
  object-fit: contain;
  object-position: bottom center;
  user-select: none;
  pointer-events: none;
  opacity: 0.38;
  filter: brightness(0.8); /* #fff → ~#ccc, så opacity matcher teksten */
}

@media (max-width: 899px) {
  .proof-card {
    transform: none !important;
    opacity: 1 !important;
    visibility: visible !important;
  }
}

/*
 * Bærbare skærme. Titel, kort og presse-båndet lagde tilsammen beslag på lidt
 * mere end en skærmhøjde, og så faldt "omtalt i" ud under kanten. Kortene har
 * plads at give af: panelet har sin egen min-height, så de kollapser ikke.
 */
@media (max-height: 1000px) {
  .proof-hold__inner {
    padding-block: calc(var(--hdr-h) + clamp(1.5rem, 4vh, 3rem)) 1rem;
  }
  .proof__head {
    margin-bottom: clamp(1.6rem, 3.5vh, 2.4rem);
  }
  .proof-card {
    min-height: min(44vh, 22rem);
    gap: 1rem;
  }
  .proof-card__panel {
    min-height: 8rem;
  }
  .proof-press {
    margin-top: clamp(2rem, 4vh, 3rem);
  }
}

/* ---------- 8 · kontakt (composer + lead-popup) ---------- */

.contact {
  position: relative;
  z-index: 6;
  /* Desktop: cover over proof-exit. Mobil: normalt flow. */
  margin-top: 0;
  /*
   * Sektionen er lang med vilje. Formularen står i den første skærm; resten er
   * det rum hvor partikelfeltet bygger op og samler sig i mærket. Det rum lå
   * tidligere i en selvstændig outro-sektion, og så var finalen fordelt over
   * to kasser med en kant imellem der skulle lappes. Nu er det ét forløb i ét
   * element, og der er ingen grænse at skjule.
   */
  min-height: 300svh;
  background: transparent;
  /* Luften om formularen hører til dens egen ramme, ikke til den lange
     sektion. Uden nulstillingen lægger .section sin block-padding oveni
     wrappens, og formularen skubbes ned fra midten af sin skærm. */
  padding-block: 0;
  box-sizing: border-box;
}
/*
 * Ink-lag over formularens egen skærm. Det dækker nøgletals-blokken bagved og
 * slipper først når den er ude af billedet, og det slutter i en gradient i
 * stedet for en kant — feltet nedenunder toner frem gennem den.
 *
 * Laget falmede tidligere væk med scroll. Det gav en dobbelt overgang: først
 * forsvandt scrimmen, og bagved lå blokken stadig som en flade med sin egen
 * underkant. Nu ligger scrimmen fast og lader ditheret komme frem forneden.
 */
.contact__scrim {
  position: absolute;
  inset: 0 0 auto 0;
  height: 152svh;
  background: linear-gradient(
    to bottom,
    var(--ink) 0,
    var(--ink) 62%,
    transparent 100%
  );
  pointer-events: none;
  z-index: 0;
}
/* Formularen holder sin egen skærm i toppen af den lange sektion. */
.contact__wrap {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 100svh;
  padding-block: calc(var(--hdr-h) + 1.5rem) clamp(3rem, 8vh, 5rem);
  width: 100%;
  max-width: 46rem;
  margin-inline: auto;
  box-sizing: border-box;
  text-align: center;
  opacity: calc(1 - var(--contact-fade, 0) * 0.92);
}
.contact__head {
  margin-bottom: clamp(1.8rem, 4vh, 2.8rem);
}
.contact__title {
  margin: 0;
  color: var(--on-dark);
  white-space: nowrap;
}

.composer {
  display: grid;
  gap: 1.1rem;
  text-align: left;
}

.composer__box {
  display: grid;
  gap: 0.6rem;
  padding: 1.15rem 1.15rem 0.85rem;
  background: var(--graphite);
  border: 1px solid var(--hair-dark);
  border-radius: 1.15rem;
  overflow: visible;
  transition: border-color 220ms var(--ease);
}
.composer__box:focus-within {
  border-color: rgba(204, 204, 204, 0.28);
}

.composer__input {
  width: 100%;
  min-height: 8.75rem;
  resize: none;
  border: 0;
  outline: 0;
  background: none;
  color: var(--on-dark);
  font-family: var(--sans);
  font-size: clamp(1rem, 1.4vw, 1.15rem);
  font-weight: 300;
  line-height: 1.45;
  padding: 0.2rem 0.35rem;
}
.composer__input::placeholder {
  color: var(--on-dark-dim);
}

.composer__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-inline: 0.2rem;
}

.composer__topic {
  position: relative;
  display: inline-flex;
  align-items: center;
  z-index: 2;
}
.composer__topic.is-open {
  z-index: 5;
}
.composer__topic-btn {
  position: relative;
  appearance: none;
  border: 1px solid var(--hair-dark);
  border-radius: var(--r-pill);
  background: rgba(204, 204, 204, 0.06);
  color: var(--on-dark);
  font-family: var(--sans);
  font-size: 0.6875rem;
  font-weight: 400;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 0.55em 2em 0.55em 1em;
  cursor: pointer;
  outline: 0;
}
.composer__topic-btn::after {
  content: "";
  position: absolute;
  right: 0.85em;
  top: 50%;
  width: 0.35em;
  height: 0.35em;
  border-right: 1px solid currentColor;
  border-bottom: 1px solid currentColor;
  transform: translateY(-65%) rotate(45deg);
  color: var(--on-dark-dim);
  pointer-events: none;
}
.composer__topic.is-open .composer__topic-btn,
.composer__topic-btn:hover,
.composer__topic-btn:focus-visible {
  border-color: rgba(204, 204, 204, 0.35);
  background: rgba(204, 204, 204, 0.1);
}
.composer__topic-menu {
  position: absolute;
  left: 0;
  top: calc(100% + 0.45rem);
  margin: 0;
  padding: 0.35rem;
  list-style: none;
  min-width: 11rem;
  background: var(--ink-2);
  border: 1px solid var(--hair-dark);
  border-radius: 1rem;
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.45);
}
.composer__topic-menu[hidden] {
  display: none;
}
.composer__topic-menu [role="option"] {
  padding: 0.65em 0.85em;
  border-radius: var(--r-sm);
  color: var(--on-dark-dim);
  font-family: var(--sans);
  font-size: 0.6875rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  cursor: pointer;
}
.composer__topic-menu [role="option"]:hover,
.composer__topic-menu [role="option"]:focus-visible {
  background: rgba(204, 204, 204, 0.08);
  color: var(--on-dark);
}
.composer__topic-menu [role="option"][aria-selected="true"] {
  color: var(--on-dark);
}
.composer__topic-menu [role="option"][aria-selected="true"]::before {
  content: "✓ ";
  letter-spacing: 0;
}

.composer__send {
  width: 2.4rem;
  height: 2.4rem;
  border: 0;
  border-radius: var(--r-pill);
  background: rgba(204, 204, 204, 0.12);
  color: var(--on-dark);
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: background-color 220ms var(--ease), color 220ms var(--ease);
}
.composer__send:hover {
  background: var(--on-dark);
  color: var(--ink);
}

.composer__chips {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
}
.composer__chip {
  border-radius: var(--r-pill);
  border: 1px solid var(--hair-dark);
  background: transparent;
  color: var(--on-dark-dim);
  font-family: var(--sans);
  font-size: 0.8125rem;
  padding: 0.65em 1.15em;
  cursor: pointer;
  transition:
    background-color 220ms var(--ease),
    border-color 220ms var(--ease),
    color 220ms var(--ease);
}
.composer__chip:hover {
  color: var(--on-dark);
  border-color: rgba(204, 204, 204, 0.35);
  background: rgba(204, 204, 204, 0.06);
}

/* ---------- team bio-detail modal ---------- */

.bio-modal {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: grid;
  place-items: center;
  padding: var(--gut);
}
.bio-modal[hidden] {
  display: none;
}
.bio-open {
  overflow: hidden;
}
.bio-modal__backdrop {
  position: absolute;
  inset: 0;
  border: 0;
  background: rgba(5, 5, 7, 0.78);
  backdrop-filter: blur(6px);
  cursor: pointer;
}
.bio-modal__panel {
  position: relative;
  z-index: 1;
  width: min(100%, 26rem);
  max-height: min(92vh, 46rem);
  overflow: auto;
  background: var(--ink);
  color: var(--on-dark);
  border: 1px solid var(--hair-dark);
  display: flex;
  flex-direction: column;
  animation: bio-in 420ms var(--ease) both;
}
@keyframes bio-in {
  from {
    opacity: 0;
    transform: translateY(18px) scale(0.985);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
.bio-modal__bar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 0.75rem;
  padding: 0.85rem 1rem;
  border-bottom: 1px solid var(--hair-dark);
}
.bio-modal__bar .label:first-child {
  justify-self: start;
  opacity: 0.7;
}
.bio-modal__mark {
  width: 0.95rem;
  height: 0.95rem;
  justify-self: center;
}
.bio-modal__mark svg {
  width: 100%;
  height: 100%;
  display: block;
  fill: var(--on-dark);
}
.bio-modal__close {
  justify-self: end;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--on-dark);
  cursor: pointer;
  opacity: 0.7;
  transition: opacity 200ms var(--ease);
}
.bio-modal__close:hover {
  opacity: 1;
}
.bio-modal__media {
  position: relative;
  aspect-ratio: 1;
  overflow: hidden;
  background: var(--graphite);
  border-bottom: 1px solid var(--hair-dark);
}
.bio-modal__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  display: block;
  filter: grayscale(1);
}
.bio-modal__cross {
  position: absolute;
  z-index: 1;
  width: 10px;
  height: 10px;
  opacity: 0.45;
  pointer-events: none;
}
.bio-modal__cross::before,
.bio-modal__cross::after {
  content: "";
  position: absolute;
  background: var(--on-dark);
}
.bio-modal__cross::before {
  left: 50%;
  top: 0;
  width: 1px;
  height: 100%;
  transform: translateX(-50%);
}
.bio-modal__cross::after {
  top: 50%;
  left: 0;
  height: 1px;
  width: 100%;
  transform: translateY(-50%);
}
.bio-modal__cross:nth-child(1) { top: 0.65rem; left: 0.65rem; }
.bio-modal__cross:nth-child(2) { top: 0.65rem; right: 0.65rem; left: auto; }
.bio-modal__cross:nth-child(3) { bottom: 0.65rem; left: 0.65rem; top: auto; }
.bio-modal__cross:nth-child(4) { bottom: 0.65rem; right: 0.65rem; top: auto; left: auto; }
.bio-modal__rows {
  margin: 0;
  padding: 0;
}
.bio-modal__row {
  display: grid;
  grid-template-columns: 4.5rem 1fr;
  gap: 1rem;
  align-items: start;
  padding: 1rem 1.1rem;
  border-bottom: 1px solid var(--hair-dark);
}
.bio-modal__row dt {
  margin: 0;
  padding-top: 0.2rem;
  opacity: 0.55;
}
.bio-modal__row dd {
  margin: 0;
  color: var(--white);
}
.bio-modal__name {
  font-size: clamp(1.35rem, 2.4vw, 1.75rem);
  letter-spacing: -0.03em;
  line-height: 1.05;
  text-transform: uppercase;
}
.bio-modal__role {
  font-family: var(--display);
  font-size: 1.05rem;
  font-weight: 400;
  letter-spacing: -0.02em;
  text-transform: uppercase;
}
.bio-modal__row .body {
  font-size: 0.92rem;
  line-height: 1.55;
  color: var(--on-dark);
  font-weight: 300;
}
.bio-modal__link {
  display: block;
  text-align: center;
  padding: 1.05rem 1rem;
  color: var(--on-dark);
  text-decoration: none;
  opacity: 0.75;
  transition: opacity 200ms var(--ease);
}
.bio-modal__link:hover {
  opacity: 1;
}

/* Lead popup */
.lead-modal {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: grid;
  place-items: center;
  padding: var(--gut);
}
.lead-modal[hidden] {
  display: none;
}
.lead-modal__backdrop {
  position: absolute;
  inset: 0;
  border: 0;
  background: rgba(5, 5, 7, 0.72);
  cursor: pointer;
}
.lead-modal__panel {
  position: relative;
  z-index: 1;
  width: min(100%, 28rem);
  background: var(--ink-2);
  color: var(--on-dark);
  border: 1px solid var(--hair-dark);
  border-radius: 1.15rem;
  padding: clamp(1.4rem, 3vw, 2rem);
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.45);
}
.lead-modal__head {
  margin-bottom: 1.4rem;
}
.lead-modal__head h3 {
  margin: 0 0 0.55rem;
}
.lead-modal__sub {
  margin: 0;
  color: var(--on-dark-dim);
}
.lead-modal__form {
  display: grid;
  gap: 0.9rem;
}
.lead-field {
  display: grid;
  gap: 0.4rem;
  text-align: left;
}
.lead-field .label {
  color: var(--on-dark-dim);
}
.lead-field input {
  width: 100%;
  border: 1px solid var(--hair-dark);
  border-radius: var(--r-md);
  background: var(--ink);
  color: var(--on-dark);
  font-family: var(--sans);
  font-size: 1rem;
  font-weight: 300;
  padding: 0.85rem 1rem;
  outline: 0;
}
.lead-field input:focus {
  border-color: rgba(204, 204, 204, 0.35);
}
.lead-modal__actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.6rem;
  margin-top: 0.5rem;
}
.lead-modal__cancel {
  background: transparent;
  border: 1px solid var(--hair-dark);
  color: var(--on-dark);
}
.lead-modal__actions .pill--solid {
  background: var(--on-dark);
  color: var(--ink);
  border-color: var(--on-dark);
}
.lead-modal__actions .pill {
  cursor: pointer;
  font-family: var(--sans);
}

/* ---------- rystelse + supernova ---------- */

/* Klassen sættes kun mens det står på. En permanent transform på .hero ville
   lave en containing block og flytte alt position:fixed indeni resten af tiden. */
html.is-shaking .hero,
html.is-shaking .hdr,
html.is-shaking .menu {
  transform: translate3d(var(--shake-x, 0px), var(--shake-y, 0px), 0);
  will-change: transform;
}

.nova-flash {
  position: fixed;
  inset: 0;
  z-index: 40;
  pointer-events: none;
  opacity: 0;
  mix-blend-mode: screen;
  background: radial-gradient(
    circle at 50% 46%,
    rgba(196, 150, 255, 0.5),
    rgba(112, 40, 200, 0.34) 32%,
    rgba(40, 140, 200, 0.16) 54%,
    rgba(12, 12, 12, 0) 72%
  );
}

@media (prefers-reduced-motion: reduce) {
  html.is-shaking .hero,
  html.is-shaking .hdr,
  html.is-shaking .menu {
    transform: none;
  }
  .nova-flash {
    display: none;
  }
}

/* ---------- 10 · footer ---------- */

/* Uden egen baggrund, så partiklerne bagved kan ses samle sig til mærket. */
.footer {
  position: relative;
  z-index: 2;
  padding: clamp(4rem, 10vh, 8rem) var(--gut) clamp(2rem, 5vh, 3rem);
  color: var(--on-dark);
}

/* Mærkets plads. Feltet er tomt med vilje: WebGL tegner lockuppet præcis her,
   og forholdet er logoets eget (300 : 56,31), så partiklerne rammer kassen. */
.footer__mark {
  width: min(78vw, 62rem);
  aspect-ratio: 300 / 56.31;
  margin: 0 auto clamp(3rem, 9vh, 6rem);
  display: grid;
  place-items: center;
}
.footer__mark-fallback {
  width: 100%;
  height: auto;
  opacity: 0;
}
/* Kun hvis canvasset aldrig blev klar (ingen WebGL) står mærket som billede. */
body:not(:has(.stage[data-ready="true"])) .footer__mark-fallback {
  opacity: 0.9;
}

.footer__inner {
  display: grid;
  gap: clamp(3rem, 8vh, 5rem);
}

.footer__nav {
  display: grid;
  gap: clamp(2rem, 4vw, 3rem);
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  padding-top: clamp(2rem, 5vh, 3rem);
  border-top: 1px solid var(--hair-dark);
}
.footer__head {
  margin: 0 0 1.1rem;
  color: var(--on-dark-dim);
}
.footer__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.55rem;
}
.footer__list a,
.footer__addr {
  font-size: 0.95rem;
  font-weight: 300;
  line-height: 1.5;
}
.footer__addr {
  margin: 0;
  color: var(--on-dark-dim);
}

/* Samme hårlinje som nav-linksene i headeren: den tegnes ind, den blinker
   ikke frem. Ingen farve, kun lys. */
.footer__list a {
  position: relative;
  display: inline-block;
  color: var(--on-dark);
  padding-bottom: 2px;
  transition: color 260ms var(--ease);
}
.footer__list a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 420ms var(--ease);
}
.footer__list a:hover {
  color: var(--white);
}
.footer__list a:hover::after {
  transform: scaleX(1);
}
.footer__ext {
  font-size: 0.75em;
  opacity: 0.6;
}

.footer__base {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem 2rem;
  padding-top: clamp(1.5rem, 4vh, 2.5rem);
  border-top: 1px solid var(--hair-dark);
}
.footer__legal {
  margin: 0;
  color: var(--on-dark-dim);
}
/* De juridiske sider står på egen linje over bundlinjen — ikke inde i den,
   hvor de ville presse CVR og "til toppen" sammen på smalle skærme. */
.footer__legal-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 1.5rem;
  margin-top: clamp(2rem, 5vh, 3rem);
}
.footer__legal-link {
  color: var(--on-dark-dim);
  transition: color 260ms var(--ease);
}
.footer__legal-link:hover {
  color: var(--white);
}
.footer__top {
  color: var(--on-dark-dim);
  transition: color 260ms var(--ease);
}
.footer__top:hover {
  color: var(--white);
}

/* På telefon skal menuen være lav nok til at mærket stadig står inde i
   skærmen når man er nået til bunden. Én kolonne skubbede det ud over kanten. */
@media (max-width: 760px) {
  .footer {
    padding-top: clamp(2.5rem, 7vh, 4rem);
  }
  .footer__mark {
    width: 84vw;
    margin-bottom: clamp(2rem, 5vh, 3rem);
  }
  .footer__inner {
    gap: clamp(2rem, 5vh, 3rem);
  }
  .footer__nav {
    grid-template-columns: repeat(2, 1fr);
    gap: 1.6rem 1.2rem;
    padding-top: clamp(1.5rem, 4vh, 2rem);
  }
  .footer__head {
    margin-bottom: 0.7rem;
  }
  .footer__list {
    gap: 0.4rem;
  }
  .footer__list a,
  .footer__addr {
    font-size: 0.9rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .footer__list a::after {
    transition: none;
  }
}

/* Desktop cover-overlaps — SKAL stå efter base-reglerne (margin-top: 0),
   ellers vinder base i cascade og work-board trækker -400vh op på mobil. */
@media (min-width: 901px) {
  .process.section {
    margin-top: -140vh;
  }
  .work-board.section {
    margin-top: -400vh;
  }
  .team.section {
    margin-top: -100vh;
  }
  .proof.section {
    margin-top: -100vh;
  }
  .contact {
    margin-top: -170vh;
  }
}

/* Mobil: Se selv overlapper marketing-outro (SKAL stå efter base margin-top: 0). */
@media (max-width: 900px) {
  .work-board.section {
    /* Sweet spot mellem “for langt scrub” og “dækker helix for tidligt”. */
    margin-top: -70vh;
  }

  /* Kontakt: mellemting mellem 300svh (for langt) og content-højde (for kort). */
  .contact {
    min-height: 170svh;
  }
  .contact__scrim {
    height: 110svh;
  }
  .contact__wrap {
    min-height: 100svh;
    justify-content: center;
    padding-block: calc(var(--hdr-h) + 1.25rem) clamp(2.5rem, 6vh, 4rem);
  }
}

