/* ==========================================================================
   HVALEN STUDIO — designsystem
   Alt av farger, typografi og spacing styres av variablene i :root.
   Endre der, så følger hele siden etter.
   ========================================================================== */

:root {
  /* Farger — hentet fra logo og profil */
  --cream:      #FFFFF5;
  --cream-warm: #FFFFC4;
  --blue:       #0A39BC;
  /* Store blå flater (bolker, footer). Logoblå i full bredde leser lysere
     og flatere enn i logoen, så flatene går et hakk mørkere — samme kulør,
     bare lavere lyshet. Tekst, logo og knapper beholder --blue. */
  --blue-flate: #082C93;
  --blue-deep:  #0B005E;
  --blue-bright:#0059FF;
  --red:        #EA2D2D;
  --ink:        #0A39BC;                  /* = --blue, logofargen */
  --ink-soft:   rgba(10, 57, 188, 0.75);   /* mer dekkevne enn før, den lysere blåfargen trenger det */
  --line:       rgba(10, 57, 188, 0.16);
  --black:      #0B0B14;

  /* Typografi */
  --font: "Inter Tight", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  /* Fluid typeskala */
  --fs-display: clamp(3.2rem, 11vw, 11rem);
  /* Gulvet er hevet fra 2,6 rem: under ~680 px er det gulvet som gjelder,
     og der ble sidetittelen for spinkel mot den brede skjermen. Stjerna i
     sidehodet måles mot den samme verdien og følger etter. */
  --fs-h1:      clamp(3.4rem, 7.5vw, 6.5rem);
  --fs-h2:      clamp(2rem, 4.6vw, 4rem);
  --fs-h3:      clamp(1.35rem, 2.1vw, 2rem);
  --fs-lead:    clamp(1.1rem, 1.55vw, 1.5rem);
  --fs-body:    clamp(1rem, 1.1vw, 1.125rem);
  --fs-small:   0.875rem;
  --fs-label:   0.75rem;

  /* Layout */
  --pad:        clamp(1.25rem, 5vw, 5rem);
  --gap:        clamp(1rem, 2.2vw, 2rem);
  --section:    clamp(4.5rem, 11vh, 9rem);
  --maxw:       1600px;
  --radius:     14px;               /* bilder og andre indre flater */
  --radius-lg:  24px;               /* kort og felter som rammer inn noe */
  /* Svak blå skygge under alle avrundede felter — samme blåfarge som resten
     av paletten, ikke grått, så den legger seg som en tone og ikke som skitt. */
  --shadow:     0 6px 16px -8px color-mix(in srgb, var(--blue) 34%, transparent);
  /* Løftet variant — brukes når et helt kort heves på hover. */
  --shadow-lift: 0 10px 24px -12px color-mix(in srgb, var(--blue) 40%, transparent);
  /* Under farget flate i full bredde. Negativ spredning holder den fra å
     lekke ut over overkanten. */
  --shadow-band: 0 20px 34px -22px color-mix(in srgb, var(--blue) 65%, transparent);
  /* Panelflate. Går svakt mot blått, ikke mot hvitt: krem ligger allerede på
     96 % lyshet, så et lysere felt gir bare 6–10 trinn i én kanal og
     forsvinner. Denne skiller seg i alle tre kanalene og legger et hint av
     kulde mot den varme kremen, uten å bli et grått felt. */
  --boks:       color-mix(in srgb, var(--blue) 4%, var(--cream));
  --nav-h:      112px;

  /* Trappa av blåtoner nedover forsiden. Verdiene bor her fordi overgangene
     mellom seksjonene er gradienter som må ende på nøyaktig fargen under —
     hardkodet ville de sklidd fra hverandre ved neste justering. */
  /* Frostglasset i nav-baren. Brukes også som ramme rundt kortene på hover,
     så de to flatene holder nøyaktig samme tone. */
  --frost:      color-mix(in srgb, var(--cream) 78%, transparent);


  --ease:       cubic-bezier(0.22, 1, 0.36, 1);
}

/* --------------------------------------------------------------- Reset --- */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--cream);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--fs-body);
  line-height: 1.55;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, video, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

h1, h2, h3, h4 {
  margin: 0;
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 0.95;
  text-wrap: balance;
}

p { margin: 0; text-wrap: pretty; }

::selection { background: var(--red); color: var(--cream); }

:focus-visible {
  outline: 3px solid var(--red);
  outline-offset: 3px;
  border-radius: 2px;
}

/* -------------------------------------------------------------- Layout --- */

.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--pad);
}

/* Nav-baren er sticky og ligger over innholdet. Uten dette havner alt man
   hopper til via en #-lenke rett bak baren. Gjelder alle elementer med id,
   for scroll-margin gjør ingenting før noe faktisk scroller dit. */
[id] { scroll-margin-top: calc(var(--nav-h) + clamp(1rem, 3vw, 2.5rem)); }

.section { padding-block: var(--section); }

/* Blå bolk i full bredde. Seksjonen ligger utenfor .wrap — den flyter kant
   til kant — og innholdet får sin egen .wrap inni. Alt som ellers er blått
   på kremt må snus her. */
.section--blue {
  background: var(--blue-flate);
  color: var(--cream);
  /* Skygge begge veier, utenfor kanten: oppover legger den seg på det
     kremhvite over bolken, nedover på det under. */
  box-shadow:
    0 -16px 28px -20px color-mix(in srgb, var(--blue) 60%, transparent),
    var(--shadow-band);

  /* Mindre luft over overskriften enn en vanlig seksjon — bolken er farget,
     så den trenger ikke like mye rom for å skille seg ut. */
  padding-top: clamp(2.5rem, 6vh, 4.5rem);
}

/* «Hva gjør vi?» er lys igjen. Bolken over er sort, så skillet
   ligger i skyggen den kaster nedover — se .section--musikk. Her trengs
   bare litt mindre luft i toppen enn en vanlig seksjon, siden den mørke
   kanten over allerede markerer starten. */
.section--tjenester {
  /* Luften i toppen står i en variabel fordi stjerna under må vite hvor
     langt ned overskriften faktisk begynner. */
  --tj-topp: clamp(4.5rem, 12vh, 8.5rem);
  padding-top: var(--tj-topp);
}

/* Stjerna som krysser skjøten står til høyre, løsrevet fra overskriften.
   .wrap må posisjoneres for at den skal kunne henge på innholdskanten —
   right: var(--pad) treffer nøyaktig der teksten slutter, siden wrapperen
   har samme polstring.

   Regnestykket for høyden: .wrap begynner --tj-topp under seksjonskanten,
   så et løft på den avstanden pluss halve stjerna setter sentrum i skjøten.
   Bildet er 564 × 588, altså litt høyere enn bredt — derfor 0.52 og ikke
   0.5 av bredden.

   top og ikke transform: .star spinner allerede med en transform, og en ny
   ville overskrevet animasjonen. z-index må overgå musikkbolkens 1, ellers
   maler den blå flaten over stjerna i stedet for under. */
.section--tjenester > .wrap { position: relative; }

/* .star.kantstjerne og ikke bare .kantstjerne: regelen står foran .star i
   fila, og med lik spesifisitet vinner den som kommer sist. Da slo .star sin
   bredde og omdreiningstid gjennom, stjerna ble liten — mens løftet fortsatt
   ble regnet ut fra den store verdien, så den endte midt inne i det blå. */
.star.kantstjerne {
  --kant-str: clamp(88px, 12vw, 176px);

  position: absolute;
  right: var(--pad);
  top: calc(-1 * (var(--tj-topp) + var(--kant-str) * 0.52));
  width: var(--kant-str);
  z-index: 2;

  /* Saktere enn de små stjernene: samme omdreiningstid på en stor flate
     leser som mye raskere. */
  animation-duration: 30s;
}

.section--blue .section-head {
  border-bottom-color: color-mix(in srgb, var(--cream) 26%, transparent);
}

.section--blue .section-head .count,
.section--blue .card__tag {
  color: color-mix(in srgb, var(--cream) 72%, transparent);
}

/* ----------------------------------------------------- Musikkbolken --- */
/* Samme oppbygning som .section--blue: flaten går kant til kant, så .wrap
   ligger inni. Nå i samme logoblå som bolken over — det som skiller dem er
   ikke fargen, men at denne avsluttes som et kort. */

.section--musikk {
  position: relative;

  /* Sort, ikke blå: musikken skal leses som sin egen bolk, ikke som
     fortsettelsen av profilene over. Skjøten er en bølge — se ::before. */
  background: var(--black);
  color: var(--cream);

  /* Underkanten møter en lys flate, og skyggen nedover er hele skillet
     mellom dem: bolken leser som et lag som ligger oppå det kremhvite.
     z-index må til — uten den maler bakgrunnen til seksjonen under over
     skyggen, siden den kommer senere i dokumentet. */
  z-index: 1;
  box-shadow: 0 18px 30px -14px color-mix(in srgb, var(--black) 70%, transparent);

  /* Avrundet bare nedad: toppen flukter med den blå bolken over.
     Underkanten er kortkanten. Både bakgrunnen og skyggen følger radien av
     seg selv — ingen overflow: hidden nødvendig, innholdet ligger i .wrap
     med polstring og kommer aldri nær hjørnene. */
  border-bottom-left-radius: var(--radius-lg);
  border-bottom-right-radius: var(--radius-lg);
}

/* Bølgekant i toppen av den sorte bolken, i stedet for en rett linje mot
   det blå. Samme bølge som nav-baren, bare fylt under linja og høyere
   utslag, og den driver sakte med maskDrift. Ligger over overkanten
   (bottom: 100 %) og spiser seg inn i den blå bolken, så selve
   seksjonsgrensen er skjult bak sort. -1 px overlapp mot halvpiksel-sømmer. */
.section--musikk::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(100% - 1px);
  height: clamp(28px, 4.5vw, 64px);
  background: var(--black);
  pointer-events: none;

  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 800 100' preserveAspectRatio='none'%3E%3Cpath fill='%23fff' d='M0,52 c25,-28 75,-28 100,0c25,28 75,28 100,0c25,-28 75,-28 100,0c25,28 75,28 100,0c25,-28 75,-28 100,0c25,28 75,28 100,0c25,-28 75,-28 100,0c25,28 75,28 100,0 L800,100 L0,100 Z'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 800 100' preserveAspectRatio='none'%3E%3Cpath fill='%23fff' d='M0,52 c25,-28 75,-28 100,0c25,28 75,28 100,0c25,-28 75,-28 100,0c25,28 75,28 100,0c25,-28 75,-28 100,0c25,28 75,28 100,0c25,-28 75,-28 100,0c25,28 75,28 100,0 L800,100 L0,100 Z'/%3E%3C/svg%3E");
  -webkit-mask-size: 200% 100%;
          mask-size: 200% 100%;
  -webkit-mask-repeat: repeat-x;
          mask-repeat: repeat-x;

  animation: maskDrift 24s linear infinite;
}

/* Uten mask-støtte: ingen bølge, bare den rette kanten. */
@supports not ((mask-image: linear-gradient(#000, #000)) or (-webkit-mask-image: linear-gradient(#000, #000))) {
  .section--musikk::before { display: none; }
}

/* Klippene står på en mørk flate, så --shadow (bygget av --blue) forsvinner.
   Denne må være mørkere enn underlaget for å synes. */
.section--musikk .card__media {
  box-shadow: 0 18px 38px -18px color-mix(in srgb, var(--black) 75%, transparent);
  transition: box-shadow 0.45s var(--ease);
}

/* Glorie på hover: skygge uten forskyvning legger seg jevnt hele veien rundt
   og leser som lys, ikke som tyngde. Den røde gløden tegner seg mot
   det sorte; den vanlige skyggen ligger under og holder klippet på plass.
   Regelen står etter nøytraliseringen av kortets hover, som slår av
   box-shadow på selve kortet — her er den på mediefeltet i stedet. */
@media (hover: hover) and (pointer: fine) {
  .section--musikk .card:hover .card__media {
    box-shadow:
      0 0 0 1px color-mix(in srgb, var(--red) 75%, transparent),
      0 0 44px 8px color-mix(in srgb, var(--red) 40%, transparent),
      0 18px 38px -18px color-mix(in srgb, var(--black) 75%, transparent);
  }
}

/* Ingen ramme rundt klippet: uten polstring flukter videokanten med .wrap,
   altså samme linje som overskriften over og seksjonene under. Kortet har
   heller ingen hover-tilstand — bare teksten oppå reagerer. */
.section--musikk .card--wide { padding: 0; }

.section--musikk .card--wide:hover { transform: none; }
.section--musikk .card--wide::before { display: none; }

/* To og to i bredden. Den faste høyden fra .card--wide er laget for full
   bredde og blir et høyt tårn i en halv kolonne, så klippene holder 16:9
   her i stedet. Navnet krymper med feltet. */
.section--musikk .card--wide .card__media {
  height: auto;
  aspect-ratio: 16 / 9;
}

.section--musikk .card__over b { font-size: clamp(1.9rem, 3.4vw, 3.2rem); }

/* Alltid to og to, også på bredskjerm. auto-fit ga tre i bredden der, og
   da ble den fjerde stående alene på en ny rad. Én kolonne på mobil. */
.section--musikk .grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

@media (max-width: 700px) {
  .section--musikk .grid--2 { grid-template-columns: minmax(0, 1fr); }
}

/* Plassholderen er laget for krem bakgrunn og lyser som et hull mot det
   sorte. Her får den en mørk flate med samme striper. */
.section--musikk [data-placeholder] {
  background:
    repeating-linear-gradient(45deg,
      transparent 0 14px,
      color-mix(in srgb, var(--cream) 4%, transparent) 14px 28px),
    color-mix(in srgb, var(--cream) 6%, var(--black));
}

/* Kortene løftes mot den lyse panelflaten. Da må teksten snu samtidig —
   krem tekst på en nesten hvit flate ville forsvunnet. */
.section--blue .card::before {
  background: var(--boks);
  /* --shadow-lift er bygget av --blue og forsvinner mot en blå flate.
     Her må skyggen være mørkere enn underlaget for å synes i det hele tatt. */
  box-shadow: 0 16px 32px -14px color-mix(in srgb, var(--blue-deep) 85%, transparent);
}
.section--blue .card:hover .card__title { color: var(--ink); }
.section--blue .card:hover .card__tag { color: var(--ink-soft); }

/* Pilene må snu mot det blå: blå ring på blått er usynlig. */
.section--blue .slider__btn {
  border-color: var(--cream);
  color: var(--cream);
}

.section--blue .slider__btn:hover:not(:disabled) {
  background: var(--cream);
  border-color: var(--cream);
  color: var(--ink);
}

.section--tight { padding-block: calc(var(--section) * 0.55); }


/* Seksjonsoverskrift med hånd­tegnet stjerne */
.section-head {
  display: flex;
  align-items: baseline;
  gap: 0.7em;
  margin-bottom: clamp(2rem, 4vw, 3.5rem);
  border-bottom: 1px solid var(--line);
  padding-bottom: 1rem;
}

/* Uten strek under. Sliderseksjonene får det samme via [data-slider]. */
.section-head--ren { border-bottom: 0; }

.section-head h2 { font-size: var(--fs-h2); }

.section-head .count {
  margin-left: auto;
  font-size: var(--fs-label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* Stjerna skal veie opp mot overskriften ved siden av, så den måles mot
   --fs-h2 og ikke mot brødteksten (som er det em ville gitt her). */
.star {
  width: calc(var(--fs-h2) * 0.64);
  flex: none;
  align-self: center;
  animation: spin 18s linear infinite;
}

@keyframes spin { to { transform: rotate(360deg); } }

.eyebrow {
  font-size: var(--fs-label);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--red);
  margin-bottom: 1.2rem;
}

.lead {
  font-size: var(--fs-lead);
  line-height: 1.4;
  max-width: 30ch;
  letter-spacing: -0.015em;
}

/* ----------------------------------------------------------- Navigasjon --- */

.nav {
  position: sticky;
  top: 0;
  z-index: 100;
  background: none;   /* bakgrunnen ligger i .nav__bg, som er maskert */
  transition: transform 0.45s var(--ease);

  /* Vannlinja ligger på 87 % med ±11 % utslag. Målestokken er «Ta kontakt»-
     pillen, som er ~39 px høy — altså nesten dobbelt så høy som en vanlig
     navlenke. Med disse tallene klarerer bølgetoppen den med ca. 10 px.
     Maska bor her, ikke på .nav__bg, fordi skyggelaget under bruker samme
     bølge. */
  --wave-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 800 100' preserveAspectRatio='none'%3E%3Cpath fill='%23fff' d='M0,87 c25,-11 75,-11 100,0c25,11 75,11 100,0c25,-11 75,-11 100,0c25,11 75,11 100,0c25,-11 75,-11 100,0c25,11 75,11 100,0c25,-11 75,-11 100,0c25,11 75,11 100,0 L800,0 L0,0 Z'/%3E%3C/svg%3E");

  /* Samme bølge, mykt uttonet: feGaussianBlur inne i SVG-en gjør maska
     gradvis gjennomsiktig, så skyggen starter på full styrke ved vannlinja
     og dør ut noen piksler under. Blur i CSS ville ikke hjulpet — filter
     kjører før maske, så kanten hadde blitt like skarp likevel.
     Tegnet fra x=-200 til x=1000, altså to bølgelengder utenfor flisa på
     hver side, ellers hadde uttoningen laget skjøter i gjentaket. */
  --wave-shadow-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 800 100' preserveAspectRatio='none'%3E%3Cdefs%3E%3Cfilter id='f' x='-50%25' y='-50%25' width='200%25' height='200%25'%3E%3CfeGaussianBlur stdDeviation='4'/%3E%3C/filter%3E%3C/defs%3E%3Cpath fill='%23fff' filter='url(%23f)' d='M-200,87 c25,-11 75,-11 100,0c25,11 75,11 100,0c25,-11 75,-11 100,0c25,11 75,11 100,0c25,-11 75,-11 100,0c25,11 75,11 100,0c25,-11 75,-11 100,0c25,11 75,11 100,0c25,-11 75,-11 100,0c25,11 75,11 100,0c25,-11 75,-11 100,0c25,11 75,11 100,0 L1000,0 L-200,0 Z'/%3E%3C/svg%3E");
}

/* Ett lag, ikke to. Det ble prøvd å dele baren i en stillestående frostet
   flate og et tynt bølgebånd, for å slippe å male om hele baren for hvert
   bilde. Men to lag med hvert sitt backdrop-filter regner uskarpheten hver
   for seg og klamrer til hver sin kant i skjøten — det gir en synlig
   hårstrek tvers over baren uansett hvor likt de ellers er stilt inn.

   Kostnaden er derfor tilbake: mask-position males om per bilde, oppå et
   lag med backdrop-filter. Hakkingen ved sidelasting kom uansett mest fra
   at hver hover-effekt hadde sin egen evige animasjonsløkke i JS — se
   js/main.js, der de nå bare kjører når noe faktisk beveger seg. */
.nav__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--frost);
  backdrop-filter: blur(16px) saturate(1.5);
  -webkit-backdrop-filter: blur(16px) saturate(1.5);

  -webkit-mask-image: var(--wave-mask);
          mask-image: var(--wave-mask);
  -webkit-mask-size: 200% 100%;
          mask-size: 200% 100%;
  -webkit-mask-repeat: repeat-x;
          mask-repeat: repeat-x;

  animation: maskDrift 15s linear infinite;
}

/* Skjult mens man scroller nedover (se main.js). Litt lenger enn egen høyde,
   så skyggen under bølgen også forsvinner. Vises-tilstanden er transform:
   none, ikke translateY(0): en transform gjør .nav til containing block for
   den faste mobilmenyen, og da ville den blitt klippet. */
.nav.nav--skjult { transform: translateY(calc(-100% - 12px)); }

/* Svak blå skygge under bølgekanten. Eget lag, forskjøvet noen piksler ned
   og maskert med den uttonede bølgen — drop-shadow rett på .nav__bg går
   ikke, for filter gjør elementet til backdrop-root og slår ut
   frostglasset. Samme drift, så skyggen følger kanten.
   z-index -1 legger den bak flaten, men fortsatt over innholdet på sida. */
.nav::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--blue);
  opacity: 0.1;
  transform: translateY(4px);
  pointer-events: none;

  -webkit-mask-image: var(--wave-shadow-mask);
          mask-image: var(--wave-shadow-mask);
  -webkit-mask-size: 200% 100%;
          mask-size: 200% 100%;
  -webkit-mask-repeat: repeat-x;
          mask-repeat: repeat-x;

  animation: maskDrift 15s linear infinite;
}

/* Flisa er dobbelt så bred som elementet og inneholder fire bølgelengder.
   0 % → 100 % forskyver nøyaktig én elementbredde, altså to bølgelengder,
   og løkken er sømløs. */
@keyframes maskDrift {
  from { -webkit-mask-position:   0% 0; mask-position:   0% 0; }
  to   { -webkit-mask-position: 100% 0; mask-position: 100% 0; }
}

/* Nettlesere uten mask-støtte: rett underkant i stedet for bølge.
   Bedre enn en usynlig navbar. */
@supports not ((mask-image: linear-gradient(#000, #000)) or (-webkit-mask-image: linear-gradient(#000, #000))) {
  .nav__bg { animation: none; }
  .nav::after { display: none; }
}


.nav__inner {
  position: relative;
  z-index: 2; /* over både flaten og skummet */
  display: flex;
  align-items: center;
  gap: var(--gap);
  height: var(--nav-h);
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--pad);
}

/* --------------------------------------------------- Bølger i nav-baren ---
   To lag som sklir hver sin vei i ulikt tempo — det gir dybde og gjør at
   mønsteret aldri ser ut til å gjenta seg. Hver SVG er 200 % bred og
   inneholder fire bølgelengder; å flytte den -50 % tilsvarer nøyaktig to
   bølgelengder, så løkken er sømløs.                                      */

/* Hvalen flyter — vugger i takt med bølgene under seg. Vuggingen ligger på
   lenka og saltoen på bildet inni: to animasjoner kan ikke dele samme
   transform, og da ville den ene slått ut den andre. Slik legger de seg
   oppå hverandre i stedet, og hvalen vugger videre mens den snurrer. */
.nav__logo {
  flex: none;
  transform-origin: 50% 90%;
  animation: floatOnWave 6s ease-in-out infinite;
}

.nav__logo img {
  display: block;
  height: 28px;
  width: auto;
  transform-origin: 50% 60%;
}

/* Baklengs salto: mot klokka, med et hopp så den får bue. Klassen settes
   fra js/main.js ved hover og tas av først når animasjonen er ferdig — med
   :hover ville saltoen blitt kuttet midt i om musa forlot logoen.

   Mykningen ligger i vinklene, ikke i tidskurven. Setter man ease-in-out på
   en animasjon med flere steg, mykes hvert delintervall for seg, og da
   bremser og akselererer rotasjonen åtte ganger underveis — det er hakking.
   Her går tida lineært mens vinklene følger en jevn S-kurve, altså én
   sammenhengende oppspinning og nedbremsing. Hoppet følger en sinusbue.

   will-change gjør bildet til et eget lag før bevegelsen starter, så SVG-en
   ikke må tegnes om for hver vinkel. */
.nav__logo img.salto {
  animation: baklengsSalto 0.75s linear;
  will-change: transform;
}

@keyframes baklengsSalto {
  0%     { transform: translateY(0)      rotate(0deg); }
  12.5%  { transform: translateY(-4.6px) rotate(-15.5deg); }
  25%    { transform: translateY(-8.5px) rotate(-56.2deg); }
  37.5%  { transform: translateY(-11.1px) rotate(-113.9deg); }
  50%    { transform: translateY(-12px)  rotate(-180deg); }
  62.5%  { transform: translateY(-11.1px) rotate(-246.1deg); }
  75%    { transform: translateY(-8.5px) rotate(-303.8deg); }
  87.5%  { transform: translateY(-4.6px) rotate(-344.5deg); }
  100%   { transform: translateY(0)      rotate(-360deg); }
}

@keyframes floatOnWave {
  0%, 100% { transform: translateY(0)     rotate(-2.2deg); }
  25%      { transform: translateY(-3px)  rotate(0.4deg); }
  50%      { transform: translateY(1.5px) rotate(2.2deg); }
  75%      { transform: translateY(-2px)  rotate(0.4deg); }
}

.nav__links {
  display: flex;
  gap: clamp(1rem, 2.4vw, 2.4rem);
  margin-left: auto;
  align-items: center;
}

.nav__links a {
  /* Egen farge, ikke arvet: baren har sin egen lyse flate, og en side som
     setter en annen tekstfarge på <body> ville ellers slukket lenkene. */
  color: var(--ink);
  font-size: var(--fs-small);
  font-weight: 600;
  letter-spacing: -0.01em;
  position: relative;
  padding-block: 0.35em;
}

/* Understrek som gror ut fra venstre */
.nav__links a::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 2px;
  background: var(--red);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.4s var(--ease);
}

.nav__links a:hover::after,
.nav__links a[aria-current="page"]::after { transform: scaleX(1); }

.nav__links a[aria-current="page"] { color: var(--red); }

.nav__cta {
  border: 1.5px solid var(--ink);
  border-radius: 100px;
  padding: 0.5em 1.1em !important;
  transition: background 0.3s var(--ease), color 0.3s var(--ease);
}
.nav__cta::after { display: none; }
.nav__cta:hover { background: var(--ink); color: var(--cream); }

.nav__toggle { display: none; }

/* --------------------------------------------------------------- Hero --- */

/* Heroen trekkes opp bak nav-baren, så videoen starter helt øverst i
   vinduet. Da har den maskerte flaten noe å være gjennomskinnelig mot,
   og bølgekanten leser fra første piksel i stedet for å begynne under
   en heldekkende krembjelke. Gjelder kun forsiden — på undersidene
   ville det samme skjult overskriften. */
.hero {
  position: relative;
  margin-top: calc(var(--nav-h) * -1);
  min-height: min(100svh, 940px);
  display: grid;
  align-items: end;
  overflow: hidden;
  background: var(--black);
  color: var(--cream);
}

.hero__media {
  position: absolute;
  inset: 0;
}

.hero__media video,
.hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Blått som toner ut oppover. Bunnen møter det blå båndet under heroen,
   så videoen glir rett over i seksjonen etter — og overskriften får noe
   å stå mot uansett hva som er i bildet. */
.hero__media::after {
  content: "";
  position: absolute;
  inset: 0;
  /* --blue-flate, ikke --blue: bunnen må ende på nøyaktig samme farge som
     bolken under, ellers blir skjøten en synlig kant. */
  /* Kort uttoning: helt blått bare helt nederst (for skjøten), og borte
     før midten, så videoen får stå i sine egne farger. */
  background: linear-gradient(to top,
    var(--blue-flate) 0%,
    color-mix(in srgb, var(--blue-flate) 55%, transparent) 12%,
    color-mix(in srgb, var(--blue-flate) 15%, transparent) 30%,
    transparent 48%);
}

.hero__inner {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding: var(--pad);
  padding-bottom: clamp(2.5rem, 6vh, 5rem);
}

/* Raden fyller hele innholdsbredden, og space-between skyver hvalen ut til
   høyre kant — samme linje som seksjonene lenger nede på sida. Derfor faste
   andeler i stedet for at delene vokser og fyller.

   41 % og 29 % er valgt slik at de blir like høye: ordmerket er 2,62:1 og
   hvalen 1,85:1, så teksten må være rundt 1,4 ganger bredere for å nå samme
   høyde. Den ligger et hakk under, fordi to rader bokstaver leser høyere
   enn en heldekkende form.

   min-width: 0 er nødvendig: flex-elementer har min-width: auto, altså sin
   egen innholdsbredde, og for et bilde er det SVG-ens iboende piksler. Uten
   det kan ingen av delene krympe under originalstørrelsen. */
.hero__topp {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: clamp(1.5rem, 5vw, 5.5rem);
  width: 100%;
}

.hero__title { flex: 0 1 41%; min-width: 0; margin: 0; }
.hero__hval  { flex: 0 1 29%; min-width: 0; animation-delay: 0.12s; }

.hero__title img,
.hero__hval {
  display: block;
  width: 100%;
  height: auto;
  animation: merkeInn 1.1s var(--ease) backwards;
}

/* Bildet inni spanen. Bølgingen ved hover settes på dette elementet fra
   js/main.js, så den ikke kolliderer med inngangsanimasjonen over. */
.hero__hval img {
  display: block;
  width: 100%;
  height: auto;
  transform-origin: 50% 60%;
}

@keyframes merkeInn {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: none; }
}

.hero__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 1.6rem;
  align-items: center;
  margin-top: clamp(1.5rem, 3vw, 2.5rem);
  padding-top: 1.4rem;
  border-top: 1px solid rgba(255, 255, 245, 0.28);
  font-size: var(--fs-small);
  letter-spacing: 0.02em;
  animation: fade 1s var(--ease) 0.5s backwards;
}

.hero__meta .dot { color: var(--red); }

/* Andre halvdel av raden, skjøvet ut til høyre kant. Egen gruppe framfor
   margin-left: auto på det første ordet — da holder «Kreativt studio ✱ Oslo»
   sammen hvis raden brekker på smale skjermer. */
.hero__meta-hoyre {
  display: inline-flex;
  align-items: center;
  gap: 1.6rem;
  margin-left: auto;
}

/* Smal skjerm: «Alt under ett tak» får ikke plass på linja og havnet alene
   til høyre på en ny linje. Her står den heller venstrestilt under, litt
   nedtonet, som en undertittel, og tjenestene står tettere. */
@media (max-width: 600px) {
  .hero__meta { gap: 0.5rem 0.9rem; }
  .hero__meta-hoyre {
    flex-basis: 100%;
    margin-left: 0;
    opacity: 0.75;
  }
}

@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

/* ------------------------------------------------------------- Marquee --- */

.marquee {
  /* Én verdi styrer all luft i stripa — mellom ord, rundt stjernene og i
     skjøten mellom de to kopiene. Skru på denne for tettere/luftigere. */
  --marquee-gap: clamp(1.75rem, 3.2vw, 3.5rem);

  background: var(--red);
  color: var(--cream);
  padding-block: 0.85rem;
  overflow: hidden;
  white-space: nowrap;
  border-block: 1px solid var(--red);

  /* Skygge bare nedover, så stripa leser som et lag over footeren.
     position + z-index må til: uten dem maler footerens bakgrunn over
     skyggen, siden den kommer senere i dokumentet. Mørk tone, ikke blå —
     --shadow er bygget av logoblå og ville forsvunnet mot footeren.
     overflow: hidden klipper bare innholdet, ikke elementets egen skygge. */
  position: relative;
  z-index: 1;
  box-shadow: 0 12px 22px -10px color-mix(in srgb, var(--black) 34%, transparent);
}

.marquee__track {
  display: inline-flex;
  gap: var(--marquee-gap);
  padding-right: var(--marquee-gap);
  animation: slide 38s linear infinite;
  font-size: clamp(1rem, 1.8vw, 1.6rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  text-transform: uppercase;
}

.marquee__group {
  display: inline-flex;
  align-items: center;
  gap: var(--marquee-gap);
}

/* Stjerne etter hvert ord, med samme luft foran seg som mellom ordene.
   Da blir rytmen ord–stjerne–ord helt jevn, også der de to kopiene møtes. */
.marquee__group > span::after {
  content: "✱";
  margin-left: var(--marquee-gap);
  opacity: 0.75;
}

@keyframes slide { to { transform: translateX(-50%); } }

/* --------------------------------------------------------------- Kort --- */

.grid {
  display: grid;
  gap: var(--gap);
  grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
}

/* Én i bredden: kortene stables. */
.grid--1 { grid-template-columns: minmax(0, 1fr); }

.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); }

/* Fire i bredden, alltid på én linje. auto-fit ville brutt til 3 + 1 så
   snart vinduet ble under ~1500 px, og da står den fjerde alene. */
.grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* Kortet er bilde og tekst i ett. I ro er det bare bildet som har skygge;
   på hover flyttes skyggen ut til hele kortet, slik at bilde og tekst løftes
   som én flate. Polstringen ligger der hele tiden — legger man den på først
   ved hover, hopper teksten. */
.card {
  display: block;
  position: relative;
  /* Mer i bunn enn på sidene: teksten trenger mer luft under seg enn
     bildet gjør på kantene, ellers ser kortet sammenklemt ut. */
  padding: 12.5px 12.5px 22px;
  /* Konsentrisk: ytre radius = indre radius + avstanden mellom dem. Derfor
     regnet ut og ikke --radius-lg — ellers blir hjørnene ujevnt tykke. */
  border-radius: calc(var(--radius) + 12.5px);
  isolation: isolate;
  transition: transform 0.28s var(--ease);
}

/* Den lyse flaten som tennes på hover ligger i sitt eget lag og fades inn
   med opacity. Alternativet — å la kortet bytte background og box-shadow —
   maler hele kortet på nytt for hvert bilde i overgangen, og kortet
   inneholder video, maske og blandingsmodus. Det var den ommalingen som
   hakket. opacity kjøres på kompositoren og koster ingenting.

   z-index -1 legger laget bak innholdet; isolation: isolate på kortet
   holder det fra å falle bak seksjonsbakgrunnen. */
.card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: var(--cream);
  box-shadow: var(--shadow-lift);
  opacity: 0;
  transition: opacity 0.28s var(--ease);
  pointer-events: none;
}

@media (hover: hover) and (pointer: fine) {
  .card:hover { transform: translateY(-4px); }
  .card:hover::before { opacity: 1; }

  /* Profilkortene i slideren vipper én gang, som kortene på Om oss.
     Løftet gjentas i hvert steg fordi animasjonen overstyrer hele
     transform-egenskapen. Bare her: musikkortene lenger nede har ingen
     hover-tilstand å vippe fra. */
  .slider__track .card:hover { animation: kortVippLoft 0.5s var(--ease); }

  .card:hover .card__stat { opacity: 1; }

  .card:hover .card__stat span {
    opacity: 1;
    transform: none;
  }

  /* 80 ms mellom hver linje. Fire trinn holder til det største kortet —
     Alle har to kontoer i dag, men det er plass til flere. */
  .card:hover .card__stat span:nth-child(1) { transition-delay: 0.06s; }
  .card:hover .card__stat span:nth-child(2) { transition-delay: 0.14s; }
  .card:hover .card__stat span:nth-child(3) { transition-delay: 0.22s; }
  .card:hover .card__stat span:nth-child(4) { transition-delay: 0.30s; }
  .card:has(.card__stat):hover .card__map { opacity: 0.5; }

  /* Gråtoningen følger styrken på det blå laget: full grayscale ville
     strippet fargene uansett hvor svakt laget over ligger. Litt ekstra
     lys, siden multiply med en mørk blåfarge alltid trekker ned. */
  .card:has(.card__stat):hover .card__media > img {
    filter: grayscale(0.5) brightness(1.15) contrast(0.95);
  }

  /* Uten denne ligger det to skygger oppå hverandre. */
  .card:hover .card__media { box-shadow: none; }
}

.card__media {
  position: relative;
  isolation: isolate;      /* holder blandingsmodusen inne i bildefeltet */
  overflow: hidden;
  border-radius: var(--radius);
  background: #f0eee6; background: color-mix(in srgb, var(--ink) 8%, var(--cream));
  aspect-ratio: 4 / 5;
  box-shadow: var(--shadow);
}

.card__media > img,
.card__media > video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--pos, 50% 50%);
  display: block;      /* inline gir en baseline-glipe under klippet */
  transition: transform 0.8s var(--ease), filter 0.6s var(--ease);
}

/* Felt med video får mørk bunn i stedet for den lyse plassholderflaten.
   Avrunding av høyden kan etterlate en halv piksel under klippet, og mot
   lys bakgrunn blir den en hvit strek langs underkanten. */
.card__media:has(> video),
.artistkort__media:has(> video),
.artist__stort:has(> video) { background: var(--black); }

.card:hover .card__media > img,
.card:hover .card__media > video { transform: scale(1.045); }

/* Navn og sjanger midt på klippet. Sløret bak er nødvendig: videoen skifter
   hele tiden, og uten det ville teksten falle ut mot lyse bilderuter. */
.card__over {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  text-align: center;
  padding: 1rem;
  color: var(--cream);
  /* Nøytral, ikke blå: klippene skal beholde fargene sine. Akkurat nok
     mørke til at navnet står mot neon og solnedgang. */
  background: color-mix(in srgb, var(--black) 22%, transparent);
  /* Svak skygge rett bak bokstavene. Sløret alene holder ikke når klippet
     skifter til en lys rute — dette følger formen på teksten. */
  text-shadow: 0 2px 10px color-mix(in srgb, var(--black) 55%, transparent);
  pointer-events: none;
  transform-origin: center;
  transition: transform 0.45s var(--ease);
}

.card__over b {
  font-size: clamp(2.2rem, 5vw, 4.6rem);
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1;
}

/* Teksten vokser på hover. Skalering framfor ny font-size: da flytter ikke
   linjene på seg, og overgangen kan gli. */
@media (hover: hover) and (pointer: fine) {
  .card:hover .card__over { transform: scale(1.09); }
}

.card__over > span {
  font-size: var(--fs-label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 600;
  /* Krem, ikke rød: rødt drukner mot det blå sløret og de skiftende klippene. */
  color: var(--cream);
}

/* Følgertall over bildet, tent på hover — én linje per plattform. */
.card__stat {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 1rem;
  z-index: 2;              /* over gradient map-en, ellers ganges teksten ned */
  font-size: clamp(1.1rem, 1.8vw, 1.5rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: #fff;
  opacity: 0;
  transition: opacity 0.45s var(--ease);
  pointer-events: none;
}

/* Linjene stiger inn hver for seg, den andre litt etter den første. Uten
   forskyvningen kommer de som én blokk, og da merkes bevegelsen knapt.
   Forsinkelsen står bare i hover-regelen — på vei ut skal begge forsvinne
   med en gang, ikke etter tur. */
.card__stat span {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  white-space: nowrap;
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.4s var(--ease), transform 0.55s var(--ease);
}

.card__stat img {
  width: 18px;
  height: 18px;
  flex: none;
  filter: brightness(0) invert(1);
}

/* Gradient map på hover: bildet gråtones, og et farget lag ganges oppå.
   Multiply lar svart forbli svart og fargen slå gjennom i høylysene, så
   tonene kartlegges fra svart i skyggene til laget sin farge i lyset.

   --blue-bright og ikke --blue: kortene står på logoblå, og ganger man den
   samme fargen oppå, forsvinner bildet inn i bakgrunnen. Den klare blåen
   ligger i samme familie, men lyst nok til å lese som et eget lag.

   Bare kort som faktisk har et tall å vise får behandlingen. */
.card__map {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: var(--blue-bright);
  mix-blend-mode: multiply;
  opacity: 0;
  transition: opacity 0.45s var(--ease);
  pointer-events: none;
}

/* Navn og merkelapp står alltid på samme linje. Da må begge være små nok
   til å få plass side om side i det smaleste kortet — derfor egen, mindre
   skala her enn --fs-h3 og --fs-label ellers på sida. */
/* Navn øverst, kategori under. Side om side ble for trangt: med lange
   navn («Johanne Brinchmann») og smale mobilkort rant teksten ut over
   kanten, og å la bare noen kort bryte ga ulikt oppsett fra kort til kort. */
.card__body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.3rem;
  padding-top: 0.9rem;
  min-width: 0;
}

.card__title {
  font-size: clamp(1.1rem, 1.45vw, 1.5rem);
  letter-spacing: -0.03em;
  white-space: nowrap;      /* navnet skal aldri brekke i to … */
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;  /* … men heller ikke renne ut av kortet */
  transition: color 0.45s var(--ease);
}

.card__tag {
  font-size: 0.7rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-soft);
  font-weight: 600;
  white-space: nowrap;
  transition: color 0.45s var(--ease);
}

/* Liggende format er 16:9 over hele sida. Musikkortene beskjæres gradvis:
   høyden settes direkte, mens bredden fortsatt følger spalten.

   Ikke aspect-ratio med max-height — da regner nettleseren bredden ut fra
   den begrensede høyden i stedet for å kutte, og kortet krymper i stedet
   for å bli beskåret.

   Full 16:9-høyde er rundt 50,6vw på smale skjermer, siden .wrap tar 5vw
   på hver side. 50vw treffer altså nesten nøyaktig hele klippet der, mens
   taket på 360 px biter mer og mer jo bredere vinduet blir. Ved 1440 px er
   halve høyden borte, som er der vi startet.

   object-fit: cover med utsnitt i midten tar like mye i topp som i bunn. */
.card--wide .card__media {
  aspect-ratio: auto;
  height: min(50vw, 460px);
}

.card--square .card__media { aspect-ratio: 1; }

/* ------------------------------------------------------------ Slider --- */
/* Vannrett karusell med scroll-snap. Ingen bibliotek: nettleseren gjør
   selve rullingen, JS-en flytter den bare ett kort om gangen når man
   trykker pilene. Sveiping og tastatur virker uansett om JS feiler.

   Sporet får negativ margin og tilsvarende padding, så kortene kan skli
   helt ut til kanten av .wrap uten at fokusringen klippes. */

.slider { position: relative; }

.slider__track {
  display: flex;
  /* Strammere enn --gap: kortenes egen polstring teller også som luft,
     så standardavstanden ble for stor mellom dem. */
  gap: clamp(0.4rem, 0.9vw, 0.9rem);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  /* Ingen scroll-snap: sporet sklir sakte videre hele tiden, og snapping
     ville dratt det tilbake til nærmeste kort for hvert bilde. */
  margin-inline: calc(var(--pad) * -1);
  padding-inline: var(--pad);
  /* En vannrett scroller klipper alt som stikker utenfor, også skygger.
     Polstringen gir skyggen plass; den negative marginen tar igjen det
     meste, så seksjonen ikke vokser. */
  padding-block: 30px;
  margin-block: -18px;
  scrollbar-width: none;               /* Firefox */
  -ms-overflow-style: none;
}

.slider__track::-webkit-scrollbar { display: none; }

.slider__track > * {
  flex: 0 0 clamp(265px, 26vw, 385px);
  /* Uten denne blir et kort aldri smalere enn teksten sin — og navnet står
     på én linje. «Johanne Brinchmann» + kategorien gjorde kortet hennes
     bredere enn de andre, og bildet større. */
  min-width: 0;
}

/* Sporet har 30 px polstring i overkant for å gi skyggen plass, og den
   luften kommer i tillegg til marginen under streken. Halver marginen her,
   så avstanden ned til kortene blir som ellers på sida. */
[data-slider] .section-head {
  margin-bottom: clamp(0.8rem, 1.7vw, 1.5rem);
  border-bottom: 0;
}

/* Pilene ligger i seksjonsoverskriften, på linje med tittelen — der
   telleren ellers står. */
.slider__nav {
  display: flex;
  gap: 0.5rem;
  margin-left: auto;
  align-self: center;
}

.slider__btn {
  width: 48px;
  height: 48px;
  border-radius: 100px;
  /* Samme blåfarge og samme tyngde som overskriften ved siden av — en tynn,
     lys ring ble stående og vippe mot den fete tittelen. */
  border: 2px solid var(--ink);
  display: grid;
  place-items: center;
  color: var(--ink);
  transition: background 0.35s var(--ease), color 0.35s var(--ease),
              border-color 0.35s var(--ease), opacity 0.35s var(--ease);
}

/* Strek i stedet for tegn: da bestemmer vi tykkelsen selv. */
.slider__btn svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 3.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.slider__btn:hover:not(:disabled) {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--cream);
}

/* Deaktivert i endene — dempet, men fortsatt synlig, så det er tydelig
   at karusellen har en start og en slutt. */
.slider__btn:disabled { opacity: 0.3; cursor: default; }

@media (hover: none) {
  /* På touch sveiper man. Pilene ville bare tatt plass. */
  .slider__nav { display: none; }
}

/* Tjenestekort — tekstbasert, uten bilde */
.service {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(1.5rem, 2.5vw, 2.25rem);
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  min-height: clamp(240px, 30vw, 340px);
  transition: background 0.45s var(--ease), color 0.45s var(--ease), border-color 0.45s var(--ease);
}

.service:hover {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--cream);
}

.service:hover .service__num,
.service:hover p { color: inherit; opacity: 0.75; }

.service__num {
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--red);
}

.service h3 {
  font-size: var(--fs-h3);
  margin-top: auto;
}

.service p { color: var(--ink-soft); font-size: var(--fs-small); }

/* Plassholder for media vi ennå ikke har fått tak i.
   Fjern data-placeholder og legg inn <img> når bildet er på plass. */
[data-placeholder] {
  display: grid;
  place-items: center;
  background:
    repeating-linear-gradient(45deg,
      transparent 0 14px,
      color-mix(in srgb, var(--ink) 4%, transparent) 14px 28px),
    var(--cream-warm);
}

[data-placeholder] .ph-star {
  width: 22%;
  max-width: 90px;
  height: auto !important;
  opacity: 0.5;
  animation: spin 22s linear infinite;
}

.row__media[data-placeholder] { aspect-ratio: 4 / 5; }
.row--wide .row__media[data-placeholder] { aspect-ratio: 4 / 3; }

/* -------------------------------------------------- Musikkoversikt --- */
/* /musikk viser bare klipp og beskrivelse, to og to med god luft. Resten
   (cover, portretter) ligger på hver artists egen side under /musikk/.
   Ingen boks rundt: klippet er flaten, teksten står fritt under. */
.artister {
  display: grid;
  /* To og to, som på forsiden: auto-fit ga tre i bredden på store skjermer
     og en artist alene på andre rad. Én kolonne på mobil. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(3rem, 7vw, 6rem) clamp(1.5rem, 4vw, 4rem);
}

@media (max-width: 700px) {
  .artister { grid-template-columns: minmax(0, 1fr); }
}

.artistkort {
  display: flex;
  flex-direction: column;
  gap: clamp(1.1rem, 2vw, 1.6rem);
  color: inherit;
}

.artistkort__media {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius);
  aspect-ratio: 16 / 9;
  background: #f0eee6; background: color-mix(in srgb, var(--ink) 8%, var(--cream));
  box-shadow: var(--shadow);
}

.artistkort__media video,
.artistkort__media img:not(.ph-star) {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--pos, 50% 50%);
  display: block;
  transition: transform 0.8s var(--ease);
}

.artistkort__navn {
  font-size: var(--fs-h3);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
}

.artistkort__tekst .row__tag { margin-bottom: 0.6rem; }

.artistkort__tekst p {
  margin-top: 0.75rem;
  max-width: 52ch;
  color: var(--ink-soft);
}

.artistkort__mer {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  margin-top: 1.1rem;
  font-size: var(--fs-small);
  font-weight: 600;
  transition: color 0.3s var(--ease), gap 0.3s var(--ease);
}

@media (hover: hover) and (pointer: fine) {
  .artistkort:hover .artistkort__media video,
  .artistkort:hover .artistkort__media img:not(.ph-star) { transform: scale(1.03); }
  .artistkort:hover .artistkort__mer { color: var(--red); gap: 0.8em; }
}

/* ------------------------------------------------------ Artistkort --- */
/* Tre nivåer nedover kortet:

     hovedklipp        full bredde, 16:9
     tekst | kvadrat   halv bredde hver
     tre portretter    en tredel hver, 4:5

   Klippet er dobbelt så bredt som da det delte raden med teksten, og det er
   bredden som avgjør hvor stort et 16:9-motiv får bli. Under kommer tre
   stående felter i 4:5 — samme format som portrettene på Profiler, så
   formatet betyr det samme over hele sida. */

/* .row.artist, ikke bare .artist: .row har like høy spesifisitet og står
   lenger ned i fila, så den ville ellers vunnet med sine to spalter. */
.row.artist {
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(0.9rem, 2vw, 1.5rem);
  align-items: start;
}

/* Høyden settes direkte i stedet for med aspect-ratio: et 16:9-klipp i full
   kortbredde blir nesten 700 px høyt på en laptop, og da fyller det skjermen
   alene. Med et tak på 380 px er teksten under synlig samtidig.

   46vw ligger like under klippets egen høyde på smale skjermer, så der biter
   ingenting og motivet står helt. Jo bredere vinduet blir, jo mer beskjæres
   det — object-fit: cover tar like mye i topp som i bunn.

   Ikke aspect-ratio med max-height: da regner nettleseren bredden ut fra den
   begrensede høyden, og feltet krymper i stedet for å bli beskåret. */
.artist__stort {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius);
  height: min(46vw, 380px);
  background: #f0eee6; background: color-mix(in srgb, var(--ink) 8%, var(--cream));
}

.artist__under {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(1.25rem, 3vw, 2.5rem);
  align-items: start;
}

.artist__portretter {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(0.35rem, 0.9vw, 0.7rem);
}

.artist__kvadrat,
.artist__portretter > * {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius);
  background: #f0eee6; background: color-mix(in srgb, var(--ink) 8%, var(--cream));
}

.artist__kvadrat { aspect-ratio: 1; }
.artist__portretter > * { aspect-ratio: 4 / 5; }

.artist__stort video,
.artist__stort img,
.artist__kvadrat img:not(.ph-star),
.artist__portretter img:not(.ph-star) {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--pos, 50% 50%);
  display: block;
}

.artist .row__body { max-width: none; }

/* --------------------------------------------------------- Kategorikort --- */
/* Avrundede felter med bilde og tekst. Brukes som inngang til hver
   underside på Produksjon. */

.cats {
  display: grid;
  gap: var(--gap);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* Kvadratisk variant — brukes på Prosjekter, der de fire kategoriene er
   hele innholdet på sida og tåler å ta mer plass. Klasse på beholderen og
   ikke på hvert kort, så formatet er én ting å endre.
   Vinner også over mobilregelen lenger ned: to klasser slår én. */
.cats--kvadrat .cat { aspect-ratio: 1; }

/* Bredt kort over begge spaltene (Strategi). Lavere enn kvadratene, så det
   leser som en avslutning og ikke som et sjette, større kort. */
.cats .cat--bred,
.cats--kvadrat .cat--bred { grid-column: 1 / -1; aspect-ratio: 21 / 9; }

@media (max-width: 700px) {
  .cats .cat--bred,
  .cats--kvadrat .cat--bred { aspect-ratio: 4 / 3; }
}

.cat {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: var(--radius-lg);
  aspect-ratio: 16 / 9;
  background: var(--ink);
  color: var(--cream);
  box-shadow: var(--shadow);
}

/* Plassholder til vi har bilde — samme flate som .cat__img ville dekket. */
.cat__ph {
  position: absolute;
  inset: 0;
}

.cat__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--pos, 50% 50%);
  transition: transform 0.9s var(--ease);
}

/* Legger seg over bildet (siste barn i malingsrekkefølgen) og gir teksten
   noe å stå mot uansett hvor lyst bildet er. */
.cat::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg,
    rgba(11, 0, 94, 0.10) 0%,
    rgba(11, 0, 94, 0.30) 45%,
    rgba(11, 11, 20, 0.88) 100%);
}

.cat:hover .cat__img { transform: scale(1.05); }

.cat__body {
  position: relative;   /* over ::after */
  z-index: 1;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 0.45rem;
  padding: clamp(1.25rem, 2.6vw, 2.25rem);
}

.cat__count {
  font-size: var(--fs-label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--cream);   /* rødt forsvinner mot det mørke overlegget */
  opacity: 0.82;
}

.cat h3 {
  font-size: var(--fs-h2);
  text-transform: uppercase;
  display: flex;
  align-items: center;
  gap: 0.4em;
}

.cat h3 span {
  font-size: 0.55em;
  transition: transform 0.4s var(--ease);
}

.cat:hover h3 span { transform: translateX(0.35em); }

.cat p {
  font-size: var(--fs-small);
  opacity: 0.82;
  max-width: 36ch;
}

/* ------------------------------------------------ Tjenester på forsiden --- */

/* Kategoriene på forsiden er ikke lenger fire kort i rutenett med teksten
   inni. De er fire brede rader der navnet står stort ved siden av flata,
   vekslende side, med en hårstrek mellom seg. Kortvarianten (.cat) lever
   videre på Prosjekter, der de fire kategoriene er hele sida og tåler å
   være kompakte. */
.tjenester {
  display: grid;
  gap: clamp(1.75rem, 4vw, 3.25rem);
}

.tjeneste {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
  gap: clamp(1.5rem, 5vw, 4rem);
  align-items: center;
  padding-top: clamp(1.75rem, 4vw, 3.25rem);
  border-top: 1px solid var(--line);
}

/* Første rad ligger rett under seksjonsoverskriften, som har sin egen strek. */
.tjeneste:first-child { border-top: 0; padding-top: 0; }

/* Annenhver rad snus. order flytter flata til første kolonne, men
   rutenettet plasserer fortsatt etter ordensrekkefølge i sporene slik de
   står — så sporbreddene må snus sammen med den. Ellers havner bildet i
   den smale kolonnen på partallsradene, og siden flata har et fast
   sideforhold, ville den blitt lavere der enn på oddetallsradene. */
.tjeneste:nth-child(even) {
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
}

.tjeneste:nth-child(even) .tjeneste__flate { order: -1; }

/* Overskrift og brødtekst deler kolonne. Uten denne wrapperen ville
   rutenettet lagt avsnittet i bildekolonnen — tre barn i to spalter. */
/* Tjeneste uten bilde (Strategi & rådgiving): én spalte, tekst i lesbar
   bredde. Står nederst, så den snudde rekkefølgen for partallsrader gjelder
   ikke. */
.tjeneste--tekst,
.tjeneste--tekst:nth-child(even) { grid-template-columns: minmax(0, 1fr); }
.tjeneste--tekst .tjeneste__tekst { max-width: 60ch; }

.tjeneste__tekst {
  display: grid;
  gap: clamp(0.75rem, 1.6vw, 1.25rem);
}

.tjeneste__tekst p {
  color: var(--ink-soft);
  max-width: 44ch;
}

.tjeneste__navn {
  /* Større enn --fs-h2, mindre enn heroen: navnet er det som bærer raden nå
     som det ikke lenger står oppå et bilde. */
  font-size: clamp(2.25rem, 5.2vw, 4.5rem);
  display: flex;
  align-items: center;
  gap: 0.3em;
  transition: color 0.35s var(--ease);
}

.tjeneste__navn span {
  font-size: 0.45em;
  transition: transform 0.4s var(--ease);
}

.tjeneste__flate {
  position: relative;
  /* grid + place-items, ikke block: regelen står etter [data-placeholder] i
     fila og har samme spesifisitet, så en display: block her ville slått ut
     sentreringen av plassholderstjerna. */
  display: grid;
  place-items: center;
  overflow: hidden;
  border-radius: var(--radius-lg);
  aspect-ratio: 16 / 9;
  background: var(--boks);
  box-shadow: var(--shadow);
  transition: box-shadow 0.5s var(--ease);
}

.tjeneste__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--pos, 50% 50%);
  transition: transform 0.9s var(--ease);
}

@media (hover: hover) and (pointer: fine) {
  .tjeneste:hover .tjeneste__navn { color: var(--red); }
  .tjeneste:hover .tjeneste__navn span { transform: translateX(0.35em); }
  .tjeneste:hover .tjeneste__img { transform: scale(1.05); }
  .tjeneste:hover .tjeneste__flate { box-shadow: var(--shadow-lift); }
}

/* Stablet: navnet over flata, samme rekkefølge i alle radene. order må
   nullstilles, ellers havner annenhver flate over sitt eget navn. Det samme
   gjelder de snudde sporene — regelen over er mer spesifikk enn .tjeneste,
   og en mediespørring endrer ikke på det, så partallsradene ville blitt
   stående tospaltet her. */
@media (max-width: 720px) {
  .tjeneste,
  .tjeneste:nth-child(even) {
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(1rem, 3vw, 1.5rem);
  }

  .tjeneste:nth-child(even) .tjeneste__flate { order: 0; }
}

/* Tilbakelenke på underidene */
.backlink {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-size: var(--fs-small);
  font-weight: 600;
  color: var(--ink-soft);
  margin-bottom: 1.5rem;
  transition: color 0.3s var(--ease), gap 0.3s var(--ease);
}

.backlink:hover { color: var(--red); gap: 0.8em; }

/* ------------------------------------------------------- Vekslende rader --- */

.rows { display: flex; flex-direction: column; gap: clamp(4rem, 9vw, 8rem); }

.row {
  display: grid;
  gap: clamp(1.5rem, 4vw, 4rem);
  align-items: center;
  grid-template-columns: 1fr 1fr;
}

/* Innrammet variant — brukes på Profiler, der hver rad skal lese som ett
   kort. Radene står tettere enn ellers, for boksene skiller dem allerede;
   den store luften mellom dem var det som holdt dem fra hverandre før. */
.rows--boks {
  gap: clamp(1.25rem, 2.5vw, 2.25rem);
}

/* Kortflaten. Radene på Profiler og Musikk deler den. */
.rows--boks .row {
  position: relative;
  background: var(--boks);
  border-radius: var(--radius-lg);
  padding: clamp(1.25rem, 2.4vw, 2.25rem);
  box-shadow: var(--shadow);
  transition: transform 0.5s var(--ease), box-shadow 0.5s var(--ease);
}

/* Ring rundt hvert mediefelt. Den ligger klar hele tiden, bare gjennomsiktig,
   så bildet ikke flytter seg når den tennes på hover. */
.rows--boks .row__media,
.rows--boks .artist__stort,
.rows--boks .artist__kvadrat,
.rows--boks .artist__portretter > * { position: relative; }

.rows--boks .row__media::after,
.rows--boks .artist__stort::after,
.rows--boks .artist__kvadrat::after,
.rows--boks .artist__portretter > *::after {
  content: "";
  position: absolute;
  inset: 0;
  border: 1px solid transparent;
  border-radius: inherit;
  pointer-events: none;
  transition: border-color 0.5s var(--ease);
}

/* Boksen vokser litt og får et blått skjær rundt seg, og ringene tennes
   samtidig. Ikke på Profiler (.rows--rolig) — der står boksene stille. Skygge uten forskyvning legger seg jevnt hele veien rundt og
   leser som lys, ikke som tyngde; den vanlige skyggen ligger under så
   boksen fortsatt står på noe. */
@media (hover: hover) and (pointer: fine) {
  .rows--boks:not(.rows--rolig) .row:hover {
    transform: scale(1.015);
    box-shadow:
      0 0 0 1px color-mix(in srgb, var(--blue) 22%, transparent),
      0 0 34px 6px color-mix(in srgb, var(--blue) 26%, transparent),
      var(--shadow);
  }

  .rows--boks:not(.rows--rolig) .row:hover .row__media::after,
  .rows--boks:not(.rows--rolig) .row:hover .artist__stort::after,
  .rows--boks:not(.rows--rolig) .row:hover .artist__kvadrat::after,
  .rows--boks:not(.rows--rolig) .row:hover .artist__portretter > *::after {
    border-color: color-mix(in srgb, var(--blue) 22%, transparent);
  }
}

/* Bildet til høyre i første rad, så annenhver. Slik møter tekst tekst og
   grafikk grafikk i overgangen fra sidehodet: overskriften fortsetter i
   navnet under, og stjerna til høyre leder inn i det første fotografiet. */
.row:nth-child(odd) .row__media { order: 2; }

.row__media {
  /* Forankrer .row__cta, som ligger absolutt plassert i hjørnet. Uten den
     finner knappen ingen posisjonert forelder og fester seg til sida i
     stedet for til bildet. */
  position: relative;
  border-radius: var(--radius);
  overflow: hidden;
  background: #f0eee6; background: color-mix(in srgb, var(--ink) 8%, var(--cream));
  box-shadow: var(--shadow);
}

/* --ratio lar enkeltbilder beholde sitt eget format. Uten den ville f.eks.
   et kvadratisk podkastcover blitt beskåret til 4:3, og da ryker både
   tittelen på toppen og navnene i bunnen. */
.row__media img,
.row__media video {
  width: 100%;
  aspect-ratio: var(--ratio, 4 / 5);
  object-fit: cover;
}

.row--wide .row__media img,
.row--wide .row__media video { aspect-ratio: var(--ratio, 4 / 3); }

.row__body { max-width: 46ch; }

.row__body h3 {
  font-size: var(--fs-h2);
  margin-bottom: 1.1rem;
}

/* Følgertall med plattformikon, rett under navnet. */
.row__social {
  display: flex;
  flex-wrap: wrap;      /* smale skjermer: knappene legger seg under hverandre */
  align-items: center;
  /* Større mellom kontoene enn inni dem (0.35rem), så de to pillene leser
     som ett par og ikke som fire løsrevne merker. */
  gap: 0.6rem 1.4rem;
  margin: 1.3rem 0 0;      /* knappene står under teksten nå */
}

/* Én pille per opplysning: ikonet sier hvilken plattform, den neste hvem,
   den siste hvor mange. Bare ikonet er fylt — med tre fylte piller ville
   raden blitt en blå klump, og ingenting hadde ledet blikket. */
/* Ikonet står fast til venstre; navn og følgertall ligger i en egen boks
   ved siden av som kan brytes. Da rykkes det som brytes inn under navnet,
   i stedet for å starte helt ute i venstre kant og se løsrevet ut. */
.row__konto {
  display: inline-flex;
  align-items: flex-start;
  gap: 0.35rem;
  max-width: 100%;
}

.row__konto-info {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  min-width: 0;
}

/* Hele gruppa er én lenke til kontoen. Pillene reagerer samlet, så det er
   tydelig at de tre hører sammen og peker samme sted. */
a.row__konto .pille {
  transition: background 0.3s var(--ease), border-color 0.3s var(--ease),
              color 0.3s var(--ease);
}

a.row__konto:hover .pille--ramme {
  border-color: var(--red);
  color: var(--red);
}

/* Flere kontoer i én rad: hvert brukernavn er sin egen lenke og reagerer
   alene, i stedet for at hele raden lyser opp. */
.row__konto--flere a.pille--navn {
  transition: border-color 0.3s var(--ease), color 0.3s var(--ease);
}
.row__konto--flere a.pille--navn:hover {
  border-color: var(--red);
  color: var(--red);
}

/* Merkelapp inne i håndtakspillen, f.eks. «Norsk» og «Internasjonal» når en
   profil har to kontoer på samme plattform. Inni pillen, ikke ved siden av:
   som egen bit brøt den alene ned på neste linje og så løsrevet ut. */
.pille__merke {
  margin-left: 0.15rem;
  font-size: 0.68em;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--red);
}

a.row__konto:hover .pille--fylt { background: var(--red); }

/* Kontoen løftes litt i tillegg til fargeskiftet. På Profiler står selve
   boksen stille, så det er her bevegelsen ligger. */
a.row__konto { transition: transform 0.3s var(--ease); }

@media (hover: hover) and (pointer: fine) {
  a.row__konto:hover { transform: translateY(-2px); }
}

.pille {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.45rem 0.95rem;
  border-radius: 100px;
  font-size: var(--fs-small);
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
}

.pille--fylt {
  background: var(--blue);
  color: var(--cream);
}

/* Ikonene er ettfargede blå SVG-er — mot den blå flaten må de snus til
   hvitt, og da holder det med brightness/invert. */
.pille--fylt img { filter: brightness(0) invert(1); }

/* Uten brukernavn blir pilla et rundt merke. Lik polstring hele veien. */
.pille--ikon { padding: 0.45rem; }

.pille--ramme {
  border: 1.5px solid color-mix(in srgb, var(--ink) 28%, transparent);
  color: var(--ink-soft);
  font-weight: 500;
}

/* Brukernavnet er viktigere enn tallet: full farge og tyngre snitt, men
   samme form, så de tre pillene fortsatt leser som én rekke. */
.pille--navn {
  color: var(--ink);
  font-weight: 600;
}

.row__social img { width: 18px; height: 18px; flex: none; }

/* Knappen ligger nede i det hjørnet som vender bort fra teksten. Radene
   veksler på hvilken side bildet står, så knappen bytter side med dem —
   da havner den aldri klemt inntil tekstspalten.

   Samme høyde som pillene med følgertall under: polstring, skriftstørrelse
   og linjeavstand er hentet derfra, så knappene på raden leser som ett sett.

   Skyggen er der for lesbarhet — et bilde kan være hva som helst bak. */
.row__cta {
  position: absolute;
  right: clamp(0.6rem, 1.4vw, 1rem);
  bottom: clamp(0.6rem, 1.4vw, 1rem);
  z-index: 1;

  display: inline-flex;
  align-items: center;
  padding: 0.45rem 0.95rem;
  border-radius: 100px;
  background: var(--blue);
  color: var(--cream);
  font-size: var(--fs-small);
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  box-shadow: 0 6px 18px -8px color-mix(in srgb, var(--black) 70%, transparent);
  transition: transform 0.35s var(--ease), background 0.35s var(--ease);
}

/* Partallsradene har bildet til venstre og teksten til høyre — der må
   knappen over i venstre hjørne. Samme regel som snur selve raden. */
.row:nth-child(even) .row__cta {
  left: clamp(0.6rem, 1.4vw, 1rem);
  right: auto;
}

.row__cta:hover {
  transform: translateY(-2px);
  background: var(--red);
}

/* Står knappene rett under navnet — som på profiler uten beskrivelse —
   trenger navnet mindre luft under seg. */
.row__body h3:has(+ .row__social) { margin-bottom: 0.45rem; }

.row__body p { color: var(--ink-soft); }

/* Lenker i brødteksten (profilnavn, «Hør på …»). Den globale a-regelen
   fjerner understreken, og uten den ser de ut som vanlig tekst. */
.row__body p:not(.row__social) a,
.prose p a {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: color 0.3s var(--ease);
}

.row__body p:not(.row__social) a:hover,
.prose p a:hover { color: var(--red); }

.row__tag {
  display: inline-block;
  font-size: var(--fs-label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--red);
  margin-bottom: 0.9rem;
}

/* -------------------------------------------------------- Videogalleri --- */
/* To i bredden på Video-sida. Alle feltene har samme format uansett hva
   klippet er filmet i — object-fit: cover ordner beskjæringen, og --pos
   flytter utsnittet på enkeltklipp som tåler det dårlig. */

.vids {
  display: grid;
  gap: clamp(1.25rem, 3vw, 2.75rem);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.vid__media {
  position: relative;
  border-radius: var(--radius);
  overflow: hidden;
  background: #f0eee6; background: color-mix(in srgb, var(--ink) 8%, var(--cream));
  aspect-ratio: var(--ratio, 16 / 9);
  box-shadow: var(--shadow);
}

.vid__media video,
.vid__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--pos, 50% 50%);
  display: block;
}

/* Filterraden over rutenettet: piller i samme form som SoMe-pillene,
   valgt kategori fylt med logoblå. */
.filter {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: clamp(1.5rem, 3vw, 2.5rem);
}

.filter[hidden] { display: none; }

.filter__knapp {
  padding: 0.55rem 1.1rem;
  border-radius: 100px;
  border: 1.5px solid color-mix(in srgb, var(--ink) 28%, transparent);
  background: none;
  font: inherit;
  font-size: var(--fs-small);
  font-weight: 600;
  color: var(--ink-soft);
  cursor: pointer;
  transition: background 0.25s var(--ease), color 0.25s var(--ease), border-color 0.25s var(--ease);
}

.filter__knapp:hover { border-color: var(--ink); color: var(--ink); }

.filter__knapp[aria-pressed="true"] {
  background: var(--blue);
  border-color: var(--blue);
  color: var(--cream);
}

/* hidden-attributtet må slå gjennom display: grid fra .vid. */
.vid[hidden] { display: none; }

/* Felter som lenker videre til en egen prosjektside. */
a.vid { cursor: pointer; }

/* Med mus: hvert felt har først et gjennomskinnelig blått slør med
   tittelen, og på hover tones sløret bort så klippet kommer helt fram. Rutenettet leser da som en
   rolig innholdsfortegnelse, og bevegelsen er belønningen for å se nærmere.
   Tittelen ligger utenfor .vid__media i HTML-en (ikke inni), så den kan
   stå under klippet på touch — her legges den oppå med absolutt posisjon. */
.vid { position: relative; }

.vid__title {
  margin: 0;
  display: flex;
  flex-direction: column;
  /* Egen skala, ikke --fs-h3: feltene er halve sidebredden, og tittelen
     tåler å være større her enn en vanlig underoverskrift. */
  font-size: clamp(1.7rem, 3vw, 2.9rem);
}

/* Artistnavnet under tittelen — mindre og litt nedtonet, så tittelen
   fortsatt er det man leser først. */
.vid__artist {
  margin-top: 0.4rem;
  font-size: var(--fs-body);
  font-weight: 400;
  letter-spacing: 0.02em;
  opacity: 0.85;
}

@media (hover: hover) and (pointer: fine) {
  .vid__title {
    position: absolute;
    inset: 0;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: clamp(1rem, 2.4vw, 1.75rem);
    border-radius: var(--radius);
    color: var(--cream);
    /* Gjennomskinnelig, så klippet skimtes bak tittelen før hover. */
    background: color-mix(in srgb, var(--blue) 35%, transparent);
    /* Med så tynt slør må teksten ha litt hjelp mot lyse bilder. */
    text-shadow: 0 2px 12px color-mix(in srgb, var(--black) 55%, transparent);
    transition: opacity 0.45s var(--ease);
    pointer-events: none;      /* skal aldri stjele klikk fra feltet */
  }

  .vid:hover .vid__title,
  .vid:focus-visible .vid__title,
  .vid:focus-within .vid__title { opacity: 0; }
}

/* Touch: ingen hover å avsløre med, så klippet spiller hele tiden og
   tittelen står under, venstrestilt som en bildetekst. */
@media not ((hover: hover) and (pointer: fine)) {
  .vid { display: grid; gap: 0.6rem; }

  .vid__title {
    font-size: var(--fs-h3);
    color: var(--ink);
    line-height: 1.1;
  }

  .vid__artist {
    margin-top: 0.2rem;
    font-size: var(--fs-small);
    color: var(--ink-soft);
    opacity: 1;
  }
}

/* ------------------------------------------------------------- Embed --- */
/* YouTube og annet innhold fra tredjepart. Fast 16:9 og samme avrunding
   som resten av mediefeltene, så det ikke skiller seg ut. */

.embed {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius);
  overflow: hidden;
  background: #f0eee6; background: color-mix(in srgb, var(--ink) 8%, var(--cream));
  box-shadow: var(--shadow);
}

.embed iframe,
.embed video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

/* Utdrag som spilles lokalt i stedet for en innebygd spiller. */
.embed video { object-fit: cover; display: block; }
.embed:has(> video) { background: var(--black); }

/* ------------------------------------------------------- Brødtekst --- */
/* Løpende tekst på prosjektsider. Smal spalte, for lange linjer er tunge
   å lese. */

.prose {
  max-width: 68ch;
  padding-top: var(--section);
}

.prose h2 {
  font-size: var(--fs-h2);
  text-transform: uppercase;
  margin-bottom: 1.5rem;
}

/* Artikkel (Strategi): flere mellomtitler etter hverandre. I versaler og
   full h2-størrelse ropte de høyere enn sidetittelen og druknet teksten. */
.prose--artikkel h2 {
  font-size: var(--fs-h3);
  text-transform: none;
  letter-spacing: -0.02em;
  margin-top: 2.25rem;
}
.prose--artikkel h2:first-child { margin-top: 0; }

.prose p {
  color: var(--ink-soft);
  font-size: var(--fs-lead);
  margin: 0 0 1.2rem;
}

/* Faktaliste nederst i teksten. Etiketten står alltid over verdien: side
   om side brøt bare de lengste etikettene («Film, klipp og animasjon»), og
   da sto én verdi alene under mens resten sto ved siden av. */
.facts {
  list-style: none;
  margin: 2.5rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.9rem;
}

.facts li {
  display: grid;
  gap: 0.35rem;
  padding-bottom: 0.9rem;
  border-bottom: 1px solid var(--line);
}

.facts span {
  font-size: var(--fs-label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--red);
}

/* ------------------------------------------------- Spotlight på video --- */
/* Hovrer du en video dempes resten av siden, og videoen løftes fram — som
   når lyset skrus av i en kinosal. Skrus på per side med klassen
   spotlight-video på <body>; ligger den ikke der, skjer ingenting.

   Dempingen er et fixed lag over hele viewporten, også over nav (z-100).
   Videoen løftes over det laget igjen, så den blir stående i fullt lys. */

.spotlight-video::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 200;
  background: var(--black);
  opacity: 0;
  pointer-events: none;          /* laget skal aldri spise klikk */
  transition: opacity 0.55s var(--ease);
}

/* Bare når en video faktisk hovres — :has() lar oss reagere på et barn
   uten JavaScript. */
@media (hover: hover) and (pointer: fine) {
  .spotlight-video:has(.row__media:hover)::after { opacity: 0.88; }

  .spotlight-video .row__media {
    position: relative;
    transition: transform 0.55s var(--ease);
  }

  .spotlight-video .row__media:hover {
    z-index: 201;                /* over dempingen */
    transform: scale(1.05);
  }
}

/* --------------------------------------------------------------- Team --- */

/* ------------------------------------------------------------ Teamet --- */
/* Tre i bredden, portrett, med navn og stilling under. Hele beskrivelsen
   ligger i en <dialog> som åpnes ved klikk — kortene holder oversikten,
   dialogen holder detaljene.

   Kortene er <button>, ikke <div> med klikkhåndterer: da får de tastatur,
   fokusring og riktig rolle uten at vi bygger noe av det selv. */

/* Smalere enn spalten og med god luft mellom kortene: i full bredde ble
   portrettene store og rutenettet tett. */
.ansatte {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.5rem, 4vw, 3.5rem);
  max-width: 1040px;
  margin-inline: auto;
}

.ansatt {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.15rem;
  padding: clamp(0.75rem, 1.4vw, 1.1rem);
  border-radius: var(--radius-lg);
  background: var(--boks);
  box-shadow: var(--shadow);
  text-align: left;
  font: inherit;
  color: inherit;
  transition: transform 0.5s var(--ease), box-shadow 0.5s var(--ease);
}

.ansatt__foto {
  position: relative;
  /* grid, ikke block: da sentrerer [data-placeholder] stjerna si. Med block
     — som står senere i fila enn plassholderregelen — falt den til hjørnet.
     Et ekte foto fyller feltet uansett, siden det har width/height 100 %. */
  display: grid;
  place-items: center;
  overflow: hidden;
  border-radius: var(--radius);
  aspect-ratio: 4 / 5;
  margin-bottom: 0.9rem;
  background: #f0eee6; background: color-mix(in srgb, var(--ink) 8%, var(--cream));
}

.ansatt__foto img:not(.ph-star) {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--pos, 50% 30%);
  display: block;
  transition: transform 0.8s var(--ease);
}

/* Navn og stilling til venstre, pila ytterst til høyre. */
.ansatt__bunn {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
}

.ansatt__bunn > span {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}

/* Kortet tar imot seg selv når popupen lukkes: det kommer inn litt for
   lite, går så vidt forbi og setter seg. Uten dette bare dukker det opp
   igjen, og overleveringen fra dialogen blir et kutt. */
.ansatt.lander { animation: kortLander 0.3s var(--ease); }

/* Skaleringen gjentas i hvert steg fordi en animasjon overstyrer hele
   transform-egenskapen — uten den ville kortet falt tilbake til full
   størrelse mens det vipper. Siste steg er identisk med hover-tilstanden,
   så overgangen tilbake er umerkelig. */
@keyframes kortVippLoft {
  0%   { transform: translateY(-4px) rotate(0deg); }
  30%  { transform: translateY(-4px) rotate(-0.8deg); }
  65%  { transform: translateY(-4px) rotate(0.5deg); }
  100% { transform: translateY(-4px) rotate(0deg); }
}

@keyframes kortVipp {
  0%   { transform: scale(1.015) rotate(0deg); }
  22%  { transform: scale(1.015) rotate(-0.8deg); }
  48%  { transform: scale(1.015) rotate(0.65deg); }
  74%  { transform: scale(1.015) rotate(-0.35deg); }
  100% { transform: scale(1.015) rotate(0deg); }
}

@keyframes kortLander {
  0%   { transform: scale(0.9); }
  55%  { transform: scale(1.03); }
  100% { transform: none; }
}

/* Skrå pil opp: den samme gesten som utgående lenker bruker, altså «dette
   fører videre». Rister én gang når kortet hovres — en kort påminnelse om
   at kortet er klikkbart, ikke en løkke som maser. */
.ansatt__pil {
  flex: none;
  width: 30px;
  height: 30px;
  margin-top: 0.1rem;
  fill: none;
  stroke: var(--ink);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Ristingen fyller hele syklusen, og syklusen er kort: to ganger i
   sekundet så lenge musa ligger der. Utslagene er små nettopp fordi det går
   fort — større utslag i dette tempoet blir en vibrasjon, ikke en gest. */
@keyframes pilRist {
  0%, 100% { transform: none; }
  25%      { transform: translate(1.5px, -1.5px) rotate(6deg); }
  60%      { transform: translate(-1px, 1px) rotate(-5deg); }
}

.ansatt__navn {
  font-size: var(--fs-h3);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.15;
}

.ansatt__rolle {
  font-size: var(--fs-small);
  color: var(--ink-soft);
}

/* Ringen rundt fotoet, som på de andre kortene. Ligger klar hele tiden og
   tennes på hover, så bildet ikke flytter seg når den kommer. */
.ansatt__foto::after {
  content: "";
  position: absolute;
  inset: 0;
  border: 1px solid transparent;
  border-radius: inherit;
  pointer-events: none;
  transition: border-color 0.5s var(--ease);
}

/* Plassholderne er ikke klikkbare og skal ikke se ut som om de er det. */
.ansatt--tom .ansatt__navn,
.ansatt--tom .ansatt__rolle { color: var(--ink-soft); }

/* «Deg?» spenner over hele siste rad i stedet for å stå alene i en tredel.
   Da går rutenettet opp uansett antall i bredden (3, 2 eller 1), og kortet
   leser som en invitasjon og ikke som en ledig stol. Stiplet ramme og ingen
   flate: det er en åpen plass, ikke en person. */
.ansatt--tom {
  grid-column: 1 / -1;
  flex-direction: row;
  align-items: center;
  gap: clamp(1rem, 2.4vw, 1.75rem);
  background: none;
  box-shadow: none;
  border: 1.5px dashed color-mix(in srgb, var(--ink) 30%, transparent);
}

.ansatt--tom .ansatt__foto {
  flex: none;
  width: clamp(64px, 9vw, 104px);
  aspect-ratio: 1;
  margin-bottom: 0;
}

/* Stjerna fyller mer av den lille ruta enn av et helt portrett. */
.ansatt--tom .ph-star { width: 55%; }

/* Kortet er en e-postlenke. Teksten tar resten av bredden, så pila havner
   ytterst til høyre som på de andre kortene. */
.ansatt--tom .ansatt__bunn { flex: 1; align-items: center; }

.ansatt__mail {
  margin-top: 0.35rem;
  font-size: var(--fs-small);
  font-weight: 600;
  color: var(--ink);
  transition: color 0.3s var(--ease);
}

.ansatt--tom { transition: border-color 0.3s var(--ease); }

@media (hover: hover) and (pointer: fine) {
  .ansatt--tom:hover { border-color: var(--red); }
  .ansatt--tom:hover .ansatt__mail { color: var(--red); }
  .ansatt--tom:hover .ansatt__pil { animation: pilRist 0.5s ease-in-out infinite; }
}

@media (hover: hover) and (pointer: fine) {
  .ansatt:not(.ansatt--tom):hover {
    transform: scale(1.015);
    box-shadow:
      0 0 0 1px color-mix(in srgb, var(--blue) 22%, transparent),
      0 0 34px 6px color-mix(in srgb, var(--blue) 26%, transparent),
      var(--shadow);
    /* Kortet vipper én gang, som om det ber om å bli trykket på. Utslagene
       avtar, så det roer seg av seg selv. */
    animation: kortVipp 0.5s var(--ease);
  }

  .ansatt:not(.ansatt--tom):hover .ansatt__foto::after {
    border-color: color-mix(in srgb, var(--blue) 22%, transparent);
  }

  .ansatt:not(.ansatt--tom):hover .ansatt__foto img { transform: scale(1.03); }

  .ansatt:not(.ansatt--tom):hover .ansatt__pil {
    animation: pilRist 0.5s ease-in-out infinite;
  }
}

/* ------------------------------------------------------------ Dialog --- */
/* <dialog> med showModal() gir fokusfelle, Esc og bakgrunn uten at vi
   skriver noe av det selv. Vi styrer bare utseendet. */

/* Bildet ved siden av teksten, ikke over. Et 16:9-bilde på tvers av hele
   dialogen spiste så mye høyde at teksten måtte scrolles; stående ved siden
   av får begge plass på én skjerm. */
.modal {
  width: min(920px, calc(100vw - 2 * var(--pad)));
  /* svh, ikke vh: på mobil endrer vh seg når adresselinja glir inn og ut,
     og da ble popupen sentrert på nytt midt i vendingen. */
  max-height: min(86vh, 900px);
  max-height: min(86svh, 900px);
  border: 1px solid color-mix(in srgb, var(--ink) 22%, transparent);
  border-radius: var(--radius-lg);
  background: var(--boks);
  color: var(--ink);
  box-shadow: 0 40px 90px -30px color-mix(in srgb, var(--blue-deep) 60%, transparent);
  overflow: auto;
  overscroll-behavior: contain;

  grid-template-columns: minmax(0, 34%) minmax(0, 1fr);
  align-items: start;
  /* Polstring rundt hele innholdet, så bildet står som et felt inne i
     dialogen og ikke går helt ut i kantene. */
  padding: clamp(0.75rem, 1.4vw, 1.1rem);
  gap: clamp(0.75rem, 1.4vw, 1.1rem);
}

/* display bare når dialogen er åpen. Setter man den på .modal, overstyrer
   den nettleserens egen «dialog:not([open]) { display: none }» — og da står
   alle dialogene synlige nederst på sida.

   fixed med inset 0 og margin auto sentrerer dialogen i skjermen uansett
   hvor langt ned man har scrollet. Nettleseren gjør dette selv for modale
   dialoger, men bare så lenge vi ikke overstyrer position — og det er
   nettopp det en «position: relative» for lukkeknappens skyld ville gjort.
   fixed gir knappen det samme utgangspunktet. */
.modal[open] {
  display: grid;
  position: fixed;
  inset: 0;
  margin: auto;
  /* Eget lag fra start. Uten det bygger Safari laget først når 3D-vendingen
     begynner, og første åpning kunne flimre. */
  will-change: transform;
}

/* Sida bak en åpen popup (se laasScroll i main.js). scrollbar-gutter
   holder plass til rullefeltet på desktop, så sida ikke hopper sidelengs
   når det forsvinner. */
html { scrollbar-gutter: stable; }
html.scroll-laast { overflow: hidden; }
html.scroll-laast body { overflow: hidden; overscroll-behavior: none; }

/* Scrolling inni popupen skal ikke smitte over på sida bak. */
.modal { overscroll-behavior: contain; }

.modal::backdrop {
  /* Logoblå, ikke --blue-deep: den dype tonen er nesten indigo, og over den
     kremhvite sida leser den lilla. */
  background: color-mix(in srgb, var(--blue) 60%, transparent);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.modal__foto {
  overflow: hidden;
  border-radius: var(--radius);
  aspect-ratio: 4 / 5;
  height: 100%;
  background: #f0eee6; background: color-mix(in srgb, var(--ink) 8%, var(--cream));
}

.modal__foto img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--pos, 50% 30%);
  display: block;
}

.modal__tekst {
  padding: clamp(0.75rem, 1.6vw, 1.4rem) clamp(0.75rem, 1.6vw, 1.4rem)
           clamp(0.75rem, 1.6vw, 1.4rem) clamp(0.5rem, 1vw, 0.9rem);
}

.modal__tekst h3 {
  font-size: var(--fs-h2);
  margin-bottom: 0.35rem;
}

.modal__tekst p { color: var(--ink-soft); }
.modal__tekst p + p { margin-top: 1rem; }

.modal__lukk {
  position: absolute;
  top: clamp(0.75rem, 1.5vw, 1.25rem);
  right: clamp(0.75rem, 1.5vw, 1.25rem);
  z-index: 1;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: 100px;
  background: var(--boks);
  color: var(--ink);
  box-shadow: var(--shadow);
  transition: background 0.3s var(--ease), color 0.3s var(--ease);
}

.modal__lukk svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
}

.modal__lukk:hover {
  background: var(--ink);
  color: var(--cream);
}

/* Inngangen: kortet i rutenettet vender seg én gang og blir til popupen.

   Selve bevegelsen styres fra js/main.js, ikke herfra — den må starte
   nøyaktig der kortet ligger på skjermen, og den posisjonen kan bare måles
   når man klikker. CSS-en her holder baksiden og bakgrunnen.

   Utgangen er raskere og uten vending. JS-en legger på .lukker og venter til
   animasjonen er ferdig før dialogen faktisk stenges — uten det ville den
   forsvinne momentant, siden display går rett til none. */
.modal[open]::backdrop { animation: modalBak 0.3s var(--ease); }

/* Baksiden av kortet: logoblå, som et spillkort man snur. Dekker innholdet
   den første halvdelen av vendingen, altså mens kortet vender bort fra oss —
   da ser man aldri teksten speilvendt, og byttet fra kort til popup skjer
   skjult bak den. */
.modal::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 5;
  border-radius: inherit;
  background: var(--blue-flate) url("/media/logo-hval-hvit.svg") no-repeat center;
  background-size: min(46%, 260px) auto;
  opacity: 0;
  pointer-events: none;

  /* Speilvendt med vilje. Baksiden vises bare mens kortet er snudd bort fra
     oss, og da er alt på den speilvendt av selve rotasjonen — hvalen ville
     ellers svømt feil vei. To speilinger gir riktig vei. */
  transform: scaleX(-1);
}

/* Varigheten må stemme med VENDING i js/main.js — baksiden skal slukke
   nøyaktig halvveis i vendingen. */
.modal[open]::after { animation: kortBakside 0.46s linear; }

/* Veien ut er kort og uten vending — kortet legges rett tilbake. Baksiden
   skal derfor ikke vises; den hører til snuingen. */
.modal.lukker::backdrop { animation: modalBakUt 0.24s var(--ease) forwards; }
.modal.lukker::after { animation: none; opacity: 0; }

/* Teksten glir ned og under bildet mens dialogen er på vei tilbake. Ren
   transform, så ingenting flyttes i layouten. */
.modal.lukker .modal__tekst {
  transform: translateY(35%);
  opacity: 0;
  transition: transform 0.24s var(--ease), opacity 0.16s var(--ease);
}

.modal.lukker .modal__lukk {
  opacity: 0;
  transition: opacity 0.12s var(--ease);
}

/* Ved 35 % står kortet på høykant og er usynlig. Der byttes baksiden bort,
   og popupen er allerede snudd riktig vei når den kommer til syne.
   Vendingen i JS-en går lineært fram til akkurat dette punktet, så 35 % av
   tiden svarer til høykant i vinkelen. De to tallene hører sammen: endrer du
   det ene, må du endre det andre. */
@keyframes kortBakside {
  0%,    34.9% { opacity: 1; }
  35%,   100%  { opacity: 0; }
}


@keyframes modalBak   { from { opacity: 0; } }
@keyframes modalBakUt { to   { opacity: 0; } }

/* Smale skjermer: bildet legger seg over teksten igjen. Der er det høyde
   nok å scrolle på, og en stående spalte ville blitt for smal til begge. */
@media (max-width: 700px) {
  .modal { grid-template-columns: minmax(0, 1fr); }
  .modal__foto { aspect-ratio: 3 / 2; height: auto; }
}

.member__role {
  font-size: var(--fs-label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--red);
  margin-bottom: 1rem;
}

.member__mail {
  /* Luft opp mot teksten over. inline-block fordi en ren inline-lenke ikke
     tar imot margin i toppen — den ville ligget klistret til avsnittet. */
  display: inline-block;
  margin-top: 1.5rem;
  font-weight: 600;
  border-bottom: 1.5px solid var(--line);
  padding-bottom: 2px;
  transition: border-color 0.3s var(--ease), color 0.3s var(--ease);
}

/* Står den i en rad sammen med klistremerket, gir raden luften i stedet. */
.member__foot .member__mail { margin-top: 0; }

.member__mail:hover { color: var(--red); border-color: var(--red); }

.member__foot {
  margin-top: 1.5rem;
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2.5vw, 2rem);
  flex-wrap: wrap;
}

/* ------------------------------------------------------------ Klistremerke --- */
/* Låner pilleformen fra .btn så den hører hjemme på siden, men beholder
   et snev av klistremerke: liten skjevhet og hard skygge. Retter seg opp
   når du peker på den. */

.sticker {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  padding: 0.55em 1.15em;
  border-radius: 100px;
  background: var(--red);
  color: var(--cream);
  font-size: var(--fs-small);
  font-weight: 600;
  letter-spacing: -0.01em;
  white-space: nowrap;
  transform: rotate(-2.5deg);
  box-shadow: 2px 3px 0 var(--ink);
  transition: transform 0.35s var(--ease), box-shadow 0.35s var(--ease);
}

.sticker:hover {
  transform: rotate(0deg) translateY(-2px);
  box-shadow: 3px 5px 0 var(--ink);
}

.sticker__star {
  width: 1.1em;
  flex: none;
  animation: spin 14s linear infinite;
  /* Stjerna er rød på gjennomsiktig — gjør den kremhvit mot rød bakgrunn */
  filter: brightness(0) invert(1);
}

.sticker strong { font-weight: 700; }

/* -------------------------------------------------- Sidehode med illustrasjon --- */

.pagehead__row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: clamp(1.5rem, 4vw, 4rem);
  align-items: center;
}

/* ------------------------------------------------------------- Sidehode --- */

.pagehead {
  padding-top: clamp(3rem, 8vh, 7rem);
  padding-bottom: clamp(2.5rem, 6vh, 5rem);
}

.pagehead h1 {
  font-size: var(--fs-h1);
  text-transform: uppercase;
  letter-spacing: -0.045em;
}

.pagehead .lead { margin-top: 1.5rem; max-width: 44ch; color: var(--ink-soft); }

/* Stjerna står der de andre sidene har illustrasjonen sin, ytterst til
   høyre. Måles mot h1, ikke mot --fs-h2 som i seksjonsoverskriftene, ellers
   blir den forsvinnende liten ved siden av sidetittelen.

   Spanen rundt finnes fordi de to bevegelsene ikke kan dele element: bildet
   spinner med en CSS-animasjon, mens pusten ved hover skalerer spanen fra
   js/main.js. To animasjoner kan ikke styre samme transform. */
.pagehead__star {
  display: block;
  flex: none;
  width: calc(var(--fs-h1) * 0.95);
  margin-left: auto;
}

.pagehead__star .star {
  display: block;
  width: 100%;
}

/* På mobil er den lengste overskriften («PROSJEKTER») nesten like bred som
   skjermen. Full stjerne + vanlig mellomrom dyttet stjerna 23 px utenfor
   kanten, så begge krymper her. */
@media (max-width: 520px) {
  .pagehead__row { gap: 0.6rem; }
  /* Stjerna roterer, og på skrå er den ~40 % bredere enn rett opp. Derfor
     mindre her enn tallene alene skulle tilsi. */
  .pagehead__star { width: calc(var(--fs-h1) * 0.46); }
  /* Gulvet i --fs-h1 er for stort for «PROSJEKTER» på 375–390 px: ordet
     alene fylte nesten hele bredden. Følger skjermbredden her nede. */
  .pagehead h1 { font-size: min(var(--fs-h1), 12.5vw); }
}

/* ------------------------------------------------------------- Logoer --- */

/* Logostripe rett under hero.
   Logoene har vidt forskjellige former — brede ordmerker (Volvo), runde merker
   (DNT) og mørke skjold med hvit utsparet tekst (Norsk Mat). Derfor får hver
   logo samme *boks* å fylle, ikke samme høyde: object-fit ordner resten.
   Trenger en enkeltlogo finjustering, sett --s på den i HTML-en. */

.logos {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  /* Én verdi styrer luften mellom merkene, og den brukes også i regnestykket
     for hvor mange som får plass per rad lenger ned. Strammere enn før:
     med 3.5rem ble raden ~1250 px bred, og på en skjerm rundt 1200 px falt
     det siste merket ned alene. */
  --logo-gap: clamp(1.25rem, 2.6vw, 3rem);
  gap: var(--logo-gap);
}

.logos li { display: flex; align-items: center; }

/* Sju merker deler seg ikke pent av seg selv: flex fyller raden grådig, så
   det som ikke får plass blir stående alene på neste linje. Under bredden
   der alle sju går inn, låses antallet per rad i stedet — fire og fire gir
   4 + 3, og begge radene sentreres av justify-content på .logos. */
@media (max-width: 1240px) {
  .logos li {
    flex: 0 0 calc((100% - var(--logo-gap) * 3) / 4);
    justify-content: center;
  }

  /* Kolonnen er nå smalere enn de bredeste merkene (Volvo er ~257 px ved
     full høyde), så taket må følge kolonnen i stedet for å stå fast. */
  .logos img { max-width: 100%; }
}

/* Fire i bredden blir for smått her; to og to gir merker man ser. */
@media (max-width: 620px) {
  .logos li { flex-basis: calc((100% - var(--logo-gap)) / 2); }
}

.logos img {
  /* Felles høyde som utgangspunkt — forutsigbart, og det var denne
     størrelsen som satt best. --s justerer enkeltlogoer optisk:
     runde merker trenger mer høyde enn brede ordmerker for å veie likt.
     Alt i piksler, ikke prosent: prosenthøyde løste seg ikke mot raden
     og gjorde det kvadratiske DNT-merket kjempestort. */
  height: calc(clamp(22px, 3vw, 36px) * var(--s, 1));
  width: auto;
  /* Kun sikkerhetsnett. Volvo er bredest (~257 px ved full høyde), så
     grensen ligger over den — ellers ville den blitt lavere enn resten. */
  max-width: min(280px, 40vw);
  object-fit: contain;
  /* Ekte gråtone — beholder lysforskjellene, så utsparet hvit tekst
     overlever. (brightness(0) gjorde dem til svarte klumper.) */
  filter: grayscale(1);
  opacity: 0.5;
  transition: opacity 0.4s var(--ease), filter 0.4s var(--ease);
}

.logos li:hover img { opacity: 1; filter: none; }

/* Montreux er et tynt, bredt ordmerke i parentes og forsvant ved siden av de
   tunge merkene på smale skjermer. Litt større der. */
@media (max-width: 700px) {
  .logo--montreux img { --s: 1.4; }
}

.logos__label {
  text-align: center;
  font-size: var(--fs-label);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--ink-soft);
  margin-bottom: clamp(1.25rem, 2.5vw, 2rem);
}

.logostrip { padding-block: calc(var(--section) * 0.55); }

/* --------------------------------------------------------------- CTA --- */

/* Lys flate, ikke mørk. Nederst på hver side står allerede logostripa,
   denne og den blå footeren tett — tre mørke felt på rad tok kraften ut av
   footeren. Nå er den røde knappen det eneste som roper her. */
.cta {
  background: var(--boks);
  color: var(--ink);
  border-radius: var(--radius-lg);
  padding: clamp(2.5rem, 7vw, 6rem);
  display: grid;
  gap: 2rem;
  align-items: end;
  grid-template-columns: 1fr auto;
  box-shadow: var(--shadow);
}

.cta h2 {
  font-size: var(--fs-h2);
  text-transform: uppercase;
  max-width: 16ch;
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  background: var(--red);
  color: var(--cream);
  border-radius: 100px;
  padding: 0.85em 1.6em;
  font-weight: 600;
  white-space: nowrap;
  transition: transform 0.35s var(--ease), background 0.35s var(--ease);
}

/* Rød i ro, logoblå ved hover. Kremhvit flate var det opplagte valget mot
   den lyse boksen, men da forsvant knappen nesten i bakgrunnen sin. */
.btn:hover { transform: translateY(-3px); background: var(--blue); color: var(--cream); }

/* -------------------------------------------------------------- Footer --- */

/* Blå flate med rett overkant. Bølgen som lå her før krevde tre lag —
   selve flaten i ::after, en maske i to deler og et skyggelag under — og
   drev en maske-animasjon som malte om for hvert bilde. Alt det er borte;
   footeren er nå en helt vanlig flate. */

.footer {
  background: var(--blue-flate);
  color: var(--cream);
  padding-block: clamp(3rem, 6vw, 5rem) 2rem;
}


.footer__grid {
  display: grid;
  gap: clamp(2rem, 4vw, 3rem);
  grid-template-columns: 1.6fr repeat(3, minmax(120px, 1fr));
}

.footer__brand img { height: 30px; width: auto; margin-bottom: 1.2rem; }

.footer__brand address {
  font-style: normal;
  color: color-mix(in srgb, var(--cream) 76%, transparent);
  font-size: var(--fs-small);
  line-height: 1.7;
}

.footer__col h4 {
  font-size: var(--fs-label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  /* Rødt mot blått blir grøtete i så liten tekst — den varme kremfargen
     holder seg i paletten og er langt lettere å lese. */
  color: var(--cream-warm);
  margin-bottom: 1rem;
}

.footer__col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; }

.footer__col a {
  font-size: var(--fs-small);
  color: color-mix(in srgb, var(--cream) 76%, transparent);
  transition: color 0.3s var(--ease);
}

.footer__col a:hover { color: var(--cream); }

.footer__base {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: space-between;
  margin-top: clamp(3rem, 6vw, 5rem);
  padding-top: 1.5rem;
  border-top: 1px solid color-mix(in srgb, var(--cream) 24%, transparent);
  font-size: var(--fs-label);
  color: color-mix(in srgb, var(--cream) 70%, transparent);
  letter-spacing: 0.04em;
}


/* ---------------------------------------------------- Scroll-avsløring --- */

[data-reveal] {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 0.9s var(--ease), transform 0.9s var(--ease);
}

[data-reveal].is-in { opacity: 1; transform: none; }

/* ---------------------------------------------------------- Responsivt --- */

@media (max-width: 1080px) {
  .grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 700px) {
  .cats { grid-template-columns: 1fr; }
  /* 16:9 blir en stripe når kortet får hele skjermbredden. */
  .cat { aspect-ratio: 4 / 3; }
  .vids { grid-template-columns: 1fr; }
}

@media (max-width: 520px) {
  .grid--4 { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 860px) {
  .row,
  .cta { grid-template-columns: 1fr; }

  /* Teamet: to i bredden når tre blir for smalt. Ett kort i bredden lenger
     ned — den regelen står etter denne i fila, ellers ville de to vinne på
     smale skjermer der begge treffer. */
  .ansatte { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* Teksten og de tre feltene stables når spalten blir for smal til begge. */
  .artist__under { grid-template-columns: minmax(0, 1fr); }
  .row:nth-child(odd) .row__media { order: 0; }
  .cta { align-items: start; }


  .pagehead__row { grid-template-columns: 1fr; }

  /* Sidehodet på Profiler har en stjerne til høyre, ikke en bred
     illustrasjon. Den skal bli stående ved siden av overskriften — stables
     den, havner den alene på en linje og tar unødig mye høyde.

     Overskriften brekker i to linjer her, så det er høyde å ta av: stjerna
     kan holde nesten full størrelse. */
  .pagehead__row:has(.pagehead__star) { grid-template-columns: 1fr auto; }
  .pagehead__star { width: calc(var(--fs-h1) * 0.85); }

  .footer__grid { grid-template-columns: 1fr 1fr; }
  .footer__brand { grid-column: 1 / -1; }

  /* Mobilmeny */
  .nav__toggle {
    display: block;
    margin-left: auto;
    width: 30px;
    height: 30px;
    position: relative;
    z-index: 1;
  }

  .nav__toggle span {
    position: absolute;
    left: 3px;
    width: 24px;
    height: 2px;
    background: var(--ink);
    transition: transform 0.4s var(--ease), opacity 0.3s var(--ease);
  }

  .nav__toggle span:nth-child(1) { top: 11px; }
  .nav__toggle span:nth-child(2) { top: 18px; }

  .nav[data-open="true"] .nav__toggle span:nth-child(1) { transform: translateY(3.5px) rotate(45deg); }
  .nav[data-open="true"] .nav__toggle span:nth-child(2) { transform: translateY(-3.5px) rotate(-45deg); }

  /* Menyen skal ligge UNDER baren, ikke begynne under den. Startet den på
     --nav-h, ble det et glipp mellom bølgekanten og menyflaten der man så
     rett på sideinnholdet. Nå går panelet helt til toppen og skyves ned med
     polstring i stedet, mens baren males oppå.

     For at det skal virke må .nav__inner slippe sin egen stablekontekst, så
     panelet kan legge seg bak .nav__bg. Logo og hamburger må da løftes
     tilbake over baren hver for seg. */
  .nav__inner { z-index: auto; }
  .nav__logo { position: relative; z-index: 1; }

  .nav__links {
    position: fixed;
    inset: 0 0 auto 0;
    z-index: -1;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    background: var(--cream);
    padding: var(--pad);
    padding-top: calc(var(--nav-h) + 0.5rem);
    border-bottom: 1px solid var(--line);
    transform: translateY(-100%);

    /* visibility tar lenkene ut av tabrekkefølgen når menyen er lukket —
       ellers kan man tabbe seg inn i et panel som står utenfor skjermen.
       Slås av først når utglidningen er ferdig, og på med en gang ved
       åpning, så animasjonen fortsatt synes. */
    visibility: hidden;
    transition: transform 0.5s var(--ease), visibility 0s linear 0.5s;
  }

  .nav[data-open="true"] .nav__links {
    transform: none;
    visibility: visible;
    transition: transform 0.5s var(--ease), visibility 0s;
  }

  .nav__links a {
    font-size: clamp(1.6rem, 7vw, 2.4rem);
    font-weight: 700;
    letter-spacing: -0.035em;
    padding-block: 0.35em;
    width: 100%;
    border-bottom: 1px solid var(--line);
  }

  .nav__links a::after { display: none; }

  .nav__cta {
    border: 0;
    padding: 0.35em 0 !important;
    color: var(--red);
  }

}

@media (max-width: 520px) {
  /* Ett kort i bredden, men lavere bilder: i 4:5 fyller ett kort nesten
     hele skjermen, og da ser man ikke at det finnes flere under. Liggende
     format gir plass til to av gangen. */
  .ansatte { grid-template-columns: minmax(0, 1fr); }
  .ansatt__foto { aspect-ratio: 4 / 3; }

  /* Kortet er nå like bredt som skjermen, og da blir skalaen fra tre
     smale spalter for spinkel. Navn og stilling opp et hakk hver. */
  .ansatt__navn { font-size: 1.6rem; }
  .ansatt__rolle { font-size: 1rem; }
  .ansatt__pil { width: 34px; height: 34px; }

  /* Footeren beholder to spalter: én spalte ga fire lister under hverandre,
     nesten to skjermhøyder med lenker. Adressen tar hele bredden. */
  .footer__grid { grid-template-columns: 1fr 1fr; gap: 2rem 1.25rem; }
}

/* ------------------------------------------------------- Sort side ---
   /musikk på sort, som musikkbolken på forsiden. Nav og footer er som før;
   bare innholdet snus: krem tekst, dempet brødtekst, rød stjerne og etiketter
   beholdes. Plassholderne får den mørke varianten fra forsiden. */
.side-sort { background: var(--black); color: var(--cream); }

.side-sort .pagehead h1,
.side-sort .artistkort__navn,
.side-sort .artistkort__mer { color: var(--cream); }

.side-sort .artistkort__tekst p { color: color-mix(in srgb, var(--cream) 72%, transparent); }

.side-sort .artistkort__media { box-shadow: 0 18px 38px -18px color-mix(in srgb, #000 80%, transparent); }

.side-sort [data-placeholder] {
  background:
    repeating-linear-gradient(45deg,
      transparent 0 14px,
      color-mix(in srgb, var(--cream) 4%, transparent) 14px 28px),
    color-mix(in srgb, var(--cream) 6%, var(--black));
}

/* «Skal vi lage noe sammen?» som mørk boks i stedet for den lyse. */
.side-sort .cta {
  background: color-mix(in srgb, var(--cream) 5%, var(--black));
  color: var(--cream);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--cream) 12%, transparent);
}

/* ------------------------------------------------------ Prosjektkort ---
   Ett hjem per prosjekt, flere dører inn: kategorisidene (Design og
   animasjon, Fysiske produkter, Strategi) viser kort med én linje om hva
   akkurat det fagfeltet gjorde, og lenker til prosjektets egen side. Da
   står hele historien ett sted, og overlappen mellom kategoriene blir en
   oversikt i stedet for tre ulike tekster om det samme. */
.pkort-seksjon { padding-top: clamp(1.5rem, 4vh, 3rem); }
.pkort-seksjon + .pkort-seksjon { padding-top: clamp(3rem, 8vh, 5.5rem); }

.pkort-tittel {
  font-size: var(--fs-h3);
  font-weight: 700;
  letter-spacing: -0.02em;
  margin-bottom: clamp(1.25rem, 3vw, 2rem);
}

.pkorter {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(2rem, 4vw, 3rem) var(--gap);
}

.pkort { display: grid; align-content: start; gap: 0.4rem; color: inherit; }

.pkort__media {
  overflow: hidden;
  border-radius: var(--radius);
  aspect-ratio: 16 / 9;
  margin-bottom: 0.55rem;
  background: #f0eee6; background: color-mix(in srgb, var(--ink) 8%, var(--cream));
  box-shadow: var(--shadow);
}

.pkort__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--pos, 50% 50%);
  display: block;
  transition: transform 0.6s var(--ease);
}

.pkort__merke {
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--red);
}

.pkort__navn { font-size: var(--fs-h3); font-weight: 700; letter-spacing: -0.02em; line-height: 1.1; }
.pkort__vinkel { color: var(--ink-soft); max-width: 46ch; }

@media (hover: hover) and (pointer: fine) {
  a.pkort:hover .pkort__media img { transform: scale(1.04); }
  a.pkort:hover .pkort__navn { color: var(--red); }
}

@media (max-width: 900px) { .pkorter { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 600px) { .pkorter { grid-template-columns: minmax(0, 1fr); } }

/* Fagfeltene et prosjekt hører til, som lenker tilbake til kategoriene. */
.fagfelt {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 1.25rem;
  padding: 0;
  list-style: none;
}

.fagfelt a {
  display: inline-block;
  padding: 0.45rem 1rem;
  border-radius: 100px;
  border: 1.5px solid color-mix(in srgb, var(--ink) 28%, transparent);
  font-size: var(--fs-small);
  font-weight: 600;
  color: var(--ink-soft);
  transition: border-color 0.25s var(--ease), color 0.25s var(--ease);
}

.fagfelt a:hover { border-color: var(--ink); color: var(--ink); }

/* Bilderad på en prosjektside. */
.pbilder {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--gap);
  padding-top: var(--section);
}

.pbilder img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: var(--pos, 50% 50%);
  border-radius: var(--radius);
  display: block;
}

/* To bilder i 16:9 i stedet for tre stående. */
.pbilder--to { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.pbilder--to img { aspect-ratio: 16 / 9; }
.pbilder--en { grid-template-columns: minmax(0, 1fr); }
.pbilder--en img { aspect-ratio: 16 / 9; }
.pkort-seksjon + .pbilder, .pagehead + .pbilder { padding-top: 0; }

@media (max-width: 600px) { .pbilder { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
@media (max-width: 600px) { .pbilder--to { grid-template-columns: minmax(0, 1fr); } }

/* ----------------------------------------------------------- Sjekk ut ---
   Nederst på hver artistside («Sjekk ut») og hver videoprosjektside
   («Se også»): tre andre å gå videre til. Fargene arves fra
   sida (currentColor og opacity), så samme blokk står like godt på krem,
   på GK-sort og på tre40fire-blått. */
.sjekk {
  padding-top: clamp(2.5rem, 7vh, 5rem);
  padding-bottom: var(--section);
}

.sjekk__tittel {
  font-size: var(--fs-h3);
  font-weight: 700;
  letter-spacing: -0.02em;
  margin-bottom: clamp(1.25rem, 3vw, 2rem);
}

.sjekk__rad {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--gap);
}

.sjekk__kort { display: grid; gap: 0.35rem; color: inherit; }

.sjekk__media {
  overflow: hidden;
  border-radius: var(--radius);
  aspect-ratio: 16 / 9;
  margin-bottom: 0.5rem;
  background: var(--black);
}

.sjekk__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.6s var(--ease);
}

.sjekk__navn { font-size: var(--fs-h3); font-weight: 700; letter-spacing: -0.02em; line-height: 1.1; }

.sjekk__tag {
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.7;
}

@media (hover: hover) and (pointer: fine) {
  .sjekk__kort:hover .sjekk__media img { transform: scale(1.05); }
}

/* Mobil: én rad man sveiper gjennom i stedet for tre store kort under
   hverandre. Neste kort stikker fram i kanten, så man ser at det er flere. */
@media (max-width: 700px) {
  .sjekk__rad {
    display: flex;
    gap: 0.9rem;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    overscroll-behavior-x: contain;
    margin-inline: calc(var(--pad) * -1);
    padding-inline: var(--pad);
    scroll-padding-inline: var(--pad);
    scrollbar-width: none;
  }
  .sjekk__rad::-webkit-scrollbar { display: none; }
  .sjekk__kort { flex: 0 0 72%; scroll-snap-align: start; }
}

/* ===================================================== Artistunivers ---
   Hver artist under /musikk/ kan ha sitt eget rom inni Hvalen-sida: egne
   farger, egen grafikk, samme byggeklosser. Nav og footer er Hvalen sine,
   så det leser som et univers *inni* sida, ikke en ny side.

   <body class="univers univers-xxx"> setter fargene; byggeklossene (u-*)
   leser dem. Ny artist = ny fargeblokk + eget hode, resten er gjenbruk:

     --u-bunn    bakgrunn
     --u-sterk   overskrifter og navn
     --u-tekst   brødtekst (dempet)
     --u-aksent  streker, etiketter, hover
     --u-flate   kontaktboksen                                            */
.univers {
  background: var(--u-bunn);
  color: var(--u-sterk);
}

.univers .backlink { color: var(--u-tekst); }
.univers .backlink:hover { color: var(--u-aksent); }

.u-ingress {
  max-width: 46ch;
  margin: clamp(2rem, 5vh, 3.5rem) auto 0;
  text-align: center;
  font-size: var(--fs-lead);
  line-height: 1.5;
  color: var(--u-tekst);
}

.u-seksjon { padding-block: clamp(2.5rem, 7vh, 5rem); }

/* Seksjonstitler uten merke foran. En strek ved hver tittel ble for mye.
   Streetboys har stjerna si her, se det universet. */
.u-tittel {
  display: flex;
  align-items: center;
  gap: 0.6em;
  font-size: var(--fs-h3);
  font-weight: 700;
  letter-spacing: -0.02em;
  margin-bottom: clamp(1.25rem, 3vw, 2rem);
}

/* -- Musikkvideoer: den første stor, resten to og to -- */
.u-videoer {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem) var(--gap);
}

.u-video { display: grid; gap: 0.9rem; color: inherit; }
.u-video--stor { grid-column: 1 / -1; }
.u-video__media {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius);
  aspect-ratio: 16 / 9;
  background: var(--black);
  box-shadow: 0 0 0 1px transparent;
  transition: box-shadow 0.3s var(--ease);
}

.u-video__media video,
.u-video__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.u-video__tekst { display: grid; gap: 0.3rem; }
.u-video__tekst b { font-size: var(--fs-h3); letter-spacing: -0.02em; line-height: 1.15; }
.u-video__tekst span { color: var(--u-tekst); max-width: 52ch; }

.u-video__yt {
  justify-self: start;
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--u-aksent);
}

@media (hover: hover) and (pointer: fine) {
  /* Bare på lenker: et klipp uten lenke er ikke klikkbart og skal ikke se
     ut som om det er det. */
  a.u-video:hover .u-video__media { box-shadow: 0 0 0 2px var(--u-aksent); }
}

/* -- Spotify: bare spilleren, smalere enn spalten og med ekstra luft over
   og under, så den står som et pusterom. -- */
.u-spotify {
  display: grid;
  justify-items: center;
  padding-block: clamp(4rem, 12vh, 9rem);
}

.u-spotify__spiller {
  width: min(100%, 720px);
  height: 452px;          /* Spotify sin høyde for spiller med låtliste */
  border: 0;
  border-radius: var(--radius);
  background: var(--black);
}

/* -- Kontakt og booking nederst: to felt side om side. Adressen er det
   største her — det er den man kom for. -- */
.u-kontakt {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.5rem, 4vw, 3rem);
  padding: clamp(2rem, 5vw, 4rem);
  border-radius: var(--radius-lg);
  background: var(--u-flate);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--u-aksent) 45%, transparent);
}

.u-kontakt__felt { display: grid; gap: 0.5rem; min-width: 0; }

.u-kontakt__etikett {
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--u-aksent);
}

.u-kontakt__mail {
  font-size: var(--fs-h3);
  font-weight: 700;
  letter-spacing: -0.02em;
  overflow-wrap: anywhere;
  color: var(--u-sterk);
  transition: color 0.3s var(--ease);
}

a.u-kontakt__mail:hover { color: var(--u-aksent); }

@media (max-width: 760px) {
  .u-videoer,
  .u-kontakt { grid-template-columns: minmax(0, 1fr); }
}

/* ------------------------------------------ Univers: Gjenfødt Kultur ---
   GK-grønt på nesten sort, og storkene og logoen fra plateuniverset. */
.univers-gk {
  --u-bunn:   #0d0d0f;
  --u-sterk:  var(--cream);
  --u-tekst:  color-mix(in srgb, var(--cream) 78%, transparent);
  --u-aksent: #2f9e44;
  --u-flate:  color-mix(in srgb, var(--cream) 4%, #0d0d0f);
}

/* Hover på GK-videoene: bare den grønne rammen (felles for universene),
   ikke lenger det grønne gradient map-filteret over hele klippet. */

/* Hode: stork | logo | stork, som i porteføljen */
.gk-hode {
  padding-top: clamp(2rem, 5vh, 4rem);
  padding-bottom: clamp(2rem, 5vh, 4rem);
}

.gk-hode__rad {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(1rem, 3vw, 3rem);
  margin-top: clamp(1rem, 3vh, 2rem);
}

.gk-hode__stork {
  flex: none;
  width: clamp(70px, 11vw, 170px);
  height: auto;
}

.gk-hode__stork--speil { transform: scaleX(-1); }

.gk-hode__midt {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.gk-hode h1 { margin: 0; width: min(100%, 620px); }
.gk-hode h1 img { width: 100%; height: auto; display: block; }

.gk-hode__sts {
  width: min(48%, 290px);
  height: auto;
  margin-top: 0.4rem;
}

/* STS */
.gk-sts__tittel img {
  width: clamp(110px, 14vw, 170px);
  height: auto;
}

.gk-sts__tittel span {
  font-size: var(--fs-small);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--u-tekst);
}

.gk-sts__banner {
  overflow: hidden;
  border-radius: var(--radius);
  aspect-ratio: 21 / 9;
  background: var(--black);
}

.gk-sts__banner video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.gk-sts__rad {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 4rem);
  align-items: center;
  margin-top: clamp(2rem, 5vw, 4rem);
}

.gk-sts__tekst { display: grid; gap: 1rem; max-width: 52ch; color: var(--u-tekst); }

.gk-sts__lenke {
  justify-self: start;
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--u-aksent);
}

.gk-sts__foto {
  width: 100%;
  height: auto;
  border-radius: var(--radius);
}

@media (max-width: 760px) {
  .gk-sts__rad { grid-template-columns: minmax(0, 1fr); }
  .gk-hode__stork { width: clamp(44px, 14vw, 70px); }
}

/* ----------------------------------------------------- Univers: Dinho ---
   Sort bunn, så den røde veggen i portrettet er eneste farge på sida.
   Beige fra vesten som aksent. */
.univers-dinho {
  --u-bunn:   #000;
  --u-sterk:  var(--cream);
  --u-tekst:  color-mix(in srgb, var(--cream) 74%, transparent);
  --u-aksent: #D4BDB1;
  --u-flate:  #0e0e0e;
}

.dinho-hode {
  padding-top: clamp(2rem, 5vh, 4rem);
  padding-bottom: clamp(1rem, 3vh, 2rem);
  text-align: center;
}

.dinho-hode .backlink { display: flex; width: fit-content; }

.dinho-hode__navn {
  margin: clamp(1rem, 3vh, 2rem) 0 clamp(1rem, 3vw, 2rem);
  font-size: clamp(5rem, 22vw, 18rem);
  text-transform: uppercase;
  letter-spacing: -0.05em;
  line-height: 0.85;
}

.dinho-hode__foto {
  display: block;
  width: min(100%, 1100px);
  height: auto;
  margin-inline: auto;
  border-radius: var(--radius);
}

/* ------------------------------------------------ Univers: Streetboys ---
   Fra den grafiske profilen deres: kremhvit logo på kullsvart og røykbrunt,
   oransje tekst på beige papir, og den mørkerøde stjerna som eget merke.
   Analogt og varmt, som filmkornet i bannerne og «Fri». */
.univers-sb {
  --sb-papir:   #E4D9C2;
  --sb-oransje: #EE9C22;
  --sb-rod:     #920516;
  --u-bunn:   #181716;
  --u-sterk:  #E4D9C2;
  --u-tekst:  color-mix(in srgb, #E4D9C2 74%, transparent);
  --u-aksent: var(--sb-oransje);
  --u-flate:  var(--sb-papir);
}

.sb-hode {
  padding-top: clamp(2rem, 5vh, 4rem);
  padding-bottom: clamp(1rem, 3vh, 2rem);
}

.sb-hode__banner {
  margin: clamp(1rem, 3vh, 2rem) 0 0;
  overflow: hidden;
  border-radius: var(--radius);
}

.sb-hode__banner img { display: block; width: 100%; height: auto; }

/* Stjerna foran seksjonstitlene, i stedet for den vanlige streken. */
.univers-sb .u-tittel::before {
  content: "";
  flex: none;
  width: 0.75em;
  height: 1.05em;
  border-radius: 0;
  background: url("/media/musikk/streetboys/stjerne.png") center / contain no-repeat;
}

/* Kontaktboksen som et ark fra drikkemenyen: beige papir, mørk tekst og
   oransje etiketter. */
.univers-sb .u-kontakt { box-shadow: none; }
.univers-sb .u-kontakt__mail { color: var(--u-bunn); }

/* ------------------------------------------------- Univers: tre40fire ---
   Y2K: elektrisk blå og limegrønn rett fra logoklistremerket, gutta som
   animerte utklipp på rad, HIP-POP i flammer og raketten ved spilleren. */
.univers-344 {
  --t4-bla:   #0006FF;
  --t4-gronn: #24FF00;
  --u-bunn:   var(--t4-bla);
  --u-sterk:  #fff;
  --u-tekst:  color-mix(in srgb, #fff 82%, transparent);
  --u-aksent: var(--t4-gronn);
  --u-flate:  color-mix(in srgb, var(--black) 22%, var(--t4-bla));
}

.t4-hode {
  padding-top: clamp(2rem, 5vh, 4rem);
  padding-bottom: clamp(1rem, 3vh, 2rem);
}

.t4-hode__logo {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-top: clamp(1rem, 3vh, 2rem);
}

/* Klistremerket svever og vipper litt, som om det ligger i vann. */
.t4-hode h1 {
  margin: 0;
  width: min(80%, 520px);
  animation: t4Svev 6s ease-in-out infinite;
}

.t4-hode h1 img { width: 100%; height: auto; display: block; }

/* HIP-POP i flammer, som tittel over Spotify-spilleren. */
.t4-flamme {
  width: min(70%, 340px);
  height: auto;
  margin-bottom: clamp(1rem, 3vw, 2rem);
}

@keyframes t4Svev {
  0%, 100% { transform: translateY(0) rotate(-2deg); }
  50%      { transform: translateY(-10px) rotate(1.5deg); }
}

/* Gjengen på rad, stående på samme gulvlinje, litt omlagt. */
.t4-gjeng {
  display: flex;
  justify-content: center;
  align-items: flex-end;
  margin-top: clamp(1.5rem, 4vh, 3rem);
}

.t4-gutt {
  position: relative;
  margin-inline: clamp(-1.25rem, -1.5vw, -0.25rem);
  transition: opacity 0.35s var(--ease);
}

/* Grønn glød bak den som hovres. En vanlig gradient som tones inn med
   opacity — billig, i motsetning til drop-shadow på en animert GIF. */
.t4-gutt::before {
  content: "";
  position: absolute;
  inset: 5% -15% 0;
  z-index: -1;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--t4-gronn) 55%, transparent), transparent);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.35s var(--ease);
}

.t4-gutt img {
  display: block;
  height: clamp(110px, 22vw, 300px);
  width: auto;
  transform-origin: 50% 100%;
  transition: transform 0.45s cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* Navnet i samme stil som logoklistremerket: tunge, avrundede gemener
   presset inntil hverandre, blå fyll, limegrønn kontur og hvit kant ytterst.

   To lag, ingen filtre: den grønne konturen er text-stroke på selve navnet
   (paint-order legger den bak fyllet, så bokstavene ikke blir tynnere), og
   den hvite kanten er en kopi av navnet i ::before med tykkere hvit kontur.
   Et forsøk med kjedede drop-shadow-filtre fikk nettleseren til å krasje
   under sprett-animasjonen — filtre regnes ut på nytt for hvert bilde. */
.t4-gutt__navn {
  position: absolute;
  left: 50%;
  top: 0;
  z-index: 3;
  font-family: "Baloo 2", "Arial Rounded MT Bold", var(--font);
  font-size: clamp(1.8rem, 4.8vw, 4.2rem);
  font-weight: 800;
  letter-spacing: -0.07em;
  text-transform: lowercase;
  line-height: 1;
  white-space: nowrap;
  color: var(--t4-bla);
  -webkit-text-stroke: 0.17em var(--t4-gronn);
  paint-order: stroke fill;
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, 10%) scale(0.4) rotate(-14deg);
  transition:
    opacity 0.2s var(--ease),
    transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* Den hvite kanten: samme tekst rett bak, med kontur så tykk at den
   stikker ut forbi den grønne. z-index -1 holder seg inni navnet, siden
   transform gjør navnet til sin egen stacking context. */
.t4-gutt__navn::before {
  content: attr(data-navn);
  position: absolute;
  inset: 0;
  z-index: -1;
  color: #fff;
  -webkit-text-stroke: 0.34em #fff;
}

@media (hover: hover) and (pointer: fine) {
  /* De andre trer tilbake når én er i fokus. */
  /* opacity, ikke filter: gutta er animerte GIF-er, og et filter måtte
     vært regnet ut på nytt for hver ramme i alle fire. */
  .t4-gjeng:has(.t4-gutt:hover) .t4-gutt:not(:hover) { opacity: 0.45; }

  .t4-gutt:hover { z-index: 2; }
  .t4-gutt:hover img { transform: scale(1.08); }
  .t4-gutt:hover::before { opacity: 1; }

  .t4-gutt:hover .t4-gutt__navn {
    opacity: 1;
    transform: translate(-50%, -85%) scale(1) rotate(-6deg);
  }
}

/* Raketten tar av ved siden av spilleren — bare på brede skjermer, der
   det er plass til den. */
.univers-344 .u-spotify { position: relative; }

.t4-rakett {
  position: absolute;
  left: max(var(--pad), calc(50% - 360px - clamp(120px, 14vw, 200px) - 3rem));
  bottom: clamp(4rem, 12vh, 9rem);
  width: clamp(90px, 10vw, 150px);
  height: auto;
  animation: t4Rakett 4s ease-in-out infinite;
}

@keyframes t4Rakett {
  0%, 100% { transform: translateY(0) rotate(-6deg); }
  50%      { transform: translateY(-18px) rotate(-3deg); }
}

@media (max-width: 1100px) {
  .t4-rakett { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  [data-reveal] { opacity: 1; transform: none; }
  /* Dempingen kan bli — den er lys, ikke bevegelse. Forstørrelsen ryker. */
  .spotlight-video .row__media:hover { transform: none; }
}
