/* .producten-hero keeps its own padding (outer, full-bleed photo — padding
   never shrinks a background paint area, only the content's position) and
   its content <div> gets a plain .wrap class in the template, so the text
   caps/centers to the exact same 1280px column as .site-nav instead of
   drifting with viewport width. */
.producten-hero{height:340px;position:relative;display:flex;align-items:flex-end;padding:0 var(--gutter) 48px var(--gutter);}
.producten-hero h1{color:white;font-size:var(--fs-hero);}
.producten-hero .btn{margin-top:20px;}

/* Shared hero for category.php / landingspage.php (includes/landing-hero.php).
   Same outer-padding/inner-bare-wrap split as .site-nav: .landing-hero-inset
   carries the gutter floor, the bare .wrap inside it caps/centers to 1280px,
   and .landing-hero-content (no padding/margin of its own now) sits at that
   same left edge with just its own narrower 640px reading-width cap. */
.landing-hero{position:relative;min-height:420px;display:flex;align-items:flex-end;overflow:hidden;}
.landing-hero-photo{position:absolute;inset:0;background-size:cover;background-position:center;}
.landing-hero::after{content:'';position:absolute;inset:0;background:linear-gradient(0deg, rgba(0,0,0,.6), rgba(0,0,0,.1) 65%);}
/* Content is bottom-anchored (align-items:flex-end above), so this
   padding-top is a pure safety margin, not a positioning nudge — it only
   ever matters for a hero whose title+text block is tall enough to reach
   it (e.g. a 3-line heading with no photo, like Geluidsmetingen's), and
   is otherwise invisible on short-title heroes that never get that tall. */
.landing-hero-inset{position:relative;z-index:1;width:100%;padding:64px var(--gutter) 48px var(--gutter);}
.landing-hero-content{max-width:640px;}
.landing-hero-content h1{color:white;font-size:var(--fs-hero);margin-bottom:14px;}
.landing-hero-text{color:rgba(255,255,255,.92);font-size:15px;line-height:1.6;margin-bottom:24px;}
.landing-hero-text p{margin:0 0 10px 0;}

/* Optional header video (landing_hero_video_url, 2026-09-20) — content
   and video sit side by side on desktop, matching the live site's own
   /geluidsmetingen/ treatment; only kicks in via the --video modifier so
   every other landing-hero page (no video set) is unaffected. */
.landing-hero--video .landing-hero-inset > .wrap{display:flex;flex-wrap:wrap;gap:40px;align-items:center;}
.landing-hero-video{flex:1 1 380px;max-width:480px;aspect-ratio:16/9;border-radius:16px;overflow:hidden;box-shadow:0 20px 40px rgba(0,0,0,.3);}
.landing-hero-video iframe{width:100%;height:100%;border:0;display:block;}

.landing-usps{background:#F0EEE9;padding:56px var(--gutter);}
.landing-usps h2{font-size:var(--fs-h2);text-align:center;margin-bottom:40px;}
.landing-usps-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:32px;}
.landing-usp-item{text-align:left;}
.landing-usp-icon{width:44px;height:44px;border-radius:50%;background:var(--card);display:flex;align-items:center;justify-content:center;color:var(--petrol);margin-bottom:14px;}
.landing-usp-item h3{font-size:16px;margin-bottom:8px;}
.landing-usp-tekst{font-size:14px;line-height:1.6;color:var(--ink-muted);}
.landing-usp-tekst p{margin:0;}

/* Horizontal gutter here was accidentally dropped in an earlier refactor
   (only vertical padding was kept, on the assumption .wrap would supply
   the horizontal inset — but .wrap itself carries no padding, only a
   max-width cap, so on any viewport under 1280px — not just mobile, a
   1024px laptop too — this content sat flush against the screen edges). */
.landing-content-section{padding:56px var(--gutter);}
.landing-content-section--grijs{background:#f1efe9;}
.landing-content-section-inner{display:grid;grid-template-columns:1fr 1fr;gap:48px;align-items:stretch;}
.landing-content-section-inner--text-only{grid-template-columns:1fr;max-width:760px;}
/* Reorders the two grid children visually without changing DOM order —
   .landing-section-tekst and .landing-section-media-col are always the
   text then media children, in that order, regardless of section type. */
.landing-content-section-inner--reverse .landing-section-tekst{order:2;}
.landing-content-section-inner--reverse .landing-section-media-col{order:1;}
/* Rich-text typography for CMS-authored section copy — shared with
   .landing-full-card (the "volledige-afbeelding-tekst" elevated card),
   which renders the same kind of CKEditor HTML but previously had none of
   these rules at all, leaving it noticeably plainer/smaller than every
   other section type. h2 matches the live site's own 35px (was 28px here
   — not a deliberate size-down, just an unreviewed carry-over from the
   Ritswanden build this was extended from). */
.landing-section-tekst,
.landing-full-card{font-size:18px;line-height:1.6;}
.landing-section-tekst h2,
.landing-full-card h2{font-size:var(--fs-h2);font-weight:700;margin-bottom:8px;}
/* Measured directly off the live page's computed styles (not guessed from
   its SCSS source, which didn't turn up an explicit h3 rule): h3 there is
   28px/700/black, essentially a second-tier heading, not a small muted
   subtitle like this used to render it as. */
.landing-section-tekst h3,
.landing-full-card h3{font-size:var(--fs-h3);font-weight:700;color:var(--ink);margin-bottom:8px;}
.landing-section-tekst p,
.landing-full-card p{margin:0 0 14px 0;}
/* Checkmark bullets (matches the live site's ".green-list" treatment —
   a small solid-color circle with a white check, not a default browser
   bullet) for any CMS-authored <ul> in this rich text. */
.landing-section-tekst ul,
.landing-full-card ul{list-style:none;margin:0 0 14px 0;padding:0;}
.landing-section-tekst ul li,
.landing-full-card ul li{display:flex;align-items:baseline;gap:10px;margin-bottom:6px;}
.landing-section-tekst ul li::before,
.landing-full-card ul li::before{content:'';flex-shrink:0;width:18px;height:18px;margin-top:2px;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 18 18'%3E%3Ccircle cx='9' cy='9' r='9' fill='%23309867'/%3E%3Cpath d='M5.4 9l2.4 2.4L12.6 6.6' stroke='white' stroke-width='1.8' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");background-size:contain;background-repeat:no-repeat;}
.landing-section-tekst--centered{text-align:center;max-width:640px;margin:0 auto 32px auto;}
h2.landing-section-tekst--centered{font-size:var(--fs-h2);font-weight:700;max-width:none;}
.landing-section-knop{margin-top:8px;}
.landing-section-media-col{display:flex;flex-direction:column;gap:20px;}
.landing-section-labels{display:flex;gap:16px;flex-wrap:wrap;}
.landing-section-label{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:600;color:var(--ink-muted);}
.landing-section-photo{border-radius:16px;}
.landing-section-media{display:flex;gap:12px;overflow-x:auto;}
.landing-section-media img{width:100%;max-width:260px;height:200px;object-fit:cover;border-radius:16px;flex-shrink:0;}

/* "volledige-afbeelding-tekst" — full-bleed photo with an elevated text
   card overlapping its bottom edge (negative margin pulls the card up). */
.landing-full-section{position:relative;}
.landing-full-photo{border-radius:0;}
.landing-full-card{position:relative;z-index:1;margin-top:-100px;background:var(--card);border-radius:6px;padding:80px;max-width:640px;}

/* "merken" section type — reuses real brand logos (vs. the homepage's
   .merken-row, which is plain text names). */
/* Always one row on desktop (requested 2026-09-20) — nowrap + overflow:
   hidden simply clips whichever logos don't fit rather than wrapping to
   an uneven second row; the 900px breakpoint below switches back to
   wrap so mobile can stack them onto 2 rows instead of clipping any. */
.merken-logos-row{display:flex;align-items:center;justify-content:space-between;gap:32px;flex-wrap:nowrap;overflow:hidden;}
/* 108px wide x 150px tall on request (2026-09-20) — was 150px tall/220px
   max-width, matching the reference site's own slider verbatim, but that
   read too large in this static (non-carousel) row of several at once.
   object-fit:contain on a fixed box keeps every logo's own aspect ratio
   (no stretching) while still occupying the same-size slot as the rest. */
.merken-logo{flex-shrink:0;}
.merken-logo img{width:108px;height:150px;object-fit:contain;filter:grayscale(1);opacity:.6;transition:opacity .15s ease,filter .15s ease;}
.merken-logo:hover img{filter:none;opacity:1;}

/* MERKEN OVERZICHT (/merken/) + individual brand pages */
.brands-overview{padding:48px var(--gutter) 80px var(--gutter);}
.brands-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:20px;}
.brand-tile{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;padding:32px 20px;border:1px solid var(--line);text-decoration:none;color:var(--ink);text-align:center;min-width:0;}
.brand-tile img{max-width:min(140px,100%);max-height:48px;width:auto;height:auto;object-fit:contain;}
.brand-tile span{font-weight:700;font-size:14px;}
.brand-tile:hover{border-color:var(--petrol);}
.brand-tile:not(:has(img)){min-height:96px;}
.brand-tile:not(:has(img)) span{font-size:16px;}

.brand-header{padding:56px var(--gutter) 32px var(--gutter);text-align:center;}
/* .brand-header now carries the shared .photo-N placeholder gradient
   (brand.php, no photo field exists on this template) — .photo's own
   ::after highlight is position:absolute with no z-index, which paints
   above plain in-flow content unless that content is also given a
   stacking context, hence position:relative + z-index here. */
.brand-header .wrap{position:relative;z-index:1;}
/* margin:0 auto, not just .brand-header{text-align:center} — the global
   img{display:block} reset (site.css) takes this out of inline flow, so
   text-align on the ancestor has no effect on it; it was rendering
   flush-left instead of centered until this was added. */
.brand-header-logo{max-width:220px;max-height:72px;width:auto;height:auto;object-fit:contain;margin:0 auto 20px auto;}
.brand-header h1,
.brand-header-title{font-size:var(--fs-h1);font-family:"Overpass",system-ui,sans-serif;font-weight:800;letter-spacing:-0.01em;color:var(--ink);}

@media (max-width:900px){
  .brands-grid{grid-template-columns:repeat(2,1fr);}
  .landing-usps-grid{grid-template-columns:1fr;}
  .landing-content-section-inner{grid-template-columns:1fr;}
  .landing-full-card{margin-top:0;max-width:none;padding:40px 24px;}
  .merken-logos-row{justify-content:center;flex-wrap:wrap;overflow:visible;}
  /* The reference site halves its own logo height on mobile
     (.brand-slider .brand height:150px -> 75px below ~576px) — matching
     that here too, since 150px unscaled would make this section very
     tall on a phone (8 logos stacked several-per-row at full height). */
  .merken-logo img{width:72px;height:100px;}
}
/* Outer padding stays here (gutter floor); the breadcrumb text itself is
   wrapped in a bare .wrap in each template so it caps/centers with .site-nav
   instead of the old flat-gutter-only inset drifting apart on wide screens. */
/* Bottom padding added 2026-09-19: was top-only (matching .content-intro's
   own top-only spacer just below), which is fine when the next section has
   no background fill of its own, but reads as a hard, gapless seam right
   under the breadcrumb text wherever the next section DOES have one (e.g.
   .landing-usps' grey fill on /akoestiek-als-service/ — its own 56px
   padding is real but invisible until the fill itself starts, so the two
   colors met with zero breathing room). Giving .breadcrumb its own bottom
   space fixes that everywhere at once instead of patching each section. */
.breadcrumb{padding:20px var(--gutter);font-size:13px;color:var(--ink-muted);}
.breadcrumb a{color:var(--ink-muted);}

.content-intro{padding:20px var(--gutter) 0 var(--gutter);}
.content-intro h1{font-size:var(--fs-h1);}

/* Outer padding (gutter floor) for the whole filter+grid+pagination band
   lives on .product-grid-section; the bare .wrap inside it caps/centers to
   1280px, and filter-bar/product-grid/pagination keep only vertical padding
   so their content doesn't get gutter-inset a second time on top of that. */
.product-grid-section{padding:0 var(--gutter);}
.filter-bar{display:flex;gap:16px;padding:24px 0;flex-wrap:wrap;}
.filter-dropdown{position:relative;}
.filter-toggle{display:flex;align-items:center;gap:10px;background:var(--card);border:1px solid var(--line);border-radius:8px;padding:12px 20px;font-size:14px;font-weight:600;cursor:pointer;color:var(--ink);}
.filter-toggle svg{color:var(--ink-muted);transition:transform .15s ease;flex-shrink:0;}
.filter-dropdown.open .filter-toggle svg{transform:rotate(180deg);}
.filter-panel{display:none;position:absolute;top:100%;left:0;margin-top:8px;background:var(--card);border:1px solid var(--line);border-radius:8px;box-shadow:0 12px 32px rgba(0,0,0,.14);padding:14px;min-width:220px;z-index:15;max-height:320px;overflow-y:auto;}
.filter-dropdown.open .filter-panel{display:block;}
.filter-option{display:flex;align-items:center;gap:8px;padding:6px 0;font-size:14px;}

.product-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:24px;padding:0 0 60px 0;}
.product-grid .product-card{overflow:hidden;border:1px solid var(--line);text-decoration:none;color:inherit;display:block;}
/* .product-card's own display:block (two classes) otherwise beats the
   browser's built-in [hidden]{display:none} (one attribute selector) on
   specificity alone, so the JS filter's card.hidden=true was silently
   doing nothing — every card stayed visible regardless of the filter. */
.product-grid .product-card[hidden]{display:none;}
.product-grid .product-photo{height:200px;position:relative;}
.product-grid .product-photo .pill{position:absolute;top:14px;left:14px;}
.product-grid .accoustic-badge{position:absolute;top:14px;right:14px;width:32px;height:32px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-weight:800;font-size:13px;color:#fff;background:#21696a;}
/* Exact colors measured off the live site's own A-E label circles
   (getComputedStyle on .label-a..e there) — a dark-green-to-pale-green
   scale, not this project's own petrol/orange palette, since these mirror
   a real external rating (like an energy label) rather than site branding. */
.product-grid .accoustic-badge--a{background:#1d693b;}
.product-grid .accoustic-badge--b{background:#5f8647;}
.product-grid .accoustic-badge--c{background:#93a55b;}
.product-grid .accoustic-badge--d{background:#c1c475;}
.product-grid .accoustic-badge--e{background:#e4df8e;}
.product-grid .product-body{padding:16px;}
.product-grid .product-brand{color:var(--ink-muted);font-size:12px;}
.product-grid .product-title{font-weight:700;font-size:15px;margin-top:2px;}
.product-grid .product-stars{display:flex;gap:2px;align-items:center;margin-top:6px;font-size:12px;color:var(--ink-muted);}
.product-grid .product-price{margin-top:10px;font-size:14px;}
.product-grid .product-price .amount{font-weight:700;}

.pagination{display:flex;gap:8px;justify-content:center;padding:0 0 60px 0;}
.pagination-btn{width:36px;height:36px;border-radius:50%;border:1px solid var(--line);background:var(--card);cursor:pointer;font-size:14px;}
.pagination-btn.is-active{background:var(--petrol);color:white;border-color:var(--petrol);}

@media (max-width:900px){
  .product-grid{grid-template-columns:repeat(2,1fr);}
  .filter-bar{padding:16px 0;}
}

/* Same outer-padding/inner-bare-wrap split as .site-nav: .product-detail-section
   carries the gutter floor, .product-detail (the actual grid, no padding/max-width
   of its own now) sits inside a bare .wrap so it caps/centers with the header. */
.product-detail-section{padding:56px var(--gutter);}
.product-detail{display:grid;grid-template-columns:1fr 1fr;gap:56px;align-items:start;}
.product-detail-photo{height:440px;border-radius:20px;position:relative;}
/* Acoustic-label pill over the main photo (2026-09-20) — reuses the same
   .accoustic-badge letter/color scheme as the product-grid card badge,
   but that badge's own rules are scoped to ".product-grid" so its base
   circle styling is repeated here rather than broadening that selector
   (which would also change its position on every catalog card). */
.product-detail-label-badge{position:absolute;left:16px;bottom:16px;display:flex;align-items:center;gap:8px;background:white;border-radius:999px;padding:6px 16px 6px 6px;font-weight:700;font-size:14px;color:var(--ink);box-shadow:0 8px 20px rgba(0,0,0,.14);z-index:1;}
.product-detail-label-badge .accoustic-badge{position:static;width:28px;height:28px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-weight:800;font-size:12px;color:#fff;background:#21696a;}
.product-detail-label-badge .accoustic-badge--a{background:#1d693b;}
.product-detail-label-badge .accoustic-badge--b{background:#5f8647;}
.product-detail-label-badge .accoustic-badge--c{background:#93a55b;}
.product-detail-label-badge .accoustic-badge--d{background:#c1c475;}
.product-detail-label-badge .accoustic-badge--e{background:#e4df8e;}
.product-thumbs{display:flex;gap:10px;margin-top:12px;flex-wrap:wrap;}
.product-thumb{width:72px;height:72px;border-radius:10px;border:2px solid transparent;background-size:cover;background-position:center;cursor:pointer;padding:0;opacity:.7;}
.product-thumb:hover{opacity:1;}
.product-thumb.is-active{border-color:var(--petrol);opacity:1;}
.product-detail-brand{color:var(--ink-muted);font-size:14px;text-decoration:none;display:inline-block;}
.product-detail-brand:hover{color:var(--petrol);}
.product-detail h1{font-size:var(--fs-h1);margin-top:6px;}
.product-detail-price{font-size:24px;font-weight:700;margin-top:16px;}

.product-tabs{margin-top:32px;}
.product-tabs-nav{display:flex;gap:24px;border-bottom:1px solid var(--line);}
.product-tab-btn{background:none;border:none;border-bottom:2px solid transparent;padding:12px 0;font-size:15px;font-weight:600;color:var(--ink-muted);cursor:pointer;margin-bottom:-1px;}
.product-tab-btn.is-active{color:var(--petrol);border-bottom-color:var(--petrol);}
.product-tab-panel{display:none;padding-top:24px;font-size:15px;line-height:1.7;}
.product-tab-panel.is-active{display:block;}
.product-tab-panel p{margin:0 0 16px 0;}
.product-tab-panel a{text-decoration:underline;}
.product-tab-panel .kenmerk-row{display:flex;justify-content:space-between;gap:16px;padding:10px 0;border-top:1px solid var(--line);font-size:14px;}
.product-tab-panel .kenmerk-label{color:var(--ink-muted);}
.product-tab-panel .kenmerk-waarde{font-weight:600;text-align:right;}
.kenmerk-sterren{display:inline-flex;gap:2px;vertical-align:middle;}

.custom-product-badge{display:flex;align-items:center;gap:10px;background:var(--card);border-radius:12px;padding:14px 16px;margin-top:20px;font-size:14px;font-weight:600;color:var(--petrol);}
.custom-product-badge svg{flex-shrink:0;}

.related-products-section{padding:24px var(--gutter) 80px;}
.related-products-section h2{font-size:var(--fs-h2);font-family:"Overpass",system-ui,sans-serif;margin-bottom:32px;}

.product-downloads{display:flex;flex-direction:column;gap:10px;margin-top:24px;}
.product-download-link{display:flex;align-items:center;gap:10px;color:var(--ink);text-decoration:none;font-size:14px;}
.product-download-link svg{flex-shrink:0;color:var(--petrol);}
.product-download-link strong{color:var(--petrol);font-weight:600;}

.variant-groep{margin-top:24px;}
.variant-groep-label{font-weight:700;font-size:14px;margin-bottom:8px;}
.variant-groep-naam-huidig{font-weight:400;color:var(--ink-muted);}
.variant-opties{display:flex;flex-wrap:wrap;gap:8px;}
.variant-optie{border:1px solid var(--line);border-radius:999px;padding:8px 16px;background:var(--card);cursor:pointer;font-size:13px;display:inline-block;}
/* product_familie_waarde renders this same class on a real <a> (it
   navigates to a sibling product page, unlike the in-page option
   buttons) — the site's global a{color:var(--petrol)} would otherwise
   make every non-selected link look selected. */
a.variant-optie{text-decoration:none;color:var(--ink);}
.variant-optie.is-selected{border-color:var(--petrol);color:var(--petrol);font-weight:700;}
.variant-optie--kleur{width:32px;height:32px;padding:0;border-radius:50%;border:2px solid var(--line);}
.variant-optie--kleur.is-selected{border-color:var(--petrol);box-shadow:0 0 0 2px white inset;}
.variant-prijs-hint{color:var(--ink-muted);font-weight:400;font-size:12px;}

.reviews-list{display:flex;flex-direction:column;gap:16px;}
.review-item{border-top:1px solid var(--line);padding-top:16px;}
.review-item:first-child{border-top:none;padding-top:0;}
.review-item .review-stars{display:flex;gap:2px;margin-bottom:8px;}
.review-item p{margin:0 0 8px;}
.review-item .review-naam{font-weight:700;}

.product-intro{color:var(--ink-muted);font-size:15px;line-height:1.6;margin-top:16px;}
.product-intro p{margin:0 0 8px 0;}

/* CONTACT PAGE */
.contact-section{padding:48px var(--gutter) 96px var(--gutter);}
.contact-grid{display:grid;grid-template-columns:1.2fr 1fr;gap:56px;align-items:start;}
.contact-form-col h1{font-size:var(--fs-h1);margin-bottom:12px;}
.contact-form-intro{font-size:16px;color:var(--ink-muted);line-height:1.6;margin-bottom:24px;}
.contact-form{display:flex;flex-direction:column;gap:18px;}
.contact-field{display:flex;flex-direction:column;gap:6px;font-size:14px;font-weight:600;}
.contact-field input[type="text"],
.contact-field input[type="email"],
.contact-field input[type="number"],
.contact-field select,
.contact-field textarea{font-family:inherit;font-size:15px;font-weight:400;padding:12px 16px;border:1px solid var(--line);border-radius:12px;background:var(--card);color:var(--ink);resize:vertical;}
.contact-field input[type="file"]{font-family:inherit;font-size:14px;font-weight:400;padding:10px 0;color:var(--ink-muted);}
.contact-field input:focus,
.contact-field select:focus,
.contact-field textarea:focus{outline:none;border-color:var(--petrol);}
.contact-radio-row{display:flex;gap:20px;flex-wrap:wrap;margin-top:4px;}
.contact-radio{display:flex;align-items:center;gap:8px;font-size:14px;font-weight:400;}
.contact-form button[type="submit"]{align-self:flex-start;margin-top:8px;}
.contact-info-card{padding:32px;}
.contact-info-card h4{font-size:18px;margin-bottom:12px;}
.contact-info-intro{font-size:15px;line-height:1.6;color:var(--ink-muted);margin-bottom:20px;}
.contact-info-intro p{margin:0 0 10px 0;}
.contact-info-list{list-style:none;margin:0;padding:0;}
.contact-info-list li{padding:10px 0;border-top:1px solid var(--line);}
.contact-info-list li:first-child{border-top:none;}
.contact-info-list a{color:var(--ink);font-weight:600;}
.contact-info-list a:hover{color:var(--petrol);}
/* margin-top:0 (was 20px) — stacked on top of .contact-info-list li's own
   10px bottom padding, that extra margin made the gap under the phone
   number (30px to the border) much bigger than the gap above it (10px
   list-item padding + the border itself), flagged 2026-09-20. Padding
   trimmed to match for a symmetric 10px-border-10px rhythm throughout. */
.contact-whatsapp{margin-top:0;padding-top:10px;padding-bottom:10px;border-top:1px solid var(--line);}
.contact-whatsapp-label{font-size:13px;color:var(--ink-muted);margin-bottom:10px;}
.contact-whatsapp-link{display:inline-flex;align-items:center;gap:10px;font-weight:700;color:var(--ink);}
.contact-whatsapp-link:hover{color:var(--petrol);}
.contact-whatsapp-icon{width:32px;height:32px;min-width:32px;border-radius:50%;background:#25D366;color:#fff;display:flex;align-items:center;justify-content:center;}
.contact-bedrijfsgegevens{margin-top:0;padding-top:10px;border-top:1px solid var(--line);font-size:13px;color:var(--ink-muted);line-height:1.7;}

@media (max-width:900px){
  .contact-grid{grid-template-columns:1fr;}
  /* Placed after the unconditional .product-detail{grid-template-
     columns:1fr 1fr;...} rule earlier in this file on purpose: an
     identical-specificity override placed BEFORE the rule it's meant
     to override loses on source order regardless of the media query,
     so the product page's 2-column desktop layout was never actually
     collapsing to 1 column on mobile until this was moved down here. */
  /* gap:56px (desktop, unconditional .product-detail rule above) was
     inherited unchanged here — fine as a horizontal gap between the 2
     desktop columns, but once display:contents (below) promotes photo/
     thumbs/info/tabs into one stacked single-column flow, that same 56px
     becomes FOUR separate large vertical gaps (photo->thumbs, thumbs->
     info, info->tabs), which read as excessive empty space relative to
     the text — flagged 2026-09-20. 16px reads as normal stacked spacing. */
  .product-detail{grid-template-columns:1fr;gap:16px;}

  /* .breadcrumb above this section already has its own 20px top+bottom
     padding — stacked with this section's unconditional 56px top padding,
     that's 76px of empty space before the product photo, which reads as
     excessive on a small mobile viewport (flagged 2026-09-20). Bottom
     padding is untouched, only the top. */
  .product-detail-section{padding-top:24px;}

  /* Stacked mobile reading order should be photo -> title/price/CTA ->
     description tabs (matches the live reference's own mobile product
     page), not photo+tabs -> title/price/CTA as plain DOM order would
     give here (.product-detail-media wraps both the photo AND
     .product-tabs together). display:contents promotes the photo and
     tabs to be direct grid items in their own right so each can take
     an independent `order`, without any HTML change. */
  .product-detail-media{display:contents;}
  /* height:300px override (desktop is 440px, unitless): SEO audit
     2026-09-18 flagged that on mobile the photo kept its full desktop
     height, pushing title/price/CTA below the fold on first load (no
     scroll needed on desktop's wider-but-shorter viewport, but mobile is
     narrow-and-short). Shrinking just the photo, not the whole layout. */
  .product-detail-photo{order:1;height:300px;}
  .product-thumbs{order:2;}
  .product-detail-info{order:3;}
  .product-tabs{order:4;}
}

/* SEARCH (/zoeken/) — .search-results-grid reuses .product-grid's own
   layout/card rules (added via the shared class) for product hits;
   .search-result-item is a lighter card for category/brand hits, which
   have no photo/price, just a title and breadcrumb. */
.search-header{background:#EFEEEA;padding:48px var(--gutter);}
.search-form-large{display:flex;max-width:640px;margin:0 auto;border:1px solid var(--line);border-radius:999px;background:var(--card);overflow:hidden;}
.search-form-large input{flex:1;border:none;background:none;padding:16px 24px;font-size:16px;font-family:inherit;color:var(--ink);outline:none;}
.search-form-large button{border:none;background:var(--petrol);color:white;padding:0 24px;cursor:pointer;display:flex;align-items:center;}
.search-form-large button:hover{background:var(--petrol-dark);}

.search-results{padding:48px var(--gutter) 96px var(--gutter);}
.search-results h1{font-size:var(--fs-h1);text-align:center;}
.search-empty-state{text-align:center;color:var(--ink-muted);font-size:16px;padding:24px 0;}
.search-count{text-align:center;color:var(--ink-muted);font-size:15px;margin-top:8px;margin-bottom:32px;line-height:1.6;}
.search-count a{color:var(--petrol);font-weight:600;}

.search-result-item{padding:24px;border:1px solid var(--line);text-decoration:none;color:inherit;display:flex;flex-direction:column;justify-content:center;min-height:200px;}
.search-result-path{color:var(--ink-muted);font-size:12px;margin-bottom:6px;}
.search-result-title{font-weight:700;font-size:16px;}

/* FILTER FAB + MODAL — once the filter-bar itself has scrolled out of
   view (tracked via IntersectionObserver in main.js), a floating button
   appears so filters stay reachable without scrolling back up. Clicking
   it MOVES the real .filter-bar (not a clone — avoids duplicate
   name="merk"/"label" inputs going out of sync) into the modal body;
   closing moves it back to #filter-bar-anchor. Inside the modal the
   three dropdowns are forced open and stacked vertically instead of
   behaving as dropdowns. */
.filter-fab{position:fixed;right:24px;bottom:24px;width:52px;height:52px;border-radius:50%;background:var(--petrol);color:white;border:none;box-shadow:0 8px 24px rgba(0,0,0,.25);display:flex;align-items:center;justify-content:center;cursor:pointer;z-index:60;}
.filter-fab:hover{background:var(--petrol-dark);}
/* Same [hidden] vs. author-stylesheet specificity issue as .product-card
   above: an explicit display value on the element's own selector always
   beats the browser's [hidden]{display:none} UA-stylesheet rule, so the
   toggle via .hidden = true/false silently did nothing without this. */
.filter-fab[hidden]{display:none;}
/* Mobile-only (2026-09-19): on desktop the filter bar sits right at the
   top of a wide viewport, so "scrolled out of view" isn't the same signal
   of "hard to reach" it is on a narrow one — this beats the JS [hidden]
   toggle above regardless of scroll position, same breakpoint (900px) the
   rest of the site already uses for its mobile/desktop split. */
@media (min-width: 901px){
  .filter-fab{display:none !important;}
}

.filter-modal{position:fixed;inset:0;z-index:70;}
.filter-modal[hidden]{display:none;}
.filter-modal-overlay{position:absolute;inset:0;background:rgba(0,0,0,.4);opacity:0;transition:opacity .2s ease;}
.filter-modal-panel{position:absolute;left:0;right:0;bottom:0;max-height:80vh;background:var(--card);border-radius:16px 16px 0 0;display:flex;flex-direction:column;transform:translateY(100%);transition:transform .25s ease;}
.filter-modal.open .filter-modal-overlay{opacity:1;}
.filter-modal.open .filter-modal-panel{transform:translateY(0);}
.filter-modal-header{display:flex;align-items:center;justify-content:space-between;padding:18px 20px;border-bottom:1px solid var(--line);font-weight:700;font-size:16px;}
.filter-modal-header button{background:none;border:none;font-size:24px;line-height:1;cursor:pointer;color:var(--ink-muted);padding:0 4px;}
.filter-modal-body{padding:8px 20px 24px 20px;overflow-y:auto;}

.filter-modal-body .filter-bar{flex-direction:column;gap:0;padding:0;}
.filter-modal-body .filter-dropdown{border-bottom:1px solid var(--line);}
.filter-modal-body .filter-dropdown:last-child{border-bottom:none;}
.filter-modal-body .filter-toggle{width:100%;justify-content:space-between;border:none;padding:16px 0;border-radius:0;}
.filter-modal-body .filter-panel{display:block;position:static;box-shadow:none;border:none;padding:0 0 16px 0;margin:0;min-width:0;max-height:none;}
.filter-modal-body .filter-toggle svg{display:none;}

/* OFFERTE-MANDJE (quote request) — matches the live site's own "Vraag een
   offerte aan" page: a form column (contact-field/.contact-form reused
   as-is) beside a "Producten in aanvraag" cart-style list. */
.offerte-mandje-section{padding:48px var(--gutter) 96px var(--gutter);}
.offerte-mandje-grid{display:grid;grid-template-columns:1.2fr 1fr;gap:56px;align-items:start;}
.offerte-mandje-form-col h1{font-size:var(--fs-h1);margin-bottom:16px;}
.offerte-mandje-intro{color:var(--ink-muted);font-size:15px;line-height:1.6;margin:0 0 8px;}
.offerte-mandje-vereist{color:var(--ink-muted);font-size:13px;margin:0 0 24px;}
.offerte-form-grid{display:flex;flex-direction:column;gap:18px;}
.offerte-form-row{display:grid;grid-template-columns:1fr 1fr;gap:18px;}
/* Segmented pill toggle, not a visible radio-with-label row — one
   continuous rounded shape (border on the wrapper, no per-segment
   border/radius) so switching feels like flipping a single control
   rather than picking between two separate boxes. The radio input
   itself stays in the DOM (position:absolute, visually hidden) for
   real keyboard/screen-reader support; the filled/active look comes
   entirely from :has(input:checked) on its own segment. */
.offerte-klanttype-opties{display:flex;max-width:300px;border:1px solid var(--line);border-radius:999px;overflow:hidden;background:var(--card);}
.offerte-klanttype-optie{position:relative;flex:1;display:flex;align-items:center;justify-content:center;padding:13px 16px;font-size:15px;font-weight:600;color:var(--ink-muted);cursor:pointer;transition:background .15s ease,color .15s ease;}
.offerte-klanttype-optie:has(input:checked){background:var(--petrol);color:#fefaf3;}
.offerte-klanttype-optie input{position:absolute;inset:0;margin:0;opacity:0;cursor:pointer;}
.offerte-mandje-leeg{padding:24px;border:1px solid var(--line);border-radius:16px;color:var(--ink-muted);}
.offerte-mandje-leeg a{color:var(--petrol);font-weight:600;}

.offerte-mandje-producten-col h2{font-size:22px;margin-bottom:16px;}
.mandje-items{display:flex;flex-direction:column;gap:12px;margin-bottom:20px;}
.mandje-item{display:flex;align-items:center;gap:14px;padding:16px;border:1px solid var(--line);border-radius:16px;}
.mandje-item-aantal input{width:52px;padding:8px;border:1px solid var(--line);border-radius:8px;font-size:14px;text-align:center;}
.mandje-item-info{flex:1;min-width:0;}
.mandje-item-naam{font-weight:700;font-size:14px;}
.mandje-item-variant{color:var(--ink-muted);font-size:13px;margin-top:2px;}
.mandje-item-remove{width:24px;height:24px;min-width:24px;border-radius:50%;background:var(--bg);display:flex;align-items:center;justify-content:center;color:var(--ink-muted);font-size:16px;line-height:1;text-decoration:none;}
.mandje-item-remove:hover{background:var(--line);color:var(--ink);}
.offerte-mandje-btn{display:flex;width:100%;margin-top:12px;text-align:center;}

@media (max-width: 900px){
  .offerte-mandje-grid{grid-template-columns:1fr;}
  .offerte-form-row{grid-template-columns:1fr;}
  .offerte-klanttype-opties{max-width:none;}
}

/* /geluidsmetingen/'s 4-step iPhone-screenshot guide (2026-09-20) — real
   phone-shaped screenshots, so they're shown at a fixed, phone-proportioned
   width rather than stretched to fill an arbitrary grid cell. */
.geluidsmeting-stappen-section{padding:64px var(--gutter);}
.geluidsmeting-stappen-section h2{font-size:var(--fs-h2);text-align:center;margin-bottom:40px;}
.geluidsmeting-stappen-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:32px;align-items:start;}
.geluidsmeting-stap{text-align:center;}
.geluidsmeting-stap img{width:100%;max-width:220px;height:auto;margin:0 auto 20px auto;border-radius:16px;box-shadow:0 12px 32px rgba(0,0,0,.14);}
.geluidsmeting-stap h3{font-size:17px;font-family:"Overpass",system-ui,sans-serif;margin-bottom:8px;}
.geluidsmeting-stap p{font-size:14px;color:var(--ink-muted);line-height:1.6;}

@media (max-width: 900px){
  .geluidsmeting-stappen-grid{grid-template-columns:repeat(2,1fr);}
}
@media (max-width: 600px){
  .geluidsmeting-stappen-grid{grid-template-columns:1fr;}
}
