:root {
    --navy-950: #122c56;
    --navy-900: #17346a;
    --navy-800: #1f3f7c;
    --navy-700: #2a4f92;
    --navy-600: #3760ab;
    --lime: #a6ff1e;
    --lime-dark: #8be000;
    --lime-soft: rgba(166, 255, 30, 0.14);
    --bg: #f4f6fa;
    --card: #ffffff;
    --text: #101828;
    --text-muted: #5c6579;
    --border: #e4e8f0;
    --danger: #e0435b;
    --radius: 12px;
    --shadow: 0 2px 10px rgba(10, 23, 48, 0.06);
    --shadow-hover: 0 8px 24px rgba(10, 23, 48, 0.12);
    --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }

body {
    margin: 0;
    font-family: var(--font);
    background: var(--bg);
    color: var(--text);
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, h4 { line-height: 1.2; margin: 0 0 0.5em; font-weight: 700; }
p { margin: 0 0 1em; }

.container {
    width: 100%;
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 20px;
}

/* Buttons */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 12px 22px;
    border-radius: 999px;
    font-weight: 700;
    font-size: 0.95rem;
    border: 2px solid transparent;
    cursor: pointer;
    transition: transform 0.12s ease, box-shadow 0.12s ease, background 0.12s ease;
    white-space: nowrap;
}
.btn:active { transform: scale(0.97); }
.btn-primary {
    background: var(--lime);
    color: var(--navy-950);
}
.btn-primary:hover { background: var(--lime-dark); box-shadow: 0 4px 14px rgba(166, 255, 30, 0.35); }
.btn-outline {
    background: transparent;
    border-color: var(--navy-700);
    color: var(--navy-800);
}
.btn-outline:hover { background: var(--navy-800); color: #fff; }
.btn-ghost {
    background: transparent;
    color: inherit;
}
.btn-danger { background: var(--danger); color: #fff; }
.btn-block { width: 100%; }
.btn-sm { padding: 8px 16px; font-size: 0.85rem; }

/* Header */
.site-header {
    background: var(--navy-950);
    color: #fff;
    position: sticky;
    top: 0;
    z-index: 50;
    border-bottom: 1px solid rgba(255,255,255,0.06);
}
/* VoIP en Mobiel only — requested live 2026-09-05: once the subbar below got lightened to
   navy-600, the logo bar's own navy-950 read as "zwart" by contrast. A modest step up (still the
   darker of the two bars, just not near-black next to it) fixes that without touching VDB
   Computers, whose subbar stayed navy-900 and never had this contrast problem. */
.brand-voip .site-header { background: var(--navy-900); }
.header-inner {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 20px;
    padding: 16px 20px;
}
.header-left { display: flex; align-items: center; justify-self: start; min-width: 0; }
.header-center { justify-self: center; }
.logo {
    display: inline-flex;
    align-items: center;
    line-height: 0;
    flex-shrink: 0;
}
.logo img { height: 44px; width: auto; display: block; }
/* See partials/header.php — a wider-drawn wordmark logo (VoIP en Mobiel) renders visibly
   wider than a narrower one (VDB Computers) at the same height; a shorter height here brings
   its rendered WIDTH back in line instead, which is what actually reads as "the same size". */
.logo-img--compact { height: 36px; }

.header-subbar { background: var(--navy-900); border-top: 1px solid rgba(255,255,255,0.08); }
/* VoIP en Mobiel only — requested live 2026-09-05: the menu-button bar (Webwinkel/Vaste
   Telefonie/Mobiele Telefonie/...) needed clearer contrast against the logo bar above it; navy-900
   sat too close to the header's own navy-950. A noticeably lighter navy keeps it in the same
   palette (not a new color) while actually reading as two distinct bars. VDB Computers is
   untouched — its .header-subbar keeps the rule right above. */
.brand-voip .header-subbar { background: var(--navy-600); border-top-color: rgba(255,255,255,0.12); }
.header-subbar .container { padding-top: 10px; padding-bottom: 10px; }

.main-nav { display: flex; gap: 24px; align-items: center; flex-wrap: wrap; }

/* Admin-pinned quick-access category buttons (e.g. "Notebooks") shown directly in the subbar,
   next to — not inside — the "Categorieën" dropdown. Outline style so the lime dropdown button
   still reads as the primary "browse everything" action. */
.header-subbar-link {
    display: inline-flex;
    align-items: center;
    color: rgba(255,255,255,0.85);
    font-weight: 700;
    font-size: 0.78rem;
    padding: 6px 12px;
    border-radius: 999px;
    border: 1.5px solid rgba(255,255,255,0.25);
    transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.header-subbar-link:hover { background: rgba(255,255,255,0.1); border-color: var(--lime); color: var(--lime); }

/* Standalone "Internet Postcode check" button — its own light-blue accent (distinct from the lime
   primary action and the now-outline "Tarieven en diensten"), pushed to the far right of the bar
   via the flex auto-margin trick (.main-nav is already display:flex, so this needs no wrapper).
   Requested live 2026-09-03. */
.header-subbar-link--postcode {
    margin-left: auto;
    background: #4fc3f7;
    border-color: #4fc3f7;
    color: var(--navy-950);
}
.header-subbar-link--postcode:hover { background: #29b6f6; border-color: #29b6f6; color: var(--navy-950); }

.nav-dropdown { position: relative; }
.nav-dropdown-toggle {
    background: var(--lime);
    border: none;
    border-radius: 999px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-family: inherit;
    color: var(--navy-950);
    font-weight: 700;
    font-size: 0.9rem;
    padding: 9px 16px;
    transition: background 0.15s;
}
.nav-dropdown-toggle:hover { background: #95e619; }
.nav-dropdown-toggle svg { transition: transform 0.15s; }
.nav-dropdown.open .nav-dropdown-toggle { background: #95e619; }
.nav-dropdown.open .nav-dropdown-toggle svg { transform: rotate(180deg); }

/* "Tarieven en diensten" (and the other menu buttons sharing this class) — kept borderless/plain
   so the lime "Webwinkel" button (the primary, most-clicked action) stays the one colored pill in
   the bar; still a .nav-dropdown-toggle underneath so the open/hover JS and chevron rotation all
   keep working unchanged. Originally had a white pill border (requested live 2026-09-03: "de knop
   Tarieven en diensten wel witte letters witte rand ... zo springt de webwinkel knop er uit"), but
   with 4 of these now in the bar (Tarieven/Diensten/Contact/Support) that read as "druk" and "niet
   zo professioneel" — dropped to a plain text-style link, same white-on-hover-lime feedback minus
   the outlined pill shape. Same specificity as the base rules above (one class each) — this only
   wins because it's declared after them, so keep any future edits to that base block above these. */
.nav-dropdown-toggle--outline { background: transparent; border: 1.5px solid transparent; color: #fff; font-weight: 500; padding-left: 2px; padding-right: 2px; }
.nav-dropdown-toggle--outline:hover,
.nav-dropdown.open .nav-dropdown-toggle--outline { background: transparent; border-color: transparent; color: var(--lime); }
/* Two-panel mega-menu: top-level categories on the left, the hovered/tapped one's
   subcategories flip in on the right — same pattern as Coolblue/MediaMarkt/Bol.com use once a
   catalog has too many categories for one flat scrolling list. */
.nav-megamenu {
    display: none;
    position: absolute;
    top: calc(100% + 18px);
    left: 0;
    width: 580px;
    max-width: 90vw;
    background: #fff;
    border-radius: var(--radius);
    box-shadow: 0 16px 36px rgba(9,20,45,0.25);
    overflow: hidden;
    z-index: 60;
}
.nav-dropdown.open .nav-megamenu { display: flex; }
.nav-megamenu-list {
    width: 230px;
    flex-shrink: 0;
    background: #f7f8fb;
    border-right: 1px solid var(--border);
    padding: 8px;
    overflow-y: auto;
    max-height: 70vh;
}
.nav-megamenu-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    width: 100%;
    background: none;
    border: none;
    text-align: left;
    font-family: inherit;
    padding: 10px 12px;
    border-radius: 8px;
    color: var(--navy-950);
    font-weight: 600;
    font-size: 0.88rem;
    cursor: pointer;
}
.nav-megamenu-item svg { color: var(--text-muted); flex-shrink: 0; }
.nav-megamenu-item:hover, .nav-megamenu-item.active { background: #fff; color: var(--navy-800); box-shadow: 0 1px 4px rgba(9,20,45,0.08); }
.nav-megamenu-item.active svg { color: var(--navy-800); }

.nav-megamenu-panels { flex: 1; min-width: 0; padding: 14px; overflow-y: auto; max-height: 70vh; }
.nav-megamenu-panel { display: none; flex-direction: column; }
.nav-megamenu-panel.active { display: flex; }
.nav-megamenu-panel a {
    display: block;
    padding: 8px 10px;
    border-radius: 8px;
    color: var(--navy-950);
    font-weight: 500;
    font-size: 0.88rem;
}
.nav-megamenu-panel a:hover { background: #f2f5fb; color: var(--navy-800); }
.nav-megamenu-panel-all {
    font-weight: 700 !important;
    color: var(--navy-800) !important;
    border-bottom: 1px solid var(--border);
    margin-bottom: 6px;
    padding-bottom: 10px !important;
    border-radius: 0 !important;
}
.nav-megamenu-back { display: none; }

/* A second, simpler dropdown ("Tarieven en diensten") — same .nav-dropdown-toggle button/open
   behavior as the Categorieën mega-menu, but a flat list of 2-3 plain links needs none of that
   component's two-column (list + panel) machinery, which is sized for real subcategory drill-
   down and would leave an oddly wide, mostly-empty box for a handful of flat links. */
.nav-simple-menu {
    display: none;
    position: absolute;
    top: calc(100% + 18px);
    left: 0;
    width: 260px;
    background: #fff;
    border-radius: var(--radius);
    box-shadow: 0 16px 36px rgba(9,20,45,0.25);
    overflow: hidden;
    z-index: 60;
    padding: 8px;
}
.nav-dropdown.open .nav-simple-menu { display: block; }
.nav-simple-menu a { display: block; padding: 10px 12px; border-radius: 8px; color: var(--navy-950); font-weight: 600; font-size: 0.88rem; }
.nav-simple-menu a:hover { background: #f2f5fb; color: var(--navy-800); }

.header-actions { display: flex; align-items: center; gap: 14px; justify-self: end; }

.contact-link {
    display: flex;
    align-items: center;
    color: #fff;
    padding: 6px;
    border-radius: 999px;
    transition: background 0.15s, color 0.15s;
}
.contact-link:hover { background: rgba(255,255,255,0.1); color: var(--lime); }

.admin-edit-link {
    display: flex;
    align-items: center;
    gap: 6px;
    background: #ff8a1e;
    color: #fff;
    font-size: 0.8rem;
    font-weight: 700;
    padding: 7px 12px;
    border-radius: 999px;
    white-space: nowrap;
}
.admin-edit-link:hover { background: #e67610; color: #fff; }

.print-link {
    display: flex;
    align-items: center;
    gap: 6px;
    background: #fff;
    color: var(--navy-900);
    border: 1px solid var(--border);
    font-size: 0.8rem;
    font-weight: 700;
    padding: 7px 12px;
    border-radius: 999px;
    white-space: nowrap;
}
.print-link:hover { background: var(--navy-900); color: #fff; border-color: var(--navy-900); }

.search-form { display: flex; align-items: center; background: rgba(255,255,255,0.08); border-radius: 999px; padding: 8px 8px 8px 20px; }
.search-form input {
    background: transparent;
    border: none;
    color: #fff;
    font-size: 0.95rem;
    width: 380px;
    outline: none;
}
.search-form input::placeholder { color: rgba(255,255,255,0.45); }
.search-form button { background: var(--lime); border: none; color: var(--navy-950); width: 36px; height: 36px; border-radius: 999px; cursor: pointer; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
/* Header search is hidden below 900px (see media query) since it doesn't fit alongside the
   icons — this mobile copy lives inside the hamburger menu instead, so search isn't lost. */
.search-form-mobile { display: none; }

/* Account/contact move into the hamburger menu on mobile too (see media query) — these are
   hidden here and only shown there, keeping the top row down to just cart + hamburger. */
.mobile-account-links { display: none; }
.mobile-account-link {
    display: flex;
    align-items: center;
    gap: 10px;
    color: rgba(255,255,255,0.9);
    font-weight: 600;
    font-size: 0.92rem;
    padding: 10px 12px;
    border-radius: 8px;
    transition: background 0.15s, color 0.15s;
}
.mobile-account-link:hover { background: rgba(255,255,255,0.1); color: var(--lime); }

.account-link {
    display: flex;
    align-items: center;
    gap: 8px;
    color: #fff;
    text-decoration: none;
    font-size: 0.88rem;
    font-weight: 600;
    padding: 6px 10px;
    border-radius: 999px;
    transition: background 0.15s, color 0.15s;
}
.account-link:hover { background: rgba(255,255,255,0.1); color: var(--lime); }
.account-link svg { flex-shrink: 0; }
.account-link-label { max-width: 130px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.cart-link {
    position: relative;
    display: flex;
    align-items: center;
    color: #fff;
    padding: 6px;
    border-radius: 999px;
    transition: background 0.15s, color 0.15s;
}
.cart-link:hover { background: rgba(255,255,255,0.1); color: var(--lime); }
.cart-badge {
    position: absolute;
    top: -4px;
    right: -6px;
    background: var(--lime);
    color: var(--navy-950);
    font-size: 0.68rem;
    font-weight: 800;
    min-width: 18px;
    height: 18px;
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 4px;
    border: 2px solid var(--navy-950);
}

.nav-toggle { display: none; background: none; border: none; color: #fff; font-size: 1.6rem; cursor: pointer; }

/* Hero */
.hero {
    background: linear-gradient(135deg, var(--navy-950) 0%, var(--navy-800) 100%);
    background-size: cover;
    background-position: center;
    color: #fff;
    padding: 72px 0;
    position: relative;
    overflow: hidden;
}
.hero::after {
    content: "";
    position: absolute;
    right: -120px;
    top: -120px;
    width: 420px;
    height: 420px;
    background: radial-gradient(circle, var(--lime-soft) 0%, transparent 70%);
}
/* An uploaded hero image already carries its own dark tones/light streaks — the lime glow
   decoration was designed for the flat gradient background and clashes on top of a photo. */
.hero.has-image::after { display: none; }
/* The dark gradient tint painted over an uploaded hero photo (for text legibility) was removed
   live 2026-09-05 — "over die afbeelding zit nu volgens mij een opacity dat wil ik niet" — this
   text-shadow keeps the heading/intro readable against a busy photo without darkening the image
   itself. */
.hero.has-image .hero-content h1,
.hero.has-image .hero-content p,
.hero.has-image .hero-content .eyebrow { text-shadow: 0 1px 10px rgba(0,0,0,0.7); }
.hero-inner { position: relative; }
.hero-content { max-width: 640px; text-align: left; }
.hero h1 { font-size: clamp(2rem, 4vw, 3rem); margin-bottom: 0.4em; }
.hero p { color: rgba(255,255,255,0.75); font-size: 1.1rem; margin-bottom: 1.6em; }

/* VoIP en Mobiel-only homepage sections — "Onze diensten" showcase grid, USP-band, overstap-CTA.
   Aangemaakt 2026-09-03: "ik wil dat je de frontpage echt maakt zoals providers dit doen". */
.hero-actions { display: flex; gap: 12px; flex-wrap: wrap; }
.btn-outline-light { background: transparent; color: #fff; border: 2px solid rgba(255,255,255,0.5); font-weight: 700; }
.btn-outline-light:hover { border-color: #fff; background: rgba(255,255,255,0.08); }

.service-tile-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 20px; }
.service-tile {
    display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
    background: var(--card); border: 1px solid var(--border); border-radius: var(--radius);
    padding: 26px 24px; box-shadow: var(--shadow); transition: box-shadow 0.15s, transform 0.15s;
    text-decoration: none; color: inherit;
}
.service-tile:hover { box-shadow: var(--shadow-hover); transform: translateY(-2px); }
.service-tile-icon {
    width: 48px; height: 48px; border-radius: 12px; background: var(--lime-soft); color: var(--navy-900);
    display: flex; align-items: center; justify-content: center; margin-bottom: 6px;
}
.service-tile h3 { margin: 0; font-size: 1.08rem; }
.service-tile p { margin: 0; color: var(--text-muted); font-size: 0.88rem; line-height: 1.6; }
.service-tile-price { font-size: 0.85rem; color: var(--text-muted); margin-top: 4px; }
.service-tile-price strong { color: var(--navy-900); font-size: 1rem; }
.service-tile-cta { margin-top: auto; padding-top: 14px; font-weight: 700; font-size: 0.86rem; color: var(--navy-700); }

.usp-band { background: #fff; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
/* padding-top/bottom only (not the shorthand) — same footgun as .section above: this element
   also carries class="container", and a padding:32px 0 shorthand here silently zeroes out
   .container's own horizontal padding since both are one-class selectors on the same element and
   this rule comes later in the file. Invisible on desktop (masked by .container's centering
   gutter past its 1200px max-width) but on mobile — full viewport width — it was the actual
   cause of the USP icons sitting flush against both screen edges, reported live 2026-09-04. */
.usp-band-inner { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 24px; padding-top: 32px; padding-bottom: 32px; }
.usp-item { display: flex; gap: 14px; align-items: flex-start; }
.usp-item svg { flex: none; color: var(--navy-800); margin-top: 2px; }
.usp-item strong { display: block; font-size: 0.94rem; margin-bottom: 2px; }
.usp-item span { color: var(--text-muted); font-size: 0.84rem; line-height: 1.5; }

.advice-split { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: center; }
.advice-split-text p { color: var(--text-muted); font-size: 1rem; line-height: 1.7; margin: 14px 0 22px; }
.advice-split-text h2 { margin: 6px 0 0; font-size: 1.7rem; }
.advice-split-img { width: 100%; height: 340px; object-fit: cover; border-radius: var(--radius); }
@media (max-width: 800px) {
    .advice-split { grid-template-columns: 1fr; }
    .advice-split-img { order: -1; height: 220px; }
}

.switch-banner {
    margin-top: 56px; background: linear-gradient(135deg, var(--navy-950) 0%, var(--navy-800) 100%);
    border-radius: 20px; padding: 40px 44px; display: flex; align-items: center; justify-content: space-between;
    gap: 28px; flex-wrap: wrap; color: #fff;
}
.switch-banner h2 { margin: 0 0 10px; font-size: 1.5rem; }
.switch-banner p { margin: 0; color: rgba(255,255,255,0.78); max-width: 520px; font-size: 0.94rem; line-height: 1.6; }

/* Onbezorgd-bellen flagship banner (homepage) — requested 2026-09-04: "wij hebben pakketten
   met onbezorgd bellen daarvan wil ik wel een mooie duidelijke grafisch sterke banner op de
   frontpage". Deliberately more graphic than .switch-banner (lime medallion + soundwave rings,
   pricing chips) so it reads as a distinct flagship-product highlight, not another plain CTA box. */
.callplan-banner {
    position: relative; overflow: hidden; margin-top: 56px;
    background: radial-gradient(120% 160% at 100% 0%, rgba(166,255,30,0.16) 0%, rgba(166,255,30,0) 55%), linear-gradient(135deg, var(--navy-950) 0%, var(--navy-800) 100%);
    border-radius: 24px; padding: 48px; display: flex; align-items: center; gap: 44px; color: #fff;
}
.callplan-banner-rings {
    position: absolute; right: -60px; top: 50%; transform: translateY(-50%);
    width: 320px; height: 320px; border-radius: 50%; border: 1px solid rgba(166,255,30,0.16); pointer-events: none;
}
.callplan-banner-rings::before, .callplan-banner-rings::after {
    content: ""; position: absolute; inset: 40px; border-radius: 50%; border: 1px solid rgba(166,255,30,0.16);
}
.callplan-banner-rings::after { inset: 80px; }
.callplan-banner-visual {
    flex: none; width: 128px; height: 128px; border-radius: 50%;
    background: linear-gradient(135deg, var(--lime) 0%, var(--lime-dark) 100%);
    display: flex; align-items: center; justify-content: center;
    box-shadow: 0 12px 32px rgba(166,255,30,0.28); position: relative; z-index: 1;
}
.callplan-banner-body { position: relative; z-index: 1; flex: 1; min-width: 280px; }
.callplan-banner-body h2 { margin: 0 0 10px; font-size: 1.7rem; }
.callplan-banner-body > p { margin: 0 0 24px; color: rgba(255,255,255,0.78); max-width: 560px; font-size: 0.96rem; line-height: 1.65; }
.callplan-price-row { display: flex; flex-wrap: wrap; gap: 14px; margin-bottom: 26px; }
.callplan-price {
    position: relative; background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.14);
    border-radius: 14px; padding: 14px 20px; min-width: 122px;
}
.callplan-price--best { background: rgba(166,255,30,0.1); border-color: var(--lime); padding-top: 22px; }
.callplan-price .callplan-price-badge {
    position: absolute; top: -8px; left: 14px; background: var(--lime); color: var(--navy-950);
    font-size: 0.56rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.03em;
    padding: 2px 7px; border-radius: 999px; line-height: 1.5;
}
.callplan-price strong { display: block; font-size: 0.82rem; font-weight: 700; color: rgba(255,255,255,0.75); margin-bottom: 4px; }
.callplan-price span { font-size: 1.3rem; font-weight: 800; color: #fff; }
.callplan-price span small { font-size: 0.68rem; font-weight: 600; color: rgba(255,255,255,0.6); }
.callplan-banner-actions { display: flex; gap: 14px; flex-wrap: wrap; align-items: center; }
.callplan-banner-note { margin: 16px 0 0; font-size: 0.82rem; color: rgba(255,255,255,0.55); }
@media (max-width: 760px) {
    .callplan-banner { flex-direction: column; align-items: flex-start; padding: 36px 28px; }
    .callplan-banner-rings { display: none; }
}

.folder-banner { background: linear-gradient(135deg, #ff8a1e 0%, #ffb347 100%); padding: 28px 0; }
.folder-banner-inner { display: flex; align-items: center; justify-content: space-between; gap: 20px; flex-wrap: wrap; }
.folder-banner-eyebrow { color: rgba(255,255,255,0.85); font-weight: 800; text-transform: uppercase; letter-spacing: 0.08em; font-size: 0.78rem; display: block; margin-bottom: 4px; }
.folder-banner h2 { color: #fff; margin: 0 0 4px; font-size: 1.6rem; }
.folder-banner p { color: rgba(255,255,255,0.92); margin: 0; font-size: 0.95rem; }
.folder-banner-btn { background: #fff; color: #ff8a1e; font-weight: 800; flex-shrink: 0; }
.folder-banner-btn:hover { background: var(--navy-950); color: #fff; }

/* Section headings */
/* padding-top/bottom only (not the shorthand) — .section is combined with .container as
   class="container section" on nearly every page, and a full `padding: 56px 0` shorthand here
   would silently override .container's horizontal padding to 0. Masked on desktop by the
   max-width:1200px centering gutter, but on mobile the container spans the full viewport, so
   this was the actual cause of content touching the screen edges on every page. */
.section { padding-top: 56px; padding-bottom: 56px; }
.section-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 28px; flex-wrap: wrap; gap: 12px; }
.section-head h2 { font-size: 1.6rem; }
.section-head a { color: var(--navy-700); font-weight: 700; font-size: 0.9rem; }
/* Site-wide "compacter op mobiel" (both brands) — requested live 2026-09-04: "op mobiel... zit er
   boven aan de pagina allemaal heel veel wit ruimte... mag dit wat kleiner qua tekst en
   compacter... mobiel heeft vaak een goede resolutie". Plain h1 had no font-size rule at all
   (falling back to the browser's ~32px default) and .section's 56px top padding was identical for
   a 1200px desktop page and a 380px phone — together the single biggest source of empty space
   before any real content on nearly every storefront page (.hero h1 and other already-sized
   headings are unaffected: their own selectors are more specific and win regardless). */
@media (max-width: 640px) {
    .section { padding-top: 28px; padding-bottom: 36px; }
    h1 { font-size: 1.6rem; }
    .section-head { margin-bottom: 18px; }
    .section-head h2 { font-size: 1.25rem; }
}
.eyebrow { color: var(--lime-dark); font-weight: 800; text-transform: uppercase; letter-spacing: 0.08em; font-size: 0.78rem; margin-bottom: 10px; display: block; }

.folder-category-heading { font-size: 1.3rem; margin: 0 0 18px; padding-bottom: 10px; border-bottom: 2px solid #ff8a1e; }

/* Category grid */
.category-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 20px; }
.category-card {
    background: var(--navy-900);
    color: #fff;
    border-radius: var(--radius);
    padding: 28px 24px;
    position: relative;
    overflow: hidden;
    transition: transform 0.15s ease;
}
.category-card:hover { transform: translateY(-4px); }
.category-card h3 { font-size: 1.15rem; margin-bottom: 6px; }
.category-card p { color: rgba(255,255,255,0.6); font-size: 0.88rem; margin-bottom: 0; }
.category-card .arrow { color: var(--lime); font-weight: 800; margin-top: 14px; display: inline-block; }

/* Category images are treated as ready-made marketing banners (own title/tagline/icons already
   baked in), not photos to crop-and-caption — so no dark overlay or duplicate heading text on
   top, just the banner itself in a clean bordered card, at its natural-ish 3:2 aspect ratio. */
.category-card-image { padding: 0; background: #fff; border: 1px solid var(--border); box-shadow: var(--shadow); aspect-ratio: 3 / 2; }
.category-card-image:hover { box-shadow: var(--shadow-hover); }
.category-card-image img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.25s ease; }
.category-card-image:hover img { transform: scale(1.04); }

/* Product grid */
.product-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 22px; }
/* Two columns of shrunk cards on mobile instead of one huge full-width card per row — requested
   live 2026-09-04: "op mobiel kun je ook als je door de producten scrolt 2 producten naast elkaar
   tonen als je de blokken half zo klein maakt op beide shops. maar op de pc moet het op beide
   shops hetzelfde blijven". Scoped to this one small-screen breakpoint only, so desktop/tablet
   (both brands) keep the exact same auto-fill 240px-minimum grid as before. Excludes the explicit
   .view-list toggle, which already has its own (single-column, full-width row) mobile styling
   further up that this shouldn't interfere with. */
@media (max-width: 640px) {
    .product-grid:not(.view-list) { grid-template-columns: repeat(2, 1fr); gap: 10px; }
    .product-grid:not(.view-list) .product-thumb { padding: 6px; }
    .product-grid:not(.view-list) .product-info { padding: 10px 10px 12px; gap: 4px; }
    .product-grid:not(.view-list) .product-name { font-size: 0.82rem; line-height: 1.3; }
    .product-grid:not(.view-list) .product-desc { display: none; }
    .product-grid:not(.view-list) .price { font-size: 1rem; }
    .product-grid:not(.view-list) .price-compare { font-size: 0.68rem; margin-right: 3px; }
    .product-grid:not(.view-list) .stock-indicator { font-size: 0.68rem; margin: 0 0 6px; }
    .product-grid:not(.view-list) .add-btn { width: 30px; height: 30px; font-size: 1.1rem; }
    .product-grid:not(.view-list) .badge { font-size: 0.58rem; padding: 4px 7px; top: 8px; left: 8px; letter-spacing: 0.02em; }
}
.product-card {
    background: var(--card);
    border-radius: var(--radius);
    overflow: hidden;
    box-shadow: var(--shadow);
    transition: box-shadow 0.15s ease, transform 0.15s ease;
    display: flex;
    flex-direction: column;
    position: relative;
    border: 1px solid var(--border);
    cursor: pointer;
}
.product-card:hover { box-shadow: var(--shadow-hover); transform: translateY(-3px); }
.product-thumb {
    aspect-ratio: 1 / 1;
    background: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    position: relative;
    padding: 10px;
}
.product-thumb img { width: 100%; height: 100%; object-fit: contain; }
.product-thumb .placeholder { color: #b7c0cf; font-size: 2rem; font-weight: 800; }
.badge {
    position: absolute;
    top: 12px;
    left: 12px;
    background: var(--lime);
    color: var(--navy-950);
    font-size: 0.7rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 5px 10px;
    border-radius: 999px;
}
.badge.sale { background: var(--danger); color: #fff; }
.badge.flyer { background: #ff8a1e; color: #fff; }
.product-info { padding: 16px 18px 18px; display: flex; flex-direction: column; gap: 6px; flex: 1; }
.product-cat { font-size: 0.75rem; color: var(--text-muted); font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; }
.product-name { font-size: 1rem; font-weight: 700; margin: 0; }
.product-name a { color: var(--text); }
.product-name a:hover { color: var(--navy-700); }
.product-desc { font-size: 0.85rem; color: var(--text-muted); flex: 1; }
.stock-indicator { font-size: 0.78rem; font-weight: 700; margin: 0 0 8px; }
.stock-indicator.in-stock { color: #1a8a4a; }
.stock-indicator.out-of-stock { color: var(--text-muted); }
.product-price-row { display: flex; align-items: center; justify-content: space-between; margin-top: 6px; }

.product-grid.view-list { display: flex; flex-direction: column; gap: 14px; }
.product-grid.view-list .product-card { flex-direction: row; }
.product-grid.view-list .product-card:hover { transform: none; }
.product-grid.view-list .product-thumb { width: 150px; height: 150px; aspect-ratio: unset; flex-shrink: 0; }
/* Titel is voldoende in lijstweergave — de korte omschrijving voegde weinig toe en maakte elke
   rij onnodig hoog/breed naast de al zichtbare titel, prijs en voorraadstatus. Was previously
   also the row's flex:1 spacer (see .product-price-row below for why that mattered). */
.product-grid.view-list .product-desc { display: none; }
/* The badge (e.g. "Folderaanbieding") sizes to fit its own text and is clipped by the thumb's
   overflow:hidden — fine at the grid view's much larger thumb, but the list view's fixed-width
   thumb is too narrow for the longer badge labels at full size, cutting them off mid-word.
   Shrunk specifically here rather than site-wide, since the grid view has plenty of room. */
.product-grid.view-list .badge { font-size: 0.6rem; padding: 4px 7px; top: 8px; left: 8px; letter-spacing: 0.02em; }
.product-grid.view-list .product-info { flex-direction: row; align-items: center; gap: 24px; padding: 14px 20px; }
/* Name takes all the space not used by the status+price block on the right, instead of a fixed
   220px — reads much better for this catalog's long Complies-style names ("Lenovo AIO
   ThinkCentre neo 50A | 27" Full HD IPS | ..."). */
.product-grid.view-list .product-name { flex: 1; width: auto; min-width: 0; }
/* Stock status stacked directly above the price/button, both right-aligned as one block — was
   previously a separate item floating between the name and price, which (once .product-desc's
   old flex:1-spacer role was removed) made every row's price sit at a different x-position
   depending on how long that product's status text happened to be. Grouping them removes that
   dependency entirely: .product-name's flex:1 consumes all the leftover space up to this block,
   so it's always flush right regardless of what precedes it. */
.product-grid.view-list .product-status-price { flex: 0 0 auto; display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
.product-grid.view-list .stock-indicator { margin: 0; }
.product-grid.view-list .product-price-row { margin-top: 0; gap: 16px; }
@media (max-width: 640px) {
    .product-grid.view-list .product-card { flex-direction: column; }
    .product-grid.view-list .product-thumb { width: 100%; height: auto; aspect-ratio: 1/1; }
    .product-grid.view-list .product-info { flex-direction: column; align-items: stretch; }
    .product-grid.view-list .product-name { width: auto; }
}

/* Category filter sidebar */
.category-layout { display: grid; grid-template-columns: 240px 1fr; gap: 40px; align-items: start; }
/* Mobile-only collapse toggle for .filter-sidebar (see the 900px media query below for its real
   styling) — hidden here by default so it never appears on desktop even without JS. */
.filter-toggle-btn { display: none; }
/* A parent category with no products of its own (only subcategories) shows a subcategory grid
   instead of a product list/filters — nothing to filter, so the sidebar column collapses away
   entirely rather than leaving a mostly-empty 240px gap next to it. */
.category-layout-no-sidebar { grid-template-columns: 1fr; }
/* A category with many spec facets (RAM, CPU, opslag, ...) stacks well past the viewport height
   — capping the sidebar itself and letting it scroll internally keeps it fully reachable while
   sticky, instead of overflowing off-screen and losing the lower filter groups until the page
   scrolls far enough to un-stick it entirely. */
.filter-sidebar {
    position: sticky;
    top: 90px;
    max-height: calc(100vh - 110px);
    overflow-y: auto;
    background: var(--card);
    border-radius: var(--radius);
    border: 1px solid var(--border);
    box-shadow: var(--shadow);
    padding: 20px 14px 20px 20px;
}
.filter-group { border-bottom: 1px solid var(--border); padding-bottom: 18px; margin-bottom: 18px; }
.filter-group:last-of-type { border-bottom: none; }
.filter-group h4 { font-size: 0.82rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.03em; color: var(--text-muted); margin: 0 0 12px; }
.filter-group .checkbox-row { margin-bottom: 10px; align-items: flex-start; }
.filter-group .checkbox-row:last-child { margin-bottom: 0; }
.filter-group .checkbox-row span { font-size: 0.9rem; }
.filter-group-scroll { max-height: 220px; overflow-y: auto; padding-right: 4px; }

/* Thin, muted scrollbars for the sidebar itself and each facet's inner value list — the default
   OS scrollbar is chunky/grey and clashes with the rest of the UI here. Kept deliberately subtle
   (matches --border, barely visible at rest) rather than the site's navy accent color — the
   navy version read as too dark/attention-grabbing for something that's just a scroll affordance. */
.filter-sidebar, .filter-group-scroll {
    scrollbar-width: thin;
    scrollbar-color: var(--border) transparent;
}
.filter-sidebar::-webkit-scrollbar, .filter-group-scroll::-webkit-scrollbar { width: 6px; }
.filter-sidebar::-webkit-scrollbar-track, .filter-group-scroll::-webkit-scrollbar-track { background: transparent; }
.filter-sidebar::-webkit-scrollbar-thumb, .filter-group-scroll::-webkit-scrollbar-thumb { background-color: var(--border); border-radius: 10px; }
.filter-sidebar::-webkit-scrollbar-thumb:hover, .filter-group-scroll::-webkit-scrollbar-thumb:hover { background-color: #c3cad9; }
.price-range-inputs { display: flex; align-items: center; gap: 8px; }
.price-range-inputs input { min-width: 0; padding: 8px 10px; font-size: 0.88rem; }
.price-range-inputs span { color: var(--text-muted); flex-shrink: 0; }
.filter-reset { display: inline-block; color: var(--danger); font-weight: 700; font-size: 0.85rem; }

.category-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 14px;
    margin-bottom: 24px;
    padding-bottom: 18px;
    border-bottom: 1px solid var(--border);
}
.category-toolbar-filters { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.view-toggle { display: flex; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.view-toggle button {
    background: #fff;
    border: none;
    padding: 8px 12px;
    cursor: pointer;
    display: flex;
    align-items: center;
    color: var(--text-muted);
}
.view-toggle button + button { border-left: 1px solid var(--border); }
.view-toggle button.active { background: var(--navy-950); color: #fff; }
.price { font-size: 1.25rem; font-weight: 800; color: var(--navy-900); }
.price-compare { font-size: 0.85rem; color: var(--text-muted); text-decoration: line-through; margin-right: 6px; }
.add-btn {
    width: 40px; height: 40px;
    border-radius: 999px;
    background: var(--navy-950);
    color: var(--lime);
    border: none;
    font-size: 1.3rem;
    cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    transition: background 0.15s;
    flex-shrink: 0;
}
.add-btn:hover { background: var(--lime); color: var(--navy-950); }
.add-btn:disabled { background: var(--border); color: var(--text-muted); cursor: not-allowed; }
.add-btn:disabled:hover { background: var(--border); color: var(--text-muted); }

/* Breadcrumbs */
.breadcrumbs { font-size: 0.85rem; color: var(--text-muted); margin-bottom: 20px; }
.breadcrumbs a:hover { color: var(--navy-800); }
.breadcrumbs span { margin: 0 6px; }
@media (max-width: 640px) {
    .breadcrumbs { font-size: 0.76rem; margin-bottom: 10px; }
}

/* Product detail */
.product-detail { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: start; }
.product-gallery { background: #fff; border: 1px solid var(--border); border-radius: var(--radius); aspect-ratio: 1/1; display: flex; align-items: center; justify-content: center; overflow: hidden; position: relative; padding: 20px; }
.product-gallery img { width: 100%; height: 100%; object-fit: contain; }
.product-gallery .placeholder { font-size: 3rem; font-weight: 800; color: #b7c0cf; }

.product-thumbs { display: flex; gap: 10px; margin-top: 12px; flex-wrap: wrap; }
.gallery-thumb {
    background: #fff;
    border: 2px solid var(--border);
    border-radius: 8px;
    width: 64px;
    height: 64px;
    padding: 0;
    overflow: hidden;
    cursor: pointer;
    flex-shrink: 0;
}
.gallery-thumb img { width: 100%; height: 100%; object-fit: contain; display: block; }
.gallery-thumb.active { border-color: var(--lime-dark); }
.gallery-thumb:hover { border-color: var(--navy-700); }
.product-main h1 { font-size: 1.9rem; }
.stock-line { font-weight: 700; font-size: 0.9rem; margin: 14px 0; }
.stock-line.in { color: #1a8a4a; }
.stock-line.low { color: #92650a; }
.stock-line.critical { color: var(--danger); }
.stock-line.out { color: var(--danger); }
.product-price-block { display: flex; align-items: baseline; gap: 10px; margin: 18px 0; }
.product-price-block .price { font-size: 2rem; }
.qty-form { display: flex; gap: 12px; align-items: center; margin-top: 24px; flex-wrap: wrap; }
.product-actions-row { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.product-actions-row .qty-form { margin-top: 0; }
.qty-input {
    width: 70px; padding: 12px; border-radius: 10px; border: 1.5px solid var(--border);
    font-size: 1rem; text-align: center;
}
.product-description { margin-top: 32px; border-top: 1px solid var(--border); padding-top: 24px; white-space: pre-line; color: var(--text-muted); }
/* Genuine HTML descriptions (Businesscom) bring their own <p>/<ul> spacing — pre-line would
   double up on that (literal newlines in the source markup rendered as extra line breaks on top
   of the browser's own block-level spacing). See product.php for how this class gets applied. */
.product-description-html { white-space: normal; }
.product-description-html p { margin: 0 0 12px; }
.product-description-html ul { margin: 0 0 12px; padding-left: 20px; }
.product-description-html li { margin-bottom: 4px; }
/* Long descriptions (common on synced products) pushed "Vaak samen besteld" far below the fold —
   collapsed to a fixed height by default with a fade-out + "Lees meer" toggle, JS decides
   whether the toggle is even needed (see product.php) so a short description never gets a
   pointless button. */
.product-description.collapsed { max-height: 220px; overflow: hidden; position: relative; }
.product-description.collapsed::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 50px; background: linear-gradient(to bottom, transparent, var(--bg)); pointer-events: none; }
.read-more-btn {
    display: inline-flex; align-items: center; gap: 4px; margin-top: 12px;
    background: none; border: none; padding: 0; color: var(--navy-600); font-weight: 700; font-size: 0.88rem; cursor: pointer;
}
.read-more-btn:hover { text-decoration: underline; }

/* Product specs — native <details>, collapsed by default, zero JS needed */
.product-specs { margin-top: 20px; border-top: 1px solid var(--border); padding-top: 20px; }
.product-specs summary { cursor: pointer; font-weight: 700; list-style: none; display: flex; align-items: center; gap: 6px; }
.product-specs summary::-webkit-details-marker { display: none; }
.product-specs summary::before { content: '+'; display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; font-weight: 800; color: var(--navy-600); }
.product-specs[open] summary::before { content: '−'; }

/* Product page's "Leverinformatie" toggle — collapsed by default so the leverbelofte explanation
   doesn't take up space unasked, styled as a real button rather than the plain-text disclosure
   .product-specs uses. Requested live 2026-09-05: "dat blok ingeklapt laten en dan als titel van
   de knop lever informatie, en dan er op klikken dan krijg je de uitleg". */
.delivery-info-toggle summary { cursor: pointer; list-style: none; display: inline-flex; }
.delivery-info-toggle summary::-webkit-details-marker { display: none; }
.specs-table { width: 100%; border-collapse: collapse; margin-top: 16px; font-size: 0.9rem; }
.specs-table tr { border-bottom: 1px solid var(--border); }
.specs-table tr:last-child { border-bottom: none; }
.specs-table th, .specs-table td { text-align: left; padding: 8px 0; font-weight: 400; }
.specs-table th { width: 45%; color: var(--text-muted); }

/* Reviews */
.product-rating-summary { display: inline-flex; align-items: center; gap: 6px; margin-bottom: 10px; font-size: 0.85rem; color: var(--text-muted); text-decoration: none; }
.product-rating-summary:hover { text-decoration: underline; }
.product-rating-summary .stars, .review-item-head .stars { color: #f5a623; letter-spacing: 1px; }
.reviews-list { display: flex; flex-direction: column; gap: 20px; max-width: 640px; }
.review-item { border-bottom: 1px solid var(--border); padding-bottom: 20px; }
.review-item:last-child { border-bottom: none; padding-bottom: 0; }
.review-item-head { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; flex-wrap: wrap; }
.review-item-title { font-weight: 700; margin: 0 0 4px; }
.review-item-body { color: var(--text-muted); margin: 0; white-space: pre-line; }
/* Interactive star picker: radios laid out highest-value-first then reversed visually, so a
   plain CSS sibling selector (~) can fill "this star and everything before it" on hover/checked
   without any JS. */
.star-rating-input { display: flex; flex-direction: row-reverse; justify-content: flex-end; gap: 2px; }
.star-rating-input input { position: absolute; opacity: 0; width: 0; height: 0; }
.star-rating-input label { font-size: 1.8rem; line-height: 1; color: var(--border); cursor: pointer; }
.star-rating-input input:checked ~ label,
.star-rating-input label:hover,
.star-rating-input label:hover ~ label { color: #f5a623; }

/* Forms */
.form-group { margin-bottom: 18px; }
.form-group label { display: block; font-weight: 700; font-size: 0.88rem; margin-bottom: 6px; }
.form-control {
    width: 100%; padding: 12px 14px; border-radius: 10px; border: 1.5px solid var(--border);
    font-size: 0.95rem; font-family: var(--font); background: #fff; color: var(--text);
}
.form-control:focus { outline: none; border-color: var(--navy-700); }
textarea.form-control { resize: vertical; min-height: 100px; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.checkbox-row { display: flex; align-items: center; gap: 8px; }
.checkbox-row input { width: 18px; height: 18px; }

.alert { padding: 14px 18px; border-radius: 10px; margin-bottom: 18px; font-size: 0.9rem; font-weight: 600; }
.alert-error { background: #fde8ea; color: #b3273f; }
.alert-success { background: var(--lime-soft); color: #3c6b00; }
.alert-info { background: #eaf1ff; color: var(--navy-800); }

/* Vinkjeslijst voor korte feitjes (bv. "Goed om te weten"-blokken) — vervangt een kale <ul> door
   een scanbaar 2-koloms rooster met check-icoontjes. Aangemaakt 2026-09-04: "de goed om te
   weten blok beneden kan visueel ook mooier". */
.check-list { display: grid; grid-template-columns: 1fr 1fr; gap: 14px 28px; margin: 0 0 24px; padding: 0; list-style: none; }
.check-list li { display: flex; align-items: flex-start; gap: 10px; font-size: 0.9rem; line-height: 1.55; color: var(--text-muted); }
.check-list li svg { flex: none; color: var(--lime-dark); margin-top: 3px; }
@media (max-width: 640px) { .check-list { grid-template-columns: 1fr; } }

/* Uitgelicht kader voor een uitzondering/voorwaarde binnen een pagina (bv. Fair Use Policy) —
   zelfde toon als .alert-info maar met een linkeraccent, iets steviger dan een losse alinea. */
.callout { background: #eaf1ff; border-left: 4px solid var(--navy-700); border-radius: 8px; padding: 16px 20px; font-size: 0.88rem; color: var(--navy-900); line-height: 1.6; }
.callout strong { color: var(--navy-950); }

/* Twee-koloms vergelijking (bv. 0800 vs 0900) — elke kaart met een eigen accentkleur bovenaan en
   een korte pro/con-lijst. Aangemaakt 2026-09-04. */
.compare-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 24px; }
.compare-card { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); padding: 24px; border-top: 4px solid var(--navy-700); }
.compare-card--alt { border-top-color: var(--lime-dark); }
.compare-card h3 { margin: 0 0 4px; font-size: 1.1rem; }
.compare-card .compare-price { color: var(--text-muted); font-size: 0.88rem; margin-bottom: 14px; }
.compare-card .compare-price strong { color: var(--navy-900); font-size: 1.05rem; }
.compare-card ul { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 8px; }
.compare-card li { display: flex; align-items: flex-start; gap: 8px; font-size: 0.86rem; line-height: 1.55; color: var(--text-muted); }
.compare-card li svg { flex: none; margin-top: 3px; }
.compare-card li.compare-pro svg { color: var(--lime-dark); }
.compare-card li.compare-caution svg { color: #b3273f; }
@media (max-width: 640px) { .compare-grid { grid-template-columns: 1fr; } }

/* Compacte variantenlijst (bv. 0900/0909/0906) — geen prijskaart, gewoon 3 korte definities op een rij. */
.variant-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 16px; margin: 0 0 20px; }
.variant-list-item { border: 1px solid var(--border); border-radius: 10px; padding: 14px 16px; }
.variant-list-item strong { display: block; margin-bottom: 4px; color: var(--navy-900); font-size: 0.92rem; }
.variant-list-item span { color: var(--text-muted); font-size: 0.84rem; line-height: 1.5; }

/* App Store / Google Play downloadknoppen — officiële badge-afbeeldingen i.p.v. kale tekstlinks. */
.app-badges { display: flex; gap: 14px; flex-wrap: wrap; margin: 4px 0 24px; }
.app-badges img { height: 44px; width: auto; display: block; }

/* Genummerde stappenlijst (bv. app installeren) met een optionele afbeelding ernaast op één stap. */
.step-list { counter-reset: step; list-style: none; margin: 0 0 20px; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.step-list li { counter-increment: step; position: relative; padding: 10px 0 10px 40px; border-bottom: 1px solid var(--border); font-size: 0.92rem; line-height: 1.6; color: var(--text-muted); }
.step-list li:last-child { border-bottom: none; }
.step-list li::before {
    content: counter(step); position: absolute; left: 0; top: 10px; width: 26px; height: 26px;
    border-radius: 50%; background: var(--lime); color: var(--navy-950); font-weight: 800; font-size: 0.82rem;
    display: flex; align-items: center; justify-content: center;
}
.step-list-qr { float: right; width: 84px; height: 84px; margin: 0 0 10px 14px; border-radius: 8px; }

/* Cart — .cart-table is reused (order-detail, dashboard, returns, return-form all have
   different column shapes than the real shopping cart), so the column-width percentages below
   are scoped to .cart-layout .cart-table specifically, not the bare class. */
.cart-table { width: 100%; border-collapse: collapse; table-layout: fixed; }
.cart-table th { text-align: left; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-muted); padding: 0 0 12px; border-bottom: 1px solid var(--border); }
.cart-table td { padding: 16px 12px 16px 0; border-bottom: 1px solid var(--border); vertical-align: middle; }
.cart-layout .cart-table th:nth-child(1), .cart-layout .cart-table td:nth-child(1) { width: 44%; }
.cart-layout .cart-table th:nth-child(2), .cart-layout .cart-table td:nth-child(2) { width: 14%; }
.cart-layout .cart-table th:nth-child(3), .cart-layout .cart-table td:nth-child(3) { width: 16%; }
.cart-layout .cart-table th:nth-child(4), .cart-layout .cart-table td:nth-child(4) { width: 16%; }
.cart-layout .cart-table th:nth-child(5), .cart-layout .cart-table td:nth-child(5) { width: 10%; padding-right: 0; }
/* order-detail.php reuses .cart-table with the same 5-column shape (Product/Prijs/Aantal/Totaal/acties)
   but is wrapped in .checkout-layout, not .cart-layout, so it needs its own matching width rules —
   see the "reused across ... each with a different column count" note in the mobile breakpoint above. */
.order-detail-table th:nth-child(1), .order-detail-table td:nth-child(1) { width: 44%; }
.order-detail-table th:nth-child(2), .order-detail-table td:nth-child(2) { width: 14%; }
.order-detail-table th:nth-child(3), .order-detail-table td:nth-child(3) { width: 16%; }
.order-detail-table th:nth-child(4), .order-detail-table td:nth-child(4) { width: 16%; }
.order-detail-table th:nth-child(5), .order-detail-table td:nth-child(5) { width: 10%; padding-right: 0; }
.cart-product { display: flex; align-items: center; gap: 14px; min-width: 0; }
.cart-thumb { width: 64px; height: 64px; border-radius: 8px; background: #fff; border: 1px solid var(--border); overflow: hidden; flex-shrink: 0; display:flex; align-items:center; justify-content:center; }
.cart-thumb img { width: 100%; height: 100%; object-fit: contain; }
.cart-product a { min-width: 0; line-height: 1.4; font-size: 0.88rem; }
.cart-summary { background: var(--card); border-radius: var(--radius); padding: 24px; box-shadow: var(--shadow); border: 1px solid var(--border); }
/* Neutral content card matching .cart-summary's own box treatment — for wrapping primary
   content (e.g. account/order-detail's items table + addresses) that would otherwise sit bare
   on the page background next to a boxed sidebar, looking visually unfinished by comparison. */
.content-card { background: var(--card); border-radius: var(--radius); padding: 24px; box-shadow: var(--shadow); border: 1px solid var(--border); }
.summary-row { display: flex; justify-content: space-between; margin-bottom: 12px; font-size: 0.95rem; }
.summary-row.total { font-weight: 800; font-size: 1.15rem; border-top: 1px solid var(--border); padding-top: 12px; margin-top: 4px; }
.cart-layout { display: grid; grid-template-columns: 1fr 340px; gap: 40px; align-items: start; }
/* The "Offerte" box sits under .cart-summary in markup order but belongs visually in the same
   340px right-hand column, not full-width under the product table — was previously an inline
   style="grid-column:2" on the element itself, which (being inline) silently overrode the mobile
   media query's .cart-layout { grid-template-columns: 1fr } collapse below: with only one column
   defined, a hard-coded "column 2" placement makes the grid fabricate an extra IMPLICIT column
   to satisfy it, so .cart-summary re-joined it there too — the exact "vreemd naast elkaar" report
   live 2026-09-02, present at every mobile width (not just the 641-900px gap fixed just above).
   A real class, reset explicitly in the same mobile block as the rest of .cart-layout, so there's
   nothing left that can out-rank the collapse. */
.cart-quote-card { grid-column: 2; margin-top: 20px; }
/* Was plain bold-red text ("oudbollig" per live feedback 2026-09-02) — now a quiet icon-only
   ghost button, muted by default and only turning red (the "this removes something" signal) on
   hover/focus, matching the SVG-icon language already used in the header (search/account/cart).
   Icon-only on every screen size now, not just mobile — the "Verwijderen" label stays in the DOM
   (visually hidden, not display:none) purely for screen readers/no-JS clarity. */
.remove-link {
    display: inline-flex; align-items: center; gap: 6px;
    background: none; border: none; cursor: pointer; padding: 4px;
    color: var(--text-muted); font-family: inherit;
    border-radius: 6px; transition: color 0.15s;
}
.remove-link:hover, .remove-link:focus-visible { color: var(--danger); }
.remove-link svg { flex-shrink: 0; }
.remove-link-label {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0, 0, 0, 0); white-space: nowrap;
}
.empty-state { text-align: center; padding: 80px 20px; color: var(--text-muted); }
.empty-state h2 { color: var(--text); }

/* Internetcheck (postcodechecker — VoIP en Mobiel) */
/* Same dark .hero band as the homepage, just a shorter one (no room needed for a "Bekijk
   assortiment" CTA — the form right below IS the call to action here) — negative margin pulls
   the white form card up to visually overlap the hero's bottom edge, the common "the tool is the
   hero" landing-page pattern, so the checker itself reads as the main event, not an afterthought
   under a wall of marketing copy. */
.internetcheck-hero { padding: 56px 0 96px; }
.internetcheck-hero .hero-content { max-width: 720px; }
.internetcheck-form-card { max-width: 720px; margin: -64px auto 0; position: relative; z-index: 1; box-shadow: var(--shadow-hover); }
.internetcheck-address-row { grid-template-columns: 2fr 1fr 1fr; }
.internetcheck-submit-btn { width: 100%; }

.internetcheck-usps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; padding: 44px 0 8px; max-width: 980px; margin: 0 auto; }
.internetcheck-usp { display: flex; gap: 14px; align-items: flex-start; }
.internetcheck-usp svg { flex-shrink: 0; color: var(--navy-800); margin-top: 2px; }
.internetcheck-usp h3 { margin: 0 0 4px; font-size: 1rem; }
.internetcheck-usp p { margin: 0; font-size: 0.86rem; color: var(--text-muted); line-height: 1.5; }

.internetcheck-address-heading { font-weight: 700; margin: 0 0 20px; color: var(--navy-900); font-size: 1.1rem; }
.internetcheck-supplier-group { margin-bottom: 32px; }
.internetcheck-supplier-head { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; padding-bottom: 10px; border-bottom: 2px solid var(--navy-900); flex-wrap: wrap; }
.internetcheck-supplier-head h2 { margin: 0; font-size: 1.15rem; }
.internetcheck-tech-badge { background: var(--lime-soft); color: var(--navy-900); font-size: 0.72rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.03em; padding: 3px 10px; border-radius: 999px; }
.internetcheck-recommended-badge { background: var(--navy-900); color: #fff; font-size: 0.72rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.03em; padding: 3px 10px; border-radius: 999px; }
.internetcheck-supplier-count { margin-left: auto; color: var(--text-muted); font-size: 0.82rem; }
/* The priority (FIBEROPERATOR) group's own underline picks up the brand lime instead of plain
   navy — sorted first by icRenderResults() already, this is the extra visual "this one" nudge
   requested alongside it (2026-09-02), without a heavier treatment (e.g. a full card background
   tint) that would fight the result cards' own already-established white-card look. */
.internetcheck-supplier-group--priority .internetcheck-supplier-head { border-bottom-color: var(--lime-dark); }
.internetcheck-supplier-logo { height: 28px; width: auto; max-width: 120px; object-fit: contain; }

.internetcheck-result { margin-bottom: 16px; transition: box-shadow 0.15s, transform 0.15s; }
.internetcheck-result:hover { box-shadow: var(--shadow-hover); transform: translateY(-1px); }
.internetcheck-result-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; margin-bottom: 14px; }
/* [hidden] guard load-bearing here too, same reason as .internetcheck-vastrecht-note's own —
   a plain class rule setting `display` beats the UA stylesheet's low-specificity
   `[hidden] { display: none }`, so without this a result with no logo set would still reserve
   an empty image box. */
.internetcheck-result-logo[hidden] { display: none; }
.internetcheck-result-logo { height: 56px; width: auto; max-width: 130px; object-fit: contain; flex-shrink: 0; }
.internetcheck-result-head-text { flex: 1; min-width: 0; }
.internetcheck-result-name { margin: 0 0 4px; font-size: 1.1rem; }
.internetcheck-result-meta { margin: 0; font-size: 0.85rem; }
.internetcheck-result-price { text-align: right; font-size: 1.5rem; font-weight: 800; color: var(--navy-900); white-space: nowrap; }
.internetcheck-result-price span { font-size: 0.75rem; font-weight: 600; color: var(--text-muted); }
.internetcheck-onetime { font-size: 0.78rem !important; }
.internetcheck-on-request { font-size: 0.95rem; color: var(--navy-800); }
/* [hidden] guard is load-bearing, not decorative — a plain class rule setting `display` beats
   the UA stylesheet's own low-specificity `[hidden] { display: none }`, so without this the note
   rendered for EVERY result regardless of its own hidden attribute (caught live via an actual
   rendered screenshot, not just reasoned from the CSS — two test cards, one true/one false,
   both showed the box until this was added). */
.internetcheck-vastrecht-note[hidden] { display: none; }
.internetcheck-vastrecht-note {
    display: flex; align-items: flex-start; gap: 10px;
    background: #fff4d6; color: #7a5300; border-radius: 8px;
    padding: 12px 14px; margin: 14px 0 0; font-size: 0.82rem; line-height: 1.5;
}
.internetcheck-vastrecht-note svg { flex-shrink: 0; margin-top: 1px; }
.internetcheck-lead-form { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--border); }

.internetcheck-loading { display: flex; align-items: center; gap: 12px; padding: 32px 20px; color: var(--text-muted); font-size: 0.95rem; }
.internetcheck-spinner {
    width: 20px; height: 20px; flex-shrink: 0; border-radius: 50%;
    border: 2.5px solid var(--border); border-top-color: var(--navy-800);
    animation: internetcheck-spin 0.7s linear infinite;
}
@keyframes internetcheck-spin { to { transform: rotate(360deg); } }
@media (max-width: 900px) {
    .internetcheck-usps { grid-template-columns: 1fr; gap: 20px; }
}
@media (max-width: 640px) {
    .internetcheck-hero { padding: 40px 0 80px; }
    .internetcheck-form-card { margin-top: -56px; }
    .internetcheck-address-row { grid-template-columns: 1fr; }
    .internetcheck-result-head { flex-direction: column; }
    .internetcheck-result-price { text-align: left; }
    .internetcheck-supplier-count { margin-left: 0; width: 100%; }
    /* Requested "op een pc" specifically (2026-09-02) — already shown once per supplier group
       heading regardless, so on a narrow screen the per-card repeat is dropped rather than
       taking up scarce width next to the price. */
    .internetcheck-result-logo { display: none; }
}

/* Tarieven vaste telefonie (VoIP en Mobiel) */
.pricing-section { margin-bottom: 48px; }
.pricing-section h2 { margin: 0 0 8px; font-size: 1.4rem; }
.pricing-section > .text-muted { margin: 0 0 20px; }
/* auto-fit/minmax instead of a fixed column count: a fixed repeat(4,1fr)/repeat(3,1fr) reserved
   that many tracks regardless of how many cards (or how wide the container) actually was — a
   single dienst in a "Rij" column (see block-row-col) still only got 1 of 3-4 tracks, ~25-33%
   width instead of filling its column. Reported live 2026-09-03: "dan is het blok van het
   product maar 50% breed van dat hele blok". auto-fit also reacts to the *container's* own width,
   not just the viewport — a card inside a narrow row-column on an otherwise-wide desktop screen
   needs to collapse to one column there too, which a viewport media query alone could never do
   (removed the old max-width:1024px/640px overrides below for the same reason — auto-fit already
   handles every width, including ones a breakpoint never anticipated). --wide is now identical to
   the base rule; kept as a distinct class only so the existing PHP that emits it doesn't need to
   change. */
.pricing-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 20px; }
.pricing-grid--wide { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.pricing-card {
    background: var(--card); border: 1px solid var(--border); border-radius: var(--radius);
    padding: 24px; display: flex; flex-direction: column; box-shadow: var(--shadow);
}
.pricing-card--highlight { border-color: var(--navy-800); box-shadow: var(--shadow-hover); position: relative; }
.pricing-card h3 { margin: 0 0 10px; font-size: 1.1rem; }
.pricing-card-price { font-size: 1.7rem; font-weight: 800; color: var(--navy-900); margin-bottom: 16px; }
.pricing-card-price span { font-size: 0.8rem; font-weight: 600; color: var(--text-muted); }
.pricing-card ul { list-style: none; margin: 0 0 20px; padding: 0; flex: 1; }
.pricing-card li { padding: 6px 0; border-bottom: 1px solid var(--border); font-size: 0.88rem; }
.pricing-card li:last-child { border-bottom: none; }
.pricing-card-warn { color: var(--danger); }
.pricing-card--compact ul { margin-bottom: 16px; }
.pricing-footnote { font-size: 0.8rem; color: var(--text-muted); margin-top: 16px; line-height: 1.6; }
.pricing-info-list { margin: 0; padding-left: 20px; color: var(--text-muted); line-height: 1.7; font-size: 0.9rem; }
.pricing-info-list li { margin-bottom: 8px; }

/* Uitklapbare FAQ-items op de /faq pagina — native <details>/<summary>, geen JS nodig. Aangemaakt
   2026-09-03: "kun je faq uitklapbare items maken?". */
.faq-list { display: flex; flex-direction: column; gap: 10px; }
.faq-item { border: 1px solid var(--border); border-radius: 10px; padding: 0 20px; }
.faq-item summary { list-style: none; display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 16px 0; font-weight: 700; cursor: pointer; }
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item-chevron { flex: none; transition: transform 0.15s; color: var(--text-muted); }
.faq-item[open] .faq-item-chevron { transform: rotate(180deg); }
.faq-item p { margin: 0 0 18px; color: var(--text-muted); line-height: 1.7; }

/* Betaalmethoden-overzicht op de /betaalmethoden pagina — aangemaakt 2026-09-03. */
.payment-method-list { display: flex; flex-direction: column; gap: 20px; }
.payment-method { display: flex; align-items: center; gap: 20px; }
.payment-method-icon { width: 56px; height: 56px; object-fit: contain; flex: none; }
.payment-method-icon--svg { display: flex; align-items: center; justify-content: center; }
.payment-method h3 { margin: 0 0 4px; font-size: 1rem; }
.payment-method p { margin: 0; color: var(--text-muted); font-size: 0.9rem; line-height: 1.6; }

/* Downloads-overzicht op de /downloads pagina — aangemaakt 2026-09-03. */
.download-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 20px; }
.download-block { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); padding: 20px 22px; }
.download-block h4 { margin: 0 0 10px; font-size: 0.95rem; }
.download-block ul { margin: 0; padding: 0; list-style: none; }
.download-block li { border-bottom: 1px solid var(--border); }
.download-block li:last-child { border-bottom: none; }
.download-block a { display: flex; align-items: center; gap: 10px; padding: 8px 0; font-size: 0.85rem; color: var(--navy-800); }
.download-block a:hover { color: var(--lime-dark, var(--navy-950)); }
.download-block a:hover span:last-child { text-decoration: underline; }

/* Kleine bestandstype-badges v&oacute;&oacute;r elke downloadlink — aangemaakt 2026-09-04: "en nu
   deze pagina knap maken" (was een kale opsomming van tekstlinks zonder enig visueel houvast). */
.file-badge { flex: none; display: inline-flex; align-items: center; justify-content: center; min-width: 34px; height: 18px; padding: 0 5px; border-radius: 4px; font-size: 0.62rem; font-weight: 800; letter-spacing: 0.02em; }
.file-badge--pdf { background: #fde8ea; color: #b3273f; }
.file-badge--zip { background: #fff3d6; color: #9c6500; }
.file-badge--exe { background: #eaf1ff; color: var(--navy-700); }
.file-badge--mac { background: rgba(11,125,115,0.14); color: #0b7d73; }
.file-badge--bin { background: #eef0f4; color: var(--text-muted); }
.file-badge--link { background: var(--lime-soft); color: #3c6b00; }

/* Partnerkaarten op de /partners pagina — aangemaakt 2026-09-03. */
.partner-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 16px; margin-top: 8px; }
.partner-card { background: #fff; border: 1px solid var(--border); border-radius: 10px; padding: 18px 20px; }
.partner-card-logo { height: 40px; max-width: 100%; width: auto; object-fit: contain; object-position: left; display: block; margin-bottom: 12px; }
.partner-card h4 { margin: 0 0 8px; font-size: 1rem; }
.partner-card p { margin: 0 0 4px; color: var(--text-muted); font-size: 0.85rem; }
.partner-card p a { color: var(--text-muted); }
.partner-card-link { display: inline-block; margin-top: 10px; font-size: 0.85rem; font-weight: 700; color: var(--navy-800); }

/* API-response voorbeelden op de /api pagina — een leesbare monospace box in plaats van de oude
   site's kale &nbsp;/<br>-opmaak met blauwe tekst. Aangemaakt 2026-09-03. */
.api-example { background: #f4f6fa; border-radius: 8px; padding: 14px 18px; margin: 0 0 20px; font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 0.82rem; line-height: 1.6; color: var(--navy-800); white-space: pre-wrap; overflow-x: auto; }

/* Missing from this stylesheet entirely — every "mb-0" use on the storefront (cart.php and
   these tarieven pages both) has been a silent no-op ever since, only ever defined in admin.css.
   Added here so it actually does what every caller already assumed. */
.mb-0 { margin-bottom: 0; }

/* "Compact" dienstenblok-weergave — naam + prijs zonder kenmerkenlijst, voor blokken met veel
   diensten waar een volledige prijskaart per stuk te veel ruimte zou kosten. */
.service-chip-grid { display: flex; flex-wrap: wrap; gap: 10px; }
.service-chip {
    display: inline-flex; align-items: baseline; gap: 8px;
    background: var(--card); border: 1px solid var(--border); border-radius: 999px;
    padding: 10px 16px; font-size: 0.88rem;
}
.service-chip--highlight { border-color: var(--navy-800); box-shadow: var(--shadow); }
.service-chip-name { font-weight: 700; color: var(--navy-900); }
.service-chip-price { color: var(--text-muted); }
.service-chip-price small { font-size: 0.78rem; }

/* Gegroepeerde kenmerkenlijst met een accentkleur per groep — vervangt een kale <ul> voor lange
   functie-opsommingen (PBX, straks mogelijk ook elders). Ontwerp goedgekeurd 2026-09-03 (zie het
   voorstel-artifact); --grp/--grp-bg worden per .feature-group inline gezet zodat één CSS-blok
   elke groep zijn eigen kleur geeft zonder aparte klassen per kleur. */
.feature-group { --grp: var(--navy-900); --grp-bg: rgba(23,52,106,0.12); margin-bottom: 28px; }
.feature-group:last-child { margin-bottom: 0; }
.feature-group-label {
    font-size: 0.72rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
    color: var(--text-muted); margin: 0 0 14px; display: flex; align-items: center; gap: 10px;
}
.feature-group-label::before { content: ""; width: 9px; height: 9px; border-radius: 50%; background: var(--grp); flex-shrink: 0; }
.feature-group-label::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.feature-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px 20px; }
.feature-row { display: flex; gap: 12px; align-items: flex-start; padding: 12px 0; border-bottom: 1px solid var(--border); }
.feature-icon-box {
    width: 34px; height: 34px; border-radius: 9px; background: var(--grp-bg);
    display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.feature-icon-box svg { width: 18px; height: 18px; stroke: var(--grp); fill: none; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.feature-row-title { font-size: 0.9rem; font-weight: 700; color: var(--text); margin: 0 0 2px; }
.feature-row-desc { font-size: 0.83rem; color: var(--text-muted); line-height: 1.45; margin: 0; }
@media (max-width: 720px) { .feature-grid { grid-template-columns: 1fr; } }

/* Elementor-achtige paginablokken (titel/afbeelding/knop/kolommen) — zie
   views/storefront/tariff-page-blocks.php en PageBlock::KINDS. */
.block-heading h2 { margin: 0 0 8px; }
.block-heading-sub { color: var(--text-muted); font-size: 1rem; line-height: 1.6; }

/* Grote, donkere "verkoopbanner" bovenaan een tarievenpagina — vervangt het eerdere platte
   witte kaartje (te veel witruimte rond de illustratie) door iets dat aanvoelt als de hero-
   achtige promoblokken van grote providers: donkere gradient, badge, grote kop, CTA-knop en een
   illustratie die tot de rand van het blok doorloopt. Aangemaakt 2026-09-04 na "dat blok heeft
   extreem veel witruimte rechts en onder, neem eens een voorbeeld van andere grotere
   verkoopsites". Geschreven als los stuk HTML in een tekstblok (niet het generieke
   .block-image--split component), zodat dit ene bovenste blok zich mag onderscheiden van de
   rest van de (bewust rustigere) pagina.*/
.promo-banner {
    background: linear-gradient(135deg, var(--navy-950) 0%, var(--navy-800) 100%);
    border-radius: 20px; overflow: hidden; position: relative;
    display: grid; grid-template-columns: 1.15fr 0.85fr; align-items: end; min-height: 320px;
}
.promo-banner::after {
    content: ""; position: absolute; left: -80px; top: -80px; width: 320px; height: 320px;
    background: radial-gradient(circle, var(--lime-soft) 0%, transparent 70%); pointer-events: none;
}
.promo-banner-text { position: relative; z-index: 1; padding: 40px 20px 40px 44px; color: #fff; }
.promo-banner-badge {
    display: inline-block; background: var(--lime); color: var(--navy-950); font-weight: 800;
    font-size: 0.74rem; text-transform: uppercase; letter-spacing: 0.05em; padding: 5px 12px;
    border-radius: 999px; margin-bottom: 14px;
}
.promo-banner h2 { color: #fff; font-size: clamp(1.5rem, 2.6vw, 2rem); margin: 0 0 14px; line-height: 1.2; }
.promo-banner p { color: rgba(255,255,255,0.78); font-size: 0.98rem; line-height: 1.7; margin: 0 0 24px; max-width: 460px; }
.promo-banner-credit { color: rgba(255,255,255,0.4); font-size: 0.7rem; display: block; margin-top: 16px; }
.promo-banner-figure { position: relative; z-index: 1; align-self: end; justify-self: end; height: 100%; display: flex; align-items: flex-end; }
.promo-banner-figure img { max-height: 340px; width: auto; display: block; }
@media (max-width: 780px) {
    .promo-banner { grid-template-columns: 1fr; }
    .promo-banner-figure { justify-self: center; order: -1; padding-top: 20px; }
    .promo-banner-figure img { max-height: 220px; }
    .promo-banner-text { padding: 28px 24px 32px; }
}

/* display:flex + centered content only matters for a lone image (no --split text next to it) —
   e.g. an image sitting in its own row-column, stretched to match a taller sibling column. Without
   this it top-aligns and leaves dead space below. .block-image--split overrides display to grid
   further down, so this never affects the existing text+image layout. */
.block-image { background: var(--card); border-radius: var(--radius); border: 1px solid var(--border); padding: 24px; display: flex; flex-direction: column; justify-content: center; }
.block-image-figure { margin: 0; }
.block-image-figure img { width: 100%; height: auto; border-radius: 8px; display: block; }
.block-image-figure figcaption { font-size: 0.82rem; color: var(--text-muted); margin-top: 8px; }
.block-image--split { display: grid; grid-template-columns: 1fr 1fr; gap: 28px; align-items: center; }
.block-image--split h2 { grid-column: 1 / -1; }
.block-image--split.block-image--right .block-image-figure { order: 2; }
.block-image--split .block-image-text { font-size: 0.95rem; line-height: 1.65; }
@media (max-width: 720px) { .block-image--split { grid-template-columns: 1fr; } .block-image--split .block-image-figure { order: 0 !important; } }

.block-button { background: var(--card); border-radius: var(--radius); border: 1px solid var(--border); padding: 24px; text-align: center; }
.block-button h2 { margin-top: 0; }
.block-button > div { color: var(--text-muted); margin-bottom: 16px; }

.block-columns-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 28px; }
.block-columns-col { background: var(--card); border-radius: var(--radius); border: 1px solid var(--border); padding: 24px; font-size: 0.95rem; line-height: 1.65; }
@media (max-width: 720px) { .block-columns-grid { grid-template-columns: 1fr; } }

/* "Rij" blok — 1 tot 6 kolommen (gelijk of verhouding, bv. 2:1), elk met hoogstens één ander blok
   erin (zie PageBlock::childrenForRow()). grid-template-columns komt rechtstreeks van het blok's
   column_layout (bv. "2:1" -> "2fr 1fr"), server-side berekend in renderTariffBlock(). */
.block-row { display: grid; gap: 28px; align-items: stretch; }
.block-row-col > .content-card, .block-row-col > .block-heading, .block-row-col > .block-image,
.block-row-col > .block-button, .block-row-col > .pricing-section { height: 100%; }
/* Toggleable per row (checkbox on the block's edit form) — off lets each column keep its own
   natural height instead of stretching to match its tallest sibling. Default stays "aan" (no
   class added) so every row built before this option existed keeps rendering exactly as before. */
.block-row--natural { align-items: start; }
.block-row--natural .block-row-col > .content-card, .block-row--natural .block-row-col > .block-heading,
.block-row--natural .block-row-col > .block-image, .block-row--natural .block-row-col > .block-button,
.block-row--natural .block-row-col > .pricing-section { height: auto; }
@media (max-width: 720px) { .block-row { grid-template-columns: 1fr !important; } }

/* Kleurthema per dienstenblok (rand + knopkleur) — zie PageBlock::ACCENTS. 'standaard' voegt geen
   klasse toe en blijft dus exact zoals de bestaande, hardcoded navy/lime-stijl hierboven.
   Requested live 2026-09-03: "wil ik eigenlijk ook verschillende templates zodat er bijvoorbeeld
   kleuren in de randen zitten knoppen andere kleur enz dat ik wat variatie er in kan brengen".
   Dezelfde vier kleuren als het eerder goedgekeurde kenmerken-blok op de PBX-pagina, voor
   herkenbaarheid over de site heen. */
.pricing-section--accent-lime .pricing-card,
.pricing-section--accent-coral .pricing-card,
.pricing-section--accent-amber .pricing-card,
.pricing-section--accent-teal .pricing-card { border-top-width: 4px; }
.pricing-section--accent-lime .pricing-card { border-top-color: var(--lime); }
.pricing-section--accent-coral .pricing-card { border-top-color: #c1451f; }
.pricing-section--accent-amber .pricing-card { border-top-color: #9c6500; }
.pricing-section--accent-teal .pricing-card { border-top-color: #0b7d73; }

.pricing-section--accent-lime .pricing-card--highlight { border-color: var(--lime); box-shadow: 0 8px 24px rgba(166,255,30,0.3); }
.pricing-section--accent-coral .pricing-card--highlight { border-color: #c1451f; box-shadow: 0 8px 24px rgba(193,69,31,0.25); }
.pricing-section--accent-amber .pricing-card--highlight { border-color: #9c6500; box-shadow: 0 8px 24px rgba(156,101,0,0.25); }
.pricing-section--accent-teal .pricing-card--highlight { border-color: #0b7d73; box-shadow: 0 8px 24px rgba(11,125,115,0.25); }

.pricing-section--accent-coral .pricing-card--highlight .btn-primary { background: #c1451f; color: #fff; }
.pricing-section--accent-coral .pricing-card--highlight .btn-primary:hover { background: #a03a1a; }
.pricing-section--accent-amber .pricing-card--highlight .btn-primary { background: #9c6500; color: #fff; }
.pricing-section--accent-amber .pricing-card--highlight .btn-primary:hover { background: #7d5100; }
.pricing-section--accent-teal .pricing-card--highlight .btn-primary { background: #0b7d73; color: #fff; }
.pricing-section--accent-teal .pricing-card--highlight .btn-primary:hover { background: #086158; }
/* lime accent's highlighted button is already lime (.btn-primary's own default) — nothing to override. */

.pricing-section--accent-lime .info-table thead tr { border-bottom: 2px solid var(--lime); }
.pricing-section--accent-coral .info-table thead tr { border-bottom: 2px solid #c1451f; }
.pricing-section--accent-amber .info-table thead tr { border-bottom: 2px solid #9c6500; }
.pricing-section--accent-teal .info-table thead tr { border-bottom: 2px solid #0b7d73; }

.pricing-section--accent-lime .service-chip--highlight { border-color: var(--lime); }
.pricing-section--accent-coral .service-chip--highlight { border-color: #c1451f; }
.pricing-section--accent-amber .service-chip--highlight { border-color: #9c6500; }
.pricing-section--accent-teal .service-chip--highlight { border-color: #0b7d73; }

/* Kaartachtige tabel i.p.v. platte tekst op de pagina-achtergrond — aangemaakt 2026-09-04: "die
   tabel onderin kan toch wel een stuk mooier". Zebra-rijen + hover + een uitgelichte laatste
   (prijs)kolom maken een tabel met veel gelijksoortige rijen (bv. 5 landen, allemaal met dezelfde
   prijsopbouw) een stuk makkelijker scanbaar dan platte tekstregels. */
.table-scroll { overflow-x: auto; background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); }
.info-table { width: 100%; border-collapse: collapse; }
.info-table th, .info-table td { text-align: left; padding: 14px 20px; border-bottom: 1px solid var(--border); font-size: 0.9rem; }
.info-table th { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.03em; color: var(--text-muted); border-bottom: 2px solid var(--border); }
.info-table td:first-child { font-weight: 700; color: var(--navy-900); }
.info-table td:last-child { font-weight: 700; color: var(--navy-900); font-size: 0.98rem; }
.info-table tbody tr:nth-child(even) { background: var(--bg); }
.info-table tbody tr:hover { background: var(--lime-soft); }
.info-table tbody tr:last-child td { border-bottom: none; }
.badge-status { display: inline-block; padding: 4px 12px; border-radius: 999px; font-size: 0.75rem; font-weight: 700; }
.badge-nieuw { background: #e6f0ff; color: #1955a8; }
.badge-in_behandeling { background: #fff4d6; color: #92650a; }
.badge-verzonden { background: #e3f0ff; color: #1a5fb0; }
.badge-afgerond { background: #e2f7ea; color: #1a8a4a; }
.badge-geannuleerd { background: #fde8ea; color: var(--danger); }
.badge-wacht_op_betaling { background: #f3e8ff; color: #7c3aed; }
.badge-betaald { background: #e2f7ea; color: #1a8a4a; }
.badge-open { background: #fde8ea; color: var(--danger); }
.badge-credit-flag { background: #fff4d6; color: #92650a; }
.badge-aangevraagd { background: #fff4d6; color: #92650a; }
.badge-goedgekeurd { background: #e3f0ff; color: #1a5fb0; }
.badge-afgewezen { background: #fde8ea; color: var(--danger); }
.badge-ontvangen { background: #e6f0ff; color: #1955a8; }
.badge-afgehandeld { background: #e2f7ea; color: #1a8a4a; }

/* Checkout */
.checkout-layout { display: grid; grid-template-columns: 1fr 380px; gap: 40px; align-items: start; }
/* Contact page reuses .checkout-layout for its info-card + map split, but wants two equal
   columns instead of checkout's fixed 380px summary sidebar — previously an inline
   style="grid-template-columns: 1fr 1fr" on the element itself, which (being inline) always beat
   the existing mobile media-query override below regardless of viewport width. That was the
   real cause of "als ik op mobiel contact aan klik dan komt het er naast" (map squeezed beside
   the info card instead of stacking) reported live 2026-09-04 — moved into a real class so the
   media query can win on mobile like it already does for every other .checkout-layout page. */
.checkout-layout--contact { grid-template-columns: 1fr 1fr; }
.order-line { display: flex; justify-content: space-between; gap: 12px; font-size: 0.9rem; padding: 8px 0; border-bottom: 1px solid var(--border); }
.order-line > span:first-child {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    line-height: 1.35;
}
.order-line > span:last-child { flex-shrink: 0; font-weight: 600; white-space: nowrap; }

.checkout-step { border: 1px solid var(--border); border-radius: var(--radius); padding: 24px 26px; margin-bottom: 20px; background: #fff; }
.checkout-step-title { display: flex; align-items: center; gap: 12px; margin: 0 0 18px; font-size: 1.15rem; color: var(--navy-950); }
.checkout-step-number {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--navy-950);
    color: #fff;
    font-size: 0.85rem;
    font-weight: 800;
    flex-shrink: 0;
}

.delivery-method-options { display: flex; flex-direction: column; gap: 10px; }
.delivery-method-option {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 12px 14px;
    cursor: pointer;
}
.delivery-method-option input { margin-top: 3px; }
.delivery-method-option:has(input:checked) { border-color: var(--navy-700); background: #f4f6fa; }

.payment-badge { display: inline-flex; align-items: center; padding: 2px 9px; border-radius: 5px; font-size: 0.68rem; font-weight: 800; letter-spacing: 0.02em; color: #fff; line-height: 1.6; }
.payment-badge-ideal { background: #cc0066; }
.payment-badge-wero { background: #1a0b3d; }

.upsell-card {
    background: linear-gradient(135deg, #f4ffe0 0%, #eafccb 100%);
    border: 2px solid var(--lime-dark);
    border-radius: var(--radius);
    padding: 20px 22px;
    margin: 0 0 24px;
}
.upsell-card h3 { color: var(--navy-950); font-size: 1.1rem; }
.upsell-item {
    display: flex;
    align-items: center;
    gap: 14px;
    background: #fff;
    border-radius: 10px;
    padding: 12px 14px;
    margin-bottom: 10px;
}
.upsell-item:last-child { margin-bottom: 0; }
.upsell-item-thumb { width: 52px; height: 52px; border-radius: 8px; object-fit: contain; background: #f4f6fa; border: 1px solid var(--border); flex-shrink: 0; }
.upsell-item-info { flex: 1; display: flex; flex-direction: column; gap: 2px; font-size: 0.88rem; }
.upsell-item-qty { display: flex; flex-direction: column; align-items: center; gap: 2px; flex-shrink: 0; }
.upsell-item-qty label { font-size: 0.72rem; font-weight: 600; color: var(--text-muted); text-align: center; max-width: 78px; }
.upsell-item-qty .transfer-qty-input { width: 64px; padding: 6px 8px; text-align: center; }
.upsell-item-qty .transfer-qty-input:disabled { background: #f4f6fa; color: var(--text-muted); }

/* Footer */
.site-footer { background: var(--navy-950); color: rgba(255,255,255,0.7); padding: 48px 0 24px; margin-top: 64px; }
.footer-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 32px; margin-bottom: 32px; }
.footer-grid h4 { color: #fff; font-size: 0.9rem; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 14px; }
.footer-grid a { display: block; color: rgba(255,255,255,0.6); font-size: 0.9rem; margin-bottom: 10px; }
.footer-grid a:hover { color: var(--lime); }
.footer-bottom { border-top: 1px solid rgba(255,255,255,0.1); padding-top: 20px; font-size: 0.82rem; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 8px; }

/* Generiek modaal formulier (bv. reseller-aanmelding) — aangemaakt 2026-09-04. */
.modal-overlay {
    display: none; position: fixed; inset: 0; background: rgba(10,23,48,0.55); z-index: 200;
    align-items: center; justify-content: center; padding: 20px;
}
.modal-overlay.is-open { display: flex; }
.modal-box { background: #fff; border-radius: var(--radius); max-width: 480px; width: 100%; max-height: 90vh; overflow-y: auto; padding: 32px; position: relative; }
.modal-close { position: absolute; top: 16px; right: 16px; background: none; border: none; font-size: 1.4rem; line-height: 1; color: var(--text-muted); cursor: pointer; padding: 4px; }
.modal-close:hover { color: var(--text); }
.modal-box h2 { margin: 0 0 8px; font-size: 1.3rem; }
.modal-box .text-muted { margin: 0 0 20px; }
.modal-box .form-group { margin-bottom: 14px; }
.modal-box label { display: block; font-size: 0.85rem; font-weight: 700; margin-bottom: 5px; }
.modal-box .form-status { font-size: 0.88rem; font-weight: 600; margin-top: 14px; display: none; }
.modal-box .form-status.is-error { display: block; color: #b3273f; }
.modal-box .form-status.is-success { display: block; color: #3c6b00; }
.modal-box form.is-sent { display: none; }
.modal-box .form-sent-message { display: none; }
.modal-box form.is-sent + .form-sent-message { display: block; }

/* Toast */
.toast {
    position: fixed; bottom: 24px; right: 24px; background: var(--navy-950); color: #fff;
    padding: 14px 22px; border-radius: 10px; font-weight: 700; font-size: 0.9rem;
    box-shadow: 0 8px 24px rgba(0,0,0,0.25); z-index: 100; opacity: 0; transform: translateY(12px);
    transition: opacity 0.2s, transform 0.2s; pointer-events: none;
    border-left: 4px solid var(--lime);
}
.toast.show { opacity: 1; transform: translateY(0); }

/* Admin edit shortcut — a floating "Bewerken" button shown only to a logged-in admin viewing a
   real (non-builder) tarieven-page, so jumping into the visual builder doesn't require going
   back to /admin and searching for the page. Requested live 2026-09-03: "als ik in de admin
   ingelogd ben dan wil ik op de frontpage een knop om direct naar het bewerken van de pagina te
   gaan dat scheelt weer opzoeken". Bottom-left so it never overlaps the .toast (bottom-right). */
.admin-edit-fab {
    position: fixed; left: 24px; bottom: 24px; z-index: 100;
    display: inline-flex; align-items: center; gap: 8px;
    background: var(--lime); color: var(--navy-950); font-weight: 700; font-size: 0.88rem;
    padding: 12px 18px; border-radius: 999px; text-decoration: none;
    box-shadow: 0 8px 24px rgba(0,0,0,0.22); border: 2px solid var(--navy-950);
}
.admin-edit-fab:hover { filter: brightness(0.95); }

/* Pagination-less search */
.search-form-page { display: flex; gap: 10px; max-width: 480px; margin-bottom: 32px; }
.search-form-page input { flex: 1; }

/* Legal / info pages */
.legal-content { max-width: 720px; color: var(--text); }
.legal-content h2 { font-size: 1.2rem; margin: 32px 0 12px; }
.legal-content h2:first-child { margin-top: 0; }
.legal-content p { margin: 0 0 14px; color: var(--text-muted); line-height: 1.7; }
.legal-content ul { margin: 0 0 14px; padding-left: 20px; color: var(--text-muted); line-height: 1.7; }
.legal-content a { color: var(--navy-800); text-decoration: underline; }

@media (max-width: 900px) {
    /* Mobile header: the desktop logo height (44px) reads as oversized once the row also has to
       fit the cart icon and hamburger in ~390px width — reported live 2026-09-04: "logo op mobiel
       is een heel stuk te groot". Shrinking the row's own padding too so the whole header takes
       up noticeably less vertical space, matching how most mobile sites keep the header compact. */
    .header-inner { padding: 10px 16px; gap: 10px; }
    .logo img { height: 26px; }
    .logo-img--compact { height: 22px; }

    /* The category subbar only exists as a visible bar on desktop — on mobile it stays
       collapsed (no empty strip under the header) until the hamburger opens .main-nav, at
       which point it reveals itself so the dropdown panel has something to anchor to. */
    .header-subbar { display: none; border-top: none; position: relative; }
    .header-subbar:has(.main-nav.open) { display: block; }
    .header-subbar .container { padding: 0; }
    .main-nav { display: none; }
    /* Full redesign of the open mobile panel — requested live 2026-09-04: "menu op mobiel werkt
       ook niet prettig ... uiterlijk van het menu op mobiel hoeft niet hetzelfde te zijn ... alle
       knoppen in menu op mobiel mogen wat netjes simpel maar duidelijk te klikken". The previous
       version had no max-height/overflow of its own: being position:absolute (out of normal
       flow), a tall opened submenu could extend below the viewport with no way to scroll down to
       it — the actual cause of "werkt niet prettig". Fixed by giving the panel its own scroll
       region sized to the remaining viewport height below the (now-shorter) header. */
    .main-nav.open {
        display: flex;
        flex-direction: column;
        /* .main-nav's own base (desktop) rule sets flex-wrap:wrap for its horizontal bar — left
           unset here, that wrap carries straight over into this vertical layout too, and a
           column-direction flex container with wrap enabled starts a NEW COLUMN to the right the
           moment its content is taller than max-height, instead of just scrolling. That was the
           real cause of "als het menu aan de onderkant niet genoeg ruimte heeft dan komt er een
           kolom rechts naast, ik moet naar rechts scrollen" reported live 2026-09-04. */
        flex-wrap: nowrap;
        gap: 8px;
        /* position:fixed (not absolute) anchored to the actual header height (measured: 61px on
           mobile after the logo/padding shrink above), with bottom:0 instead of a max-height/vh
           calculation — reported live 2026-09-04 on shop.vdbcomputers.nl (7 pinned categories,
           tall enough to need it): "de onderste 2 knoppen kan ik niet zien, ik kan dan niet
           scrollen". The panel WAS technically scrollable (overflow-y:auto, scrollHeight >
           clientHeight all checked out), but position:absolute inside a page whose <body> gets
           overflow:hidden while open is a known unreliable combination for touch-scrolling a
           NESTED scroll container on mobile Safari in particular. position:fixed is the standard,
           robust pattern for a mobile nav sheet and sidesteps that interaction entirely; bottom:0
           also avoids 100vh's own mobile quirk of not accounting for a browser's address bar. */
        position: fixed;
        top: 61px;
        left: 0;
        right: 0;
        bottom: 0;
        background: var(--navy-950);
        padding: 16px 16px 24px;
        box-shadow: 0 16px 28px rgba(0,0,0,0.25);
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior: contain;
    }
    .nav-dropdown { width: 100%; }
    /* Every top-level tappable row in the mobile panel — the browse dropdowns (Webwinkel/
       Categorieën + each admin-defined menu) and the pinned category shortcuts — now share one
       consistent "list row" look instead of desktop's mix of lime pill / plain text / outline
       button, so they all read as equally, obviously tappable at a comfortable ~48px height. */
    .nav-dropdown-toggle,
    .header-subbar-link {
        width: 100%;
        justify-content: space-between;
        border-radius: 10px;
        padding: 13px 16px;
        font-size: 0.96rem;
    }
    .nav-dropdown-toggle--outline {
        background: rgba(255,255,255,0.06);
        color: #fff;
        font-weight: 700;
    }
    .nav-dropdown-toggle--outline:hover,
    .nav-dropdown.open .nav-dropdown-toggle--outline { background: rgba(255,255,255,0.06); color: var(--lime); }
    .header-subbar-link {
        display: flex;
        border: none;
        background: rgba(255,255,255,0.06);
        font-weight: 700;
    }
    .header-subbar-link:hover { background: rgba(255,255,255,0.1); color: #fff; }
    /* Keeps its own white background + dark text at every viewport (never overridden here),
       same as .nav-megamenu-list's own — it's what makes this legible sitting inside the dark
       navy mobile nav panel, not a floating white box needing its own color scheme. */
    .nav-simple-menu { position: static; box-shadow: none; width: 100%; margin-top: 6px; border-radius: 10px; }
    .nav-simple-menu a { padding: 12px 14px; min-height: 20px; }
    .nav-megamenu {
        position: static;
        box-shadow: none;
        margin-top: 6px;
        width: 100%;
        max-width: none;
        flex-direction: column;
        border-radius: 10px;
    }
    .nav-megamenu-list { width: 100%; max-height: none; border-right: none; overflow: visible; padding: 6px; }
    .nav-megamenu-item { padding: 12px; }
    .nav-megamenu-panels { display: none; max-height: none; overflow: visible; }
    /* Drill-down on mobile: tapping a category swaps the list for its subcategories full-width,
       via .showing-panel toggled in JS, rather than a cramped side-by-side layout. */
    .nav-megamenu.showing-panel .nav-megamenu-list { display: none; }
    .nav-megamenu.showing-panel .nav-megamenu-panels { display: block; }
    .nav-megamenu-back {
        display: flex;
        align-items: center;
        gap: 6px;
        background: none;
        border: none;
        font-family: inherit;
        color: var(--navy-800);
        font-weight: 700;
        font-size: 0.85rem;
        padding: 6px 8px 14px;
        cursor: pointer;
    }
    /* Internet Postcode check — on desktop this is pushed to the far right of the bar via
       margin-left:auto, a trick that (unexpectedly) also pushes it to the CROSS axis end of the
       column-direction mobile panel — the "floating oddly off to one side" bug reported live
       2026-09-04. Neutralized here and re-styled as its own full-width closing CTA row instead. */
    .header-subbar-link--postcode {
        margin-left: 0;
        margin-top: 8px;
        justify-content: center;
        border-top: 1px solid rgba(255,255,255,0.12);
        padding-top: 20px;
        border-radius: 0;
        background: transparent;
        color: #4fc3f7;
    }
    .header-subbar-link--postcode svg { margin-right: 8px; }
    .header-subbar-link--postcode:hover { background: transparent; color: #29b6f6; }
    .nav-toggle {
        display: flex; align-items: center; justify-content: center;
        width: 40px; height: 40px; font-size: 1.5rem; border-radius: 10px;
    }
    .nav-toggle:active { background: rgba(255,255,255,0.08); }
    /* Set on <body> while the mobile panel is open (main.js) — stops the page underneath from
       scrolling along with a touch-drag inside the (now internally-scrollable) nav panel. */
    body.nav-open-lock { overflow: hidden; }
    .search-form { display: none; }
    .search-form-mobile { display: flex; width: 100%; margin-bottom: 4px; }
    .search-form-mobile input { flex: 1; width: auto; }
    .search-form-mobile input, .search-form-mobile button { min-height: 44px; }
    /* Account/contact move into the hamburger menu on mobile — only cart stays in the top row. */
    .account-link, .contact-link { display: none; }
    .mobile-account-links {
        display: flex; flex-direction: column; gap: 2px; width: 100%; margin-bottom: 6px;
        background: rgba(255,255,255,0.05); border-radius: 10px; padding: 4px;
    }
    .mobile-account-link { padding: 13px 12px; font-size: 0.96rem; }
    .product-detail, .cart-layout, .checkout-layout { grid-template-columns: 1fr; }
    .cart-quote-card { grid-column: 1; }
    .category-layout { grid-template-columns: 1fr; }
    /* Collapsed by default on mobile, behind its own toggle button — requested live 2026-09-04:
       "op mobiel komt altijd eerst de complete filter en daarna pas de producten, de filter moet
       op mobiel dan eigenlijk ingeklapt zijn". Desktop is untouched: this whole rule (and the
       toggle button below) only exists inside this media query, so .filter-sidebar keeps its
       normal sticky-column CSS and the button stays display:none there. */
    .filter-sidebar { position: static; margin-bottom: 24px; max-height: none; overflow-y: visible; display: none; }
    .filter-sidebar.mobile-open { display: block; }
    .filter-toggle-btn {
        display: flex; align-items: center; gap: 10px; width: 100%; margin-bottom: 14px;
        background: var(--card); border: 1px solid var(--border); border-radius: var(--radius);
        padding: 13px 16px; font-family: inherit; font-weight: 700; font-size: 0.94rem;
        color: var(--text); cursor: pointer; box-shadow: var(--shadow);
    }
    .filter-toggle-btn.open { border-color: var(--navy-700); }
    .filter-toggle-count {
        background: var(--navy-950); color: #fff; font-size: 0.72rem; font-weight: 800;
        min-width: 20px; height: 20px; border-radius: 999px; display: inline-flex;
        align-items: center; justify-content: center; padding: 0 6px;
    }
    .filter-toggle-chevron { margin-left: auto; transition: transform 0.15s; }
    .filter-toggle-btn.open .filter-toggle-chevron { transform: rotate(180deg); }
    .form-row { grid-template-columns: 1fr; }

    /* .cart-table is reused across cart/order-detail/dashboard/returns/return-form, each with a
       different column count — rather than tuning widths per page, every one of them collapses
       to a stacked "card per row" layout here, with data-label attributes (where present)
       supplying the field name in front of the value. Same 900px breakpoint as .cart-layout/
       .checkout-layout's own grid collapse just above — this used to be a separate, narrower
       640px breakpoint, which meant a viewport between 641-900px (a phone in landscape, or a
       small tablet) got the WORST of both: .cart-layout still a 2-column grid (table + 340px
       summary side by side) while the table itself still tried to render as a full 5-column
       table, squeezed into that narrow left column — the "vreemd naast elkaar" reported live
       2026-09-02. Matching the breakpoints means the table only ever stacks into cards exactly
       when it has the full row width to do so in, never a half-width squeeze. */
    .cart-table thead { display: none; }
    .cart-table, .cart-table tbody, .cart-table tr, .cart-table td { display: block; width: 100% !important; }
    /* The desktop .cart-table-card wrapper (see cart.php) gives the whole table one shared white
       card — on mobile each ROW already gets its own white card + shadow (just below), so keeping
       the wrapper's box too would nest a card inside a card. Neutralized here rather than not
       wrapping at all, so cart.php doesn't need two different markup structures per breakpoint. */
    .cart-table-card { background: none; padding: 0; box-shadow: none; border: none; }
    /* Same white-card + soft-shadow treatment .cart-summary/.content-card already use elsewhere
       on this page — previously just a border with no fill, so the row barely stood out against
       the page's own off-white background (var(--bg)). Requested live 2026-09-02. */
    .cart-table tr { background: var(--card); box-shadow: var(--shadow); border: 1px solid var(--border); border-radius: var(--radius); padding: 12px 14px; margin-bottom: 14px; }
    .cart-table td { padding: 6px 0 !important; border-bottom: none !important; }
    .cart-table td[data-label]::before {
        content: attr(data-label);
        display: block;
        font-size: 0.7rem;
        font-weight: 800;
        text-transform: uppercase;
        letter-spacing: 0.03em;
        color: var(--text-muted);
        margin-bottom: 2px;
    }

    /* The winkelwagen's own product row, redesigned as an actual mobile card rather than the
       generic block-per-cell fallback above — reported "niet echt mooi" live 2026-09-02. Scoped
       to ".cart-layout .cart-table" (only the real cart page uses that wrapper — order-detail.php
       sits in .checkout-layout, dashboard/returns/return-form in neither) so order history and
       returns keep the plain generic stack untouched. A CSS grid on the row lays out product /
       price+aantal side by side / totaal, with "Verwijderen" as a small × in the corner instead
       of its own full-width line. */
    .cart-layout .cart-table tr {
        display: grid;
        grid-template-columns: 1fr auto;
        grid-template-areas: "product product" "price qty" "total total";
        gap: 2px 12px;
        padding: 14px 40px 14px 14px;
        position: relative;
    }
    .cart-layout .cart-table td { padding: 0 !important; }
    .cart-layout .cart-table td:nth-child(1) { grid-area: product; margin-bottom: 10px; }
    .cart-layout .cart-table td:nth-child(2) { grid-area: price; align-self: end; }
    .cart-layout .cart-table td:nth-child(3) { grid-area: qty; justify-self: end; align-self: end; }
    .cart-layout .cart-table td:nth-child(3) .cart-qty-form { display: flex; justify-content: flex-end; }
    .cart-layout .cart-table td:nth-child(4) {
        grid-area: total;
        margin-top: 10px;
        padding-top: 10px !important;
        border-top: 1px dashed var(--border);
        display: flex;
        justify-content: space-between;
        align-items: baseline;
    }
    .cart-layout .cart-table td:nth-child(4)::before { margin-bottom: 0 !important; }
    .cart-layout .cart-table td:nth-child(4) { font-weight: 700; font-size: 1.02rem; }
    .cart-layout .cart-table td:nth-child(5) {
        /* width: auto !important, not just position:absolute, is load-bearing: the generic
           fallback rule above (.cart-table td { width: 100% !important; }) still matches this
           cell too and, being !important, kept winning over a plain (non-important) width here —
           an absolutely positioned box that's 100% of the row's width but anchored by "right"
           computes its LEFT edge miles offscreen, which is exactly why the × rendered pinned to
           the top-LEFT instead of the top-right corner it was meant for (reported live
           2026-09-02, confirmed via an actual rendered screenshot, not just reasoned from CSS). */
        position: absolute;
        top: 12px;
        right: 12px;
        width: auto !important;
    }
    /* Round icon button in the card's corner — the base .remove-link rule already made the label
       visually-hidden and this icon-only everywhere, so mobile only needs the circle/positioning
       treatment on top of that, not a second copy of the label-hiding rule. */
    .cart-layout .cart-table .remove-link {
        display: flex; align-items: center; justify-content: center;
        width: 28px; height: 28px; padding: 0; border-radius: 50%;
        background: var(--bg); color: var(--danger);
    }
}
