@charset "UTF-8";

/* ===========================================================================
   stil.css — tokens, reset og typografi
   Fotografportefølje for David · Kristensen IT

   Denne fila eier grunnlaget som alle tre sidene deler. Kategorimeny, masonry
   og lightbox hører hjemme i galleri.css; skjemaet i skjema.css.
   Se docs/design.md for begrunnelsene bak verdiene her.
   =========================================================================== */


/* ---------------------------------------------------------------------------
   1. Skrifter

   Selvhostet, aldri Google Fonts CDN — vi skal ikke overføre besøkendes
   IP-adresse til USA for å hente en skriftfil (GDPR, se docs/design.md).
   Statiske instanser framfor variable fonter: vi bruker tre faste vekter,
   og da er statiske filer mindre og mer forutsigbare.
   --------------------------------------------------------------------------- */

@font-face {
  font-family: 'Bodoni Moda';
  src: url('../assets/fonter/bodoni-moda-v28-latin-regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Instrument Sans';
  src: url('../assets/fonter/instrument-sans-v4-latin-regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Instrument Sans';
  src: url('../assets/fonter/instrument-sans-v4-latin-500.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}


/* ---------------------------------------------------------------------------
   2. Tokens
   --------------------------------------------------------------------------- */

:root {
  /* Farger — rene svart/hvitt, ingen aksentfarge.
     «Svart» er #111 og ikke #000: ren svart på ren hvit gir en hard kant
     som ser billig ut på skjerm. Aktiv tilstand, hover og fokus løses med
     typografi, vekt, opasitet og linjer — aldri med farge. */
  --papir:        #FFFFFF;                  /* bakgrunn, alltid */
  --blekk:        #111111;                  /* brødtekst og overskrifter */
  --blekk-dempet: #6E6E6E;                  /* bildetekster, metadata, inaktiv meny */
  --blekk-svak:   #A3A3A3;                  /* plassholdertekst, deaktiverte felt */
  --hårstrek:     #E4E4E4;                  /* alle linjer og feltrammer */
  --slør:         rgba(255, 255, 255, 0.86); /* klebrig meny over bilder */

  /* Skrifter. Reservefonten vises mens .woff2 lastes (font-display: swap),
     så den skal ligge nærmest mulig i formspråk. */
  --skrift-display: 'Bodoni Moda', 'Didot', 'Times New Roman', serif;
  --skrift-brod:    'Instrument Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;

  /* Typeskala */
  --skala-display: clamp(2.75rem, 1.6rem + 5.6vw, 6rem);   /* Davids navn */
  --skala-h1:      clamp(2rem, 1.3rem + 3.2vw, 3.5rem);    /* seksjonstittel */
  --skala-h2:      clamp(1.5rem, 1.2rem + 1.4vw, 2rem);
  --skala-ingress: clamp(1.125rem, 1rem + 0.5vw, 1.375rem);
  --skala-brod:    1.0625rem;   /* 17px — behagelig for lengre lesing */
  --skala-liten:   0.875rem;    /* bildetekst, hjelpetekst i skjema */
  --skala-etikett: 0.75rem;     /* kategorimeny, versalier */

  /* Rom — 4px-basert. Bruk tokens, ikke tall. */
  --rom-1:  0.25rem;
  --rom-2:  0.5rem;
  --rom-3:  0.75rem;
  --rom-4:  1rem;
  --rom-6:  1.5rem;
  --rom-8:  2rem;
  --rom-12: 3rem;
  --rom-16: 4rem;
  --rom-24: 6rem;
  --rom-32: 8rem;
  --rom-48: 12rem;

  --side-marg:   clamp(1.25rem, 5vw, 5rem);
  --maks-bredde: 1600px;   /* galleriet */
  --maks-tekst:  62ch;     /* løpende tekst */

  /* Bevegelse — én kurve gjennom hele nettstedet. Den bremser lenge på
     slutten, som en tung skuff som lukker seg; standard ease føles billig
     ved siden av. */
  --kurve:     cubic-bezier(0.22, 1, 0.36, 1);
  --tid-rask:  180ms;   /* hover, fokus */
  --tid-rolig: 420ms;   /* indikator, innfading */
}


/* ---------------------------------------------------------------------------
   3. Reset
   --------------------------------------------------------------------------- */

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

* {
  margin: 0;
}

html {
  /* Ingen scroll-behavior: smooth. Galleriet har egen rAF-basert scroll med
     easeOutQuart som må kunne avbrytes ved brukerinngrep (docs/galleri.md);
     native smooth ville kjempet mot den. */
  -webkit-text-size-adjust: 100%;
}

body {
  min-height: 100svh;
  background-color: var(--papir);
  color: var(--blekk);
}

/* Bildeforholdet er hellig: max-width uten fast høyde lar bildet beholde sitt
   eget sideforhold. Ingen object-fit, ingen beskjæring — layouten tilpasser
   seg bildet, aldri motsatt. */
img,
picture,
svg,
video {
  display: block;
  max-width: 100%;
}

img,
video {
  height: auto;
}

/* Et fotografi har rette hjørner. Ingen avrunding, ingen skygger — heller
   ikke der nettleseren legger dem på av seg selv. */
img,
input,
textarea,
select,
button,
fieldset {
  border-radius: 0;
}

input,
textarea,
select,
button {
  font: inherit;
  color: inherit;
  background-color: transparent;
}

button {
  border: 0;
  padding: 0;
  cursor: pointer;
  text-align: inherit;
}

textarea {
  resize: vertical;
}

::placeholder {
  color: var(--blekk-svak);
  opacity: 1;   /* Firefox demper plassholdere av seg selv */
}

::selection {
  background-color: var(--blekk);
  color: var(--papir);
}

/* Tastaturfokus må være umulig å forveksle med hover, og kan ikke bruke
   farge når paletten er svart/hvitt. Aldri outline: none uten erstatning. */
:focus-visible {
  outline: 2px solid var(--blekk);
  outline-offset: 3px;
}


/* ---------------------------------------------------------------------------
   4. Typografi
   --------------------------------------------------------------------------- */

body {
  font-family: var(--skrift-brod);
  font-size: var(--skala-brod);
  font-weight: 400;
  line-height: 1.65;
}

/* Bodoni Moda kun i store størrelser. Under 24px kollapser tynnstrekene og
   det ser bare uskarpt ut — derfor stopper display-skriften ved h2, som er
   minst 24px i hele clamp-området. */
h1,
h2,
.display {
  font-family: var(--skrift-display);
  font-weight: 400;
  line-height: 1.05;
  letter-spacing: -0.02em;   /* store bokstaver i Bodoni faller ellers fra hverandre */
  text-wrap: balance;
}

.display {
  font-size: var(--skala-display);
}

h1 {
  font-size: var(--skala-h1);
}

h2 {
  font-size: var(--skala-h2);
}

/* h3 og nedover lander under 24px og holdes derfor i brødskriften. */
h3 {
  font-family: var(--skrift-brod);
  font-size: var(--skala-ingress);
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: -0.01em;
}

h4,
h5,
h6 {
  font-family: var(--skrift-brod);
  font-size: var(--skala-brod);
  font-weight: 500;
  line-height: 1.35;
}

.ingress {
  font-size: var(--skala-ingress);
  font-weight: 400;
  line-height: 1.5;
}

/* Versalier med rikelig sperring leses som gallerimerking, ikke som roping.
   Sperringen er hele poenget — uten den blir det bare store bokstaver. */
.etikett {
  font-size: var(--skala-etikett);
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.liten {
  font-size: var(--skala-liten);
  line-height: 1.5;
}

.dempet {
  color: var(--blekk-dempet);
}

/* Løpende tekst holdes under 62ch. Lengre linjer mister leseren i overgangen
   fra én linje til neste. */
.tekstblokk {
  max-width: var(--maks-tekst);
}

.tekstblokk > * + * {
  margin-top: var(--rom-4);
}

/* Understreking kun på lenker i løpende tekst. Navigasjonslenker markerer
   seg med vekt og opasitet i stedet. */
a {
  color: inherit;
  text-decoration: none;
}

.tekstblokk a {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
  transition: color var(--tid-rask) var(--kurve);
}

.tekstblokk a:hover {
  color: var(--blekk-dempet);
}

ul,
ol {
  padding-left: var(--rom-6);
}

strong,
b {
  font-weight: 500;   /* 500 er den tyngste vekten som er lastet */
}

/* Ingen kursiv noe sted på nettstedet. */
em,
i,
cite {
  font-style: normal;
  font-weight: 500;
}

hr {
  border: 0;
  border-top: 1px solid var(--hårstrek);
}

/* Synlig kun for skjermlesere — for tekst som gir mening i lydform, men som
   ville støyet visuelt. */
.kun-skjermleser {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}


/* ---------------------------------------------------------------------------
   5. Sidens ramme

   Sidefoten skal ligge nederst også på korte sider — 404 og en kontaktside
   uten mye innhold ville ellers fått den midt på skjermen.
   --------------------------------------------------------------------------- */

body {
  display: flex;
  flex-direction: column;
}

main {
  flex: 1;
}

/* Versalier med sperring går igjen i alle navigasjonsflatene. Samme
   behandling som .etikett, men uten å måtte henge klassen på hvert element. */
.hopp-lenke,
.sidehode__navn,
.hovedmeny__lenke,
.om__lenke {
  font-size: var(--skala-etikett);
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}


/* ---------------------------------------------------------------------------
   6. Hoppelenke og sidehode
   --------------------------------------------------------------------------- */

/* Skjult ved å skyves ut av skjermen, ikke med display: none — da ville den
   falt ut av tabulatorrekkefølgen og mistet hele hensikten. */
.hopp-lenke {
  position: absolute;
  top: var(--rom-2);
  left: var(--rom-2);
  z-index: 10;
  padding: var(--rom-2) var(--rom-4);
  background-color: var(--papir);
  border: 1px solid var(--blekk);
  transform: translateY(-250%);
  transition: transform var(--tid-rask) var(--kurve);
}

.hopp-lenke:focus-visible {
  transform: translateY(0);
}

.sidehode {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--rom-4) var(--rom-8);
  padding: var(--rom-6) var(--side-marg);
  border-bottom: 1px solid var(--hårstrek);
}

/* Davids navn står i brødskriften her. Bodoni ville vært riktig formspråk,
   men kollapser under 24px, og sidehodet skal ikke rope. */
.sidehode__navn {
  color: var(--blekk);
}

.hovedmeny__liste {
  display: flex;
  flex-wrap: wrap;
  gap: var(--rom-6);
  padding: 0;
  list-style: none;
}

/* Aktiv side og hover skilles med blekkstyrke, ikke med farge — det finnes
   ingen aksentfarge å ta av. */
.hovedmeny__lenke {
  color: var(--blekk-dempet);
  transition: color var(--tid-rask) var(--kurve);
}

.hovedmeny__lenke:hover,
.hovedmeny__lenke--aktiv {
  color: var(--blekk);
}


/* ---------------------------------------------------------------------------
   7. Hero
   --------------------------------------------------------------------------- */

.hero {
  max-width: var(--maks-bredde);
  margin-inline: auto;
  padding: var(--rom-24) var(--side-marg) var(--rom-16);
}

.hero__ingress {
  max-width: var(--maks-tekst);
  margin-top: var(--rom-6);
}


/* ---------------------------------------------------------------------------
   8. Om-seksjon
   --------------------------------------------------------------------------- */

.om {
  display: grid;
  gap: var(--rom-8);
  align-items: start;
  max-width: var(--maks-bredde);
  margin-inline: auto;
  padding: 0 var(--side-marg) var(--rom-24);
}

/* Stablet layout: portrettet går kant til kant i kolonnen. Høyden følger av
   sideforholdet — ingen object-fit, ingen beskjæring. */
.om__bilde {
  width: 100%;
}

.om__lenke {
  justify-self: start;
  padding: var(--rom-3) var(--rom-6);
  border: 1px solid var(--hårstrek);
  transition: background-color var(--tid-rask) var(--kurve),
              border-color var(--tid-rask) var(--kurve),
              color var(--tid-rask) var(--kurve);
}

/* Inverteres på hover, som primærknappen ellers på nettstedet. */
.om__lenke:hover {
  background-color: var(--blekk);
  border-color: var(--blekk);
  color: var(--papir);
}

/* Bilde ved siden av tekst først når det er plass til at begge får puste.
   Under dette stables de, bildet først. */
@media (min-width: 600px) {
  /* minmax(0, …) i stedet for bare 2fr 3fr: uten nullgulvet ville bildets
     egenbredde på 1200px sette minstebredden for kolonnen og sprenge
     rutenettet på mellomstore skjermer. Forholdet 2:3 er det samme. */
  .om {
    grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
    column-gap: var(--rom-12);
    row-gap: var(--rom-8);
  }

  /* I to kolonner ville et stående portrett blitt urimelig høyt ved siden av
     teksten. Høyden er et tak, ikke en fast høyde: med width: auto skalerer
     bildet ned proporsjonalt og beholder sideforholdet sitt. */
  .om__bilde {
    grid-column: 1;
    grid-row: 1 / span 2;
    width: auto;
    max-height: 520px;
  }

  .om__tekst {
    grid-column: 2;
    grid-row: 1;
  }

  .om__lenke {
    grid-column: 2;
    grid-row: 2;
  }
}


/* ---------------------------------------------------------------------------
   9. Feilside
   --------------------------------------------------------------------------- */

.feilside {
  max-width: var(--maks-bredde);
  margin-inline: auto;
  padding: var(--rom-24) var(--side-marg);
}

.feilside__tekst {
  margin-top: var(--rom-6);
}


/* ---------------------------------------------------------------------------
   10. Sidefot
   --------------------------------------------------------------------------- */

.sidefot {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--rom-2) var(--rom-8);
  padding: var(--rom-8) var(--side-marg);
  border-top: 1px solid var(--hårstrek);
  font-size: var(--skala-liten);
}

.sidefot__opphavsrett {
  color: var(--blekk-dempet);
}


/* ---------------------------------------------------------------------------
   11. Redusert bevegelse

   CSS alene stopper ikke en rAF-basert scroll. JavaScript må i tillegg
   sjekke matchMedia('(prefers-reduced-motion: reduce)') og hoppe rett til
   seksjonen — se docs/galleri.md.
   --------------------------------------------------------------------------- */

@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;
  }
}
