/* ═══════════════════════════════════════════════════════════════════════
   CykelTjek.dk — MODERNIST (rebrand 21/8)
   ═══════════════════════════════════════════════════════════════════════

   Erstatter den tidligere nordiske hav/hør/frost/rav-palet. Modernist er
   det designsystem mobilapp-mockuppen ("Cykeltjek App.dc.html") er tegnet
   i, og skiftet er bevidst sitewide — desktop såvel som mobil — ikke kun
   den nye mobilvisning. Ét typesnit (Archivo), én rød accentfamilie, og
   0px hjørner overalt (se radius-reglerne pr. selektor i resten af filen).

   Ingen tokens herunder er omdøbt — kun værdierne er ændret. Alt der
   allerede refererer fx var(--primary) eller var(--felt) virker derfor
   uændret; det er selve farven bag navnet der har skiftet.

*/
:root {
  /* ==========================================================================
     CykelTjek.dk — DESKTOP REDESIGN TOKENS
     Varm cream-, rav- og rustpalette. Skrifttype: Archivo.
     ========================================================================== */

  /* BAGGAGRUNDE & OVERFLADER */
  --page: hsl(40, 15%, 86%);
  /* Primær lys indholdsoverflade */
  --paper: hsl(42, 60%, 96%);
  /* Ekstra lys kort- og inputoverflade */
  --paper-strong: hsl(42, 57%, 99%);

  /* LYS TEKST */
  --ink: hsl(0, 3%, 12%);
  --muted-ink: hsl(0, 3%, 37%);

  /* MØRKE BAGGGRUNDE */
  --dark: hsl(0, 2%, 17%);
  --dark-deep: hsl(12, 4%, 12%);

  /* MØRK TEKST / PÅ MØRK FLADE */
  --light-ink: hsl(0, 2%, 95%);
  --light-ink-dim: hsla(0, 2%, 95%, 0.72);

  /* RUST ACCENT (Primær) */
  --rust: hsl(18, 40%, 44%);
  --rust-hover: hsl(13, 44%, 33%);
  --rust-light: hsl(21, 42%, 57%);
  --rust-extra-light: hsl(21, 46%, 74%);
  --rust-tint: hsl(18, 47%, 90%);

  /* KATEGORI FARVER */
  --rose: hsl(17, 60%, 91%);
  --sage: hsl(100, 23%, 91%);
  --mauve: hsl(330, 28%, 92%);
  --mist: hsl(202, 18%, 92%);
  --apricot: hsl(29, 62%, 92%);
  --lavender: hsl(262, 26%, 92%);
  --oat: hsl(36, 42%, 92%);
  --mint: hsl(152, 20%, 91%);

  /* BORDERS */
  --line: hsla(0, 3%, 12%, 0.12);
  --line-light: hsla(0, 0%, 100%, 0.14);

  /* SKYGGER */
  --shadow: hsla(18, 18%, 25%, 0.10);

  /* HJØRNER (Standarder fra guide) */
  --radius-sm: 12px;
  --radius-md: 14px;
  --radius: 16px;
  /* Standard */
  --radius-lg: 20px;
  --radius-app: 22px;

  /* BACKWARDS COMPATIBILITY (L映射到新的 tokens hvis der bruges ældre filer) */
  --bg: var(--page);
  --bg-2: var(--paper);
  --bg-3: var(--paper-strong);
  --surface: var(--paper);
  --surface-alt: var(--paper-strong);
  --border: var(--line);
  --text: var(--ink);
  --muted: var(--muted-ink);
  --primary: var(--rust);
  --primary-hover: var(--rust-hover);
  --primary-soft: var(--rust-tint);
  --cta: var(--rust);
  --cta-hover: var(--rust-hover);
  --paa-farve: var(--light-ink);
  --felt: var(--dark);
  --felt-dyb: var(--dark-deep);
  --paa-felt: var(--light-ink);
  --paa-felt-dim: var(--light-ink-dim);
  --felt-linje: var(--line-light);
  --felt-linje-kraftig: var(--line-light);
  --primary-paa-felt: var(--rust);

  /* GLOBALE LAYOUT MÅL */
  --maxw: min(100% - 48px, 1376px);
  --maxw-deals: min(100% - 48px, 1376px);
  --app-frame-width: min(100% - 48px, 1376px);

  /* TYPOGRAFI */
  --font-display: 'Archivo',
    'Helvetica Neue',
    Arial,
    sans-serif;
  --font-body: 'Archivo',
    system-ui,
    sans-serif;
  --font-data: 'Archivo',
    system-ui,
    sans-serif;

  color-scheme: light;
  --fejl: #7C1405;
}

/* ⚠ HER LÅ DET MØRKE TEMA OG TEMASKIFTEREN — begge fjernet 19/8.
   Sitet har ét udtryk nu: den lyse nordiske palet ovenfor, som er den
   der er designet imod. Et tema mere ville betyde to sæt beslutninger
   at holde i sync ved hver eneste ændring, og det andet sæt ville få
   halvdelen af opmærksomheden.
   Alt hvad der hørte til er væk i samme omgang: `data-tema`-attributten,
   temaknappen i header.php, anvendTema()/gemTema() i favorites.js,
   inline-scriptet i <head>, og `ck_tema` i localStorage. Finder du en
   rest der stadig nævner dem, er den efterladt — ikke tilsigtet. */


* {
  box-sizing: border-box;
  margin: 0;
  padding: 0
}

html {
  scroll-behavior: smooth
}

body {
  font-family: var(--font-body);
  background: var(--page);
  color: var(--text);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  font-weight: 400;
  margin: 0;
  overflow-x: hidden;
}

.app-wrapper {
  background: var(--paper);
  width: var(--app-frame-width);
  margin: 24px auto;
  border-radius: var(--radius-app);
  box-shadow: 0 20px 80px var(--shadow);
  min-height: calc(100vh - 48px);
  overflow: hidden;
  /* Holder indholdet inde i de afrundede hjørner */
  display: flex;
  flex-direction: column;
}

/* Fix til at undgå, at indhold vokser over bredden og skubber app-wrapper ud af telefonens skærm
   på grund af automatisk flexbox min-width */
.app-wrapper>* {
  min-width: 0;
}

/* Responsiv specificerering fra guide: "App-ramme: Skærme under 900px" */
@media (max-width: 900px) {
  .app-wrapper {
    width: 100%;
    margin: 0;
    border-radius: 0;
    min-height: 100vh;
  }
}


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: 0
}

/* 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;
  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
  }
}

/* ── Visuelt skjult, men til stede for skærmlæsere ──
   TILFØJET 21/8, første brug: <label for="sortMobil"> (cykler.php) — den
   kompakte mobil-sorteringsvælger har ingen synlig label (selve
   <select>'en viser allerede "Sorter: …"), men et formfelt uden NOGEN
   label, hverken synlig eller programmatisk, er ikke tilgængeligt.
   display:none ville fjerne den fra skærmlæsere også — standardmønstret
   klipper den i stedet visuelt uden at fjerne den fra tilgængeligheds-
   træet. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.container {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 28px
}

::selection {
  background: var(--primary);
  color: var(--paa-farve)
}

/* Disclosure bar (Affiliate-linje) */
.disclosure-bar {
  background: var(--dark-deep);
  color: var(--light-ink-dim);
  font-size: 10px;
  min-height: 34px;
  padding: 7px 24px;
  text-align: center;
}

.disclosure-bar a {
  color: var(--rust);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.disclosure-bar a:hover {
  text-decoration: none;
}

/* Kampagnebanner — sat i admin-panelet (site_settings). Står OVER
   disclosure-bar'en, med primærfarven så den skiller sig ud som et
   tidsbegrænset budskab i modsætning til disclosure-barens neutrale tone. */
.campaign-banner {
  background: var(--primary);
  /* ⚠ var #fff. --primary er MØRK i lyst tema og LYS i mørkt tema, så en
     fast hvid tekst holdt kun det ene sted. --paa-farve findes præcis
     til det her og vender med temaet. */
  color: var(--paa-farve);
  font-size: 13px;
  font-weight: 600;
  padding: 9px 0;
  text-align: center;
}

.campaign-banner a {
  color: inherit;
  text-decoration: underline;
}

/* Header */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--paper);
  color: var(--ink);
  border-bottom: 1px solid var(--line);
}

.header-inner {
  display: flex;
  align-items: center;
  gap: 28px;
  min-height: 78px;
}

.logo {
  display: flex;
  align-items: center;
  gap: 11px;
  /* Cykelmærket står på feltet — se noten ved --primary-paa-felt. */
  color: var(--primary-paa-felt)
}

.logo-text {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -.07em;
  color: var(--ink);
}

.logo-text strong {
  color: var(--rust);
  font-weight: 800;
}


.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
  flex: 1;
  color: var(--ink);
}

.main-logo-icon {
  color: var(--rust);
  width: 38px;
  height: 28px;
}

.brand-name {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 500;
  letter-spacing: -.02em;
}

.brand-name strong {
  font-weight: 800;
}

.main-nav {
  display: flex;
  gap: clamp(16px, 2vw, 32px);
}

.main-nav a {
  font-size: 13px;
  font-weight: 650;
  color: var(--muted-ink);
  transition: color .2s ease;
}

.main-nav a:hover,
.main-nav a.is-active {
  color: var(--rust);
}

/* ⚠ RETTET 20/8: margin-left: auto stod her fra dengang .header-actions
   selv indeholdt søgefelt + CTA og skulle skubbes til højre uafhængigt.
   .main-nav fik SIN EGEN margin-left: auto i header-forenklingen samme
   dag (se dens kommentar) — med to elementer der begge har auto-margin i
   samme retning, DELER flexbox den ledige plads ligeligt mellem dem.
   Nav fik derfor kun HALVDELEN af pladsen og endte svævende midt i
   baren, mens den nu tomme .header-actions (kun hamburgerknappen,
   0 bred på computerbredde) åd den anden halvdel og landede helt ude i
   kanten for sig selv. Mathias fandt det ved at tegne streger mellem to
   skærmbilleder: navigationen fulgte ikke mosaikkens højrekant nedenunder.
   Kun ÉT element i rækken må have auto-margin — det er nav nu. */
.header-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 12px;
  flex: 1;
}



/* "Se cykler" brød over 3 linjer i den smalle mobil-header */
.header-actions .btn {
  white-space: nowrap
}

/* ⚠ Her lå temaknappen (.tema-knap + tre ikontilstande). Fjernet 19/8
   sammen med det mørke tema — en knap der kun kan vælge ét tema er ikke
   en knap. Se noten ved :root øverst. */

.search {
  display: flex;
  align-items: center;
  position: relative;
  /* Sekundært søgefelt på brede skærme (ligger i header-actions) */
  width: min(310px, 29vw);
  margin-left: 14px;
}

.search input {
  appearance: none;
  -webkit-appearance: none;
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 10px 13px 10px 36px;
  font-family: inherit;
  font-size: 13px;
  width: 100%;
  background: var(--paper-strong);
  color: var(--ink);
  outline: 0;
  transition: border-color .2s ease, box-shadow .2s ease;
}

.search-btn {
  position: absolute;
  left: 13px;
  top: 50%;
  transform: translateY(-50%);
  width: 16px;
  height: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  color: var(--rust);
  cursor: pointer;
}

.search-btn svg {
  width: 16px;
  height: 16px;
}

.search input::placeholder {
  color: var(--muted-ink);
}

.search input:focus {
  border-color: var(--rust);
  box-shadow: 0 0 0 3px hsla(18, 47%, 90%, 0.5);
  /* 12% rusttoning */
}

.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: 50px;
  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);
  /* ⚠ Var var(--text). Det gav 2,63:1 — næsten sort tekst på mørkebrun.
     Fejlen har ligget i det lyse tema hele tiden, men var usynlig så
     længe mørkt var standard: dér var --text lys og alt så rigtigt ud.
     Da lyst blev det eneste tema 19/8, blev den synlig.
     --paa-farve er den eneste rigtige her; den er defineret netop som
     "tekst oven på en farvet flade". */
  color: var(--paa-farve);
  box-shadow: 0 6px 24px rgba(224, 138, 58, .38)
}

.btn-ghost {
  background: transparent;
  color: var(--text);
  border: 1px solid var(--border)
}

/* Solid mørk knap til brug PÅ en lys flade (modsat .paa-felt-knapperne
   ovenfor, som er til brug PÅ feltet). Findes fordi mockuppen fra 19-20/8
   bruger den til "Se hele udvalget →" under kategorirækkerne — en tredje
   vægt mellem .btn-primary (den ene stærke CTA pr. skærm) og .btn-ghost
   (sekundær): en solid, mørk knap der ikke konkurrerer med rav-orange, men
   stadig er tydeligt klikbar. */
.btn-dark {
  background: var(--felt);
  color: var(--paa-felt);
  /* Frostkant — mockuppens .knap har den (border: 1px solid var(--frost)),
     min egen udgave manglede den. Sitet har ikke en --frost-token, kun
     rgba(148,166,178,…) skrevet i hånden andre steder (partner-båndets
     eger og skilletegn) — samme farve, #94A6B2, som literal her. */
  border: 1px solid #94A6B2
}

.btn-dark:hover {
  background: var(--felt-lift);
  color: var(--paa-felt)
}

/* ── .paa-felt — kontekstklasse for alt der ligger PÅ det mørke felt ──
   Sættes på en container (header, footer, forsidens hero), ikke på det
   enkelte element. Alt indeni skifter så til feltets accentfarve og
   feltets tekstfarver.

   Findes fordi --primary og --cta er afstemt til den LYSE læseflade.
   En amber-knap i --cta på det mørke felt er mørk-på-mørk og ser
   snavset ud; --primary-paa-felt er samme kulør ved den lyshed feltet
   kræver. Se noten ved tokenet.

   Bruges i dag af .site-header og .site-footer. Når forsidens hero
   bliver et felt, får den samme klasse — ikke sin egen kopi af
   reglerne. */
.paa-felt .btn-primary {
  background: var(--primary-paa-felt);
  color: var(--felt-dyb);
  box-shadow: 0 4px 18px rgba(0, 0, 0, .22)
}

.paa-felt .btn-primary:hover {
  background: var(--primary-paa-felt-hover);
  color: var(--felt-dyb);
  box-shadow: 0 6px 24px rgba(0, 0, 0, .3)
}

.paa-felt .btn-ghost {
  border-color: var(--felt-linje-kraftig);
  color: var(--paa-felt)
}

/* ⚠ Var var(--primary-paa-felt) (rød/laks til mørk baggrund) — rav/rusts
   egen lyse variant (#C08260), samme rettelse som .footer-col a:hover. */
.paa-felt .btn-ghost:hover {
  border-color: #C08260;
  color: #C08260;
  background: transparent
}

.paa-felt a {
  color: inherit
}

.brand .brand-name {
  color: var(--text);
}

.brand .brand-name strong {
  color: #8B4C06;
}

/* ⚠ Var var(--primary) (rød) — rav/rust (var(--rust)), samme rettelse som
   resten af mobilredesignet. Sat sitewide (ikke mobil-scopet): .btn-ghost
   bruges også af "Alle produkter"/"Se guides" på desktop-heroen, og en
   knap der glødede rødt ét sted og rustfarvet et andet ville se
   inkonsekvent ud. */
.btn-ghost:hover {
  border-color: var(--rust);
  color: var(--rust)
}

.btn-sm {
  font-size: 13.5px;
  padding: 9px 18px
}

.nav-toggle {
  display: none;
  /* ⚠ TILFØJET 21/8 (DESIGNSYSTEM.md, A5): knappen flyttede FØR #nav i
     DOM'en, så en tastaturbruger møder den før menulinkene (CSS `order`
     ændrer aldrig Tab-rækkefølgen, kun det visuelle — se header.php's
     egen kommentar). Den er nu direkte barn af .header-inner (samme
     flex-container som .brand/#nav/.header-actions), ikke længere af
     .header-actions — order:1 holder den visuelt yderst til højre,
     uændret fra før flytningen. */
  order: 1;
  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(--paa-felt);
  border-radius: 0
}

/* 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: 0;
  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: 0;
  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: 0;
  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: 0;
  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/.pris-head er FJERNET 21/8. Begge var scopet til
   #tilbud's titel/tidsstempel-linje, "bruges kun ét sted i hele
   kodebasen" som den gamle kommentar her selv sagde — og det ene sted er
   væk: titlen/tidsstemplet flyttede ned i den nye .deals-hero__box (se
   den, længere nede i filen), efter ønske fra Mathias (Retning 1-guiden,
   ændringer til design/). .pris-opdateret/.pris-opdateret-tid/.pris-prik
   lever videre uændret i navn, men genbruges nu inde i den mørke boks —
   se dens egne dark-bg-overrides. */

/* Categories — editorial, borderless */
.cat-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0
}

/* Bærer søgefeltet OG guide-knappen under kategorigitteret (se index.php,
   6/8). justify-content: flex-end holder parret i samme højrestillede
   position søgefeltet alene havde dengang det stod i .kat-sekundaer.
   .kat-soeg's egen `margin-left: auto` er neutraliseret nedenfor — med to
   børn i rækken ville den skubbe GUIDE-knappen væk fra søgningen i stedet
   for at samle dem, fordi auto-margin virker på sit eget element, ikke på
   søskende efter det. */
.hero-kat-under {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: 10px;
  /* Delelinje mellem mosaikken og søgerækken — fra mockuppen 19-20/8, ikke
     med i første udgave af hero'en. margin-top er ÉN afstand, ikke to: den
     erstatter den gamle rene margin, så linjen og luften over den ikke
     lægger sig oven i hinanden. */
  margin-top: 28px;
  padding-top: 24px;
  /* ⚠ TILFØJET 20/8: manglede helt. Mockuppens .hero-under har
     padding: 26px 0 30px — luft under rækken FØR partnerbåndet, ikke kun
     over den. Uden den sad søgefelt/knapper og partnerbåndets rullende
     navne næsten oven i hinanden; Mathias beskrev det som "presset og
     klemt". */
  padding-bottom: 30px;
  border-top: 1px solid var(--felt-linje)
}

/* width: auto neutraliserer .kat-soeg's EGEN 900px-regel (`width: 100%`),
   som ellers fik formularen til at fylde hele rækken og skubbe
   guide-knappen ned på sin egen linje mellem 561 og 900px — målt direkte:
   uden denne linje stod de to IKKE på samme række i det interval. */
.hero-kat-under .kat-soeg {
  margin-left: 0;
  width: auto
}

/* Kortere felt end .kat-soeg's fælles 300px — "Søg mærke eller model" er
   den primære handling, men to elementer om pladsen betyder ingen af dem
   skal kræve al bredden for sig selv. 220px rummer stadig placeholderens
   eksempel ("fx Engwe") uden at klippe det.
   ⚠ `flex` skal overskrives, ikke kun `width`. .kat-soeg's 900px-regel
   sætter `flex: 1` (dvs. flex-basis: 0%) på inputtet, og flex-basis
   bestemmer hovedaksens størrelse FØR width overhovedet læses — en højere
   CSS-specificitet på `width` alene vinder ikke over det. */
.hero-kat-under .kat-soeg input {
  flex: 0 1 220px;
  width: 220px
}

/* ⚠ TILFØJET 20/8: mockuppens .soegefelt (WebFetch af artifact e339b87a)
   vokser ubetinget — flex:1 på både container og input, ved ENHVER
   bredde, ingen særtilfælde. Live havde søgefeltet fastlåst til 220px
   permanent, også på fuld computerbredde, hvor der er masser af plads —
   resultatet var en kort søgeboks med et stort tomt hul i midten af
   rækken, mens "Alle produkter"/"Se guides" blev presset helt ud i
   højre kant af justify-content: space-between (fjernet, se
   min-width:901px-blokken andetsteds i filen).
   Kun ≥901px: den smallere 561-900px-zone beholder sin egen, allerede
   afprøvede 220px-løsning (se kommentaren ovenfor) — den er en reel
   pladsbegrænsning, ikke en fejl, og røres ikke. */
@media (min-width: 901px) {
  .hero-kat-under .kat-soeg {
    flex: 1 1 auto
  }

  .hero-kat-under .kat-soeg input {
    flex: 1 1 auto;
    width: auto
  }
}

/* ⚠ TILFØJET 20/8, VENDT OM 20/8: sat til 3px efter den TIDLIGERE
   mockup ("artifact e339b87a"). Den nye mockup-runde (variant 1a) har
   ingen rektangulære knapper noget sted — alle knapper, inkl. disse to,
   er fulde piller. Reglen kan fjernes helt: uden den arver de .btn's
   egen 999px, som er den rigtige værdi nu. Kommentaren blive stående
   som forklaring, hvis nogen leder efter reglen igen. */

.kat-guide-link {
  flex-shrink: 0;
  white-space: nowrap
}

/* ⚠ RETTET 20/8: .kat-alle-link ("Alle produkter") skiftede før mellem
   synlig/skjult ved 681px, og en tredje knap .kat-produkter-link
   ("Se produkter") tog over ≥901px — en vekslen der fandtes for ikke at
   duplikere headerens dengang faste CTA. Den CTA er væk fra headeren
   (partials/header.php), så hele vekslingen — og .kat-produkter-link
   selv — er overflødig. Mockuppen (WebFetch af artifact e339b87a, 20/8)
   har ét statisk link her, synligt ved alle bredder. */
.kat-alle-link {
  flex-shrink: 0;
  white-space: nowrap
}

/* ⚠ space-between-reglen der stod her er FJERNET 20/8: med .kat-soeg nu
   flex:1 (se ovenfor) fylder søgefeltet al den plads der ellers ville
   blive fordelt, så space-between endte med at skubbe "Se guides" helt
   ud i kanten, langt fra "Alle produkter" ved siden af — mockuppen
   holder de to knapper samlet lige efter søgefeltet, ikke spredt. */

@media (max-width: 560px) {

  /* Under 560px er der ikke plads til feltet, knappen OG en guide-knap på
     samme linje uden at noget klippes — samme regnestykke som forsidens
     produktkort et par steder nedenfor. Guide-knappen får sin egen række. */
  .hero-kat-under {
    flex-direction: column;
    align-items: stretch
  }

  /* Genindfører fuld bredde, som .kat-soeg's 900px-regel ellers gav —
     men den blev neutraliseret et par regler ovenfor (width: auto),
     specifikt for at kunne holde formularen SMAL mellem 561 og 900px.
     Her, under 560px, er formularen alene på sin egen række igen, så den
     skal tilbage til fuld bredde. */
  .hero-kat-under .kat-soeg {
    width: 100%
  }

  .hero-kat-under .kat-soeg input {
    flex: 1;
    width: auto
  }

  /* Knappen skåret ned til .btn-sm's mål, så feltet — den primære
     handling på mobil — får det meste af den vundne bredde i stedet for
     knappen. `.kat-soeg .btn` (ovenfor) fjernede allerede den globale
     width:100%-fejl; dette er den ekstra kompakthed der blev bedt om
     specifikt til telefonvisning, ikke en fejlrettelse. */
  .hero-kat-under .kat-soeg .btn {
    padding: 10px 16px;
    font-size: 13.5px
  }

  .kat-alle-link,
  .kat-guide-link {
    justify-content: center
  }
}

.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 h2 {
  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
}

/* flex-wrap er ikke pynt: "Se alle mountainbikes →" har white-space:
   nowrap og flex-shrink: 0, så på en 320px skærm kan overskrift og link
   ikke være på samme linje — og uden wrap skubbede linket 19px ud over
   skærmkanten og gjorde HELE siden sidelæns scrollbar. Målt 19/8. */
.deal-kategori-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 20px;
  flex-wrap: wrap;
  margin-bottom: 18px
}

.deal-kategori-head h3 {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 600
}

/* ⚠ TILFØJET 21/8: produktantallet flyttede hertil fra sidebar-boksens
   genvejsliste, efter ønske fra Mathias — samme .cat-count/data-kat-em
   som kategorimosaikkens fliser, udfyldt af den allerede eksisterende
   renderKategoriAntal() (script.js), ingen ny JS-logik. Tydeligt
   nedtonet i forhold til selve kategorinavnet — ellers konkurrerer to
   lige tunge tal/navne om samme linje. */
.deal-kategori-head h3 .cat-count {
  font-family: var(--font-data);
  font-size: 14px;
  font-weight: 500;
  color: var(--muted)
}

.deal-kategori-head h3 .cat-count strong {
  font-weight: 500
}

.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. */
/* ⚠ RETTET 20/8: kortets hover-løft (.product-card:hover, translateY(-2px))
   blev klippet af foroven, kun her på forsiden. `overflow-x: auto` uden en
   eksplicit `overflow-y` bliver ikke stående som visible — CSS' egen
   tvangsregel gør begge akser 'auto', så snart den ene er 'auto' og den
   anden 'visible' (spec: "if one is visible and the other is not, the
   visible one is set to auto"). Rækken var derfor lodret klippet hele
   tiden, bare usynligt, fordi kortene stod presset op mod toppen. Samme
   `padding-bottom: 4px` fandtes allerede til at give plads i bunden;
   `padding-top` manglede helt. /tilbud rammes ikke — dens grid har ingen
   overflow-x og altså ingen klipning. */
/* ⚠ RETTET 20/8: scrollbar-width:thin tegnede en synlig rullebjælke under
   hver kategori-række — overflødig ved siden af pilene
   (initDealScrollKnapper(), script.js) og det femte kort der bevidst
   kigger frem i kanten (se noten ovenfor) som allerede signalerer at
   rækken kan rulles. `none` fjerner selve bjælken; rækken kan stadig
   rulles med touch/trackpad/pilene, kun den visuelle bjælke er væk. */
/* ⚠ align-items: flex-start — uden den strækker flexboksens standard
   (stretch) HVERT kort til samme højde som det højeste i rækken (fx et
   kort med "Fås i X varianter" eller en 3-linjers titel), og
   .product-body's flex:1 fylder den ekstra højde ud som tomt rum under
   "Se cykel"-knappen. flex-start lader hvert kort være sin egen naturlige
   højde i stedet, efter ønske om at trække bunden op mod knappen. */
.deal-kategori-scroll {
  display: flex;
  align-items: flex-start;
  gap: 20px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding-top: 4px;
  padding-bottom: 4px;
  scrollbar-width: none
}

.deal-kategori-scroll::-webkit-scrollbar {
  display: none
}

/* Var 260px. Kortet blev skåret ned andre steder 6/8 (polstring, titel,
   .trust-micro fjernet) uden at bredden fulgte med, og billedet er
   proportionsstyret (aspect-ratio 4/3 på .deal-img) — så billedet stod
   ubevægeligt, mens alt omkring det skrumpede. Målt: billedets andel af
   kortets højde voksede fra 35% til 40%, og på et bredt vindue viste
   .container's faste 1180px stadig kun 4 af 10 kort pr. kategori.
   220px trækker billedet med ned og lader et femte kort kigge frem i
   kanten, samme affordance som 44%-reglen gav på mobil. */
.deal-kategori-scroll .deal-card {
  flex: 0 0 220px;
  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. */
/* ⚠ RETTET 20/8: kant→skygge, facit i "Implementeringsguide - PRAECIS.md"
   (ændringer til design/), afsnit 1 — sidste af sitets runde skygge-pile
   der stadig havde sin gamle kant. */
.deal-scroll-knap {
  position: absolute;
  top: 50%;
  transform: translateY(6px);
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--surface);
  border: none;
  color: var(--text);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: var(--skygge-m);
  transition: .15s
}

.deal-scroll-knap:hover {
  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 havde sin egen kortskal (baggrund/kant/hjørner/hover-løft) og
   sit eget billedfelt (.deal-img) frem til 6/8. Kortet er nu bygget af
   .product-card/.product-img — samme klasser som /tilbud — så det ser ud
   som dem, i stedet for at ligne dem via en parallel, næsten-identisk
   kopi. .deal-card lever videre som EKSTRA klasse på artiklen, men bærer
   nu KUN den vandrette scroll-rækkes egen breddestyring, se
   `.deal-kategori-scroll .deal-card` OVENFOR. Selve kortudseendet —
   skal/billede/krop/pris/CTA — kommer fra .product-card og dens børn. */

/* .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. */
/* ⚠ RETTET 20/8, VENDT OM 20/8: border-radius var var(--radius) (10px),
   blev sat til 3px efter en TIDLIGERE mockup ("artifact e339b87a") der
   ville have kant + skarpt hjørne ("teknisk tegning"). Den nye,
   godkendte mockup-runde (variant 1a "Rolig finish", mappen
   "ændringer til design/") vælger det modsatte: ingen kant, en blød
   skygge, og runde hjørner. Værdierne herunder er ikke skønnet — de
   kommer ord for ord fra "CSS-ændringer til implementering.md" i samme
   mappe, som Mathias lagde som facit efter at min egen tolkning af
   mockuppen ikke ramte præcist. */
.product-card {
  background: #FFF;
  border: none;
  border-radius: 16px;
  box-shadow: 0 4px 12px rgba(8, 18, 26, 0.04);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: transform .2s ease, box-shadow .2s ease;
  cursor: pointer;
  position: relative;
}

.product-card:hover {
  box-shadow: 0 12px 23px rgba(8, 18, 26, 0.06);
  transform: translateY(-2px);
}

/* Forhold frem for fast højde.
 *
 * Var `height: 190px` uanset kortets bredde. På en telefon med to kolonner
 * er kortet ~150 px bredt, og et 190 px højt billede fyldte da mere end
 * halvdelen af kortet — målt 41 % da kortet var 319 px bredt, og det bliver
 * værre jo smallere kortet er.
 *
 * 4/3 følger kortet: ~112 px ved 150 px bredde, ~197 px ved 263 px. Det er
 * samtidig tættere på cykelfotos' eget format end en fast højde er.
 *
 * ⚠ Klassen deles med favoritsiden og produktsidens relaterede (invariant
 * 11), som begge bruger smallere kort end /tilbud. De får derfor et lavere
 * billede med — hvilket er den rigtige retning begge steder. */
.product-img {
  aspect-ratio: 4 / 3;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-alt);
  /* ⚠ RETTET 20/8, VENDT OM 20/8: kortet har ikke længere en ydre kant
     (se .product-card), så en indre linje her ville stå alene uden
     noget at fortsætte fra. Tonefarven --surface-alt mod --surface
     under er selv adskillelsen. */
  position: relative;
  overflow: hidden;
  /* ⚠ Denne linje bærer fallback-ikonet. bikeIcon() (favorites.js) tegner
     sine SVG'er med stroke="currentColor", fordi en SVG-attribut ikke
     forstår var(). Farven skal derfor komme herfra — fjernes den, bliver
     ikonet sort på begge temaer. Gælder også #pd-image-slot nedenfor og
     favoritsidens kort; alle tre viser samme ikon. */
  color: var(--primary)
}

/* Samme begrundelse som .product-img ovenfor: produktsidens galleri og
   favoritkortene viser det samme fallback-ikon og skal give det en farve
   at arve. Invariant 11's mønster — klassen deles af tre sider, så
   reglen hører hjemme her i styles.css og ikke i en sidespecifik fil. */
#pd-image-slot,
.fav-card .product-img {
  color: var(--primary)
}

.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. */
/* ⚠ RETTET 21/8: stod tidligere som en "måtte" med 8px luft, runde hjørner
   og skygge (se git-historik) — et bevidst designvalg fra dengang kortet
   havde en mørk ramme og et kant-til-kant hvidt foto ville have kollideret
   med den. Den mørke ramme er væk siden "Rolig finish"-redesignet
   (kant→skygge): kortets baggrund er nu --surface, en lys cremefarve, og
   --foto-flade er hvid — de to ligger tæt nok til at et kant-til-kant foto
   ikke længere kolliderer med noget. Fylder nu hele .product-img'et, efter
   ønske fra Mathias. */
.product-photo {
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: var(--foto-flade);
  transition: transform .3s
}

/* ⚠ FLYTTET 22/8 fra cykler.css (invariant 11) — .product-kategori-tag
   bruges nu af BÅDE /tilbud's kort (cykler.js) OG forsidens deal-kort
   (script.js, index.php's SSR-fald), og kun /tilbud loader cykler.css.
   Skjult som standard; #productGrid (cykler.css) og #dealGrid (denne
   fil, mobil-blokken nedenfor) slår den til igen ≤768px — på desktop
   bærer butiksnavnet allerede identifikationen, og begge på samme linje
   blev redundant. */
.product-kategori-tag {
  display: none;
}

.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
}

/* Klippet til to linjer.
 *
 * Uden dette bliver kortene ujævnt høje, så snart gitteret bliver smalt:
 * "Specialized Diverge 4 Sport Alloy 2026 - Satin Burnt Gold Metallic"
 * fylder fem linjer på et 150 px-kort, mens nabokortet fylder én. Et gitter
 * med huller ser i stykker ud.
 *
 * To linjer, ikke tre: titlen er sjældent det, man vælger ud fra i en liste
 * — det er billedet og prisen. Hele titlen står på produktsiden. */
.product-title {
  font-size: 13.5px;
  font-weight: 650;
  line-height: 1.4;
  color: var(--ink);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: calc(2 * 1.4em);
}

.product-rating {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12.5px;
  color: var(--muted)
}

.product-stars {
  color: var(--deal);
  letter-spacing: -1px
}

/* ⚠ RETTET 20/8: margin-top:auto trak prisen til BUNDEN af kortet — ikke
   et fast mellemrum under titlen. Kortets højde bestemmes af CSS Grids
   standard align-items:stretch (alle kort i samme række strækkes til det
   højeste), og hvor meget "ledig plads" der er tilbage til den auto-margin
   afhænger af forholdet mellem billedets 4:3-format (skalerer med
   kortbredden) og tekstblokkens FASTE px-højde (skalerer ikke). På
   desktop går regnestykket næsten op (målt: 6px mellemrum — kun selve
   flex-gap'en, ingen ekstra margin). På mobil er billedet forholdsmæssigt
   lavere, så der bliver mere ledig plads tilbage, og auto-margin suger
   den hele vejen op: 14px, mere end dobbelt så meget. Samme titel, samme
   pris, forskelligt mellemrum — det var det brugeren pegede på.
   Nu hvor titel (min-height, 2 linjer) og metalinjen (min-height 16px)
   begge har fast reserveret højde, er der intet legitimt behov for at
   skubbe prisen til bunden længere — hvert kort i en række har allerede
   samme indholdshøjde. margin-top:auto er fjernet; mellemrummet er nu
   udelukkende flex-gap'en (.product-body, 6px/4px på mobil) + denne
   padding-top, samme værdi uanset skærmbredde. */
.product-price-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 8px;
  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-data);
  font-variant-numeric: tabular-nums;
  font-size: 16px;
  font-weight: 800;
  letter-spacing: -.02em;
  color: var(--rust);
}

.product-save {
  font-size: 12px;
  font-weight: 600;
  color: var(--deal);
  background: var(--deal-soft);
  padding: 2px 8px;
  border-radius: 0
}

.product-stores {
  font-size: 11.5px;
  color: var(--faint);
  margin-top: 2px
}

.product-stores strong {
  color: var(--primary)
}

/* "Fås i N varianter" — samme model i flere udgaver, se variantLinje().
   BOR HER OG IKKE I cykler.css: klassen bruges af BÅDE cykler.js (/tilbud)
   og script.js (forsiden), og kun cykler.php loader cykler.css. Lå reglen
   dér, ville linjen stå uformateret på forsiden. Invariant 11. */
.product-varianter {
  font-size: 11.5px;
  color: var(--faint);
  margin-top: 2px
}

/* "Laveste i 30 dage" — se p.atLowest30d/lavesteLinje() i cykler.js og
   script.js. BOR HER, samme begrundelse som .product-varianter ovenfor:
   klassen bruges af begge de filer, kun cykler.php loader cykler.css.
   En pille i stedet for almindelig tekst, ligesom .product-save — begge
   er positive prispåstande og skal læses ens, ikke som endnu en grå
   metalinje. */
.product-laveste {
  font-size: 11px;
  font-weight: 600;
  color: var(--deal);
  background: var(--deal-soft);
  padding: 2px 8px;
  border-radius: 0
}

/* "Sammenlign N butikker" og "Fås i N varianter" side om side i stedet for
   under hinanden. De to er søskende i .product-body, som er en
   flex-KOLONNE, så de stod nødvendigvis på hver sin linje og kostede
   ~21 px pr. kort uden at sige mere. Nu pakket i én flex-række, der
   ombryder hvis kortet er for smalt — på lodret plads er et smalt kort det
   dyreste sted at spilde.
   ⚠ RETTET 20/8: begge spænd er valgfrie (de fleste kort har hverken —
   ét tilbud, ingen varianter — se butiksLinje()). .product-price-row
   ovenfor er bundankret (margin-top:auto) i samme flex-søjle, så en
   linje der nogle gange er tom og nogle gange fylder 16px flyttede
   prisen op og ned fra kort til kort i samme række — målt som "prisen
   skifter position" på tværs af et helt vindue af kort. min-height låser
   pladsen fast, uanset om linjen reelt har noget at vise. */
.product-meta-linje {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 10px;
  min-height: 16px
}

.product-meta-linje .product-stores,
.product-meta-linje .product-varianter {
  margin-top: 0
}

.product-varianter strong {
  color: var(--text)
}

/* ⚠ TILFØJET 22/8, efter ønske — genindfører en synlig kort-knap, som
   .product-cta's egen kommentar herunder beskriver blev fjernet 20/8.
   Rører ikke den begrundelse: hele kortet er stadig klikbart via
   .product-cta (invariant 15), denne knap er nu en ekstra, synlig
   indgang til det samme mål, ikke en erstatning for klikbarheden. */
/* .product-card .product-se-knap (to klasser), ikke .product-se-knap
   alene: en global `.btn { width: 100% }` under 680px (linje ~3189)
   har samme specificitet som én enkelt klasse og stod SENERE i filen,
   så den vandt over width:auto uanset align-self. To klasser slår den
   uden !important. */
.product-card .product-se-knap {
  display: inline-flex;
  align-self: flex-start;
  width: auto;
  margin-top: 8px;
  border-radius: 14px;
  padding: 7px 11px;
  font-size: 11.5px;
  font-weight: 750;
  background: var(--rust);
  color: #fff;
  box-shadow: none;
  transition: box-shadow .2s ease, background-color .2s ease;
}

.product-card .product-se-knap:hover {
  background: var(--rust);
  box-shadow: 0 4px 10px rgba(192, 130, 96, 0.3);
}

/* ⚠ RETTET 20/8: var en fyldt orange knap ("Se produkt →") nederst i
   hvert kort — mockuppens .vare (WebFetch af artifact e339b87a) har
   INGEN knap, kun butik/navn/pris, fordi hele kortet allerede er
   klikbart (invariant 15, initCardClickthrough). Med "Alle produkter"
   samtidig blevet en mørk knap (tidligere commit i dag) stod den orange
   kortknap og skurrede mod den — to forskellige farver for "gå videre",
   side om side på samme side.

   Klassen er BEHOLDT, ikke fjernet: initCardClickthrough() (favorites.js)
   finder stadig URL'en via .product-cta ved at læse dens href — fjernes
   elementet helt, mister hele kortet sin klikbarhed OG tastaturbrugere
   mister deres eneste fokuserbare vej ind på produktet (hjerteknappen
   navigerer ikke). Løsningen er derfor at PAKKE titlen ind i linket i
   stedet for at have en selvstændig knaprække under prisen — samme
   mønster som titel-som-link i enhver almindelig webshop. Ingen synlig
   tekst tilføjes; det er visuelt usynligt, kun title'en arver linkets
   klikbarhed. */
.product-cta {
  display: block;
  color: inherit;
  text-decoration: none
}

/* .deal-body/.deal-retailer/.deal-title/.deal-rating/.stars/
   .deal-price-row/.deal-old/.deal-price/.deal-save/.deal-cta(-tekst/-pil/
   -butik) er fjernet 6/8. Kortet bygger nu på .product-body/.product-
   retailer/.product-title/.product-rating/.product-stars/.product-price-
   row/.product-old/.product-price/.product-save/.product-cta — samme
   klasser som /tilbud, se dealCardHtml() i script.js. Alle var reelt
   næsten-identiske kopier af deres product-*-modstykker (samme farver,
   samme mål, i visse tilfælde bogstaveligt samme værdier), og en af dem
   var netop derfor kilden til en klippet CTA-knap et par commits tidligere
   — to steder at rette samme problem. Efterprøvet før sletning: ingen af
   klasserne bruges nogen andre steder i projektet (kun i denne fil og i
   script.js, som begge er rettet i samme commit). */

.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 et flex-column-kort (fx .bento-card) 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: 0;
  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
}

/* ── Mærkater på produktbilledet ────────────────────────────────────────────
   Bor HER og ikke i cykler.css, af samme grund som .product-card m.fl.
   (invariant 11): cykler.js, favoritter.js OG produkt.js renderer dem alle
   tre, men kun cykler.php og favoritter.php loader cykler.css.

   ⚠ .udsolgt-badge blev flyttet hertil, men BEHOLDEREN blev efterladt i
   cykler.css. Resultatet var værre end at have ladet begge blive: på
   produktsidens "Relaterede produkter" mistede .product-badge-wrap sin
   `position: absolute`, faldt tilbage til at være et almindeligt
   blokelement inde i .product-img, og skubbede "Kun N tilbage" halvt uden
   for kortet, hvor det blev klippet af. Opdaget 2/8 på et skærmbillede.

   Læren er invariant 11's egentlige indhold: det er ikke nok at flytte den
   regel man kigger på — hele den gruppe, der hører sammen visuelt, skal
   flyttes samlet. En positioneret forælder uden sit barn, eller omvendt,
   fejler først dér hvor kun den ene fil er indlæst. */
.product-badge-wrap {
  position: absolute;
  top: 12px;
  left: 12px;
  display: flex;
  gap: 6px;
  flex-direction: column;
  align-items: flex-start
}

.product-badge-wrap .urgency-badge {
  font-size: 11px;
  padding: 3px 9px
}

/* Favorit-hjertet — delt af korthjerterne på /tilbud, /favoritter OG
   produktsidens galleri (.pdetail-fav). FLYTTET hertil fra favoritter.css
   22/8: produktsiden loader kun produkt.css, aldrig favoritter.css, så
   hjertet var reelt ustylet dér — et 24×24px SVG-ikon uden knap-krop,
   ingen cirkel, ingen kontrast (implementeringsguide, produktsiden, §2).
   Samme invariant 11-mønster som .product-photo/.product-badge-wrap
   ovenfor: en klasse brugt på tværs af sider skal bo hvor ALLE de sider
   der bruger den rent faktisk loader den. */
.fav-heart {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  /* Cirklen SKAL følge temaet.
     Stod som rgba(14, 17, 16, .72) — hardkodet mørk, altså det mørke
     temas --bg. Forgrunden var derimod var(--muted), som følger temaet.
     I lyst tema gav det mørkegråt hjerte på en mørk cirkel, og knappen
     var reelt usynlig indtil man holdt musen over den (hvor :hover
     farver den rød). Rapporteret fra testmiljøet 27/7.

     Knappen ligger oven på .product-photo, som er var(--foto-flade) —
     hvid i BEGGE temaer. Cirklen er derfor halvgennemsigtig oven på
     hvidt: mørk i mørkt tema, næsten hvid i lyst. Ikonet vender med
     den. */
  /* Kanten og skyggen er det der gør cirklen til en KNAP.
     Uden dem er den næsten usynlig i lyst tema: cirklen bliver
     rgb(249,247,241) oven på en fotoflade der er rgb(246,243,236) —
     målt, altså ingen kontrast overhovedet. Ikonet ville stå tydeligt,
     men selve klikmålet ville ikke tegne sig.
     En rgba(--bg-rgb)-kant duer ikke: den er lys på lys i lyst tema.
     var(--border) er derimod defineret pr. tema til netop dette. */
  border: 1px solid var(--border);
  background: rgba(var(--bg-rgb), .72);
  box-shadow: var(--skygge-s);
  backdrop-filter: blur(6px);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  /* var(--text), ikke var(--muted): et favorithjerte skal invitere til
     et klik. --muted var så afdæmpet at knappen forsvandt i billedet
     selv i det mørke tema, hvor kontrasten teknisk var i orden. */
  color: var(--text);
  transition: color .18s, background .18s, transform .18s;
  z-index: 2;
}

.fav-heart svg {
  width: 16px;
  height: 16px;
}

.fav-heart:hover {
  color: var(--favorit);
  background: rgba(var(--favorit-rgb), .15);
  transform: scale(1.1);
}

.fav-heart-active {
  color: var(--favorit) !important;
  background: rgba(var(--favorit-rgb), .18) !important;
}

.fav-heart-active svg path {
  fill: var(--favorit);
  stroke: var(--favorit);
}

.discount-badge {
  display: inline-flex;
  align-items: center;
  font-size: 11.5px;
  font-weight: 700;
  background: var(--deal);
  color: var(--paa-farve);
  padding: 3px 10px;
  border-radius: 0
}

/* Kønsmærkat (koenBadgeHtml() i favorites.js) — bevidst neutral, IKKE
   samme farve som urgency/discount. De to skal haste et klik; dette er
   bare en oplysning, og skal ikke konkurrere om opmærksomheden. */
.koen-badge {
  display: inline-flex;
  align-items: center;
  font-size: 11px;
  font-weight: 600;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  padding: 3px 9px;
  border-radius: 0
}

/* 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: 0;
  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-micro og dens fire varianter (.hero, .deal-card, .bento-card) er
   fjernet 6/8 sammen med markupen i dealCardHtml() — se begrundelsen dér.
   Efterprøvet før sletningen: ingen .php-, .html- eller .js-fil renderer
   klassen længere. ⚠ Forveksl den ikke med .trust-item/.hero-kat-trust,
   som er tallene i forsidens hero ("6 partnerbutikker", "8 cykeltyper") —
   de er i brug i index.php og er urørte. */

/* 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: none;
  border-radius: var(--radius);
  box-shadow: var(--skygge-s), var(--skygge-m);
}

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

/* ===== /guides, genbygget 22/8 efter mockup: <h1>, kategori-piller,
   flush-left liste med tynde dividers. Ingen fremhævet kort, ingen
   statistik — se guideListeItemHtml()/renderGuideKrom() (script.js). ===== */

.guides-mobil {
  padding: 46px 0 66px;
}

.guides-mobil-head,
.guides-pillrow,
.guides-liste {
  width: min(100% - 44px, 760px);
  margin-left: auto;
  margin-right: auto;
}

.guides-mobil-head {
  margin-top: 28px;
  margin-bottom: 10px;
}

.guides-mobil-head h1 {
  font-family: var(--font-display);
  font-size: 30px;
  font-weight: 700;
  margin: 0;
}

/* Vandret rulle i stedet for flex-wrap — samme mønster som .tilbud-chips
   (cykler.css). Pillerne brød tidligere til en ny linje, når de ikke kunne
   være på én række; efter ønske (22/8) skal de blive på ÉN linje og
   scrolle i stedet. */
.guides-pillrow {
  display: flex;
  flex-wrap: nowrap;
  gap: 8px;
  margin-bottom: 24px;
  overflow-x: auto;
  scrollbar-width: none;
}

.guides-pillrow::-webkit-scrollbar {
  display: none;
}

/* Samme pille-stil som er etableret på /tilbud (.tilbud-chips .chip) og
   /favoritter ("Rediger") denne omgang — bevidst kant i stedet for
   .guide-pil's flade tonale fyldfarve, så alle tre app-faners pille-/
   knap-sprog stemmer overens. */
.guides-pil {
  display: inline-flex;
  flex: none;
  align-items: center;
  min-height: 32px;
  padding: 5px 16px;
  background: var(--bg);
  border: 1.5px solid var(--text);
  border-radius: 10px;
  color: var(--text);
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
}

/* ⚠ Var var(--primary) (rød) — rav/rust (var(--rust)), samme rettelse som
   resten af mobilredesignet. */
.guides-pil.aktiv {
  background: var(--rust);
  border-color: var(--rust);
  color: var(--paa-farve);
}

.guides-liste {
  display: flex;
  flex-direction: column;
}

.guides-item {
  display: grid;
  grid-template-columns: 76px 1fr;
  align-items: center;
  gap: 13px;
  padding: 16px 0;
  border-bottom: 1px solid var(--border-soft);
  text-decoration: none;
  color: inherit;
}

.guides-liste .guides-item:first-child {
  padding-top: 0;
}

.guides-liste .guides-item:last-child {
  border-bottom: none;
}

.guides-item-foto {
  flex: none;
  width: 76px;
  height: 62px;
  border-radius: 8px;
  overflow: hidden;
  background: var(--surface-alt);
}

.guides-item-foto img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.guides-item-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

/* ⚠ Var var(--primary) (rød) — rav/rust (var(--rust)), samme rettelse som
   resten af mobilredesignet. */
.guides-item-kicker {
  font-size: 11.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .03em;
  color: var(--rust);
}

.guides-item-body h2 {
  font-size: 14px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--text);
  margin: 0;
}

.guides-item-laesetid {
  font-size: 12.5px;
  color: var(--faint);
}

/* ⚠ RETTET 20/8, VENDT OM 20/8: samme kant→skygge-vending som
   .product-card ovenfor — den nye godkendte mockup-runde (variant 1a,
   "ændringer til design/") vil have runde hjørner og en blød skygge,
   ikke en kant med 3px hjørne. Størst effekt her, hvor kortet er
   fremhævet (#guideFeatured .guide-fremhaevet arver klassen uden egen
   radius). */
.guide-card {
  background: var(--surface);
  border: none;
  border-radius: var(--radius);
  box-shadow: var(--skygge-s), var(--skygge-m);
  overflow: hidden;
  transition: .2s;
  cursor: pointer
}

.guide-card:hover {
  box-shadow: var(--skygge-m), var(--skygge-l);
  transform: translateY(-2px)
}

.guide-img {
  height: 180px;
  /* Gradienten ligger som baggrund. Fejler billedet, fjerner onerror det, og
     farven står tilbage — derfor overflow:hidden frem for at give img'et sin
     egen baggrund. */
  overflow: hidden;
  position: relative;
}

.guide-img img {
  width: 100%;
  height: 100%;
  /* contain, ikke cover: produktfotos er hvide studiebilleder, og et cover
     ville beskære cyklen i begge ender. Padding'en holder den fri af kanten. */
  object-fit: contain;
  padding: 14px;
  display: block;

  /* SAMME flade som produktkortenes fotos (.product-photo). --foto-flade er
     hvid i BEGGE temaer med vilje, fordi billederne selv har hvid baggrund
     — se begrundelsen ved variablen.

     ⚠ Her stod først mix-blend-mode: multiply i lyst tema, så det hvide
     smeltede sammen med gradienten. Det så rigtigt ud på ét kort i mørkt
     tema og blev en stor orange flade i lyst. Fladen skal ikke skifte med
     temaet — det er hele grunden til at variablen ikke arves om. */
  background: var(--foto-flade);
}

.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: 0;
  margin-bottom: 12px;
  letter-spacing: .02em
}

/* ⚠ RETTET 20/8: 21px var større end mockuppens 18px (variant 1a,
   Guides - Finish.dc.html) — titlen dominerede kortet mere end
   billedet/beskrivelsen, hvor mockuppen holder teksten roligere og
   billedet som det første man lægger mærke til. */
.guide-card h3 {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 600;
  line-height: 1.3;
  margin-bottom: 10px;
  letter-spacing: -.01em
}

/* ⚠ RETTET 20/8: .guide-card ligger inde i <section class="about-section">
   (guides.php), og .about-section p (styles.css, "Indholdssider") sætter
   1.15rem (~18,4px) med SAMME specificitet (klasse+element) — kun senere i
   filen, så den vandt over denne regel uanset hvad den stod til. Fundet
   ved at måle: kilden sagde 14,5px, browseren viste 18,4px. Scopet til
   .about-section herunder giver highere specificitet (klasse+klasse+
   element), så guide-kortets egen, mindre tekst rent faktisk vinder. */
.about-section .guide-card p {
  font-size: 14px;
  color: var(--muted);
  margin-bottom: 16px;
  /* Klippet til 2 linjer 12/8 — 28 guider på siden betød en del scroll for
     at overskue listen, og beskrivelsen var den største enkeltbid af hvert
     korts højde efter billedet. Kortet er en teaser, ikke artiklen selv,
     så 2 linjer er nok til at afgøre om man vil klikke videre. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden
}

.read-more {
  font-weight: 600;
  color: var(--primary);
  font-size: 13.5px
}

.read-more:hover {
  text-decoration: underline
}

/* ── /guides: statistik, piller og fremhævet kort ──
   Kom til 8/8, efter at siden gik fra 0 til 16 rigtige guider (7 første
   runde, 9 om el-løbehjul/kabinescooter/låse/tasker/dæk/vedligehold — se
   git-loggen). Før var siden bare et fladt gitter; med 16 artikler i to
   reelle kategorier (Guides/Tips) giver et overblik mening, ligesom
   forsidens hero-kat-trust gjorde det for de tomme partnertal. Alt herunder
   udfyldes af script.js (renderGuideKrom/renderGuideListe) — ingen af
   tallene eller pillerne står nogensinde statisk i markuppen. */
/* ⚠ RETTET 20/8, VENDT OM 20/8: var en bordered box (kant hele vejen
   rundt, radius 3px, egen --surface-baggrund). Mockuppen har ingen boks
   her — kun en øverste skillelinje mod hero-teksten ovenover, samme
   tonale mønster som resten af sitets sektionsadskillelser. */
/* ⚠ RETTET 20/8, IGEN: var(flex:1 + stretch + width:100%) var bygget til
   den GAMLE bordered box (12/8) — dengang skulle to celler fylde en kasses
   fulde bredde jævnt for ikke at se efterladt ud. Boksen er væk (se noten
   herover), men de gamle mål stod tilbage: fuld bredde, centreret tekst og
   en kant MELLEM cellerne — resultatet var to adskilte, spredte klumper i
   stedet for mockuppens (variant 1a) ÉN kompakt, venstrestillet gruppe af
   tal-over-label-blokke uden nogen linje imellem. Målt direkte mod
   mockup-filen: ingen border-left, intet stretch, generøst gap (32-40px)
   i stedet. */
/* ⚠ RETTET 20/8: flex-wrap tilføjet, fordi hver kategori nu er sin egen
   .guide-stat (se renderGuideKrom(), script.js) i stedet for én samlet
   "fordelings"-celle — med fire-fem blokke plus datoen ville en fast
   ét-linjes række løbe ud over en smal skærm uden den. */
.guide-stats {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: flex-start;
  gap: 24px 40px;
  border: none;
  border-top: 1px solid var(--border-soft);
  border-radius: 0;
  background: transparent;
  padding-top: 20px;
  margin-bottom: 24px;
  width: 100%
}

.guide-stat {
  display: flex;
  flex: 0 0 auto;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  text-align: left
}

.guide-stat strong {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 600;
  line-height: 1
}

.guide-stat span {
  font-size: 12px;
  color: var(--faint)
}

/* Pillerne ligner filterknapperne på /tilbud (samme runde form, samme
   aktiv-farve), men er deres eget, mindre sæt — /tilbud's filterknapper
   sidder i en sidebar med andre mål og en helt anden DOM-struktur, så en
   delt klasse ville låse de to steder unødigt sammen. */
.guide-pillrow {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 28px
}

/* ⚠ RETTET 20/8: var en bordered pille (kant + --surface-baggrund).
   Mockuppens piller (variant 1a, Guides - Finish.dc.html) har ingen kant
   — bare en flad tonal fyldfarve (#EDE7DA = var(--surface-alt) her).
   Kanten gjorde rækken visuelt tungere end mockuppens rolige rad af
   bløde chips. */
.guide-pil {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  border: none;
  border-radius: 0;
  background: var(--surface-alt);
  color: var(--muted);
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  transition: .15s
}

.guide-pil:hover {
  color: var(--primary);
  background: var(--border-soft)
}

/* ⚠ RETTET 20/8: aktiv-tilstanden var rav (var(--primary)). Mockup-runde
   variant 1a's "Alle"-pille er FELTETS navy (#243745 i mockuppen =
   var(--felt) her), ikke rav — målt direkte i mockup-filen
   (Guides - Finish.dc.html). */
.guide-pil.aktiv {
  background: var(--felt);
  border-color: var(--felt);
  color: var(--paa-felt)
}

.guide-pil-antal {
  font-size: 11.5px;
  opacity: .75
}

/* Det fremhævede kort er ALTID den nyeste guide (se begrundelsen ved
   fremhaevetGuideHtml() i script.js) — vandret layout i stedet for
   gittercellen, så det ikke kan forveksles med et kort i gitteret
   nedenunder. */
#guideFeatured .guide-fremhaevet {
  display: flex;
  margin-bottom: 32px;
  cursor: pointer
}

#guideFeatured .guide-fremhaevet .guide-img {
  flex: 0 0 42%;
  height: auto;
  min-height: 260px
}

#guideFeatured .guide-fremhaevet .guide-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 32px 36px
}

.guide-fremhaevet-maerker {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-bottom: 14px
}

.guide-nyeste-maerke {
  display: inline-block;
  font-size: 11.5px;
  font-weight: 700;
  color: var(--paa-farve);
  background: var(--primary);
  padding: 4px 11px;
  border-radius: 0;
  letter-spacing: .02em
}

/* Overskriver .guide-tag's egen margin-bottom: den sidder nu ved siden af
   nyeste-mærket i stedet for over titlen. */
.guide-fremhaevet-maerker .guide-tag {
  margin-bottom: 0
}

#guideFeatured .guide-fremhaevet h2 {
  font-family: var(--font-display);
  font-size: 28px;
  font-weight: 600;
  line-height: 1.2;
  margin-bottom: 12px;
  letter-spacing: -.01em
}

#guideFeatured .guide-fremhaevet p {
  font-size: 15.5px;
  color: var(--muted);
  margin-bottom: 20px;
  max-width: 52ch
}

/* ⚠ RETTET 20/8: knappen var BÅDE .btn-primary (massiv rav-bund, fuld
   pilleform) og .read-more — samme tunge CTA-stil som lige er fjernet fra
   produktkortene ("Se produkt", se CLAUDE.md) og som ikke findes i det
   godkendte design. Fjernet fra fremhaevetGuideHtml() i script.js, så det
   fremhævede kort nu bruger samme diskrete tekstlink som de øvrige
   guide-kort (.guide-card .read-more nedenfor) — der er ingen mørk/farvet
   bund bag linket her (.guide-body er lys), så ingen farveoverstyring er
   nødvendig længere. */
#guideFeatured .guide-fremhaevet .read-more {
  font-size: 15.5px
}

@media (max-width: 780px) {
  #guideFeatured .guide-fremhaevet {
    flex-direction: column;
    margin-bottom: 20px
  }

  /* Var height:auto + min-height:200px, arvet fra desktop-reglen ovenfor.
     I rækkelayoutet (desktop) stretcher flexbox billedet til kroppens højde,
     så "auto" var uskadeligt der. I søjlelayoutet her stretcher intet
     højden, så en img med width:100%/height:100% kunne ikke regne 100% ud
     af en "auto"-forælder og faldt tilbage til sit eget billedformat —
     et højformat-foto (fx et lodret løbehjul) fyldte 317px, næsten 40% af
     en 812px mobilskærm, FØR overskrift eller tekst overhovedet var synlig.
     En fast højde (som gitterkortenes egen .guide-img: 180px) gør kortet
     forudsigeligt kompakt uanset billedets format. */
  #guideFeatured .guide-fremhaevet .guide-img {
    flex-basis: auto;
    height: 160px;
    min-height: 0
  }

  #guideFeatured .guide-fremhaevet .guide-body {
    padding: 18px
  }

  #guideFeatured .guide-fremhaevet h2 {
    font-size: 21px;
    margin-bottom: 8px
  }

  /* Klippes til 2 linjer på mobil — samme tekst renderer op til 4-5 linjer
     i den brede skrifttype her, og fylder mere end overskriften selv. */
  #guideFeatured .guide-fremhaevet p {
    font-size: 14px;
    margin-bottom: 14px;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden
  }

  #guideFeatured .guide-fremhaevet .read-more {
    font-size: 13.5px
  }
}

/* Newsletter */
/* Var 72px. Sektionens eget indhold (overskrift + én sætning + to knapper)
   er kun 119px højt, men stod med 72px luft foroven OG forneden — og fordi
   #om lige efter har SIN egen 88px (før 6/8's rettelse dér), lagde de to
   sig oven i hinanden til 160px ren luft mellem "Min favoritliste" og
   "01 — VI HENTER". 48px er stadig tydelig sektionsadskillelse, bare uden
   at den dominerer over indholdet den omslutter. */
.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: 48px 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: 0;
  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(--dark);
  color: var(--light-ink-dim);
  padding: 44px clamp(28px, 4.5vw, 72px) 28px;
}

.footer-grid {
  display: grid;
  grid-template-columns: 1.3fr 0.7fr 0.7fr;
  gap: 40px;
  padding-bottom: 40px;
}

.footer-col a,
.footer-col h2 {
  overflow-wrap: break-word;
}

.footer-brand .logo {
  color: var(--rust);
  margin-bottom: 0;
}

.logo-light .logo-text {
  color: var(--light-ink);
}

.logo-light .logo-text strong {
  color: var(--rust);
}

.footer-brand p {
  font-size: 13px;
  color: var(--light-ink-dim);
  max-width: 245px;
  margin-top: 14px;
  line-height: 1.6;
}

.footer-col h2 {
  font-family: var(--font-body);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .1em;
  color: var(--light-ink);
  margin-bottom: 15px;
  font-weight: 800;
}

.footer-col a {
  display: block;
  font-size: 13px;
  color: var(--light-ink-dim);
  margin-top: 9px;
  transition: color .2s ease;
}

.footer-col a:hover {
  color: var(--rust);
}

.footer-bottom {
  border-top: 1px solid var(--line-light);
  padding-top: 22px;
  display: flex;
  gap: 20px;
  font-size: 11px;
}

.footer-bottom .container {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.footer-bottom p {
  font-size: 13px;
  color: var(--paa-felt-dim)
}

.footer-disclosure {
  font-size: 12.5px;
  color: var(--paa-felt-dim);
  opacity: .85
}

/* ⚠ HER LÅ FIRE UBRUGTE FARVETEMAER — 'frost', 'skov', 'rust' og
   'skifer' — på ~80 linjer. De blev sat af setupThemeSwitcher() i
   script.js, som leder efter `.swatch`-knapper. De knapper fandtes
   ikke i NOGEN markup, så temaerne kunne aldrig vælges. Fjernet 19/8
   sammen med funktionen.
   Sitet har siden 19/8 slet ikke noget temavalg — hverken det døde
   `data-theme` eller det tidligere rigtige `data-tema`. Ét udtryk,
   én palet. */
/* 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: 0;
  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: 0;
  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)
  }

  /* Var 240px — en tabletspecifik indskrænkning FRA basens dengang 260px.
     Basen er nu selv 220px (se .deal-kategori-scroll .deal-card, 6/8), som
     allerede er mindre end de gamle 240 — en override der satte kortet
     STØRRE end basen ville have inverteret skalaen (smallere skærm =
     bredere kort, baglæns). Reglen er derfor fjernet; kortet arver 220px
     herfra og opefter uændret.

     Den tabletspecifikke skjulning af butiksnavnet i knappen ("Se pris hos
     C…" klippet af på et smalt kort) er væk sammen med selve knappe-teksten
     der krævede den: kortet bruger nu /tilbud's egen, korte CTA-tekst
     ("Se produkt →" / "Se butikker →"), som er kort nok til aldrig at
     klippe — se dealCardHtml() i script.js, 6/8. */

  .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: minmax(0, 1fr) minmax(0, 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
  }

  /* ⚠ RETTET 20/8: .main-nav's egen margin-left:auto (linje 422) er det
     ENESTE der skubber headerens højre gruppe ud til kanten — men
     display:none her fjerner nav'en helt fra flex-rækken, og dens
     auto-margin forsvinder med den. Uden erstatning landede
     hamburgerknappen lige efter logoet i stedet for ude ved kanten,
     samme fejlklasse som desktop-navigationen havde (se kommentaren ved
     .header-actions ovenfor) — bare udløst af at nav'en er skjult i
     stedet for af to konkurrerende auto-margins. */
  .header-actions {
    margin-left: auto
  }

  .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;
    /* ⚠ Var var(--surface). Menuen folder ud UNDER headeren og er altså
       en del af FELTET, ikke af læsefladen. Med den lyse --surface stod
       linkene — som arver --paa-felt-dim — elfenben på creme og var
       reelt usynlige. Fejlen ramte KUN mobil, hvor menuen findes. */
    background: var(--felt);
    border-bottom: 1px solid var(--felt-linje);
    padding: 14px 28px;
    gap: 0
  }

  .main-nav.open a {
    padding: 13px 0;
    border-bottom: 1px solid var(--felt-linje)
  }

  .main-nav.open a:last-child {
    border-bottom: none
  }

  /* ⚠ RETTET 20/8: .fav-badge er position:absolute; top:-6px; right:-14px
     (favoritter.css) — rigtigt når .fav-nav-link er et kompakt inline-link
     i den vandrette desktop-nav, hvor "-14px fra højre" lander lige ved
     siden af selve teksten. I den udfoldede mobilmenu strækker linket sig
     derimod ud til FULD BREDDE (samme regel som alle de andre nav-linjer),
     så "-14px fra højre" blev til helt ude ved menuens egen kant — badget
     endte svævende oppe ved skillelinjen over "Favoritter" i stedet for
     ved selve ordet. Her nulstilles den til at stå i normal tekstflow,
     lige efter "Favoritter". */
  .main-nav.open .fav-badge {
    position: static;
    margin-left: 8px;
    vertical-align: middle
  }
}

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

  .brand {
    gap: 8px
  }

  .brand-badge {
    width: 28px;
    height: 33px
  }

  .brand-badge svg {
    width: 16px;
    height: 16px
  }

  .brand-name {
    font-size: 16px
  }

  .header-actions {
    flex: 1;
    gap: 10px
  }

  .header-actions .btn {
    display: none
  }

  .search {
    flex: 1;
    min-width: 0
  }

  .search input {
    width: 100%;
    /* Feltet er typisk kun ~80px bredt her (logo+temaknap+hamburgermenu
       fylder resten), og den normale højre-padding (40px, reserveret til
       søgeknappen) levnede kun ca. 24px til selve teksten — pladsholderen
       "Søg cykler…" blev klippet ned til bogstaveligt "S" og intet andet,
       hvilket så ud som en fejl, ikke et søgefelt. Fundet 8/8. Mindre
       knap + mindre pladsholder-skrift giver plads nok til det korte
       "Søg" (sat i header.php). */
    padding-right: 30px
  }

  .search-btn {
    width: 26px;
    height: 26px;
    right: 2px
  }

  .search-btn svg {
    width: 14px;
    height: 14px
  }

  .search input::placeholder {
    font-size: 12px
  }

  .cat-grid,
  .steps,
  .guide-grid {
    grid-template-columns: 1fr
  }

  /* 180px (basens højde, til et 3-spaltet gitter) er unødigt højt når
     kortet alligevel fylder hele skærmbredden på mobil — 28 guider stablet
     i én kolonne blev en lang scroll. object-fit: contain på billedet
     tåler at blive lavere uden at se beskåret ud. */
  .guide-img {
    height: 130px
  }

  /* Footerens linkspalter (Kategorier/CykelTjek) stod tidligere fuld
     bredde, én under den anden — stablet lodret fyldte skærmen langt ned
     uden at have brug for det, hver enkelt liste er kort.
     .footer-brand spænder over begge kolonner og ryger dermed på sin
     egen række (logo + brødtekst skal have fuld bredde), mens de to
     .footer-col-elementer automatisk lægger sig side om side i rækken
     under — ingen ekstra klasser nødvendig, kun grid auto-placement.
     ⚠ RETTET 22/8: var 3 spor fra dengang der var tre .footer-col
     ("Butikker" fjernet); 2 spor efterlader ikke længere et tomt sidste
     spor. */
  .footer-grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 28px 14px
  }

  .footer-brand {
    grid-column: 1 / -1
  }

  .footer-col h2 {
    margin-bottom: 10px
  }

  .footer-col a {
    padding: 4px 0
  }

  /* ── Kortbredden på mobil ────────────────────────────────────────────
     78 % gav et kort på 249 px i en 319 px bred række — altså 1,19 kort
     ad gangen (målt 6/8). Det er lige akkurat nok til at SKJULE at rækken
     kan scrolles: man ser ét kort og en stribe, der lige så godt kunne
     være kanten af sektionen.
     44 % giver 140 px, to hele kort og et glimt af det tredje — og fordi
     billedet nu følger kortets bredde (aspect-ratio nedenfor), falder
     kortets HØJDE med. Bredden er altså også en lodret gevinst.
     ⚠ 46 % blev prøvet først og gav 2,01 kort: det tredje kort begyndte
     præcis ved rækkens kant, så glimtet var ét enkelt billedpunkt. Et
     "næsten to komma nul" er værre end to, for så ser rækken afsluttet ud.
     Til sammenligning: klodstjek.dk bruger 150 px på samme skærmbredde. */
  .deal-kategori-scroll .deal-card {
    flex-basis: 44%
  }

  .deal-kategori-scroll {
    gap: 12px
  }

  /* Kortet bruger nu .product-* (se dealCardHtml() i script.js, 6/8), som
     ikke i sig selv er scopet til denne smalle rækkes bredde — /tilbud har
     sin EGEN kompakte variant af de samme klasser, men scopet til
     .product-grid, som deal-kortene ikke er en del af. Uden reglerne her
     ville forsidens 140 px-kort arve /tilbud's fulde, brede mål.
     Tallene er MÅLT for netop 140 px, ikke overtaget fra cykler.css —
     de to sæt ligner hinanden, fordi begge kort er optimeret til omtrent
     samme bredde, ikke fordi det ene styrer det andet.
     På et 140 px-kort æder 18 px polstring (product-body's normale mål)
     en syvendedel af bredden — samme regnestykke som .product-body fik
     strammet på /tilbud. */
  .deal-kategori-scroll .product-body {
    padding: 12px;
    gap: 5px
  }

  .deal-kategori-scroll .product-retailer {
    font-size: 11px
  }

  .deal-kategori-scroll .product-title {
    font-size: 14px
  }

  .deal-kategori-scroll .product-price {
    font-size: 19px
  }

  .deal-kategori-scroll .product-price-row {
    padding-top: 8px;
    gap: 6px 8px
  }

  /* ⚠ FJERNET 22/8: ".deal-kategori-scroll .product-cta { margin-top:10px;
     padding:9px 6px; font-size:12px }" stod her. Git-historik viser den
     hed ".deal-cta" indtil en omdøbning — dengang en SELVSTÆNDIG
     CTA-knap nederst i kortet. Omdøbningen ramte ved et uheld
     ".product-cta", som i dag er linket der wrapper TITLEN øverst i
     kortet (samme klasse som resten af sitet bruger til det formål,
     invariant 15/21) — padding+margin-top polstrede altså titlen ud og
     gjorde forsidens deal-kort markant højere end de identiske kort på
     /tilbud, som aldrig havde denne regel. .product-title's egen
     font-size:14px (nedenfor) vandt allerede over de 12px her, så kun
     bloatet forsvinder — intet synligt mistes. */
  .deal-kategori {
    margin-bottom: 30px
  }

  .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: 18px;
  /* ⚠ RETTET 22/8, VENDT OM 22/8: var 0 (se den tidligere begrundelse
     nedenfor om det mørke temas rester) — efter fornyet ønske er runde
     kanter tilbage, denne gang som en bevidst afvigelse (samme princip
     som chips/søgebaren), ikke en glemt rest. */
  border-radius: 14px;
  box-shadow: var(--skygge-l);
  z-index: 9999;
  display: flex;
  flex-direction: column;
  gap: 10px;
  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 p {
  margin: 0;
  font-size: 0.95rem;
  color: var(--faint);
  line-height: 1.6;
}

/* Første sætning bærer det overskriften bar før. --text mod --faint på
   resten giver den samme rangorden som en h4 gjorde, uden dens 38 px. */
.cookie-content strong {
  color: var(--text);
}

/* "Læs mere" havde NØJAGTIG samme farve som brødteksten (begge
   rgb(138,134,127), målt 6/8) og ingen understregning — et link ingen
   kunne se var et link. Det var uheldigt før og er værre nu: beskeden
   henviser bevidst detaljerne til /privatliv, så linket er hele udgangen
   fra en kasse der kun kan rumme et resumé. Samme udseende som
   .disclosure-bar a, der har haft det rigtigt hele tiden. */
.cookie-content a {
  color: var(--primary);
  text-decoration: underline;
}

.cookie-actions {
  display: flex;
  gap: 12px;
  justify-content: flex-end;
}

.cookie-actions .btn {
  padding: 8px 16px;
  font-size: 14px;
  /* Runde kanter, efter ønske — samme afvigelse som selve banneret. */
  border-radius: 10px;
}

@media (max-width: 480px) {
  .cookie-banner {
    bottom: 0;
    left: 0;
    right: 0;
    max-width: none;
    /* Kun toppen rundes — banneret rører stadig skærmens bund/sider på
       mobil, så en fuld radius ville vise firkantede hjørner nederst
       alligevel. */
    border-radius: 14px 14px 0 0;
    border-bottom: none;
    /* Målt 6/8 på 375x812: kassen fyldte 301 px — 37 % af skærmen — og
       dækkede præcis den kortrække, mobiloptimeringen af /tilbud lige
       havde gravet frem. 131 af de 301 px var RAMME: overskrift 38,
       polstring 40, mellemrum 16, knaprække 37.
       Teksten er ikke blevet kortere. Den er blevet længere og rigtigere
       (den påstod at sitet ikke førte statistik, og det gjorde det),
       så højden skal komme fra rammen.
       ⚠ RETTET 22/8: strammet yderligere efter ønske — 16px/12px blev
       12px/8px, samme grund: teksten kan ikke blive kortere, kun rammen. */
    padding: 12px;
    gap: 8px;
  }

  .cookie-banner .cookie-actions .btn {
    padding: 7px 18px;
  }
}

/* ════════════════════════════════════════════════════════════════════
   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 — feltet fortsætter fra headeren ══
   INGEN top-padding og INGEN top-kant: headeren og hero'en skal læse som
   ét ubrudt felt, og en overgang mellem dem ville afsløre at det er to
   elementer. Begge bruger --felt, så der er intet at få øje på.

   Vignetteringen i siderne er det eneste der giver fladen form: en
   lakeret flade er krum, ikke flad. Et rudenet blev afprøvet og
   forkastet — det læste som synlige småfirkanter frem for tekstur, og
   maskens kant tegnede et lyst hjørne. */
.hero-kat {
  position: relative;
  min-height: 420px;
  padding: clamp(50px, 6vw, 80px) clamp(28px, 7vw, 104px);
  background: radial-gradient(130% 100% at 18% -15%, var(--dark-deep) 0%, var(--dark) 48%, var(--dark-deep) 100%);
  color: var(--light-ink);
  overflow: hidden;
  border-bottom: 0;
}

.hero-kat::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    linear-gradient(rgba(243, 238, 228, .04) 1px, transparent 1px),
    linear-gradient(90deg, rgba(243, 238, 228, .04) 1px, transparent 1px);
  background-size: 38px 38px;
  mask-image: radial-gradient(72% 68% at 60% 38%, #000 0%, rgba(0, 0, 0, .62) 40%, rgba(0, 0, 0, .2) 66%, transparent 88%);
  -webkit-mask-image: radial-gradient(72% 68% at 60% 38%, #000 0%, rgba(0, 0, 0, .62) 40%, rgba(0, 0, 0, .2) 66%, transparent 88%);
}

.hero-kat::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background: linear-gradient(90deg, rgba(0, 0, 0, .18) 0%, transparent 14%, transparent 86%, rgba(0, 0, 0, .18) 100%);
}

.hero-kat>* {
  position: relative;
  z-index: 1;
}

.hero-kat-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  max-width: 1376px;
  margin: 0 auto;
  position: relative;
}

.hero-kat-text {
  max-width: 560px;
}

.hero-meta {
  margin-bottom: 24px;
}

.hero-eyebrow {
  color: var(--rust);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.hero-trust {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: 36px;
}

.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.1);
  color: var(--paper);
  padding: 8px 16px;
  border-radius: 40px;
  font-family: var(--font-body);
  font-size: 12.5px;
  font-weight: 600;
}

.status-opdateret {
  color: var(--paper);
  font-family: var(--font-body);
  font-size: 12.5px;
  font-weight: 700;
}

.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #22c55e;
}

.hero-kat h1 {
  font-family: var(--font-display);
  font-size: clamp(46px, 6vw, 78px);
  line-height: .95;
  letter-spacing: -.03em;
  font-weight: 800;
  margin-bottom: 24px;
  color: var(--paper);
  max-width: 540px;
}

.hero-kat h1 .accent {
  color: var(--rust);
}

.hero-kat .lead {
  font-size: 16px;
  max-width: 510px;
  color: var(--light-ink-dim);
  line-height: 1.6;
}

/* ══════════════════════════════════════════════════════════════════════
   TEKNISK TEGNING — hero'ens blikfang
   ══════════════════════════════════════════════════════════════════════ */
.tegning {
  position: absolute;
  width: min(55%, 720px);
  right: -5%;
  bottom: 14px;
}

.tegning svg {
  width: 100%;
  height: auto;
  overflow: visible
}

.tg-hjul,
.tg-ramme,
.tg-drev,
.tg-detalje {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round
}

.tg-hjul {
  stroke: rgba(255, 255, 255, 0.15);
  stroke-width: 2.2
}

.tg-eger {
  stroke: rgba(255, 255, 255, 0.05);
  stroke-width: 1;
  fill: none
}

.tg-ramme {
  stroke: #fff;
  stroke-width: 3.4;
  opacity: 0.9;
}

.tg-drev {
  stroke: var(--rust);
  stroke-width: 2.4
}

.tg-detalje {
  stroke: var(--rust);
  stroke-width: 2.2
}

/* Måltegn — en konstruktionstegning måler sit emne */
.tg-maal {
  stroke: var(--rust);
  stroke-width: 1;
  stroke-dasharray: 4 4;
  fill: none
}

.tg-maal-tekst {
  fill: var(--rust);
  font-family: var(--font-data);
  font-size: 11px;
  letter-spacing: .06em
}

/* Tegner sig selv ved indlæsning.
   pathLength="1" i markupen normaliserer hver streg til længden 1, så
   ÉN dasharray-værdi virker for dem alle uanset faktisk længde — ellers
   skulle hver streg have sin egen målte længde. */
.tegn {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: tegn 1.5s cubic-bezier(.5, .1, .2, 1) forwards
}

@keyframes tegn {
  to {
    stroke-dashoffset: 0
  }
}

.d1 {
  animation-delay: .15s
}

.d2 {
  animation-delay: .3s
}

.d3 {
  animation-delay: .45s
}

.d4 {
  animation-delay: .6s
}

.d5 {
  animation-delay: .72s
}

.d6 {
  animation-delay: .85s
}

.tg-fade {
  opacity: 0;
  animation: tgfade .7s ease forwards 1.25s
}

@keyframes tgfade {
  to {
    opacity: 1
  }
}

@media (prefers-reduced-motion: reduce) {
  .tegn {
    stroke-dashoffset: 0;
    animation: none
  }

  .tg-fade {
    opacity: 1;
    animation: none
  }
}



/* ══════════════════════════════════════════════════════════════════════
   KATEGORIMOSAIK
   ══════════════════════════════════════════════════════════════════════ */
.mosaik {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: minmax(clamp(132px, 14vw, 164px), auto);
  gap: clamp(9px, 1vw, 12px);
}

.udforsk-section {
  padding: 30px 0 20px;
  background-color: var(--paper);
}

.deals-head {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.u-eyebrow {
  font-size: 11.5px;
  font-weight: 700;
  color: var(--rust);
  letter-spacing: .05em;
  text-transform: uppercase;
}

.deals-titel {
  font-size: 34px;
  font-weight: 700;
  font-family: var(--font-display);
  margin: 0;
  line-height: 1.1;
  color: var(--ink);
}

.udforsk-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  margin-bottom: 30px;
}

.udforsk-titles {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.udforsk-eyebrow {
  font-size: 11.5px;
  font-weight: 700;
  color: var(--rust);
  letter-spacing: .05em;
  text-transform: uppercase;
}

.udforsk-titles h2 {
  font-size: 34px;
  font-weight: 700;
  font-family: var(--font-display);
  margin: 0;
  line-height: 1.1;
  color: var(--ink);
}

.udforsk-alle {
  color: var(--rust);
  font-weight: 600;
  text-decoration: none;
  font-size: 14.5px;
  margin-bottom: 4px;
}

.udforsk-alle:hover {
  text-decoration: underline;
}

.mosaik {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 164px;
  grid-auto-flow: dense;
  gap: 10px;
}

.mosaik .flise {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  background-color: var(--surface);
  border-radius: 16px;
  padding: 20px;
  text-decoration: none;
  color: var(--ink);
  transition: transform .2s cubic-bezier(.2, .7, .2, 1), box-shadow .2s ease;
  overflow: hidden;
}

.mosaik .flise:nth-child(1) {
  background: #F5E6DA;
}

.mosaik .flise:nth-child(2) {
  background: #E7EDE4;
}

.mosaik .flise:nth-child(3) {
  background: #F0E4E9;
}

.mosaik .flise:nth-child(4) {
  background: #E4E9EC;
}

.mosaik .flise:nth-child(5) {
  background: #F6E9DD;
}

.mosaik .flise:nth-child(6) {
  background: #E9E6F0;
}

.mosaik .flise:nth-child(7) {
  background: #EFE7DA;
}

.mosaik .flise:nth-child(8) {
  background: #E3EAE7;
}

.mosaik .flise-hoej {
  grid-column: span 1;
  grid-row: span 2;
}

.mosaik .flise-bred {
  grid-column: span 2;
  grid-row: span 1;
}

.mosaik .flise:hover {
  transform: translateY(-4px);
  box-shadow: 0 12px 24px rgba(8, 18, 26, 0.06);
}

.mosaik .flise:focus-visible {
  outline: 2.5px solid var(--rust);
  outline-offset: 3px;
}

.mosaik .flise-foto {
  position: absolute;
  right: -5%;
  bottom: -5%;
  width: 65%;
  height: 65%;
  object-fit: contain;
  object-position: bottom right;
  margin: 0;
  pointer-events: none;
  transition: transform .35s cubic-bezier(.2, .7, .2, 1);
  border-radius: 8px;
  /* For real images */
}

.mosaik .flise-hoej .flise-foto {
  width: 90%;
  height: 70%;
  min-height: 45%;
  right: -10%;
  bottom: -5%;
}

.mosaik .flise:hover .flise-foto {
  transform: scale(1.03);
}

.mosaik .flise-tekst {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column-reverse;
  /* Count above h2 */
  gap: 6px;
}

.mosaik .flise-pil {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 1px solid rgba(8, 18, 26, 0.12);
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(8, 18, 26, 0.5);
  margin-top: auto;
  align-self: flex-start;
  z-index: 2;
  transition: all .2s ease;
}

.mosaik .flise:hover .flise-pil {
  background: var(--ink);
  color: #fff;
  border-color: var(--ink);
  transform: scale(1.05);
}

.mosaik .flise h2 {
  font-family: var(--font-display);
  font-size: 21px;
  /* Slightly larger */
  font-weight: 700;
  letter-spacing: -.02em;
  line-height: 1.15;
  margin: 0;
  color: var(--ink);
}

.mosaik .flise .cat-count {
  font-size: 11px;
  color: rgba(8, 18, 26, 0.5);
  margin-bottom: 0;
}

.mosaik .flise-tal {
  font-family: var(--font-data);
  font-size: 10.5px;
  letter-spacing: .01em;
  line-height: 1.3;
  white-space: nowrap
}

.mosaik .flise-tal strong {
  font-weight: 500;
  color: var(--muted);
  font-variant-numeric: tabular-nums
}

@container (max-width: 168px) {
  .mosaik .flise h2 {
    font-size: 16px;
    letter-spacing: -.035em
  }
}

@media (max-width: 860px) {
  .mosaik {
    grid-template-columns: repeat(2, 1fr);
    grid-auto-flow: row dense;
    grid-auto-rows: minMax(164px, auto);
  }

  .mosaik .flise-hoej {
    grid-column: span 1;
    grid-row: span 2;
  }

  .mosaik .flise-bred {
    grid-column: span 2;
    grid-row: span 1;
  }
}


/* 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 {
  font-family: var(--font-data);
  font-variant-numeric: tabular-nums;
  color: var(--text);
  font-weight: 500
}

/* 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)
}

/* Egen række for selve pillerne (se begrundelsen i index.php). flex-basis
   100% + wrap gengiver PRÆCIS det gamle layout på computerbredde — .kat-pille
   lå før direkte i .kat-sekundaer og wrappede der; nu wrapper den her i
   stedet, med samme gap og samme visuelle resultat. */
.kat-pille-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  flex-basis: 100%
}

@media (max-width: 680px) {

  /* Fra flex-wrap til én vandret rulle-række, samme mønster som
     .deal-kategori-scroll: overflow-x + faste bredder (flex-shrink: 0), for
     ellers er der intet at rulle. 9 linjer på 375px bliver til én. */
  .kat-pille-row {
    flex-wrap: nowrap;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    padding-bottom: 4px;
    scrollbar-width: thin
  }

  .kat-pille-row .kat-pille {
    flex-shrink: 0;
    scroll-snap-align: start
  }

  /* Mobil har allerede sin egen vandret rulle-række herover — alle 19
     piller er nået via scroll i én linje uden knappen. */
  .kat-pille-toggle {
    display: none
  }
}

/* ⚠ TILFØJET 21/8: 19 piller wrappede til op mod 4 linjer på
   computerbredde — en "voldsom mur af kanter" (samme begrundelse som
   mobil-rullereglen ovenfor gav for mobil, men den gjaldt aldrig
   computerbredde, se dens docblok: "uændret på computerbredde"). Rettet
   ved at klappe rækken sammen til én linje med is-collapsed (sat i
   markuppen, se index.php) og en knap der folder resten ud. */
@media (min-width: 681px) {
  .kat-pille-row.is-collapsed {
    flex-wrap: nowrap;
    overflow: hidden
  }

  .kat-pille-row.is-collapsed .kat-pille {
    flex-shrink: 0
  }
}

.kat-pille-toggle {
  align-self: flex-start;
  margin-top: 4px;
  background: none;
  border: none;
  padding: 0;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--primary);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px
}

.kat-pille-toggle:hover {
  color: var(--primary-dark, var(--primary))
}

/* flex-basis: 100% tvinger labelen til altid at stå alene på sin egen
   linje. Uden den delte den linje med "Udstyr"-pillen i et smalt
   vindue (~400-560px, bl.a. iPhone 14/15/16 Pro Max) — netop bredt nok
   til label+pille 1, men ikke pille 2. Pille 2 knækkede så ned til en
   NY linje, der starter helt ude ved venstrekanten (samme sted som
   labelen), altså LÆNGERE til venstre end pille 1 lige ovenover — en
   skæv indrykning, meldt med skærmbillede 6/8. Med labelen på sin egen
   linje wrapper de to piller altid som en gruppe for sig selv, ensartet
   venstrestillet uanset bredde. Efterprøvet: ingen ændring ved 375px
   (stod allerede på hver sin linje) eller ved bredder hvor begge piller
   plus label deler linje uden problemer. */
.kat-sekundaer-label {
  flex-basis: 100%;
  font-size: 14px;
  color: var(--muted)
}

.kat-pille {
  font-size: 13.5px;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 50px;
  padding: 6px 14px;
  transition: .2s
}

/* ⚠ Var var(--primary) (rød) — rav/rust (var(--rust)), samme rettelse som
   resten af mobilredesignet. */
.kat-pille:hover {
  border-color: var(--rust);
  color: var(--text)
}

.kat-pille em {
  font-style: normal;
  color: var(--faint);
  margin-left: 4px
}

/* ⚠ RETTET 20/8: stod her som et almindeligt LYST felt (var(--surface),
   var(--border), var(--text)) — de globale tokens, som er afstemt til
   sidens lyse læseflade, ikke til feltet. Formularen ligger inde i
   .hero-kat.paa-felt, men intet i denne blok tog hensyn til det: en
   lyst indrammet boks midt i den mørke hero, i stedet for mockuppens
   glasagtige felt der smelter ind i baggrunden (rgba(243,238,228,.06) —
   6% af --paa-felt, næsten usynlig indtil man klikker i den).
   Container BÆRER nu selv kant/afrunding/baggrund; input og knap er
   begge kantløse indeni, så de to smelter sammen til én pille i stedet
   for to separate former ved siden af hinanden. */
.kat-soeg {
  display: flex;
  gap: 0;
  margin-left: auto;
  border: 1px solid rgba(201, 213, 221, .4);
  border-radius: 0;
  overflow: hidden;
  background: rgba(243, 238, 228, .06);
  transition: border-color .15s
}

.kat-soeg:focus-within {
  border-color: var(--primary-paa-felt)
}

.kat-soeg input {
  width: 300px;
  max-width: 100%;
  background: transparent;
  border: 0;
  border-radius: 0;
  color: var(--paa-felt);
  font: inherit;
  font-size: 14px;
  padding: 10px 14px
}

.kat-soeg input::placeholder {
  color: var(--paa-felt-dim)
}

.kat-soeg input:focus {
  outline: none
}

/* ⚠ Der findes en global `.btn { width: 100% }` under 680px (se linje
   ~2395), skrevet til stakkede CTA'er som nyhedsbrevet. Den er UNSCOPET og
   ramte derfor også søgeknappen her: browseren læste dens ønskede bredde
   som "hele rækken", og med input's flex-basis presset ned mod sin
   min-content-bredde endte knappen med at æde langt mere plads end sin
   tekst, mens feltet blev klemt sammensmalt. Målt 508px FØR denne regel:
   felt 191px, knap 253px — omvendt af hvad en søgeknap bør fylde.
   `.kat-soeg .btn` har højere specificitet (0,2,0 mod 0,1,0) og vinder
   derfor uanset media-rækkefølge; her nulstilles den til indholdsstørrelse,
   så det er FELTET og ikke knappen der får den frigjorte plads. */
.kat-soeg .btn {
  width: auto;
  flex: 0 0 auto;
  /* Containeren (.kat-soeg) bærer nu selv afrundingen og klipper med
     overflow: hidden — knappen skal derfor være firkantet, ellers ses
     dens egen runde pilleform inde i den fælles kant. */
  border-radius: 0;
  box-shadow: none
}

/* ⚠ TILFØJET 21/8 — Retning 1 (ændringer til design/Retning 1 -
   implementeringsguide.dc.html). #tilbud (views/index.php) bruger ikke
   længere den fælles .container — barnet kan ikke blive bredere end sin
   forælder, og .container's max-width: 1240px ville have gjort
   --maxw-deals virkningsløs. .deals-section bærer derfor sin egen
   bredde, kun her. Resten af forsiden (hero, kategorimosaik, METODEN, Om
   CykelTjek) og alle andre sider er urørt — de har hver deres egen
   .container, uændret. */
.deals-section {
  max-width: var(--maxw-deals);
  margin-inline: auto;
  padding-inline: clamp(24px, 4vw, 40px)
}

/* Første kategori-række + den mørke sidebar-boks (titel, undertekst,
   kategori-genveje, "Priser hentet"). Erstatter den tidligere
   .pris-head-linje øverst på siden — se docblokken ved .section-head
   ovenfor i filen for hvorfor. order:2 på boksen, order:1 på rækken:
   boksen står FØRST i DOM'en (så en skærmlæser møder titlen før
   produktkortene, og mobilstakningen nedenfor viser den øverst uden
   videre), men VISUELT efter rækken på desktop, som en sidebar til
   højre. */
.deals-hero {
  display: flex;
  gap: 28px;
  align-items: stretch;
  margin-bottom: 40px
}

.deals-hero__row {
  order: 1;
  flex: 1;
  min-width: 0;
  overflow: hidden
}

.deals-hero__box {
  order: 2;
  flex: 0 0 280px;
  background: var(--felt);
  border-radius: 0;
  padding: 26px 22px 22px;
  display: flex;
  flex-direction: column;
  color: var(--paa-felt)
}

.deals-hero__box h2 {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 800;
  letter-spacing: -.03em;
  line-height: 1.15;
  margin-bottom: 10px
}

.deals-hero__box p {
  font-size: 14.5px;
  color: var(--paa-felt-dim)
}

/* ⚠ RETTET 21/8: erstatter .deals-hero__links (kategori-genveje,
   fjernet — Mathias ville have et samlet cykel-/udstyrstal og en kort
   metode-sætning i stedet, ikke ved siden af genvejene). Samme visuelle
   linje-mønster (border-top pr. række) som genvejene havde. */
.deals-hero__stats {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 16px
}

.deals-hero__stats div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 0;
  border-top: 1px solid var(--felt-linje)
}

.deals-hero__stats strong {
  font-family: var(--font-data);
  font-size: 18px;
  font-weight: 600;
  color: var(--paa-felt);
  font-variant-numeric: tabular-nums
}

.deals-hero__stats span {
  font-size: 13px;
  color: var(--paa-felt-dim)
}

.deals-hero__metode {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--felt-linje);
  font-size: 13px;
  color: var(--paa-felt-dim)
}

@media (max-width: 860px) {
  .deals-hero {
    flex-direction: column
  }

  .deals-hero__row,
  .deals-hero__box {
    order: initial;
    flex: 1 1 auto
  }
}

/* Var 7/8 en tynd 13.5px-linje i --muted, som druknede ved siden af
   overskriften — løst dengang med en baggrundsboks (se historik i git).
   Erstattet 20/8 af mockuppens eyebrow-mønster: samme label-over-værdi
   som resten af sitet (.u-eyebrow, "TRIN 01" osv.), så "friskheds-beviset"
   ikke længere er sin egen unikke stilart, men en gentagelse af et mønster
   den besøgende allerede kender fra resten af siden. white-space: nowrap
   på værdilinjen (ikke hele blokken) løser samme problem som boksen gjorde
   — datoen kan ikke knække midt i "20.08 · 03:02" — uden at kræve en
   baggrundsflade for at stå ud.
   ⚠ RETTET 21/8: boede før i .pris-head, øverst på siden på lys baggrund
   (text-align:right, --faint/--felt). Genbruges nu inde i den mørke
   .deals-hero__box — venstrestillet, og begge farver rettet til deres
   dark-bg-modstykker (samme mønster som .metode-head .u-eyebrow). */
.deals-hero__box .pris-opdateret {
  text-align: left;
  margin-top: auto;
  padding-top: 16px;
  border-top: 1px solid var(--felt-linje)
}

.pris-opdateret .u-eyebrow {
  display: block;
  color: var(--trust-paa-felt);
  margin-bottom: 5px
}

/* Størrelse hentet ORDRET fra mockuppens kildekode (.aflaesning-tid,
   WebFetch af artifact e339b87a, 20/8). Farven er rettet til
   --paa-felt (lys) 21/8 — --felt (mørk navy) var beregnet til lys
   baggrund og ville have været usynlig i den mørke boks. */
.pris-opdateret-tid {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-data);
  font-size: 21px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--paa-felt);
  letter-spacing: -.02em;
  white-space: nowrap
}

.pris-prik {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--primary-paa-felt);
  flex: none
}

/* ⚠ #om (padding: 56px 0) er FJERNET 20/8. Den var rigtig dengang —
   se historikken — men id'et sidder nu på .metode-band, som fik sit eget
   fulde padding-system i redesignet 19-20/8 (clamp(52px,7vw,78px) 0
   clamp(44px,6vw,64px)). En ID-selector (specificitet 1,0,0) vinder over
   en klasse uanset rækkefølge, så denne gamle regel overskrev STILLE
   metode-båndets egen padding ned til en flad 56px — fundet ved at
   sammenligne getComputedStyle direkte mod mockuppens kildekode, ikke
   ved at kigge; forskellen er for lille til at se med det blotte øje. */

/* 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
}

/* border-top er fjernet 6/8 efter ønske. De tre celler har gap:0 i
   .metode's grid, så deres tre 2px-kanter sad flugtende og læstes som
   ÉN sammenhængende streg hen over hele sektionens bredde. */
.metode-item {
  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 h2 {
    font-size: 15.5px
  }
}

/* ── 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: 0
}

/* .deal-card-skeleton havde sine egne to regler her indtil 6/8. Skeletonet
   bruger nu de samme indre klasser (.product-img/.product-body) og samme
   markørklasse (.product-card-skeleton) som cykler.js's eget skeleton —
   se script.js's renderDealsSkeleton() — så reglerne nedenfor dækker
   begge sider uden en duplikeret variant. */

/* 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);
  /* Var var(--radius) (10px) — samme rettelse som resten af sitets
     kort/paneler, se .guide-card. */
  border-radius: 0;
  color: var(--muted)
}

.deal-fejl p {
  margin-bottom: 16px
}

/* ── Hero-kat-top: overskrift/lead ved siden af cykeltegningen ──
   To celler: .hero-kat-text (eyebrow, H1, lead) og .tegning (den
   selvtegnende SVG). Stables på mobil, se @media(max-width: 780px)
   nedenfor. */
.hero-kat-top {
  display: grid;
  grid-template-columns: 1fr 1.1fr;
  gap: clamp(24px, 4vw, 56px);
  align-items: center;
  margin-bottom: clamp(28px, 4vw, 44px)
}

.hero-kat-text {
  max-width: 520px
}

.hero-kat-text .lead {
  margin-bottom: 0
}

/* ⚠ FJERNET 22/8: .hero-kat-trust/.trust-item/.trust-icon/.trust-text/
   .hero-kat-side hørte til et TIDLIGERE hero-layout — et nøgletalspanel
   ved siden af overskriften. index.php har ikke afgivet den markup
   siden, kun .hero-kat-text og .tegning findes i .hero-kat-top i dag.
   Fundet af "Implementeringsguide — forsiden på mobil" (22/8) som dødt
   CSS uden modstykke i nogen view, inkl. deres to mobil-brudpunkter ved
   900px/560px. Bekræftet grep'et tomt i views/ og assets/ før sletning. */

@media (max-width: 780px) {

  /* .hero-kat's eget brudpunkt sidder ved 560px (se nedenfor) — 780px
     giver luft før teksten begynder at knække grimt, som guiden
     anbefaler. Uden dette brudpunkt presses H1 og tegning ind i hver sin
     ~150px-spalte på en telefon i stedet for at stå fuld bredde
     ovenpå hinanden. */
  .hero-kat-top {
    grid-template-columns: 1fr;
    gap: 24px;
  }

  .hero-kat-text {
    max-width: none;
  }

  /* Tegningen er dekoration (aria-hidden i markuppen) — den må gerne
     krympe under sin desktop-bredde, så den ikke dominerer skærmen over
     selve overskriften, som er sidens vigtigste linje her. */
  .tegning {
    max-width: 280px;
    margin: 0 auto;
  }
}

/* ══ PARTNERBÅND ══
   ⚠ Her stod `width: 0; min-width: 100%` med en lang begrundelse om at
   holde båndet ude af en flex-søjles breddeberegning. Den situation
   findes ikke længere: båndet lå dengang INDE i hero'ens højre kolonne
   ved siden af nøgletals-panelet. Nu er det fuldbredde og direkte barn
   af sektionen, og de to linjer gav 3px vandret overløb ved 360px.

   Rammen og de runde hjørner er også væk af samme grund — et bånd der
   går fra kant til kant skal ikke se ud som en kasse. Kun en hårlinje
   foroven adskiller det fra søgerækken. */
.partner-baand {
  width: 100%;
  height: 44px;
  overflow: hidden;
  background: var(--felt);
  border-top: 1px solid rgba(22, 35, 44, 0.06);
  border-bottom: 1px solid rgba(22, 35, 44, 0.06);
  margin-top: 20px;
  padding: 0;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 clamp(16px, 4vw, 40px), #000 calc(100% - clamp(16px, 4vw, 40px)), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 clamp(16px, 4vw, 40px), #000 calc(100% - clamp(16px, 4vw, 40px)), transparent 100%);
}

.partner-spor {
  display: flex;
  width: max-content;
  height: 100%;
  /* ⚠ 46s, ikke 18s: båndet skal drive stille forbi, ikke haste. Og
     -25% hænger sammen med de FIRE kopier i markupen — én kopis bredde.
     Ændrer du antallet af kopier, skal procenten i @keyframes med. */
  animation: partner-rul 46s 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: 0;
  transition: color .15s
}

.partner-link:hover,
.partner-link:focus-visible {
  color: var(--primary-paa-felt)
}

/* 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;
  height: 100%;
  /* Afstanden bæres nu af li'ets egen padding, så den er ens hen over
     overgangen mellem to kopier og inde i en kopi. */
  gap: 0;
  padding: 0;
  margin: 0;
  list-style: none;
  flex-shrink: 0
}

.partner-liste li {
  position: relative;
  display: flex;
  align-items: center;
  height: 100%;
  padding: 0 46px;
  /* Added horizontal padding to space out links instead of li padding */
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 700;
  color: var(--paa-felt);
  white-space: nowrap;
}

/* ⚠ Skilletegnet er et lille HJUL, ikke en lodret streg. Streger gjorde
   rækken til en TABEL — hvert navn i sin egen celle — og et bånd der
   løber må ikke læse som data. Hjulet er samme figur som resten af
   sitet bruger, centreret præcis på grænsen mellem to navne
   (right: -3px = halvdelen af de 6px). */
.partner-liste li::after {
  content: '';
  position: absolute;
  right: -3px;
  top: 50%;
  transform: translateY(-50%);
  width: 6px;
  height: 6px;
  border-radius: 50%;
  border: none;
  background: var(--rust);
}

/* -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
  }
}

/* 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
}

/* ── Guide-artikel (views/guide.php) ────────────────────────────────────────
   Fase J: guider renderes serverside fra guides-tabellen. Klasserne bor her
   i styles.css og ikke i en egen fil, fordi header/footer loader kun denne
   — samme grund som invariant 11 giver for produktkortene. */
.guide-hero {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  padding: 72px 0 48px;
  border-top: 3px solid var(--guide-farve, var(--primary));
}

.guide-kicker {
  display: inline-block;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--guide-farve, var(--primary));
  margin-bottom: 12px;
}

.guide-hero h1 {
  font-size: clamp(28px, 4vw, 44px);
  line-height: 1.15;
  margin: 0 0 14px;
  max-width: 22ch;
}

.guide-resume {
  font-size: 18px;
  color: var(--muted);
  max-width: 60ch;
  margin: 0 0 18px;
}

.guide-dato {
  font-size: 13px;
  color: var(--faint);
  margin: 0;
}

/* Læsebredden er bevidst smal. Brødtekst i fuld sidebredde er ulæselig, og
   artiklen er det eneste sted på sitet med lange tekstblokke. */
.guide-indhold {
  max-width: 72ch;
  padding-top: 40px;
  padding-bottom: 24px;
  font-size: 17px;
  line-height: 1.7;
}

.guide-indhold h2 {
  font-size: 26px;
  margin: 40px 0 14px;
}

.guide-indhold h3 {
  font-size: 20px;
  margin: 30px 0 10px;
}

.guide-indhold p {
  margin: 0 0 18px;
}

.guide-indhold ul,
.guide-indhold ol {
  margin: 0 0 18px;
  padding-left: 22px;
}

.guide-indhold li {
  margin-bottom: 8px;
}

/* ⚠ :not(.btn) er ikke pynt.
   Reglen her har specificitet 0,1,1 og slog derfor .btn-primary (0,1,0)
   ihjel: købsknappen på et produktkort fik linkfarven --primary som TEKST
   oven på sin egen orange flade --cta. Orange på orange — knappen var
   næsten ulæselig, og fejlen viste sig først da den første artikel med
   produktkort blev udgivet, fordi kortene kun findes inde i brødteksten.
   Undtagelsen dækker enhver .btn, så et fremtidigt knapmønster i en
   artikel ikke rammer den samme mur. */
.guide-indhold a:not(.btn) {
  color: var(--primary);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* Knapper i brødteksten skal se ud som knapper overalt ellers på sitet:
   ingen understregning, og teksten fra .btn-primary. Reglen står eksplicit
   frem for at hvile på arverækkefølgen, så den overlever at nogen tilføjer
   endnu en .guide-indhold a-regel senere. */
.guide-indhold a.btn {
  text-decoration: none;
}

.guide-indhold a.btn-primary {
  color: var(--paa-farve);
}

.guide-indhold img {
  max-width: 100%;
  height: auto;
  border-radius: 0;
}

/* Tabeller i brødtekst må aldrig få siden til at scrolle vandret. */
.guide-indhold table {
  display: block;
  overflow-x: auto;
  max-width: 100%;
  border-collapse: collapse;
}

.guide-bund {
  max-width: 72ch;
  padding-bottom: 64px;
}

/* ── Produktreference i en artikel (backend/lib/Artikel.php) ────────────────
   Vandret boks: billede til venstre, tekst og knap til højre. Bevidst ANDET
   udseende end produktkortene i gitteret — her er den et indslag i en tekst,
   ikke et element i en liste, og den skal kunne skelnes fra brødteksten. */
.artikel-produkt {
  display: flex;
  gap: 18px;
  align-items: center;
  margin: 28px 0;
  padding: 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0;
}

.artikel-produkt-billede {
  flex: 0 0 120px;
  height: 120px;
  display: flex;
  align-items: center;
  justify-content: center;
  /* var #fff — se --foto-flade: billederne har selv hvid bund, så fladen
     skal matche dem i BEGGE temaer. Tokenet findes netop derfor. */
  background: var(--foto-flade);
  border-radius: 0;
  overflow: hidden;
}

/* .product-photo bor i styles.css (invariant 11) og styrer selv sin
   størrelse — her sættes kun rammen omkring. */
.artikel-produkt-billede .product-photo {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.artikel-produkt-tekst {
  min-width: 0;
  flex: 1;
}

.artikel-produkt-butik {
  display: block;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: 4px;
}

.artikel-produkt-titel {
  font-size: 17px;
  line-height: 1.3;
  margin: 0 0 8px;
}

.artikel-produkt-titel a {
  color: inherit;
  text-decoration: none;
}

.artikel-produkt-titel a:hover {
  text-decoration: underline;
}

.artikel-produkt-pris {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 12px;
}

.artikel-produkt-nu {
  font-size: 21px;
  font-weight: 700;
}

/* Vises KUN når lowest_30d faktisk er højere end prisen nu (invariant 1).
   Er der ingen dokumenteret førpris, findes disse elementer slet ikke. */
.artikel-produkt-foer {
  font-size: 14px;
  color: var(--faint);
  text-decoration: line-through;
}

.artikel-produkt-spar {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--primary);
}

.artikel-produkt-knap {
  display: inline-flex;
  font-size: 13.5px;
  padding: 10px 18px;
}

.artikel-produkt-intetbillede {
  width: 100%;
  height: 100%;
  background: var(--border);
  border-radius: 0;
}

/* Produktet findes ikke længere. Dæmpet og uden købsknap — en artikel bliver
   stående i årevis, produkter gør ikke. */
.artikel-produkt--vaek {
  display: block;
  color: var(--faint);
  font-size: 14px;
}

.artikel-produkt--vaek p {
  margin: 0;
}

@media (max-width: 560px) {
  .artikel-produkt {
    flex-direction: column;
    align-items: stretch;
  }

  .artikel-produkt-billede {
    flex: 0 0 auto;
    height: 160px;
  }
}

/* ══════════════════════════════════════════════════════════════════════
   TEKSTSIDER — .about-*
   ══════════════════════════════════════════════════════════════════════

   Det smalle læsefelt der bruges af Om os, Privatliv, Kontakt,
   Handelsbetingelser, Guides-oversigten og 404.

   ⚠ DE HØRER TIL HER, IKKE I EN SIDESPECIFIK FIL — invariant 11.
   Reglerne lå i assets/css/om-os.css, som kun blev loadet af tre af de seks
   sider der bruger klasserne. Handelsbetingelser, 404 og guides-oversigten
   stod derfor uden læsefelt: fuld bredde, standardskrift på overskrifterne
   og ingen luft. Markupen var identisk med Om os — det eneste der
   manglede, var én linje $extraStyles.

   Samme faldgrube som .product-card og .product-photo havde i cykler.css.
   Tilføjer du en klasse som mere end én side bruger, så læg den her.
   ══════════════════════════════════════════════════════════════════════ */

.about-page {
  /* Samme lyse baggrund som resten af sitet */
  background-color: var(--bg);
}

.about-hero {
  padding: 60px 0 20px 0;
  text-align: left;
}

/* Samme eyebrow-mønster som forsidens "Om"-sektion og /tilbud + /favoritter
   (accent-ordet i deres H1'er) — de fire indholdssider (om-os, kontakt,
   privatliv, handelsbetingelser) havde ingen af delene og stod tilbage som
   det generiske layout fra før redesignet 19-20/8, selvom paletten var
   rigtig. Samme klasse, ét sted at style den. */
.about-hero .u-eyebrow {
  display: block;
  color: var(--primary);
  margin-bottom: 12px;
}

/* .about-title/.about-lead(-sub) bruges kun på /guides og 404 — ingen af
   dem havde egne regler før 12/8, så de kørte på browserens standard
   <h1>/<p>. Style dem selv i stedet for at læne sig op ad .about-section
   h1/p (som kræver forælderen .about-section, ikke .about-hero). */
.about-title {
  font-family: var(--font-display);
  font-size: 2.4rem;
  letter-spacing: -.02em;
  margin-bottom: 10px;
}

.about-lead {
  font-size: 17px;
  color: var(--text);
  margin-bottom: 6px;
}

.about-lead-sub {
  font-size: 14.5px;
  color: var(--muted);
  max-width: 640px;
  line-height: 1.6;
}

/* ── 404-siden ──
   Modifier oven på .about-hero, se views/404.php for markuppen og
   begrundelsen for den statiske SVG (en forenklet, urørt kopi af
   forsidens hero-tegning, ikke en ændring af den). */
.error-404 {
  text-align: center;
  padding: 90px 20px 110px;
}

.error-404 .tegning-404 {
  width: 190px;
  margin: 0 auto 4px;
  opacity: .5
}

.error-404 .tegning-404 svg {
  display: block;
  width: 100%;
  height: auto
}

.tegning-404-ramme {
  color: var(--border)
}

.tegning-404-brud {
  color: var(--cta)
}

.error-404-tal {
  font-family: var(--font-display);
  font-size: clamp(60px, 11vw, 88px);
  font-weight: 700;
  color: var(--cta);
  line-height: 1;
  letter-spacing: -.02em;
  margin: 0
}

.error-404 .about-title {
  margin-top: 14px
}

.error-404-knapper {
  margin-top: 34px;
  display: flex;
  justify-content: center;
  gap: 12px;
  flex-wrap: wrap
}

.about-content {
  /* Det smalle, læsevenlige læsefelt */
  max-width: 760px;
  margin: 0 auto;
  padding: 20px 20px 100px 20px;
}

.about-section {
  margin-bottom: 32px;
}

.about-section h1 {
  font-size: 2.8rem;
  color: var(--text);
  margin-bottom: 1.2rem;
  font-family: var(--font-display);
  letter-spacing: -0.02em;
  /* "Handelsbetingelser" er 19 tegn i ét ord — ved 320px overløb den 33px
       ud over kanten, fordi CSS' standard (overflow-wrap: normal) kun
       bryder ved mellemrum, aldrig inde i et ord. Pre-eksisterende, fundet
       20/8 ved harmoniseringen af de fire indholdssider. */
  overflow-wrap: break-word;
}

.about-section h2 {
  font-size: 1.8rem;
  color: var(--text);
  margin-bottom: 1.2rem;
  font-family: var(--font-display);
  letter-spacing: -0.01em;
}

/* ⚠ TILFØJET 20/8: rav-prik foran hver h2, efter facit i
   "Implementeringsguide - PRAECIS.md" (ændringer til design/), afsnit 8.
   Bekræftet mod mockuppen: KUN Privatliv og Handelsbetingelser har
   prikken — Om os' to h2'er har den ikke. Scopet til .legal-page
   (sat på <main> i views/privatliv.php og views/handelsbetingelser.php)
   i stedet for globalt på .about-section h2, så den aldrig kan ramme
   Om os eller Kontakt ved en fejl. */
.legal-page .about-section h2 {
  display: flex;
  align-items: center;
  gap: 10px;
}

.legal-page .about-section h2::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--cta);
  flex-shrink: 0;
}

/* ⚠ TILFØJET 20/8, udvidet 21/8: Privatlivs h2'er ("Cookies", "Statistik",
   "Affiliate Links") skal have et talmærke ("1.", "2.", "3.") i stedet for
   den almindelige prik — bedt om af Mathias. Scopet til .h2-nummer (sat
   direkte på hvert h2 i views/privatliv.php), ikke på den delte
   .legal-page .about-section h2::before-regel ovenfor — den regel bruges
   også af Handelsbetingelsers tre overskrifter, som fortsat skal have
   almindelige prikker.
   Tallet er en CSS-tæller, ikke en hardkodet streng: der var kun ét afsnit
   20/8, og en fast '1.' holdt op med at være rigtig i det øjeblik et andet
   afsnit tilføjedes. counter-reset sidder på .legal-page (fælles med
   Handelsbetingelser, som er uden risiko — den bruger aldrig .h2-nummer). */
.legal-page {
  counter-reset: privatliv-nummer;
}

.legal-page .about-section h2.h2-nummer::before {
  counter-increment: privatliv-nummer;
  content: counter(privatliv-nummer) '.';
  width: auto;
  height: auto;
  border-radius: 0;
  background: none;
  color: var(--text);
  font-family: var(--font-display);
  font-size: inherit;
  font-weight: 700;
  flex-shrink: 0;
}

.about-section p {
  font-size: 1.15rem;
  /* Luft mellem linjerne — det er lange tekster der skal læses */
  line-height: 1.85;
  color: var(--faint);
  margin-bottom: 1.2rem;
}

.about-section strong {
  color: var(--text);
  font-weight: 600;
}

.about-section em {
  font-style: italic;
  color: var(--text);
}

.about-section ul {
  margin-bottom: 24px;
  padding-left: 20px;
  color: var(--muted);
}

.about-section li {
  margin-bottom: 8px;
}

@media (max-width: 768px) {
  .about-hero {
    padding: 40px 0 10px 0;
  }

  .about-section h1 {
    font-size: 2.2rem;
  }

  .about-section h2 {
    font-size: 1.5rem;
  }

  .about-section p {
    font-size: 1.05rem;
    line-height: 1.6;
  }
}

/* ══════════════════════════════════════════════════════════════════════
   OM-SEKTIONEN — redaktionel opdeling
   ══════════════════════════════════════════════════════════════════════ */
.u-eyebrow {
  font-family: var(--font-data);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase
}

.om {
  display: grid;
  grid-template-columns: 282px minmax(0, 1fr);
  gap: clamp(26px, 5vw, 72px);
  align-items: start
}

.om-titel {
  border-top: 2px solid var(--felt);
  padding-top: 20px
}

.om-titel h2 {
  font-family: var(--font-display);
  font-size: clamp(23px, 2.7vw, 30px);
  font-weight: 800;
  letter-spacing: -.035em
}

.om-titel .u-eyebrow {
  color: var(--faint);
  display: block;
  margin-top: 12px
}

/* Kolofon — venstre spalte stod tom under overskriften. Nu bærer den de
   tal nogen faktisk kan efterprøve, sat som et specifikationsblad:
   etiket til venstre, tal højrestillet i mono. */
.kolofon {
  margin-top: 30px
}

.kolofon-post {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  padding: 10px 0;
  /* var(--border) = #CFC6B2, en anelse mere dæmpet end kilden. */
  border-top: 1px solid var(--bg-3)
}

.kolofon-post:last-child {
  border-bottom: 1px solid var(--bg-3)
}

.kolofon-post span {
  font-size: 12.5px;
  color: var(--faint)
}

.kolofon-post b {
  font-family: var(--font-data);
  font-size: 14.5px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--felt);
  letter-spacing: -.02em;
  white-space: nowrap
}

.om-tekst {
  max-width: 60ch
}

/* Manchet: bærer hele beskeden, så den skal træde tydeligt frem for de
   øvrige afsnit — ellers registreres springet ikke. */
/* ⚠ Selectoren er .om-tekst .om-manchet, ikke bare .om-manchet, og det
   er ikke pynt: .om-manchet alene har specificitet (0,1,0), mens
   .om-tekst p (nedenfor) har (0,1,1) — én klasse OG ét element slår én
   klasse alene, uanset at .om-manchet ser mere specifik ud for et
   menneske. Uden dette tabte manchetten sin egen font-size til den
   almindelige brødtekststørrelse (15,5px i stedet for op til 22,5px) —
   den skulle bære hele beskeden, og gjorde det ikke. Samme fejl findes i
   selve mockuppens kildekode (WebFetch af artifact e339b87a, 20/8) —
   den var ikke opdigtet her, men den var heller ikke rigtig dér, og
   rettes derfor uafhængigt af om kilden selv gør det. */
.om-tekst .om-manchet {
  font-size: clamp(19px, 2vw, 22.5px);
  line-height: 1.45;
  color: var(--text);
  letter-spacing: -.022em;
  margin-bottom: 22px
}

.om-tekst p {
  color: var(--muted);
  font-size: 15.5px;
  margin-bottom: 14px
}

.om-tekst p:last-child {
  margin-bottom: 0
}

.om-tekst a {
  color: var(--primary);
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px solid rgba(139, 76, 6, .4)
}

.om-tekst a:hover {
  border-bottom-color: var(--primary)
}

/* Citatet bruger samme hårlinje-sprog som resten af siden (2px felt-streg
   over) frem for den sædvanlige farvede venstrekant — så læser det som en
   del af systemet og ikke som en indsat widget. */
.om-citat {
  margin: 30px 0 0;
  padding-top: 22px;
  border-top: 2px solid var(--felt)
}

.om-citat .u-eyebrow {
  color: var(--primary);
  display: block;
  margin-bottom: 13px
}

.om-citat p {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(19px, 2.2vw, 25px);
  line-height: 1.26;
  letter-spacing: -.038em;
  color: var(--text);
  margin: 0;
  max-width: 22ch
}

/* ⚠ TILFØJET 21/8: #om-cykeltjek's egen 88px bund-padding (.section) og
   .metode-bånds egen top-padding (clamp(52px,7vw,78px) herunder) lagde sig
   oven i hinanden til op mod 166px ren luft mellem "Prishistorik siden" og
   "SÅDAN GØR VI" — nøjagtig samme fejlklasse som .newsletter-fixet
   dokumenterer ovenfor i filen (to sektioners padding der stables i stedet
   for at dele ét mellemrum). Kun bunden af #om-cykeltjek er reduceret;
   toppen (mod pille-listen ovenfor) er urørt, og .metode-bånds egen
   top-padding er urørt, da den også skal bære en synlig grænse alene når
   båndet ikke ligger efter #om-cykeltjek (fx hvis rækkefølgen ændres). */
#om-cykeltjek {
  padding-bottom: 48px
}

/* .metode-bånds egen top-padding (op til 78px) lægger sig oven i
   #om-cykeltjeks bund og gav stadig ~126px tilsammen efter rettelsen
   ovenfor. Scopet til lige netop denne rækkefølge (adjacent sibling), ikke
   .metode-band generelt — båndet skal beholde sin fulde top-padding, hvis
   det nogensinde står et andet sted uden en sektion lige før. */
#om-cykeltjek+.metode-band {
  padding-top: clamp(32px, 4vw, 48px)
}

/* ══════════════════════════════════════════════════════════════════════
   METODE-BÅND — bogbinder siden sammen med hero'en
   ══════════════════════════════════════════════════════════════════════ */
.metode-band {
  position: relative;
  background: var(--felt);
  background-image: radial-gradient(120% 130% at 82% 0%, var(--felt-lift) 0%, var(--felt) 46%, var(--felt-dyb) 100%);
  color: var(--paa-felt);
  border-top: 1px solid var(--felt-linje-kraftig);
  padding: clamp(52px, 7vw, 78px) 0 clamp(44px, 6vw, 64px);
  overflow: hidden
}

.metode-head {
  margin-bottom: clamp(34px, 4.5vw, 48px);
  max-width: 46ch
}

.metode-head .u-eyebrow {
  color: var(--trust-paa-felt);
  display: block;
  margin-bottom: 14px
}

.metode-head h2 {
  font-family: var(--font-display);
  font-size: clamp(25px, 3.4vw, 36px);
  font-weight: 800;
  letter-spacing: -.035em;
  color: var(--paa-felt)
}

/* ⚠ TILFØJET 21/8: sætningen brækkede over to linjer på desktop, fordi
   .metode-head's max-width: 46ch (46 tegn) er tættere på sætningens egen
   længde end det ser ud til — clamp()'ens variable font-size gør bruddet
   uforudsigeligt alt efter viewport. Kun låst på desktop (samme
   860px-grænse som resten af metode-båndets layout skifter ved); på mobil
   skal linjen fortsat kunne bryde naturligt, for der er ikke plads til den
   i én linje uden at skalere teksten helt ned. */
@media (min-width: 861px) {
  .metode-head h2 {
    white-space: nowrap
  }
}

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

.metode-band .metode-trin {
  padding: 26px 30px 0 0;
  border-top: 1px solid var(--felt-linje-kraftig)
}

.metode-band .metode-trin+.metode-trin {
  padding-left: 30px;
  border-left: 1px solid var(--felt-linje)
}

.metode-nr {
  font-family: var(--font-data);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: .14em;
  color: var(--primary-paa-felt);
  display: block;
  margin-bottom: 18px
}

.metode-band .metode-trin h3 {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 800;
  margin-bottom: 7px;
  letter-spacing: -.03em;
  color: var(--paa-felt)
}

.metode-band .metode-trin p {
  color: var(--paa-felt-dim);
  font-size: 14.5px
}

/* De tre diagrammer. Trin 02 er den vigtigste: den tegner Omnibus-reglen
   — én måling pr. nat, og den laveste i vinduet markeret i rav. */
.metode-fig {
  width: 100%;
  height: auto;
  margin-bottom: 20px
}

.mf-linje {
  stroke: var(--trust-paa-felt);
  stroke-width: 1.3;
  fill: none
}

.mf-svag {
  stroke: rgba(148, 166, 178, .42);
  stroke-width: 1.1;
  fill: none
}

.mf-prik {
  fill: var(--trust-paa-felt)
}

.mf-boks {
  stroke: var(--trust-paa-felt);
  stroke-width: 1.5;
  fill: none
}

.mf-rav {
  fill: var(--primary-paa-felt)
}

.mf-rav-l {
  stroke: var(--primary-paa-felt);
  stroke-width: 1.4;
  fill: none
}

.mf-rav-stiplet {
  stroke: var(--primary-paa-felt);
  stroke-width: 1.2;
  fill: none;
  stroke-dasharray: 3 3
}

.mf-tekst {
  fill: var(--primary-paa-felt);
  font-family: var(--font-data);
  font-size: 8.5px;
  letter-spacing: .08em
}

/* ⚠ TILFØJET 21/8: "Hurtige fakta"-listen, flyttet ind fra den nu slettede
   /sadan-finder-vi-priserne. Egen linje under de tre trin, ikke en fjerde
   kolonne — det er tre løse fakta, ikke et fjerde trin i processen. */
.metode-fakta {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 10px 32px;
  margin: 30px 0 0;
  padding: 22px 0 0;
  border-top: 1px solid var(--felt-linje)
}

.metode-fakta li {
  position: relative;
  padding-left: 16px;
  color: var(--paa-felt-dim);
  font-size: 14px
}

.metode-fakta li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 8px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--primary-paa-felt)
}

@media (max-width: 860px) {
  .om {
    grid-template-columns: minmax(0, 1fr);
    gap: 22px
  }

  .metode-band .metode {
    grid-template-columns: minmax(0, 1fr)
  }

  .metode-band .metode-trin {
    padding: 24px 0 0
  }

  .metode-band .metode-trin+.metode-trin {
    padding-left: 0;
    border-left: 0
  }

  .metode-fig {
    max-width: 260px
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   MOBILVISNING — app-skal (bundnavigation, søgeoverlay, guides-liste)
   ═══════════════════════════════════════════════════════════════════════
   Tilføjet 21/8 ved implementering af mobilapp-mockuppen
   ("Cykeltjek App.dc.html"). Ingen af disse regler rører desktop —
   alt er inde i @media (max-width: 768px), sitets etablerede
   mobil-brydepunkt for komponentniveau (adskilt fra hovednavigationens
   1080px hamburger-brydepunkt, som er urørt).
   ═══════════════════════════════════════════════════════════════════════ */

/* ⚠ TILFØJET 22/8: .app-tabbar var kun stylet INDE i @media (max-width:
   768px) — position:fixed, flex osv. Uden en modsvarende default var
   markuppen (app-tabbar.php, inkluderet af footer.php på alle fire
   app-faner) et helt almindeligt, ustylet <nav> på desktop-bredde: en rå
   tekstliste af links nederst på siden, under footeren. Fundet ved at
   scrolle helt ned på /favoritter og /guides i 800px bredde. Skjules nu
   som standard; media queryen nedenfor slår den til igen ≤768px. */
.app-tabbar {
  display: none;
}

@media (max-width: 768px) {

  /* ── Headeren skjules helt på mobil, sitewide ──
     Efter ønske (21/8) — bundnavigationen (app-tabbar.php, lige
     nedenfor) overtager Hjem/Tilbud/Favoritter/Guides, så det øverste
     bånd (logo, hovednavigation, søgefelt, hamburgermenu) er
     overflødigt på ≤768px. Et evt. .campaign-banner ligger UDENFOR
     .site-header i header.php og forbliver derfor synligt.
     ⚠ #headerSearch (søgeoverlayets felt) er dermed også skjult, og
     uden en synlig knap et andet sted er søgning ikke tilgængelig fra
     mobilvisningen længere — søgeoverlayet (sog-overlay.js) findes
     stadig i DOM'en, men har ingen udløser tilbage. Ingen ny udløser
     tilføjet her; det var ikke en del af det bedte. */
  .site-header {
    display: none;
  }

  /* ── Disclosure-baren skjules KUN visuelt på mobil, IKKE fjernet ──
     Efter ønske (21/8) — men den er lovpligtig (markedsføringsloven
     §5-6) og "vises UBETINGET" ifølge sin egen begrundelse i header.php.
     display:none her betyder den forbliver i DOM'en og vises fortsat på
     desktop; loven overholdes stadig, kun ≤768px mister den visuelt.
     ⚠ Slet ALDRIG selve elementet fra header.php for at "rydde op" —
     det ville fjerne oplysningen fra HELE sitet, ikke kun mobil. */
  .disclosure-bar {
    display: none;
  }

  /* ── Bundnavigation ── app-tabbar.php. Under filterskuffens z-index:200
     (cykler.css) — skuffen skal fortsat kunne lægge sig ovenpå. */
  .app-tabbar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 150;
    display: flex;
    background: var(--surface);
    border-top: 1px solid var(--border-soft);
    padding-bottom: env(safe-area-inset-bottom);
  }

  .app-tabbar__item {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    padding: 10px 0 12px;
    font-size: 11px;
    font-weight: 600;
    color: var(--muted);
    text-decoration: none;
    min-height: 44px;
  }

  /* ⚠ Var var(--primary) (sitets røde --cta) — mockuppens rav/rust
     (var(--rust)), samme accent som resten af forsidens mobilredesign
     (badges, "Se cykel", "Se alle" osv.). Tabbaren er delt på tværs af
     alle fire app-faner (Hjem/Tilbud/Favoritter/Guides), så farven sættes
     her uden .forside-mobil-scope, med vilje — en aktiv fane der skiftede
     farve alt efter hvilken side man stod på, ville se ude af trit ud. */
  .app-tabbar__item[aria-current="page"] {
    color: var(--rust);
  }

  /* Reserverer bundplads så bundbjælken ikke dækker sidste indhold/footer.
     :has() undgår en betinget body-klasse — virker kun for sider der rent
     faktisk inkluderer .app-tabbar (produktsiden gør ikke, se dens egen
     sticky-CTA-regel i produkt.css). */
  body:has(.app-tabbar) {
    padding-bottom: calc(58px + env(safe-area-inset-bottom));
  }

  /* Footeren skal ikke kunne dukke op midt i det første skærmbillede.
     Ramte /favoritter hårdt: tom-tilstanden (eller 1-2 gemte kort) er så
     kort at footeren startede lige under den, med bundmenuen flydende
     oven på — content og footer blandet sammen på én skærm. At løse det
     ved at have "nok" indhold er ikke en løsning (en tom liste er en
     helt legitim tilstand). I stedet: hovedindholdet fylder MINDST resten
     af viewporten (minus bundmenuens egen højde), så footeren først kan
     komme i spil når man rent faktisk scroller forbi det første
     skærmbillede — uanset hvor lidt indhold siden har. Gælder alle fire
     app-faner (samme :has()-afgrænsning som padding-bottom ovenfor), ikke
     kun /favoritter, så det samme ikke kan ske på fx en tom /guides. */
  body:has(.app-tabbar) main#hovedindhold {
    min-height: calc(100dvh - 58px - env(safe-area-inset-bottom));
  }

  /* Favoritters bulk-redigeringsbjælke erstatter tabbaren midlertidigt —
     de to må aldrig stables (to faste bundbjælker på en lille skærm). */
  body:has(.fav-bulk-bar.is-open) .app-tabbar {
    display: none;
  }

  /* ⚠ Footer fjernet fra /favoritter og /guides på mobil, efter ønske —
     samme rettelse som /tilbud (cykler.css, body:has(.tilbud-layout)).
     .fav-mobil/.guides-mobil findes kun i hhv. favoritter.php og
     guides.php's <main>, så forsiden er urørt (den har sin egen
     .forside-mobil, ikke disse to). app-tabbar.php er IKKE en del af
     .site-footer og forsvinder derfor ikke med — bundnavigationen
     fungerer stadig. */
  body:has(.fav-mobil) .site-footer,
  body:has(.guides-mobil) .site-footer {
    display: none;
  }

  /* ── Edge-to-edge på de fire app-sider ──
     Efter ønske (22/8). .container's faste 28px sidepolstring (56px
     spildt bredde i alt på en 375px skærm) var sat for HELE sitet og
     ramte disse fire sider lige så hårdt som forsiden — men her, hvor
     hvert kort/hver linje allerede har sin egen indre luft (kort-
     polstring, tabelceller), var den ydre polstring ren dobbeltluft.
     Halveret til 14px, ikke fjernet helt: ren 0px ville lade tekst
     (overskrifter, "Ingen favoritter endnu") støde direkte mod
     skærmkanten, hvilket ikke er "edge-to-edge" i god forstand, kun
     ulæseligt. Scopet til de fire sideklasser — .container i sig selv
     er urørt og beholder 28px alle andre steder (forsiden, /om-os,
     osv.). */
  .tilbud-layout.container,
  .fav-mobil.container,
  .guides-mobil.container,
  .pd-mobil.container {
    padding-left: 14px;
    padding-right: 14px;
  }

  /* ⚠ FORSIDEN — MOBIL (22/8): det gamle desktop-layout (hero, mosaik,
     Om, Metoden) skjules PÅ MOBIL ALENE, erstattet af .hjem-mobil
     (views/index.php, vist længere nede i denne fil). .forside-mobil på
     desktopbredde er urørt og viser stadig hele siden uændret.

     ⚠ #tilbud ER BEVIDST IKKE i denne liste. Mockuppens "Tilbud lige
     nu"-sektion genbruger SAMME data/kategori-rækker som desktop
     (renderDeals()/SSR-faldet) — kun ny overskrift, se
     .hjem-mobil-tilbud-head og .deals-hero__box's mobilregel nedenfor.
     Føjer du flere sektioner til .forside-mobil, som mobilvisningen
     IKKE skal genbruge: læg dem til listen her, ikke i en blanket
     ">*"-regel — den slog #tilbud ihjel indtil denne rettelse. */
  .forside-mobil>.hero-kat,
  .forside-mobil>.udforsk-section,
  .forside-mobil>#om-cykeltjek,
  .forside-mobil>.metode-band {
    display: none;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   HJEM — MOBILVISNING (22/8)
   ═══════════════════════════════════════════════════════════════════════
   Bygget fra bunden efter "Implementeringsguide - Hjem mobil" + et
   vedhæftet billede (mockup). Alt herunder er skjult som standard og kun
   vist ≤768px (samme mønster som .app-tabbar ovenfor i filen) — desktop
   rører intet af dette.
   ═══════════════════════════════════════════════════════════════════════ */
.hjem-mobil,
.hjem-mobil-tilbud-head,
.deal-kategori-link-mobil {
  display: none;
}

@media (max-width: 768px) {

  /* ── Guidens "Farver": #DDD8CE uden for kortet, #FBF7EF som
     kortbaggrund (gentaget under "Overordnet kort") ── Manglede helt
     indtil nu; siden brugte sitets almindelige --bg/--bg-2 (grå), ikke
     mockuppens varme cream-toner.
     ⚠ RETTET: gjaldt kun forsiden — /tilbud, /favoritter, /guides og
     produktsiden brugte stadig den gamle grå --bg, efter ønske udvidet
     til alle fem app-sider. body:has() scoper det til netop disse fem
     <main>-klasser (samme mønster som body:has(.app-tabbar) ovenfor) —
     admin, /om-os osv. er urørt.
     ⚠ Kun main'en selv får kort-farven her (#FBF7EF) — .hjem-mobil og
     #tilbud nedenfor SKAL matche den eksplicit på forsiden, ellers viser
     deres egen (nu forkerte) --bg-2 igennem oven på main'ens baggrund. */
  body:has(.forside-mobil, .tilbud-layout, .fav-mobil, .guides-mobil, .pd-mobil) {
    background: #DDD8CE;
  }

  main.forside-mobil,
  main.tilbud-layout,
  main.fav-mobil,
  main.guides-mobil,
  main.pd-mobil {
    width: 100%;
    max-width: 420px;
    margin: 0 auto;
    background: #FBF7EF;
  }

  /* "Overordnet kort": radius 28px, skygge, overflow hidden — men kun når
     der er plads til at se #DDD8CE uden om kortet (guidens egen
     "Yderpadding (desk)"). På en rigtig telefon (≤420px) fylder kortet
     hele skærmen, og en rundet top ville klippe et synligt trekantshjørne
     af cream oven på et ellers helt almindeligt websted — det er
     mockup-værktøjets eget preview-fif, ikke noget en rigtig besøgende
     skal se på deres egen skærm. */
  @media (min-width: 421px) {

    main.forside-mobil,
    main.tilbud-layout,
    main.fav-mobil,
    main.guides-mobil,
    main.pd-mobil {
      margin-block: 32px;
      border-radius: 28px;
      overflow: hidden;
      box-shadow: 0 30px 60px rgba(0, 0, 0, .18);
    }
  }

  /* ⚠ background: #FBF7EF — var var(--bg-2) (sitets grå), efter ønske
     erstattet med guidens kortfarve, se blokken lige ovenfor.
     ⚠ padding-bottom: 12px, IKKE 0 — uden en bundpolstring her collapser
     .hjem-mobil-mosaik's eget margin-bottom (12px) IGENNEM .hjem-mobils
     kant og lander uden for dens baggrund, som en synlig lysere stribe
     (sidens --bg) lige før #tilbud's mørkere --bg-2 begynder. En
     ikke-nul padding-bottom stopper collapset. */
  .hjem-mobil {
    display: block;
    padding: 20px 14px 12px;
    background: #FBF7EF;
  }

  /* ── Topbar: ordmærke + søge-/favoritikon ── */
  .hjem-mobil-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 12px;
  }

  .hjem-mobil-logo {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-family: var(--font-display);
    font-size: 20px;
    font-weight: 800;
    letter-spacing: -.02em;
    color: var(--text);
  }

  /* Cykel-ikonet — samme rav-farve som "Tjek" (nedenfor). Header-baren
     står på LYS baggrund (i modsætning til footeren, som er mørk), så
     den lyse-baggrunds rav-hex (#8B4C06, samme som kategori-fliserne)
     bruges her, IKKE footerens mørke-baggrunds-variant (#E89832). */
  .hjem-mobil-logo svg {
    color: #8B4C06;
    flex-shrink: 0;
  }

  .hjem-mobil-logo strong {
    color: #8B4C06;
    font-weight: 800;
  }

  .hjem-mobil-ikoner {
    display: flex;
    align-items: center;
    gap: 8px;
  }

  .hjem-mobil-ikon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    border: none;
    background: transparent;
    color: var(--text);
    padding: 0;
  }

  .hjem-mobil-ikon svg {
    width: 20px;
    height: 20px;
  }

  /* ── Søgebar, foldet ud fra søgeikonet (setupHjemMobilSoeg(), script.js) ──
     Samme visuelle princip som /tilbud's titlebar-søgning (cykler.css,
     .tilbud-titlebar-search) — pilleformet felt, søgeikon inde i højre
     kant. [hidden] styrer synligheden (sat/fjernet i JS), ikke display
     her, så attributten er den ene sandhedskilde. */
  .hjem-mobil-soeg {
    position: relative;
    margin-bottom: 16px;
  }

  /* ⚠ padding-right var 40px (plads til forstørrelsesglas-knappen, nu
     fjernet efter ønske, se index.php) — ensartet 14px hele vejen rundt. */
  .hjem-mobil-soeg input {
    appearance: none;
    -webkit-appearance: none;
    width: 100%;
    border: 1.5px solid var(--text);
    border-radius: 999px;
    background: var(--bg);
    color: var(--text);
    font-family: inherit;
    font-size: 13px;
    padding: 9px 14px;
  }

  .hjem-mobil-soeg input::placeholder {
    color: var(--muted);
  }

  .hjem-mobil-soeg input:focus {
    outline: none;
    border-color: var(--rust);
  }

  /* ── Hero-tekst — mørkt felt, som guidens "Implementeringsguide" og som
     desktoppens .hero-kat (samme --felt/--text-gradient, se linje 3396).
     Var lys indtil nu (arvede .hjem-mobils cream --bg-2) — det var en
     reel afvigelse fra mockuppen, ikke et bevidst valg (bekræftet med
     Mathias). Bryder ud af .hjem-mobils 14px sidepolstring med
     negative margins, samme mønster som .hjem-mobil-tilbud-head. */
  .hjem-mobil-hero {
    position: relative;
    overflow: hidden;
    margin: 0 -14px 24px;
    padding: 26px 18px 22px;
    background: linear-gradient(160deg, var(--felt) 0%, var(--text) 70%);
  }

  /* Glow-cirkel, øverst til højre — samme rav-farve som accenten
     herunder, blot meget lav opacitet. Rent dekorativt: aria-hidden ville
     være overkill her, den ligger bag al tekst (z-index) og læses aldrig
     af en skærmlæser i forvejen. */
  .hjem-mobil-hero::before {
    content: '';
    position: absolute;
    top: -30px;
    right: -40px;
    width: 200px;
    height: 200px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(156, 91, 66, .35) 0%, transparent 70%);
    pointer-events: none;
  }

  .hjem-mobil-hero>* {
    position: relative;
  }

  .hjem-mobil-eyebrow {
    display: block;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: #C08260;
    margin-bottom: 3px;
  }

  .hjem-mobil-titel {
    font-family: var(--font-display);
    font-size: 30px;
    font-weight: 800;
    letter-spacing: -.03em;
    line-height: 1.1;
    color: var(--paa-felt);
    margin: 0 0 3px;
  }

  .hjem-mobil-titel .accent {
    color: #C08260;
  }

  .hjem-mobil-tagline {
    font-size: 12.5px;
    color: var(--paa-felt-dim);
    margin: 0;
  }

  /* ── Kategori-mosaik: 2 kolonner, ensartet størrelse ──
     .cat-card/.cat-count[data-kat] er GENBRUGT (ikke nye klasser) — se
     docblokken i index.php: renderKategoriAntal() (script.js) slår op på
     dem uanset markup, og skjuler en flise (kort.hidden) hvis
     kategorien reelt er tom. */
  /* ⚠ RETTET 22/8: var 32px — #tilbud's egen skillelinje
     (.section-alt's border-top) sad dermed langt fra mosaikken, med et
     stort tomt felt mellem Børnecykel/El-løbehjul-rækken og linjen.
     Sænket, så linjen ligger lige under rækken, efter ønske. */
  /* ⚠ margin-bottom FJERNET 22/8 — flyttet til .hjem-mobils egen
     padding-bottom (se ovenfor) for at undgå margin-collapse gennem
     .hjem-mobils kant. Sæt IKKE et margin-bottom her igen uden at
     fjerne/justere padding-bottom tilsvarende, ellers dobbelt-tælles
     afstanden. */
  .hjem-mobil-mosaik {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 10px;
  }

  /* ⚠ .hjem-mobil-flise genbruger .cat-card (se index.php's docblok) for
     renderKategoriAntal()'s skyld, ikke for udseendet — .cat-card's egen
     border-top:2px + padding (styles.css:1085) er bygget til et helt
     andet kort (kategorisiden) og gav en vandret streg mellem hver
     flise-række plus skæv højrepolstring, som ikke findes i mockuppen.
     Nulstillet her, scopet til mobilfliserne alene. */
  /* ⚠ RETTET 22/8 (3): erstatter (2)'s udgave — den havde stadig kant +
     skygge på flisen (fra før tinten flyttede hertil) og fotoet gik helt
     ud til kortets egne kanter. Efter ønske, ny spec: INGEN kant/skygge
     på flisen, 8px 8px 0-polstring rundt om fotoet (fotoet er nu et
     indsat billede MED luft til tinten, ikke kant-til-kant), og fotoet
     får sin egen lidt tættere radius (10px mod flisens 16px). */
  .hjem-mobil-flise {
    display: flex;
    flex-direction: column;
    border-top: none;
    border-radius: 16px;
    overflow: hidden;
    padding: 0;
    min-width: 0;
  }

  /* 8 roterende pasteltoner, én pr. flise — efter guidens
     "Kategori-gitter"-tabel. $ckFliserMobil har præcis 8 rækker (samme
     rækkefølge som CSS'en her), så nth-child rammer 1:1 uden et
     data-attribut. Tilføjes der en niende flise, mangler den en farve og
     falder tilbage til var(--foto-flade) (fotoets egen default,
     nedenfor) — ret rækken op til 8 igen, eller udvid listen her.
     ⚠ Sidder nu på HELE flisen (var på fotoet alene), så tonen fortsætter
     ned bag navnet i stedet for at stoppe ved fotoets underkant. */
  .hjem-mobil-flise:nth-child(1) {
    background: #F5E6DA;
  }

  .hjem-mobil-flise:nth-child(2) {
    background: #E7EDE4;
  }

  .hjem-mobil-flise:nth-child(3) {
    background: #F0E4E9;
  }

  .hjem-mobil-flise:nth-child(4) {
    background: #E4E9EC;
  }

  .hjem-mobil-flise:nth-child(5) {
    background: #F6E9DD;
  }

  .hjem-mobil-flise:nth-child(6) {
    background: #E9E6F0;
  }

  .hjem-mobil-flise:nth-child(7) {
    background: #EFE7DA;
  }

  .hjem-mobil-flise:nth-child(8) {
    background: #E3EAE7;
  }

  /* ⚠ RETTET 22/8: var 1/1 (kvadratisk), så aspect-ratio 2/1 — begge dele
     erstattet af en FAST højde efter ønske. Bredden er fri (grid-cellens
     1fr) — på en iOS-ramme (402px, 20px polstring hver side) giver det
     ca. 176×82px pr. flise, på Android (412px) ca. 181×82px.
     object-fit:cover på img'en beskærer det fritlagte foto til den faste
     højde uden at forvrænge det.
     ⚠ RETTET 22/8 (2): fotoets egen radius/kant/margin er væk — flisens
     overflow:hidden (ovenfor) klipper nu billedet ind i kortets fælles
     hjørner i stedet, så foto og navn deler ÉN ramme uden en synlig
     kant midt i flisen. background: var(--foto-flade) er kun et
     nødfald hvis $ckFliserMobil nogensinde får en niende flise uden en
     tilsvarende nth-child-farve ovenfor. */
  /* ⚠ RETTET 22/8 (3): 82px -> 112px og fik sin egen 10px-radius, efter
     ønske — fotoet er nu et INDSAT billede (flisens 8px 8px 0-polstring
     ovenfor giver luften), ikke længere kant-til-kant med flisen. */
  .hjem-mobil-pic {
    display: block;
    aspect-ratio: 4/3;
    width: 100%;
    background: transparent;
    overflow: hidden;
    margin: 0;
  }

  .hjem-mobil-pic img {
    width: 100%;
    max-width: 100%;
    height: 100%;
    object-fit: contain;
    object-position: bottom right;
  }

  /* ⚠ RETTET 22/8 (5): var padding-top 5px — stadig synlig luft mellem
     foto og navn (efter ønske, "op på eller over" en stiplet linje tegnet
     lige under fotoet). Sat til 0 — .hjem-mobil-flise-foto (ovenfor)
     ender kant-til-kant med navnet nu, ingen ekstra afstand tilføjes her. */
  /* ⚠ Selektoren SKAL være ".hjem-mobil-flise .hjem-mobil-flise-navn"
     (to klasser), ikke bare ".hjem-mobil-flise-navn" alene — den generiske
     ".cat-card span { color: var(--faint) }" (styles.css:1121, bygget til
     et helt andet kort) har højere specificitet end én klasse og vandt
     tavst over sort tekst her, selvom farven i koden så rigtig ud. */
  .hjem-mobil-flise .hjem-mobil-flise-navn {
    display: block;
    font-family: var(--font-body);
    font-size: 13.5px;
    font-weight: 700;
    color: #201E1D;
    line-height: 1.2;
    padding: 4px 12px 14px;
  }

  /* ⚠ Skjult efter ønske (22/8) — mockuppen viser intet antal under
     flisenavnet. Elementet selv SKAL BLIVE i markuppen (index.php):
     renderKategoriAntal() (script.js) bruger .cat-count[data-kat] til at
     SKJULE HELE FLISEN hvis kategorien reelt er tom (kort.hidden = true)
     — den sikkerhedsnet-logik kører stadig, kun teksten er usynlig. */
  .hjem-mobil-flise-antal {
    display: none;
  }

  /* ── "Tilbud lige nu" — erstatter .deals-hero__box's overskrift ──
     Boksen selv ("Sådan ser priserne ud lige nu") skjules herunder;
     rækkerne den ellers omslutter (.deals-hero__row + efterfølgende
     .deal-kategori) er URØRTE og vises som normalt, bare under denne
     nye, enklere overskrift. */
  /* ⚠ RETTET 22/8: var padding:0 14px — .deals-section har allerede sin
     egen 14px sidepolstring (se nedenfor), så de to lagde oveni
     hinanden og gav 28px i alt, mere end resten af mobilvisningens
     14px. Overskriften stod dermed rykket længere ind end mosaikken. */
  /* ⚠ RETTET 22/8: linjen matchede ikke linjen ovenfor (mosaik/#tilbud) —
     den er #tilbud's egen border-top, kant-til-kant på HELE sektionen,
     mens denne sad inde i .deals-section's 14px sidepolstring og derfor
     var indrykket. margin-inline:-14px bryder boksen ud til samme
     kant-til-kant bredde; padding-inline:14px holder selve teksten
     (h2/linket) på nøjagtig samme plads som før. */
  /* ⚠ Var udbrudt med margin-inline:-14px + padding-inline:14px for at give
     border-bottom'en (nu fjernet) fuld kant-til-kant-bredde. Uden en linje
     at brede ud er tricket overflødigt — .deals-section's egen 14px
     sidepolstring er nok i sig selv. */
  /* ⚠ RETTET: var padding-bottom 8px + margin-bottom 10px — efter ønske
     ("meget luft" mellem "Tilbud lige nu" og "Elcykler") strammet til 2px
     hver. Størstedelen af den oplevede luft var slet ikke margin/padding,
     men h2'ens ARVEDE line-height:1.65 (body, styles.css:197) — 17px×1.65
     ≈ 28px linjehøjde, hvoraf det meste stod som usynlig plads UNDER
     bogstaverne. line-height:1.15 herunder fjerner den. */
  /* ⚠ RETTET: "Se alle →" er fjernet fra rækken (index.php) — justify-
     content:space-between havde intet at spredes imod uden det andet
     flex-barn og efterlod overskriften venstrestillet. text-align:center
     erstatter den, efter ønske. */
  .hjem-mobil-tilbud-head {
    display: flex;
    align-items: baseline;
    justify-content: center;
    text-align: center;
    gap: 12px;
    padding: 0 0 2px;
    margin-bottom: 2px;
  }

  .hjem-mobil-tilbud-head h2 {
    font-family: var(--font-display);
    font-size: 17px;
    font-weight: 700;
    line-height: 1.15;
    color: var(--text);
  }

  /* .deals-section's egen padding (clamp(24px,4vw,40px), styles.css)
     lander på 24px ved denne bredde — for meget luft i forhold til
     resten af mobilvisningens 14px. Matcher .hjem-mobil-tilbud-head's
     egen 14px sidepolstring ovenfor, så overskrift og kort-rækker flugter
     lodret. */
  .forside-mobil .deals-section {
    padding-inline: 14px;
  }

  /* Den mørke "Sådan ser priserne ud lige nu"-boks er desktop-chrome —
     .hjem-mobil-tilbud-head ovenfor erstatter den på mobil. Selve
     rækken (.deals-hero__row) og alle efterfølgende .deal-kategori
     forbliver synlige og urørte. */
  .forside-mobil .deals-hero__box {
    display: none;
  }

  /* ⚠ FUNDET: "der er stadig stort mellemrum" mellem FØRSTE kategori
     (Elcykler) og NÆSTE (Racercykler) — kun mellem de to, ikke resten.
     Årsagen var usynlig i markeringen: kun Elcykler-rækken ligger inde i
     .deals-hero (styles.css:3993, margin-bottom:40px), fordi den — før
     boksen ovenfor blev skjult — skulle stå ved siden af den. De
     efterfølgende kategorier er almindelige søskende af #dealGrid'et uden
     den ekstra margin. 40px + .deal-kategori's egen 20px (ovenfor) gav
     60px, dobbelt så meget som mellem de øvrige rækker. */
  .forside-mobil .deals-hero {
    margin-bottom: 0;
  }

  /* ⚠ #tilbud er en .section-alt (styles.css:922) — .section's egen 60px
     toppolstring (styles.css:3208) skubbede "Tilbud lige nu" langt væk fra
     mosaikken, så der stod et stort tomt felt mellem dem. Efter ønske:
     toppolstringen sænket, kun for forsiden på mobil. Bundpolstringen er
     urørt.
     ⚠ background: #FBF7EF — .section-alt's egen var(--bg-2) (grå) gjorde
     denne sektion synligt mørkere end mosaikken ovenfor, hvor begge nu
     skal være ÉN flad kortfarve (guidens "Farver", se main.forside-mobil
     ovenfor).
     ⚠ border-top/-bottom: none — .section-alt's to linjer (styles.css:922)
     indrammede "Tilbud lige nu" som en boks, efter ønske fjernet. Kun
     scopet til forsidens mobilvisning; /tilbud m.fl. bruger ikke #tilbud
     og er urørt. */
  .forside-mobil #tilbud {
    padding-top: 8px;
    background: #FBF7EF;
    border-top: none;
    border-bottom: none;
  }

  /* ── "Tilbud lige nu"-kortene — nyt kortdesign (build spec, 22/8) ──
     Erstatter den tidligere udgave (kopi af /tilbud's mobilkort). Kan
     ikke genbruge SELEKTOREN direkte: cykler.css loades kun på
     views/cykler.php (invariant 11, CLAUDE.md), så #dealGrid får sit eget
     sæt regler her i den delte fil, ID-scopet så det vinder over både
     .product-card's almindelige regler OG .deal-kategori-scroll .deal-card
     (styles.css:3151, ≤680px, class+class — taber til #dealGrid uanset
     kildeorden). */
  #dealGrid .deal-kategori-scroll {
    gap: 12px;
  }

  #dealGrid .deal-card {
    flex: 0 0 160px;
  }

  #dealGrid .product-card {
    width: 160px;
    background: #FFFFFF;
    border: 1px solid rgba(32, 30, 29, .08);
    border-radius: 16px;
    box-shadow: none;
  }

  #dealGrid .product-card:hover {
    box-shadow: none;
    transform: none;
  }

  /* Fast billedhøjde + cover — var aspect-ratio:4/3 + object-fit:contain
     (.product-img/.product-photo, styles.css). "Cover" beskærer i stedet
     for at vise hele cyklen med luft i siderne, efter ønske (build spec). */
  #dealGrid .product-img {
    aspect-ratio: auto;
    height: 110px;
  }

  #dealGrid .product-photo {
    object-fit: cover;
  }

  /* Hjertet var 34×34px/top:10/right:10 (.fav-heart, styles.css) — mindre
     og tættere på hjørnet efter build spec, med en helt hvid (ikke
     temafarvet) baggrund, da kortet altid er hvidt her. */
  #dealGrid .fav-heart {
    width: 26px;
    height: 26px;
    top: 8px;
    right: 8px;
    background: rgba(255, 255, 255, .9);
    border: none;
    box-shadow: none;
    backdrop-filter: none;
  }

  #dealGrid .fav-heart svg {
    width: 13px;
    height: 13px;
  }

  #dealGrid .product-body {
    padding: 10px 11px 12px;
    gap: 5px;
  }

  /* Farverne er guidens "Kategori-badge"-række (var(--rust) på #F3E3DB) —
     var indtil nu sitets neutrale --text/--surface-alt. */
  #dealGrid .product-kategori-tag {
    display: inline-block;
    align-self: flex-start;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--rust);
    background: #F3E3DB;
    border: none;
    border-radius: 6px;
    padding: 2px 7px;
    margin-bottom: 0;
  }

  /* ⚠ Var display:none — build spec viser nu forhandlernavnet igen
     (11.5px, dæmpet), modsat den tidligere version der skjulte det til
     fordel for kategori-badgen alene. */
  #dealGrid .product-retailer {
    display: block;
    font-size: 11.5px;
    text-transform: none;
    letter-spacing: normal;
    color: #8A8580;
    font-weight: 400;
  }

  #dealGrid .product-title {
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1.25;
    color: #201E1D;
    min-height: 0;
  }

  #dealGrid .product-price-row {
    padding-top: 0;
  }

  #dealGrid .product-price {
    font-size: 15px;
    font-weight: 700;
    color: #201E1D;
  }

  /* "Se cykel"-knappen er ellers sitets røde --cta (.btn-primary), smal og
     venstrestillet (.product-card .product-se-knap, styles.css) — guidens
     knap er rav/rust (var(--rust), hover var(--rust-deep)), fuld bredde og
     centreret tekst, scopet til forsidens mobil-deal-kort alene. */
  #dealGrid .product-se-knap {
    align-self: stretch;
    width: 100%;
    justify-content: center;
    padding: 8px 0;
    font-size: 12.5px;
    border-radius: 10px;
    background: var(--rust);
    box-shadow: none;
  }

  #dealGrid .product-se-knap:hover {
    background: var(--rust-deep);
  }

  /* ── Kategori-rækkens "Se alle" flyttet ind i overskriften ──
     Efter ønske: produktantallet (.cat-count) og den fulde
     "Se alle X →" (til højre i .deal-kategori-head) skjules på mobil;
     en kompakt "Se alle →" (.deal-kategori-link-mobil, index.php/
     script.js) er allerede placeret INDE i h3'en og vises i stedet —
     se dens egen docblok for hvorfor den sidder der og ikke bare er en
     tekstændring af det eksisterende link. */
  #dealGrid .cat-count {
    display: none;
  }

  #dealGrid .deal-kategori-link {
    display: none;
  }

  /* ⚠ RETTET: "Se alle →" sad klistret op ad kategorinavnet (inline midt i
     h3'en), efter ønske tilbage til højre kant — samme placering som
     desktoppens .deal-kategori-link (invariant: begge er "til højre i
     .deal-kategori-head"). Linket er stadig INDE i h3'en (se dens egen
     docblok for hvorfor), så h3 gøres selv til en flex-række der spreder
     kategorinavnet og linket til hver sin side; .deal-kategori-head's egen
     flex/space-between rammer intet her, da h3 er dens eneste synlige
     barn på mobil (.cat-count og desktop-linket er begge skjult ovenfor). */
  #dealGrid .deal-kategori-head h3 {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    /* h3 er .deal-kategori-head's ENESTE synlige flex-barn på mobil (se
       ovenfor), og et flex-barn uden flex-grow sizer sig kun til sit eget
       indhold — uden width:100% var der intet at sprede "Se alle →" ud
       imod, og linket blev stående klistret op ad kategorinavnet. */
    width: 100%;
    /* Samme fund som .hjem-mobil-tilbud-head h2 ovenfor: arvet
       line-height:1.65 (body) gav "Elcykler" en langt højere linjeboks end
       teksten selv fylder, og det læste som ekstra luft over/under
       overskriften. */
    line-height: 1.15;
  }

  /* .deal-kategori-head's almindelige margin-bottom:18px (styles.css:1150)
     er sat til afstanden mellem "Elcykler" og kortene under — for meget
     her efter h3'ens egen linjehøjde blev strammet ovenfor. */
  #dealGrid .deal-kategori-head {
    margin-bottom: 10px;
  }

  /* ⚠ Var 44px (styles.css:1132) / 30px (≤680px, styles.css:3204) — den
     samme "meget luft"-klage som .hjem-mobil-tilbud-head/.deal-kategori-head
     ovenfor, bare mellem HELE kategori-blokke i stedet for inde i én.
     .deal-kategori bruges kun her på forsiden (ingen andre views), så
     #dealGrid-scopet er ren dokumentation af hvor tallet gælder, ikke en
     nødvendig afgrænsning mod andre sider. */
  #dealGrid .deal-kategori {
    margin-bottom: 20px;
  }

  #dealGrid .deal-kategori-link-mobil {
    display: inline-block;
    font-size: 14px;
    font-weight: 600;
    color: var(--rust);
    margin-left: 0;
    white-space: nowrap;
  }

  /* Kønsbadgen ("Dame") på produktkortenes billede — mindre boks og
     runde hjørner, efter ønske. Bevidst afvigelse fra sitets 0px-hjørner
     (Modernist), samme mønster som kategori-pillen/knapperne ovenfor.
     .koen-badge er delt på tværs af ALLE kort (/tilbud, forsiden,
     favoritter) — scopet til mobil alene, desktop beholder 0px. */
  .koen-badge {
    font-size: 9px;
    padding: 2px 6px;
    border-radius: 6px;
  }

  /* "Se hele udvalget →" — lavere og smallere, med runde hjørner, efter
     ønske. width:auto skal slå den globale ".btn { width:100% }"
     (styles.css, ≤680px) — to klasser (0,2,0) vinder over én (0,1,0). */
  .deal-grid-cta .btn {
    width: auto;
    padding: 9px 20px;
    border-radius: 10px;
  }

  /* "Leder du efter tilbehør?" trukket op mod "Se hele udvalget"
     ovenfor og gjort mere kompakt, efter ønske. */
  .kat-sekundaer {
    margin-top: 16px;
    padding-top: 14px;
    gap: 8px;
  }

  .kat-sekundaer-label {
    font-size: 13px;
  }

  .kat-pille-row {
    gap: 8px;
  }

  .kat-pille {
    font-size: 11px;
    padding: 3px 9px;
    border-radius: 20px;
  }

  /* Produktantallet i pillerne skjult efter ønske — samme princip som
     kategori-mosaikkens fliser (index.php/styles.css): selve
     .cat-count-elementet BLIVER i markuppen, kun teksten er usynlig.
     Ingen sikkerhedsnet-logik at bevare her (renderKategoriAntal()'s
     kort.hidden-gren rammer kun .cat-card, som .kat-pille ikke er), men
     samme mønster holdt for konsistens. */
  .kat-pille .cat-count {
    display: none;
  }
}

/* ── Søgeoverlay ──
   #headerSearch (header.php) flyttes visuelt herind ved fokus — SAMME
   element, ikke et duplikat (kun ét #headerSearch må findes i DOM'en).
   z-index:220 — over filterskuffens 200, under cookiebanneret (9999).

   ⚠ RETTET 21/8: manglede en display:none UDEN for mediequeryen. Uden
   den er .search-overlay et helt almindeligt <div>, der falder ned i
   sidens normale flow på skrivebordsbredde — den lå der og var synlig
   under headeren på hver eneste side hele tiden, bare ingen havde testet
   ved en bred viewport siden den blev bygget. Samme fejlklasse som
   .tilbud-chips' tilsvarende rækkefølgeproblem tidligere i sessionen:
   to regler med samme specificitet afgøres af RÆKKEFØLGE, ikke af
   hvilken der sidder i en media query. */
.search-overlay {
  display: none;
}

@media (max-width: 768px) {
  .search-overlay {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 220;
    background: var(--bg);
    overflow-y: auto;
    padding: 16px 20px;
    transform: translateY(100%);
    transition: transform .25s ease;
  }

  .search-overlay.is-open {
    transform: translateY(0);
  }

  .search-overlay.is-open .search {
    display: flex;
  }

  .search-overlay-top {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 18px;
  }

  .search-overlay-top .search {
    flex: 1;
  }

  .search-overlay-luk {
    flex: none;
    font-size: 13px;
    font-weight: 600;
    color: var(--text);
    background: none;
    border: none;
    padding: 8px 4px;
    min-height: 44px;
    cursor: pointer;
  }

  .search-overlay h2 {
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--muted);
    margin: 0 0 6px;
  }

  .search-overlay-forslag {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 13px 2px;
    border-bottom: 1px solid var(--border-soft);
    color: var(--text);
    min-height: 44px;
  }

  .search-overlay-forslag svg {
    flex: none;
    opacity: .6;
  }
}

@media (prefers-reduced-motion: reduce) {
  .search-overlay {
    transition: none;
  }
}

/* ── Guides — flush-left rækkeliste ──
   Ny, dedikeret ≤768px-blok, tilføjet EFTER de eksisterende 920px/680px-
   blokke (rører dem ikke) — vinder derfor over begge i hele 0-768px-
   intervallet ved samme specificitet. Samme klassenavne som desktop
   (.guide-card, .guide-tag) — kun layoutet ændres, hverken SSR-loopet
   (guides.php) eller renderGuideKrom() (script.js) skal ændres. */
@media (max-width: 768px) {
  .guide-grid {
    grid-template-columns: 1fr;
    gap: 0;
  }

  /* :not(.guide-fremhaevet) — den fremhævede guide (#guideFeatured) deler
     .guide-card-klassen, men har sit eget, ID-scopede layout (§920px-blok
     ovenfor: flex-direction:column), som fortsat skal vinde. Uden
     undtagelsen ville den fremhævede guide også miste sin baggrund/skygge
     og blive en flush-list-række som resten. */
  .guide-card:not(.guide-fremhaevet) {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 14px;
    background: transparent;
    box-shadow: none;
    border-bottom: 1px solid var(--border-soft);
    padding: 14px 2px;
  }

  .guide-card:not(.guide-fremhaevet) .guide-img {
    width: 84px;
    height: 84px;
    flex: none;
    margin-bottom: 0;
  }

  .guide-card:not(.guide-fremhaevet) .guide-body {
    padding: 0;
  }

  .guide-card:not(.guide-fremhaevet) .guide-tag {
    margin-bottom: 6px;
  }
}

/* ── Udforsk Sektionens Søgebar ── */
.udforsk-search {
  flex-grow: 1;
  max-width: 540px;
  margin-left: 40px;
  margin-right: auto;
}