/* TYPSNITTSBYTE 2026-09-02: familjenamnet "neuemontreal" i styles.css ar
   kvar for att inte rora referensens egen CSS, men @font-face pekar nu pa
   FoundersGrotesk-*.woff2. Tva skal:
     1. Founders Grotesk har tabular figures (tnum), Neue Montreal har inte.
        Det loser arskolumnen utan hack.
     2. Neue Montreal ar ruesaintabels licensierade typsnitt och far aldrig
        levereras till klient. Founders Grotesk ar Marias eget.
   Filnamnet i @font-face ar sanningen; familjenamnet ar bara en etikett. */

/* skeleton.css — det enda som lagts till ovanpå referensens egen styles.css.
   Markupen och stilmallen är DERAS, oförändrade. Här står bara det som krävs
   för att skelettet ska fungera utan deras CDN och utan deras bilder. */

/* REFERENSENS EGET TYPSNITT — neuemontreal, samma som ruesaintabel.paris.
   Christoffer 2026-08-31: "säkerställ att vi använder samma typsnitt som
   referens sidan".

   RIGHTS: neuemontreal är licensierat. Det ligger här för att riktningen ska
   gå att bedöma mot referensen. Det får INTE följa med när något publiceras
   för Maria — då byts det mot hennes eget (Founders Grotesk ligger kvar i
   fonts/ för det). */
@font-face { font-family:"neuemontreal"; src:url("fonts/FoundersGrotesk-Light.woff2") format("woff2"); font-weight:300; font-display:swap; }
@font-face { font-family:"neuemontreal"; src:url("fonts/FoundersGrotesk-Regular.woff2") format("woff2"); font-weight:400; font-display:swap; }
@font-face { font-family:"neuemontreal"; src:url("fonts/FoundersGrotesk-Medium.woff2") format("woff2"); font-weight:500; font-display:swap; }
@font-face { font-family:"neuemontreal"; src:url("fonts/FoundersGrotesk-Bold.woff2") format("woff2"); font-weight:700; font-display:swap; }

/* Bilderna är utbytta mot en grå 4x4-SVG; width/height står kvar i markupen så
   varje bildplats behåller sin proportion och rutnätet håller. */
img[src^="data:image/svg+xml"] { object-fit: cover; background: #d8d6d3; }

/* Videorna har fått sin src borttagen (data-skel-video). Platsen hålls med
   samma grå ton, så rytmen mellan rörligt och stilla går att läsa. */
video[data-skel-video] { background: #d8d6d3; display: block; width: 100%; height: 100%; }

/* LOAD-IN — EXAKT ur referensens egen kod, chunk-11.js (GSAP-timeline).
   Inte uppmatt, inte extrapolerat: detta ar deras anrop, ord for ord.

     tl.fromTo(WRAPPER, {clipPath:"inset(100% 0% 0% 0%)", opacity:1},
                        {clipPath:"inset(0% 0% 0% 0%)", duration:1.5,  ease:"power3.inOut"})
       .fromTo(INNER,   {scale:1.25},          {scale:1,            duration:1.7,  ease:"power3.inOut"}, 0)
       .fromTo(INNER,   {filter:"blur(10px)"}, {filter:"blur(0px)", duration:1.75, ease:"power1.inOut"}, 0.2)

   Fyra saker jag hade fel om innan:
     1. clip-path FINNS. Den ligger pa YTTRE elementet. Min forra matning laste
        den pa det inre barnet, dar den aldrig ror sig, och jag tog bort den.
     2. De tre har OLIKA langd: 1.5 / 1.7 / 1.75 s. Inte en gemensam.
     3. blur startar 0.2 s SENARE an de andra tva.
     4. blur har annan easing (power1) an clip/scale (power3).

   GSAP power3 = quart (t^4), power1 = quad (t^2). Bada uttryckta som linear()
   samplad ur den exakta formeln, sa kurvan ar identisk, inte en
   cubic-bezier-approximation. */
.opacity-0.overflow-hidden {
  opacity: 1;
  clip-path: inset(100% 0% 0% 0%);
  transition: clip-path 1500ms linear(0.00000, 0.00001, 0.00009, 0.00043, 0.00136, 0.00333, 0.00691, 0.01280, 0.02184, 0.03498, 0.05331, 0.07805, 0.11055, 0.15226, 0.20480, 0.26989, 0.34938, 0.44526, 0.55474, 0.65062, 0.73011, 0.79520, 0.84774, 0.88945, 0.92195, 0.94669, 0.96502, 0.97816, 0.98720, 0.99309, 0.99667, 0.99864, 0.99957, 0.99991, 0.99999, 1.00000) 0ms;
}
.opacity-0.overflow-hidden.is-in {
  clip-path: inset(0% 0% 0% 0%);
}
.opacity-0.overflow-hidden > .block {
  display: block;
  transform: scale(1.25);
  filter: blur(10px);
  transition:
    transform 1700ms linear(0.00000, 0.00001, 0.00009, 0.00043, 0.00136, 0.00333, 0.00691, 0.01280, 0.02184, 0.03498, 0.05331, 0.07805, 0.11055, 0.15226, 0.20480, 0.26989, 0.34938, 0.44526, 0.55474, 0.65062, 0.73011, 0.79520, 0.84774, 0.88945, 0.92195, 0.94669, 0.96502, 0.97816, 0.98720, 0.99309, 0.99667, 0.99864, 0.99957, 0.99991, 0.99999, 1.00000) 0ms,
    filter    1750ms linear(0.00000, 0.00163, 0.00653, 0.01469, 0.02612, 0.04082, 0.05878, 0.08000, 0.10449, 0.13224, 0.16327, 0.19755, 0.23510, 0.27592, 0.32000, 0.36735, 0.41796, 0.47184, 0.52816, 0.58204, 0.63265, 0.68000, 0.72408, 0.76490, 0.80245, 0.83673, 0.86776, 0.89551, 0.92000, 0.94122, 0.95918, 0.97388, 0.98531, 0.99347, 0.99837, 1.00000) 200ms;
  will-change: transform, filter;
}
.opacity-0.overflow-hidden.is-in > .block {
  transform: scale(1);
  filter: blur(0px);
}

@media (prefers-reduced-motion: reduce) {
  .opacity-0.overflow-hidden,
  .opacity-0.overflow-hidden > .block {
    clip-path: none; transform: none; filter: none; transition: none;
  }
}

/* Blocken måste ha höjd INNAN bilden laddat, annars ligger hela strömmen i vyn
   samtidigt och load-in triggar för allt på en gång i stället för allteftersom.
   Referensens markup bär width/height på bilderna; Marias är utbytta, så
   proportionen sätts här. Liggande installationsvyer: 3:2. */
.opacity-0.overflow-hidden > .block > img,
.opacity-0.overflow-hidden > .block > video {
  aspect-ratio: 3 / 2;
  width: 100%;
  height: auto;
  object-fit: cover;
}


/* TYPOGRAFIN ÄR REFERENSENS, orörd (Christoffer 2026-08-31: "samma storlek,
   placering och typsnitt som skelettet"). Inga överstyrningar här — måtten
   kommer ur referensens egen stilmall: märket 16/16, nav 12/12 med 21 i pitch,
   räknaren 12/18. Sätts något värde här glider bygget isär från skelettet. */

/* Headern: referensens .span-w-1 ger 7.73vw = 130 px vid 1680, byggt för
   "S + A". "MARIA KOSHENKOVA" i 16 px behöver ~153 px och bröts därför till
   två rader, vilket sköt ner navet 16 px (y198 mot referensens y182).
   Headern får den bredd namnet kräver; allt annat är referensens. */
header.fixed { width: max-content !important; }
header.fixed h1 { white-space: nowrap !important; height: 16px; }
header.fixed h1 span { white-space: nowrap !important; display: inline !important; }

/* PROJEKTMENYN. Hover på räknarens titel fäller ut listan nedåt, en rad i
   taget. Inaktiva i ljusgrått, svarta på hover. Klick scrollar till projektet.
   Ligger i ett eget fixed-lager: sätts position:relative på räknarens
   container bryts referensens centrering. */
.projnav {
  display: flex;
  flex-direction: column;
  gap: 3px;
  width: max-content;
  /* Ingen max-height och ingen overflow: hela listan maste fa flöda, annars
     kan det aktuella projektet inte ligga kvar pa mittlinjen nar man ar
     langt ner i listan. */
  opacity: 0;
  pointer-events: none;
  transition: opacity .22s ease;
}
.projnav.is-open { opacity: 1; pointer-events: auto; }
.projnav button {
  all: unset;
  cursor: pointer;
  display: block;
  font-family: inherit;
  font-size: 12px;
  line-height: 15px;
  color: #b5b5b5;
  white-space: nowrap;
  opacity: 0;
  transform: translateY(-5px);
  /* HOVER-FIX 2026-08-31: color fick tidigare samma transition-delay som
     utfällningen (upp till 700 ms på nedersta raden), eftersom en enda
     inline transition-delay gäller ALLA egenskaper. Musen svepte förbi
     innan färgen hann svara — det upplevdes som hackigt. Nu bär bara
     opacity/transform fördröjningen, via --d. color svarar alltid direkt. */
  transition:
    color .14s ease 0s,
    opacity .28s ease var(--d, 0ms),
    transform .28s ease var(--d, 0ms);
}
.projnav.is-open button { opacity: 1; transform: none; }
.projnav button:hover,
.projnav button.is-current { color: #000; }

/* Under stegningen slocknar hover-highlighten (Christoffer 2026-09-01).
   Musen star stilla medan listan flyttar sig under den, sa utan detta
   lyser en rad upp bara for att den rakade hamna under pekaren, och den
   konkurrerar med den faktiskt valda raden. is-current lyser vidare. */
.projnav.no-hover button:hover:not(.is-current) { color: #b5b5b5; }

@media (max-width: 767.98px) { .projnav { display: none !important; } }

/* HEADER-LOAD-IN — EXAKT ur referensens kod, chunk-35.js.
   Referensen animerar INTE headern som bilderna. Den har ett eget, kortare
   anrop, och det traffar hela <header> som en enhet, sa loggan och
   navigationen kommer in tillsammans:

     gsap.fromTo(header, {opacity:0, y:5},
                         {opacity:1, y:0, delay:.5, duration:.8, ease:"power3.out"})

   Samma chunk renderar `<header className="fixed bg-white top-0 left-0
   span-w-1 h-fit z-50 margin-x-1 ...">`, alltsa exakt vart element.
   Triggas pa isLoaded (sidladdning), inte pa scroll.
   GSAP power3.out = quart out, 1-(1-t)^4, samplad till linear(). */
header.fixed {
  opacity: 0;
  transform: translateY(5px);
  transition:
    opacity   800ms linear(0.00000, 0.10948, 0.20972, 0.30124, 0.38458, 0.46022, 0.52868, 0.59040, 0.64585, 0.69548, 0.73969, 0.77891, 0.81352, 0.84389, 0.87040, 0.89338, 0.91316, 0.93005, 0.94434, 0.95633, 0.96626, 0.97440, 0.98097, 0.98618, 0.99024, 0.99334, 0.99563, 0.99727, 0.99840, 0.99914, 0.99958, 0.99983, 0.99995, 0.99999, 1.00000, 1.00000) 500ms,
    transform 800ms linear(0.00000, 0.10948, 0.20972, 0.30124, 0.38458, 0.46022, 0.52868, 0.59040, 0.64585, 0.69548, 0.73969, 0.77891, 0.81352, 0.84389, 0.87040, 0.89338, 0.91316, 0.93005, 0.94434, 0.95633, 0.96626, 0.97440, 0.98097, 0.98618, 0.99024, 0.99334, 0.99563, 0.99727, 0.99840, 0.99914, 0.99958, 0.99983, 0.99995, 0.99999, 1.00000, 1.00000) 500ms;
}
header.fixed.is-loaded {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  header.fixed { opacity: 1; transform: none; transition: none; }
}

/* Nar projektmenyn ar oppen fadas WORK / COMMISSIONS / ABOUT bort, sa fokus
   ligger pa projektnavigationen. Loggan star kvar: den ar ortsmarkering.

   EXHIBITIONS STAR OCKSA KVAR (Christoffer 2026-09-10). Den ar rubriken over
   det man tittar pa, inte konkurrerande navigation, och den forsvann tidigare
   just nar listan behovde en rubrik. Se .nav-exh nedan for hur den lyfts nar
   listan vaxer upp i dess position. */
body.projnav-open header.fixed ul li:not(.nav-exh) {
  /* !important kravs: referensens egen <ul> bar en INLINE style="opacity: 1"
     fran sin animation, och inline vinner over varje selektor utan den. */
  opacity: 0 !important;
  pointer-events: none;
}
header.fixed ul,
header.fixed ul li { transition: opacity .22s ease; }

/* EXHIBITIONS lyfts av listan i stallet for att tackas av den.
   Utfallningen vaxer UTAT fran den aktuella raden, alltsa aven uppat. Ligger
   man langt ner i listan nar forsta radens ovankant hogre an EXHIBITIONS egen
   rad, och da skulle namnen tryckas in over rubriken. --exh-lift skrivs av
   motion.js till exakt overlappet, och rubriken foljer med pa toppen av
   animationen i stallet.

   Transformen bar samma kurva och varaktighet som listans egna rader
   (.28s ease), sa lyftet och utfallningen sker i takt. */
.nav-exh {
  transform: translateY(calc(var(--exh-lift, 0px) * -1));
  transition: transform .28s ease, opacity .22s ease;
  will-change: transform;
}
@media (prefers-reduced-motion: reduce) { .nav-exh { transition: none; } }

/* PARKERAD. Nar listan vuxit sa langt att rubriken skulle passera loggan
   stannar den strax under den, och namnen fortsatter under i stallet
   (Christoffer 2026-09-10). Da behovs en botten: utan den laser radernas text
   rakt genom ordet EXHIBITIONS. Bottnen ar papperets egen vita, dragen ut
   nagra pixlar i sidled sa den tacker prickmarkoren pa -12 ocksa.

   Headern maste samtidigt ligga OVER projektmenyn: menyns lager ar z-index 60
   och headern 50, alltsa malades listan ovanpa rubriken. */
/* Headern lyfts over projektmenyn (menyns lager ar z-index 60), MEN dess egen
   vita botten maste bort samtidigt. Referensens header bar `bg-white` och ar
   `h-fit`, alltsa ett vitt block fran loggan ner genom hela navlistan. Lyft man
   det blocket over listan masker det radernas vanstra del i hela sin hojd, och
   det var precis den stora rutan Christoffer sag 2026-09-10.

   Botten ges i stallet BARA till de tva rader som behover den: loggan, som
   alltid star kvar, och EXHIBITIONS nar den parkerat. Da ar den vita ytan exakt
   en textrad hog och det marks inte att det ar en ruta bakom. */
body.projnav-open header.fixed {
  z-index: 70; background: transparent;
  /* Lyft over listan far inte gora headern till ett osynligt lock: den ar
     `h-fit`, alltsa 276 px hog, och fangade klick och hover pa de rader som
     lag under den. Bara loggan och EXHIBITIONS tar emot pekaren, resten
     slapper igenom. Samma modell som referensens egen meny. */
  pointer-events: none;
}
body.projnav-open header.fixed h1,
body.projnav-open header.fixed li.nav-exh { pointer-events: auto; }
body.projnav-open header.fixed h1 {
  background: #fff;
  box-shadow: -8px 0 0 #fff, 8px 0 0 #fff;
}
.nav-exh.is-parked {
  background: #fff;
  box-shadow: -14px 0 0 #fff, 14px 0 0 #fff;   /* tacker prick och hoger kant */
  /* Bandet ska vara exakt en LISTRAD hogt, inte en rubrikrad: listans pitch ar
     18 px (15 px radhojd + 3 px gap) och rubrikens radhojd ar 12. Utan de tre
     extra pixlarna i over- och underkant sticker en passerande rad ut med en
     hartunn strimma. padding vaxer bandet, negativ margin halller texten kvar
     pa sin baslinje, sa ingenting flyttar sig. */
  padding-block: 3px;
  margin-block: -3px;
}

/* Verksnamnet lyfts i bade raknarens titel och projektmenyn. Artal och
   plats star kvar i normal vikt, sa verket ar det som drar blicken.
   Vikt 500 (Medium), inte 700: bold var for tung mot 14 px versaler
   (Christoffer 2026-09-01). NeueMontreal-Medium.woff2 ar redan laddad. */
.projnav button strong,
.fixed.top-1\/2.left-0 p strong {
  font-weight: 500;
}

/* Block nedanfor vyn vid landning far sitt fardiga lage utan animation. */
.opacity-0.overflow-hidden.no-anim,
.opacity-0.overflow-hidden.no-anim > .block {
  transition: none !important;
}

/* TITELRADEN ANKRAS PA SIN FORSTA RAD (Christoffer 2026-09-01).
   Referensens `-translate-y-1/2` centrerar hela blocket. Nar ett projektnamn
   wrappar till tva rader vaxer blocket och BADA raderna centreras kring
   mitten, sa den forsta raden glider uppat och namnet tappar sin fasta plats.

   Uppmatt: enradig titel top 441, hojd 18, forsta radens mitt 450.
   Tvaradig: top 432, hojd 36, forsta radens mitt 441. Nio pixlars glidning.

   Nu ligger blocket med sin FORSTA rad pa mittlinjen och vaxer nedat.
   --rad-mitt sätts av motion.js fran uppmatt line-height, sa varden foljer
   med om typsnittet andras. flex-start behovs for att siffran ska folja
   forsta raden i stallet for att centreras mot hela blocket. */
.fixed.top-1\/2.-translate-y-1\/2.left-0.span-w-4 {
  transform: translateY(calc(-1 * var(--rad-mitt, 9px))) !important;
  align-items: flex-start;
}

/* ARTAL I EGEN KOLUMN (Christoffer 2026-09-01, omgjord 09-02).

   Forsta losningen tvingade varje siffra i en lika bred cell och skot sedan
   ytterkanterna med translateX. Den gav rak kant men forstorde kerningen:
   "2021" fick synliga glapp mellan tecknen. Kanten var ratt, ordbilden fel.

   Riktig losning: Founders Grotesk HAR tabular figures (`tnum`), vilket
   Neue Montreal saknar. Verifierat i fontfilerna:
     FoundersGrotesk-*  case frac kern liga locl tnum
     NeueMontreal-*     aalt ccmp kern locl mark mkmk salt
   Med tnum matte alla artal exakt 28.81 px; utan, 20.06 till 26.75.

   Tvingande skal utover elegansen: Neue Montreal ar ruesaintabels
   licensierade typsnitt och far aldrig folja med till klienten.
   Founders Grotesk ar Marias eget. */
.projnav button,
.fixed.top-1\/2.-translate-y-1\/2.left-0 > p:first-child {
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.t-yr {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  flex: 0 0 auto;
}
.t-rest {
  flex: 1 1 auto;
  min-width: 0;
}

/* Under stegningen slocknar hover-highlighten (Christoffer 2026-09-01).
   Musen star stilla medan listan flyttar sig under den, sa utan detta
   lyser en rad upp bara for att den rakade hamna under pekaren, och den
   konkurrerar med den faktiskt valda raden. is-current lyser vidare. */
.projnav.no-hover button:hover:not(.is-current) { color: #b5b5b5; }

@media (max-width: 767.98px) { .projnav { display: none !important; } }

/* HEADER-LOAD-IN — EXAKT ur referensens kod, chunk-35.js.
   Referensen animerar INTE headern som bilderna. Den har ett eget, kortare
   anrop, och det traffar hela <header> som en enhet, sa loggan och
   navigationen kommer in tillsammans:

     gsap.fromTo(header, {opacity:0, y:5},
                         {opacity:1, y:0, delay:.5, duration:.8, ease:"power3.out"})

   Samma chunk renderar `<header className="fixed bg-white top-0 left-0
   span-w-1 h-fit z-50 margin-x-1 ...">`, alltsa exakt vart element.
   Triggas pa isLoaded (sidladdning), inte pa scroll.
   GSAP power3.out = quart out, 1-(1-t)^4, samplad till linear(). */
header.fixed {
  opacity: 0;
  transform: translateY(5px);
  transition:
    opacity   800ms linear(0.00000, 0.10948, 0.20972, 0.30124, 0.38458, 0.46022, 0.52868, 0.59040, 0.64585, 0.69548, 0.73969, 0.77891, 0.81352, 0.84389, 0.87040, 0.89338, 0.91316, 0.93005, 0.94434, 0.95633, 0.96626, 0.97440, 0.98097, 0.98618, 0.99024, 0.99334, 0.99563, 0.99727, 0.99840, 0.99914, 0.99958, 0.99983, 0.99995, 0.99999, 1.00000, 1.00000) 350ms,
    transform 800ms linear(0.00000, 0.10948, 0.20972, 0.30124, 0.38458, 0.46022, 0.52868, 0.59040, 0.64585, 0.69548, 0.73969, 0.77891, 0.81352, 0.84389, 0.87040, 0.89338, 0.91316, 0.93005, 0.94434, 0.95633, 0.96626, 0.97440, 0.98097, 0.98618, 0.99024, 0.99334, 0.99563, 0.99727, 0.99840, 0.99914, 0.99958, 0.99983, 0.99995, 0.99999, 1.00000, 1.00000) 350ms;
}
header.fixed.is-loaded {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  header.fixed { opacity: 1; transform: none; transition: none; }
}

/* Nar projektmenyn ar oppen fadas WORK / COMMISSIONS / ABOUT bort, sa fokus
   ligger pa projektnavigationen. Loggan star kvar: den ar ortsmarkering.

   EXHIBITIONS STAR OCKSA KVAR (Christoffer 2026-09-10). Den ar rubriken over
   det man tittar pa, inte konkurrerande navigation, och den forsvann tidigare
   just nar listan behovde en rubrik. Se .nav-exh nedan for hur den lyfts nar
   listan vaxer upp i dess position. */
body.projnav-open header.fixed ul li:not(.nav-exh) {
  /* !important kravs: referensens egen <ul> bar en INLINE style="opacity: 1"
     fran sin animation, och inline vinner over varje selektor utan den. */
  opacity: 0 !important;
  pointer-events: none;
}
header.fixed ul,
header.fixed ul li { transition: opacity .22s ease; }

/* EXHIBITIONS lyfts av listan i stallet for att tackas av den.
   Utfallningen vaxer UTAT fran den aktuella raden, alltsa aven uppat. Ligger
   man langt ner i listan nar forsta radens ovankant hogre an EXHIBITIONS egen
   rad, och da skulle namnen tryckas in over rubriken. --exh-lift skrivs av
   motion.js till exakt overlappet, och rubriken foljer med pa toppen av
   animationen i stallet.

   Transformen bar samma kurva och varaktighet som listans egna rader
   (.28s ease), sa lyftet och utfallningen sker i takt. */
.nav-exh {
  transform: translateY(calc(var(--exh-lift, 0px) * -1));
  transition: transform .28s ease, opacity .22s ease;
  will-change: transform;
}
@media (prefers-reduced-motion: reduce) { .nav-exh { transition: none; } }

/* PARKERAD. Nar listan vuxit sa langt att rubriken skulle passera loggan
   stannar den strax under den, och namnen fortsatter under i stallet
   (Christoffer 2026-09-10). Da behovs en botten: utan den laser radernas text
   rakt genom ordet EXHIBITIONS. Bottnen ar papperets egen vita, dragen ut
   nagra pixlar i sidled sa den tacker prickmarkoren pa -12 ocksa.

   Headern maste samtidigt ligga OVER projektmenyn: menyns lager ar z-index 60
   och headern 50, alltsa malades listan ovanpa rubriken. */
/* Headern lyfts over projektmenyn (menyns lager ar z-index 60), MEN dess egen
   vita botten maste bort samtidigt. Referensens header bar `bg-white` och ar
   `h-fit`, alltsa ett vitt block fran loggan ner genom hela navlistan. Lyft man
   det blocket over listan masker det radernas vanstra del i hela sin hojd, och
   det var precis den stora rutan Christoffer sag 2026-09-10.

   Botten ges i stallet BARA till de tva rader som behover den: loggan, som
   alltid star kvar, och EXHIBITIONS nar den parkerat. Da ar den vita ytan exakt
   en textrad hog och det marks inte att det ar en ruta bakom. */
body.projnav-open header.fixed {
  z-index: 70; background: transparent;
  /* Lyft over listan far inte gora headern till ett osynligt lock: den ar
     `h-fit`, alltsa 276 px hog, och fangade klick och hover pa de rader som
     lag under den. Bara loggan och EXHIBITIONS tar emot pekaren, resten
     slapper igenom. Samma modell som referensens egen meny. */
  pointer-events: none;
}
body.projnav-open header.fixed h1,
body.projnav-open header.fixed li.nav-exh { pointer-events: auto; }
body.projnav-open header.fixed h1 {
  background: #fff;
  box-shadow: -8px 0 0 #fff, 8px 0 0 #fff;
}
.nav-exh.is-parked {
  background: #fff;
  box-shadow: -14px 0 0 #fff, 14px 0 0 #fff;   /* tacker prick och hoger kant */
  /* Bandet ska vara exakt en LISTRAD hogt, inte en rubrikrad: listans pitch ar
     18 px (15 px radhojd + 3 px gap) och rubrikens radhojd ar 12. Utan de tre
     extra pixlarna i over- och underkant sticker en passerande rad ut med en
     hartunn strimma. padding vaxer bandet, negativ margin halller texten kvar
     pa sin baslinje, sa ingenting flyttar sig. */
  padding-block: 3px;
  margin-block: -3px;
}

/* Verksnamnet lyfts i bade raknarens titel och projektmenyn. Artal och
   plats star kvar i normal vikt, sa verket ar det som drar blicken.
   Vikt 500 (Medium), inte 700: bold var for tung mot 14 px versaler
   (Christoffer 2026-09-01). NeueMontreal-Medium.woff2 ar redan laddad. */
.projnav button strong,
.fixed.top-1\/2.left-0 p strong {
  font-weight: 500;
}

/* Block nedanfor vyn vid landning far sitt fardiga lage utan animation. */
.opacity-0.overflow-hidden.no-anim,
.opacity-0.overflow-hidden.no-anim > .block {
  transition: none !important;
}

/* TITELRADEN ANKRAS PA SIN FORSTA RAD (Christoffer 2026-09-01).
   Referensens `-translate-y-1/2` centrerar hela blocket. Nar ett projektnamn
   wrappar till tva rader vaxer blocket och BADA raderna centreras kring
   mitten, sa den forsta raden glider uppat och namnet tappar sin fasta plats.

   Uppmatt: enradig titel top 441, hojd 18, forsta radens mitt 450.
   Tvaradig: top 432, hojd 36, forsta radens mitt 441. Nio pixlars glidning.

   Nu ligger blocket med sin FORSTA rad pa mittlinjen och vaxer nedat.
   --rad-mitt sätts av motion.js fran uppmatt line-height, sa varden foljer
   med om typsnittet andras. flex-start behovs for att siffran ska folja
   forsta raden i stallet for att centreras mot hela blocket. */
.fixed.top-1\/2.-translate-y-1\/2.left-0.span-w-4 {
  transform: translateY(calc(-1 * var(--rad-mitt, 9px))) !important;
  align-items: flex-start;
}

/* ARTAL I EGEN KOLUMN (Christoffer 2026-09-01).
   Tva fel lostes har. Texten efter aret borjade pa olika x eftersom aret var
   en del av samma textflode. Och artalen sag olika breda ut: typsnittets
   siffror ar proportionella som standard, sa "2004" ar bredare an "2011"
   trots lika manga tecken. tabular-nums tvingar alla siffror till samma
   bredd, vilket ger bade hard hogerkant pa aren och rak vansterkant pa
   texten efter dem. Kommatecknet ar borttaget, avstandet gors med gap. */
.projnav button,
.fixed.top-1\/2.-translate-y-1\/2.left-0 > p:first-child {
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.t-yr {
  /* tabular-nums provades forst och bet INTE: NeueMontreal-woff2:n saknar
     tnum-tabellen, sa siffrorna forblev proportionella och aren matte
     22.25 till 28.36 px. Bredden sätts darfor explicit fran den bredaste
     artalet, uppmatt i motion.js vid start, och hogerstalls sa aren far en
     hard hogerkant och texten efter dem en rak vansterkant. */
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  flex: 0 0 auto;
  width: var(--ar-bredd, 30px);
  /* Ingen text-align har: varje siffra bar sin egen cell nedan, sa artalet
     fyller kolumnen jamnt at bada hall. text-align: right gav hard hogerkant
     men lat vansterkanten vandra, eftersom "1" ar 4.16 px och "0" ar 7.45. */
}
.t-yr .d {
  display: inline-block;
  width: var(--siffra, 7.5px);
  text-align: center;
}
/* Ytterkanterna dras utat. Med alla siffror centrerade i sina celler slutade
   "2011" 1.4 px tidigare an "2026", eftersom en smal etta (4.16 px) far luft
   pa bada sidor i en 8 px cell. Uppmatt bläckslut fore fixen: 39.08 mot
   40.31-40.72. Forsta siffran vansterstalls och sista hogerstalls, sa bade
   vanster- och hogerkant blir raka oavsett vilka siffror artalet innehaller.
   Mellersta siffrorna star kvar centrerade. */
.t-yr .d:first-child { text-align: left; }
.t-yr .d:last-child  { text-align: right; }

/* Glyfens egen luft pa hogerkanten, KALIBRERAD MOT RENDERADE PIXLAR.

   Fonten saknar tabular figures (verifierat: "1111" och "0000" skiljer 13 px
   i bade NeueMontreal och FoundersGrotesk), sa varje siffra bar olika mycket
   inbyggd luft. Med hogerstalld cell slutade "2011" anda 0.83 px tidigare an
   "2026", eftersom en etta har mest luft till hoger.

   Varden nedan ar uppmatta i produktens EGEN meny genom att nollstalla
   kompensationen, skarmdumpa i 8x och lasa av blackets slutpixel per sista
   siffra. Tva tidigare forsok misslyckades: canvas measureText gav varden
   som inte matchade rendering, och Range.getBoundingClientRect ger
   layout-boxen och matte noll skillnad for samtliga siffror.

   translateX, inte margin: negativ margin pa sista barnet flyttar bara
   efterfoljande element och lamnar glyfen dar den star.

   Kalibrera om med _analysis/calib2.mjs om typsnitt eller storlek andras. */
.t-yr .d:last-child.d0 { transform: translateX(0.375px); }
.t-yr .d:last-child.d1 { transform: translateX(0.750px); }
.t-yr .d:last-child.d2 { transform: translateX(0.375px); }
.t-yr .d:last-child.d3 { transform: translateX(0.250px); }
.t-yr .d:last-child.d4 { transform: translateX(0.125px); }
.t-yr .d:last-child.d5 { transform: translateX(0.250px); }
.t-yr .d:last-child.d6 { transform: translateX(0.375px); }
.t-yr .d:last-child.d7 { transform: translateX(0.000px); }
.t-yr .d:last-child.d8 { transform: translateX(0.250px); }
.t-yr .d:last-child.d9 { transform: translateX(0.375px); }
.t-rest {
  flex: 1 1 auto;
  min-width: 0;
}

/* ══════════════════════════════════════════════════════════════════════
   WORK.HTML — verkssidan, RUMMET. Tillagt 2026-09-05, i slutet (GL24:
   aldrig regex i styles.css eller ovanför). Skelettets vänsterkolumn är
   position:fixed, vilket är referensens grammatik på desktop. På telefon
   låg den ovanpå bilderna (samma fel som project.html har), så där läggs
   den i flödet i stället. Ingen annan sida påverkas: allt är scopat på
   body[data-page="work"]. */
@media (max-width: 767px) {
  body[data-page="work"] .wk-left {
    position: static;
    transform: none;
    width: auto;
    margin-inline: 8px;
  }
  /* Krommet är fast och vitt, så första blocket måste börja under det. */
  body[data-page="work"] .wk-left:first-of-type { padding-top: 104px; }
  body[data-page="work"] .wk-title { margin-top: 20px; }
  body[data-page="work"] .wk-meta  { margin-top: 16px; margin-bottom: 32px; }
  /* Kreditlistans spaltbredder är desktopenheter och krockar på 390.
     Etiketten får en egen fast spalt, värdet resten. */
  /* Brödtexten är span-w-2 (två desktopspalter) och blir en smal remsa på 390. */
  body[data-page="work"] .wk-meta > p.span-w-2 { width: auto; }
  body[data-page="work"] .wk-meta li.flex { display: grid; grid-template-columns: 104px 1fr; }
  body[data-page="work"] .wk-meta li.flex .span-w-1,
  body[data-page="work"] .wk-meta li.flex .span-w-2 { width: auto; white-space: normal; }
  /* Bildspalten har ingen vänstermarginal att ta hänsyn till på telefon. */
  body[data-page="work"] .span-ml-4 { margin-left: 0; }
}

/* ══════════════════════════════════════════════════════════════════════
   R1 LADDSEKVENS, OMGJORD (Christoffer 2026-09-16, andra passet).
   Första försöket gav utställningsnamnet en EGEN, kortare opacity än sin
   egen translateY, i tron att den maskerade glidningen. Christoffer såg
   ändå knappt någon rörelse och bad om "exakt samma effekt som
   navigationen, loggan och räknaren" — alltså SAMMA mekanik som headerns
   egen sedan tidigare: opacity OCH transform på SAMMA element, samma
   distans (5px), samma varaktighet (800ms) och samma kurva (power3.out),
   bara förskjutna i tid mot varandra. Ny ordning, också hans:
     Grupp A (delay 0):    bilder (orörda, se nedan) + utställningsnamn + räknare
     Grupp B (delay 350ms): navigationen (Exhibitions/Work/Commissions/About)
     Grupp C (delay 700ms): loggan
   Bilderna rörs fortfarande inte: deras kurva är hämtad EXAKT ur referensen. */
.fixed.top-1\/2.-translate-y-1\/2.left-0.span-w-4 > p {
  opacity: 0;
  transform: translateY(5px);
  transition:
    opacity   800ms linear(0.00000, 0.10948, 0.20972, 0.30124, 0.38458, 0.46022, 0.52868, 0.59040, 0.64585, 0.69548, 0.73969, 0.77891, 0.81352, 0.84389, 0.87040, 0.89338, 0.91316, 0.93005, 0.94434, 0.95633, 0.96626, 0.97440, 0.98097, 0.98618, 0.99024, 0.99334, 0.99563, 0.99727, 0.99840, 0.99914, 0.99958, 0.99983, 0.99995, 0.99999, 1.00000, 1.00000) 0ms,
    transform 800ms linear(0.00000, 0.10948, 0.20972, 0.30124, 0.38458, 0.46022, 0.52868, 0.59040, 0.64585, 0.69548, 0.73969, 0.77891, 0.81352, 0.84389, 0.87040, 0.89338, 0.91316, 0.93005, 0.94434, 0.95633, 0.96626, 0.97440, 0.98097, 0.98618, 0.99024, 0.99334, 0.99563, 0.99727, 0.99840, 0.99914, 0.99958, 0.99983, 0.99995, 0.99999, 1.00000, 1.00000) 0ms;
}
.fixed.top-1\/2.-translate-y-1\/2.left-0.span-w-4.is-title-in > p {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  .fixed.top-1\/2.-translate-y-1\/2.left-0.span-w-4 > p {
    opacity: 1; transform: none; transition: none;
  }
}

/* HEADERN SPLITTAS I TVÅ EGNA REVEALS (Christoffer 2026-09-16). Tidigare
   animerade header.fixed h1 OCH ul tillsammans som EN enhet (se
   HEADER-LOAD-IN ovan, två dubblettkopior). Den kopplingen bryts här:
   headern själv görs statisk och alltid synlig, h1 och ul får VAR SIN
   identiska reveal (samma kurva/distans/varaktighet som originalet),
   triggade av SAMMA .is-loaded-klass som JS redan sätter — bara med olika
   transition-delay, precis som Grupp A/B/C ovan.

   !important krävs på ul: referensens egen markup bär en INLINE
   style="opacity: 1" (och transform: translate(0px, 0px)) kvar från sin
   egen körning, och inline vinner över varje selektor utan important
   (samma problem som .nav-exh-fadningen löser på LI-nivå, se ovan). h1
   har ingen sådan inline-stil men får important i samma regel för att
   hållas identisk med ul. */
header.fixed {
  opacity: 1 !important;
  transform: none !important;
  transition: none !important;
}
header.fixed h1,
header.fixed ul {
  opacity: 0 !important;
  transform: translateY(5px) !important;
  transition:
    opacity   800ms linear(0.00000, 0.10948, 0.20972, 0.30124, 0.38458, 0.46022, 0.52868, 0.59040, 0.64585, 0.69548, 0.73969, 0.77891, 0.81352, 0.84389, 0.87040, 0.89338, 0.91316, 0.93005, 0.94434, 0.95633, 0.96626, 0.97440, 0.98097, 0.98618, 0.99024, 0.99334, 0.99563, 0.99727, 0.99840, 0.99914, 0.99958, 0.99983, 0.99995, 0.99999, 1.00000, 1.00000) 0ms,
    transform 800ms linear(0.00000, 0.10948, 0.20972, 0.30124, 0.38458, 0.46022, 0.52868, 0.59040, 0.64585, 0.69548, 0.73969, 0.77891, 0.81352, 0.84389, 0.87040, 0.89338, 0.91316, 0.93005, 0.94434, 0.95633, 0.96626, 0.97440, 0.98097, 0.98618, 0.99024, 0.99334, 0.99563, 0.99727, 0.99840, 0.99914, 0.99958, 0.99983, 0.99995, 0.99999, 1.00000, 1.00000) 0ms;
}
header.fixed ul { transition-delay: 350ms; }
header.fixed h1 { transition-delay: 700ms; }
header.fixed.is-loaded h1,
header.fixed.is-loaded ul {
  opacity: 1 !important;
  transform: translateY(0) !important;
}

@media (prefers-reduced-motion: reduce) {
  header.fixed h1, header.fixed ul {
    opacity: 1 !important; transform: none !important; transition: none !important;
  }
}

/* LOGGA I MEDIUM (Christoffer 2026-09-16, justerad samma dag: "finns det en
   mellanstorlek, om det finns vill jag ha mellanskillnaden"). 700 (Bold) var
   det första försöket men för tungt. Founders Grotesk har fyra riktiga
   vikter — Light 300, Regular 400, Medium 500, Bold 700 — och 500 är den
   enda äkta mellanvikten (ingen 600/Semibold-fil finns). Samma vikt som
   titelns egen <strong> i räknarraden bär sedan 2026-09-01, den rörs inte
   av detta. */
header.fixed h1 { font-weight: 500; }

/* MJUK FADE PÅ LAZY-LADDADE BILDER (Christoffer 2026-09-17). "Det tar ett
   litet tag innan de syns och sedan kommer de in hårt" — det är INTE
   clip-path-reveal:en ovan (den är redan klar innan man scrollar dit, se
   GL28/no-anim), det är webbläsarens egen lazy-loading: img/video har
   loading="lazy", så själva bildfilen hämtas och avkodas först när den
   närmar sig vyn, och utan en egen transition målas den in i ett enda
   steg. Detta är en SEPARAT fade på bildelementet självt, oberoende av
   clip-path-wrapperns — motion.js sätter .is-media-loaded när img `load`
   eller video `loadeddata` faktiskt fyrar (eller direkt om det redan
   hänt, cache/snabb nätverk). */
.opacity-0.overflow-hidden > .block > img,
.opacity-0.overflow-hidden > .block > video {
  opacity: 0;
  transition: opacity 400ms ease;
}
.opacity-0.overflow-hidden > .block > img.is-media-loaded,
.opacity-0.overflow-hidden > .block > video.is-media-loaded {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .opacity-0.overflow-hidden > .block > img,
  .opacity-0.overflow-hidden > .block > video {
    opacity: 1;
    transition: none;
  }
}
