/* BEVISET — porterad grammatik från helenedelmarmol.com.
   Facit: deras egen stilmall (captured/styles.css) och deras egen JS
   (captured/js/, okomprimerad → porterad rad för rad, GL19).
   Ytan är Marias: Courier Prime är referensens eget typsnitt och fritt (OFL),
   men rubriken sätts i Founders Grotesk eftersom deras ABC Walter Neue är
   licensierad och aldrig får följa med ut. */

@font-face{font-family:"Courier Prime";src:url("fonts/CourierPrime-Regular-latin.woff2") format("woff2");
  font-weight:400;font-style:normal;font-display:swap;
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:"Courier Prime";src:url("fonts/CourierPrime-Regular-latin-ext.woff2") format("woff2");
  font-weight:400;font-style:normal;font-display:swap;
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;}
@font-face{font-family:"Founders Grotesk";src:url("fonts/FoundersGrotesk-Bold.woff2") format("woff2");
  font-weight:700;font-style:normal;font-display:block;}

:root{
  --spacing:.25rem;          /* deras grundenhet, 4px */
  --u:12px;                  /* p-3 = spacing*3 */
  --radius-sm:.25rem;        /* 4px */
  --font-sans:"Founders Grotesk";   /* rubriken läser detta, precis som deras */
  --paper:#fff;
  --ink:#000;                /* AVVIKELSE mot deras #969696 (2,8:1). Svart läser mot loggans grå. */
  --logo-ink:#969696;        /* referensens uppmätta grå */
  --img-bg:#efefee;          /* hdm-grey-100 */
  --h:60svh;                 /* bildhöjd, deras [--h:60svh] */
  --m:calc((100svh - var(--h)) * .5);
}

*{box-sizing:border-box}
html{background:var(--paper);scrollbar-width:none}
html::-webkit-scrollbar{display:none}
body{margin:0;color:var(--ink);background:transparent;
  font-family:"Courier Prime",ui-monospace,monospace;
  font-size:13px;line-height:14px;letter-spacing:-0.025em;}
@media (min-width:100rem){ body{font-size:14px;line-height:15px} }
@media (min-width:120rem){ body{font-size:15px;line-height:16px} }
ul{list-style:none;margin:0;padding:0}
h1,h2,p{margin:0;font-size:inherit;font-weight:400;line-height:inherit}
a{color:inherit;text-decoration:none}
::selection{background:var(--ink);color:var(--paper)}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* RUBRIKLAGRET — WaxTextEffect. LÄNGST BAK av alla lager: negativt z-index i
   rotens staplingskontext. html bär pappret, body är genomskinlig, annars
   målas duken över. Menyns difference-blandning kan då se både rubriken och
   bilderna som bakgrund — hade väggen haft eget z-index vore de osynliga för
   blandningen (GL14). */
.headline{position:fixed;inset:0;z-index:-1;pointer-events:none}
.headline canvas{display:block;width:100%;height:100%}
/* Fallback när WebGL saknas: ordmärket som vanlig text, samma storleksformel. */
.logo-fallback{display:none}
.headline.is-fallback canvas{display:none}
.headline.is-fallback{display:grid;place-items:center;background:var(--paper)}
.headline.is-fallback .logo-fallback{display:block;font-family:"Founders Grotesk",system-ui,sans-serif;
  font-weight:700;font-size:var(--logo-size,10vw);line-height:1;letter-spacing:-0.05em;color:var(--logo-ink);white-space:nowrap;
  text-transform:uppercase}   /* VERSALER (Christoffer 2026-09-16). DOM-texten står kvar "Maria Koshenkova", bara optiken versaliseras — grinden läser textContent. line-height:1: annars är radboxen 14px (body) medan glyfen är ~143px, och det komposit-lagrade elementet under introt klipper toppen. */
.headline .tex{position:absolute;visibility:hidden;pointer-events:none}

/* MENYN — vanlig textfärg igen (Christoffer 2026-08-31). Difference-effekten
   flyttades till ordmärket. Inget z-index, ingen transform och ingen
   opacity-animation här ändå: kollapsen animerar höjd, inte opacity. */
/* Referensens pointer-events-modell: lagret släpper igenom klick, bara
   texten tar emot dem. Annars äter den utfällda menyn hela skärmen. */
.menu{pointer-events:none}
.menu a,.menu .cat,.menu .current,.menu .row{pointer-events:auto}
.menu{position:fixed;inset-inline:0;top:0;
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));column-gap:var(--u);padding:var(--u);
  color:var(--ink)}
/* VITA BOXEN BAKOM NAVET (Christoffer 2026-09-10). Ingen egen div: bakgrunden
   ligger på .menu, vars höjd redan drivs av raderna. Boxen växer och krymper
   därför exakt i takt med att raderna rullar in, utan en andra animation att
   hålla i synk. Bara när man lämnat toppen: i toppen finns inget bakom att
   täcka, och en vit bar mot vitt papper är bara en kant. */
body[data-scrolled="on"] .menu{background:var(--paper)}
.menu{transition:background-color .35s cubic-bezier(.4,0,.2,1)}
@media (min-width:48rem){ .menu{grid-template-columns:repeat(6,minmax(0,1fr))} }
.nav{grid-column:1}
.nav ul{padding-left:var(--u)}
.menu-col{min-width:0}
@media (min-width:48rem){
  .menu-solo{grid-column:2 / span 2}
  .menu-group{grid-column:4 / span 2}
}
.cat{margin-bottom:0;position:relative;width:max-content}

/* KOLLAPS. Höjden animeras, ALDRIG opacity — animerad opacity isolerar
   lagret och slår ut difference-blandningen (GL14). overflow:hidden isolerar
   inte. */
/* HOVER-RUTANS KLIPP (Christoffer 2026-09-16). Rutan sitter på left:-12px, som
   navets prickar, men .rows{overflow:hidden} (som bär kollapsen) klippte bort
   den: fyra rundor grön grind med en osynlig ruta. padding-left flyttar in
   raden 12 px, margin-left drar tillbaka hela boxen 12 px — nettoläget för
   texten är oförändrat, men klipprektangeln når nu 12 px längre vänster och
   rymmer rutan. overflow MÅSTE stå kvar, den bär höjdkollapsen. */
.rows{overflow:hidden;height:var(--rows-h,auto);
  padding-left:12px;margin-left:-12px;
  transition:height .35s cubic-bezier(.4,0,.2,1)}
.menu[data-state="collapsed"] .rows{height:0}
.menu[data-state="collapsed"] .cat{margin-bottom:0}


/* PRICKEN — deras .dot: 6×6, left −12, inset-block 3, radie 1, border 1px transparent */
.dot{position:relative}
.dot::before{content:"";position:absolute;inset-block:3px;left:-12px;width:6px;height:6px;
  background-color:currentColor;border:1px solid transparent;border-radius:1px}
.group:hover .dot::before{background-color:transparent;border-color:transparent}
.dot:hover::before{background-color:currentColor;border-color:transparent}
.hoverdot::before{content:"";position:absolute;inset-block:3px;left:-12px;width:6px;height:6px;
  background-color:transparent;border:1px solid transparent;border-radius:1px}
.hoverdot:hover::before{background-color:currentColor}
/* Hover-markör på ALLA rader (Christoffer 2026-09-10). Markupen ger bara de
   tio dokumenterade raderna .hoverdot, eftersom bara de leder till en bild.
   De övriga fyrtiosju hade ingen hover alls. Samma markör som navets, satt i
   CSS så att build.py och de 57 raderna inte behöver röras. */
.menu .row:not(.dot):not(.hoverdot)::before{content:"";position:absolute;inset-block:3px;left:-12px;
  width:6px;height:6px;background-color:transparent;border:1px solid transparent;border-radius:1px}
.menu .row:not(.dot):not(.hoverdot):hover::before{background-color:currentColor}
/* Deras w-max gäller nav- och listrader, ALDRIG bildlistan (då dör mx-auto). */
.nav li,.menu li{position:relative;width:max-content}
.project{position:relative}
.nav a,.menu a{transition:color .3s cubic-bezier(.4,0,.2,1)}

.menu .rows li{width:max-content;max-width:100%}
.menu .y{display:inline-block;width:58px}

@media (orientation:portrait){
  .menu{grid-template-columns:1fr;row-gap:14px}
  .nav,.menu-col{grid-column:1}
  .menu .rows li{width:auto}
  /* Telefonen: listan får aldrig täcka hela skärmen utan att gå att stänga.
     Utfälld är den rullbar i sig själv, resten av sidan rullar under. */
  .menu[data-state="expanded"] .rows{max-height:calc(100svh - 12rem);overflow-y:auto;scrollbar-width:none}
}

/* SLÖJAN ÄR BORTTAGEN 2026-09-10 (Christoffer). Den tonade hela sidan när
   menyn var utfälld. Nu bär menyn i stället en egen vit box, och strömmen
   under den lämnas orörd. */


/* ══════════════════════════════════════════════════════════════════════
   RUNDA 5, 2026-09-10. Kollapsen bygger om: hopfällt visar navets valda
   post, kategorirubriken och den aktiva utställningens namn under den.
   Utställningsnamnet till höger i navet är borttaget.
   ══════════════════════════════════════════════════════════════════════ */

/* NAVET hopfällt: bara den valda posten syns. Ingen ifylld ruta behövs då,
   den vore den enda posten att markera. */
.nav li{transition:opacity .2s cubic-bezier(.4,0,.2,1)}
.menu[data-state="collapsed"] .nav li:not(.is-current){display:none}
/* Utfälld bär EXHIBITIONS en svart ifylld ruta, som varje annan aktiv rad
   (Christoffer 2026-09-10). Hopfälld är den den enda posten som syns, och då
   markerar rutan ingenting. */
.menu[data-state="expanded"] .nav .is-current::before{content:"";position:absolute;
  inset-block:3px;left:-12px;width:6px;height:6px;background-color:currentColor;
  border:1px solid transparent;border-radius:1px}
.menu[data-state="collapsed"] .nav .is-current::before{content:none}

/* AKTIV UTSTÄLLNING under sin egen kategori. Svart ruta till vänster, samma
   6x6 på -12 som allt annat i den här menyn. Raden finns alltid i flödet,
   även tom, så att den vita boxen håller sin höjd (se nedan). */
.cat-current{position:relative;margin:0;width:max-content;max-width:100%;
  min-height:14px;line-height:14px}
/* Kategorin man är i får en OUTLINE, utställningens namn under den får den
   FYLLDA rutan (Christoffer 2026-09-10). Outline = du är i den här gruppen,
   fylld = det här är verket. */
.cat.dot::before{background-color:transparent;border-color:currentColor}
.cat-current[data-filled]::before{content:"";position:absolute;inset-block:3px;left:-12px;
  width:6px;height:6px;background-color:currentColor;border:1px solid transparent;border-radius:1px}

/* VITA BOXEN: exakt två textrader hög i hopfällt läge, så den inte hoppar
   mellan lägena (Christoffer 2026-09-10). 2 x 14 px rad + 2 x 12 px padding.
   Utfälld växer den med raderna som förut. */
.menu[data-state="collapsed"]{min-height:calc(14px * 2 + var(--u) * 2)}
.rows{margin-top:14px}
.menu[data-state="collapsed"] .rows{margin-top:0}

/* HOVER-MARKÖR: VIT ruta med kant, till skillnad från den aktiva rutan som är
   ifylld svart (Christoffer 2026-09-10). Mot det vita papperet är en helvit
   ruta osynlig, så den får donorns egen kantslot: paper-fyllning, ink-kant. */
/* Hover-markören är en OUTLINE, inte en fylld ruta (Christoffer 2026-09-10).
   Fylld svart ruta = aktiv. Outline = pekaren är här. */
.hoverdot:hover::before,
.menu .row:not(.dot):not(.hoverdot):hover::before,
.cat:hover::before{background-color:transparent;border-color:currentColor}

/* BILDSTRÖMMEN — deras klasser, oförändrad matematik:
   pt-[calc(var(--m)+var(--h)+.75rem)] pb-[var(--m)]
   portrait:mt-[calc(var(--m)-4.5rem)] portrait:[--h:calc((100vw-1.5rem)*.5625)] */
.stream{position:relative;--stream-gap:60px;   /* Christoffer 2026-09-16: nästan dubbla luften (var 32px, ref 12px), bara här */
  /* +16px (Christoffer 2026-09-16): luft mellan navet och första bilden, de satt rakt på varann */
  padding-top:calc(var(--m) + var(--h) + .75rem + 16px);padding-bottom:var(--m)}
.stream ul > * + *{margin-top:var(--stream-gap)}
.project{position:relative;pointer-events:none}
.project > a{display:block;margin-inline:auto;height:var(--h);width:calc(var(--h) * var(--r));
  overflow:clip;background:var(--img-bg);pointer-events:auto}   /* inga rundade horn, Christoffer 2026-09-10 */
.project img{width:100%;height:100%;object-fit:cover;pointer-events:none;display:block}

@media (orientation:portrait){
  .stream{margin-top:calc(var(--m) - 4.5rem);--h:calc((100vw - 1.5rem) * .5625)}
  .project{height:calc(100svh - 9rem)}
  .project > a{--h:calc(var(--w) / var(--r));--m:calc((100svh - var(--h)) * .5);
    position:sticky;top:var(--m);width:var(--w);height:var(--h)}
  .project--wide > a{--w:calc(100vw - 1.5rem)}
  .project--tall > a{--w:calc((200vw/3) - 1.25rem)}
}

@media (prefers-reduced-motion:reduce){
  .nav a,.menu a,.rows,.menu,
  .logo-fallback,.nav li,.menu .cat,.menu .cat-current,.menu .rows li,.project,.project img{transition:none}
  .logo-fallback{animation:none !important}
}

/* ══════════════════════════════════════════════════════════════════════
   WORK.HTML — Faun's Flesh, tombstone först. Tillagt 2026-09-05, i slutet
   (GL34: aldrig regex på det ovan). Grammatiken är referensens
   Information-sida: kontaktblocket fast i kolumn 2–3 (md:fixed top-0,
   col-start-2 col-span-2), innehållet rullar under. Länkar i referensens
   blå (#3333ff, Information-sidans enda färg), oskrivet påstående i svart. */
:root{ --link:#3333ff }   /* hdm-blue, 8,6:1 mot papper */

/* Tombstonen. Fast i kolumn 2–3 från 48rem, samma sexkolumnsgrid som menyn. */
.sheet{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));column-gap:var(--u);padding:var(--u);
  pointer-events:none}
.tombstone{grid-column:1 / -1;pointer-events:auto;min-width:0}
@media (min-width:48rem){
  /* z-index 1: bilderna kommer senare i DOM och skulle annars målas ÖVER
     tombstonen. Tombstonen står först i DOM med flit (läsordningen är tesen). */
  .sheet{position:fixed;inset-inline:0;top:0;z-index:1;grid-template-columns:repeat(6,minmax(0,1fr))}
  .tombstone{grid-column:2 / span 2}
}
/* Rad = etikett + värde. Etikettkolumnen 19 tecken à 7,47 px (DESIGN.md §3),
   värdet radbryter under sig självt, aldrig under etiketten. */
.tombstone li{display:grid;grid-template-columns:142px minmax(0,1fr);column-gap:var(--u)}
.tombstone .k{white-space:nowrap}
.tombstone a{color:var(--link)}
.tombstone a:hover{text-decoration:underline}   /* deras .prose a:hover */

/* Bildströmmen — samma matematik som index (.stream/.project), egen klass
   så figure + kreditrad får plats utan att röra indexreglerna. */
.shots{position:relative;
  padding-top:calc(var(--m) + var(--h) + .75rem);padding-bottom:var(--m)}
.shots ul > * + *{margin-top:var(--u)}
.shot{position:relative;pointer-events:none}
.shot figure{margin:0;width:calc(var(--h) * var(--r));margin-inline:auto}
.shot a{display:block;height:var(--h);width:100%;
  overflow:clip;background:var(--img-bg);pointer-events:auto}   /* inga rundade horn (Christoffer 2026-09-10) */
.shot img{width:100%;height:100%;object-fit:cover;pointer-events:none;display:block}
/* Kreditraden: referensen saknar den (DESIGN.md §10), konstruerad i samma
   13/14 som allt annat, 12 px under bilden, vänsterkant = bildens. */
.credit{margin-top:var(--u);pointer-events:auto}

@media (orientation:portrait){
  .shots{margin-top:calc(var(--m) - 4.5rem);--h:calc((100vw - 1.5rem) * .5625)}
  .shot{height:calc(100svh - 9rem)}
  .shot figure{--w:calc(100vw - 1.5rem);--h:calc(var(--w) / var(--r));
    --m:calc((100svh - var(--h) - 26px) * .5);   /* 26 = kreditradens 12 + 14 */
    position:sticky;top:var(--m);width:var(--w)}
  .shot a{height:var(--h)}
}

/* Telefon: tombstonen ligger i flödet under den fasta naven (54 px + 12).
   Referensens mobil lägger blocket i kolumn 2 av 2; 177 px räcker inte för
   raderna, så samma avvikelse som index (R2-avvikelse 3): full bredd. */
@media (max-width:47.99rem){
  .sheet{padding-top:calc(54px + var(--u))}
  /* Ordmärket finns inte under md hos referensen (hidden md:block). */
  /* .is-fallback sätter display:grid (reservtext utan WebGL). Utan att den
     nämns här vinner den, och ordmärket syns på telefon i Safari. */
  .headline, .headline.is-fallback{display:none}
  body[data-page="work"] .shots{padding-top:calc(var(--u) * 2)}
}

/* BILDSTRÖMMEN: storleken följer avståndet till viewportens mitt.
   Lagen är uppmätt på tylermitchell.co/films, mobil vy, 2026-09-10, genom att
   följa EN bild genom hela svepet i 20 px-steg (37 mätpunkter):

       s = clamp(0.466, 1, 1.02 − |d| / viewportHöjd)

   BÄRAREN BYTTES 2026-09-10, andra försöket. Först drevs layoutmåtten
   (height/width), precis som referensen gör. Det gav exakt luft men hackade:
   varje bildruta reflowade ett 6 000 px dokument med tio bilder, och två pass
   per ram krävdes för att skalan skulle konvergera, alltså upp till tjugo
   framtvingade layouter per ram.

   Nu bär TRANSFORMEN skalan, och positionen räknas i JS:
     - varje li behåller sin oförändrade plats i flödet: höjd 60svh, luft 12
       px. Dokumenthöjden ändras därför aldrig och scrollen kan inte jittra.
     - JS skriver translate3d + scale per bild, med luften inräknad, så det
       VISUELLA mellanrummet är exakt 12 px oavsett skala.
   Allt ligger på compositorn, inga layoutläsningar per bild. */
.project > a{display:block;margin-inline:auto;height:var(--h);width:calc(var(--h) * var(--r));
  overflow:clip;background:var(--img-bg);pointer-events:auto;
  transform-origin:50% 50%;will-change:transform;backface-visibility:hidden}
@media (prefers-reduced-motion:reduce){ .project > a{transform:none !important} }

/* ══════════════════════════════════════════════════════════════════════
   LADDSEKVENS (R2 BEVISET, 2026-09-16, ca 4 s). Styrd av body[data-intro],
   satt av inline-skriptet i index.html:
     "play" (fördolt, vit yta) → "run" (kör övergångarna) → "done".
   Övergångarna bor här, inte i JS. Fördolt läge ligger på [data-intro="play"];
   när skriptet flippar bort "play" animeras varje egenskap till sitt normalläge
   med sin egen delay, vilket GER sekvensen:
     steg 1  vit yta hålls              0 → .7 s, inget syns (cinematisk paus)
     steg 2  loggan tonar in HELSVART   opacity delay .7 s / .5 s  → svart 1.2 s
     steg 3  HÅLL på svarta loggan       1.2 → 2 s, inget annat syns
     steg 4  resten laddas in medan      nav + kategori + aktiv utställning +
             loggan bleknar till grå     rader: delay 2 s (+ --i×.03 s), .4 s
                                         logga color: delay 2 s / 1.6 s (#000→grå)
     steg 5  första bilden reser in      .project opacity + IMG translateY,
                                         delay 3.4 s, .5 s

   Ordningen är hans (2026-09-16): loggan FÖRST och ensam, den aktiva
   utställningens namn (.cat-current, "2025 Sophienholm…") kommer in MED navet,
   aldrig före. Därför döljs .cat-current under play precis som raderna.

   TRE regler, hårt lärda:
   1. ALDRIG opacity på .rows eller .menu (GL14: isolerar difference-blandningen).
      Varje RAD animeras för sig, aldrig containern.
   2. Bilden bär translateY på IMG, inuti a:s overflow:clip — ALDRIG på li eller
      a. Både grinden och measureSlots (site.js) mäter li/a-rekten; en transform
      där förskjuter hela strömmen och firstShotTop-grinden faller. a:s opacity
      lämnas orörd (grind "INGEN nedtoning"): opaciteten tonas på li.
   3. Under 48rem är loggan display:none — steg 2 no-op:ar på telefon av sig
      självt. reduced-motion: inline-skriptet sätter "done" direkt, inget döljs. */
body[data-intro="play"] .logo-fallback{opacity:0;color:#000}
body[data-intro="play"] .nav li,
body[data-intro="play"] .menu .cat,
body[data-intro="play"] .menu .cat-current,
body[data-intro="play"] .menu .rows li{opacity:0}
body[data-intro="play"] .project{opacity:0}
body[data-intro="play"] .project img{transform:translateY(30px)}

/* Loggan drivs av en KEYFRAME, inte en transition-delay. Grå-färgen bor på
   .headline.is-fallback (klassen sätts av site.js vid osäker tidpunkt), och en
   transition-from race:ar mot den: loggan visade sig redan grå. Keyframen sätter
   färgen explicit i varje steg och vinner över is-fallback-racet:
     .7 s vit → tonar in HELSVART → håller svart → grånar när resten laddas in.
   Gäller bara index-introt: body:not([data-page]) utesluter work.html, och
   run/done (aldrig play) kör den EN gång utan omstart. reduced-motion: animation
   av nedan, då syns loggan direkt i sin grå vila. */
@keyframes introLogo{
  0%  {opacity:0;color:#000}          /* vit-hold ligger i animation-delay */
  14% {opacity:1;color:#000}          /* intonad, svart (~1.2 s) */
  37% {opacity:1;color:#000}          /* svart hålls (~2.0 s) */
  83% {opacity:1;color:var(--logo-ink)} /* grånat (~3.6 s) */
  100%{opacity:1;color:var(--logo-ink)}
}
body:not([data-page])[data-intro="run"] .logo-fallback,
body:not([data-page])[data-intro="done"] .logo-fallback{animation:introLogo 3.5s ease .7s both}

.nav li,.menu .cat,.menu .cat-current{transition:opacity .4s ease;transition-delay:2s}
.menu .rows li{transition:opacity .4s ease;
  transition-delay:calc(2s + var(--i,0) * .03s)}
.project{transition:opacity .5s ease;transition-delay:3.4s}
.project img{transition:transform .5s ease;transition-delay:3.4s}
