    /* ========= SHARED CHROME (V7) ========= */
    /* R13: samme kapning som theme.css:8 — denne kopi loades EFTER theme.css og
       ville ellers vinde padding'en tilbage til skærmkanten på shop/PDP/kurv. */
    .topstrip { background: var(--ink); color: var(--snow); padding: 10px max(var(--gutter), calc((100% - var(--content-w)) / 2 + var(--gutter))); font-size: 11.5px; font-weight: 500; letter-spacing: 0.04em; display: flex; justify-content: space-between; align-items: center; }
    .topstrip__pills { display: flex; gap: 28px; }
    .topstrip__pills span { display: inline-flex; align-items: center; gap: 8px; opacity: 0.8; }
    .topstrip__pills .dot { background: var(--cobalt-soft); width: 8px; height: 8px; border-radius: 50%; }
    .topstrip__lang { display: flex; gap: 20px; }
    .topstrip__lang a { opacity: 0.6; }
    .topstrip__lang a[aria-current="true"], .topstrip__lang a:hover { opacity: 1; }

    .nav { background: var(--snow); border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 50; }
    .nav__row { max-width: var(--content-w); margin: 0 auto; padding: 18px var(--gutter); display: grid; grid-template-columns: auto 1fr auto; gap: 48px; align-items: center; }
    .logo__img { height: 44px; width: auto; display: block; }
    .nav__primary { display: flex; gap: 32px; justify-content: center; font-size: 14.5px; font-weight: 500; }
    .nav__primary a { padding: 8px 0; border-bottom: 1.5px solid transparent; }
    .nav__primary a:hover, .nav__primary a[aria-current="page"] { border-color: var(--cobalt); }
    .nav__util { display: flex; gap: 24px; align-items: center; font-size: 14px; }
    .nav__util a { display: inline-flex; align-items: center; gap: 8px; }
    .nav__util .cart { background: var(--ink); color: var(--snow); padding: 10px 18px; border-radius: var(--r-1); font-weight: 500; }
    .nav__util .cart b { font-family: var(--font-mono); font-size: 12px; opacity: 0.8; margin-left: 6px; font-weight: 400; }
    @media (max-width: 1100px) { .nav__row { grid-template-columns: auto auto; } .nav__primary { display: none; } }

    /* ========= CRUMB + PAGE HEAD ========= */
    .page-head { max-width: var(--content-w); margin: 0 auto; padding: 28px var(--gutter) 32px; display: grid; grid-template-columns: 1.4fr 1fr; gap: 64px; align-items: end; }
    .page-head h1 { font-family: var(--font-sans); font-weight: 400; font-size: var(--t-h1); line-height: 0.96; letter-spacing: -0.028em; margin: 16px 0 0; }
    .page-head h1 em { font-style: italic; color: var(--cobalt); }
    .page-head p { color: var(--ink-soft); max-width: 56ch; margin: 16px 0 0; font-size: var(--t-body-l); line-height: 1.5; }
    .page-head__stat { display: flex; flex-direction: column; gap: 4px; text-align: right; }
    .page-head__stat b { font-family: var(--font-sans); font-weight: 500; font-size: 56px; line-height: 1; letter-spacing: -0.025em; }
    .page-head__stat span { font-family: var(--font-mono); font-size: 11px; color: var(--ink-mute); letter-spacing: 0.06em; text-transform: uppercase; }
    @media (max-width: 900px) { .page-head { grid-template-columns: 1fr; gap: 16px; } .page-head__stat { text-align: left; } }

    /* ========= SHELL: FILTERS + CONTENT ========= */
    .shell { max-width: var(--content-w); margin: 0 auto; padding: 0 var(--gutter) var(--s-20); display: grid; grid-template-columns: 280px 1fr; gap: 48px; align-items: start; }
    @media (max-width: 1000px) { .shell { grid-template-columns: 1fr; } }
    /* V-03: 1fr = minmax(auto,1fr), og auto-minimum betyder at et gridspor ikke
       KAN blive smallere end sit bredeste barns min-content. Ét barn med et
       nowrap-flexlayout (fx .pager) trækker derfor hele kolonnen ud over
       viewporten og skubber indholdet ud af skærmen. min-width:0 fjerner
       auto-minimum og gør sporet reelt fleksibelt. Gælder alle .shell-børn,
       så fælden ikke kan komme igen med næste komponent. */
    .shell > * { min-width: 0; }

    /* ========= FILTER RAIL ========= */
    .filters { position: sticky; top: 88px; display: flex; flex-direction: column; gap: 28px; padding-bottom: 32px; }
    /* V-10: under 1000 px er railen en DRAWER, ikke en skjult kolonne.
       display:none er stadig hviletilstanden — men nu findes der en vej tilbage.
       position er BEVIDST ikke sat her: den åbne tilstand skal kunne sætte
       fixed, og en static her ville skulle overskrives af noget stærkere. */
    @media (max-width: 1000px) { .filters { display: none; } }
    .filters__head { display: flex; justify-content: space-between; align-items: center; }
    .filters__head h2 { font-family: var(--font-sans); font-weight: 500; font-size: 18px; margin: 0; }
    .filters__head button { background: 0; border: 0; cursor: pointer; font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-mute); padding: 0; }
    .filters__head button:hover { color: var(--ink); }
    .fg { border-top: 1.5px solid var(--ink); padding-top: 14px; }
    .fg h3 { font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; font-weight: 500; color: var(--ink); margin: 0 0 12px; display: flex; justify-content: space-between; }
    .fg h3 span { color: var(--ink-mute); font-weight: 400; }
    .fg__list { display: flex; flex-direction: column; gap: 8px; }
    .frow { display: flex; align-items: center; gap: 10px; font-size: 13.5px; cursor: pointer; padding: 3px 0; }
    .frow input { appearance: none; width: 14px; height: 14px; border: 1.5px solid var(--ink); border-radius: var(--r-1); cursor: pointer; position: relative; flex-shrink: 0; }
    .frow input:checked { background: var(--cobalt); border-color: var(--cobalt); }
    .frow input:checked::after { content: ""; position: absolute; left: 3px; top: 0; width: 5px; height: 9px; border: solid var(--snow); border-width: 0 1.5px 1.5px 0; transform: rotate(45deg); }
    .frow .ct { margin-left: auto; color: var(--ink-mute); font-family: var(--font-mono); font-size: 11px; }
    .swatches { display: grid; grid-template-columns: repeat(7, 1fr); gap: 8px; }
    .swatch { width: 100%; aspect-ratio: 1; border-radius: 50%; border: 1.5px solid var(--line); cursor: pointer; padding: 0; }
    .swatch[aria-pressed="true"] { outline: 2px solid var(--ink); outline-offset: 2px; }

    /* ========= TOOLBAR ========= */
    .toolbar { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; padding: 14px 16px; background: var(--snow); border: 1.5px solid var(--ink); margin-bottom: 16px; }
    .toolbar__chips { display: flex; gap: 6px; flex-wrap: wrap; flex: 1; }
    .chip-active { display: inline-flex; align-items: center; gap: 6px; padding: 4px 4px 4px 12px; background: var(--cobalt-tint); border: 1px solid var(--cobalt); font-size: 12px; border-radius: var(--r-pill); color: var(--cobalt-deep); }
    .chip-active__x { width: 18px; height: 18px; border-radius: 50%; display: grid; place-items: center; background: var(--cobalt); color: var(--snow); font-size: 11px; cursor: pointer; border: 0; }
    .toolbar .woocommerce-ordering { margin: 0; } /* Pernille 2/9: form-margin skubbede sorteringen ud af linje */
    .toolbar select { height: 32px; padding: 0 28px 0 12px; background: var(--paper); border: 1.5px solid var(--line); font-size: 12px; appearance: none; background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%230D1019' stroke-width='1.5'><path d='m3 5 3 3 3-3'/></svg>"); background-repeat: no-repeat; background-position: right 8px center; background-size: 12px; }
    .density { display: inline-flex; border: 1.5px solid var(--line); overflow: hidden; }
    .density button { background: 0; border: 0; padding: 7px 11px; cursor: pointer; font-size: 12px; color: var(--ink-soft); border-right: 1px solid var(--line); }
    .density button:last-child { border-right: 0; }
    .density button[aria-pressed="true"] { background: var(--ink); color: var(--snow); }

    /* Pr.-side-vælgeren (Pernille 2/9) — samme formsprog som .density. */
    .pp { display: inline-flex; align-items: center; border: 1.5px solid var(--line); overflow: hidden; }
    .pp__lbl { padding: 7px 9px 7px 11px; font-size: 11px; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-soft); border-right: 1px solid var(--line); }
    .pp__opt { padding: 7px 11px; font-size: 12px; color: var(--ink-soft); text-decoration: none; border-right: 1px solid var(--line); }
    .pp__opt:last-child { border-right: 0; }
    .pp__opt.is-active { background: var(--ink); color: var(--snow); }
    @media (max-width: 700px) { .pp__lbl { display: none; } }

    /* ========= PRODUCT GRID ========= */
    .grid { display: grid; gap: 16px 16px; grid-template-columns: repeat(3, 1fr); }
    .grid[data-density="cozy"]  { grid-template-columns: repeat(2, 1fr); gap: 32px 24px; }
    .grid[data-density="dense"] { grid-template-columns: repeat(4, 1fr); gap: 12px 12px; }
    @media (max-width: 700px) { .grid, .grid[data-density="cozy"], .grid[data-density="dense"] { grid-template-columns: 1fr 1fr; } }

    /* Ikke-produkter i søgeresultatet: sider og artikler. De havde INGEN regler
       overhovedet og lå som bar tekst i et gitter fuldt af indrammede kort.
       Det er ikke en sjælden kant: målt 2026-08-02 giver "levering" 6 kort og
       4 rækker, og "engros" giver 10 rækker og nul kort — en hel side uden
       arkiv. De bliver i SAMME gitter (en fuld-bredde-liste ved siden af kort
       ville bryde rækkerne), men de har intet billede, så de arver kortets
       ramme og typografi — ikke dets kvadrat. */
    /* Navigationsstriben over gitteret på søgesiden. Bevidst ÉN linje uden
       rammer om de enkelte links: den skal kunne ses uden at konkurrere med
       kortene, for i 9 ud af 10 søgninger er det stoffet man er kommet efter. */
    .sidehit { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 16px; padding: 11px 16px; margin-bottom: 16px; background: var(--cobalt-tint); border: 1px solid var(--cobalt); }
    .sidehit__lbl { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--cobalt-deep); flex-shrink: 0; }
    .sidehit a { font-size: 13.5px; line-height: 1.35; color: var(--cobalt-deep); text-decoration: none; border-bottom: 1px solid currentColor; }
    .sidehit a:hover { color: var(--ink); }

    .result-row { background: var(--snow); border: 1.5px solid var(--ink); padding: 20px; display: flex; flex-direction: column; gap: 10px; }
    .result-row__type { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-mute); }
    .result-row h3 { font-family: var(--font-sans); font-weight: 500; font-size: 17px; line-height: 1.25; letter-spacing: -0.01em; margin: 0; }
    .result-row h3 a { color: var(--ink); text-decoration: none; }
    .result-row h3 a:hover { color: var(--cobalt); }
    .result-row p { margin: 0; font-size: 13.5px; line-height: 1.5; color: var(--ink-soft); }

    /* Product card — V8 style: square media + unit selector below */
    .pc {
      background: var(--snow);
      border: 1.5px solid var(--ink);
      display: flex; flex-direction: column;
      transition: transform var(--d-med) var(--ease);
      position: relative;
    }
    /* Løftet er en mus-affordance. På touch findes :hover som en "klæbrig"
       tilstand der bliver hængende efter et tap, så kortet står 3px oppe indtil
       man rammer noget andet. (hover: hover) + (pointer: fine) er begge nødvendige:
       en Surface med både touch og pen matcher hover:hover alene. */
    @media (hover: hover) and (pointer: fine) {
      .pc:hover { transform: translateY(-3px); }
    }
    .pc__media {
      aspect-ratio: 1; position: relative;
      background: var(--stone);
      border-bottom: 1.5px solid var(--ink);
      overflow: hidden;
    }
    .pc__media .bg { position: absolute; inset: 0; }
    /* Marc 2026-08-02: "billederne ser forstrakte ud" på søgeresultaterne.
       Kortets <img> bærer width="400" height="400" i markup'en. På butiks- og
       kategorisiderne fik den height:auto gratis fra WooCommerces eget ark
       (.woocommerce-page img) — men den body-klasse sætter WC KUN på sine egne
       sider, og en /?s=-side er ikke en af dem (målt: body.search-results har
       hverken woocommerce eller woocommerce-page). Højden stod derfor fast på
       400 px mens max-width:100% pressede bredden ned i kolonnen: 170 px bred,
       400 px høj på en telefon i to spalter. Reglen hører hjemme i temaet og
       ikke i en body-klasse vi ikke ejer — (0,2,1) slår WC's (0,1,1), så den
       gælder også på butikssiden, hvor den er visuelt neutral (thumbnailen er
       hårdt beskåret 400×400 og fyldte allerede kvadratet). */
    .pc__media .bg img { width: 100%; height: 100%; object-fit: cover; display: block; }
    /* F9-4: billede 2 fader ind på hover — src sættes først af plp.js ved
       første mouseenter, så gitteret ikke downloader 24 skjulte billeder. */
    .pc__media .pc__img-hover { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity var(--d-med) var(--ease); pointer-events: none; }
    .pc:hover .pc__img-hover[src] { opacity: 1; }
    .pc__media .bg::after {
      content: ""; position: absolute; inset: 0;
      background-image: repeating-linear-gradient(45deg, transparent 0 14px, rgba(13,16,25,0.05) 14px 15px);
    }
    .pc__flag {
      position: absolute; top: 12px; left: 12px;
      background: var(--cobalt); color: var(--snow);
      padding: 4px 10px;
      font-size: 10.5px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
      z-index: 2;
    }
    .pc__flag--stock { background: var(--moss); }
    .pc__flag--low { background: var(--rust); }
    .pc__flag--out { background: var(--ink-faint); color: var(--ink); }
    .pc__fav {
      position: absolute; top: 10px; right: 10px;
      width: 32px; height: 32px;
      background: var(--snow);
      border: 1.5px solid var(--ink);
      border-radius: 50%;
      cursor: pointer;
      font-size: 14px; line-height: 1;
      display: grid; place-items: center;
      z-index: 2;
      transition: background var(--d-fast) var(--ease), color var(--d-fast) var(--ease);
    }
    .pc__fav:hover { background: var(--ink); color: var(--snow); }
    .pc__fav.is-saved { background: var(--cobalt); color: var(--snow); border-color: var(--cobalt); }

    .pc__body { padding: 14px 14px 12px; display: flex; flex-direction: column; gap: 8px; }
    .pc__title-row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
    .pc__name { font-family: var(--font-sans); font-weight: 500; font-size: 14.5px; line-height: 1.25; letter-spacing: -0.01em; margin: 0; flex: 1; min-width: 0; }
    .pc__name a { color: inherit; }
    .pc__name a:hover { color: var(--cobalt); }
    .pc__spec-row { display: flex; gap: 12px; align-items: center; font-family: var(--font-mono); font-size: 10.5px; color: var(--ink-mute); letter-spacing: 0.04em; text-transform: uppercase; flex-wrap: wrap; }
    .pc__spec-row .sw { width: 12px; height: 12px; border-radius: 50%; border: 1px solid var(--line); }
    .pc__stock { display: flex; align-items: center; gap: 6px; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.04em; white-space: nowrap; /* F9-6: "34 m" må ikke ombryde så "m" står alene på næste linje */ }
    .pc__stock--moss { color: var(--moss); }
    .pc__stock--rust { color: var(--rust); }
    .pc__stock--mute { color: var(--ink-mute); }
    .pc__stock .dot { width: 7px; height: 7px; border-radius: 50%; }
    .pc__stock--moss .dot { background: var(--moss); }
    .pc__stock--rust .dot { background: var(--rust); }
    .pc__stock--mute .dot { background: var(--ink-faint); }

    /* The 2-unit selector — Stykke / Rulle with real roll graphics */
    .units {
      display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
      margin-top: 6px; padding-top: 12px;
      border-top: 1px solid var(--line);
    }
    /* Varer med kun ÉN lovlig længde (fx acetat foer 1/25 m) efterlod ellers
       en tom halv kolonne, nu hvor tiers ikke længere er låst til 10+50. */
    .units > .unit-btn:only-child { grid-column: 1 / -1; }
    .unit-btn {
      display: flex; flex-direction: column; align-items: center; gap: 4px;
      padding: 10px 8px 8px;
      background: var(--paper);
      border: 1.5px solid var(--line);
      cursor: pointer;
      text-align: center;
      transition: border-color var(--d-fast) var(--ease), background var(--d-fast) var(--ease);
    }
    .unit-btn:hover { border-color: var(--ink); }
    .unit-btn[aria-pressed="true"] { border-color: var(--cobalt); background: var(--cobalt-tint); }
    .unit-btn img { width: 36px; height: 36px; object-fit: contain; opacity: 0.85; }
    .unit-btn[aria-pressed="true"] img { opacity: 1; }
    .unit-btn .label { font-size: 11.5px; font-weight: 500; letter-spacing: 0; line-height: 1; margin-top: 2px; }
    .unit-btn .price { font-family: var(--font-mono); font-size: 11px; color: var(--ink-mute); font-weight: 500; }
    .unit-btn .per-m { font-family: var(--font-mono); font-size: 10px; color: var(--ink-mute); display: block; margin-top: 1px; }
    .unit-btn[aria-pressed="true"] .price { color: var(--cobalt-deep); }
    .unit-btn[aria-pressed="true"] .per-m { color: var(--cobalt); }

    .pc__cta {
      display: flex; gap: 6px; margin-top: 6px;
      padding-top: 10px; border-top: 1px solid var(--line);
    }
    .pc__add {
      flex: 1;
      background: var(--cobalt); color: var(--snow);
      border: 1.5px solid var(--cobalt);
      padding: 9px 12px;
      font-family: var(--font-sans); font-size: 12.5px; font-weight: 500;
      letter-spacing: 0;
      cursor: pointer;
      display: flex; align-items: center; justify-content: center; gap: 6px;
      transition: background var(--d-fast) var(--ease);
    }
    .pc__add:hover { background: var(--cobalt-deep); border-color: var(--cobalt-deep); }
    .pc__add[disabled] { background: var(--paper); color: var(--ink-faint); border-color: var(--line); cursor: not-allowed; }
    /* R15: mængden knappen faktisk lægger i kurven. Mono + let dæmpet, så den
       læses som en VÆRDI ved siden af handlingen og ikke som en del af verbet —
       samme adskillelse som .pc__rate bruger mellem længde og pris. Skillestregen
       er en border, ikke et tegn, så den ikke kan brydes over to linjer.
       .pc__add er allerede flex med gap:6px, og stregen ville stå midt i det
       mellemrum; margin-left:-1px trækker den ind på tekstens side, padding-left
       giver den luft på sin egen. white-space:nowrap fordi "10 m" aldrig må
       knække. Målt i harness: indholdet er 175px i en 178px knap ved tætteste
       visning (251px kort, 2560px viewport) — passer, og "50 m" er lige så bred
       som "10 m" fordi tallene er tabular. */
    .pc__add-q {
      font-family: var(--font-mono); font-size: 11px; font-weight: 400;
      letter-spacing: 0.02em; white-space: nowrap;
      opacity: 0.8;
      margin-left: -1px; padding-left: 7px;
      border-left: 1px solid rgba(248, 248, 244, 0.35);
      font-variant-numeric: tabular-nums;
    }
    /* R17: ✓-kvitteringen er en TILSTAND, ikke en DOM-ombytning. Den gamle sti
       gemte knappens innerHTML i dataset.orig ved første køb og skrev det tilbage
       efter ✓ — så et andet køb med en anden længde rullede badgen tilbage til den
       FØRSTE længde, mens data-sel og den markerede række stod på den nye. Knappen
       løj om hvad den havde lagt i kurven. Her forlader <span data-add-q> aldrig
       DOM'en; kun hvilket søskende-span der vises skifter. Derfor er der heller
       ingen tekst der kan brække til to linjer på et 163px mobilkort, og ingen ny
       oversat streng: ✓ er et tegn, ikke et ord. */
    .pc__add-ok { display: none; }
    .pc__add[data-state="ok"] { background: var(--cobalt-deep); border-color: var(--cobalt-deep); }
    .pc__add[data-state="ok"] .pc__add-lbl { display: none; }
    .pc__add[data-state="ok"] .pc__add-ok { display: inline; font-weight: 600; }
    .pc__notify {
      flex: 1;
      background: var(--paper); color: var(--ink);
      border: 1.5px solid var(--ink);
      padding: 9px 12px;
      font-family: var(--font-sans); font-size: 12.5px; font-weight: 500;
      cursor: pointer;
    }
    .pc__notify:hover { background: var(--ink); color: var(--snow); }

    /* In-grid editorial / Vault upsell tile */
    .grid-break {
      grid-column: span 2;
      background: var(--vault-bg);
      border: 1.5px solid var(--vault-bg);
      color: var(--vault-ink);
      padding: 32px 36px;
      display: flex; flex-direction: column; justify-content: space-between;
      min-height: 0;
      position: relative;
    }
    .grid-break .kicker {
      font-family: var(--font-sans); font-size: 11px; font-weight: 500;
      letter-spacing: 0.08em; text-transform: uppercase;
      color: var(--vault-mute);
    }
    .grid-break h3 {
      font-family: var(--font-sans); font-weight: 400;
      font-size: 32px; line-height: 0.98; letter-spacing: -0.025em;
      margin: 12px 0 8px;
    }
    .grid-break h3 em {
      font-style: italic;
      background: var(--vault-foil); -webkit-background-clip: text; background-clip: text; color: transparent;
    }
    .grid-break p { color: var(--vault-mute); font-size: 13px; margin: 0; line-height: 1.5; }
    .grid-break .cta { font-family: var(--font-sans); font-size: 13px; font-weight: 500; color: var(--vault-ink); border-bottom: 1px solid var(--vault-line); padding-bottom: 2px; margin-top: 16px; display: inline-block; }
    @media (max-width: 700px) { .grid-break { grid-column: span 2; } }

    /* ========= PAGINATION ========= */
    /* V-03: flex-wrap er ikke kosmetik, det er selve fixet. Uden wrap er en
       flex-containers min-content = SUMMEN af børnene: 290,4 px på side 1 og
       410,7 px på side 2, hvor "Forrige" dukker op. .shell er 1fr på mobil, og
       1fr = minmax(auto,1fr), så sporet kan ikke blive smallere end sit bredeste
       barns min-content — derfor blev hele indholdskolonnen 410,7 px på en 360 px
       skærm og resten klippet væk. Med wrap er min-content det BREDESTE ENKELTE
       element (101 px, FI "Seuraava →"), som passer på selv den smalleste telefon. */
    .pager { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 4px; padding: 48px 0 16px; font-size: 13px; }
    .pager a, .pager span { min-width: 38px; height: 38px; padding: 0 10px; display: grid; place-items: center; border: 1.5px solid transparent; color: var(--ink-soft); }
    .pager a:hover { border-color: var(--line); }
    .pager span[aria-current] { background: var(--ink); color: var(--snow); border-color: var(--ink); }
    /* 38x38 klarer WCAG 2.2 AA (24x24) men falder på AAA, Apple HIG og Material
       (44x44). Efter wrap er der plads til at give touch det den skal have. */
    @media (pointer: coarse) {
      .pager { gap: 8px; }
      .pager a, .pager span { min-width: 44px; height: 44px; }
    }
    /* .pager .pager__nav er slettet: paginate_links() med type=plain udskriver
       "prev page-numbers", aldrig pager__nav — selektoren ramte ingenting.
       Den rigtige regel blev skrevet forfra længere nede (P3 sweep). */

    /* ========= FAQ ========= */
    .faq { max-width: var(--content-w); margin: 0 auto; padding: var(--s-16) var(--gutter); display: grid; grid-template-columns: 1fr 1.4fr; gap: 64px; border-top: 1px solid var(--line); }
    .faq h2 { font-family: var(--font-sans); font-weight: 400; font-size: var(--t-h2); margin: 16px 0 0; letter-spacing: -0.025em; line-height: 1.04; }
    .faq h2 em { font-style: italic; color: var(--cobalt); }
    .faq__lead { color: var(--ink-soft); margin-top: 16px; font-size: var(--t-body); }
    .faq__list { display: flex; flex-direction: column; }
    .faq__list details { border-top: 1px solid var(--line); padding: 20px 0; }
    .faq__list details:last-child { border-bottom: 1px solid var(--line); }
    .faq__list summary { cursor: pointer; list-style: none; font-family: var(--font-sans); font-weight: 500; font-size: 18px; line-height: 1.3; display: flex; justify-content: space-between; align-items: center; gap: 24px; }
    .faq__list summary::-webkit-details-marker { display: none; }
    .faq__list summary::after { content: "+"; font-size: 22px; color: var(--ink-mute); }
    .faq__list details[open] summary::after { content: "−"; }
    .faq__list p { color: var(--ink-soft); margin: 12px 0 0; max-width: 60ch; font-size: var(--t-body); }
    @media (max-width: 900px) { .faq { grid-template-columns: 1fr; gap: 24px; } }

    /* ========= FLYOUT CART (compact for now) ========= */
    .flyout { position: fixed; inset: 0; z-index: 100; pointer-events: none; visibility: hidden; }
    .flyout[data-open="true"] { pointer-events: auto; visibility: visible; }
    /* Selve panelreglen er flyttet til theme.css (V-07) — ét ark ejer bredden. */
    .flyout__backdrop { position: absolute; inset: 0; background: rgba(13,16,25,0.45); opacity: 0; transition: opacity var(--d-med) var(--ease); cursor: pointer; }
    .flyout[data-open="true"] .flyout__backdrop { opacity: 1; }
    .flyout__head { padding: 24px 28px 20px; border-bottom: 1.5px solid var(--ink); display: grid; grid-template-columns: 1fr auto; gap: 16px; align-items: start; }
    .flyout__head .ey { font-size: 10.5px; font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-mute); display: block; margin-bottom: 8px; }
    .flyout__head h2 { font-family: var(--font-sans); font-weight: 400; font-size: 28px; line-height: 1; letter-spacing: -0.025em; margin: 0; }
    .flyout__head h2 em { font-style: italic; color: var(--cobalt); }
    .flyout__close { width: 36px; height: 36px; display: grid; place-items: center; border: 1.5px solid var(--ink); cursor: pointer; font-size: 16px; }
    .flyout__close:hover { background: var(--ink); color: var(--snow); }
    .flyout__lines { padding: 16px 28px; display: flex; flex-direction: column; gap: 0; }
    .fline { display: grid; grid-template-columns: 56px 1fr auto; gap: 14px; padding: 16px 0; border-bottom: 1px solid var(--line); align-items: start; }
    .fline:last-child { border-bottom: 0; }
    .fline__media { width: 56px; height: 56px; background: var(--stone); border: 1px solid var(--line); }
    .fline__name { font-family: var(--font-sans); font-weight: 500; font-size: 14px; line-height: 1.2; margin: 0; }
    .fline__meta { display: flex; gap: 8px; margin-top: 4px; font-family: var(--font-mono); font-size: 10.5px; color: var(--ink-mute); align-items: center; }
    .fline__meta .sw { width: 10px; height: 10px; border-radius: 50%; border: 1px solid var(--line); }
    .fline__meta img { width: 16px; height: 16px; opacity: 0.7; }
    .fline__qty { display: inline-flex; align-items: stretch; border: 1px solid var(--line); margin-top: 8px; background: var(--paper); font-family: var(--font-mono); font-size: 12px; height: 26px; }
    .fline__qty button { width: 24px; cursor: pointer; background: 0; border: 0; }
    .fline__qty input { width: 44px; text-align: center; border: 0; background: transparent; font: inherit; outline: 0; color: var(--ink); }
    .fline__qty .unit { padding: 0 8px 0 6px; color: var(--ink-mute); display: flex; align-items: center; border-left: 1px solid var(--line); font-size: 10px; letter-spacing: 0.04em; text-transform: uppercase; }
    .fline__price { text-align: right; min-width: 88px; display: flex; flex-direction: column; align-items: end; gap: 4px; }
    .fline__price .total { font-family: var(--font-sans); font-weight: 500; font-size: 18px; letter-spacing: -0.015em; }
    .flyout__totals { padding: 20px 28px 0; display: flex; flex-direction: column; gap: 8px; }
    .flyout__totals .row { display: flex; justify-content: space-between; font-size: 13.5px; }
    .flyout__totals .row .lbl { color: var(--ink-soft); }
    .flyout__totals .row.big { border-top: 1.5px solid var(--ink); padding-top: 14px; margin-top: 6px; font-family: var(--font-sans); font-weight: 500; font-size: 18px; }
    .flyout__totals .row .val { font-family: var(--font-mono); }
    .flyout__totals .row.big .val { font-size: 22px; letter-spacing: -0.015em; font-family: var(--font-sans); }
    .flyout__cta { padding: 16px 28px 28px; display: flex; flex-direction: column; gap: 8px; }
    .btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; height: 48px; padding: 0 24px; font-family: var(--font-sans); font-size: 14px; font-weight: 500; background: var(--ink); color: var(--snow); border: 1.5px solid var(--ink); cursor: pointer; }
    .btn:hover { background: var(--cobalt); border-color: var(--cobalt); }
    .btn--brand { background: var(--cobalt); border-color: var(--cobalt); }
    .btn--ghost { background: 0; color: var(--ink); }
    .btn--ghost:hover { background: var(--ink); color: var(--snow); }
    .btn--block { width: 100%; }
    .btn--mini { height: 36px; padding: 0 14px; font-size: 12.5px; }

    /* Flyout: free shipping bar, delivery info, bundles */
    .ship-bar { padding: 16px 28px; border-bottom: 1px solid var(--line); background: var(--cobalt-wash); }
    .ship-bar__row { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 8px; font-size: 12.5px; }
    .ship-bar__row b { font-weight: 600; color: var(--cobalt-deep); }
    .ship-bar__track { height: 4px; background: var(--snow); position: relative; border: 1px solid var(--cobalt); border-radius: var(--r-pill); overflow: hidden; }
    .ship-bar__fill { position: absolute; left: 0; top: 0; bottom: 0; background: var(--cobalt); border-radius: var(--r-pill); transition: width var(--d-med) var(--ease); }
    .ship-bar__done { color: var(--moss); font-weight: 500; }

    .delivery-info { padding: 14px 28px; display: flex; gap: 12px; align-items: start; background: var(--snow); border-bottom: 1px solid var(--line); }
    .delivery-info svg { color: var(--cobalt); flex-shrink: 0; margin-top: 2px; }
    .delivery-info b { font-weight: 600; display: block; font-size: 13px; }
    .delivery-info span { font-size: 12px; color: var(--ink-soft); display: block; line-height: 1.45; }
    .delivery-info code { font-family: var(--font-mono); font-size: 11px; color: var(--ink-mute); }

    .bundles { padding: 20px 28px; background: var(--cobalt-tint); border-top: 1px solid var(--cobalt); border-bottom: 1px solid var(--cobalt); }
    .bundles__head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 14px; }
    .bundles__head h3 { font-family: var(--font-sans); font-weight: 500; font-size: 15px; margin: 0; }
    .bundles__head span { font-size: 11px; color: var(--cobalt-deep); font-family: var(--font-mono); letter-spacing: 0.04em; }
    .bundle { background: var(--snow); border: 1px solid var(--cobalt); padding: 10px 12px; display: grid; grid-template-columns: 36px 1fr auto; gap: 12px; align-items: center; margin-bottom: 6px; }
    .bundle:last-child { margin-bottom: 0; }
    .bundle__ico { width: 36px; height: 36px; background: var(--cobalt-tint); display: grid; place-items: center; color: var(--cobalt-deep); border-radius: 50%; flex-shrink: 0; }
    .bundle__ico .sw { width: 18px; height: 18px; border-radius: 50%; border: 1px solid var(--cobalt); }
    .bundle__info b { font-size: 13px; font-weight: 500; display: block; line-height: 1.2; }
    .bundle__info span { font-size: 11px; color: var(--ink-mute); }
    .bundle__add { width: 28px; height: 28px; border-radius: 50%; background: var(--cobalt); color: var(--snow); border: 0; cursor: pointer; font-size: 16px; line-height: 1; }
    .bundle__add:hover { background: var(--cobalt-deep); }
    .bundle__add[data-added="true"] { background: var(--moss); }

    /* ========= FOOTER ========= */
    footer.site { background: var(--ink); color: var(--snow); padding: var(--s-16) var(--gutter) 40px; margin-top: var(--s-20); }
    footer.site .ftr { max-width: var(--content-inner); margin: 0 auto; display: grid; grid-template-columns: 1.4fr repeat(4, 1fr); gap: 56px; }
    footer.site .brand { display: flex; flex-direction: column; gap: 20px; max-width: 36ch; }
    footer.site .brand img { width: 220px; height: auto; filter: brightness(0) invert(1); opacity: 0.95; }
    footer.site .brand p { color: rgba(248,248,244,0.6); font-size: 13.5px; margin: 0; line-height: 1.55; }
    footer.site h4 { font-size: 11px; font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase; color: rgba(248,248,244,0.4); margin: 0 0 18px; }
    footer.site ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 12px; font-size: 13.5px; }
    footer.site a { color: rgba(248,248,244,0.75); }
    footer.site a:hover { color: var(--cobalt-soft); }
    footer.site .base { max-width: var(--content-inner); margin: 64px auto 0; padding-top: 24px; border-top: 1px solid rgba(248,248,244,0.12); display: flex; justify-content: space-between; gap: 24px; flex-wrap: wrap; font-size: 12px; color: rgba(248,248,244,0.5); }
    @media (max-width: 900px) { footer.site .ftr { grid-template-columns: 1fr 1fr; } }


/* P1: page-head eyebrow style */
.page-head__eyebrow { display: block; font-size: var(--t-eyebrow); font-weight: 500; letter-spacing: var(--tracked-eye); text-transform: uppercase; color: var(--ink-mute); margin-bottom: 8px; }

    /* P2 batch 8: chips reset link + search sort select */
    .chips-reset { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-mute); margin-left: 8px; align-self: center; }
    .chips-reset:hover { color: var(--ink); }
    .toolbar__chips { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
    .search-bar__sort select { height: 34px; padding: 0 28px 0 12px; background: var(--snow); border: 1.5px solid var(--line); font-size: 12.5px; cursor: pointer; }
    .search-bar__meta { display: flex; justify-content: space-between; align-items: center; gap: 16px; }

    /* P3 sweep: boxed prev/next pager buttons */
    /* F9-F4: SVG-chevroner (archive-product.php) kræver flex, ikke grid —
       ikon + ord skal stå på linje med luft imellem, lodret centreret. */
    .pager a.prev.page-numbers, .pager a.next.page-numbers { border: 1.5px solid var(--ink); padding: 0 16px; display: inline-flex; align-items: center; gap: 6px; }
    .pager a.prev.page-numbers svg, .pager a.next.page-numbers svg { display: block; flex: 0 0 auto; }
    /* F8-1 (Marc 7/8): på mobil bæres »Forrige/Næste« i .pager__word og skjules —
       pilene + tallene er nok, og rækken holder sig på ÉN linje på 390px. */
    @media (max-width: 700px) {
      .pager a.prev.page-numbers, .pager a.next.page-numbers { padding: 0 12px; }
      .pager .pager__word { display: none; }
    }
    /* F9-5: på de smalleste skærme skjules fjern-sidetallet EFTER prikkerne
       (»… 446«) — prikkerne siger allerede "der er flere", og de 50 px er
       forskellen på ét spor og ombrydning ved 375-390px. Rammer KUN når
       prikker findes, så tal nær enderne aldrig forsvinder. */
    @media (max-width: 480px) {
      .pager { gap: 4px; }
      .pager span.dots + a.page-numbers { display: none; }
    }
    .pager a.prev.page-numbers:hover, .pager a.next.page-numbers:hover { background: var(--ink); color: var(--snow); }
    /* Algolia highlight → cobalt mark */
    .algolia-search-highlight, em.algolia-search-highlight { font-style: normal; background: var(--cobalt-tint); color: var(--cobalt-deep); padding: 0 2px; }

    /* Favorites state (P2 scope decided 2026-07-22) */
    .pc__fav { position: absolute; top: 10px; right: 10px; z-index: 2; width: 34px; height: 34px; border-radius: 50%; background: rgba(248,248,244,0.92); border: 1px solid var(--line); cursor: pointer; font-size: 16px; line-height: 1; color: var(--ink-soft); display: grid; place-items: center; }
    .pc__fav:hover { border-color: var(--ink); color: var(--ink); }
    .pc__fav[aria-pressed="true"] { color: var(--cobalt); border-color: var(--cobalt); }
    .btn-sec[data-fav][aria-pressed="true"] { border-color: var(--cobalt); color: var(--cobalt-deep); }
    .acct-favs__head { margin-top: 32px; }

    /* R1 Lane 0: guest login CTA on cards */
    .pc__login { margin-top: 6px; padding-top: 12px; border-top: 1px solid var(--line); }
    .pc__login a { font-size: 12.5px; font-weight: 500; color: var(--cobalt); }

    /* R1 Lane 2: per-m leads, total subdued (Marc: pris/m øverst, samlet nederst) */
    .unit-btn .per-m--lead { font-family: var(--font-mono); font-size: 12.5px; font-weight: 600; color: var(--ink); display: block; margin-top: 2px; }
    .unit-btn[aria-pressed="true"] .per-m--lead { color: var(--cobalt-deep); }
    .unit-btn .price--sub { font-family: var(--font-mono); font-size: 10px; color: var(--ink-mute); font-weight: 400; }
    /* density glyph buttons */
    .density button { font-size: 10px; letter-spacing: -1px; line-height: 1; padding: 8px 9px; }
    /* category description at page bottom */
    .cat-desc { margin: 48px auto 16px; }
    .cat-desc__inner { max-width: 72ch; color: var(--ink-soft); font-size: 14px; line-height: 1.65; border-top: 1px solid var(--line); padding-top: 24px; }
    /* N-04: bundteksten er et ANDET felt end term_description, så begge kan stå på
       samme side. Står de det, ville to hårstreger og 48px luft læse som to
       adskilte sektioner — de er ét stykke SEO-tekst. Anden blok får derfor
       hverken streg eller topluft. Teksten er skrevet i en editor og indeholder
       ægte h2/h3 (målt: 129 af 130 rækker er HTML), som skal have en størrelse. */
    .cat-desc--bottom { margin-top: 0; }
    .cat-desc--bottom .cat-desc__inner { border-top: 0; padding-top: 0; }
    .cat-desc__inner h2 { font-size: 18px; line-height: 1.3; margin: 28px 0 8px; color: var(--ink); }
    .cat-desc__inner h3 { font-size: 15px; line-height: 1.35; margin: 20px 0 6px; color: var(--ink); }
    .cat-desc__inner :is(h2, h3):first-child { margin-top: 0; }
    .cat-desc__inner p { margin: 0 0 12px; }
    .cat-desc__inner :is(ul, ol) { margin: 0 0 12px; padding-left: 20px; }
    .cat-desc__inner li { margin-bottom: 4px; }

    /* ===== R1: YITH rail mapped 1:1 onto the mock's fg design (Marc:
       "filtrene ser helt forkerte ud") — mock group boxes, heads, checkbox
       rows w/ right-aligned counts, hover states. ===== */
    .yith-wcan-filters { display: flex; flex-direction: column; gap: 0; }
    /* Pernille 2/9: boksene har mellemrum, saa delt-kant-designet efterlod
       alle undtagen den foerste uden topkant. Nu fuld ramme paa hver boks. */
    .yith-wcan-filter { border: 1.5px solid var(--ink); background: var(--snow); margin: 0 !important; padding: 0 !important; }
    .yith-wcan-filter .filter-title { font-size: 11px !important; letter-spacing: 0.08em; text-transform: uppercase; font-weight: 600 !important; color: var(--ink); margin: 0 !important; padding: 12px 14px; background: var(--snow-deep); border-bottom: 1px solid var(--line); cursor: pointer; }
    .yith-wcan-filter .filter-content { padding: 10px 14px 12px; }
    .yith-wcan-filter .filter-items { display: flex; flex-direction: column; gap: 2px; margin: 0; padding: 0; list-style: none; }
    .yith-wcan-filter .filter-item { margin: 0 !important; padding: 0 !important; }
    .yith-wcan-filter .filter-item a, .yith-wcan-filter .filter-item label { display: flex !important; align-items: center; gap: 9px; padding: 7px 6px !important; font-size: 13px !important; color: var(--ink) !important; border-radius: 2px; text-decoration: none; }
    .yith-wcan-filter .filter-item a:hover, .yith-wcan-filter .filter-item label:hover { background: var(--paper); }
    .yith-wcan-filter .filter-item .term-label { flex: 1; }
    /* .item-count, ikke .count: YITH udskriver <small class="item-count">
       (templates/filters/global/count.php:23). Den gamle .count-regel matchede intet. */
    .yith-wcan-filter .filter-item .item-count { font-family: var(--font-mono); font-size: 10.5px; color: var(--ink-mute); }
    .yith-wcan-filter .filter-item.checkbox a::before, .yith-wcan-filter .filter-item.checkbox label::before { content: ""; width: 15px; height: 15px; border: 1.5px solid var(--line); background: var(--snow); flex-shrink: 0; }
    .yith-wcan-filter .filter-item.checkbox.active a::before, .yith-wcan-filter .filter-item.checkbox a.active::before { background: var(--cobalt); border-color: var(--cobalt); box-shadow: inset 0 0 0 2.5px var(--snow); }
    .yith-wcan-filter .show-more { font-size: 11.5px; font-weight: 500; color: var(--cobalt); margin-top: 6px; display: inline-block; }
    .filters__head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 12px; }
    .filters__head h2 { font-size: 16px; font-weight: 600; margin: 0; }

    /* R16: .pc__qty-reglerne er slettet. Antalsvælgeren bor ikke længere på
       kortet — hverken direkte (R1) eller i et overlay (R14). Den er flyttet
       til købs-sheeten (.bs__qty i buy-sheet.css), hvor der er plads til 48px
       touch-mål i stedet for 26-28px. Kortet har nu ÉN handling: åbn sheeten,
       eller læg standardlængden i kurven med antal 1. */

    /* R2: ÉN checkbox pr. filter-punkt (mine ::before på både a OG label + YITH's
       egen boks gav TRE) — behold YITH's native, tonet. */
    .yith-wcan-filter .filter-item.checkbox a::before,
    .yith-wcan-filter .filter-item.checkbox label::before { content: none !important; }
    .yith-wcan-filter .filter-item input[type="checkbox"] { accent-color: var(--cobalt); width: 15px; height: 15px; }

    /* F9-F1 (Marc 20/8: "filtrene skal være sticky eller i hvert fald følge
       produkterne"). R2 slog sticky HELT fra, fordi skinnen (målt 2.430 px)
       blev pinnet med utilgængelig bund — det PROBLEM var ægte, men static
       var den forkerte kur. Kuren er egen scroll: skinnen følger med OG alle
       filtre kan nås ved at rulle inde i den. align-self:start er
       forudsætningen — uden den strækker grid-kolonnen skinnen til
       produkternes højde, og sticky får aldrig vandringsrum (målt: computed
       static + stretch). V-10's medie-hegn er bevaret: mobil-draweren
       (≤1000px) er urørt, .vh-rail forbliver static som R2 besluttede. */
    @media (min-width: 1001px) {
      .filters, aside.filters {
        position: sticky !important;
        top: 88px;
        align-self: start;
        max-height: calc(100vh - 104px);
        overflow-y: auto;
        overscroll-behavior: contain;
        scrollbar-width: thin;
        padding-right: 6px;
      }
      .vh-rail { position: static !important; }
    }
    @media (max-width: 1000px) {
      .vh-rail { position: static !important; }
    }

    /* R2: vault-tile spænder hele rækken → altid 3 kort pr. række */
    .grid-break--row { grid-column: 1 / -1; }

    /* R2: beskrivelse fuld bredde */
    .cat-desc__inner { max-width: none; }

    /* R3: dense-grid overflow (grid-børn min-width:auto → skubbede ud til højre) */
    .grid.products > * { min-width: 0; }
    .grid[data-density="dense"] .pc__body { padding: 10px 12px 12px; }
    /* R3: FAQ fuld bredde + 2 kolonner */
    /* R5: basen (linje 229) er et 1fr/1.4fr-grid → h2 røg i HØJRE spor og
       indholdet klemtes i venstre. Sektionen skal FLYDE; kolonnerne ejes af
       .faq-content alene. */
    /* R13 (Marc: "den strakte version følger ikke sidens bredde"): max-width:none
       er FJERNET. Den slog .wrap/--content-w ud, så sektionen kørte fuld viewport
       — ~540px ud over indholdskassen i hver side på 2560px. Kun display:block er
       bærende; basen linje 229 leverer igen 1480px + gutter. */
    .faq { display: block; }
    /* R6: theme.css:587 satte max-width:780px på .faq-content — det VAR
       "still not full width". max-width:none her vinder (senere fil) og er
       ufarlig nu: forælderen .faq er kappet på --content-w, så de to kolonner
       fylder indholdskassen (1368px) og ikke mere. */
    .faq-content { display: grid; grid-template-columns: 1fr 1fr; gap: 16px 40px; margin-top: 24px; max-width: none; }
    @media (max-width: 800px) { .faq-content { grid-template-columns: 1fr; } }

/* R6: SPAR-flag + førpris på tilbudsvarer */
.pc__flag--sale { background: var(--rust, #B4552D); color: var(--snow); }
/* V-04: SKAL ligge efter .pc__flag--sale. De to regler har samme specificitet
   (0,1,0), så kilderækkefølgen afgør — og --sale er skrevet her på :496, ikke
   deroppe ved :116 sammen med de andre.
   Farven er --amber, ikke --rust, fordi --rust allerede betyder to ting på
   kortet i forvejen: .pc__flag--low (:116) og .pc__flag--sale (denne linje) er
   BEGGE #B85A1C. Et tredje rust-flag ville gøre farven meningsløs. --amber står
   i tokens-v4.css:30 og bruges 0 gange på PLP i dag.
   PDP'en bruger gal__badge--rust til det samme (single-product.php:72). Vil Marc
   have dem ens, er det denne ene linje der skal skiftes til var(--rust). */
.pc__flag--pre { background: var(--amber, #D89C2E); color: var(--ink); }
.pc .price--sub s { color: var(--ink-faint); margin-right: 4px; }
.tm-card__add--err { background: var(--rust, #B4552D) !important; }

/* R7 A5: tættere rytme mellem egenskaberne i filter-railen */
.fg__list { gap: 3px; }
.frow { padding: 1px 0; }
.filters { gap: 20px; }
.filters .yith-wcan-filter .filter-content ul li, .filters .yith-wcan-filters .filter-item { margin: 0; padding: 1px 0; }

/* R8: filter-rytmen — YITH's EGNE klasser bar padding'en (7px 6px pr. label);
   mine .frow-regler ramte dem aldrig */
.filters .yith-wcan-filter .filter-item label,
.filters .yith-wcan-filter .filter-item a.term-label,
.filters .yith-wcan-filter .filter-item a { padding: 2px 6px !important; }
.filters .yith-wcan-filter .filter-content ul li { margin: 0 !important; line-height: 1.35; }
.filters .yith-wcan-filter { margin-bottom: 6px !important; }
.filters .yith-wcan-filter .filter-title { margin-bottom: 6px !important; }

/* ===== R12: farve-filteret — swatches + skrift-paritet =====
   ROD 1 (ingen farver) er fikset i PHP: inc/color-swatches.php leverer hex'en på
   yith_wcan_tax_filter_item_args, fordi YITH nulstiller color_1 når preset'ets
   "use all terms" er slået til. Herunder styles kun det span, hooket nu printer.
   ROD 2 (anden skrift): i color-designet ligger teksten ét DOM-niveau dybere —
   i span.term-label inde i et klasseløst <a> — mens term-label ER <a>'et i
   checkbox-designet. Temaet satte kun font-size på a/label (linje 369), så
   shortcodes.css:175 vandt med 0.9em + text-align:center => 11,7px centreret mod
   13px venstrestillet i alle andre filtre. Kæderne herunder er 7 klasser (YITH's
   længste er 6), så det afgøres af specificitet — ikke af hvem der loades sidst. */

.filters .yith-wcan-filters {
  /* YITH's globale accent er magenta #A7144C og DELES med det live porto-shop —
     derfor omdefineret scoped her, aldrig i databasen. */
  --yith-wcan-filters_colors_accent: var(--cobalt);
}

/* li ud af YITH's 25%-brede inline-block-grid og ind i checkbox-rækkernes rytme */
.filters .yith-wcan-filters .yith-wcan-filter .filter-content .filter-items .filter-item.color {
  display: block;
  width: auto;
  margin: 0;
  text-align: left;
  font-size: 13px;
}

.filters .yith-wcan-filters .yith-wcan-filter .filter-content .filter-items .filter-item.color .term-label {
  display: flex;
  align-items: baseline;
  gap: 9px;
  flex: 1;
  font-size: 13px;
  line-height: 1.35;
  text-align: left;
}

/* cirklen: 15px = præcis samme fodaftryk som checkbox-boksen (linje 373) */
.filters .yith-wcan-filters .yith-wcan-filter .filter-content .filter-items .filter-item.color .term-color {
  width: 15px;
  height: 15px;
  flex: 0 0 15px;
  margin: 0;
  border: 0; /* YITH's 2px ring lå i layoutet og flyttede rækkehøjden — vi ringer med box-shadow */
  border-radius: 50%;
}
.filters .yith-wcan-filters .yith-wcan-filter .filter-content .filter-items .filter-item.color .color-swatch {
  border-radius: 50%;
  /* indvendig kant: uden den forsvinder Hvid og Stoevet raahvid i --snow */
  box-shadow: inset 0 0 0 1px rgba(13, 16, 25, 0.22);
}

/* Guld og Sølv er metaller — flad sennep og flad grå lyver om varen. Glansen
   lægges som background-image oven på basishex'en fra inline-style'en. */
.filters .filter-item.color.jsl-sw-metal .color-swatch {
  background-image: linear-gradient(135deg, rgba(255, 255, 255, 0.85) 0%, rgba(255, 255, 255, 0.25) 30%, rgba(0, 0, 0, 0.18) 62%, rgba(255, 255, 255, 0.6) 100%);
}
/* "Multi" er ikke én farve — hjulet siger det ærligt frem for at vælge en. */
.filters .filter-item.color.jsl-sw-multi .color-swatch {
  background-image: conic-gradient(#C3352B, #E8C22E, #3E8E4E, #2F5DA8, #7B4CA8, #C3352B);
}

.filters .yith-wcan-filters .yith-wcan-filter .filter-content .filter-items .filter-item.color > a:hover .term-color,
.filters .yith-wcan-filters .yith-wcan-filter .filter-content .filter-items .filter-item.color.active .term-color {
  box-shadow: 0 0 0 2px var(--snow), 0 0 0 3.5px var(--cobalt);
}
.filters .yith-wcan-filters .yith-wcan-filter .filter-content .filter-items .filter-item.color.active .term-label {
  font-weight: 600;
}
/* YITH's aktive ×-badge er absolut placeret i hjørnet (top/right -5px) og lander
   oven i navnet nu hvor rækken er fuld bredde. Ring + fed tekst bærer tilstanden,
   og toolbar-chippen har allerede sit eget ✕. Kæden matcher YITH's :not()-kæde. */
.filters .yith-wcan-filters .yith-wcan-filter .filter-content .filter-items .filter-item.color.active:not(.no-color):not(.no-image):not(.label-right) > a:after {
  content: none;
}

/* Falder en ny farve-term uden for hex-kortet, beholder YITH sin .no-color og
   printer intet swatch-span. Pladsholderen holder rækken på linje med de andre. */
.filters .yith-wcan-filters .yith-wcan-filter .filter-content .filter-items .filter-item.color.no-color > a::before {
  content: "";
  width: 15px;
  height: 15px;
  flex: 0 0 15px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: repeating-linear-gradient(45deg, var(--snow-deep) 0 3px, var(--paper) 3px 6px);
}

/* ===== R14/R16: KØBSBLOKKEN UD AF KORTET =====
   Marc: "the ad of to cart is too heigh and takes up too much space compared to
   the important, the fabric and fabric specs of course."
   Målt: 310,3 px af et 614,8 px kort på 390 px viewport = 50,5% (36,9% på
   desktop, 52-55% i tæt visning). Købsmekanikken fyldte altså mere end stoffet.

   R14 flyttede mekanikken til et overlay INDE i kortet (.pc__buy). R16 flyttede
   den helt ud, til den delte <dialog> i templates/buy-sheet.php. Kortet har nu
   præcis to handlinger: .pc__rates åbner sheeten, .pc__add lægger standard-
   længden i kurven med antal 1. Ingen tilstand overlever på kortet.

   HVORFOR OVERLAYET IKKE KUNNE BLIVE (rettet — den gamle forklaring her var
   forkert og ville føre den næste læser lige i grøften):
   Det var ALDRIG hover-transformen. .pc har container-type: inline-size (lige
   nedenfor). Efter css-contain-3 medfører inline-size også LAYOUT containment,
   og css-contain-2 §3.2: en layout containment box "establishes an absolute
   positioning containing block and a fixed positioning containing block".
   .pc er derfor PERMANENT containing block for position:fixed — uafhængigt af
   hover, af transform og af om musen findes. Et panel i kortet kunne kun være
   absolute, og et absolute-panel med top:100% dækker 64-119% af nabokortet i et
   2-spors mobilgrid. Det er geometri, ikke styling.
   ⚠️ Sæt ALDRIG will-change: transform på .pc for at "optimere" løftet — det
   ville tilføje endnu en containing block og genskabe fælden et andet sted.
   (MDN's side om container-type nævner ikke layout containment. Kilden er
   specifikationen, ikke MDN.)

   container-type på .pc, ikke @media: et kort i tæt visning er ~251 px bredt på
   et 2560 px viewport; ingen @media-regel kan se det. Basislayoutet er det
   SMALLE (stablet), og @container udvider det — så browsere uden container
   queries får den sikre variant, ikke den klemte. */

.pc { container-type: inline-size; }

/* Prislinjer = ÅBNEREN. R14 gjorde dem til ren tekst og lagde affordancen i en
   separat ⌄-knap ved siden af "Læg i kurv". Marc, feedback 7: "skal måske hedde
   vælg antal meter eller også skal pilen ned ved siden af, så folk er klar over
   at det er det de skal". Problemet var at ⌄ stod i CTA-rækken og lignede en
   tilføjelse til købsknappen, mens det man skulle vælge (længden) stod 40 px
   længere oppe uden nogen markering.
   Nu er de to ting samlet: prislinjerne ER knappen, med den samme ramme og den
   samme chevron som <select> i toolbaren (linje 63) — den mest direkte "her er
   flere valg"-konvention siden er har. Højden er sat til 52 px, over WCAG 2.2
   SC 2.5.8's 24x24 og over de 44x44 Apple og Marcs egne fingre arbejder med. */
.pc__rates {
  display: flex; flex-direction: column; justify-content: center; gap: 1px;
  width: 100%; min-height: 52px;
  margin-top: 8px;
  padding: 9px 30px 9px 10px;
  border: 1.5px solid var(--line);
  background: var(--paper) url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%230D1019' stroke-width='1.5'><path d='m3 5 3 3 3-3'/></svg>") no-repeat right 10px center;
  background-size: 12px;
  appearance: none; font: inherit; color: inherit; text-align: left;
  cursor: pointer;
  transition: border-color var(--d-fast) var(--ease), background-color var(--d-fast) var(--ease);
}
/* R17: hover-reglen på selve wrapperen er FJERNET, ikke glemt. Den kunne kun
   ramme (hover: hover) and (pointer: fine) — altså præcis de enheder hvor
   desktop-blokken nedenfor gør wrapperen til en passiv beholder og rækkerne til
   knapperne. Havde den fået lov at blive, ville dens background-color (0,2,0)
   slå desktop-blokkens background: none (0,1,0) og male et gråt felt bag de to
   prisrækker ved hover, uden at nogen kunne klikke på det. Hover ligger nu på
   .pc__rate, hvor handlingen faktisk er. */
/* R17: wrapperen er nu et <div> (den åbner kun sheeten på finger, og et element
   der kun virker med finger skal ikke love tastaturet noget). Fokusringen flytter
   derfor til rækkerne — og den ligger som BASISREGEL, ikke i desktop-blokken, så
   en iPad med eksternt tastatur (pointer: coarse) også får en synlig ring.
   --ink mod --cobalt-tint er ~17:1 og mod --paper ~19:1, og offset:2px lægger den
   UDEN for den koboltblå valgt-ramme, så indikator og tilstand aldrig smelter
   sammen til én utydelig streg. */
.pc__rate:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.pc__rate {
  display: flex; justify-content: space-between; align-items: baseline; gap: 8px;
  /* Rækkerne er <button> på varer med flere længder (og <span> på de 390 med kun
     én). Browserens standardstil på knapper nulstilles her, så MOBILENS udseende
     er bit for bit det samme som R16's <span>. Desktop-blokken nedenfor bygger
     sit eget udseende ovenpå. */
  width: 100%; margin: 0; padding: 0;
  border: 0; background: none; appearance: none;
  font: inherit; color: inherit; text-align: left;
}
/* .pc__qty er skjult som UDGANGSPUNKT og tændes kun i R17-blokken nederst
   (mus + kort ≥260px). Finger beholder bundsheeten uændret — Marc godkendte
   mobilen eksplicit, og to antalsvælgere på samme skærm er én for mange. */
.pc__rates-lbl, .pc__rate-ic, .pc__qty, .pc__rate-cart, .pc__rate-ok { display: none; }
/* Variant B's hovedlinje er en ren layout-wrapper om etiket + metervælger, og
   BEGGE er display:none på finger. display:contents fjerner den helt fra
   layoutet dér, så .pc__rates' flex-gap ikke bruger 1px på en tom kasse.
   Mobilen skal være bit for bit den samme i A og B. */
.pc__rates-hd { display: contents; }
.pc__rate b { font-family: var(--font-mono); font-size: 11px; font-weight: 500; color: var(--ink-mute); }
/* R17: --ink-faint (#B8BDCB) mod hvid er 1,88:1 ved 9,5px — under WCAG 1.4.3's
   4,5:1 for almindelig tekst. --ink-mute (#6B7184) er 4,86:1. Det er en
   BASISREGEL og gælder derfor også mobil: den sekundære prislinje ("50 M RULLE")
   bliver mørkere dér. Tilsigtet, ikke en regression i før/efter-sammenligningen. */
.pc__rate i { font-family: var(--font-mono); font-style: normal; font-size: 9.5px; color: var(--ink-mute); letter-spacing: 0.04em; text-transform: uppercase; white-space: nowrap; }
.pc__rate--lead b { font-size: 13.5px; font-weight: 600; color: var(--ink); }
.pc__rate--lead i { color: var(--ink-mute); }

/* .pc__cta bar selv en border-top (linje 166). Den ville lægge sig 2 px under
   .pc__rates' egen ramme og give en dobbeltstreg. Rækken er nu bare knappen. */
.pc__rates + .pc__cta, .pc__price + .pc__cta { border-top: 0; padding-top: 8px; margin-top: 0; }

/* Smalt kort: "+ Læg i kurv" og mængdebadgen stables. Alle tre tætheder falder
   til 2 spor under 700px (linje 73), så kortet er 163-169px på 390px viewport.
   Tre ting værd at holde fast i:
   1) Ombrud, ikke overløb. Derfor sagde scrollWidth "passer", og fejlen blev
      først fundet ved at KIGGE på kortet. Harnessen tæller nu linjebokse.
   2) Labelen er MÅLT til 73,99px (nowrap-probe i samme skrift). Den brækkede
      allerede før R15 — R15 gjorde en eksisterende fejl værre, den skabte den ikke.
   3) 215px var beregnet med ⌄-knappen i rækken: kortbredde − 139,38px (krop 28
      + ⌄ 40 + gap 6 + knappolstring 24 + gap 6 + mængde 35,38) = 74px ved 213,4px.
      R16 fjernede ⌄, så den præcise grænse er nu ~167px (139,38 − 46 = 93,38).
      Tærsklen bliver STÅENDE på 215px: den er nu konservativ, ikke forkert, og
      den stablede variant er en helt fin smal-visning. At sænke den til 167px
      ville flytte 163-169px-kortene ned på grænsen — præcis der hvor målingen
      siger 69,6px < 74px. Det er den fejl vi lige har rettet.
   Lodret: handling over mængde. Skillestregen giver ingen mening mellem to
   linjer og bliver til afstand i stedet. */
@container (max-width: 215px) {
  .pc__cta { gap: 4px; }
  .pc__add { flex-direction: column; gap: 1px; padding: 7px 6px; line-height: 1.25; }
  .pc__add-q { margin-left: 0; padding-left: 0; border-left: 0; opacity: 0.85; }

  /* Prislinjen stables på smalt kort. MÅLT i previewen (nowrap-probe, samme
     skrift): "39,50 kr/m" = 79,7px, "MIN. 10 M" = 62,2px, gap 8 → 149,9px.
     Side om side kræver altså 150px. R14 havde 145px at gøre godt med og lå
     allerede på kanten; R16 lagde 43px chrome oven i (1,5px ramme + 10px venstre
     + 30px højre til chevronen) og efterlod 102px — så brækkede prisen til TRE
     linjer og kortet så ødelagt ud. Ved 167px kort (390px viewport, 2 spor) er
     der 136px selv uden ramme: side om side kan simpelthen ikke lade sig gøre.
     Derfor stablet, og chevronen rykker tættere på kanten. */
  .pc__rates { padding: 8px 22px 8px 8px; background-position: right 7px center; }
  .pc__rate { flex-direction: column; align-items: flex-start; gap: 0; }
  .pc__rate b, .pc__rate i { line-height: 1.3; }
  .pc__rate + .pc__rate { margin-top: 4px; }
}

/* ===== R17: på MUS er prisstigen selve valget =====
   Marc 31/7: "På computer tilføjer det bare endnu et klik og det er stadig lidt
   uklart hvordan kunden tilføjer."

   Der åbner intet panel på mus længere. Hver prislinje er sin egen knap: klik
   30 m-linjen, og tallet på den blå knap skifter i samme sekund. Chevronen
   forsvinder, fordi der ikke længere åbner noget — en pil der lyver er værre end
   ingen pil. Klik-regnskabet: standardlængde 2 → 1 klik, anden længde 4 → 2 klik,
   en engros-session med 12 designs 24 → 12 klik.

   `not all and (pointer: coarse)`, IKKE `(pointer: fine)`: det er den præcise
   negation af plp.js' matchMedia('(pointer: coarse)'), så en pointer:none-enhed
   ikke kan få JS'ens desktop-logik og CSS'ens bundsheet-form på samme tid.
   buy-sheet.css:327 er rettet til samme formulering i samme deploy.

   Blokken gælder ALLE kortbredder med vilje. Gjorde den ikke det, ville et tæt
   kort på en 1280px laptop (~200px bredt) sidde tilbage med en chevron der ikke
   åbner noget. Under 260px stables pris over længde som i den smalle variant
   ovenfor — samme form, bare med ramme. Højdeprisen er MÅLT og betalt bevidst:
   +14px på et normalt kort (≥260px), +19px på et tæt kort. */
@media not all and (pointer: coarse) {
  .pc__rates {
    display: block;
    min-height: 0;
    margin-top: 8px;
    padding: 0;
    border: 0;
    background: none;
    cursor: default;
  }
  .pc__rate {
    flex-direction: column; align-items: flex-start; justify-content: center; gap: 0;
    min-height: 28px;
    padding: 4px 8px;
    /* WCAG 1.4.11 kræver 3:1 på afgrænsningen af en KONTROL. --line (#D7D7CE) er
       1,45:1 og duer ikke længere, nu hvor rækken faktisk ER kontrollen;
       --ink-mute (#6B7184) er 4,86:1. 1px i stedet for 1,5px, så to rammede
       felter oven på hinanden ikke bliver tungere end den ene ramme de erstatter,
       og så valgt/ikke-valgt aldrig kan give et layoutspring. */
    border: 1px solid var(--ink-mute);
    background: var(--paper);
    cursor: pointer;
    transition: background-color var(--d-fast) var(--ease), border-color var(--d-fast) var(--ease);
  }
  .pc__rate b, .pc__rate i { line-height: 1.3; }
  .pc__rate + .pc__rate { margin-top: 4px; }
  /* Valgt-tilstanden er nøjagtig samme sprog som .unit-btn på produktsiden og i
     kurven (linje 161) — kunden har set den før. --lead flytter med valget fra JS,
     så typografisk vægt og koboltmarkering ALTID peger på samme række. */
  .pc__rate[aria-pressed="true"] { border-color: var(--cobalt); background: var(--cobalt-tint); }
  .pc__rate[aria-pressed="true"] b { color: var(--cobalt-deep); }
  .pc__rate[aria-pressed="true"] i { color: var(--cobalt); }
  /* Også den allerede valgte række kvitterer for musen. Uden dette er et klik på
     den mest fremtrædende ting i boksen et helt dødt klik — og 94,9% af kunderne
     vil netop have minimummet, altså den række der allerede er valgt. */
  .pc__rate:hover { background: var(--cobalt-wash); border-color: var(--cobalt-soft); }
  .pc__rate[aria-pressed="true"]:hover { background: var(--cobalt-tint); border-color: var(--cobalt-deep); }

  /* Verbet. Det var hele klage (b): kontrollen indeholdt ikke ét eneste udsagnsord
     — "Vælg længde og antal" stod KUN i en aria-label og var usynlig for den
     seende kunde. Skjult under 260px, hvor de 13px er dyrere end de er værd. */
  @container (min-width: 260px) {
    .pc__rates-lbl {
      display: block; margin: 0 0 4px;
      font-family: var(--font-mono); font-size: 9px; line-height: 1;
      letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-mute);
    }
    /* Bredt nok til pris og længde side om side (målt: 79,7 + 8 + 62,2 = 150px,
       plus 18px ikon og 8px gap = 176px indhold). */
    .pc__rate { flex-direction: row; align-items: center; gap: 8px; padding: 3px 8px; }
    .pc__rate b { flex: 1; }
    /* Marc: "I would like to keep fabric pieces for visual." På mus findes sheeten
       ikke længere, så grafikken flytter ud på kortet. FORMEN bærer betydningen
       (papkasse = afklippet stykke, rulle på rør = hel rulle — samme skel som den
       fysiske pakkeregel ved 50 m), og meterantallet står som tekst ved siden af i
       stedet for bagt ind i pixels. Mobil beholder sine 40px-ikoner i bundsheeten. */
    /* Marc 31/7: "rullerne skal være større uden det tager mere plads". De vokser
       fra 18 til 24px og koster NUL layout: margin: -3px trækker margin-boksen
       tilbage til 18x18, og et flex-barns pladsforbrug ER margin-boksen. Rækkens
       højde (18px indhold) og de 176px bredde er derfor uændrede — tegningen
       vokser kun ind i den 3px polstring og de 8px gap, der allerede var der.
       3px er loftet: mere ville krydse rammen foroven og forneden.
       Opacitet 0.5 -> 0.6, fordi ikonet nu er rækkens største element og ikke
       samtidig må være dens svageste. */
    .pc__rate-ic { display: block; width: 24px; height: 24px; margin: -3px; flex: none; opacity: 0.6; }
    .pc__rate[aria-pressed="true"] .pc__rate-ic { opacity: 1; }

    /* ===== R18: antal i meter, på SAMME række som knappen =====
       Marc 31/7: "nu er det heller ikke muligt at vælge antal på shop siden, det
       burde kunne gøres smartere."

       .pc__cta er allerede flex med gap 6 og .pc__add { flex: 1 }, så vælgeren
       lægger sig ved siden af knappen og koster kortet 0 px i højde. Den koster
       ~86px i bredde; på et 336px kort har CTA-rækken 304px, så knappen beholder
       212px til "+ Læg i kurv" (målt tekstbredde 74px). Under 260px er der ikke
       plads, og dér gælder R17's adfærd uændret: knappen køber én tier.

       Klikregnskab mod R17: 10 m = 1 klik (uændret), 20 m = 2 klik (uændret, men
       nu står tallet der), 200 m = tast + 1 klik i stedet for 20 klik. */
    .pc__add-q { display: none; }  /* tallet står nu i feltet 6px til venstre — to steder ville før eller siden være to forskellige tal */
    .pc__qty {
      display: flex; align-items: stretch; flex: none;
      /* Samme 1px --ink-mute som prisrækkerne ovenfor: det er også en kontrol,
         og WCAG 1.4.11 kræver 3:1 (--line er 1,45:1, --ink-mute er 4,86:1). */
      border: 1px solid var(--ink-mute);
      background: var(--paper);
      transition: border-color var(--d-fast) var(--ease), box-shadow var(--d-fast) var(--ease);
    }
    /* Fokus vises på BOKSEN, ikke på det rammeløse felt inde i den — ellers får
       man to ringe uden på hinanden. Derfor må feltets egen outline slukkes. */
    .pc__qty:focus-within { border-color: var(--cobalt); box-shadow: 0 0 0 1px var(--cobalt); }
    .pc__qty-b {
      width: 26px; padding: 0; border: 0; background: none;
      color: var(--ink-soft); cursor: pointer;
      font-family: var(--font-sans); font-size: 15px; line-height: 1;
      transition: background-color var(--d-fast) var(--ease), color var(--d-fast) var(--ease);
    }
    .pc__qty-b:hover:not(:disabled) { background: var(--cobalt-wash); color: var(--cobalt-deep); }
    /* − er slået fra på minimummet i stedet for bare at gøre ingenting. B2B-
       minimummet er en regel kunden skal kunne SE, ikke opdage ved at klikke. */
    .pc__qty-b:disabled { color: var(--ink-faint); cursor: default; }
    /* Tallet stod ikke midt mellem − og + (Marc 31/7). Årsagen var ikke smag:
       feltet var 32px med højrestillet tal, så "10" efterlod ~17px død plads til
       VENSTRE for cifrene, mens "m" lå klods op ad +. Gruppen så forskudt ud —
       og den flyttede sig, hver gang et ciffer kom til.
       Nu er feltet præcis så bredt som cifrene (fitQty i plp.js sætter ch; mono +
       tabular-nums gør ét ch til ét ciffer, så det er eksakt og ikke et estimat),
       og hele gruppen "10 m" centreres som ÉN enhed. min-width holder boksen på
       samme bredde op til fire cifre, så CTA-rækken ikke hopper mens man taster.
       LODRET var den værre af de to: align-items: baseline hæftede gruppen på
       toppen af det 37,8px høje felt, så "10 m" stod målt 10,4px HØJERE end −
       og +. center stiller den midt i boksen; forskellen mellem de to
       skriftstørrelsers grundlinjer bliver derved 0,4px, altså under et pixel. */
    .pc__qty-f { display: flex; align-items: center; justify-content: center; gap: 2px; padding: 0 3px; flex: 1; min-width: 46px; }
    .pc__qty-i {
      width: 2ch; padding: 0; border: 0; background: none; text-align: right;
      font-family: var(--font-mono); font-size: 12.5px; font-weight: 600; color: var(--ink);
      font-variant-numeric: tabular-nums;
      -moz-appearance: textfield; appearance: textfield;
    }
    .pc__qty-i:focus-visible { outline: none; }
    .pc__qty-i::-webkit-outer-spin-button,
    .pc__qty-i::-webkit-inner-spin-button { -webkit-appearance: none; appearance: none; margin: 0; }
    .pc__qty-u { font-family: var(--font-mono); font-size: 10px; color: var(--ink-mute); }

    /* ===== DEMO-VARIANT B (?cta=b) =====================================
       Marc, efter at have set Quality Textiles: "i still think it could be
       improved, but it requires much fewer clicks and there's nothing to be in
       doubt of." Det QT gør rigtigt er nul-tilstanden: rækken ER købet. Det de
       mangler er antal og prisinformation — begge dele beholder vi.

       Forskellen mod A i praksis: der er ikke længere to kontroller hvor den
       ene vælger og den anden køber, så der findes ingen "hvilken række er
       valgt?"-tilstand at læse. Klik = køb, på den række man peger på.

       Hover overtager den koboltblå markering som aria-pressed havde i A. Det
       er den rigtige oversættelse: i A betød kobolt "det her SKER hvis du
       trykker på den blå knap", i B betyder den "det her sker hvis du trykker
       HER". Samme løfte, flyttet ind i den ting man faktisk peger på. */
    .pc__rates--buy .pc__rates-hd {
      display: flex; align-items: center; justify-content: space-between; gap: 8px;
      margin-bottom: 5px;
    }
    .pc__rates--buy .pc__rates-lbl { margin: 0; }
    /* Kortere end A's blå knap: 26px høj vælger i en 5px-margen frem for en
       hel CTA-række med border-top og 8px polstring. */
    .pc__rates--buy .pc__rate { padding: 5px 8px; }
    .pc__rates--buy .pc__rate:hover { border-color: var(--cobalt); background: var(--cobalt-tint); }
    .pc__rates--buy .pc__rate:hover b { color: var(--cobalt-deep); }
    .pc__rates--buy .pc__rate:hover .pc__rate-ic { opacity: 1; }
    .pc__rates--buy .pc__rate:hover .pc__rate-cart { color: var(--cobalt-deep); }
    /* Glyffen er det eneste sted i rækken der siger HANDLING frem for tal, så
       den bærer ikke tekstfarven — den er dæmpet indtil man peger. */
    .pc__rate-cart { display: block; flex: none; width: 14px; height: 14px; fill: currentColor; color: var(--ink-mute); }
    /* Kvitteringen står hvor handlingen skete. Samme 900ms og samme data-state
       som .pc__add bruger i A, så der er ét mønster og ikke to. */
    .pc__rates--buy .pc__rate[data-state="ok"] { border-color: var(--cobalt-deep); background: var(--cobalt-tint); }
    .pc__rates--buy .pc__rate[data-state="ok"] b { color: var(--cobalt-deep); }
    .pc__rates--buy .pc__rate[data-state="ok"] .pc__rate-cart { display: none; }
    .pc__rates--buy .pc__rate[data-state="ok"] .pc__rate-ok {
      display: block; flex: none; width: 14px; text-align: center;
      font-size: 13px; font-weight: 600; line-height: 1; color: var(--cobalt-deep);
    }
    /* Kun mens POST'en er i luften. Ikke en lås bagefter: to klik i træk skal
       give to køb — samme regel som cardAdd() håndhæver for .pc__add. */
    .pc__rates--buy .pc__rate.loading { opacity: 0.6; pointer-events: none; }
  }
}

/* R16: .pc[data-buy-open], .pc__buy, .pc__buy-head, .pc__buy-x, .pc__buy-foot og
   de to container queries (min-width: 300px / 340px) er slettet sammen med
   overlayet i content-product.php. Mekanikken bor i assets/css/buy-sheet.css.
   .pc__buy-reglerne stylede .units/.unit-btn, hvis basisregler ligger i pdp.css
   og stadig bruges af single-product.php og cart.php — de er urørte. */

/* ===== F-03b: vægtfilter (gsm) i filter-railen =====
   Boksen skal læses som ÉN mere i YITH-stakken, ikke som et fremmedlegeme:
   samme 1,5 px ink-ramme, samme snow-deep titelbjælke, samme 11 px versaler.
   Derfor border-top:0 når den følger efter .yith-wcan-filters (stakken deler
   kanter, jf. .yith-wcan-filter linje 368-369) og hel ramme når den står alene. */
.jsl-wf { border: 1.5px solid var(--ink); background: var(--snow); margin: 0; }
.jsl-wf__head {
  display: flex; justify-content: space-between; align-items: baseline; gap: 8px;
  margin: 0; padding: 12px 14px;
  font-size: 11px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--ink); background: var(--snow-deep); border-bottom: 1px solid var(--line);
}
.jsl-wf__unit { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0; text-transform: none; color: var(--ink-mute); }
/* Aktivt filter er en TILSTAND, ikke pynt — cobalt-tinten er den samme som
   railens aktive termer bruger, så railen kun taler ét sprog om "valgt". */
.jsl-wf--on .jsl-wf__head { background: var(--cobalt-tint); border-bottom-color: var(--cobalt-soft); }
.jsl-wf__body { padding: 18px 14px 14px; }

/* Dobbeltslider: to gennemsigtige range-inputs oven på ét fælles spor.
   pointer-events slukkes på selve inputtet og tændes igen på grebet, så det
   øverste input ikke stjæler klik på det nederstes greb. */
.jsl-wf__slider { position: relative; height: 20px; }
.jsl-wf__track, .jsl-wf__fill { position: absolute; top: 50%; height: 3px; transform: translateY(-50%); pointer-events: none; }
.jsl-wf__track { left: 0; right: 0; background: var(--line); }
.jsl-wf__fill { left: var(--wf-a, 0%); right: calc(100% - var(--wf-b, 100%)); background: var(--cobalt); }
.jsl-wf__range {
  position: absolute; left: 0; top: 0; width: 100%; height: 20px; margin: 0;
  background: transparent; pointer-events: none;
  -webkit-appearance: none; appearance: none;
}
.jsl-wf__range--a { z-index: 3; }
.jsl-wf__range--b { z-index: 4; }
.jsl-wf__range:focus { outline: 0; }
.jsl-wf__range::-webkit-slider-runnable-track { height: 3px; background: transparent; border: 0; }
.jsl-wf__range::-moz-range-track { height: 3px; background: transparent; border: 0; }
.jsl-wf__range::-webkit-slider-thumb {
  -webkit-appearance: none; pointer-events: auto;
  width: 16px; height: 16px; margin-top: -6.5px; border-radius: 50%;
  background: var(--paper); border: 1.5px solid var(--ink); cursor: grab;
  box-shadow: 0 1px 2px rgba(13, 16, 25, 0.18);
  transition: border-color var(--d-fast) var(--ease);
}
.jsl-wf__range::-moz-range-thumb {
  pointer-events: auto;
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--paper); border: 1.5px solid var(--ink); cursor: grab;
  box-shadow: 0 1px 2px rgba(13, 16, 25, 0.18);
}
.jsl-wf__range:hover::-webkit-slider-thumb, .jsl-wf__range:active::-webkit-slider-thumb { border-color: var(--cobalt); }
.jsl-wf__range:hover::-moz-range-thumb, .jsl-wf__range:active::-moz-range-thumb { border-color: var(--cobalt); }
.jsl-wf__range:focus-visible::-webkit-slider-thumb { border-color: var(--cobalt); box-shadow: 0 0 0 3px var(--cobalt-tint); }
.jsl-wf__range:focus-visible::-moz-range-thumb { border-color: var(--cobalt); box-shadow: 0 0 0 3px var(--cobalt-tint); }

/* Tallene i mono — samme regel som resten af sitet: mono KUN til SKU, priser,
   gsm/cm/m og antal (tokens-v4.css linje 119). */
.jsl-wf__read { display: flex; align-items: baseline; margin: 14px 0 0; font-family: var(--font-mono); font-size: 12.5px; color: var(--ink); }
.jsl-wf__dash { color: var(--ink-faint); margin: 0 5px; }
.jsl-wf__u { font-size: 10.5px; color: var(--ink-mute); margin-left: 5px; }

.jsl-wf__foot { display: flex; align-items: center; gap: 12px; margin-top: 14px; }
.jsl-wf__go {
  height: 32px; padding: 0 16px;
  font-family: var(--font-sans); font-size: 12px; font-weight: 500; line-height: 1;
  background: var(--ink); color: var(--snow);
  border: 1.5px solid var(--ink); border-radius: var(--r-1); cursor: pointer;
  transition: background var(--d-fast) var(--ease), border-color var(--d-fast) var(--ease);
}
.jsl-wf__go:hover { background: var(--cobalt); border-color: var(--cobalt); }
.jsl-wf__reset { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-mute); }
.jsl-wf__reset:hover { color: var(--ink); }

/* ===== V-10: FILTER-DRAWER PÅ MOBIL ==========================================
   Porto har i dag en off-canvas filtrering under 992 px (.sidebar-overlay +
   .mobile-sidebar, bundet i porto/js/theme.js). v2 havde INTET: railen var
   display:none uden nogen vej tilbage, så under 1000 px kunne kunden hverken
   filtrere på farve, længde, gsm eller kategori. Det er ikke en manglende
   feature — det er en regression i forhold til den side, vi flipper væk fra.

   Arkitekturen: ÉN <aside class="filters" id="shop-filters"> med to
   præsentationer. Over 1000 px er den kolonnen i .shell-grid'et (uændret).
   Under 1000 px er den en drawer, der glider ind fra venstre. Grunden til at
   det ikke er to markup-blokke: YITH binder sin JS til preset-id'et, og to
   kopier ville give to sæt filter-tilstand, der driver fra hinanden.

   Kontrakten er den samme som flyout-kurvens (assets/js/flyout.js):
   data-open på elementet, backdrop, Escape, scroll-lås på <body>. Genbrugt,
   ikke genopfundet — en kunde, der har lært at lukke kurven, kan lukke det her.

   RÆKKEFØLGEN ER BÆRENDE. Basisreglerne står FØR medieblokken, fordi
   `.filters-toggle { display: none }` og `.filters-toggle { display: inline-flex }`
   har nøjagtig samme specificitet [0,1,0] — så kilderækkefølgen afgør alene.
   Stod basen nedenunder, ville knappen være usynlig på mobil, og fejlen ville
   ligne "CSS'en mangler" i stedet for "CSS'en taber". (Første kørsel gjorde
   præcis det: 6 røde, hvoraf én var denne.)
   Railen selv behøver ingen rækkefølge-omhu: .filters[data-open="true"] er
   [0,2,0] og slår både .filters [0,1,0] og aside.filters [0,1,1] uanset hvor
   den står — derfor er der ikke ét !important i hele blokken. */

/* Knappen og krydset findes i markupen på ALLE bredder — de skjules med CSS,
   ikke med PHP. Ét sted at fejle i stedet for to, og skærmlæsere får den
   samme DOM uanset viewport. */
.filters-toggle {
  display: none;
  align-items: center;
  gap: 8px;
  height: 34px;
  padding: 0 14px;
  font-family: var(--font-sans);
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1;
  color: var(--ink);
  background: var(--snow);
  border: 1.5px solid var(--ink);
  border-radius: var(--r-1);
  cursor: pointer;
}
.filters-toggle:hover { background: var(--paper); }
.filters-toggle[aria-expanded="true"] { background: var(--ink); color: var(--snow); }

/* Lukkekrydset er default skjult, fordi kolonne-tilstanden på desktop ikke har
   noget at lukke. Kun drawer-reglen nedenfor tænder det. */
.filters__close {
  display: none;
  background: 0;
  border: 0;
  padding: 4px;
  margin: -4px -4px -4px 0;
  font-size: 26px;
  line-height: 1;
  color: var(--ink);
  cursor: pointer;
}
.filters__close:hover { color: var(--cobalt); }

/* Backdrop'en er skjult via [hidden] i markupen; JS fjerner attributten.
   display:none her sikrer, at den aldrig ligger og fanger klik, hvis JS skulle
   fejle midt i en tilstand. */
.filters-backdrop { display: none; }

@media (max-width: 1000px) {
  .filters-toggle { display: inline-flex; }

  .filters[data-open="true"] {
    display: flex;
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 60;
    width: min(88vw, 360px);
    max-width: 100%;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    background: var(--snow);
    border-right: 1.5px solid var(--ink);
    box-shadow: 0 0 40px rgba(0, 0, 0, 0.18);
    padding: 16px 18px 40px;
    gap: 18px;
    animation: filters-in var(--d-fast, 160ms) var(--ease, ease-out);
  }

  /* Overskriften følger med, når man ruller i en lang filterliste — ellers er
     lukkekrydset væk efter to swipes, og så er backdrop'en den eneste udvej. */
  .filters[data-open="true"] .filters__head {
    position: sticky;
    top: -16px;
    z-index: 1;
    background: var(--snow);
    margin: -16px -18px 0;
    padding: 14px 18px;
    border-bottom: 1px solid var(--line);
  }

  .filters[data-open="true"] .filters__close { display: block; }

  .filters-backdrop:not([hidden]) {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 59;
    background: rgba(15, 15, 15, 0.42);
    border: 0;
  }
}

@keyframes filters-in { from { transform: translateX(-100%); } to { transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .filters[data-open="true"] { animation: none; }
}

/* A-Z-panelets Tilbehør-sektion (Marc 2/9): lille overskrift over den udskilte
   tilbehørsliste, samme versal-formsprog som megaens kolonneoverskrifter. */
.mega__index-h { font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; font-weight: 600; color: var(--ink-soft); margin: 20px 0 10px; padding-top: 14px; border-top: 1px solid var(--line); }
