/* ===== CykelTjek.dk — Dark Nordic (warm graphite & copper) ===== */
:root {
  --bg: #0E1110;
  --bg-2: #0B0E0D;
  --bg-3: #080A09;
  --bg-rgb: 14, 17, 16;
  --surface: #161A18;
  --surface-alt: #1C211E;
  --border: #292F2B;
  --border-soft: #202622;
  --text: #EAE4D6;
  --muted: #9C988C;
  /* Var #67635C, som gav 2,7–3,3:1 og altså fejlede WCAG AA (4,5:1) overalt.
     #8A867F giver 4,5:1 på den lyseste flade (--surface-alt) og 5,5:1 på --bg-3. */
  --faint: #8A867F;
  --primary: #C77F3E;
  --primary-hover: #A6682F;
  --primary-soft: #241B12;
  --primary-rgb: 199, 127, 62;
  --cta: #E08A3A;
  --cta-hover: #C87428;
  --urgency: #F59E0B;
  --urgency-soft: #2D2313;
  --trust: #8BA4B8;
  --deal: #D9A04A;
  --deal-soft: #2A2317;
  --deal-rgb: 217, 160, 74;

  /* ── Statusfarver ──
     Beholder deres KULØR i begge temaer — et hjerte er rødt, "på lager" er
     grønt; det er betydningen, ikke stemningen. Men nuancen skal justeres i
     lyst tema: #3EC77F giver kun 1,9:1 på hvid og ville være ulæselig som
     tekst. Se det lyse sæt nedenfor.
     Stod hardkodet 20 gange på tværs af favoritter.css, produkt.css og
     admin.css, før de fik navne. */
  --favorit: #E74C6D;
  --favorit-rgb: 231, 76, 109;
  --succes: #3EC77F;
  --fejl: #E74C3C;
  --advarsel: #E67E22;

  /* ── Tekst på farvede flader ──
     ⚠ Brug ALDRIG --bg til tekst oven på --cta eller --primary.
     Det så rigtigt ud i det mørke tema, hvor --bg tilfældigvis er mørk,
     men --cta er en lys orange i BEGGE temaer. I lyst tema ville
     --bg blive næsten hvid, og knapteksten forsvinde i baggrunden.
     Denne er mørk uanset tema, fordi den flade den står på er det. */
  --paa-farve: #14100C;

  /* ── Produktfoto-flade ──
     Altid hvid, også i lyst tema. Feedenes billeder HAR hvid baggrund;
     matcher fladen dem ikke, tegner der sig en kant hele vejen rundt om
     fotoet. Se begrundelsen ved .pd-gallery i produkt.css. */
  --foto-flade: #FFFFFF;

  /* ── Skygger og overlays ──
     Skal dæmpes i lyst tema: en sort skygge giver dybde på mørk baggrund,
     men ser beskidt ud på lys. Derfor variabler frem for løse rgba(0,0,0). */
  --skygge-s: 0 2px 8px rgba(0, 0, 0, .5);
  --skygge-m: 0 8px 24px rgba(0, 0, 0, .4);
  --skygge-l: 0 24px 80px rgba(0, 0, 0, .6);
  --overlay: rgba(0, 0, 0, .75);

  --radius: 10px;
  --maxw: 1180px;
  --font-display: 'Fraunces', Georgia, 'Times New Roman', serif;
  --font-body: 'Manrope', system-ui, sans-serif;

  /* Får browserens egen UI — scrollbars, formfelter, autofyld — til at
     følge temaet. Uden den tegner Chrome hvide scrollbars på mørk side. */
  color-scheme: dark;
}

/* ══════════════════════════════════════════════════════════════════════
   LYST TEMA — TILVALG, IKKE STANDARD
   ══════════════════════════════════════════════════════════════════════

   Det mørke tema ovenfor er sitets identitet og gælder for ALLE, indtil
   den besøgende selv trykker på temaknappen.

   ⚠ Derfor er der MED VILJE ingen `@media (prefers-color-scheme: light)`
   her. Den ville give lyst tema til enhver med lys systemindstilling —
   altså de fleste — og det mørke design ville reelt blive undtagelsen.
   Valget skal være et klik, ikke en systemindstilling.
   Se temaknappen i favorites.js og forvalget i header.php.

   Paletten er ikke en inversion. Den beholder den varme, grønlige grafit
   og kobberen, men vender lyshedshierarkiet: kort løftes OP med hvidt mod
   en varm off-white side, i stedet for at være lysere flader på sort.

   Alle tekstfarver er kontrolleret mod WCAG AA (4,5:1 for brødtekst,
   3:1 for grafiske elementer og store overskrifter). Tallene står ved
   hver enkelt. Ændrer du en værdi, så beregn den igen — det er samme
   fælde som --faint havde i det mørke tema, hvor den så fin ud og
   fejlede 2,7:1. */
:root[data-tema="lys"] {
  color-scheme: light;

  --bg: #FAF8F3;
  /* bg-2/bg-3 er MØRKERE end --bg her. I det mørke tema er de lysere.
     Det er ikke en fejl: de betyder "et trin længere væk fra
     læsefladen", og den retning vender med temaet. */
  --bg-2: #F3F0E8;
  --bg-3: #EBE7DC;
  --bg-rgb: 250, 248, 243;

  --surface: #FFFFFF;
  --surface-alt: #F6F3EC;
  --border: #DCD6C8;
  --border-soft: #E8E3D7;

  --text: #191C1A;
  /* 5,9:1 på --bg. --muted bruges til nav-links og brødtekst. */
  --muted: #56534B;
  /* 4,6:1 på --bg — akkurat over AA. Gå ikke lysere. */
  --faint: #6A665D;

  /* ⚠ Kobber- og guldtonerne bærer TO roller, som trækker hver sin vej:
     de er tekstfarve (.accent, .deal-price) OG bagggrund for badges og
     knapper. På lys bund skal en tekstfarve mørkne for at kunne læses —
     men jo mørkere fladen bliver, jo dårligere står mørk tekst på den.

     Derfor er --paa-farve HVID i dette tema, ikke mørk som i det mørke.
     Fladerne må så mørkne frit, og begge roller går op. Hver værdi
     herunder er valgt så den opfylder BEGGE krav, målt:

     Målt mod den MØRKESTE lyse flade (--bg-3), ikke mod --bg. Første
     forsøg blev beregnet mod --bg alene, og så fejlede "Læs mere" i
     disclosure-baren og logoet i footeren med 4,13 — begge står på
     --bg-3. En palet skal holde på den mørkeste flade farven optræder på,
     ikke på gennemsnittet.

       værdi     på --bg-3     på --bg    hvid tekst ovenpå
       #94591F      4,58         5,34          5,66
       #B05E16      4,15 (grafik, krav 3)      4,71
       #8A6117      4,72         5,20          5,52

     Både #A6682F (4,26/4,52) og #9C6029 (4,13 på --bg-3) blev forkastet.
     Begge så rigtige ud og var det ikke — samme fælde som --faint i det
     mørke tema. Beregn, gæt ikke. */
  --primary: #94591F;
  --primary-hover: #8A5019;
  --primary-soft: #F6EADC;
  --primary-rgb: 148, 89, 31;

  /* --cta bærer knapfladen OG fokusringen. Fokusringen er et grafisk
     element (AA-krav 3:1), knapteksten er tekst (4,5:1) — begge holder. */
  --cta: #B05E16;
  --cta-hover: #9E540F;

  /* Hvid, ikke mørk — se begrundelsen ovenfor. Dette er den ene variabel
     der IKKE må arves fra det mørke tema. */
  --paa-farve: #FFFFFF;

  --urgency: #A6520A;
  --urgency-soft: #FBF0E0;
  --trust: #46647D;
  --deal: #8A6117;
  --deal-soft: #F9F2E1;
  --deal-rgb: 138, 97, 23;

  /* Kulør bevaret, nuance mørknet så de kan læses som tekst på lys bund. */
  --favorit: #C42B4B;
  --favorit-rgb: 196, 43, 75;
  --succes: #16794A;
  --fejl: #B5372A;
  --advarsel: #A6520A;

  /* Ren sort skygge ser beskidt ud på en varm lys flade — den skal have
     samme varme som baggrunden og være markant svagere end i mørkt tema,
     hvor skyggen bærer dybden. */
  --skygge-s: 0 1px 3px rgba(60, 50, 35, .08);
  --skygge-m: 0 6px 18px rgba(60, 50, 35, .10);
  --skygge-l: 0 20px 60px rgba(60, 50, 35, .16);
  --overlay: rgba(25, 20, 14, .55);

  /* --foto-flade arves fra :root med vilje: produktfotoernes flade skal
     være hvid i begge temaer, fordi billederne selv har hvid baggrund. */
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0
}

html {
  scroll-behavior: smooth
}

body {
  font-family: var(--font-body);
  background: var(--bg);
  color: var(--text);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  font-weight: 400;
}

a {
  color: inherit;
  text-decoration: none
}

/* ── Tastaturfokus ──
   Der var ingen focus-styling på links og knapper, så tastaturbrugere kun
   havde browserens standardring at gå efter på en mørk baggrund. */
:focus-visible {
  outline: 3px solid var(--cta);
  outline-offset: 2px;
  border-radius: 3px
}

/* Skip-link — første tabstop, synlig når den får fokus */
.skip-link {
  position: absolute;
  left: 12px;
  top: -60px;
  z-index: 10000;
  background: var(--cta);
  color: var(--paa-farve);
  font-weight: 700;
  font-size: 14px;
  padding: 10px 18px;
  border-radius: 0 0 8px 8px;
  transition: top .15s
}

.skip-link:focus {
  top: 0
}

/* ── Reduceret bevægelse ──
   Respekterer styresystemets indstilling: slår de pulserende urgency-badges,
   hover-løft og smooth scroll fra. */
@media (prefers-reduced-motion: reduce) {

  html {
    scroll-behavior: auto
  }

  *,
  *::before,
  *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important
  }

  .deal-card:hover,
  .bento-card:hover,
  .cat-card:hover {
    transform: none
  }
}

.container {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 28px
}

::selection {
  background: var(--primary);
  color: var(--paa-farve)
}

/* Disclosure bar */
.disclosure-bar {
  background: var(--bg-3);
  color: var(--muted);
  font-size: 13px;
  padding: 9px 0;
  text-align: center;
  border-bottom: 1px solid var(--border)
}

.disclosure-bar a {
  color: var(--primary);
  text-decoration: underline
}

/* Header */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(var(--bg-rgb), .82);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--border)
}

.header-inner {
  display: flex;
  align-items: center;
  gap: 24px;
  height: 72px
}

.logo {
  display: flex;
  align-items: center;
  gap: 11px;
  color: var(--primary)
}

.logo-text {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 600;
  letter-spacing: -.01em;
  color: var(--text)
}

.logo-text strong {
  color: var(--primary);
  font-weight: 600
}

.main-nav {
  display: flex;
  gap: 30px;
  margin-left: 14px
}

.main-nav a {
  font-size: 14.5px;
  font-weight: 500;
  color: var(--muted);
  padding: 6px 0;
  border-bottom: 2px solid transparent;
  transition: .15s;
  letter-spacing: .01em
}

.main-nav a:hover {
  color: var(--text);
  border-bottom-color: var(--primary)
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-left: auto
}

/* "Se cykler" brød over 3 linjer i den smalle mobil-header */
.header-actions .btn {
  white-space: nowrap
}

/* ── Temaknap ──
   Ikonet viser hvad klikket GØR, ikke hvilket tema man er i: i det mørke
   tema står der en sol ("skift til lyst"). Den anden konvention — vis det
   tema du er i — læses lige så ofte som den modsatte, og på en knap vinder
   handlingen. aria-label siger det samme med ord.
   Begge ikoner ligger i DOM'en og skiftes med CSS, så der ikke skal køre
   JS for at tegne knappen om ved hvert klik. */
.tema-knap {
  display: grid;
  place-items: center;
  /* 40px er under WCAG 2.5.5's 44px, men knappen har 12px gap til begge
     naboer, så det effektive klikmål holder. Gå ikke lavere. */
  width: 40px;
  height: 40px;
  flex-shrink: 0;
  padding: 0;
  background: none;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--muted);
  cursor: pointer;
  transition: color .15s, border-color .15s, background .15s
}

.tema-knap:hover {
  color: var(--text);
  border-color: var(--primary);
  background: var(--surface)
}

.tema-ikon {
  width: 18px;
  height: 18px
}

.tema-ikon-maane {
  display: none
}

:root[data-tema="lys"] .tema-ikon-sol {
  display: none
}

:root[data-tema="lys"] .tema-ikon-maane {
  display: block
}

.search {
  display: flex;
  align-items: center;
  position: relative
}

.search input {
  border: 1px solid var(--border);
  border-radius: 999px;
  /* Højre padding giver plads til søgeknappen inde i feltet */
  padding: 9px 40px 9px 16px;
  font-family: inherit;
  font-size: 14px;
  width: 200px;
  background: var(--surface);
  color: var(--text)
}

.search-btn {
  position: absolute;
  right: 3px;
  top: 50%;
  transform: translateY(-50%);
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  background: none;
  border: none;
  border-radius: 999px;
  color: var(--muted);
  cursor: pointer
}

.search-btn:hover {
  color: var(--text);
  background: var(--surface-alt)
}

.search-btn svg {
  width: 17px;
  height: 17px
}

.search input::placeholder {
  color: var(--faint)
}

.search input:focus {
  outline: 2px solid var(--primary);
  outline-offset: 1px
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: inherit;
  font-weight: 600;
  font-size: 14.5px;
  padding: 12px 24px;
  border-radius: 999px;
  cursor: pointer;
  border: none;
  transition: .18s;
  letter-spacing: .01em
}

.btn-primary {
  background: var(--cta);
  color: var(--paa-farve);
  font-weight: 700;
  box-shadow: 0 4px 18px rgba(224, 138, 58, .28)
}

.btn-primary:hover {
  background: var(--cta-hover);
  color: var(--text);
  box-shadow: 0 6px 24px rgba(224, 138, 58, .38)
}

.btn-ghost {
  background: transparent;
  color: var(--text);
  border: 1px solid var(--border)
}

.btn-ghost:hover {
  border-color: var(--primary);
  color: var(--primary)
}

.btn-sm {
  font-size: 13.5px;
  padding: 9px 18px
}

.nav-toggle {
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  background: none;
  border: none;
  cursor: pointer;
  /* Mindst 44x44 px klikmål (WCAG 2.5.5) — var 34x26 px */
  width: 44px;
  height: 44px;
  /* Uden dette klemmer flex-containeren knappen ned til 31px på 375px skærme */
  flex-shrink: 0;
  padding: 0;
  margin-right: -10px
}

.nav-toggle span {
  width: 22px;
  height: 2px;
  background: var(--text);
  border-radius: 2px
}

/* Hero */
.hero {
  padding: 96px 0 88px;
  background: radial-gradient(circle at 78% 8%, rgba(var(--primary-rgb), .14), transparent 55%), var(--bg);
  border-bottom: 1px solid var(--border)
}

.hero-grid {
  display: grid;
  grid-template-columns: 1.15fr .85fr;
  gap: 56px;
  align-items: center
}

.eyebrow {
  display: inline-block;
  background: var(--primary-soft);
  color: var(--primary);
  font-weight: 600;
  font-size: 12.5px;
  padding: 6px 14px;
  border-radius: 999px;
  margin-bottom: 24px;
  letter-spacing: .02em
}

.hero h1 {
  font-family: var(--font-display);
  font-size: clamp(38px, 5.4vw, 60px);
  line-height: 1.02;
  letter-spacing: -.02em;
  font-weight: 600;
  margin-bottom: 22px;
  font-optical-sizing: auto
}

.accent {
  color: var(--primary);
  font-style: italic;
  font-weight: 500
}

.lead {
  font-size: 18px;
  color: var(--muted);
  max-width: 540px;
  margin-bottom: 34px
}

.hero-cta {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 44px
}

.trust {
  display: flex;
  gap: 40px;
  flex-wrap: wrap
}

.trust-item {
  display: flex;
  flex-direction: column;
  gap: 2px
}

.trust-item strong {
  font-family: var(--font-display);
  font-size: 22px;
  color: var(--text);
  font-weight: 600
}

.trust-item span {
  font-size: 12.5px;
  color: var(--faint);
  letter-spacing: .02em
}

.hero-visual {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 300px
}

/* .hero-bike-img er den klasse populateHeroVisual() (script.js) faktisk
   sætter — "hero-bike" herunder er beholdt for at undgå at bryde noget der
   måtte referere til den, men matchede intet element.

   Hvid kort-baggrund i stedet for kun en drop-shadow: hero'ens billede sad
   direkte på den mørke hero-baggrund, og mange produktfotos (selv med
   transparent/lys baggrund i selve filen) druknede visuelt i den — samme
   problem som .pd-gallery havde på produktsiden, løst med samme greb. */
/* Produktfotos er typisk portrætorienterede (fx 1200×1600, forhold 0.75),
   mens rammen var landskabsformet (380 bred × 306 høj) — derfor var der
   store hvide bånd i siderne, uanset hvor lidt padding der var. Rammen er
   nu selv gjort smallere og højere for at matche fotoets eget forhold, så
   den fylder mindre i sig selv, mens cyklen inden i fylder mere ud.
   height + box-sizing:border-box holder de ydre mål faste. */
.hero-bike,
.hero-bike-img {
  width: 100%;
  max-width: 230px;
  height: 300px;
  box-sizing: border-box;
  background: var(--foto-flade);
  border-radius: 24px;
  padding: 8px;
  box-shadow: 0 20px 50px rgba(0, 0, 0, .45);
  display: flex;
  align-items: center;
  justify-content: center;
}

.hero-bike-img svg {
  width: 100%;
  height: auto;
  max-height: 220px;
}

/* Hero-visningen er pakket i ét <a> (display:contents, se
   populateHeroVisual() i script.js) — ren visuel hover-feedback for at
   vise at hele billedet/pristagget er klikbart, ikke kun teksten. */
.hero-deal-link {
  cursor: pointer;
}

.hero-deal-link:hover .price-tag {
  border-color: var(--primary);
}

.hero-deal-link:hover .hero-bike-img img {
  transform: scale(1.03);
}

.price-tag {
  position: absolute;
  top: 6px;
  right: 0;
  /* .hero-bike-img har mask-image, som opretter sin egen stacking context —
     uden et eksplicit z-index her vinder den (den kommer efter i DOM'et),
     og rammens hvide glow-kant males hen over pristagget. Ramte hårdest på
     mobil, hvor .price-tag rykkes op i rammen med top:-24px (680px-bredden
     herunder) og næsten forsvandt under den hvide glød. */
  z-index: 2;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 18px 22px;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  box-shadow: 0 20px 50px rgba(0, 0, 0, .45);
  transition: border-color .2s
}

.hero-bike-img img {
  transition: transform .3s
}

.tag-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .1em;
  color: var(--faint);
  font-weight: 600
}

.tag-old {
  font-size: 14px;
  color: var(--faint);
  text-decoration: line-through
}

.tag-price {
  font-family: var(--font-display);
  font-size: 30px;
  font-weight: 600;
  color: var(--deal)
}

.tag-save {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--paa-farve);
  background: var(--deal);
  padding: 3px 11px;
  border-radius: 999px;
  margin-top: 5px
}

/* Sections */
.section {
  padding: 88px 0
}

.section-alt {
  background: var(--bg-2);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border)
}

.section-head {
  max-width: 680px;
  margin-bottom: 52px
}

.section-head h2 {
  font-family: var(--font-display);
  font-size: clamp(28px, 3.6vw, 40px);
  font-weight: 600;
  letter-spacing: -.015em;
  margin-bottom: 14px;
  line-height: 1.1
}

.section-head p {
  font-size: 17px;
  color: var(--muted)
}

/* Categories — editorial, borderless */
.cat-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0
}

.cat-card {
  background: transparent;
  border-top: 2px solid var(--border);
  padding: 26px 24px 28px 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
  transition: .2s
}

.cat-card:hover {
  border-top-color: var(--primary)
}

.cat-card:hover h3 {
  color: var(--primary)
}

.cat-icon {
  width: 52px;
  height: 36px;
  color: var(--muted);
  transition: .2s
}

.cat-card:hover .cat-icon {
  color: var(--primary)
}

.cat-card h3 {
  font-family: var(--font-body);
  font-size: 17px;
  font-weight: 600;
  transition: .2s
}

.cat-card span {
  font-size: 13.5px;
  color: var(--faint)
}

/* Deals — kategori-rækker (forsiden)
   #dealGrid holdt tidligere .deal-grid (display:grid, 3 kolonner) direkte
   på sig selv. Nu er #dealGrid en simpel stak af .deal-kategori-blokke, og
   .deal-grid-klassen er fjernet fra markup'et — se .deal-kategori-scroll
   for det vandrette gitter INDE i hver kategori. */
.deal-kategori {
  margin-bottom: 44px;
  position: relative
}

.deal-kategori:last-child {
  margin-bottom: 0
}

.deal-kategori-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 20px;
  margin-bottom: 18px
}

.deal-kategori-head h3 {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 600
}

.deal-kategori-link {
  font-size: 14px;
  color: var(--primary);
  white-space: nowrap;
  flex-shrink: 0
}

.deal-kategori-link:hover {
  text-decoration: underline
}

/* Vandret rulle-række. Kortene har en FAST bredde (flex: 0 0 …) i stedet
   for grid — uden det ville browseren klemme dem ind til at fylde
   containeren, og der ville ikke være noget at scrolle. */
.deal-kategori-scroll {
  display: flex;
  gap: 20px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding-bottom: 4px;
  scrollbar-width: thin
}

.deal-kategori-scroll .deal-card {
  flex: 0 0 260px;
  scroll-snap-align: start
}

/* Venstre/højre-knapperne (initDealScrollKnapper() i script.js). Skjult på
   touch-skærme — der er swipe den naturlige interaktion, og knapperne ville
   bare optage plads oven i indholdet. */
.deal-scroll-knap {
  position: absolute;
  top: 50%;
  transform: translateY(6px);
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: var(--skygge-m);
  transition: .15s
}

.deal-scroll-knap:hover {
  border-color: var(--primary);
  color: var(--primary)
}

.deal-scroll-knap svg {
  width: 18px;
  height: 18px
}

.deal-scroll-knap--venstre {
  left: -18px
}

.deal-scroll-knap--hoejre {
  right: -18px
}

@media (hover: none) {
  .deal-scroll-knap {
    display: none
  }
}

.deal-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: .2s;
  cursor: pointer
}

.deal-card:hover {
  border-color: var(--primary);
  transform: translateY(-3px)
}

.deal-img {
  height: 190px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-alt);
  border-bottom: 1px solid var(--border);
  overflow: hidden
}

.deal-img svg {
  width: 120px;
  height: 80px
}

/* .product-card og .product-img (+ dens svg-regel) bor her og ikke i
   cykler.css, af samme grund som .product-photo nedenfor: cykler.js,
   favoritter.js OG produkt.js bruger alle .product-card/.product-img, men
   kun cykler.php loader cykler.css. Stod reglerne kun dér, ville kortene
   på favorit- og produktsiden være helt flade — ingen kant, ingen
   baggrund, ingen runde hjørner, intet hover-løft — hvilket var tilfældet
   indtil dette blev opdaget (målt: border 0px, background transparent,
   border-radius 0px på favoritsiden). Et fallback-ikon ville desuden
   rendere i sin urestringerede standardstørrelse, typisk 300×150px, uden
   for kortets ramme. */
.product-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: .22s;
  cursor: pointer;
  position: relative
}

.product-card:hover {
  border-color: var(--primary);
  transform: translateY(-4px);
  box-shadow: 0 12px 36px rgba(0, 0, 0, .4)
}

.product-img {
  height: 190px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-alt);
  border-bottom: 1px solid var(--border);
  position: relative;
  overflow: hidden
}

.product-img svg {
  width: 120px;
  height: 80px;
  transition: .3s
}

/* Produktfotos fra feedet. Skal bo her og ikke i cykler.css, fordi forsiden
   og favoritsiden også renderer .product-photo — uden reglen vises billedet
   i sin naturlige størrelse (800px) oven i kortets tekst. */
/* Produktfotos er fotograferet på hvid baggrund hos butikkerne, og fyldte
   tidligere hele kortets billedfelt kant til kant — et hvidt "klodser" der
   sad direkte mod kortets mørke ramme. Insat som en "måtte" med luft, runde
   hjørner og et let løft, læses den hvide flade som et bevidst designvalg
   i stedet for et sammenstød med det mørke tema. */
.product-photo {
  width: calc(100% - 16px);
  height: calc(100% - 16px);
  margin: 8px;
  object-fit: contain;
  background: var(--foto-flade);
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .2);
  padding: 8px;
  transition: transform .3s
}

.product-card:hover .product-photo,
.deal-card:hover .product-photo {
  transform: scale(1.04)
}

.product-body {
  padding: 18px;
  display: flex;
  flex-direction: column;
  flex: 1;
  gap: 6px
}

.product-retailer {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--faint);
  font-weight: 600
}

.product-title {
  font-size: 15.5px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--text)
}

.product-rating {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12.5px;
  color: var(--muted)
}

.product-stars {
  color: var(--deal);
  letter-spacing: -1px
}

.product-price-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 8px;
  margin-top: auto;
  padding-top: 10px
}

.product-old {
  text-decoration: line-through;
  color: var(--faint);
  font-size: 13px
}

/* Før-prisen får sin egen linje over nu-prisen, så der er plads til
   pris + "Spar"-badge ved siden af hinanden nedenunder. */
.product-price-row .product-old {
  width: 100%
}

.product-price {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 600;
  color: var(--text)
}

.product-save {
  font-size: 12px;
  font-weight: 600;
  color: var(--deal);
  background: var(--deal-soft);
  padding: 2px 8px;
  border-radius: 6px
}

.product-stores {
  font-size: 11.5px;
  color: var(--faint);
  margin-top: 2px
}

.product-stores strong {
  color: var(--primary)
}

.product-cta {
  margin-top: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--cta);
  color: var(--paa-farve);
  font-family: inherit;
  font-weight: 700;
  font-size: 14px;
  padding: 11px;
  border-radius: 8px;
  cursor: pointer;
  border: none;
  transition: .18s;
  width: 100%;
  text-decoration: none
}

.product-cta:hover {
  background: var(--cta-hover);
  color: var(--text)
}

.deal-body {
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 7px;
  flex: 1
}

.deal-retailer {
  /* Butiksnavnet var det svageste element på siden (2,94:1 ved 11,5px).
     Det er kerneinformation på et prissammenligningssite. */
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--muted);
  font-weight: 600
}

.deal-title {
  font-family: var(--font-body);
  font-size: 16.5px;
  font-weight: 600;
  line-height: 1.3
}

.deal-rating {
  font-size: 13px;
  color: var(--muted);
  display: flex;
  gap: 6px;
  align-items: center
}

.stars {
  color: var(--deal)
}

.deal-price-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 10px;
  margin-top: auto;
  padding-top: 12px
}

.deal-old {
  text-decoration: line-through;
  color: var(--faint);
  font-size: 14px;
  white-space: nowrap
}

.deal-price {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap
}

.deal-save {
  font-size: 12px;
  font-weight: 600;
  color: var(--deal);
  background: var(--deal-soft);
  padding: 3px 9px;
  border-radius: 6px;
  /* Uden nowrap brød "Spar 1.500 kr" og løb ud over bento-kortets kant */
  white-space: nowrap
}

/* Knappen skal holde sig på ÉN linje. Et deal-kort er 260px, .deal-body
   tager 20px i hver side og .btn 24px mere — så teksten havde kun ~172px,
   mens den længste variant ("Se pris hos Ladcyklen.dk →") kræver ~190px.
   Pilen faldt derfor ned på linje 2 og fordoblede knappens højde.
   To greb, ikke ét: sidepolstringen er sat ned (knappen er alligevel
   fuld bredde, så 24px er spildplads), og pilen er sit eget flex-element
   der ALDRIG krymper, mens teksten ellipseres. Det sidste er værnet — et
   fremtidigt langt butiksnavn kan så ikke bryde layoutet igen.

   Værdierne er MÅLT i browseren, ikke skønnet. Det smalleste kort giver
   knappen 198px, altså 182px indhold efter polstringen. Længste tekst i
   dag er "Se pris hos Ladcyklen.dk" = 151px, så der er 15px tilovers når
   gap og pil er trukket fra. Første forsøg (13px skrift, 12px polstring)
   gav kun 1px og ville være knækket ved den mindste forskel i
   fontgengivelse.
   ⚠ Mål mod "Ladcyklen.dk" hvis du ændrer noget her. De fire andre
   butiksnavne er alle kortere og afslører ikke problemet — og
   Ladcyklen.dk optræder ikke nødvendigvis på forsiden, så en visuel
   kontrol er ikke nok. */
.deal-cta {
  margin-top: 14px;
  width: 100%;
  gap: 5px;
  padding-inline: 8px;
  font-size: 12.5px;
  white-space: nowrap
}

.deal-cta-tekst {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis
}

.deal-cta-pil {
  flex: 0 0 auto
}

.deal-note {
  margin-top: 28px;
  font-size: 13px;
  color: var(--faint);
  text-align: center
}

/* Urgency badges */
.urgency-badge {
  display: inline-flex;
  align-items: center;
  /* Badget er direkte barn af flex-column-kort (.bento-card, .deal-body) og
     blev derfor strukket til fuld kortbredde. */
  align-self: flex-start;
  gap: 5px;
  font-size: 11.5px;
  font-weight: 700;
  color: var(--paa-farve);
  background: var(--urgency);
  padding: 4px 12px;
  border-radius: 999px;
  letter-spacing: .02em;
  animation: urgencyPulse 2.4s ease-in-out infinite
}

.urgency-badge::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--bg);
  animation: urgencyDot 1.2s ease-in-out infinite
}

/* Udsolgt-mærkat. Bor HER og ikke i cykler.css, af samme grund som
   .product-card m.fl. (invariant 11): kun cykler.php loader cykler.css, men
   mærkatet hører til .product-badge-wrap, som også renderes af favoritter.js
   og produkt.js. Bevidst nedtonet — det er en oplysning, ikke et tilbud, og
   må ikke konkurrere med rabatmærkatet om opmærksomheden. */
.udsolgt-badge {
  display: inline-flex;
  align-items: center;
  font-size: 11.5px;
  font-weight: 700;
  background: var(--surface-alt);
  color: var(--muted);
  border: 1px solid var(--border);
  padding: 3px 10px;
  border-radius: 999px;
  letter-spacing: .02em
}

@keyframes urgencyPulse {

  0%,
  100% {
    opacity: 1
  }

  50% {
    opacity: .82
  }
}

@keyframes urgencyDot {

  0%,
  100% {
    opacity: 1
  }

  50% {
    opacity: .4
  }
}

.urgency-badge--subtle {
  background: var(--urgency-soft);
  color: var(--urgency);
  animation: none
}

.urgency-badge--subtle::before {
  background: var(--urgency)
}

/* Stock indicator */
.stock-low {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--urgency)
}

.stock-low::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--urgency);
  animation: urgencyDot 1.2s ease-in-out infinite
}

/* Trust microcopy */
.trust-micro {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  flex-wrap: wrap;
  font-size: 12px;
  color: var(--trust);
  margin-top: 10px
}

.trust-micro span {
  display: inline-flex;
  align-items: center;
  gap: 4px
}

.trust-micro svg {
  width: 13px;
  height: 13px;
  flex-shrink: 0
}

.hero .trust-micro {
  justify-content: flex-start;
  margin-top: 16px
}

.deal-card .trust-micro {
  margin-top: 8px;
  justify-content: flex-start;
  font-size: 11px;
  gap: 10px
}

.bento-card .trust-micro {
  margin-top: 8px;
  font-size: 11px;
  justify-content: flex-start;
  gap: 8px
}

/* Steps — editorial, minimal */
.steps {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0
}

.step {
  padding: 8px 28px 8px 0;
  border-left: 1px solid var(--border);
  padding-left: 28px
}

.step:first-child {
  border-left: none;
  padding-left: 0
}

.step-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: auto;
  height: auto;
  background: none;
  color: var(--primary);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 42px;
  margin-bottom: 18px;
  line-height: 1
}

.step h3 {
  font-family: var(--font-body);
  font-size: 16.5px;
  font-weight: 600;
  margin-bottom: 10px
}

.step p {
  font-size: 14.5px;
  color: var(--muted)
}

/* Guides */
.guide-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px
}

/* Tom tilstand på /guides. grid-column: 1/-1 er nødvendig: forælderen er et
   gitter (3 kolonner her, auto-fill på selve guides-siden), så uden den
   ville beskeden klemme sig ned i én smal kolonne i venstre side. */
.guides-empty {
  grid-column: 1 / -1;
  text-align: center;
  padding: 64px 24px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.guides-empty h2 {
  font-family: var(--font-display);
  font-size: 26px;
  font-weight: 600;
  margin-bottom: 10px;
}

.guides-empty p {
  color: var(--muted);
  max-width: 420px;
  margin: 0 auto 24px;
}

.guide-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  transition: .2s;
  cursor: pointer
}

.guide-card:hover {
  border-color: var(--primary);
  transform: translateY(-3px)
}

.guide-img {
  height: 180px
}

.guide-body {
  padding: 22px
}

.guide-tag {
  display: inline-block;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--primary);
  background: var(--primary-soft);
  padding: 4px 11px;
  border-radius: 999px;
  margin-bottom: 12px;
  letter-spacing: .02em
}

.guide-card h3 {
  font-family: var(--font-display);
  font-size: 21px;
  font-weight: 600;
  line-height: 1.2;
  margin-bottom: 10px;
  letter-spacing: -.01em
}

.guide-card p {
  font-size: 14.5px;
  color: var(--muted);
  margin-bottom: 16px
}

.read-more {
  font-weight: 600;
  color: var(--primary);
  font-size: 14px
}

.read-more:hover {
  text-decoration: underline
}

/* Newsletter */
.newsletter {
  background: linear-gradient(135deg, rgba(var(--primary-rgb), .10), var(--bg));
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  padding: 72px 0
}

.newsletter-inner {
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  gap: 36px;
  align-items: center
}

.newsletter-copy h2 {
  font-family: var(--font-display);
  font-size: 32px;
  font-weight: 600;
  margin-bottom: 10px;
  letter-spacing: -.015em
}

.newsletter-copy p {
  font-size: 17px;
  color: var(--muted)
}

.newsletter-form {
  display: flex;
  gap: 10px
}

.newsletter-form input {
  flex: 1;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 13px 20px;
  font-family: inherit;
  font-size: 15px;
  background: var(--surface);
  color: var(--text)
}

.newsletter-form input::placeholder {
  color: var(--faint)
}

.newsletter-form input:focus {
  outline: 2px solid var(--primary);
  outline-offset: 1px
}

.newsletter-form .btn-primary {
  background: var(--cta);
  color: var(--paa-farve)
}

.newsletter-form .btn-primary:hover {
  background: var(--cta-hover);
  color: var(--text)
}

.newsletter-success {
  grid-column: 1/-1;
  font-weight: 600;
  color: var(--deal)
}

/* Footer */
.site-footer {
  background: var(--bg-3);
  color: var(--muted);
  padding: 64px 0 0
}

.footer-grid {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr 1fr;
  gap: 40px;
  padding-bottom: 44px
}

.footer-brand .logo {
  color: var(--primary);
  margin-bottom: 16px
}

.logo-light .logo-text {
  color: var(--text)
}

.logo-light .logo-text strong {
  color: var(--primary)
}

.footer-brand p {
  font-size: 14px;
  color: var(--faint);
  max-width: 280px
}

.footer-col h4 {
  font-family: var(--font-body);
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--text);
  margin-bottom: 16px;
  font-weight: 600
}

.footer-col a {
  display: block;
  font-size: 14.5px;
  color: var(--faint);
  padding: 6px 0;
  transition: .15s
}

.footer-col a:hover {
  color: var(--primary)
}

.footer-bottom {
  border-top: 1px solid var(--border);
  padding: 22px 0
}

.footer-bottom .container {
  display: flex;
  flex-direction: column;
  gap: 6px
}

.footer-bottom p {
  font-size: 13px;
  color: var(--faint)
}

.footer-disclosure {
  font-size: 12.5px;
  color: var(--faint);
  opacity: .85
}

/* ===== Color variants (Nordisk) ===== */
[data-theme="frost"] {
  --bg: #0B1015;
  --bg-2: #090E12;
  --bg-3: #070A0D;
  --bg-rgb: 11, 16, 21;
  --surface: #141C24;
  --surface-alt: #1A242E;
  --border: #2A3744;
  --text: #E6ECF2;
  --muted: #8E9AA8;
  --faint: #5E6875;
  --primary: #6FA8C7;
  --primary-hover: #5689A8;
  --primary-soft: #16222E;
  --primary-rgb: 111, 168, 199;
  --deal: var(--deal);
  --deal-soft: var(--deal-soft);
  --deal-rgb: 217, 160, 74
}

[data-theme="skov"] {
  --bg: #0D1210;
  --bg-2: #0A0F0D;
  --bg-3: #080B0A;
  --bg-rgb: 13, 18, 16;
  --surface: #15201B;
  --surface-alt: #1B2822;
  --border: #283630;
  --text: #E8E8DA;
  --muted: #909A8C;
  --faint: #5E685C;
  --primary: #8FB57A;
  --primary-hover: #729760;
  --primary-soft: #172216;
  --primary-rgb: 143, 181, 122;
  --deal: var(--deal);
  --deal-soft: var(--deal-soft);
  --deal-rgb: 217, 160, 74
}

[data-theme="rust"] {
  --bg: #120F0D;
  --bg-2: #0F0C0A;
  --bg-3: #0A0807;
  --bg-rgb: 18, 15, 13;
  --surface: #1D1815;
  --surface-alt: #241E1A;
  --border: #332B26;
  --text: #ECE3DA;
  --muted: #9E918A;
  --faint: #6A605A;
  --primary: #C26A4A;
  --primary-hover: #A2553A;
  --primary-soft: #241610;
  --primary-rgb: 194, 106, 74;
  --deal: var(--deal);
  --deal-soft: var(--deal-soft);
  --deal-rgb: 217, 160, 74
}

[data-theme="skifer"] {
  --bg: #101113;
  --bg-2: #0C0E10;
  --bg-3: #08090A;
  --bg-rgb: 16, 17, 19;
  --surface: #191C20;
  --surface-alt: #202429;
  --border: #2D323A;
  --text: #E6E7EA;
  --muted: #8E929A;
  --faint: #5C6068;
  --primary: #7E9DBA;
  --primary-hover: #637E99;
  --primary-soft: #1A2230;
  --primary-rgb: 126, 157, 186;
  --deal: var(--deal);
  --deal-soft: var(--deal-soft);
  --deal-rgb: 217, 160, 74
}

/* Theme switcher (sammenligning) */
.theme-switcher {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 100;
  display: flex;
  align-items: center;
  gap: 9px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 8px 14px;
  box-shadow: 0 14px 34px rgba(0, 0, 0, .45)
}

.theme-switcher-label {
  font-size: 10.5px;
  color: var(--faint);
  text-transform: uppercase;
  letter-spacing: .1em;
  font-weight: 600;
  padding-right: 2px
}

.swatch {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .14);
  background: var(--sw);
  cursor: pointer;
  padding: 0;
  transition: transform .15s, box-shadow .15s
}

.swatch:hover {
  transform: scale(1.14)
}

.swatch.active {
  border-color: var(--text);
  box-shadow: 0 0 0 2px var(--sw)
}

@media(max-width:680px) {
  .theme-switcher-label {
    display: none
  }

  .theme-switcher {
    gap: 7px;
    padding: 7px 10px
  }

  .swatch {
    width: 20px;
    height: 20px
  }
}

/* ===== Featured bikes bento banner ===== */
.section-featured {
  background: var(--bg);
  padding: 72px 0
}

.bento {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  /* Var en fast 202px: kombineret med overflow:hidden på kortene blev
     "Spar …"-badget klippet væk, når prisrækken brød til to linjer. */
  grid-auto-rows: minmax(202px, auto);
  gap: 18px
}

.bento-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 22px;
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transition: .2s
}

.bento-card:hover {
  border-color: var(--primary);
  transform: translateY(-3px)
}

.bento-featured {
  grid-column: 1/span 2;
  grid-row: 1/span 2;
  padding: 30px;
  background: radial-gradient(circle at 50% 38%, rgba(var(--primary-rgb), .13), transparent 60%), var(--surface)
}

.bento-wide {
  grid-column: 3/span 2;
  grid-row: 1;
  flex-direction: row;
  align-items: center;
  gap: 18px
}

.bento-bike {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 0
}

.bento-featured .bento-bike {
  flex: 1.5
}

.bento-featured .bento-bike svg {
  width: 100%;
  max-width: 230px;
  height: auto
}

.bento-wide .bento-bike {
  flex: 0 0 150px
}

.bento-wide .bento-bike svg {
  width: 150px;
  height: auto
}

.bento-card:not(.bento-featured):not(.bento-wide) .bento-bike {
  flex: 0 0 70px
}

.bento-card:not(.bento-featured):not(.bento-wide) .bento-bike svg {
  width: auto;
  height: 64px
}

.bento-card:not(.bento-featured):not(.bento-wide) {
  padding: 18px
}

.bento-card:not(.bento-featured):not(.bento-wide) .bento-title {
  font-size: 15.5px
}

.bento-flag {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  color: var(--paa-farve);
  background: var(--primary);
  padding: 3px 11px;
  border-radius: 999px;
  letter-spacing: .04em;
  align-self: flex-start;
  margin-bottom: 6px
}

.bento-info {
  display: flex;
  flex-direction: column
}

.bento-wide .bento-info {
  flex: 1
}

.bento-title {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 600;
  line-height: 1.15;
  margin: 4px 0 10px;
  letter-spacing: -.01em
}

.bento-card .bento-title {
  font-size: 16.5px;
  font-family: var(--font-body);
  font-weight: 600;
  margin-bottom: 8px
}

.bento-cta {
  align-self: flex-start;
  margin-top: 14px
}

.bento-wide .bento-title {
  font-size: 19px
}

/* Responsive */
@media(max-width:920px) {
  .bento {
    grid-template-columns: repeat(2, 1fr);
    grid-auto-rows: auto
  }

  .bento-featured {
    grid-column: 1/span 2;
    grid-row: auto
  }

  .bento-wide {
    grid-column: 1/span 2;
    flex-direction: row
  }

  .cat-grid,
  .steps {
    grid-template-columns: repeat(2, 1fr)
  }

  .steps .step:nth-child(3) {
    border-left: none;
    padding-left: 0
  }

  .guide-grid {
    grid-template-columns: repeat(2, 1fr)
  }

  .deal-kategori-scroll .deal-card {
    flex-basis: 240px
  }

  .hero-grid {
    grid-template-columns: 1fr;
    gap: 40px
  }

  /* Ingen order: -1 her — den dekorative cykel-SVG skubbede <h1> og CTA'erne
     under folden, så hele første skærm var pynt. Indholdet kommer først. */
  .hero-visual {
    min-height: 240px
  }

  .footer-grid {
    grid-template-columns: 1fr 1fr
  }

  .cat-card {
    border-right: 1px solid var(--border)
  }

  .cat-card:nth-child(2n) {
    border-right: none
  }
}

/* ── Headeren løb over mellem 680 og ~1060 px ──
   Målt live 27/7 ved 887 px viewport: 160 px vandret overflow, og siden
   fik en vandret scrollbar. Logo + 5 navlinks + søgefelt + temaknap +
   "Se produkter" kan ikke være der.

   Overflowet fandtes FØR temaknappen (målt 108 px), men knappen gjorde
   det værre med sine 40 px plus gap — derfor rettes det her.

   1080 er ikke et rundt tal valgt på fornemmelse. Headerens indhold er
   målt: logo 170 + nav 401 + actions 386 = 957 px, plus to gaps à 24 og
   container-padding 2 × 28 = 1061 px nødvendig viewport-bredde.
   Første forsøg satte grænsen til 920 ud fra ÉN måling ved 887 px, hvor
   overflowet var synligt. Den fjernede overflowet dér, men ikke ved 982,
   hvor der stadig manglede 65 px — intervallet ovenover blev aldrig
   afprøvet. Mål hele intervallet, ikke det ene sted fejlen blev set.

   Navlinkene falder sammen i burgermenuen ved 1080 px i stedet for 680.
   Samme mekanik som før, bare tidligere: alt i .main-nav er stadig
   tilgængeligt via .nav-toggle. */
@media(max-width:1080px) {
  .main-nav {
    display: none
  }

  .nav-toggle {
    display: flex
  }

  /* Selve udklaps-menuen SKAL vaere her og ikke i 680-blokken:
     uden den kunne burgeren ikke åbnes mellem 680 og 1080 px. */
  .main-nav.open {
    display: flex;
    position: absolute;
    top: 72px;
    left: 0;
    right: 0;
    flex-direction: column;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    padding: 14px 28px;
    gap: 0
  }

  .main-nav.open a {
    padding: 13px 0;
    border-bottom: 1px solid var(--border)
  }

  .main-nav.open a:last-child {
    border-bottom: none
  }
}

@media(max-width:680px) {




  /* Søgefeltet var display:none her, så mobilbrugere havde ingen søgning.
     Vi giver det pladsen fra "Se cykler"-knappen i stedet — den er redundant
     på mobil (menuen har "Cykler", og hero'en har en stor CTA) — og strammer
     logo og mellemrum, så feltet bliver bredt nok til at skrive i. */
  .header-inner {
    gap: 12px
  }

  .logo {
    gap: 8px;
    flex-shrink: 0
  }

  .logo svg {
    width: 34px;
    height: 22px
  }

  .logo-text {
    font-size: 19px
  }

  .header-actions {
    flex: 1;
    gap: 10px
  }

  .header-actions .btn {
    display: none
  }

  .search {
    flex: 1;
    min-width: 0
  }

  .search input {
    width: 100%
  }

  .cat-grid,
  .steps,
  .guide-grid,
  .footer-grid {
    grid-template-columns: 1fr
  }

  .deal-kategori-scroll .deal-card {
    flex-basis: 78%
  }

  .deal-kategori-head h3 {
    font-size: 18px
  }

  .cat-card {
    border-right: none
  }

  .step {
    border-left: none;
    padding-left: 0;
    border-top: 1px solid var(--border);
    padding-top: 24px
  }

  .step:first-child {
    border-top: none;
    padding-top: 0
  }

  .newsletter-inner {
    grid-template-columns: 1fr
  }

  .newsletter-form {
    flex-direction: column
  }

  .btn {
    width: 100%
  }

  .hero {
    padding: 64px 0
  }

  .section {
    padding: 60px 0
  }

  .section-featured {
    padding: 52px 0
  }

  .bento {
    grid-template-columns: 1fr
  }

  .bento-featured,
  .bento-wide {
    grid-column: 1
  }

  .bento-wide {
    flex-direction: column;
    align-items: flex-start
  }

  .bento-wide .bento-bike {
    flex: 0 0 auto
  }

  .bento-featured .bento-bike svg {
    max-width: 180px
  }

  .price-tag {
    right: 0;
    top: -24px
  }
}

/* ===== GDPR Cookie Banner ===== */
.cookie-banner {
  position: fixed;
  bottom: 24px;
  left: 24px;
  max-width: 400px;
  background: var(--surface);
  border: 1px solid var(--border);
  padding: 24px;
  border-radius: var(--radius);
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5);
  z-index: 9999;
  display: flex;
  flex-direction: column;
  gap: 16px;
  animation: slideUp 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

@keyframes slideUp {
  from {
    opacity: 0;
    transform: translateY(40px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.cookie-content h4 {
  margin: 0 0 8px 0;
  font-size: 1.15rem;
  color: var(--text);
  font-family: var(--font-display);
}

.cookie-content p {
  margin: 0;
  font-size: 0.95rem;
  color: var(--faint);
  line-height: 1.6;
}

.cookie-actions {
  display: flex;
  gap: 12px;
  justify-content: flex-end;
}

.cookie-actions .btn {
  padding: 8px 16px;
  font-size: 14px;
}

@media (max-width: 480px) {
  .cookie-banner {
    bottom: 0;
    left: 0;
    right: 0;
    max-width: none;
    border-radius: 16px 16px 0 0;
    border-bottom: none;
    padding: 20px;
  }
}

/* ════════════════════════════════════════════════════════════════════
   FORSIDE — kategorigitteret som hero
   Alt herunder er NYE klasser; ingen eksisterende regel ændres. .cat-grid,
   .cat-card, .deal-*, .section*, .newsletter og .btn genbruges som de er.
   ════════════════════════════════════════════════════════════════════ */

/* Hero er nu selve gitteret. Mindre luft end den gamle .hero (96px), fordi
   kategorierne skal være over folden — det er hele pointen med sektionen. */
.hero-kat {
  padding: 56px 0 72px;
  background: radial-gradient(circle at 78% 0%, rgba(var(--primary-rgb), .12), transparent 55%), var(--bg);
  border-bottom: 1px solid var(--border)
}

.hero-kat h1 {
  font-family: var(--font-display);
  font-size: clamp(36px, 5vw, 56px);
  line-height: 1.02;
  letter-spacing: -.02em;
  font-weight: 600;
  margin-bottom: 18px;
  font-optical-sizing: auto
}

.hero-kat .lead {
  margin-bottom: 44px
}

/* Antallet er det vigtigste på kortet efter navnet: uden det sender vi
   folk ind i en liste med 8 varer uden varsel. Tallet fed, ordet ikke. */
.cat-count strong {
  color: var(--text);
  font-weight: 600
}

/* Under 15 varer: sig det. Bedre end at lade den besøgende opdage det
   efter klikket. Sættes af renderKategoriAntal() i script.js. */
.cat-card.er-tynd .cat-count {
  color: var(--faint)
}

/* Tilbehørsrækken — bevidst nedtonet. Udstyr + cykeltøj er størstedelen af
   kataloget, men ikke det sitet handler om (samme grænse som IKKE_CYKLER). */
.kat-sekundaer {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 40px;
  padding-top: 28px;
  border-top: 1px solid var(--border)
}

.kat-sekundaer-label {
  font-size: 14px;
  color: var(--muted)
}

.kat-pille {
  font-size: 13.5px;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 6px 14px;
  transition: .2s
}

.kat-pille:hover {
  border-color: var(--primary);
  color: var(--text)
}

.kat-pille em {
  font-style: normal;
  color: var(--faint);
  margin-left: 4px
}

.kat-soeg {
  display: flex;
  gap: 8px;
  margin-left: auto
}

.kat-soeg input {
  width: 300px;
  max-width: 100%;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text);
  font: inherit;
  font-size: 14px;
  padding: 10px 14px
}

.kat-soeg input::placeholder {
  color: var(--faint)
}

.kat-soeg input:focus {
  outline: none;
  border-color: var(--primary)
}

/* Tidsstemplet står ved BEVISET, ikke i hero'en — det er dér det gør
   arbejde. Kobbertråden til venstre knytter det til overskriften. */
.pris-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 32px;
  flex-wrap: wrap
}

.pris-head .section-head {
  margin-bottom: 32px
}

.pris-opdateret {
  font-size: 13.5px;
  color: var(--muted);
  border-left: 2px solid var(--primary);
  padding-left: 12px;
  white-space: nowrap
}

.pris-opdateret strong {
  color: var(--text);
  font-weight: 600
}

/* Metoden: tre celler, ikke fire trin med nummerbobler. Kortere tekst,
   mindre plads — den skal være der, men den skal ikke fylde. */
.metode {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0
}

.metode-item {
  border-top: 2px solid var(--border);
  padding: 24px 28px 0 0
}

.metode-num {
  display: block;
  font-size: 12.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--primary);
  font-weight: 600;
  margin-bottom: 10px
}

.metode-item p {
  font-size: 15px;
  color: var(--muted)
}

.newsletter-actions {
  display: flex;
  flex-direction: column;
  gap: 14px;
  align-items: flex-start
}

/* ── Responsivt ──
   Kategorigitteret er hele forsidens jobbeskrivelse, så det skal blive
   ved med at være et gitter på telefon — to kolonner, ikke en liste. */
@media (max-width: 900px) {
  .cat-grid {
    grid-template-columns: repeat(2, 1fr);
    column-gap: 20px
  }

  .metode {
    grid-template-columns: 1fr
  }

  .metode-item {
    padding-right: 0
  }

  .kat-soeg {
    margin-left: 0;
    width: 100%
  }

  .kat-soeg input {
    flex: 1
  }
}

@media (max-width: 560px) {
  .hero-kat {
    padding: 36px 0 48px
  }

  .hero-kat .lead {
    margin-bottom: 32px
  }

  .cat-card {
    padding: 18px 12px 20px 0;
    gap: 10px
  }

  .cat-icon {
    width: 42px;
    height: 30px
  }

  .cat-card h3 {
    font-size: 15.5px
  }

  .pris-opdateret {
    white-space: normal
  }
}

/* ── Loading-skeleton og fejltilstand for dealGrid ──
   Uden disse stod gitteret enten tomt i det korte øjeblik produkter.json
   hentes, eller helt tomt og tavst hvis hentningen fejlede. */
.skeleton-block,
.skeleton-line {
  background: linear-gradient(90deg, var(--surface) 25%, var(--border) 50%, var(--surface) 75%);
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.4s ease-in-out infinite;
  border-radius: 6px
}

.deal-card-skeleton .deal-img.skeleton-block {
  border-radius: 0
}

.deal-card-skeleton .deal-body {
  display: flex;
  flex-direction: column;
  gap: 10px
}

/* Samme mønster, til /tilbud's griddet (cykler.js). Uden det stod hele
   siden med kun de statiske filter-tal og "36 tilbud fundet" synlige, mens
   griddet selv var en helt tom kasse indtil api/products.php svarede. */
.product-card-skeleton .product-img.skeleton-block {
  border-radius: 0
}

.product-card-skeleton .product-body {
  display: flex;
  flex-direction: column;
  gap: 10px
}

/* Pladsholder for #filter-butik (views/cykler.php), som ellers stod med
   .filter-options' 2px-gap beregnet til tætpakkede checkbokse — for lidt
   luft til tre løse linjer, der skal ligne kommende butiksnavne. */
#filter-butik .skeleton-line {
  margin: 7px 0
}

.skeleton-line {
  display: block;
  height: 12px
}

.skeleton-line-sm {
  width: 40%
}

.skeleton-line-lg {
  width: 85%;
  height: 18px
}

.skeleton-line-md {
  width: 55%
}

@keyframes skeleton-shimmer {
  0% {
    background-position: 200% 0
  }

  100% {
    background-position: -200% 0
  }
}

@media (prefers-reduced-motion: reduce) {

  .skeleton-block,
  .skeleton-line {
    animation: none
  }
}

.deal-fejl {
  text-align: center;
  padding: 48px 24px;
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  color: var(--muted)
}

.deal-fejl p {
  margin-bottom: 16px
}

/* ── Hero-kat: nøgletal ved siden af overskriften ──
   Stod tomt til højre for h1/lead på brede skærme. .trust/.trust-item
   genbruges som de er (defineret til den gamle hero) — kun ny placering. */
.hero-kat-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 40px;
  flex-wrap: wrap;
  margin-bottom: 44px
}

.hero-kat-text {
  max-width: 480px
}

.hero-kat-text .lead {
  margin-bottom: 0
}

/* v2: løse tal havde for lidt visuel vægt til at retfærdiggøre pladsen.
   Rammet panel med ikon pr. tal i stedet — stadig ægte data, nu med
   faktisk tilstedeværelse. */
.hero-kat-trust {
  display: flex;
  align-items: stretch;
  flex-shrink: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 6px
}

.hero-kat-trust .trust-item {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 10px;
  padding: 14px 16px
}

.hero-kat-trust .trust-item+.trust-item {
  border-left: 1px solid var(--border)
}

.trust-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 9px;
  background: var(--primary-soft);
  color: var(--primary);
  flex-shrink: 0;
  overflow: hidden
}

.trust-icon svg {
  width: 18px;
  height: 18px
}

.trust-text {
  display: flex;
  flex-direction: column;
  gap: 1px
}

.hero-kat-trust .trust-item strong {
  font-family: var(--font-display);
  font-size: 24px;
  line-height: 1.1;
  color: var(--text);
  font-weight: 600
}

.hero-kat-trust .trust-item span {
  font-size: 12px;
  color: var(--faint);
  white-space: nowrap
}

/* ── Partnerbånd under nøgletals-panelet ─────────────────────────────────
   Nøgletals-panelet og båndet er nu én søjle (.hero-kat-side) i stedet for
   at panelet selv er hero'ens højre kolonne. Panelet beholder sin bredde;
   båndet lægger sig under det i samme bredde. */
.hero-kat-side {
  display: flex;
  flex-direction: column;
  gap: 10px;
  flex-shrink: 0;
  min-width: 0;
  max-width: 100%
}

.partner-baand {
  /* Nøgletals-panelet skal bestemme søjlens bredde, ikke båndet.
     Uden de to linjer regner flexbox båndets ønskede bredde med i søjlens
     — og et bånd med fire kopier af butiksnavnene "ønsker" godt 2000px.
     Så sprængte søjlen hero'ens to-kolonne-layout, og panelet lagde sig i
     fuld bredde under overskriften i stedet for ved siden af den.
     width:0 fjerner båndet fra beregningen; min-width:100% giver det
     bagefter den bredde panelet endte med. */
  width: 0;
  min-width: 100%;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 9px 0;
  /* Blød ind- og udtoning i enderne. Uden den bliver navnene klippet midt
     over af kanten, hvilket ser ud som en fejl frem for som bevægelse. */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent)
}

.partner-spor {
  display: flex;
  width: max-content;
  animation: partner-rul 18s linear infinite
}

/* Så man kan nå at læse et navn man hæfter sig ved — og siden navnene blev
   links (28/7), er pausen også dét der gør dem mulige at ramme. Et klikmål
   i bevægelse er svært at træffe; står det stille i samme øjeblik markøren
   nærmer sig, forsvinder problemet.

   :focus-within er ikke pynt ved siden af :hover. Uden den ville en
   tastaturbruger tabbe ind i båndet og se fokusrammen glide væk under sig,
   hvilket er værre end en mus der kan følge efter. */
.partner-baand:hover .partner-spor,
.partner-baand:focus-within .partner-spor {
  animation-play-state: paused
}

.partner-link {
  color: inherit;
  text-decoration: none;
  /* Hele li'et er allerede uppercase og har letter-spacing; linket arver.
     Padding giver et klikmål der er til at ramme uden at bryde linjen. */
  padding: 4px 2px;
  border-radius: 4px;
  transition: color .15s
}

.partner-link:hover,
.partner-link:focus-visible {
  color: var(--primary)
}

/* Der står med vilje INGEN outline her. Den globale :focus-visible-regel
   (3px var(--cta), se toppen af filen) er stærkere og er lavet til netop
   den mørke baggrund. Her stod først en egen 2px-ring i var(--primary),
   som overskrev den globale med noget tyndere og svagere — altså en
   forringelse forklædt som en tilføjelse. Opfind ikke fokusstil pr.
   komponent; ret den globale hvis den ikke slår til. */

.partner-liste {
  display: flex;
  align-items: center;
  gap: 26px;
  /* Halvdelen af gap'et i hver ende: så bliver afstanden hen over
     overgangen mellem to kopier den samme som inde i en kopi. */
  padding: 0 13px;
  margin: 0;
  list-style: none;
  flex-shrink: 0
}

.partner-liste li {
  display: flex;
  align-items: center;
  gap: 22px;
  font-size: 12.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--faint);
  white-space: nowrap
}

.partner-liste li::after {
  content: "";
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--primary);
  opacity: .55;
  flex-shrink: 0
}

/* -25% er præcis én af de fire ens kopier i sporet — se kommentaren i
   index.php. Ændrer du antallet af kopier, skal denne værdi følge med. */
@keyframes partner-rul {
  from {
    transform: translateX(0)
  }

  to {
    transform: translateX(-25%)
  }
}

/* Uendelig bevægelse er en kendt udløser for svimmelhed og for
   opmærksomhedsbesvær, og båndet er ren pynt oven på information der også
   står stille. Står brugeren af, står båndet også: kopierne skjules og den
   ægte liste ombrydes i stedet. */
@media (prefers-reduced-motion: reduce) {
  .partner-spor {
    animation: none;
    width: 100%
  }

  .partner-liste[aria-hidden] {
    display: none
  }

  .partner-liste {
    flex-wrap: wrap;
    justify-content: center;
    width: 100%;
    row-gap: 6px
  }

  .partner-baand {
    -webkit-mask-image: none;
    mask-image: none
  }

  /* Prikken er en rytmemarkør i et bånd der løber. Står navnene stille og
     ombrudt, ender den som en løsrevet prik i enden af hver linje.
     Afstanden alene adskiller navnene fint. */
  .partner-liste li::after {
    display: none
  }
}

@media (max-width: 900px) {
  .hero-kat-side {
    width: 100%
  }

  .hero-kat-trust {
    width: 100%
  }

  .hero-kat-trust .trust-item {
    flex: 1;
    justify-content: center
  }
}

@media (max-width: 560px) {
  .hero-kat-trust {
    flex-direction: column;
    padding: 4px
  }

  .hero-kat-trust .trust-item {
    justify-content: flex-start;
    padding: 12px 14px
  }

  .hero-kat-trust .trust-item+.trust-item {
    border-left: none;
    border-top: 1px solid var(--border)
  }
}

/* CTA fra "Sådan ser priserne ud lige nu" videre til hele kataloget.
   De seks kort er kun en vareprøve — uden linket var der ingen vej herfra
   til /tilbud, ud over at klikke et af de seks tilfældige produkter. */
.deal-grid-cta {
  margin-top: 32px;
  text-align: center
}