@charset "UTF-8";
/* =============================================================================
   BRIKK — 2026 design system
   =============================================================================

   The single stylesheet for the redesigned brikk.dk. When the redesign is
   complete this file replaces, and allows the deletion of:

     assets/css/brikk.css       (277 KB minified legacy bundle + its scss/ source)
     assets/css/form.css
     css/*                      (bootstrap/general/generalse/style — already dead)
     fonts/fonts.css            (Avenir — the old typeface, unused in the redesign)

   Out of scope: themes/brikk/heatmap/css/* — the heatmap pages are a separate,
   self-contained world and keep their own styling.

   Rollout status
   --------------
   Loaded ONLY on funnel pages (page template "funnel-template.php"), where the
   old brikk.css + form.css are dequeued. Everything else still runs the old CSS.
   See brikk_is_redesigned_page() / brikk_enqueue_styles_scripts() in functions.php.

   Architecture
   ------------
   Sections 1–11 are the FOUNDATION: everything global that any page relies on.
   Section 12 is where reusable COMPONENTS accumulate as the redesign is ported
   (site chrome, heroes, pricing, FAQ, …). Page-scoped work (like the funnel,
   section 13) comes last so it can lean on everything above it.

   1.  Fonts
   2.  Design tokens
   3.  Reset
   4.  Base typography
   5.  Layout
   6.  Primitives (eyebrow, titles, buttons, links, check)
   7.  Forms
   8.  Long-form content flow (.brikk-flow — editor/Gutenberg output)
   9.  WordPress core classes (alignments, captions, screen-reader-text)
   10. Utilities & accessibility
   11. Vendor — minimal slick carousel core (funnel calendar)
   12. Components (site chrome & sections — grows during milestones 2–3)
       12.6 is the property list (/boliger-til-salg/) — page-scoped like §13
       12.9 is the single property page (/ejendom/…/) — page-scoped like §13
       12.10 is the exit-intent popup (#brikk-cta-popup) — scoped .brikk-redesign,
             a provable no-op on legacy pages where brikk.css/form.css own it
   13. The booking funnel (milestone 1, page-scoped)

   Conventions
   -----------
   - All custom properties and classes are prefixed `brikk-`; components are
     named `.brikk-block`, elements `.brikk-block__element`, modifiers
     `.brikk-block--modifier` (matches the A/B design's vocabulary).
   - Use tokens, not literals: colours, type sizes, spacing, z-index and motion
     all come from section 2. A raw hex/px value in a component is a smell —
     the only sanctioned literals are one-off geometry (positioning offsets)
     and self-documenting gradients.
   - No `!important`. This file owns the page; nothing needs out-specifying.
     (Single sanctioned exception: the reduced-motion kill switch in §10.)
   - Breakpoints (CSS variables cannot be used in media queries, so these are
     fixed values used consistently throughout):
         1024px  tablet    (paired min/max queries use 1024.98px on the max side
                            so fractional zoom widths never fall between them)
          768px  small tablet — type/gutter only, never section rhythm
          640px  mobile
          420px  small mobile
         1500px  (min-width) the single wide-screen enhancement
     Two breakpoints exist that are NOT part of that ladder, both scoped to one
     component and documented where they are used:
         1170px  §12.1 only — the header CTA's long→short label swap (the A/B's
                 own nav breakpoint, kept because it buys the menu 56px)
         1080px  §12.1 only — the header collapses to the burger here, NOT at
                 1024, because the menu measurably stops fitting first
                 (2026-07-30, Andreas). Two things deliberately do NOT follow it:
                 the page gutter ladder (still 1024, so the logo stays flush with
                 the section content) and the sticky header (still 1025, because
                 that is a desktop-vs-touch question, not a fit question). Both
                 are explained where they are used. Nothing else may use 1080.
   - The DESIGN REFERENCE lives next to this file: assets/css/DESIGN.md. It holds
     the full role tables (type, colour, spacing, components) distilled from the
     A/B test, the canonical values where that file disagreed with itself, and
     the new-section checklist. Consult it before building any section.
   - When porting a section out of the A/B plugin's landing.css: drop the
     .brikk-ab-page/.brikk-ab-template scoping, drop every !important, move the
     values onto tokens (DESIGN.md §9 lists the canonical value where the A/B
     file drifts), and re-home assets into the theme (see CLAUDE.md §6).
   ============================================================================= */


/* =============================================================================
   1. FONTS
   -----------------------------------------------------------------------------
   Self-hosted from assets/fonts/. Cormorant Garamond is a variable font (OFL,
   licence included alongside it); Helvetica Neue ships as four static weights.

   TODO(perf): these are .ttf/.otf originals — ~3.4 MB total. Converting to
   .woff2 would cut that by roughly 80%. Needs fonttools installed; see CLAUDE.md.
   ============================================================================= */

   @font-face {
    font-family: 'Cormorant Garamond';
    src: url('../fonts/cormorant-garamond/CormorantGaramond-VariableFont_wght.ttf') format('truetype-variations'),
    url('../fonts/cormorant-garamond/CormorantGaramond-VariableFont_wght.ttf') format('truetype');
    font-weight: 300 700;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Cormorant Garamond';
    src: url('../fonts/cormorant-garamond/CormorantGaramond-Italic-VariableFont_wght.ttf') format('truetype-variations'),
    url('../fonts/cormorant-garamond/CormorantGaramond-Italic-VariableFont_wght.ttf') format('truetype');
    font-weight: 300 700;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: 'Helvetica Neue Local';
    src: url('../fonts/helvetica-neue/HelveticaNeueLight.otf') format('opentype');
    font-weight: 300;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Helvetica Neue Local';
    src: url('../fonts/helvetica-neue/HelveticaNeueRoman.otf') format('opentype');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Helvetica Neue Local';
    src: url('../fonts/helvetica-neue/HelveticaNeueMedium.otf') format('opentype');
    font-weight: 500;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Helvetica Neue Local';
    src: url('../fonts/helvetica-neue/HelveticaNeueBold.otf') format('opentype');
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

/* Text-field variant of the sans with CORRECTED vertical metrics.
   The OTFs declare ascender 714 (≈ cap height) while Å's ring reaches 952 and
   Ø/å/digit overshoots exceed 714 — and browsers clip a text field's inner
   editor to the font's declared ascent/descent box, so field text loses its
   top pixels and Å renders ringless no matter what the CSS box allows.
   The overrides only re-declare the metrics (96% covers Å, 22% covers the
   214-unit descenders); everything else keeps 'Helvetica Neue Local' so the
   design's verified baseline geometry is untouched. Used via
   --wp--custom--font-input on input/textarea/select in §7 only. */
@font-face {
    font-family: 'Helvetica Neue Input';
    src: url('../fonts/helvetica-neue/HelveticaNeueLight.otf') format('opentype');
    font-weight: 300;
    font-style: normal;
    font-display: swap;
    ascent-override: 96%;
    descent-override: 22%;
}

@font-face {
    font-family: 'Helvetica Neue Input';
    src: url('../fonts/helvetica-neue/HelveticaNeueRoman.otf') format('opentype');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
    ascent-override: 96%;
    descent-override: 22%;
}

@font-face {
    font-family: 'Helvetica Neue Input';
    src: url('../fonts/helvetica-neue/HelveticaNeueMedium.otf') format('opentype');
    font-weight: 500;
    font-style: normal;
    font-display: swap;
    ascent-override: 96%;
    descent-override: 22%;
}

@font-face {
    font-family: 'Helvetica Neue Input';
    src: url('../fonts/helvetica-neue/HelveticaNeueBold.otf') format('opentype');
    font-weight: 700;
    font-style: normal;
    font-display: swap;
    ascent-override: 96%;
    descent-override: 22%;
}


/* =============================================================================
   2. DESIGN TOKENS
   -----------------------------------------------------------------------------
   ⭐ SINGLE SOURCE OF TRUTH: themes/brikk/theme.json (moved 2026-07-23).
   WordPress prints every token on EVERY page — including pages that never load
   this file — inside <style id="global-styles-inline-css">, as:

     settings.color.palette            → --wp--preset--color--{slug}
     settings.typography.fontFamilies  → --wp--preset--font-family--{slug}
     settings.typography.fontSizes     → --wp--preset--font-size--{slug}
     settings.spacing.spacingSizes     → --wp--preset--spacing--{slug}
     settings.custom.{key}             → --wp--custom--{key}

   Add or change tokens THERE, never here. theme.json is JSON (no comments), so
   the non-obvious token knowledge lives in this glossary:

   - card (#fff) is for ELEVATED surfaces only; card-soft (#fbfaf8) is the
     standard card on the beige canvas (DESIGN.md §4).
   - gold is an alias of green — keeps straight landing.css ports working.
   - on-dark-* are text/hairline roles on dark surfaces (image panels, dark
     bands like the A/B .brikk-inc-why / .brikk-midcta) — reuse when porting.
     Two of them are HUES, not alphas, and are not interchangeable:
     on-dark-accent (#ada3bd) is the muted lavender used for eyebrows and the
     italic location line; on-dark-purple (#9a73e6) is a genuinely saturated
     brand purple, light enough to read on charcoal — the founder band's
     eyebrow and role line (§12.4). --purple itself fails there.
   - radius / radius-lg stay 0px: the design is deliberately square-edged.
     radius-pill (999px) is only for genuinely circular elements.
   - z-scale: every positioned layer takes z-raised/chrome/nav/modal; never
     invent ad-hoc values. Inside a band: calc(var(--wp--custom--z-chrome) + 1).
   - funnel-step-active (#9871e3): design value — brand purple lifted ~32%
     toward white for contrast against the panel photo.
   - funnel-line (#d6d3d4): NEUTRAL grey — the design draws funnel field/cell
     borders cool-grey (#dadadb cells, #d3d2d4 inputs, #d6d3d1 mobile bars),
     not the warm site hairline.
   - funnel-placeholder (#b8b6ba): field placeholder grey (design ≈ #bcbabd,
     far lighter than the muted text grey).
   - font-input: same face as sans with corrected vertical metrics — text
     fields only (see §1).
   - fontSize slugs are heading-1..6, NOT h1..h6: WP kebab-cases keys/slugs,
     and a digit directly after a letter gets split ("h1" → "h-1").

   TWO tokens stay below as an exception: --brikk-pad-x and --brikk-section-y
   step down at breakpoints, and theme.json cannot express media queries.
   Keeping base value + overrides together in this file also means no
   cascade-order dependency on the inline global styles. (--brikk-flow-space
   in §8 is a local rhythm knob, not a design token.)
   ============================================================================= */

:root {
    --brikk-pad-x: 65px;        /* container gutter; steps down responsively */
    --brikk-section-y: 96px;    /* vertical rhythm between full-width sections */
}

@media (max-width: 1024px) {
    :root {
        --brikk-pad-x: 32px;
        --brikk-section-y: 72px;
    }
}

@media (max-width: 768px) {
    :root {
        --brikk-pad-x: 24px;
    }
}

@media (max-width: 640px) {
    :root {
        --brikk-pad-x: 20px;
        --brikk-section-y: 56px;
    }
}


/* =============================================================================
   3. RESET
   -----------------------------------------------------------------------------
   Deliberately assertive — but SCOPED (2026-07-23): this file now loads on
   EVERY page (the site chrome needs it), while legacy pages still run
   brikk.css for their content. All element-level sections (§3 reset, §4 base
   typography, §7 forms) are therefore scoped under the `brikk-redesign` class
   that header.php puts on <html> when brikk_is_redesigned_page() is true.
   :where() keeps every selector at zero added specificity, so redesigned
   pages behave exactly as before the scoping. Class-rooted sections (§5, §6,
   §8-§13) stay unscoped — they cannot touch legacy markup.
   ============================================================================= */

   :where(.brikk-redesign) *,
   :where(.brikk-redesign) *::before,
   :where(.brikk-redesign) *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
    border: 0;
}

html:where(.brikk-redesign) {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
}

:where(.brikk-redesign) body {
    background: var(--wp--preset--color--bg);
    color: var(--wp--preset--color--dark);
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--body);
    font-weight: 400;
    line-height: var(--wp--custom--lh-base);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
    /* Catches the .alignfull 100vw scrollbar overhang. ⚠ Makes body a clip
       container: position:sticky inside body will not stick. If milestone 2+
       needs sticky UI, move this clip to a layout wrapper instead. */
       overflow-x: hidden;
   }

   :where(.brikk-redesign) img,
   :where(.brikk-redesign) picture,
   :where(.brikk-redesign) video,
   :where(.brikk-redesign) canvas,
   :where(.brikk-redesign) svg {
    display: block;
    max-width: 100%;
    height: auto;
}

:where(.brikk-redesign) ul,
:where(.brikk-redesign) ol {
    list-style: none;
}

:where(.brikk-redesign) table {
    border-collapse: collapse;
    border-spacing: 0;
}

/* Kept out of the img/video reset on purpose: height:auto would collapse
   iframes. Width containment only, so embeds can't overflow small screens. */
   :where(.brikk-redesign) iframe {
    max-width: 100%;
}

:where(.brikk-redesign) hr {
    height: 1px;
    background: var(--wp--preset--color--line);
    border: 0;
}


/* =============================================================================
   4. BASE TYPOGRAPHY
   ============================================================================= */

   :where(.brikk-redesign) :is(h1, h2, h3, h4, h5, h6),
   :where(.brikk-redesign) .brikk-serif {
    font-family: var(--wp--preset--font-family--serif);
    font-weight: 500;
    line-height: var(--wp--custom--lh-tight);
    letter-spacing: var(--wp--custom--ls-heading);
    color: var(--wp--preset--color--dark);
    text-wrap: balance;
}

:where(.brikk-redesign) h1 { font-size: var(--wp--preset--font-size--heading-1); }
:where(.brikk-redesign) h2 { font-size: var(--wp--preset--font-size--heading-2); }
:where(.brikk-redesign) h3 { font-size: var(--wp--preset--font-size--heading-3); }
:where(.brikk-redesign) h4 { font-size: var(--wp--preset--font-size--heading-4); line-height: var(--wp--custom--lh-heading); }
:where(.brikk-redesign) h5 { font-size: var(--wp--preset--font-size--heading-5); line-height: var(--wp--custom--lh-heading); }
:where(.brikk-redesign) h6 { font-size: var(--wp--preset--font-size--heading-6); line-height: var(--wp--custom--lh-heading); }

:where(.brikk-redesign) p {
    line-height: var(--wp--custom--lh-copy);
    text-wrap: pretty;
}

:where(.brikk-redesign) a {
    color: inherit;
    text-decoration: none;
    transition: color var(--wp--custom--transition);
}

:where(.brikk-redesign) strong,
:where(.brikk-redesign) b {
    font-weight: 500;
}

:where(.brikk-redesign) small {
    font-size: var(--wp--preset--font-size--ui);
}

:where(.brikk-redesign) ::selection {
    background: var(--wp--preset--color--purple);
    color: var(--wp--custom--on-accent);
}


/* =============================================================================
   5. LAYOUT
   ============================================================================= */

   .brikk-container {
    width: 100%;
    max-width: var(--wp--custom--max);
    margin-inline: auto;
    padding-inline: var(--brikk-pad-x);
}

.brikk-container--narrow {
    max-width: var(--wp--custom--max-narrow);
}

.brikk-section {
    padding-block: var(--brikk-section-y);
}


/* =============================================================================
   6. PRIMITIVES
   ============================================================================= */

/* --- Eyebrow: tiny wide-tracked uppercase label above a heading ------------ */
/* line-height is explicit because the eyebrow is a <p> in block patterns and a
   <span> in hand-written markup: §4 gives paragraphs 1.6, spans inherit 1.4,
   and the design wants the base 1.4 for both (an eyebrow is one line by
   definition). The A/B got there by forcing 1.4 on every element in its reset. */
.brikk-eyebrow {
    display: inline-block;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--eyebrow);
    font-weight: 500;
    line-height: var(--wp--custom--lh-base);
    letter-spacing: var(--wp--custom--ls-eyebrow);
    text-transform: uppercase;
    color: var(--wp--preset--color--muted);
}

/* Eyebrows tighten on small screens — at .34em tracking an 11.5px eyebrow wraps
   awkwardly under ~640px. The design applies this to EVERY eyebrow, so it lives
   on the primitive rather than being repeated per component. */
@media (max-width: 640px) {
    .brikk-eyebrow {
        font-size: var(--wp--preset--font-size--micro);
        letter-spacing: .28em;
    }
}

/* --- Section heading + lead ----------------------------------------------- */
.brikk-section-title {
    font-family: var(--wp--preset--font-family--serif);
    font-size: var(--wp--preset--font-size--heading-2);
    font-weight: 500;
    line-height: var(--wp--custom--lh-tight);
    letter-spacing: var(--wp--custom--ls-heading);
    color: var(--wp--preset--color--dark);
}

.brikk-section-lead {
    max-width: var(--wp--custom--measure);
    font-size: var(--wp--preset--font-size--body-sm);
    line-height: var(--wp--custom--lh-copy);
    color: var(--wp--preset--color--muted);
}

/* --- Buttons --------------------------------------------------------------- */
.brikk-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--wp--preset--spacing--2);
    /* Asymmetric padding: the uppercase sans sits optically high in its box. */
    padding: 17px 22px 14px;
    border: 1px solid transparent;
    border-radius: var(--wp--custom--radius);
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui-sm);
    font-weight: 500;
    line-height: 1.3;
    letter-spacing: var(--wp--custom--ls-ui);
    text-transform: uppercase;
    text-align: center;
    cursor: pointer;
    transition: background var(--wp--custom--transition),
    color var(--wp--custom--transition),
    border-color var(--wp--custom--transition);
}

.brikk-btn--primary {
    background: var(--wp--preset--color--purple);
    color: var(--wp--custom--on-accent);
}

.brikk-btn--primary:hover {
    background: var(--wp--custom--purple-hover);
    color: var(--wp--custom--on-accent);
}

.brikk-btn--outline {
    background: transparent;
    color: var(--wp--preset--color--purple);
    border-color: var(--wp--preset--color--purple);
}

.brikk-btn--outline:hover {
    background: var(--wp--custom--purple-tint);
}

.brikk-btn--ghost {
    background: transparent;
    color: var(--wp--preset--color--dark);
    border-color: var(--wp--preset--color--dark);
}

.brikk-btn--ghost:hover {
    background: var(--wp--preset--color--dark);
    color: var(--wp--custom--on-accent);
}

.brikk-btn:disabled,
.brikk-btn[aria-disabled='true'] {
    opacity: 0.45;
    pointer-events: none;
}

/* --- Underlined arrow link ------------------------------------------------- */
.brikk-link-arrow {
    display: inline-flex;
    align-self: flex-start;
    align-items: center;
    gap: var(--wp--preset--spacing--2);
    padding-bottom: 2px;
    border-bottom: 1px solid var(--wp--custom--line-dark);
    font-size: var(--wp--preset--font-size--ui-sm);
    font-weight: 500;
    letter-spacing: var(--wp--custom--ls-ui);
    text-transform: uppercase;
    color: var(--wp--preset--color--dark);
    opacity: 0.6;
    transition: gap var(--wp--custom--transition), opacity var(--wp--custom--transition);
}

.brikk-link-arrow:hover {
    gap: var(--wp--preset--spacing--3);
    opacity: 1;
}

/* --- Checkmark bullet ------------------------------------------------------ */
/* A circled serif checkmark used in feature and price lists. */
.brikk-check {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    padding-top: 4px;
    border: 1px solid var(--wp--preset--color--purple);
    border-radius: var(--wp--custom--radius-pill);
    font-family: var(--wp--preset--font-family--serif);
    font-size: 9px;
    line-height: 1;
    color: var(--wp--preset--color--purple);
}


/* =============================================================================
   7. FORMS
   -----------------------------------------------------------------------------
   Base field styling only. Note: the dequeued form.css was Contact Form 7
   styling — .wpcf7-* chrome is re-provided PER SURFACE, not globally:
   §12.9.9 (single-property modals) and §12.10 (the exit-intent popup).
   ============================================================================= */

   :where(.brikk-redesign) :is(input, textarea, select, button) {
    font: inherit;
    color: inherit;
    background: transparent;
    border: 0;
    border-radius: 0;
    outline: 0;
}

:where(.brikk-redesign) button,
:where(.brikk-redesign) input[type='submit'],
:where(.brikk-redesign) input[type='button'] {
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
}

:where(.brikk-redesign) label {
    display: inline-block;
    font-size: var(--wp--preset--font-size--ui);
}

:where(.brikk-redesign) input[type='text'],
:where(.brikk-redesign) input[type='email'],
:where(.brikk-redesign) input[type='tel'],
:where(.brikk-redesign) input[type='number'],
:where(.brikk-redesign) input[type='search'],
:where(.brikk-redesign) input[type='password'],
:where(.brikk-redesign) input[type='url'],
:where(.brikk-redesign) input[type='date'],
:where(.brikk-redesign) textarea,
:where(.brikk-redesign) select {
    width: 100%;
    padding: 15px 16px 13px;
    background: var(--wp--preset--color--card);
    border: 1px solid var(--wp--preset--color--line);
    border-radius: var(--wp--custom--radius);
    font-family: var(--wp--custom--font-input);
    font-size: var(--wp--preset--font-size--body-sm);
    color: var(--wp--preset--color--dark);
    transition: border-color var(--wp--custom--transition);
    /* Kill native chrome (search fields especially: Safari's rounded corners
       and cancel button would override the square hairline look). */
       appearance: none;
       -webkit-appearance: none;
   }

   :where(.brikk-redesign) input[type='search']::-webkit-search-decoration,
   :where(.brikk-redesign) input[type='search']::-webkit-search-cancel-button {
    -webkit-appearance: none;
    display: none;
}

@media (max-width: 1024.98px) {
    /* Field copy is 15px on touch viewports per the design… */
    :where(.brikk-redesign) input[type='text'],
    :where(.brikk-redesign) input[type='email'],
    :where(.brikk-redesign) input[type='tel'],
    :where(.brikk-redesign) input[type='number'],
    :where(.brikk-redesign) input[type='search'],
    :where(.brikk-redesign) input[type='password'],
    :where(.brikk-redesign) input[type='url'],
    :where(.brikk-redesign) input[type='date'],
    :where(.brikk-redesign) textarea,
    :where(.brikk-redesign) select {
        font-size: 15px;
    }

    /* …EXCEPT on iOS: Safari auto-zooms the page when focusing any input
       under 16px and leaves it zoomed. -webkit-touch-callout exists only on
       iOS, so this @supports matches iOS (and nothing else). */
    @supports (-webkit-touch-callout: none) {
        :where(.brikk-redesign) input[type='text'],
        :where(.brikk-redesign) input[type='email'],
        :where(.brikk-redesign) input[type='tel'],
        :where(.brikk-redesign) input[type='number'],
        :where(.brikk-redesign) input[type='search'],
        :where(.brikk-redesign) input[type='password'],
        :where(.brikk-redesign) input[type='url'],
        :where(.brikk-redesign) input[type='date'],
        :where(.brikk-redesign) textarea,
        :where(.brikk-redesign) select {
            font-size: 16px;
        }
    }
}

:where(.brikk-redesign) :is(input, textarea, select):focus {
    border-color: var(--wp--preset--color--purple);
}

:where(.brikk-redesign) ::placeholder {
    color: var(--wp--preset--color--muted);
    opacity: 1;
}

:where(.brikk-redesign) textarea {
    min-height: 140px;
    line-height: var(--wp--custom--lh-copy);
    resize: vertical;
}

:where(.brikk-redesign) select {
    /* Native arrow is removed; the chevron is drawn as a background image so
       the control matches the square, hairline look of the text inputs. */
       appearance: none;
       padding-right: 40px;
       background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%231a1a1a' stroke-width='1.5' d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E");
       background-repeat: no-repeat;
       background-position: right 16px center;
       cursor: pointer;
   }

   :where(.brikk-redesign) :is(input[type='checkbox'], input[type='radio']) {
    width: 16px;
    height: 16px;
    accent-color: var(--wp--preset--color--purple);
    cursor: pointer;
}

/* Validation state — matches the class jQuery Validate applies. */
:where(.brikk-redesign) :is(input, textarea, select).error {
    border-color: var(--wp--custom--error);
}

:where(.brikk-redesign) label.error {
    display: block;
    margin-top: var(--wp--preset--spacing--2);
    font-size: var(--wp--preset--font-size--ui-sm);
    color: var(--wp--custom--error);
}


/* =============================================================================
   8. LONG-FORM CONTENT FLOW
   -----------------------------------------------------------------------------
   The reset in §3 strips ALL margins, which is right for hand-built components
   but wrong for editor output: Gutenberg/long-form content (blog posts, legal
   pages) would collapse into a wall of text. `.brikk-flow` opts a container's
   content back into vertical rhythm and restores the element styling that
   long-form copy needs.

   Everything uses :where() so it has ZERO specificity — any component style
   overrides it with a bare class selector, no fighting.

   NOTE for milestone 3: page.php currently renders the_content() with no
   wrapper element. When Gutenberg pages start landing, either wrap
   the_content() in <div class="brikk-flow"> or extend the selectors here.
   ============================================================================= */

   .brikk-flow {
    --brikk-flow-space: 1.1em;
}

:where(.brikk-flow) > :where(*) + :where(*) {
    margin-top: var(--brikk-flow-space);
}

/* Headings bind to what follows them: generous air above, little below. */
:where(.brikk-flow) > :where(h1, h2, h3, h4, h5, h6) {
    margin-top: calc(var(--brikk-flow-space) * 2);
}

:where(.brikk-flow) > :where(h1, h2, h3, h4, h5, h6) + :where(*) {
    margin-top: 0.65em;
}

/* Restore the list styling the reset removed — inside flowing copy only. */
:where(.brikk-flow) :where(ul) {
    list-style: disc;
    padding-left: 1.3em;
}

:where(.brikk-flow) :where(ol) {
    list-style: decimal;
    padding-left: 1.3em;
}

:where(.brikk-flow) :where(li) + :where(li) {
    margin-top: 0.4em;
}

:where(.brikk-flow) :where(blockquote) {
    padding: var(--wp--preset--spacing--4) var(--wp--preset--spacing--5);
    border-left: 2px solid var(--wp--preset--color--purple);
    background: var(--wp--preset--color--card);
    font-family: var(--wp--preset--font-family--serif);
    font-size: var(--wp--preset--font-size--heading-5);
    line-height: 1.45;
}

:where(.brikk-flow) :where(figcaption) {
    margin-top: var(--wp--preset--spacing--2);
    font-size: var(--wp--preset--font-size--ui-sm);
    color: var(--wp--preset--color--muted);
}

:where(.brikk-flow) :where(a) {
    color: var(--wp--preset--color--purple);
    text-decoration: underline;
    text-underline-offset: 2px;
}

:where(.brikk-flow) :where(a):hover {
    color: var(--wp--custom--purple-hover);
}

:where(.brikk-flow) :where(table) {
    width: 100%;
}

:where(.brikk-flow) :where(pre) {
    padding: var(--wp--preset--spacing--4);
    background: var(--wp--preset--color--dark);
    color: var(--wp--custom--on-dark);
    font-size: var(--wp--preset--font-size--ui);
    overflow-x: auto;
}


/* =============================================================================
   9. WORDPRESS CORE CLASSES
   -----------------------------------------------------------------------------
   Classes WordPress emits on editor/theme output. Kept minimal: block-library
   CSS still handles block internals; these cover what a CLASSIC theme must
   provide itself. Wide/full alignments become meaningful at milestone 3, when
   theme.json enables them — the rules are ready.
   ============================================================================= */

   .screen-reader-text {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* Skip links (milestone-2 header) must become visible when keyboard-focused. */
.screen-reader-text:focus {
    position: fixed;
    top: var(--wp--preset--spacing--3);
    left: var(--wp--preset--spacing--3);
    z-index: var(--wp--custom--z-modal);
    width: auto;
    height: auto;
    padding: var(--wp--preset--spacing--3) var(--wp--preset--spacing--4);
    clip-path: none;
    background: var(--wp--preset--color--card);
    color: var(--wp--preset--color--dark);
    font-size: var(--wp--preset--font-size--ui);
}

.alignleft {
    float: left;
    margin: 0 var(--wp--preset--spacing--5) var(--wp--preset--spacing--4) 0;
}

.alignright {
    float: right;
    margin: 0 0 var(--wp--preset--spacing--4) var(--wp--preset--spacing--5);
}

.aligncenter {
    display: block;
    margin-inline: auto;
}

/* Inside a constrained flow container, wide/full break out of the measure. */
:where(.brikk-flow) > .alignwide {
    width: 100%;
    max-width: var(--wp--custom--max-narrow);
    margin-inline: auto;
}

:where(.brikk-flow) > .alignfull {
    width: 100vw;
    max-width: 100vw;
    margin-inline: calc(50% - 50vw);
}

.wp-caption {
    max-width: 100%;
}

.wp-caption-text {
    margin-top: var(--wp--preset--spacing--2);
    font-size: var(--wp--preset--font-size--ui-sm);
    color: var(--wp--preset--color--muted);
}

/* Theme-check staples — intentionally unstyled, but must exist. */
.sticky {}
.bypostauthor {}


/* =============================================================================
   10. UTILITIES & ACCESSIBILITY
   ============================================================================= */

/* `revert` restores the element's UA default display, so these work on block
   and inline elements alike. */
   .brikk-hide-desktop { display: none; }

   @media (max-width: 640px) {
    .brikk-hide-mobile { display: none; }
    .brikk-hide-desktop { display: revert; }
}

.brikk-text-center { text-align: center; }

/* Responsive section gutter, for the outer group of every block pattern.
   -----------------------------------------------------------------------------
   The ONE piece of section geometry the block editor cannot express: a padding
   control emits a single fixed value, so a pattern with 65px padding keeps it
   on a 390px phone (exactly the bug the A/B footer shipped). Patterns therefore
   set VERTICAL padding through the editor's spacing controls — which stays
   editable — and take horizontal gutters from this class.

   Pairs with theme.json's layout.contentSize (1470px): a full-width group with
   these gutters and that content size reproduces the design's 1600px container
   exactly at every viewport. */
.brikk-gutter {
    padding-inline: var(--brikk-pad-x);
}
.brikk-measure { max-width: var(--wp--custom--measure); }

/* Visually hidden but available to screen readers. */
.brikk-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* Keyboard focus ring. Pointer users never see it; keyboard users always do. */
:focus-visible {
    outline: 2px solid var(--wp--preset--color--purple);
    outline-offset: 2px;
}

/* Text fields always match :focus-visible, so the ring would stack on the
   purple :focus border and read as a double border. The border IS their
   focus indicator. */
:where(.brikk-redesign) :is(input, textarea, select):focus-visible {
    outline: none;
}

@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }

    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}


/* =============================================================================
   11. VENDOR — MINIMAL SLICK CORE
   -----------------------------------------------------------------------------
   The funnel's date carousel is driven by slick (funnel-calendar.js:7). These
   are the structural rules from slick.css that the carousel cannot function
   without; all cosmetics live in the funnel section below. The .slick-dots
   structure is NOT here — add it when a dotted carousel (reviews, sold
   properties) ports at milestone 3.
   ============================================================================= */

   .slick-slider {
    position: relative;
    display: block;
    box-sizing: border-box;
    user-select: none;
    -webkit-touch-callout: none;
    touch-action: pan-y;
}

.slick-list {
    position: relative;
    display: block;
    overflow: hidden;
    margin: 0;
    padding: 0;
}

.slick-list:focus {
    outline: 0;
}

.slick-list.dragging {
    cursor: pointer;
}

.slick-slider .slick-track,
.slick-slider .slick-list {
    transform: translate3d(0, 0, 0);
}

.slick-track {
    position: relative;
    top: 0;
    left: 0;
    display: block;
    margin-inline: auto;
}

.slick-track::before,
.slick-track::after {
    display: table;
    content: '';
}

.slick-track::after {
    clear: both;
}

.slick-slide {
    display: none;
    float: left;
    height: 100%;
    min-height: 1px;
}

.slick-initialized .slick-slide {
    display: block;
}

.slick-arrow.slick-hidden {
    display: none;
}


/* =============================================================================
   12. COMPONENTS — SITE CHROME & SECTIONS
   -----------------------------------------------------------------------------
   Reserved. This is where the reusable pieces of the redesign accumulate:

     12.1  Header / navigation      (milestone 2 — header.php rewrite)
     12.2  Footer                   (milestone 2 — footer.php rewrite)
     12.3  Section components       (milestone 3 — hero, logos strip, features,
           pricing, testimonial, broker search, trust/reviews, marketing,
           results, all-in-one, steps, FAQ, CTA bands, founder, comparison —
           ported one by one from the A/B plugin's landing.css as pages land
           in Gutenberg, following the porting rules in the file header)

   Keep components self-contained, token-driven, and ordered as listed above.

   Ported so far:
     12.1   Site header (.brikk-header) + 12.2 mobile drawer (.brikk-drawer) —
            built 2026-07-23, geometry measured 1:1 from the A/B header.
     12.2b  Site footer (.brikk-sitefooter) — built 2026-07-29, measured 1:1
            from the A/B footer on production. Markup: footer.php.
     12.3a  Agent search (.brikk-broker) — the postcode → mægler lookup card.
            Markup: [brikk-agent-search] shortcode (brikk-tracking plugin).

   Milestone-2 still owed: a skip link in header.php (styles ready in §9).
   ============================================================================= */


/* -----------------------------------------------------------------------------
   12.1  SITE HEADER  ·  .brikk-header
   -----------------------------------------------------------------------------
   Markup: themes/brikk/header.php (the 2026 chrome). Renders on EVERY page —
   redesigned pages (only this file) and legacy pages (brikk.css + this file) —
   so it is fully self-contained: box model, fonts, link/list resets are all
   explicit and nothing is inherited from either stylesheet.

   Geometry, type and colour measured 1:1 from the A/B header
   (/ab-landing-test/, design-QA 2026-07-23): bar 93px desktop / 84px ≤1080,
   container = 1600px + --brikk-pad-x gutters, links 12.5px · ls .16em · 400,
   CTA 12px · ls .2em · 500 at ~49px height, burger 30×2px lines with 7px gaps.
   Deliberate token substitutions vs the A/B computed values (imperceptible,
   keeps the token system honest): link/burger colour --dark (A/B computed the
   legacy #2d313b / #000), hairline --line-cool #d6d3d4 (A/B border #d6d3d1).
   -------------------------------------------------------------------------- */

/* Legacy brikk.css pads the body 91px to clear its position:fixed nav. The
   2026 header is in-flow, so the offset must go everywhere. This file loads
   AFTER the legacy pair (see brikk_enqueue_styles_scripts) — equal
   specificity, later order wins. */
body {
    padding-top: 0;
}

/* The one legacy-behaviour class the chrome keeps: the drawer's scroll lock.
   Same name as the legacy offcanvas used, so muscle memory and any old JS
   references stay valid. */
body.brikk-disable-scroll {
    overflow: hidden;
}

.brikk-header,
.brikk-header *,
.brikk-header *::before,
.brikk-header *::after,
.brikk-drawer,
.brikk-drawer * {
    box-sizing: border-box;
}

.brikk-header {
    /* Own gutter variable, NOT --brikk-pad-x: pages can (and do) override the
       page gutter on an ancestor of the header — the A/B templates set
       --brikk-pad-x: 65px on body.brikk-ab-template with responsive steps
       scoped to their content wrapper only, which would freeze the header at
       65px on mobile. The chrome carries its own steps and is immune. */
    --brikk-header-pad: 65px;
    background: var(--wp--preset--color--bg);
    border-bottom: 1px solid var(--wp--custom--line-cool);
    font-family: var(--wp--preset--font-family--sans);
}

/* ⚠️ The gutter ladder deliberately still steps at 1024, NOT at the 1080 nav
   collapse below: --brikk-pad-x (the PAGE gutter) steps 65 → 32 at 1024, and the
   logo/burger must stay flush with the page content beside them. Stepping the
   header to 32px at 1080 would inset the logo 33px further than the section
   content underneath it in the 1025-1080 band. Two different breakpoints on
   purpose — the collapse is about horizontal SPACE for the menu, the gutter is
   about ALIGNMENT with the page. */
@media (max-width: 1024.98px) {
    .brikk-header { --brikk-header-pad: 32px; }
}

@media (max-width: 768px) {
    .brikk-header { --brikk-header-pad: 24px; }
}

@media (max-width: 640px) {
    .brikk-header { --brikk-header-pad: 20px; }
}

/* ⚠️ STICKY IS DELIBERATELY STILL 1025, NOT THE 1080 COLLAPSE BELOW. The two used
   to share a breakpoint only because both happened to be 1024; they are different
   questions. "Does the menu fit?" is answered by the bar's content width (1080 —
   see the note at the collapse). "Should the header follow the scroll?" is a
   desktop-vs-touch question, and a 1050px browser window is still a desktop with
   plenty of vertical room. Coupling them would have silently un-stuck the header
   across the whole 1025-1080 band, which is not what was asked for. So in that
   band the bar is sticky, 84px, and shows the burger — which is fine, and is what
   most sites do. One line to re-couple if that is ever wanted. */
@media (min-width: 1025px) {
    .brikk-header {
        position: sticky;
        top: 0;
        z-index: var(--wp--custom--z-nav);
    }

    /* Keep the sticky bar clear of the WP admin bar for logged-in users. */
    .admin-bar .brikk-header {
        top: 32px;
    }

    /* Property pages: the legacy nav was position:absolute here (shipped
       brikk.css — `.single-nsa_js_property .brikk-navigation`), i.e. it
       scrolls away instead of pinning. Keep that behaviour. */
    .single-nsa_js_property .brikk-header {
        position: static;
    }
}

.brikk-header__inner {
    /* position:relative = the anchor for the full-width mega-dropdown. */
    position: relative;
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    max-width: var(--wp--custom--max);
    margin-inline: auto;
    padding-inline: var(--brikk-header-pad);
    min-height: 93px;
}

.brikk-header__brand a {
    display: block;
    line-height: 0;
}

.brikk-header__brand img {
    /* 110px wide (height follows the intrinsic ratio → ~33.4px): matches the
       A/B header's RENDERED logo, which the legacy CSS width-capped at 110. */
    display: block;
    width: 110px;
    height: auto;
    max-width: none;
}

/* --- desktop menu --------------------------------------------------------- */

.brikk-header__nav ul {
    list-style: none;
    margin: 0;
    padding: 0;
}

.brikk-header__menu {
    display: flex;
    align-items: stretch;
}

.brikk-header__menu li {
    /* NOT position:relative — the mega-dropdown anchors to __inner instead. */
    display: flex;
    align-items: center;
    margin: 0;
}

.brikk-header__menu a {
    display: flex;
    align-items: center;
    padding: 35px 20px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 12.5px;
    font-weight: 400;
    letter-spacing: var(--wp--custom--ls-nav);
    text-transform: uppercase;
    text-decoration: none;
    color: var(--wp--preset--color--dark);
    /* 🔴 STATED, NOT INHERITED — same trap as the footer widget title. The label
       leading used to be inherited, which on a LEGACY page means the legacy
       `body { line-height: 150% }` on a 15px body, i.e. an absolute 22.5px. On a
       REDESIGNED page there is no legacy CSS, so it inherited the design
       system's 1.4 ratio = 17.5px instead, and every nav item that wraps to two
       lines came out 10px short (header 106px instead of 116px in the cramped
       1025-1170 band). Harmless while only the funnel was redesigned — the
       funnel hides the chrome — but it would have changed the header height
       site-wide at cutover. */
    line-height: 22.5px;
    /* Legacy sets transition:none on nav links explicitly — the hover
       parallelogram snaps, it does not fade. (A fade here also fails to
       paint in the headless design-QA pipeline, so keep the snap.) */
    transition: none;
}

/* Legacy top-level link box, ported 1:1 (2026-07-29, Andreas wants full
   brikk.css parity). The link is permanently skewed -11deg (the legacy
   parallelogram; the background only shows on hover) and the label span is
   counter-skewed so text stays upright. Direct-child selectors: sub-menu
   links must stay unskewed. */
.brikk-header__menu > li > a {
    transform: skew(-11deg);
}

/* Only parent items get the wider 40px right padding (it houses the
   chevron, so the parallelogram encloses label + chevron); childless items
   (Log ind, Kontakt) keep 20px, per legacy. cursor:default = legacy — the
   parent links have no href. */
.brikk-header__menu > li.menu-item-has-children > a {
    padding-right: 40px;
    cursor: default;
}

.brikk-header__menu > li > a > span {
    transform: skew(11deg);
}

/* Chevron span injected after </a> by brikk_menu_arrow() (functions.php).
   Legacy geometry: a zero-width positioned anchor (the legacy
   .brikk-navigation-toggle-dropdown-wrapper trick) whose icon is pulled
   left into the link's 40px right padding — visually inside the
   parallelogram, without being a child of the skewed link. */
.brikk-header__menu .brikk-menu-toggle {
    position: relative;
    width: 0;
    color: var(--wp--preset--color--dark);
    pointer-events: none;
}

/* 🔴 THE SIZE MUST BE STATED HERE. §3's reset gives every svg `max-width: 100%;
   height: auto` — but ONLY on redesigned pages, where <html> carries
   .brikk-redesign. The parent span above is `width: 0` (deliberately: it is a
   zero-width positioning anchor), so `max-width: 100%` resolved to 0 and the
   chevron VANISHED on every redesigned page while still rendering on legacy and
   A/B pages. Found 2026-07-30.
   This is the §6e lesson again in a new costume: shared chrome renders in two
   different CSS environments until cutover, so it must state what it needs and
   inherit nothing. Never rely on an svg's width/height ATTRIBUTES inside the
   chrome. */
.brikk-header__menu .brikk-menu-toggle svg {
    position: absolute;
    left: -30px;
    top: 50%;
    width: 10px;
    height: 7px;
    max-width: none;
    transform: translateY(-50%);
}

.brikk-header__menu li:hover > a,
.brikk-header__menu li:focus-within > a {
    background: var(--wp--custom--bg-dim);
    color: var(--wp--preset--color--dark);
}

/* The MEGA-DROPDOWN — ported 1:1 from the legacy nav (_navigation.scss:113-235)
   with the A/B recolour (#edeae7 panel). Two-column item grid with 40×40
   photo thumbnails, hairline column separators, and the Trustpilot + MDE
   block bottom-right in the reserved 310px gutter. (The skew(-11deg) hover
   parallelogram, initially dropped as off-system, was ported back
   2026-07-29 — Andreas wants full legacy-nav parity.) */

.brikk-header__menu .sub-menu {
    position: absolute;
    top: 100%;
    /* Inset by the header gutter: the legacy anchor (.brikk-navigation-inner)
       was the old container's CONTENT box — no gutters of its own — so
       left:0/right:0 put the panel flush with the logo/CTA edges. __inner
       carries its gutters as padding, and absolute offsets resolve against
       the padding box, so a 0-offset panel here overhangs the content by
       65px per side (full-bleed at ≤1600px viewports). */
    left: var(--brikk-header-pad);
    right: var(--brikk-header-pad);
    display: none;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    padding: 40px 310px 40px 60px;
    background: var(--wp--custom--bg-dim);
    z-index: var(--wp--custom--z-nav);
}

.brikk-header__menu li:hover > .sub-menu,
.brikk-header__menu li:focus-within > .sub-menu {
    display: flex;
}

.brikk-header__menu .sub-menu li {
    position: relative;
    display: flex;
    align-items: center;
    width: 100%;
    max-width: 47%;
    min-height: 64px;
    padding: 0 0 0 55px;
    border-right: 1px solid var(--wp--custom--line-cool);
}

.brikk-header__menu .sub-menu li:last-of-type {
    border-right: 0;
}

.brikk-header__menu .sub-menu a {
    display: block;
    width: 100%;
    padding: 0 30px 0 0;
    background: none;
    line-height: 1.4;
}

/* No hover underline on dropdown links: the legacy CSS underlines them, but
   the A/B's blanket `text-decoration: none !important` kills it, so the
   shipped front page shows none — matched here for parity. */

/* 40×40 photo thumbnail slot; the per-item image comes from the menu item's
   brikk-navigation-image-N class below. */
.brikk-header__menu .sub-menu a::before {
    content: '';
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 40px;
    height: 40px;
    background-color: var(--wp--custom--line-cool);
    background-size: cover;
    background-repeat: no-repeat;
}

/* Trustpilot item: sits absolutely in the panel's right gutter — MDE logo
   block above the TrustBox widget (the label carries the widget HTML). */
.brikk-header__menu .sub-menu li.brikk-navigation-trustpilot {
    position: absolute;
    right: 100px;
    bottom: 30px;
    width: auto;
    max-width: none;
    min-height: 0;
    padding: 0;
    border: 0;
}

.brikk-header__menu .sub-menu li.brikk-navigation-trustpilot a {
    padding: 0;
}

.brikk-header__menu .sub-menu li.brikk-navigation-trustpilot a::before {
    display: none;
}

.brikk-header__menu .sub-menu li.brikk-navigation-trustpilot span::before {
    content: '';
    display: block;
    width: 100px;
    height: 90px;
    margin-left: 5px;
    background-image: url('../img/mde-logo-grey.png');
    background-size: 100%;
    background-repeat: no-repeat;
}

/* TrustBox wrapper cap — on production this rule lives ONLY in the
   Customizer "Additional CSS" (DB, no theme file). Duplicated here, scoped
   to the new chrome, so the header renders the widget correctly even if
   that Customizer block is ever pruned. The widget iframe itself is drawn
   by the Trustpilot bootstrap script (hardcoded in footer.php; blocked
   locally by brikk-local-dev — the slot renders empty on local installs). */
.brikk-header__menu .sub-menu .brikk-best-visiblity-box-trustpilot-widget-scaling {
    width: 100%;
    max-width: 130px;
    height: 83px;
    margin: auto;
}

/* WPML language-switcher item (production only — WPML injects it at render
   time): HIDDEN in the new chrome, desktop menu and drawer alike (Andreas,
   2026-08-07 — matches the A/B, which hides it via li#menu-item-wpml-ls-…).
   The class selector is WPML's stable menu-item class; the [id^=] form is the
   belt-and-braces twin of the A/B's ID-based rule. Untestable locally (no
   WPML) — verify hidden on production after deploy. To bring the switcher
   back, delete this block and restore the compact per-item dropdown it
   replaced (see git-less history: CLAUDE.md §6c / the 2026-08-07 decision). */
.brikk-header__menu li.wpml-ls-menu-item,
.brikk-header__menu li[id^="menu-item-wpml-ls-"],
.brikk-drawer li.wpml-ls-menu-item,
.brikk-drawer li[id^="menu-item-wpml-ls-"] {
    display: none;
}

/* The per-item thumbnail images (menu item CSS classes, same as legacy). */
.brikk-header__menu .brikk-navigation-image-1 > a::before { background-image: url('../img/navigation/nav-1.jpg'); }
.brikk-header__menu .brikk-navigation-image-2 > a::before { background-image: url('../img/navigation/nav-2.jpg'); }
.brikk-header__menu .brikk-navigation-image-3 > a::before { background-image: url('../img/navigation/nav-3.jpg'); }
.brikk-header__menu .brikk-navigation-image-4 > a::before { background-image: url('../img/navigation/nav-4.jpg'); }
.brikk-header__menu .brikk-navigation-image-5 > a::before { background-image: url('../img/navigation/nav-5.jpg'); }
.brikk-header__menu .brikk-navigation-image-6 > a::before { background-image: url('../img/navigation/nav-6.jpg'); }
.brikk-header__menu .brikk-navigation-image-7 > a::before { background-image: url('../img/navigation/nav-7.png'); }
.brikk-header__menu .brikk-navigation-image-8 > a::before { background-image: url('../img/navigation/nav-8.jpg'); }
.brikk-header__menu .brikk-navigation-image-9 > a::before { background-image: url('../img/navigation/nav-9.jpg'); }
.brikk-header__menu .brikk-navigation-image-10 > a::before { background-image: url('../img/navigation/nav-10.jpg'); }
.brikk-header__menu .brikk-navigation-image-11 > a::before { background-image: url('../img/navigation/nav-11.png'); }
.brikk-header__menu .brikk-navigation-image-12 > a::before { background-image: url('../img/navigation/nav-12.png'); }
.brikk-header__menu .brikk-navigation-image-13 > a::before { background-image: url('../img/navigation/nav-13.jpg'); }
.brikk-header__menu .brikk-navigation-image-14 > a::before { background-image: url('../img/navigation/nav-14.jpg'); }
.brikk-header__menu .brikk-navigation-image-15 > a::before { background-image: url('../img/navigation/nav-15.jpg'); }
.brikk-header__menu .brikk-navigation-image-16 > a::before { background-image: url('../img/navigation/nav-16.jpeg'); }
.brikk-header__menu .brikk-navigation-image-17 > a::before { background-image: url('../img/navigation/nav-17.jpg'); }
.brikk-header__menu .brikk-navigation-image-18 > a::before { background-image: url('../img/navigation/nav-18.jpg'); }
.brikk-header__menu .brikk-navigation-image-19 > a::before { background-image: url('../img/navigation/nav-19.jpg'); }
.brikk-header__menu .brikk-navigation-image-20 > a::before { background-image: url('../img/navigation/nav-20.jpg'); }
.brikk-header__menu .brikk-navigation-image-21 > a::before { background-image: url('../img/navigation/nav-21.jpg'); }
.brikk-header__menu .brikk-navigation-image-22 > a::before { background-image: url('../img/navigation/nav-22.jpg'); }
.brikk-header__menu .brikk-navigation-image-23 > a::before { background-image: url('../img/navigation/nav-23.jpg'); }
/* nav-24: the SHIPPED brikk.css was hand-patched after compile to point at an
   uploads image (nav-24-brikki.jpg) — the scss still says nav-24.jpg. The
   patched image is copied into the theme so the reference stays relative. */
.brikk-header__menu .brikk-navigation-image-24 > a::before { background-image: url('../img/navigation/nav-24-brikki.jpg'); }

/* --- CTA ------------------------------------------------------------------ */

.brikk-header__cta {
    display: inline-block;
    padding: 17px 25px 16px;
    background: var(--wp--preset--color--purple);
    border-radius: var(--wp--custom--radius);
    color: var(--wp--custom--on-accent);
    font-size: 12px;
    font-weight: 500;
    letter-spacing: var(--wp--custom--ls-ui);
    line-height: 1.3;
    text-transform: uppercase;
    text-decoration: none;
    text-align: center;
    transition: background-color var(--wp--custom--transition);
}

.brikk-header__cta:hover {
    background: var(--wp--custom--purple-hover);
    color: var(--wp--custom--on-accent);
}

/* Long label by default; the short label takes over in the 1081-1170 band
   (the A/B nav-CTA breakpoint) before the whole CTA hides ≤1080. That band is
   what buys the extra 56px of menu room — the collapse breakpoint below was
   measured WITH the short label already in play. */
.brikk-header__cta-short {
    display: none;
}

@media (max-width: 1170px) {
    .brikk-header__cta-long {
        display: none;
    }

    .brikk-header__cta-short {
        display: inline;
    }
}

/* --- burger + collapsed bar ≤1080 ----------------------------------------- */

.brikk-header__burger {
    display: none;
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
}

/* 🔴 1080, NOT the design system's 1024 (changed 2026-07-30, Andreas: "when the
   browser window on a desktop goes below 1080px the navigation starts breaking
   because there isn't enough space"). This is the ONE header-only breakpoint.

   MEASURED, not chosen (headless Chrome, redesigned page, production menu
   replica, desktop nav force-shown at every width):

       logo 110  +  menu 629.4  +  short CTA 192.1  +  2×65px gutters
       = 1061.5px of LAYOUT viewport needed

   At 1065px the bar is still one 93px line. At 1060px a top-level label wraps
   inside its skewed parallelogram and the bar grows to 115px — a 22px jump, with
   the menu visibly colliding with the CTA. So the real cliff is ~1062px, and
   1080 sits just above it: the ~18px of headroom is what covers a classic 15px
   scrollbar, which is why Andreas sees it break at a 1080px WINDOW while the
   layout viewport is only ~1065px.

   ⚠️ Do not "tidy" this to 1024. Between 1024 and 1000 the bar would fit again
   (the gutter drops to 32px there and hands back 66px), so the fit-vs-width
   curve is NON-MONOTONIC — collapsing at 1024 leaves the whole 1025-1060 band
   broken while a naive check at 1010px looks fine.

   ⚠️ Whoever edits the header menu OWNS this number. One more top-level item, a
   longer label, or a wider CTA moves the cliff — re-measure the bar's
   scrollWidth/clientWidth and the max vs min height of
   `.brikk-header__menu > li > a` rather than assuming 1080 still holds.

   NOT paired with the sticky block above — that stays at 1025 on purpose; see its
   comment. Nothing else in the file uses 1080, and the page gutter ladder
   deliberately stays on 1024 (see the note above --brikk-header-pad). The `.98`
   keeps a fractional zoom width from falling into a gap. */
@media (max-width: 1080.98px) {
    .brikk-header__inner {
        min-height: 84px;
    }

    .brikk-header__nav,
    .brikk-header__cta {
        display: none;
    }

    .brikk-header__burger {
        display: block;
    }

    .brikk-header__burger span {
        display: block;
        width: 30px;
        height: 2px;
        margin: 7px 0;
        background: var(--wp--preset--color--dark);
    }
}


/* -----------------------------------------------------------------------------
   12.2  MOBILE DRAWER  ·  .brikk-drawer
   -----------------------------------------------------------------------------
   Replaces the legacy offcanvas. ⚠️ No comp exists for a new-design mobile
   menu (DESIGN.md §12.5) — this is composed from the design language (canvas
   surface, cool hairlines, tracked uppercase, purple CTA). Revisit with a
   real design if one arrives. Opened/closed by assets/js/offcanvas.js.
   -------------------------------------------------------------------------- */

.brikk-drawer {
    /* Slides in from the LEFT — same side as the legacy offcanvas (Andreas,
       2026-07-23). */
    position: fixed;
    top: 0;
    left: 0;
    width: min(360px, 86vw);
    height: 100vh;
    height: 100dvh;
    display: flex;
    flex-direction: column;
    padding: 20px 24px 24px;
    overflow-y: auto;
    background: var(--wp--preset--color--bg);
    font-family: var(--wp--preset--font-family--sans);
    z-index: var(--wp--custom--z-modal);
    transform: translateX(-100%);
    visibility: hidden;
    transition: transform 240ms ease, visibility 0s 240ms;
}

.brikk-drawer.is-open {
    transform: translateX(0);
    visibility: visible;
    transition: transform 240ms ease;
}

.brikk-drawer__top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: 44px;
    margin-bottom: 16px;
}

.brikk-drawer__logo {
    display: block;
    line-height: 0;
}

.brikk-drawer__logo img {
    display: block;
    width: auto;
    height: 30px;
}

.brikk-drawer__close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 10px;
    margin-right: -10px;
    background: none;
    border: 0;
    cursor: pointer;
    color: var(--wp--preset--color--dark);
    appearance: none;
    -webkit-appearance: none;
}

/* Explicit for the same reason as the two chevrons — see the note at
   .brikk-header__menu .brikk-menu-toggle svg. Verified a no-op (18×18). */
.brikk-drawer__close svg {
    width: 18px;
    height: 18px;
    max-width: none;
}

.brikk-drawer__nav ul {
    list-style: none;
    margin: 0;
    padding: 0;
}

.brikk-drawer__menu > li {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    border-bottom: 1px solid var(--wp--custom--line-cool);
}

.brikk-drawer__menu a {
    flex: 1;
    display: block;
    padding: 16px 0;
    font-size: 13px;
    font-weight: 400;
    letter-spacing: var(--wp--custom--ls-nav);
    text-transform: uppercase;
    text-decoration: none;
    color: var(--wp--preset--color--dark);
}

.brikk-drawer__menu .brikk-menu-toggle {
    display: inline-flex;
    align-items: center;
    padding: 16px 4px 16px 16px;
    color: var(--wp--preset--color--dark);
    cursor: pointer;
}

/* Sized explicitly for the same reason as the header chevron above. Here the
   parent is an auto-sized inline-flex box, so the reset's `max-width: 100%`
   happens to resolve to the icon's own width and nothing breaks — but "happens
   to" is not a contract. Verified a no-op (10×7 before and after). */
.brikk-drawer__menu .brikk-menu-toggle svg {
    width: 10px;
    height: 7px;
    max-width: none;
    transition: transform var(--wp--custom--transition);
}

.brikk-drawer__menu li.is-sub-open > .brikk-menu-toggle svg {
    transform: rotate(180deg);
}

.brikk-drawer__menu .sub-menu {
    display: none;
    width: 100%;
    padding: 0 0 12px;
}

.brikk-drawer__menu li.is-sub-open > .sub-menu {
    display: block;
}

.brikk-drawer__menu .sub-menu li {
    border: 0;
}

/* Trustpilot menu items never render in the mobile menu (legacy offcanvas
   hid them the same way — the TrustBox widget has no place in a drawer). */
.brikk-drawer__menu .brikk-navigation-trustpilot {
    display: none;
}

.brikk-drawer__menu .sub-menu a {
    padding: 8px 0 8px 14px;
    font-size: 12px;
    color: var(--wp--preset--color--muted);
}

.brikk-drawer__cta {
    display: block;
    margin-top: auto;
    padding: 17px 25px 16px;
    background: var(--wp--preset--color--purple);
    border-radius: var(--wp--custom--radius);
    color: var(--wp--custom--on-accent);
    font-size: 12px;
    font-weight: 500;
    letter-spacing: var(--wp--custom--ls-ui);
    line-height: 1.3;
    text-align: center;
    text-transform: uppercase;
    text-decoration: none;
    transition: background-color var(--wp--custom--transition);
}

.brikk-drawer__cta:hover {
    background: var(--wp--custom--purple-hover);
    color: var(--wp--custom--on-accent);
}

.brikk-drawer-overlay {
    position: fixed;
    inset: 0;
    background: var(--wp--custom--scrim);
    opacity: 0;
    pointer-events: none;
    transition: opacity 240ms ease;
    z-index: calc(var(--wp--custom--z-modal) - 1);
}

.brikk-drawer-overlay.is-on {
    opacity: 1;
    pointer-events: auto;
}


/* -----------------------------------------------------------------------------
   12.2b  SITE FOOTER  ·  .brikk-sitefooter
   -----------------------------------------------------------------------------
   Markup: themes/brikk/footer.php (2026 chrome). Renders on EVERY page, so it
   is fully self-contained: box model, fonts, list/link/heading resets are all
   explicit and nothing is inherited from brikk.css or from §3/§4 (which are
   scoped to html.brikk-redesign and therefore absent on legacy pages).

   Design target: the footer as it renders on the A/B templates — measured 1:1
   from https://www.brikk.dk/ (an A/B landing page) on 2026-07-29. That footer
   is legacy geometry (brikk.css `_footer.scss`) plus a thin typography/colour
   skin from landing.css:191-238; the columns, bottom bar and badge row are
   unchanged legacy. Values here reproduce the measured computed styles.

   ⚠️ landing.css ALSO contains a fully-designed BEM footer
   (`.brikk-ab-page .brikk-footer__grid/__brand/__bottom`, lines 2664-2727)
   that has NEVER rendered: all three A/B templates close `.brikk-ab-page`
   before get_footer(), so the theme footer is a sibling, never a descendant.
   It is an unbuilt comp, not the shipped design — do not mistake it for what
   the A/B footer looks like. (Its ideas that were adopted here: muted link
   colour and the link hover.)

   Four DELIBERATE fixes vs what production renders today (each one line, each
   reverting cleanly if 1:1 bug-parity is wanted):
     1. Legal links use --purple. Live renders them #1B03BA electric blue,
        from an un-minified hand patch appended to the very end of brikk.css
        (`.brikk-footer-bottom-section a`) that the A/B skin never recolours.
     2. Widget links use a flat --muted. Live stacks `opacity:.82` three times
        (the A/B applies it to .textwidget, its li AND its a — nested, so it
        composites to .82³ ≈ .55), rendering ~#7C7B79 while the rule claims
        #1A1A1A. --muted (#6b6b6b) is the design system's equivalent.
     3. The gutter steps 65/32/24/20 like the header. Live freezes it at 65px
        at every viewport (`.brikk-ab-template .brikk-container` overrides the
        legacy responsive gutters with !important and has no steps of its
        own), which on a 390px phone leaves 260px of content and makes the
        330px badge row overflow its column.
     4. The logo is the new lockup (logo-new.png) at the A/B's intended 20px
        height. The A/B authored that swap
        (`.brikk-footer-column>img { content:url(logo-new.png); height:20px }`)
        but its OWN output filter `brikk_ab_rewrite_logos()` wraps the img in
        an <a>, breaking the child combinator — so live still shows the legacy
        black SVG at 30px and the swap has never been seen. footer.php now
        wraps the logo itself, so that filter no-ops (its regex needs
        width="87" height="18" alt="BRIKK Logo").
   Reflow breakpoints are the design system's (1024/768/640) rather than the
   legacy footer's own (991/800/700/550) — the header collapses at 1024, and a
   footer still in desktop layout at 1010px reads as a bug.
   -------------------------------------------------------------------------- */

.brikk-sitefooter,
.brikk-sitefooter *,
.brikk-sitefooter *::before,
.brikk-sitefooter *::after {
    box-sizing: border-box;
}

.brikk-sitefooter {
    /* Own gutter variable, NOT --brikk-pad-x — chrome must stay immune to
       page-level token tampering. Same reasoning as --brikk-header-pad. */
    --brikk-footer-pad: 65px;
    background: var(--wp--preset--color--bg);
    color: var(--wp--preset--color--dark);
    font-family: var(--wp--preset--font-family--sans);
    font-size: 13px;
    /* ⚠️ An ABSOLUTE 22.5px, not a ratio. Production's footer inherits the
       legacy `body { line-height: 150% }`, which computes to 22.5px on the
       15px body and then inherits as that fixed value — so every footer
       element gets 22.5px of leading REGARDLESS of its own font-size. That is
       why the 11px column headings are 28px tall (22.5 + 5px padding) and why
       the 12px legal line is not cramped. Only the two elements that carry
       their own line-height in the A/B skin override it below (p → 1.6,
       li → 1.45). A ratio here silently shrinks the leading of everything
       else and the whole footer collapses ~6px per column. */
    line-height: 22.5px;
    padding: 60px 0 40px;
    margin: 0;
}

@media (max-width: 1024.98px) {
    .brikk-sitefooter {
        --brikk-footer-pad: 32px;
        padding: 40px 0;
    }
}

@media (max-width: 768px) {
    .brikk-sitefooter { --brikk-footer-pad: 24px; }
}

@media (max-width: 640px) {
    .brikk-sitefooter { --brikk-footer-pad: 20px; }
}

.brikk-sitefooter__inner {
    width: 100%;
    max-width: var(--wp--custom--max);
    margin-inline: auto;
    padding-inline: var(--brikk-footer-pad);
}

/* --- columns -------------------------------------------------------------- */

.brikk-sitefooter__cols {
    display: flex;
    justify-content: space-between;
}

.brikk-sitefooter__col {
    width: 100%;
    max-width: 23%;
}

@media (max-width: 1024.98px) {
    .brikk-sitefooter__cols { flex-wrap: wrap; }

    .brikk-sitefooter__col { max-width: 33%; }

    /* The brand column takes its own full-width row above the link columns. */
    .brikk-sitefooter__col--brand {
        max-width: 100%;
        margin-bottom: 40px;
    }
}

@media (max-width: 768px) {
    .brikk-sitefooter__col,
    .brikk-sitefooter__col--brand {
        max-width: 48%;
        margin-bottom: 30px;
    }
}

@media (max-width: 640px) {
    .brikk-sitefooter__col,
    .brikk-sitefooter__col--brand {
        max-width: 100%;
    }
}

/* --- brand column: logo, blurb, social ------------------------------------ */

/* -6px top / 10px bottom = production's own logo margins. The negative top
   pulls the wordmark up to optically align with the first link column's
   heading; without it the whole brand column sits ~6px low. */
.brikk-sitefooter__logo {
    display: inline-block;
    margin: -6px 0 10px;
    line-height: 0;
    text-decoration: none;
}

/* ⚠️ THINK IN CAP-HEIGHT, NOT BOX HEIGHT — and keep this rule and footer.php's
   asset together. The footer uses logo-new.png, the header's lockup, whose
   wordmark is only 46.5% of its box (the old logo-black.svg's was 65.5%), so the
   two assets are NOT interchangeable at the same height: at the footer's old
   `height: 30px` this lockup would render a 14px wordmark where the footer had
   always shown 20px.
   36px → 118.4px wide, a 16.7px wordmark. That is deliberately just above the
   header's 15.5px (110px wide), so the footer reads as the same chrome rather
   than as a second, bigger logo. Andreas asked for "a bit smaller" than the
   cap-height-matched 43px on 2026-07-30. */
.brikk-sitefooter__logo img {
    display: block;
    width: auto;
    height: 36px;
    max-width: none;
}

@media (max-width: 1024.98px) {
    .brikk-sitefooter__logo { margin: 0 0 20px; }
}

.brikk-sitefooter__social a {
    display: inline-block;
    text-decoration: none;
}

.brikk-sitefooter__social img {
    display: block;
    width: 23px;
    height: auto;
    margin: 15px 10px 0 0;
}

/* --- widgets -------------------------------------------------------------- */

/* The wrapper + title classes are emitted by register_sidebar() in
   functions.php, not by footer.php. They are kept at their legacy names on
   purpose: brikk.css defines NO rules for either (verified — 0 occurrences),
   so there is nothing to collide with, and the widget markup stays untouched
   if the footer is ever rolled back. */
.brikk-sitefooter .brikk-footer-widget-content {
    margin: 0;
}

.brikk-sitefooter .brikk-footer-widget-title {
    font-family: var(--wp--preset--font-family--sans);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: .24em;
    /* 🔴 STATED, NOT INHERITED. This relied on inheriting the footer's absolute
       22.5px — and on a LEGACY page it does. But the widget title is an <h3>
       (register_sidebar's `before_title`), and §4's base heading rule sets
       `line-height: lh-tight` on every h1-h6. That rule is scoped
       `:where(.brikk-redesign)` — a class header.php emits ONLY on redesigned
       pages — so THERE it intercepted the heading and gave it 11.55px instead of
       22.5px: each heading 17px instead of 28px, each column 11px short, the
       whole footer 33px shorter than designed. Invisible while only the funnel
       was redesigned; it would have hit the entire site at cutover, when every
       page carries .brikk-redesign. */
    line-height: 22.5px;
    text-transform: uppercase;
    color: var(--wp--preset--color--purple);
    margin: 4px 0 20px;
    padding: 0 0 5px;
}

/* 14px/1.6, NOT the 13px/1.45 of the link lists: the A/B's `!important` skin
   targets `.textwidget`, `.textwidget li` and `.textwidget a` — a <p> INSIDE
   .textwidget matches none of them, so it keeps the legacy
   `.brikk-footer-column p { font-size:14px; line-height:160% }` and renders
   larger than the lists. Measured on production: 14px / 22.4px.
   Colour likewise: the paragraph picks up .textwidget's opacity ONCE (.82,
   ≈#414140) where a link compounds it three times, so the blurb reads as body
   copy, not as a muted link. --dark is its flat equivalent. */
.brikk-sitefooter p {
    font-size: 14px;
    line-height: 1.6;
    color: var(--wp--preset--color--dark);
    margin: 0;
}

/* Keeps the brand blurb off the next column, per the A/B's own late patch
   (`section#text-2 p { padding-right: 12% }`) — expressed structurally here
   rather than by production widget id. */
.brikk-sitefooter__col--brand p {
    padding-right: 12%;
}

@media (max-width: 1024.98px) {
    .brikk-sitefooter__col--brand p {
        padding-right: 0;
        max-width: 60ch;
    }
}

.brikk-sitefooter ul {
    list-style: none;
    margin: 0;
    padding: 0;
}

.brikk-sitefooter li {
    font-size: 13px;
    line-height: 1.45;
    color: var(--wp--preset--color--muted);
    margin: 10px 0;
}

.brikk-sitefooter a {
    color: var(--wp--preset--color--muted);
    text-decoration: none;
    transition: color var(--wp--custom--transition);
}

.brikk-sitefooter li a {
    font-size: 13px;
    font-weight: 400;
}

.brikk-sitefooter li a:hover {
    color: var(--wp--preset--color--purple);
}

/* --- bottom bar ----------------------------------------------------------- */

.brikk-sitefooter__bottom {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin: 50px 0 0;
    padding: 20px 0 0;
    border-top: 2px solid var(--wp--custom--line-soft);
}

/* line-height inherits the footer's 22.5px — the legal line must not be
   cramped by its 12px size, and it wraps to 2-3 lines on mobile. */
.brikk-sitefooter__legal {
    font-size: 12px;
    font-weight: 400;
    letter-spacing: .14em;
    color: var(--wp--preset--color--muted);
    margin-right: 20px;
}

.brikk-sitefooter__legal a {
    color: var(--wp--preset--color--purple);
    text-decoration: none;
}

.brikk-sitefooter__legal a:hover {
    color: var(--wp--custom--purple-hover);
    text-decoration: underline;
}

/* 🔴 `min-width: 0` IS THE BUG FIX, not a tidy-up (2026-07-30, Andreas). The row's
   content is a rigid 330px — an 80px logo + its 20px margin + the TrustBox slot,
   whose 230px layout width is unaffected by the `scale(.6)` that shrinks it
   visually. As a flex item the row's automatic minimum size (`min-width: auto`)
   IS that 330px min-content, so it refused to shrink inside a narrower column and
   pushed `body.scrollWidth` past the viewport for every width **≤329px**.

   ⚠️ AND IT DID SO ON SOME PAGE TYPES ONLY, which is the §0.1 trap again: measured
   at 320px, the row was 330px wide on legacy-CSS and A/B pages but 280px on
   redesigned ones. Shared chrome rendering two different ways is the defect,
   whatever the mechanism — and it is NOT `body { overflow-x: hidden }` from §3
   (tested in isolation: the row stays 330px and still overflows).

   With `min-width: 0` all three page types are identical and none overflows:
   330px down to 390, then shrinking with its column (320 → 280, TrustBox slot 180,
   which still comfortably contains the 138px scaled widget). Nothing changes at or
   above 390px, so the desktop and normal-phone footer are untouched.
   ⚠️ Do NOT "fix" this with `flex-wrap: wrap` instead — that also stops the
   overflow, but it stacks the two badges and grows the row from 88px to 129px at
   ≤360px. Measured; the shrink is the smaller change. */
.brikk-sitefooter__badges {
    display: flex;
    justify-content: space-between;
    align-items: center;
    min-width: 0;
}

.brikk-sitefooter__badges img {
    display: block;
    width: 80px;
    height: 40px;
    margin: 1px 20px 0 0;
}

/* The TrustBox renders as a fixed-size iframe; the wrapper scales it down and
   clips the result. Drawn by the Trustpilot bootstrap script hardcoded in
   footer.php (blocked locally by brikk-local-dev — the slot stays empty on
   brikk.local, so verify this block against production, not a local shot). */
.brikk-sitefooter__tp {
    width: 230px;
    height: 88px;
    overflow: hidden;
    transform: scale(.6);
}

@media (max-width: 768px) {
    .brikk-sitefooter__bottom {
        flex-wrap: wrap;
        justify-content: center;
        text-align: center;
        margin: 25px 0 0;
    }

    .brikk-sitefooter__legal {
        width: 100%;
        margin: 0 0 20px;
    }
}


/* -----------------------------------------------------------------------------
   12.3a  AGENT SEARCH  ·  .brikk-broker
   -----------------------------------------------------------------------------
   Postcode → mægler lookup. Rendered by the [brikk-agent-search] shortcode in
   the brikk-tracking plugin; driven by assets/js/agents/agent-search.js, which
   swaps the portrait, name, role, quote and stat columns in place.

   Ported from brikk-design-ab-test/assets/css/landing.css (the .brikk-ab-page
   scope and the shared multi-section selectors are dropped; section rhythm now
   comes from --brikk-section-y, which already steps 96 → 72 → 56).

   The .brikk-broker* class vocabulary is kept deliberately — it is what both
   the JS and the ported design CSS key off. Rename only if both move together.
   -------------------------------------------------------------------------- */

.brikk-broker {
    background: var(--wp--preset--color--bg);
    color: var(--wp--preset--color--dark);
    padding: var(--brikk-section-y) 0;
}

/* --- head: eyebrow + heading + intro + the postcode form ------------------ */

.brikk-broker__head {
    text-align: center;
    max-width: 720px;
    margin: 0 auto 72px;
}

.brikk-broker--noheader .brikk-broker__head {
    display: none;
}

.brikk-broker__head .brikk-eyebrow {
    display: block;
    margin-bottom: 18px;
}

.brikk-broker__heading {
    font-family: var(--wp--preset--font-family--serif);
    font-size: calc(clamp(30px, 3.4vw, 46px) * var(--brikk-heading-scale, 1));
    font-weight: 500;
    line-height: 1.1;
    letter-spacing: .005em;
    text-wrap: balance;
    margin: 0 0 18px;
}

.brikk-broker__intro {
    color: var(--wp--preset--color--muted);
    font-size: var(--wp--preset--font-size--body);
    line-height: 1.7;
    opacity: .85;
    margin: 0 auto 34px;
    max-width: 560px;
}

.brikk-broker__search {
    display: flex;
    align-items: stretch;
    max-width: 440px;
    margin: 0 auto;
    background: var(--wp--preset--color--card);
    border: var(--wp--custom--border);
    padding: 6px;
}

/* The label is present for screen readers only — the placeholder carries the
   visible affordance. Mirrors .screen-reader-text (§9) without coupling to it. */
.brikk-broker__search-label {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Scoped through .brikk-broker__search on purpose: §7 styles input[type='text']
   at specificity (0,1,1), which would otherwise beat a bare class (0,1,0) and
   put a border + 15px type back on this field. The wrapper carries the border. */
.brikk-broker__search .brikk-broker__search-input {
    flex: 1;
    width: auto;
    min-width: 0;
    padding: 14px 18px;
    font-family: var(--wp--custom--font-input);
    font-size: 14px;
    color: var(--wp--preset--color--dark);
    background: transparent;
    border: 0;
    outline: 0;
}

.brikk-broker__search .brikk-broker__search-input::placeholder {
    color: var(--wp--preset--color--muted);
    opacity: .7;
}

.brikk-broker__search-btn {
    background: var(--wp--preset--color--purple);
    color: var(--wp--custom--on-accent);
    border: 0;
    padding: 0 28px;
    font-size: var(--wp--preset--font-size--ui-sm);
    letter-spacing: .24em;
    text-transform: uppercase;
    font-weight: 500;
    cursor: pointer;
    transition: background var(--wp--custom--transition);
}

.brikk-broker__search-btn:hover {
    background: var(--wp--custom--purple-hover);
}

.brikk-broker__search.is-loading .brikk-broker__search-btn {
    opacity: .6;
    cursor: progress;
}

.brikk-broker__search-msg {
    margin: 14px 0 0;
    font-size: var(--wp--preset--font-size--ui-sm);
    color: var(--wp--preset--color--muted);
    letter-spacing: .02em;
}

/* --- the card: portrait + copy -------------------------------------------- */

.brikk-broker__inner {
    display: grid;
    grid-template-columns: 40fr 60fr;
    gap: 64px;
    align-items: center;
}

.brikk-broker__media {
    position: relative;
    aspect-ratio: 5/6;
    overflow: hidden;
    /* Visible only while the portrait loads or if it 404s. */
    background: var(--wp--custom--line-dark);
}

.brikk-broker__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: top center;
}

/* Inset hairline frame over the portrait. Lighter than --wp--custom--on-dark-line
   because it sits on a photo, not a flat dark surface. */
.brikk-broker__media::after {
    content: "";
    position: absolute;
    inset: 14px;
    border: 1px solid rgba(255, 255, 255, .55);
    pointer-events: none;
}

.brikk-broker__credit {
    position: absolute;
    left: 28px;
    bottom: 24px;
    z-index: var(--wp--custom--z-raised);
    font-family: var(--wp--preset--font-family--serif);
    font-style: italic;
    font-size: 18px;
    color: rgba(245, 242, 238, .92);   /* --wp--preset--color--bg over the photo */
    letter-spacing: .01em;
    text-shadow: 0 1px 6px rgba(0, 0, 0, .5);
}

.brikk-broker__copy .brikk-eyebrow {
    display: block;
    font-family: var(--wp--preset--font-family--sans);
    text-transform: uppercase;
    color: var(--wp--preset--color--muted);
    font-size: var(--wp--preset--font-size--eyebrow);
    letter-spacing: var(--wp--custom--ls-eyebrow);
    font-weight: 500;
    margin-bottom: 22px;
}

.brikk-broker__copy .brikk-eyebrow::after {
    content: "";
    display: block;
    width: 30px;
    height: 2px;
    background: var(--wp--preset--color--line);
    margin-top: 14px;
}

.brikk-broker__lead {
    color: var(--wp--preset--color--muted);
    font-size: var(--wp--preset--font-size--body);
    line-height: 1.7;
    opacity: .8;
    margin: 0 0 14px;
    max-width: 600px;
}

/* --- stat columns (overridable per mægler via _brikk_agent_stats) --------- */

.brikk-broker__stats {
    display: grid;
    grid-template-columns: repeat(3, auto);
    gap: var(--wp--preset--spacing--7);
    margin: 36px 0 28px;
    padding-top: var(--wp--preset--spacing--6);
    border-top: var(--wp--custom--border);
}

.brikk-broker__stat-value {
    font-family: var(--wp--preset--font-family--serif);
    font-size: 40px;
    font-weight: 500;
    line-height: 1;
    margin-bottom: 10px;
}

.brikk-broker__stat-label {
    font-size: var(--wp--preset--font-size--micro);
    letter-spacing: .24em;
    text-transform: uppercase;
    color: var(--wp--preset--color--muted);
}

.brikk-broker__name {
    font-family: var(--wp--preset--font-family--serif);
    font-style: italic;
    font-size: 24px;
    font-weight: 500;
    line-height: 1.2;
    margin: 60px 0 6px;
}

.brikk-broker__role {
    font-size: var(--wp--preset--font-size--micro);
    letter-spacing: .24em;
    text-transform: uppercase;
    color: var(--wp--preset--color--muted);
}

/* --- responsive ----------------------------------------------------------- */

@media (max-width: 1024px) {
    .brikk-broker__inner {
        grid-template-columns: 1fr;
        gap: var(--wp--preset--spacing--7);
    }

    .brikk-broker__head {
        margin-bottom: 56px;
    }

    .brikk-broker__media {
        aspect-ratio: 4/3;
        max-width: var(--wp--custom--measure);
        margin: 0 auto;
    }

    .brikk-broker__copy {
        max-width: var(--wp--custom--measure);
        margin: 0 auto;
        width: 100%;
    }

    /* Without the head the section fills the container like its neighbours,
       instead of the centred reading column the full version stacks into. */
    .brikk-broker--noheader .brikk-broker__media,
    .brikk-broker--noheader .brikk-broker__copy {
        max-width: none;
        margin: 0;
    }

    .brikk-broker__stats {
        gap: var(--wp--preset--spacing--6);
        margin: var(--wp--preset--spacing--6) 0 var(--wp--preset--spacing--5);
        padding-top: 28px;
    }

    .brikk-broker__stat-value {
        font-size: 34px;
    }

    .brikk-broker__name {
        margin-top: 44px;
    }
}

@media (max-width: 768px) {
    .brikk-broker__heading {
        font-size: calc(clamp(28px, 5.2vw, 38px) * var(--brikk-heading-scale, 1));
    }
}

@media (max-width: 640px) {
    /* ⚠️ This section's eyebrow needs its OWN ≤640 step. The §6 primitive steps
       `.brikk-eyebrow` down to 10.5px/.28em here, but that rule is (0,1,0) while
       `.brikk-broker__copy .brikk-eyebrow` above is (0,2,0) — so the component
       rule won at every width and the eyebrow stayed 11.5px, wrapping to three
       lines where the design takes two (+17px on the section at 360px).
       landing.css hits the same problem and solves it the same way, listing this
       selector explicitly alongside the hero's in its ≤640 block. */
    .brikk-broker__copy .brikk-eyebrow {
        font-size: var(--wp--preset--font-size--micro);
        letter-spacing: .28em;
    }

    .brikk-broker__head {
        margin-bottom: 40px;
    }

    .brikk-broker__heading {
        font-size: calc(clamp(26px, 7vw, 36px) * var(--brikk-heading-scale, 1));
    }

    .brikk-broker__intro {
        font-size: 14.5px;
        line-height: 1.65;
    }

    .brikk-broker__search {
        max-width: 380px;
    }

    .brikk-broker__search .brikk-broker__search-input {
        padding: 12px 14px;
        /* 16px, not the design's 14px: under 16px iOS Safari zooms the page on
           focus and leaves it zoomed. Same guard §7 applies to every field. */
        font-size: var(--wp--preset--font-size--body);
    }

    .brikk-broker__search-btn {
        padding: 0 18px;
        font-size: 11px;
        letter-spacing: var(--wp--custom--ls-ui);
    }

    .brikk-broker__inner {
        gap: var(--wp--preset--spacing--6);
    }

    .brikk-broker__media {
        aspect-ratio: 4/3;
        max-width: 100%;
    }

    .brikk-broker__credit {
        font-size: 15px;
        left: 18px;
        bottom: var(--wp--preset--spacing--4);
    }

    .brikk-broker__lead {
        font-size: 14.5px;
        line-height: 1.65;
    }

    /* Name and role lead the stacked card, ahead of the quote. */
    .brikk-broker__copy {
        display: flex;
        flex-direction: column;
    }

    .brikk-broker__name {
        order: 1;
        font-size: 20px;
        margin: 0 0 6px;
    }

    .brikk-broker__role {
        order: 2;
        font-size: 9.5px;
        letter-spacing: var(--wp--custom--ls-ui);
        margin-bottom: var(--wp--preset--spacing--5);
    }

    .brikk-broker__lead {
        order: 3;
    }

    .brikk-broker__stats {
        order: 4;
        gap: var(--wp--preset--spacing--3);
        padding-top: var(--wp--preset--spacing--5);
        margin: var(--wp--preset--spacing--5) 0 var(--wp--preset--spacing--4);
        grid-template-columns: repeat(3, 1fr);
    }

    .brikk-broker__stat-value {
        font-size: 26px;
        margin-bottom: 6px;
    }

    .brikk-broker__stat-label {
        font-size: 9px;
        letter-spacing: .16em;
        line-height: 1.3;
    }
}

@media (max-width: 420px) {
    .brikk-broker__stats {
        gap: var(--wp--preset--spacing--2);
    }

    .brikk-broker__stat-value {
        font-size: 22px;
    }

    .brikk-broker__stat-label {
        font-size: 8.5px;
        letter-spacing: .14em;
    }
}


/* -----------------------------------------------------------------------------
   12.3b  TRUSTPILOT RATING BADGE  ·  .brikk-tp
   -----------------------------------------------------------------------------
   Markup: [brikk-trustpilot-rating] (inc/shortcodes/shortcode-trustpilot-rating.php).
   The design's own score+stars+wordmark lockup, NOT the external TrustBox —
   that widget is a fixed-width iframe that wrecks small screens.

   Ported from landing.css:764-820 + its ≤360 overflow guard.

   ⚠️ The A/B recolours this to white inside an UNSCOPED `@media (max-width:640px)`
   block, because on the landing page the badge only ever sits in the hero, which
   turns into a dark image at ≤640. As a reusable shortcode that assumption no
   longer holds, so the light-on-dark treatment is an explicit modifier:
   `--on-dark` for a surface that is always dark, `--on-dark-mobile` for one that
   inverts at ≤640 (the front-page hero). A surface that needs either and asks
   for neither renders dark-on-dark.
   -------------------------------------------------------------------------- */

.brikk-tp {
    display: inline-flex;
    flex-direction: row;
    align-items: center;
    gap: 12px;
    text-decoration: none;
}

.brikk-tp__score {
    font-size: 14px;
    font-weight: 500;
    letter-spacing: -0.01em;
    color: var(--wp--preset--color--dark);
    white-space: nowrap;
}

/* Review count stacked over the stars. */
.brikk-tp__mid {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 3px;
    line-height: 1.1;
}

/* 1.4, not the .brikk-tp__mid 1.1 it would otherwise inherit: the A/B's reset
   forces 1.4 on every element, so 1.1 never reached this span and the badge
   ships 3.6px taller than landing.css reads. Matched to what renders. */
.brikk-tp__count {
    font-size: 12px;
    font-weight: 500;
    line-height: var(--wp--custom--lh-base);
    color: var(--wp--preset--color--muted);
    white-space: nowrap;
}

.brikk-tp__count strong {
    font-weight: 700;
}

.brikk-tp__stars {
    display: block;
    height: 18.5px;
    width: auto;
    flex: none;
}

.brikk-tp__logo {
    display: block;
    height: 23px;
    width: auto;
    flex: none;
}

/* Both wordmarks are always in the DOM; only one is ever visible. */
.brikk-tp__logo--light {
    display: none;
}

.brikk-tp--on-dark .brikk-tp__score {
    color: var(--wp--custom--on-accent);
}

.brikk-tp--on-dark .brikk-tp__count {
    color: color-mix(in srgb, var(--wp--custom--on-accent) 60%, transparent);
}

.brikk-tp--on-dark .brikk-tp__logo--dark {
    display: none;
}

.brikk-tp--on-dark .brikk-tp__logo--light {
    display: block;
}

/* Surfaces that are light on desktop but invert to a dark photo at ≤640 — the
   front-page hero is the design's one example (DESIGN.md §7, strategy 1). A
   block pattern cannot add a class at a breakpoint, so the surface asks for the
   treatment once and it applies only where the surface is actually dark.
   Same four switches as --on-dark above; keep the two in sync. */
@media (max-width: 640px) {
    .brikk-tp--on-dark-mobile .brikk-tp__score {
        color: var(--wp--custom--on-accent);
    }

    .brikk-tp--on-dark-mobile .brikk-tp__count {
        color: color-mix(in srgb, var(--wp--custom--on-accent) 60%, transparent);
    }

    .brikk-tp--on-dark-mobile .brikk-tp__logo--dark {
        display: none;
    }

    .brikk-tp--on-dark-mobile .brikk-tp__logo--light {
        display: block;
    }
}

/* The badge is a fixed-width no-wrap row and overflowed around 345px. */
@media (max-width: 360px) {
    .brikk-tp {
        gap: 9px;
    }

    .brikk-tp__score {
        font-size: 12px;
    }

    .brikk-tp__count {
        font-size: 10.5px;
    }

    .brikk-tp__stars {
        height: 16px;
    }

    .brikk-tp__logo {
        height: 20px;
    }
}


/* -----------------------------------------------------------------------------
   12.3c  REVIEWS  ·  .brikk-trust / .brikk-review
   -----------------------------------------------------------------------------
   Markup: patterns/reviews.php — core blocks. Was the [brikk-reviews] shortcode
   until 2026-07-30, when Andreas moved the section into the block editor so every
   quote, name and label is editable content.

   Ported from landing.css:1022-1115 + the ≤1024/≤768/≤640 blocks.

   ⭐ MARKER-SCOPED (`.brikk-pattern`), unlike the shortcode-era version. That is
   not cosmetic: the live A/B templates use these exact class names, and
   brikk-design.css loads after landing.css on those pages, so an unmarked rule at
   (0,2,0) silently restyled them. This was the last documented source of bleed
   onto `/ab-landing-test/`, `/ab-agents-test/` and `/ejendomsmaeglersalaer/` (the
   `.brikk-trust` background re-declaration); it is gone now. See §6e's cascade
   rules — every §12.4-style rule naming a shared class needs the marker.

   `__inner` still carries the container geometry rather than reusing
   `.brikk-gutter` + the constrained layout: it is the same shape as
   patterns/results.php, and it keeps the gutter in one place. ⚠️ Do NOT also put
   `.brikk-gutter` on the outer group — that would double the gutter.

   ⚠️ Desktop padding is 80px, NOT --brikk-section-y (96px) — the A/B gives this
   section its own base rhythm. The ≤1024/≤640 steps do match the token.

   ⚠️ Block markup changed four things the selectors here have to account for:
     · the eyebrow, name and role are <p> now, not <span>/<div>, so §4 hands them
       1.6 leading unless they say otherwise — the name/role state
       `line-height: lh-base` for exactly that reason (CLAUDE.md §6e lesson 12);
     · `__head h2` / `__head p` became `__heading` / `__lead`, because in blocks
       the eyebrow is ALSO a <p> and a bare `p` selector would restyle it;
     · both images are core/image FIGURES now, so the figure and the <img> inside
       it are sized separately;
     · the size of each image is STATED, never left to its width/height
       attributes — §3's reset gives every img/svg `max-width: 100%; height: auto`
       on redesigned pages, which is what made the nav chevrons vanish (§6h).

   ⚠️ ONE KNOWN DELTA vs the A/B, and it is a TYPOGRAPHY consequence, not a layout
   bug. Block content goes through `wptexturize`, which turns the quotes' trailing
   `...` into a real ellipsis `…`. Shortcode output and the A/B's PHP templates
   never got texturized, so they render three periods. In Helvetica Neue the
   ellipsis is **14px wide against 11.69px for three periods** — 2.31px more. The
   4th quote's third line measures 290.4px in a 292px box on the A/B, i.e. 1.6px
   of slack, so those 2.31px push "anbefales…" onto a 4th line. In the 2-column
   band that makes the grid row (and the section) 22.4px taller than the A/B. It
   shows up at ONE of 23 measured widths (800px) — everywhere else the line has
   room. `…` is the correct character, so it stays. If exact parity in that band is
   ever wanted, shorten that one quote by a word or end it with a period (it is a
   complete sentence: "Brikk kan varmt anbefales."). Do NOT "fix" it in CSS.
   -------------------------------------------------------------------------- */

/* ⚠️ CORE'S DEFAULT BLOCK GAP — see the note at §12.4's steps block. Must stay
   ABOVE the component rules: `.brikk-review__meta` sets a 4px TOP margin, and at
   equal specificity source order is what lets it keep it. Without this, the
   grid's children get core's 24px `margin-block-start` ON TOP of the CSS `gap`. */
.brikk-pattern.brikk-trust > *,
.brikk-pattern .brikk-trust__inner > *,
.brikk-pattern .brikk-trust__grid > *,
.brikk-pattern .brikk-review > *,
.brikk-pattern .brikk-review__person > * {
    margin-block-start: 0;
}

.brikk-pattern.brikk-trust {
    padding: 80px 0;
}

.brikk-pattern .brikk-trust__inner {
    width: 100%;
    max-width: var(--wp--custom--max);
    margin-inline: auto;
    padding-inline: var(--brikk-pad-x);
}

.brikk-pattern .brikk-trust__head {
    max-width: 720px;
    margin: 0 auto 56px;
    text-align: center;
}

/* ⚠️ `min-height`, NOT `line-height` — and the reason is worth knowing, because it
   applies to every eyebrow that moves from hand-written markup into a pattern.
   `.brikk-eyebrow` is an INLINE-BLOCK (§6 primitive). In the A/B markup it is a
   <span>, so the line box holding it is `max(parent strut, its own height)`:
   22.4px when the label fits on one line (the body's 16px × 1.4 beats the
   eyebrow's own 11.5 × 1.4 = 16.1), and its own height once it wraps and grows
   past that. As a block <p> in a pattern it only ever occupies its own height —
   6.3px short on one line, exact once wrapped. A `min-height` of the body line
   box reproduces `max(strut, own)` at both, which is why it is expressed in
   tokens rather than as 22.4px.
   ⚠️ Do NOT move this onto the primitive: the front page's other section heads
   (steps, pricing, faq, results) were each measured Δ0 against the A/B *with* the
   small block box, i.e. their margins already absorb it, so changing the
   primitive would grow every one of them by ~6px. */
.brikk-pattern .brikk-trust__head .brikk-eyebrow {
    min-height: calc(var(--wp--preset--font-size--body) * var(--wp--custom--lh-base));
}

.brikk-pattern .brikk-trust__heading {
    margin-top: 20px;
    margin-bottom: 18px;
    font-size: calc(clamp(30px, 3.4vw, 46px) * var(--brikk-heading-scale, 1));
    font-weight: 500;
    line-height: 1.1;
}

.brikk-pattern .brikk-trust__lead {
    max-width: 600px;
    margin-inline: auto;
    margin-bottom: 0;
    color: var(--wp--preset--color--muted);
    font-size: 16px;
    line-height: 1.7;
    opacity: .8;
}

.brikk-pattern .brikk-trust__grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 20px;
    margin-bottom: 48px;
}

/* The card. A CSS flex column rather than a core flex-layout group because the
   gap steps 14 → 12px at ≤640, which a blockGap attribute cannot express.
   `.brikk-review__text { flex: 1 }` is what pins the meta row to the bottom of
   every card regardless of how long the quote is. */
.brikk-pattern .brikk-review {
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding: 30px;
    background: var(--wp--preset--color--card-soft);
    border: 1px solid color-mix(in srgb, var(--wp--preset--color--dark) 14%, transparent);
    border-radius: var(--wp--custom--radius-lg);
}

.brikk-pattern .brikk-review .brikk-stars {
    align-self: flex-start;
    margin: 0;
    line-height: 0;
}

.brikk-pattern .brikk-review .brikk-stars img {
    display: block;
    width: auto;
    height: 16px;
    max-width: none;
}

/* `text-wrap: pretty` (§4, site-wide) is turned off here for RAG PARITY with the
   A/B, which renders these quotes with plain wrapping. Measured on the 4th quote
   at 800px, `pretty` widens the rag to avoid a short last line
   ([291,276,290] → [235,224,283,114]); plain wrapping puts the first two lines
   exactly where the A/B puts them. It does NOT change the line COUNT — see the
   ellipsis note below, which is what actually does. Both spellings because
   `text-wrap-style` is the longhand and the shorthand predates it. */
.brikk-pattern .brikk-review__text {
    flex: 1;
    margin: 0;
    color: var(--wp--preset--color--muted);
    font-size: 14px;
    line-height: 1.6;
    text-wrap: auto;
    text-wrap-style: auto;
}

/* 🔴 THE TRUNCATION MARKER, AND WHY IT IS HERE RATHER THAN IN THE QUOTE TEXT.
   `wptexturize` turns a literal `...` in block content into `…` (U+2026), which in
   Helvetica Neue is 14px where three periods are 11.69px. The A/B templates are PHP
   output and are never texturized, so they render the narrower form — and those
   2.31px were enough to push a quote onto an extra line, which in the 2-column band
   made the grid row and the whole section 22.4px taller than the reference. It bit
   at exactly two widths, 800px (quote 4) and 680px (quote 1).
   `content` is not texturized, so drawing the marker here reproduces the A/B's
   metrics exactly: Δ0.0px at all 32 measured widths from 1440 down to 641, where
   two had been 22.4px out.
   ⚠️ Six copy-edit variants were measured before settling on this and every one was
   equal or worse (ending quote 4 with a period fixes 800 but not 680; fixing quote 1
   too just moves the break to 805/675/670/665). This removes the cause; a copy edit
   only ever moves a symptom.
   ⚠️ Three periods, NOT `…` — an ellipsis character here would reproduce the 14px and
   fix nothing. That is a deliberate narrowing of §6i's "`…` is the correct character"
   call, and it applies to the MARKER only, not to prose.
   ⚠️ Every card gets it. Correct here — all four quotes are excerpts of longer
   Trustpilot reviews — but wrong the day a complete quote is added, at which point
   this becomes a per-card class. And the marker is not editable in Gutenberg: the
   same trade as the comparison table's CSS row labels, for the same reason (the
   block layer cannot express the required output). */
.brikk-pattern .brikk-review__text::after {
    content: '...';
}

.brikk-pattern .brikk-review__meta {
    display: flex;
    align-items: center;
    flex-wrap: nowrap;
    gap: 10px;
    margin-top: 4px;
    padding-top: 25px;
    border-top: 1px solid var(--wp--preset--color--line);
}

.brikk-pattern .brikk-review__avatar {
    flex-shrink: 0;
    margin: 0;
    line-height: 0;
}

.brikk-pattern .brikk-review__avatar img {
    display: block;
    width: 40px;
    height: 40px;
    max-width: none;
    border-radius: var(--wp--custom--radius-pill);
    object-fit: cover;
}

/* ⚠️ BOTH STATE THEIR LEADING. They were <div>s in the A/B markup and inherited
   1.4; as <p> in blocks §4 would hand them 1.6, making every meta row ~5px
   taller and every card with it. */
.brikk-pattern .brikk-review__name {
    margin: 0;
    font-size: 12px;
    font-weight: 500;
    line-height: var(--wp--custom--lh-base);
}

/* Was `__date` in the A/B markup, but it never held a date — every card says
   "Kunde hos Brikk". Renamed to what it actually is. */
.brikk-pattern .brikk-review__role {
    margin: 0;
    font-size: 12px;
    line-height: var(--wp--custom--lh-base);
    color: var(--wp--preset--color--muted);
}

.brikk-pattern .brikk-trust__cta {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 12px;
}

@media (max-width: 1024.98px) {
    .brikk-pattern.brikk-trust {
        padding: 72px 0;
    }

    .brikk-pattern .brikk-trust__grid {
        grid-template-columns: repeat(2, 1fr);
        gap: 28px;
    }
}

@media (max-width: 768px) {
    .brikk-pattern .brikk-trust__heading {
        font-size: calc(clamp(28px, 5.2vw, 38px) * var(--brikk-heading-scale, 1));
    }
}

@media (max-width: 640px) {
    .brikk-pattern.brikk-trust {
        padding: 56px 0;
    }

    .brikk-pattern .brikk-trust__head {
        margin-bottom: 40px;
    }

    .brikk-pattern .brikk-trust__lead {
        font-size: 14.5px;
        line-height: 1.6;
    }

    .brikk-pattern .brikk-trust__grid {
        grid-template-columns: 1fr;
        gap: 20px;
    }

    /* The 4th review is dropped on mobile (design decision, DESIGN.md §4). No
       block attribute can express "hide below a breakpoint"; the card is still
       real content and still renders in the editor and on desktop. */
    .brikk-pattern .brikk-trust__grid .brikk-review:nth-child(4) {
        display: none;
    }

    .brikk-pattern .brikk-review {
        padding: 24px;
        gap: 12px;
    }

    .brikk-pattern .brikk-review__text {
        font-size: 13.5px;
        line-height: 1.6;
    }

    .brikk-pattern .brikk-review__meta {
        padding-top: 20px;
    }
}


/* -----------------------------------------------------------------------------
   12.3d  RESULTS / SOLD HOMES  ·  .brikk-results
   -----------------------------------------------------------------------------
   A DARK section. The head + stats are authored as a block pattern; the card
   grid comes from [brikk-sold-homes] (inc/shortcodes/shortcode-sold-homes.php),
   which reads the nsa_js_property CPT — the A/B hardcodes four addresses that
   would go stale the moment a page is published.

   Ported from landing.css:1117-1210 + the ≤1024/≤768/≤640 blocks.

   The section's ink is the warm canvas colour on dark, so the alpha variants
   are mixed from --bg rather than from pure white (the --on-dark-* group is
   pure-white based and reads visibly cooler here).

   NOT ported: `.brikk-results__addr span` and `.brikk-results__status` — no
   markup has ever used them.
   -------------------------------------------------------------------------- */

.brikk-results {
    padding: var(--brikk-section-y) 0;
    background: var(--wp--preset--color--dark);
    color: var(--wp--preset--color--bg);
}

.brikk-results__inner {
    width: 100%;
    max-width: var(--wp--custom--max);
    margin-inline: auto;
    padding-inline: var(--brikk-pad-x);
}

.brikk-results__head {
    text-align: center;
    max-width: 720px;
    margin: 0 auto 64px;
}

.brikk-results__head .brikk-eyebrow {
    display: block;
    margin-bottom: 22px;
    color: var(--wp--custom--on-dark-accent);
}

.brikk-results__heading {
    margin: 0 0 22px;
    font-family: var(--wp--preset--font-family--serif);
    font-weight: 500;
    font-size: calc(clamp(30px, 3.4vw, 46px) * var(--brikk-heading-scale, 1));
    line-height: 1.1;
    letter-spacing: .005em;
    text-wrap: balance;
    color: var(--wp--preset--color--bg);
}

.brikk-results__lead {
    max-width: 560px;
    margin: 0 auto;
    color: color-mix(in srgb, var(--wp--preset--color--bg) 70%, transparent);
    font-size: 16px;
    line-height: 1.7;
}

.brikk-results__stats {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    margin-bottom: 56px;
    border-top: 1px solid color-mix(in srgb, var(--wp--custom--on-accent) 8%, transparent);
    border-bottom: 1px solid color-mix(in srgb, var(--wp--custom--on-accent) 8%, transparent);
}

.brikk-results__stat {
    padding: 48px 28px;
    border-left: 1px solid color-mix(in srgb, var(--wp--custom--on-accent) 8%, transparent);
}

.brikk-results__stat:first-child {
    border-left: 0;
}

.brikk-results__stat-value {
    margin-bottom: 18px;
    font-family: var(--wp--preset--font-family--serif);
    font-weight: 500;
    font-size: clamp(34px, 3vw, 44px);
    line-height: 1;
    letter-spacing: .005em;
    color: var(--wp--preset--color--bg);
}

.brikk-results__stat-label {
    max-width: 220px;
    font-size: 12.5px;
    line-height: 1.5;
    color: color-mix(in srgb, var(--wp--preset--color--bg) 55%, transparent);
}

.brikk-results__grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 24px;
}

.brikk-results__card {
    display: flex;
    flex-direction: column;
}

.brikk-results__card-img {
    position: relative;
    aspect-ratio: 4 / 3;
    overflow: hidden;
    background: var(--wp--preset--color--dark-2);
}

.brikk-results__card-img img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.brikk-results__tag {
    position: absolute;
    top: 14px;
    left: 14px;
    z-index: var(--wp--custom--z-raised);
    padding: 5px 10px 4px;
    background: var(--wp--preset--color--purple);
    color: var(--wp--custom--on-accent);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: .16em;
    text-transform: uppercase;
}

.brikk-results__addr {
    position: absolute;
    inset: auto 0 0 0;
    padding: 60px 16px 14px;
    background: linear-gradient(to top, rgba(0, 0, 0, .7) 0%, rgba(0, 0, 0, 0) 100%);
    color: var(--wp--custom--on-accent);
    font-size: 12.5px;
    font-weight: 500;
    line-height: 1.35;
    letter-spacing: .01em;
    pointer-events: none;
}

/* A sold property has NO price — the importer zeroes every economy field on
   sale — so this slot carries "{postnr} {by}", exactly as the comp does. */
.brikk-results__price {
    margin: 18px 0 8px;
    font-family: var(--wp--preset--font-family--serif);
    font-style: italic;
    font-weight: 500;
    font-size: calc(24px * var(--brikk-heading-scale, 1));
    line-height: 1;
    color: var(--wp--custom--on-dark-accent);
}

@media (max-width: 1024.98px) {
    .brikk-results__stats,
    .brikk-results__grid {
        grid-template-columns: repeat(2, 1fr);
    }

    .brikk-results__stat:nth-child(3) {
        border-left: 0;
    }

    .brikk-results__stat:nth-child(n+3) {
        border-top: 1px solid color-mix(in srgb, var(--wp--custom--on-accent) 8%, transparent);
    }
}

@media (max-width: 768px) {
    .brikk-results__heading {
        font-size: calc(clamp(28px, 5.2vw, 38px) * var(--brikk-heading-scale, 1));
    }
}

@media (max-width: 640px) {
    .brikk-results__head {
        margin-bottom: 40px;
    }

    .brikk-results__lead {
        font-size: 14.5px;
        line-height: 1.6;
    }

    .brikk-results__stats,
    .brikk-results__grid {
        grid-template-columns: 1fr;
    }

    .brikk-results__stats {
        margin-bottom: 40px;
    }

    .brikk-results__stat {
        padding: 28px 4px;
        border-left: 0;
        border-top: 1px solid color-mix(in srgb, var(--wp--custom--on-accent) 8%, transparent);
    }

    .brikk-results__stat:first-child {
        padding-top: 4px;
        border-top: 0;
    }

    .brikk-results__stat-value {
        font-size: 32px;
        margin-bottom: 12px;
    }

    .brikk-results__stat-label {
        font-size: 12px;
        max-width: none;
    }

    .brikk-results__grid {
        gap: 20px;
    }

    .brikk-results__price {
        font-size: calc(22px * var(--brikk-heading-scale, 1));
        margin: 14px 0 6px;
    }
}


/* -----------------------------------------------------------------------------
   12.4  BLOCK-PATTERN COMPONENTS
   -----------------------------------------------------------------------------
   Styling for the section patterns in themes/brikk/patterns/. The division of
   labour is deliberate:

     · SECTION level (background, vertical padding, column gaps) → block
       attributes, so the editor's own controls change them.
     · COMPONENT internals (card chrome, check marks, price typography) → these
       classes, so a section cannot be visually broken by editing a page.
     · ALL COPY → core blocks, fully editable.

   Everything here is a class the pattern applies; nothing targets bare
   elements, so none of it can leak onto legacy or Elementor pages.
   -------------------------------------------------------------------------- */

/* The eyebrow primitive is inline-block (it is a <span> everywhere in the
   design). As a core PARAGRAPH inside a constrained layout that breaks
   centring: the layout centres children with `margin-inline:auto`, which does
   nothing to an inline-block, so the eyebrow sticks to the left gutter while
   the heading below it is centred. Scoped to the block-editor paragraph so
   every existing <span class="brikk-eyebrow"> is untouched. */
p.brikk-eyebrow {
    display: block;
}

/* --- check list ----------------------------------------------------------- */

/* The A/B markup draws each tick with `<span class="brikk-check"><span>✓</span>`
   — 14 elements in the pricing section alone, 44% of its DOM, and the reason a
   core LIST block could not express it. Same visual, drawn from a ::before, so
   the pattern uses a plain editable core/list.

   ⚠️ The tick is absolutely positioned inside the item's left padding rather
   than sitting beside the text as a flex sibling. A flex li turns every run of
   inline content into its own anonymous flex item, so
   `<li><strong>Fair pris</strong> - sælg fra kun 22.500 kr</li>` would lay the
   bold lead-in and the rest of the sentence out side by side instead of as one
   wrapping line — and the hero list is exactly that shape. Padding + absolute
   keeps the item a normal line box, and wrapped lines still indent past the
   tick. The gap between tick and text is therefore the item's padding-left
   minus the tick's 18px. */
.brikk-check-list {
    list-style: none;
    padding-left: 0;
}

.brikk-check-list li {
    position: relative;
    /* 18px tick + 10px gap (dense list — DESIGN.md §9 allows 10 here). */
    padding-left: 28px;
    color: var(--wp--preset--color--dark);
    font-size: 14px;
    line-height: 1.45;
}

.brikk-check-list li::before {
    content: '\2713';
    position: absolute;
    top: 0px;
    left: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    padding-top: 3px;
    border: 1px solid var(--wp--preset--color--purple);
    border-radius: 50%;
    color: var(--wp--preset--color--purple);
    font-family: var(--wp--preset--font-family--serif);
    font-size: 9px;
    line-height: 1;
}

/* --- arrow link ----------------------------------------------------------- */

.brikk-link-arrow a {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding-bottom: 2px;
    border-bottom: 1px solid var(--wp--custom--line-dark);
    color: var(--wp--preset--color--dark);
    font-size: 12px;
    font-weight: 500;
    letter-spacing: var(--wp--custom--ls-ui);
    text-transform: uppercase;
    text-decoration: none;
    opacity: .6;
    transition: gap var(--wp--custom--transition), opacity var(--wp--custom--transition);
}

.brikk-link-arrow a:hover {
    gap: 12px;
    opacity: 1;
}

/* --- hero ----------------------------------------------------------------- */

/* Pattern: patterns/hero.php. Three things here genuinely cannot be block
   attributes:
     · the photo is pinned to the VIEWPORT's right edge, so the section carries
       no padding at all (an absolutely-positioned child is offset from its
       ancestor's PADDING box) and the gutter sits on .brikk-hero__inner;
     · the background inverts at ≤640, and WordPress emits preset background
       classes with !important, so a backgroundColor attribute could never be
       overridden;
     · every responsive step — block attributes emit INLINE styles, which no
       media query can override.
   Everything else is core blocks and editor controls. */

.brikk-pattern.brikk-hero {
    position: relative;
    overflow: hidden;
    background: var(--wp--preset--color--bg);
}

.brikk-pattern .brikk-hero__copy {
    padding-top: 60px;
}

/* Copy rhythm. Margins rather than a block gap because the steps differ per
   element (22/40/36/30/32/30) — the column sets blockGap 0 and these own it. */
.brikk-pattern .brikk-hero__eyebrow {
    margin: 0 0 22px;
}

/* The display role. Size, weight and leading are CSS rather than block
   attributes because all three step at breakpoints: a fontSize preset emits a
   class WordPress marks !important, and a typography style emits an inline
   style — neither can be overridden by a media query. The size still reads the
   theme.json token. */
.brikk-pattern .brikk-hero__title {
    margin: 22px 0 40px;
    /* Flat 74px down to 1024, NOT the fluid `display` preset
       (clamp(38px, 5.6vw, 74px)) — that only reaches 74px at a 1321px viewport
       and shrank the title to 61.6px at 1100 where landing.css holds 74px.
       The ≤1024 clamp below picks up exactly where landing.css's ladder does. */
    font-size: calc(74px * var(--brikk-heading-scale, 1));
    font-weight: 400;
    line-height: 1.03;
    letter-spacing: .004em;
    text-wrap: balance;
}

.brikk-pattern .brikk-hero__list {
    display: flex;
    flex-direction: column;
    gap: 14px;
    margin: 0 0 36px;
}

/* 18px tick + the canonical 12px gap. line-height is the base 1.4: landing.css
   asks for 1.5 here, but its own `.brikk-ab-page *` reset overrides that on the
   <div> the text actually sits in, so 1.4 is what the A/B page renders. */
.brikk-pattern .brikk-hero__list li {
    padding-left: 30px;
    font-size: 15px;
    font-weight: 300;
    line-height: var(--wp--custom--lh-base);
    color: var(--wp--preset--color--muted);
}

.brikk-pattern .brikk-hero__list li::before {
    top: 1px;
}

.brikk-pattern .brikk-hero__list li strong {
    margin-right: 4px;
    font-weight: 500;
    color: var(--wp--preset--color--dark);
}

.brikk-pattern .brikk-hero__trust {
    margin: 0 0 30px;
    font-size: var(--wp--preset--font-size--ui);
    color: var(--wp--preset--color--muted);
}

.brikk-pattern .brikk-hero__ctas {
    margin: 0 0 32px;
}

/* Metrics row — equal columns separated by hairlines. `stretch` overrides the
   `align-items: center` core emits for every flex-layout group, without which
   the dividers only span the tallest metric's text. */
.brikk-pattern .brikk-hero__metrics {
    align-items: stretch;
    max-width: 560px;
    margin: 0 0 30px;
}

.brikk-pattern .brikk-hero__metric {
    flex: 1 1 0;
    min-width: 0;
    padding: 2px 20px;
}

.brikk-pattern .brikk-hero__metric:first-child {
    padding-left: 0;
}

.brikk-pattern .brikk-hero__metric + .brikk-hero__metric {
    border-left: 1px solid var(--wp--preset--color--line);
}

/* No margin reset here: the 8px between value and label is the metric group's
   own blockGap, which core emits as `> * + * { margin-block-start }` at one
   class of specificity — a `margin: 0` at two classes would silently kill it. */
.brikk-pattern .brikk-hero__metric-value {
    font-family: var(--wp--preset--font-family--serif);
    font-size: 26px;
    font-weight: 500;
    line-height: 1;
    color: var(--wp--preset--color--dark);
    white-space: nowrap;
}

.brikk-pattern .brikk-hero__metric-label {
    font-size: 10px;
    letter-spacing: .1em;
    line-height: 1.45;
    text-transform: uppercase;
    color: var(--wp--preset--color--muted);
}

/* The photo: a full-height panel pinned to the viewport's right edge. It sits
   in the second column so that stacking at ≤1024 needs no re-ordering, but it
   is positioned against the section, not the column. */
.brikk-pattern .brikk-hero__media {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 45vw;
    overflow: hidden;
    background: var(--wp--custom--bg-dim);
}

.brikk-pattern .brikk-hero__photo {
    position: absolute;
    inset: 0;
    margin: 0;
}

.brikk-pattern .brikk-hero__photo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.brikk-pattern .brikk-hero__media-badge {
    position: absolute;
    right: 24px;
    bottom: 24px;
    margin: 0;
    pointer-events: none;
}

.brikk-pattern .brikk-hero__media-badge img {
    width: 220px;
    height: auto;
}

/* The design's single wide-screen enhancement: past 1500px the photo stops
   bleeding and returns to the flow as the second column. */
@media (min-width: 1500px) {
    .brikk-pattern .brikk-hero__media-col {
        display: flex;
    }

    .brikk-pattern .brikk-hero__media {
        position: relative;
        inset: auto;
        width: 100%;
    }
}

@media (max-width: 1024.98px) {
    .brikk-pattern.brikk-hero .wp-block-columns {
        gap: 48px;
    }

    .brikk-pattern .brikk-hero__copy {
        max-width: 680px;
        padding-top: 48px;
    }

    .brikk-pattern .brikk-hero__title {
        margin-top: 16px;
        font-size: calc(clamp(42px, 6.4vw, 60px) * var(--brikk-heading-scale, 1));
        line-height: 1.05;
    }

    .brikk-pattern .brikk-hero__list {
        margin-bottom: 30px;
    }

    .brikk-pattern .brikk-hero__media {
        position: relative;
        inset: auto;
        width: 100%;
        margin-bottom: 24px;
        aspect-ratio: 16 / 10;
    }
}

/* The design stacks the hero at 1024, but core's Columns block only stacks
   below 782px — above that it forces `flex-wrap: nowrap !important`. So in the
   782–1024 band the stack has to come from the flex DIRECTION instead.
   ⚠️ Below 782 core stacks the columns itself with `flex-basis: 100%
   !important`; in a column-direction flex container that !important basis
   becomes a 100% HEIGHT and the layout collapses. Hence the min-width bound —
   do not merge this into the block above. */
@media (min-width: 782px) and (max-width: 1024.98px) {
    .brikk-pattern.brikk-hero .wp-block-columns {
        flex-direction: column;
    }

    .brikk-pattern.brikk-hero .wp-block-column {
        flex-basis: auto;
        flex-grow: 0;
    }
}

/* The A/B shrinks the badge at 900px; folded into the ladder at 768, where the
   stacked photo is genuinely narrow (DESIGN.md §7 — one-off component
   breakpoints fold into 1024/768/640/420). */
@media (max-width: 768px) {
    /* ⚠️ REPRODUCES A NON-MONOTONIC JUMP IN landing.css. Its ladder is
       clamp(42px, 6.4vw, 60px) at ≤1024 — which computes to 49px at 769px — and
       then clamp(50px, 10vw, 70px) at ≤768, which clamps to 70px. So the title
       grows from 49px to 70px as the viewport gets 1px NARROWER. That reads like
       an oversight rather than intent, but the brief is a 1:1 reproduction of
       what the A/B renders, and without this the hero was 43-53px short across
       the whole 641-768 band. Worth raising with Andreas before launch. */
    .brikk-pattern .brikk-hero__title {
        font-size: calc(clamp(50px, 10vw, 70px) * var(--brikk-heading-scale, 1));
    }

    .brikk-pattern .brikk-hero__media-badge {
        right: 16px;
        bottom: 16px;
    }

    .brikk-pattern .brikk-hero__media-badge img {
        width: 150px;
    }
}

/* ≤640 the hero inverts into a full-bleed dark photo with light copy
   (DESIGN.md §7, hero strategy 1). The same <img> is reused rather than the
   A/B's CSS background + 1×1 placeholder trick: one element, one download, and
   the photo stays editable in the block editor. */
@media (max-width: 640px) {
    .brikk-pattern.brikk-hero--mobilebg {
        background-color: var(--wp--preset--color--dark);
    }

    /* ⚠️ MOBILEBG-SCOPED, and it matters. These two rules ARE the inversion:
       the media column is empty (its photo is positioned against the section),
       so the stack gap would read as dead space below the copy. The agents hero
       (patterns/hero-agents.php) shares .brikk-hero but keeps a real in-flow
       photo at ≤640, where it must hold the ≤1024 ladder's 16/10 box. Leaving
       these unscoped absolutely-positioned its photo over the copy. */
    .brikk-pattern.brikk-hero--mobilebg .wp-block-columns {
        gap: 0;
    }

    .brikk-pattern.brikk-hero--mobilebg .brikk-hero__media {
        position: absolute;
        top: 0;
        right: auto;
        bottom: auto;
        left: 0;
        width: 100%;
        height: 65%;
        margin: 0;
        aspect-ratio: auto;
        background: transparent;
    }

    /* The A/B's composite gradient, whose stops are percentages of the SECTION
       height (.60 → .82 at 36% → .97 at 56% → solid at 65%). The photo is
       exactly the top 65%, so each stop is divided by .65 here and the
       section's own dark background covers everything below it. */
    .brikk-pattern.brikk-hero--mobilebg .brikk-hero__media::after {
        content: '';
        position: absolute;
        inset: 0;
        background: linear-gradient(180deg,
                color-mix(in srgb, var(--wp--preset--color--dark) 60%, transparent) 0%,
                color-mix(in srgb, var(--wp--preset--color--dark) 82%, transparent) 55%,
                color-mix(in srgb, var(--wp--preset--color--dark) 97%, transparent) 86%,
                var(--wp--preset--color--dark) 100%);
    }

    .brikk-pattern .brikk-hero__media-badge {
        display: none;
    }

    /* The 32px top padding is the shared hero ladder (60 → 48 → 32). */
    .brikk-pattern .brikk-hero__copy {
        padding-top: 32px;
    }

    /* Lifting the copy over the photo and re-ordering it (CTAs, Trustpilot,
       metrics) is the inversion, not the hero — hence mobilebg-scoped. */
    .brikk-pattern.brikk-hero--mobilebg .brikk-hero__copy {
        position: relative;
        z-index: var(--wp--custom--z-raised);
        display: flex;
        flex-direction: column;
        color: var(--wp--custom--on-dark-muted);
    }

    .brikk-pattern .brikk-hero__ctas {
        order: 1;
    }

    .brikk-pattern .brikk-hero__trust {
        order: 2;
        justify-content: center;
    }

    .brikk-pattern .brikk-hero__metrics {
        order: 3;
    }

    .brikk-pattern .brikk-hero__eyebrow {
        margin-bottom: 14px;
    }

    .brikk-pattern.brikk-hero--mobilebg .brikk-hero__eyebrow {
        color: var(--wp--custom--on-dark-faint);
    }

    .brikk-pattern .brikk-hero__title {
        margin-top: 10px;
        font-size: calc(60px * var(--brikk-heading-scale, 1));
        line-height: 1.08;
    }

    .brikk-pattern.brikk-hero--mobilebg .brikk-hero__title {
        font-weight: 600;
        color: var(--wp--custom--on-dark);
    }

    .brikk-pattern .brikk-hero__list {
        gap: 12px;
        margin-bottom: 26px;
    }

    .brikk-pattern .brikk-hero__list li {
        font-size: 14px;
    }

    .brikk-pattern.brikk-hero--mobilebg .brikk-hero__list li {
        color: var(--wp--custom--on-dark-muted);
    }

    .brikk-pattern.brikk-hero--mobilebg .brikk-hero__list li strong {
        color: var(--wp--custom--on-dark);
    }

    /* Thicker ticks so they hold up over the photo. */
    .brikk-pattern.brikk-hero--mobilebg .brikk-hero__list li::before {
        font-weight: 700;
    }

    .brikk-pattern .brikk-hero__ctas {
        flex-direction: column;
        gap: 10px;
        margin-bottom: 28px;
    }

    .brikk-pattern .brikk-hero__ctas > * {
        width: 100%;
    }

    .brikk-pattern .brikk-hero__ctas .brikk-btn {
        width: 100%;
        padding: 18px 22px 15px;
    }

    /* A dark panel keeps the numbers legible where the photo is busiest. The
       A/B's 12px radius is squared here (DESIGN.md §9 — the design is
       square-edged and that was its only rounded corner). */
    .brikk-pattern.brikk-hero--mobilebg .brikk-hero__metrics {
        padding: 14px 4px;
        background: color-mix(in srgb, var(--wp--preset--color--dark) 32%, transparent);
    }

    .brikk-pattern .brikk-hero__metrics {
        max-width: none;
        margin-bottom: 26px;
    }

    .brikk-pattern .brikk-hero__metric,
    .brikk-pattern .brikk-hero__metric:first-child {
        padding: 0 10px;
        text-align: center;
    }

    .brikk-pattern.brikk-hero--mobilebg .brikk-hero__metric + .brikk-hero__metric {
        border-left-color: var(--wp--preset--color--dark);
    }

    .brikk-pattern .brikk-hero__metric-value {
        font-size: 21px;
        white-space: normal;
    }

    .brikk-pattern.brikk-hero--mobilebg .brikk-hero__metric-value {
        color: var(--wp--preset--color--bg);
    }

    .brikk-pattern .brikk-hero__metric-label {
        letter-spacing: .06em;
    }

    .brikk-pattern.brikk-hero--mobilebg .brikk-hero__metric-label {
        color: var(--wp--custom--on-dark-faint);
    }
}

@media (max-width: 420px) {
    .brikk-pattern.brikk-hero--mobilebg .brikk-hero__title {
        font-size: calc(42px * var(--brikk-heading-scale, 1));
    }

    .brikk-pattern .brikk-hero__eyebrow {
        font-size: 10px;
        letter-spacing: .26em;
    }
}


/* --- hero: "lokale mæglere" variant --------------------------------------- */

/* Pattern: patterns/hero-agents.php. Deliberately the SAME component as the
   front page hero — landing.css says so itself ("content left, image right —
   same as landing … the layout itself uses the base hero"), so everything above
   is shared and only these five things differ:
     · a hairline closing the section off from the search below it;
     · a compact title role;
     · body paragraphs instead of the check list;
     · a stats row instead of the metrics row;
     · a captioned photo (gradient + caption) instead of the badge.
   It does NOT carry --mobilebg: this hero keeps a real in-flow photo at ≤640
   rather than inverting to a dark full-bleed image. That is why the inversion
   rules above are scoped to --mobilebg. */

.brikk-pattern.brikk-hero--agents {
    border-bottom: 1px solid var(--wp--preset--color--line);
}

/* ⚠️ ONE unconditional rule, no media queries — and that is the point. At
   (0,3,0) it outranks the shared hero's (0,2,0) size ladder at EVERY
   breakpoint, so the compact title needs no restatement at 1024/768/640/420.
   landing.css uses exactly this trick (.brikk-hero__title.brikk-hero__title--sm)
   and says why in its own comment. max-width comes along for the same reason. */
.brikk-pattern.brikk-hero--agents .brikk-hero__title {
    max-width: none;
    font-size: clamp(32px, 6vw, 44px);
}

/* Body copy. The three paragraphs' 26/30px margins COLLAPSE to 30px between
   them, exactly as in the A/B — the copy column is a normal-flow block there
   and here (the flex-direction that would kill collapsing is ≤640 and
   mobilebg-only). Colour: landing.css writes #1e1726, a near-black with a
   faint purple cast that is imperceptible at .84 alpha against --dark. */
.brikk-pattern .brikk-hero__description {
    margin: 26px 0 30px;
    max-width: none;
    font-size: 17px;
    font-weight: 300;
    line-height: 1.65;
    color: var(--wp--preset--color--dark);
    opacity: .84;
}

/* ⚠️ CORE'S DEFAULT BLOCK GAP — see the note at §12.4's steps block. These two
   containers space their children with grid `gap` and explicit margins, so
   core's footer-printed `> * + * { margin-block-start: 24px }` lands on top. */
.brikk-pattern .brikk-hero__stats > *,
.brikk-pattern .brikk-hero__stat > * {
    margin-block-start: 0;
}

/* Stats row. `repeat(4, auto)` + centred tracks with only THREE stats in the
   markup is what the A/B renders — the fourth column was designed for and never
   filled. Reproduced rather than "fixed": the three columns sit centred under
   the copy, which is the look. */
.brikk-pattern .brikk-hero__stats {
    display: grid;
    grid-template-columns: repeat(4, auto);
    justify-content: center;
    gap: 36px;
    margin: 36px 0 28px;
    padding-top: 32px;
}

/* Not a port — the standard grid-item overflow guard. A `1fr` track's implicit
   `min-width: auto` lets a long label push the row wider than the column, which
   is what the design system's other small-phone guards exist for. */
.brikk-pattern .brikk-hero__stat {
    min-width: 0;
}

.brikk-pattern .brikk-hero__stat-value {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: 4px;
    margin: 0 0 10px;
    font-family: var(--wp--preset--font-family--serif);
    font-size: 34px;
    font-weight: 500;
    line-height: 1;
    color: var(--wp--preset--color--dark);
}

/* The Trustpilot star. A CSS pseudo, not an inline <img> as in the A/B: it is
   decorative (aria-hidden there), and an <img> inside a core/paragraph is
   RichText content that would have to survive an editor round-trip byte for
   byte. Drawn as a flex item so the A/B's `align-self: center` still applies. */
.brikk-pattern .brikk-hero__stat-value--star::after {
    content: '';
    align-self: center;
    width: 20px;
    height: 20px;
    background: url('../img/trustpilot/star-single.svg') center / contain no-repeat;
}

.brikk-pattern .brikk-hero__stat-label {
    margin: 0;
    font-size: var(--wp--preset--font-size--micro);
    letter-spacing: .24em;
    line-height: var(--wp--custom--lh-base);
    text-transform: uppercase;
    text-align: center;
    color: var(--wp--preset--color--muted);
}

/* Caption over the photo, with its own readability gradient. */
.brikk-pattern.brikk-hero--agents .brikk-hero__media::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 45%;
    z-index: var(--wp--custom--z-raised);
    pointer-events: none;
    background: linear-gradient(to top,
            color-mix(in srgb, var(--wp--preset--color--dark) 65%, transparent),
            transparent);
}

.brikk-pattern .brikk-hero__media-caption {
    position: absolute;
    left: 28px;
    bottom: 24px;
    z-index: calc(var(--wp--custom--z-raised) + 1);
    max-width: 60%;
    margin: 0;
    font-family: var(--wp--preset--font-family--serif);
    font-style: italic;
    font-weight: 600;
    font-size: 17px;
    line-height: 1.35;
    letter-spacing: .01em;
    color: var(--wp--custom--on-dark);
    text-shadow: 0 1px 10px color-mix(in srgb, var(--wp--preset--color--dark) 85%, transparent);
}

@media (max-width: 1024.98px) {
    .brikk-pattern .brikk-hero__description {
        margin: 22px 0 26px;
        font-size: var(--wp--preset--font-size--body);
        line-height: var(--wp--custom--lh-copy);
    }

    .brikk-pattern .brikk-hero__stats {
        grid-template-columns: repeat(4, 1fr);
        gap: 24px;
    }

    .brikk-pattern .brikk-hero__stat-value {
        font-size: 28px;
    }
}

@media (max-width: 768px) {
    .brikk-pattern .brikk-hero__stats {
        grid-template-columns: repeat(2, 1fr);
        gap: 28px 24px;
    }
}

@media (max-width: 640px) {
    .brikk-pattern .brikk-hero__description {
        margin: 18px 0 22px;
        font-size: var(--wp--preset--font-size--body-sm);
    }

    .brikk-pattern .brikk-hero__stats {
        gap: 22px 18px;
        margin: 26px 0 20px;
        padding-top: 24px;
    }

    .brikk-pattern .brikk-hero__stat-value {
        font-size: 24px;
    }

    .brikk-pattern .brikk-hero__stat-label {
        font-size: 9.5px;
        letter-spacing: .18em;
    }

    .brikk-pattern .brikk-hero__media-caption {
        left: 16px;
        bottom: 14px;
        max-width: 85%;
    }
}


/* --- hero: "hvad er inkluderet" variant ----------------------------------- */

/* Pattern: patterns/hero-included.php. The third page on the same component —
   landing.css adds exactly three declarations for it (:4390-4401) plus a ≤640
   block (:4942-4949), and nothing else. Measured, not assumed: the photo is
   absolutely positioned at 45vw below 1500px, in-flow above it, and a 16/10
   in-flow box at ≤1024, identical to the front page hero at every width.

   It carries NEITHER --mobilebg (no dark inversion — the photo is simply
   dropped at ≤640) NOR the --agents hairline (the dark band below supplies the
   edge). */

/* ⚠️ ONE unconditional rule for the compact title, same trick and same reason as
   --agents: at (0,3,0) it outranks the shared hero's (0,2,0) size ladder at
   EVERY breakpoint, so it needs no restatement at 1024/768/640/420. landing.css
   does it with a doubled class (.brikk-hero__title.brikk-hero__title--sm) and
   explains why in its own comment.
   The 600px cap comes along in the same rule — and unlike --agents (which
   releases the cap to `none`) this variant NARROWS it, so it must also be
   restated for the body copy below. */
.brikk-pattern.brikk-hero--included .brikk-hero__title {
    max-width: 600px;
    font-size: clamp(32px, 6vw, 44px);
}

/* The shared .brikk-hero__description rule sets `max-width: none` (it was written
   for --agents, where the copy fills the column). landing.css's own base for this
   element is 440px and this page overrides it to 600px, so state it here — at
   (0,3,0), because the shared rule is (0,2,0) and comes first. */
.brikk-pattern.brikk-hero--included .brikk-hero__description {
    max-width: 600px;
}

/* 60px of air BELOW the copy as well as above. In landing.css this is an
   UNCONDITIONAL (0,2,0) rule that appears AFTER every one of the base hero's
   media-query rules for the same element, so source order makes it win at every
   width — including ≤1024, where the base steps padding-top down to 48px. That
   cascade is reproduced here with a specificity bump instead of source order,
   which is stabler: it cannot be broken by inserting a rule above it. */
.brikk-pattern.brikk-hero--included .brikk-hero__copy {
    padding-top: 60px;
    padding-bottom: 60px;
}

/* The copy box is capped at 600px once the hero stacks. In the A/B this is not a
   stated cap at all — `.brikk-hero__copy` there has `max-width: 680px` plus an
   auto margin, and an auto margin makes a GRID item shrink-to-fit, so it lands on
   600 only because both the h1 and the body copy are capped at 600. Our copy is a
   flex item (a core Column), which stretches instead, so it measured 680px.
   Stated explicitly here: 600px is the width the A/B page actually presents, and
   without it the box differs by up to 80px across the whole 641-1024 band. (Zero
   height effect today — both children are already capped — but it decides where a
   longer eyebrow would wrap, and it keeps the diff clean.) */
@media (max-width: 1024.98px) {
    .brikk-pattern.brikk-hero--included .brikk-hero__copy {
        max-width: 600px;
    }
}

@media (max-width: 640px) {
    /* The photo is dropped entirely and the copy closes up its bottom gap.
       Hiding the COLUMN rather than the media box is deliberate: an emptied
       column would still contribute the 56px stack gap, and the base's
       `gap: 0` fix is scoped to --mobilebg (where the media column is empty by
       design). One rule instead of two, and no dead flex item. */
    .brikk-pattern.brikk-hero--included .brikk-hero__media-col {
        display: none;
    }

    .brikk-pattern.brikk-hero--included .brikk-hero__copy {
        padding-bottom: 0;
    }
}


/* --- logos strip ---------------------------------------------------------- */

.brikk-logos__list {
    gap: 48px;
}

.brikk-logos__list .wp-block-image {
    margin: 0;
}

.brikk-logos__list img {
    height: 22px;
    width: auto;
}

.brikk-logos__list .brikk-logo-boligsiden img {
    height: 27px;
}

.brikk-logos__list .brikk-logo-boliga img {
    height: 22px;
}

.brikk-logos__list .brikk-logo-instagram img {
    height: 28px;
    opacity: .8;
}

@media (max-width: 1024.98px) {
    .brikk-logos__list {
        gap: 36px;
    }
}

@media (max-width: 640px) {
    .brikk-logos__list {
        gap: 26px 32px;
    }

    .brikk-logos__list img {
        height: 18px;
    }

    .brikk-logos__list .brikk-logo-boligsiden img {
        height: 22px;
    }

    .brikk-logos__list .brikk-logo-instagram img {
        height: 23px;
    }
}

/* --- feature cards -------------------------------------------------------- */

/* The card is a core Column; these give it its surface and make the arrow link
   sit on the card's baseline however long the copy is. */
.brikk-features .wp-block-column {
    display: flex;
    flex-direction: column;
    padding: 0 0 32px;
    background: var(--wp--preset--color--card-soft);
    border: 1px solid color-mix(in srgb, var(--wp--preset--color--dark) 14%, transparent);
    border-radius: var(--wp--custom--radius-lg);
    overflow: hidden;
}

.brikk-features .wp-block-column > :not(.brikk-feature__img) {
    margin-inline: 30px;
}

/* Card title: serif 26px (DESIGN.md §9 — the A/B's 25px is drift), 21px on
   mobile. CSS rather than a block attribute because of that mobile step. */
.brikk-pattern .brikk-feature__title {
    font-size: 26px;
    line-height: var(--wp--custom--lh-heading);
}

@media (max-width: 640px) {
    .brikk-pattern .brikk-feature__title {
        font-size: 21px;
    }
}

.brikk-feature__img {
    height: 240px;
    margin: 0;
    background: var(--wp--custom--bg-dim);
}

.brikk-feature__img img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Pushes the arrow link to the bottom of the card. */
.brikk-features .wp-block-column > p:not(.brikk-link-arrow) {
    flex: 1;
}

.brikk-features .brikk-link-arrow {
    align-self: flex-start;
    flex: none;
}

@media (max-width: 1024.98px) {
    .brikk-feature__img {
        height: 210px;
    }

    .brikk-features .wp-block-column > :not(.brikk-feature__img) {
        margin-inline: 26px;
    }
}

@media (max-width: 640px) {
    .brikk-feature__img {
        height: 200px;
    }

    .brikk-features .wp-block-column > :not(.brikk-feature__img) {
        margin-inline: 24px;
    }
}

/* --- pricing cards -------------------------------------------------------- */

.brikk-price-card {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: 40px 36px 36px;
    background: var(--wp--preset--color--card-soft);
    border: 1px solid color-mix(in srgb, var(--wp--preset--color--dark) 14%, transparent);
}

.brikk-price-card--featured {
    background: var(--wp--preset--color--card);
    border-color: var(--wp--preset--color--purple);
}

.brikk-price-card__badge {
    position: absolute;
    top: 0;
    right: 0;
    padding: 9px 12px 6px;
    background: var(--wp--preset--color--purple);
    color: var(--wp--custom--on-accent);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: .14em;
    text-transform: uppercase;
}

.brikk-price-card__eyebrow {
    margin: 0 0 14px;
    color: var(--wp--preset--color--muted);
    font-size: 11.5px;
    font-weight: 500;
    letter-spacing: .24em;
    text-transform: uppercase;
}

.brikk-price-card__price {
    margin: 0 0 6px;
    font-family: var(--wp--preset--font-family--serif);
    font-size: calc(56px * var(--brikk-heading-scale, 1));
    font-weight: 500;
    line-height: 1;
}

.brikk-price-card__price small {
    margin-left: 4px;
    color: var(--wp--preset--color--muted);
    font-family: var(--wp--preset--font-family--serif);
    font-size: calc(24px * var(--brikk-heading-scale, 1));
    font-weight: 500;
    /* ⚠️ 1.4, NOT the `line-height: 1` inherited from .brikk-price-card__price.
       landing.css's `.brikk-ab-page * { line-height: 1.4 }` matches this <small>
       DIRECTLY, and a direct match beats inheritance — so the A/B renders 1.4
       here, and its taller inline box makes the price line 39px, not 38px. */
    line-height: var(--wp--custom--lh-base);
}

.brikk-price-card__sub {
    margin: 15px 0 34px;
    padding-bottom: 50px;
    border-bottom: 1px solid color-mix(in srgb, var(--wp--preset--color--dark) 14%, transparent);
    color: var(--wp--preset--color--muted);
    font-size: 14px;
    line-height: 1.6;
}

.brikk-price-card .brikk-check-list {
    flex: 1;
    margin-bottom: 28px;
}

.brikk-price-card .brikk-btn {
    align-self: flex-start;
}

@media (max-width: 1024.98px) {
    .brikk-price-card {
        padding: 40px 32px 32px;
    }

    .brikk-price-card__price {
        font-size: calc(50px * var(--brikk-heading-scale, 1));
    }
}

@media (max-width: 768px) {
    .brikk-price-card {
        padding: 40px 26px 28px;
    }

    .brikk-price-card__price {
        font-size: calc(46px * var(--brikk-heading-scale, 1));
    }
}

@media (max-width: 640px) {
    .brikk-price-card {
        padding: 40px 24px 26px;
    }

    .brikk-price-card__price {
        font-size: calc(42px * var(--brikk-heading-scale, 1));
    }

    .brikk-price-card__price small {
        font-size: calc(20px * var(--brikk-heading-scale, 1));
    }

    .brikk-price-card__sub {
        margin: 12px 0 24px;
        padding-bottom: 28px;
        font-size: 13.5px;
    }

    .brikk-price-card .brikk-check-list {
        margin-bottom: 24px;
    }

    .brikk-check-list li {
        font-size: 13.5px;
    }

    /* Mobile shows the featured package in full and collapses the other one to
       a price summary (design decision, DESIGN.md §4). */
    .brikk-price-card--featured {
        order: -1;
    }

    .brikk-price-card:not(.brikk-price-card--featured) .brikk-check-list,
    .brikk-price-card:not(.brikk-price-card--featured) .brikk-btn {
        display: none;
    }

    .brikk-price-card:not(.brikk-price-card--featured) .brikk-price-card__sub {
        margin-bottom: 0;
        padding-bottom: 0;
        border-bottom: 0;
    }
}

@media (max-width: 420px) {
    .brikk-price-card {
        padding: 40px 20px 24px;
    }

    .brikk-price-card__price {
        font-size: calc(38px * var(--brikk-heading-scale, 1));
    }
}


/* >>> BRIKK front-page section patterns — assembled fragments (do not hand-edit this marker) */

/* --- testimonial ---------------------------------------------------------- */

/* ⚠️ CORE'S DEFAULT BLOCK GAP. theme.json enables spacing.blockGap, so core's
   core-block-supports CSS (printed in the FOOTER, at (0,1,0)) gives every layout
   container `> * + * { margin-block-start: 24px }`. These containers space their
   children with CSS grid/flex `gap` or with explicit margins, so that 24px lands
   ON TOP and every one of them grew. Zeroed here rather than with a blockGap
   attribute on the pattern, so the fix cannot be lost by an editor tweaking the
   section's spacing controls. */
.brikk-pattern.brikk-testimonial > * {
    margin-block-start: 0;
}


/* Pattern: patterns/testimonial.php. Everything is copy, so everything is a core
   block; only the values that STEP at a breakpoint live here (see the pattern's
   docblock). Marker-scoped like every §12.4 rule: the live A/B landing page uses
   the same .brikk-testimonial classes, and landing.css loads FIRST at (0,2,0),
   so an unmarked rule here would tie and win — restyling a production page. */

.brikk-pattern.brikk-testimonial {
    padding-top: var(--wp--preset--spacing--9);
    padding-bottom: var(--wp--preset--spacing--9);
    text-align: center;
}

.brikk-pattern .brikk-testimonial__stars {
    margin-bottom: var(--wp--preset--spacing--6);
}

/* The A/B renders this as an 18px-tall SVG; the source file is 132×24, so 90px
   wide lands exactly on 18px tall (132 ÷ 24 × 18 = 99 … the A/B constrains by
   HEIGHT, we constrain by width because core's image block emits a width). */
.brikk-pattern .brikk-testimonial__stars img {
    display: block;
    height: 18px;
    width: auto;
    margin: 0 auto;
}

.brikk-pattern .brikk-testimonial__quote {
    margin: 0 0 36px;
    color: var(--wp--preset--color--bg);
    font-family: var(--wp--preset--font-family--serif);
    font-size: calc(clamp(22px, 2.4vw, 30px) * var(--brikk-heading-scale, 1));
    font-style: italic;
    font-weight: 500;
    line-height: 1.45;
    letter-spacing: .005em;
    text-wrap: balance;
}

.brikk-pattern .brikk-testimonial__name {
    margin: 0 0 var(--wp--preset--spacing--2);
    color: var(--wp--preset--color--bg);
    font-size: 13px;
    font-weight: 500;
    line-height: var(--wp--custom--lh-base);
}

.brikk-pattern .brikk-testimonial__meta {
    margin: 0;
    color: var(--wp--custom--on-dark-accent);
    font-family: var(--wp--preset--font-family--sans);
    font-size: 11px;
    font-weight: 500;
    line-height: var(--wp--custom--lh-base);
    letter-spacing: .28em;
    text-transform: uppercase;
}

@media (max-width: 1024.98px) {
    .brikk-pattern.brikk-testimonial {
        padding-top: 72px;
        padding-bottom: 72px;
    }
}

@media (max-width: 640px) {
    .brikk-pattern.brikk-testimonial {
        padding-top: 56px;
        padding-bottom: 56px;
    }

    .brikk-pattern .brikk-testimonial__stars {
        margin-bottom: var(--wp--preset--spacing--5);
    }

    .brikk-pattern .brikk-testimonial__quote {
        margin-bottom: 26px;
        font-size: calc(clamp(20px, 5.4vw, 26px) * var(--brikk-heading-scale, 1));
        line-height: var(--wp--custom--lh-base);
    }
}


/* --- mid CTA (mobile only) ------------------------------------------------ */

/* ⚠️ CORE'S DEFAULT BLOCK GAP. theme.json enables spacing.blockGap, so core's
   core-block-supports CSS (printed in the FOOTER, at (0,1,0)) gives every layout
   container `> * + * { margin-block-start: 24px }`. These containers space their
   children with CSS grid/flex `gap` or with explicit margins, so that 24px lands
   ON TOP and every one of them grew. Zeroed here rather than with a blockGap
   attribute on the pattern, so the fix cannot be lost by an editor tweaking the
   section's spacing controls. */
.brikk-pattern.brikk-midcta > *,
.brikk-pattern .brikk-midcta__ctas > * {
    margin-block-start: 0;
}


/* Pattern: patterns/midcta.php. Hidden above 640px BY DESIGN — see the pattern's
   docblock. There is no editor control for "hide above a breakpoint", so this is
   necessarily CSS. */

.brikk-pattern.brikk-midcta {
    display: none;
}

.brikk-pattern .brikk-midcta__ctas {
    display: flex;
    flex-wrap: wrap;
    /* 10px + a 28px bottom margin: the A/B band inherits both from the hero's
       .brikk-hero__ctas rule, and they are what it renders. */
    gap: 10px;
    margin-bottom: 28px;
}

.brikk-pattern .brikk-midcta__ctas > * {
    margin: 0;
}

@media (max-width: 640px) {
    .brikk-pattern.brikk-midcta {
        display: block;
        padding-top: var(--wp--preset--spacing--1);
        padding-bottom: var(--wp--preset--spacing--2);
    }

    /* Matches the hero's ≤640 CTA treatment: full-width stacked buttons. The
       hero's own rule cannot be reused — it is scoped to .brikk-hero__ctas, and
       sharing that class would drag the hero's other breakpoints along. */
    .brikk-pattern .brikk-midcta__ctas > * {
        flex: 1 1 100%;
    }

    .brikk-pattern .brikk-midcta__ctas .brikk-btn {
        display: flex;
        width: 100%;
        justify-content: center;
        /* The A/B band reuses .brikk-hero__ctas, so it also picks up that rule's
           ≤640 button padding — 1px taller top and bottom than the base .brikk-btn. */
        padding: 18px 22px 15px;
    }
}


/* --- marketing ------------------------------------------------------------ */

/* ⚠️ CORE'S DEFAULT BLOCK GAP. theme.json enables spacing.blockGap, so core's
   core-block-supports CSS (printed in the FOOTER, at (0,1,0)) gives every layout
   container `> * + * { margin-block-start: 24px }`. These containers space their
   children with CSS grid/flex `gap` or with explicit margins, so that 24px lands
   ON TOP and every one of them grew. Zeroed here rather than with a blockGap
   attribute on the pattern, so the fix cannot be lost by an editor tweaking the
   section's spacing controls. */
.brikk-pattern .brikk-marketing__grid > *,
.brikk-pattern .brikk-marketing__list > *,
.brikk-pattern .brikk-marketing__item > *,
.brikk-pattern .brikk-marketing__item-body > *,
.brikk-pattern .brikk-marketing__media > * {
    margin-block-start: 0;
}


/* Pattern: patterns/marketing.php + [brikk-marketing-mockup].
   Two columns: an editable numbered list, and a decorative pair of device
   mock-ups pinned inside a positioned media column.

   The .brikk-marketing* and .brikk-mock* selectors MUST stay marker-scoped —
   the live A/B landing page uses every one of these class names and landing.css
   loads first at (0,2,0), so an unmarked rule here would tie and win. */

.brikk-pattern.brikk-marketing {
    padding-top: var(--wp--preset--spacing--9);
    padding-bottom: var(--wp--preset--spacing--9);
}

.brikk-pattern .brikk-marketing__grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    /* 20px, not the 24px spacing--5 token — the A/B's own value. */
    gap: 20px;
    align-items: center;
}

.brikk-pattern .brikk-marketing__copy > .brikk-eyebrow {
    display: block;
    margin: 0 0 22px;
}

.brikk-pattern .brikk-marketing__title {
    margin: 0 0 22px;
    color: var(--wp--preset--color--dark);
    font-family: var(--wp--preset--font-family--serif);
    font-size: calc(clamp(30px, 3.4vw, 46px) * var(--brikk-heading-scale, 1));
    font-weight: 500;
    line-height: 1.1;
    letter-spacing: .005em;
    text-wrap: balance;
}

.brikk-pattern .brikk-marketing__lead {
    max-width: 620px;
    margin: 0 0 36px;
    color: var(--wp--preset--color--muted);
    font-size: var(--wp--preset--font-size--body);
    line-height: 1.7;
    opacity: .85;
}

/* --- the numbered list ---------------------------------------------------- */

.brikk-pattern .brikk-marketing__list {
    max-width: 620px;
    padding-top: var(--wp--preset--spacing--6);
    border-top: 1px solid var(--wp--preset--color--line);
}

/* Each item is number + body. A grid rather than flex so the description's
   wrapped lines align with its heading instead of with the numeral. */
.brikk-pattern .brikk-marketing__item {
    display: grid;
    grid-template-columns: 64px 1fr;
    gap: 14px;
    align-items: start;
    padding: 22px 0;
}

.brikk-pattern .brikk-marketing__item + .brikk-marketing__item {
    border-top: 1px solid var(--wp--preset--color--line);
}

.brikk-pattern .brikk-marketing__num {
    margin: 0;
    color: var(--wp--preset--color--purple);
    font-family: var(--wp--preset--font-family--serif);
    font-size: 30px;
    font-style: italic;
    font-weight: 500;
    line-height: 1;
}

.brikk-pattern .brikk-marketing__item-title {
    margin: 0 0 12px;
    color: var(--wp--preset--color--dark);
    font-family: var(--wp--preset--font-family--serif);
    font-size: calc(26px * var(--brikk-heading-scale, 1));
    font-weight: 500;
    line-height: var(--wp--custom--lh-heading);
    letter-spacing: var(--wp--custom--ls-heading);
}

.brikk-pattern .brikk-marketing__item-desc {
    max-width: 500px;
    margin: 0;
    color: var(--wp--preset--color--muted);
    font-size: 14px;
    line-height: 1.5;
    opacity: .8;
}

/* --- the mock-ups --------------------------------------------------------- */

/* The media column is a positioning context with a reserved height; both cards
   are absolutely placed inside it and overlap. */
.brikk-pattern .brikk-marketing__media {
    position: relative;
    min-height: 640px;
}

/* These cards deliberately do NOT use the design's tokens for their surface and
   ink: they imitate Instagram's and a portal's own chrome, so their greys are
   those products' greys, not Brikk's. Keeping them literal is the point — a
   token change must not repaint a screenshot-like mock-up. */
.brikk-pattern .brikk-mock {
    background: #fff;
    border-radius: 4px;
    box-shadow: 0 30px 60px -25px rgba(20, 20, 30, .25), 0 8px 24px -12px rgba(20, 20, 30, .12);
}

.brikk-pattern .brikk-mock--ig {
    position: absolute;
    top: 0;
    right: 0;
    z-index: 2;
    width: 380px;
    max-width: 100%;
    color: #1a1a1a;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 13px;
}

.brikk-pattern .brikk-mock__head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
}

.brikk-pattern .brikk-mock__avatar {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: var(--wp--custom--radius-pill);
    background-color: #472cfa;
    background-image: url(../img/marketing/ig-avatar.webp);
    background-position: center;
    background-size: 70%;
    background-repeat: no-repeat;
    color: #fff;
    font-size: 14px;
    font-weight: 600;
}

.brikk-pattern .brikk-mock__head-text {
    flex: 1;
    min-width: 0;
    line-height: 1.2;
}

/* ⚠️ 1.4, not the 1.2 inherited from .brikk-mock__head-text. Both stylesheets
   put 1.2 on the parent and declare nothing on these two children — but
   landing.css's `.brikk-ab-page * { line-height: 1.4 }` matches the CHILDREN
   directly, and a direct match beats inheritance, so the A/B renders 1.4. */
.brikk-pattern .brikk-mock__name {
    font-size: 13px;
    font-weight: 600;
    line-height: var(--wp--custom--lh-base);
}

.brikk-pattern .brikk-mock__sub {
    margin-top: 2px;
    color: #6b6b6b;
    font-size: 11.5px;
    line-height: var(--wp--custom--lh-base);
}

.brikk-pattern .brikk-mock__dots {
    color: #1a1a1a;
    font-size: 18px;
    line-height: 1;
    letter-spacing: 1px;
}

.brikk-pattern .brikk-mock__photo {
    overflow: hidden;
    aspect-ratio: 4 / 3;
    background: #eee;
}

.brikk-pattern .brikk-mock__photo img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.brikk-pattern .brikk-mock__seebolig {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 16px;
    border-bottom: 1px solid #efefef;
    background: #f4f4f4;
    color: #1a1a1a;
    font-size: 13px;
    font-weight: 500;
}

.brikk-pattern .brikk-mock__seebolig svg {
    width: 14px;
    height: 14px;
}

.brikk-pattern .brikk-mock__actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 14px 4px;
}

.brikk-pattern .brikk-mock__icons {
    display: inline-flex;
    gap: 14px;
}

.brikk-pattern .brikk-mock__actions svg {
    width: 22px;
    height: 22px;
    color: #1a1a1a;
}

.brikk-pattern .brikk-mock__likes {
    padding: 4px 14px 2px;
    font-size: 13px;
    font-weight: 600;
}

.brikk-pattern .brikk-mock__caption {
    margin: 0;
    padding: 4px 14px 2px;
    color: #1a1a1a;
    font-size: 13px;
    line-height: var(--wp--custom--lh-base);
}

.brikk-pattern .brikk-mock__caption strong {
    font-weight: 600;
}

.brikk-pattern .brikk-mock__caption .brikk-mock__more {
    color: #6b6b6b;
}

.brikk-pattern .brikk-mock__time {
    padding: 4px 14px 14px;
    color: #9a9a9a;
    font-size: 10.5px;
    letter-spacing: .04em;
    text-transform: uppercase;
}

.brikk-pattern .brikk-mock--listing {
    position: absolute;
    left: 70px;
    bottom: 30px;
    z-index: 1;
    overflow: hidden;
    width: 360px;
    max-width: 100%;
    padding: 0;
    transform: rotate(-3deg);
    transform-origin: center bottom;
    font-family: var(--wp--preset--font-family--sans);
}

.brikk-pattern .brikk-mock__listing-head {
    padding: 18px 20px 48px;
    background: #f7d9dc;
}

.brikk-pattern .brikk-mock__badge {
    display: inline-block;
    padding: 10px 18px;
    background: #fff;
    color: #1a1a1a;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .18em;
    text-transform: uppercase;
}

.brikk-pattern .brikk-mock__listing-body {
    padding: 24px 30px;
}

.brikk-pattern .brikk-mock__price {
    margin-bottom: 10px;
    color: #1a1a1a;
    font-family: var(--wp--preset--font-family--serif);
    font-size: 36px;
    font-weight: 500;
    line-height: 1;
}

.brikk-pattern .brikk-mock__price-label {
    margin-bottom: 22px;
    color: #6b6b6b;
    font-size: 10.5px;
    letter-spacing: .24em;
    text-transform: uppercase;
}

.brikk-pattern .brikk-mock__specs {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 10px;
    margin: 0 0 18px;
    padding: 16px 0;
    border-top: 1px solid #efefef;
    list-style: none;
}

.brikk-pattern .brikk-mock__specs li {
    display: flex;
    flex-direction: column;
    color: #6b6b6b;
    font-size: 11px;
}

.brikk-pattern .brikk-mock__specs strong {
    display: block;
    margin-top: 2px;
    color: #1a1a1a;
    font-size: 13px;
    font-weight: 600;
}

.brikk-pattern .brikk-mock__footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.brikk-pattern .brikk-mock__cta {
    padding: 9px 14px;
    background: var(--wp--preset--color--purple);
    color: var(--wp--custom--on-accent);
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: var(--wp--custom--ls-ui);
    text-transform: uppercase;
}

.brikk-pattern .brikk-mock__contact {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: #6b6b6b;
    font-size: 10.5px;
    letter-spacing: .02em;
}

.brikk-pattern .brikk-mock__brikk {
    display: inline-block;
    width: auto;
    height: 12px;
    margin-top: -5px;
}

@media (min-width: 1500px) {
    .brikk-pattern .brikk-marketing__grid {
        grid-template-columns: 0.9fr 1.1fr;
        gap: 0;
    }

    .brikk-pattern .brikk-mock--ig {
        right: 120px;
    }

    .brikk-pattern .brikk-mock--listing {
        left: 30px;
    }
}

@media (max-width: 1024.98px) {
    .brikk-pattern.brikk-marketing {
        padding-top: 72px;
        padding-bottom: 72px;
    }

    .brikk-pattern .brikk-marketing__grid {
        grid-template-columns: 1fr;
        gap: var(--wp--preset--spacing--7);
    }

    /* Stacked: the cards leave their absolute positions and become two centred
       cards in a column. */
    .brikk-pattern .brikk-marketing__media {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 28px;
        min-height: 0;
        padding: 16px 0 24px;
    }

    .brikk-pattern .brikk-marketing__media .brikk-mock--ig,
    .brikk-pattern .brikk-marketing__media .brikk-mock--listing {
        position: static;
        width: 380px;
        max-width: 100%;
        transform: none;
    }
}

@media (max-width: 768px) {
    .brikk-pattern .brikk-marketing__title {
        font-size: calc(clamp(28px, 5.2vw, 38px) * var(--brikk-heading-scale, 1));
    }
}

@media (max-width: 640px) {
    .brikk-pattern.brikk-marketing {
        padding-top: 56px;
        padding-bottom: 56px;
    }

    .brikk-pattern .brikk-marketing__lead {
        margin-bottom: 28px;
        font-size: 14.5px;
        line-height: 1.65;
    }

    .brikk-pattern .brikk-marketing__list {
        padding-top: var(--wp--preset--spacing--5);
    }

    .brikk-pattern .brikk-marketing__item {
        grid-template-columns: 48px 1fr;
        gap: 10px;
        padding: 18px 0;
    }

    .brikk-pattern .brikk-marketing__num {
        font-size: 26px;
    }

    .brikk-pattern .brikk-marketing__item-title {
        margin-bottom: 8px;
        font-size: calc(21px * var(--brikk-heading-scale, 1));
        line-height: 1.2;
    }

    .brikk-pattern .brikk-marketing__item-desc {
        font-size: 13.5px;
        line-height: 1.55;
    }

    .brikk-pattern .brikk-marketing__media {
        gap: 20px;
        padding: 8px 0;
    }

    .brikk-pattern .brikk-mock--ig,
    .brikk-pattern .brikk-mock--listing {
        width: 320px;
        max-width: 100%;
    }
}

@media (max-width: 450px) {
    .brikk-pattern .brikk-marketing__media .brikk-mock--ig,
    .brikk-pattern .brikk-marketing__media .brikk-mock--listing {
        width: 100%;
        max-width: 100%;
    }

    /* Below 450px the rotated listing card cannot sit beside anything without
       overflowing, and stacked it just repeats the IG card's message. */
    .brikk-pattern .brikk-marketing__media .brikk-mock--listing {
        display: none;
    }
}


/* --- results (pattern additions only) ------------------------------------- */

/* ⚠️ CORE'S DEFAULT BLOCK GAP. theme.json enables spacing.blockGap, so core's
   core-block-supports CSS (printed in the FOOTER, at (0,1,0)) gives every layout
   container `> * + * { margin-block-start: 24px }`. These containers space their
   children with CSS grid/flex `gap` or with explicit margins, so that 24px lands
   ON TOP and every one of them grew. Zeroed here rather than with a blockGap
   attribute on the pattern, so the fix cannot be lost by an editor tweaking the
   section's spacing controls. */
.brikk-pattern .brikk-results__inner > *,
.brikk-pattern .brikk-results__head > *,
.brikk-pattern .brikk-results__stats > * {
    margin-block-start: 0;
}


/* Pattern: patterns/results.php. §12.3d ALREADY styles this whole section — it
   was written for the [brikk-sold-homes] shortcode and the pattern reuses it
   verbatim, so there is deliberately almost nothing here. Do not re-port §12.3d.

   Only two things are needed, both consequences of the head/stats being core
   blocks rather than the A/B's hand-written divs:

   1. §12.3d styles `.brikk-results__head .brikk-eyebrow` as a block-level span.
      As a core PARAGRAPH the eyebrow also inherits §4's paragraph margin, which
      would push the heading down by a line. Zeroed here.
   2. Core's block-layout CSS (core-block-supports) prints in the FOOTER at
      (0,1,0) and applies `> * { margin-block-start: 0 }` to layout containers.
      The stat value/label margins in §12.3d are safe from it (they are set on
      the elements themselves), but the head's paragraph margins are not — hence
      the explicit reset rather than relying on the block gap. */

.brikk-pattern .brikk-results__head > .brikk-eyebrow {
    margin-top: 0;
}

/* The stat value and label are paragraphs here, not divs as in the A/B markup.
   §12.3d gives the value a bottom margin and the label none; §4's paragraph
   margins would add a top margin to both. */
.brikk-pattern .brikk-results__stat > p {
    margin-top: 0;
}

.brikk-pattern .brikk-results__stat > p:last-child {
    margin-bottom: 0;
}

/* ⚠️ ...AND IT ZEROES margin-block-END TOO. Core's layout CSS emits
   `> * { margin-block-start: 0; margin-block-end: 0 }` on every layout
   container, at (0,1,0) but printed in the FOOTER — so it beats same-specificity
   theme rules on ORDER. That silently ate the head's bottom margins (which had
   been coming from the block gap) and, in the results section, §12.3d's own
   heading/stat-value margins. They have to be restated at (0,2,0) here. */
.brikk-pattern .brikk-results__heading {
    margin-bottom: 22px;
}

/* ⚠️ MUST stay inside a min-width query. §12.3d steps this to 12px at ≤640;
   an unscoped rule here overrode that step and put a constant +24px (4 stats ×
   6px) on every phone width. */
@media (min-width: 640.02px) {
    .brikk-pattern .brikk-results__stat-value {
        margin-bottom: 18px;
    }
}

/* ...and the ≤640 step needs restating for the same reason — core eats the
   margin at every width, so scoping the desktop rule alone left mobile at 0. */
@media (max-width: 640px) {
    .brikk-pattern .brikk-results__stat-value {
        margin-bottom: var(--wp--preset--spacing--3);
    }
}


/* --- all-in-one (Brikk Hub) ----------------------------------------------- */

/* ⚠️ CORE'S DEFAULT BLOCK GAP. theme.json enables spacing.blockGap, so core's
   core-block-supports CSS (printed in the FOOTER, at (0,1,0)) gives every layout
   container `> * + * { margin-block-start: 24px }`. These containers space their
   children with CSS grid/flex `gap` or with explicit margins, so that 24px lands
   ON TOP and every one of them grew. Zeroed here rather than with a blockGap
   attribute on the pattern, so the fix cannot be lost by an editor tweaking the
   section's spacing controls. */
.brikk-pattern .brikk-allinone__grid > *,
.brikk-pattern .brikk-allinone__copy > *,
.brikk-pattern .brikk-allinone__media > * {
    margin-block-start: 0;
}


/* Pattern: patterns/allinone.php + [brikk-hub-overlays].
   All .brikk-allinone* selectors are marker-scoped — the live A/B landing page
   uses every one of them and landing.css loads first at (0,2,0).

   The three overlay cards keep the A/B's literal greys and shadows rather than
   design tokens: they imitate an application UI floating over a screenshot, so
   their palette belongs to that illustration, not to the site's surfaces. */

/* Asymmetric on purpose: the testimonial band above already supplies air.
   landing.css is `padding: 60px 0 100px` — literal values, not the 64/96 tokens
   that were used here first (that cost 4px top and 4px bottom). */
.brikk-pattern.brikk-allinone {
    padding-top: 60px;
    padding-bottom: 100px;
}

.brikk-pattern .brikk-allinone__grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--wp--preset--spacing--8);
    align-items: center;
}

.brikk-pattern .brikk-allinone__copy > .brikk-eyebrow {
    display: block;
    margin: 0 0 18px;
}

.brikk-pattern .brikk-allinone__heading {
    max-width: 400px;
    margin: 0 0 20px;
    color: var(--wp--preset--color--dark);
    font-size: clamp(30px, 3.4vw, 50px);
    font-weight: 500;
    line-height: 1.1;
    letter-spacing: -0.015em;
}

.brikk-pattern .brikk-allinone__lead {
    max-width: 460px;
    margin: 0 0 28px;
    color: var(--wp--preset--color--muted);
    font-size: var(--wp--preset--font-size--body);
    line-height: 1.7;
    opacity: .8;
}

/* The A/B list is 16px muted at .8 opacity — bigger and lighter than the shared
   .brikk-check-list default (14px --dark), so the section overrides it. */
.brikk-pattern .brikk-allinone__list {
    margin: 0 0 var(--wp--preset--spacing--6);
}

/* ⚠️ The indent and the leading BOTH matter here, because they decide where the
   copy wraps. landing.css lays each item out as `display: flex; gap: 12px` with
   an 18px check mark = a 30px indent, and its global `.brikk-ab-page *` reset
   forces line-height 1.4. The shared .brikk-check-list default is a 28px indent
   at 1.5 — 2px wider text and taller lines — which was enough to keep an item on
   one line that the design wraps onto two. */
.brikk-pattern .brikk-allinone__list li {
    padding-left: 30px;
    color: var(--wp--preset--color--muted);
    font-size: var(--wp--preset--font-size--body);
    line-height: var(--wp--custom--lh-base);
    opacity: .8;
}

.brikk-pattern .brikk-allinone__list li + li {
    margin-top: var(--wp--preset--spacing--3);
}

.brikk-pattern .brikk-allinone__action {
    margin: 0;
}

/* --- the screenshot and its overlays -------------------------------------- */

.brikk-pattern .brikk-allinone__media {
    position: relative;
    aspect-ratio: 6 / 5;
}

.brikk-pattern .brikk-allinone__shot,
.brikk-pattern .brikk-allinone__shot img {
    display: block;
    width: 100%;
    height: 100%;
    margin: 0;
    object-fit: cover;
}

/* Notification pill */
.brikk-pattern .brikk-allinone__notif {
    position: absolute;
    top: -22px;
    left: 20%;
    z-index: 3;
    display: inline-flex;
    align-items: center;
    gap: 12px;
    padding: 11px 18px 10px 14px;
    transform: translateX(-50%);
    background: var(--wp--preset--color--card);
    box-shadow: 0 18px 40px -18px rgba(20, 14, 50, .28), 0 4px 12px rgba(20, 14, 50, .07);
    white-space: nowrap;
}

.brikk-pattern .brikk-allinone__notif-bell {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: #4f4858;
    line-height: 0;
}

.brikk-pattern .brikk-allinone__notif-dot {
    position: absolute;
    top: -2px;
    right: -2px;
    width: 7px;
    height: 7px;
    border: 1.5px solid var(--wp--preset--color--card);
    border-radius: 50%;
    background: #e54848;
}

.brikk-pattern .brikk-allinone__notif-text {
    color: var(--wp--preset--color--dark);
    font-family: var(--wp--preset--font-family--sans);
    font-size: 13px;
    line-height: 1;
}

.brikk-pattern .brikk-allinone__notif-text strong {
    font-weight: 600;
}

/* Visits bar chart */
.brikk-pattern .brikk-allinone__rating {
    position: absolute;
    top: 24px;
    right: 24px;
    z-index: 2;
    display: flex;
    flex-direction: column;
    gap: 14px;
    width: 250px;
    padding: 18px 20px;
    background: var(--wp--preset--color--card);
    box-shadow: 0 18px 40px -18px rgba(20, 14, 50, .28), 0 4px 12px rgba(20, 14, 50, .07);
}

.brikk-pattern .brikk-allinone__rating-label {
    color: #8a8294;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 12px;
    font-weight: 500;
}

.brikk-pattern .brikk-allinone__rating-chart {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 12px;
    height: 140px;
    padding: 0 6px;
}

.brikk-pattern .brikk-allinone__rating-col {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    gap: 6px;
    height: 100%;
}

.brikk-pattern .brikk-allinone__rating-value {
    color: var(--wp--preset--color--dark);
    font-family: var(--wp--preset--font-family--sans);
    font-size: 14px;
    font-weight: 600;
    line-height: 1;
}

/* Bar heights are an illustration of a shape, not a data series — there is
   nothing to drive them from, so they are :nth-child like the A/B. */
.brikk-pattern .brikk-allinone__rating-bar {
    display: block;
    width: 100%;
    max-width: 42px;
    background: #d4c8f5;
}

.brikk-pattern .brikk-allinone__rating-col:nth-child(1) .brikk-allinone__rating-bar { height: 54px; }
.brikk-pattern .brikk-allinone__rating-col:nth-child(2) .brikk-allinone__rating-bar { height: 94px; }
.brikk-pattern .brikk-allinone__rating-col:nth-child(3) .brikk-allinone__rating-bar { height: 61px; }

.brikk-pattern .brikk-allinone__rating-col.is-active .brikk-allinone__rating-bar {
    background: var(--wp--preset--color--purple);
}

.brikk-pattern .brikk-allinone__rating-month {
    margin-top: 2px;
    color: #b3acba;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 10.5px;
    font-weight: 500;
    letter-spacing: .12em;
}

/* Buyer-feedback card */
.brikk-pattern .brikk-allinone__feedback {
    position: absolute;
    bottom: -36px;
    left: -36px;
    z-index: 2;
    width: 64%;
    max-width: 380px;
    padding: 28px 30px 26px;
    background: var(--wp--preset--color--card);
    box-shadow: 0 24px 50px -22px rgba(20, 14, 50, .30), 0 6px 16px rgba(20, 14, 50, .07);
}

.brikk-pattern .brikk-allinone__feedback-eyebrow {
    margin-bottom: var(--wp--preset--spacing--5);
    color: #8a8294;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 10px;
    font-weight: 500;
    letter-spacing: .26em;
    text-transform: uppercase;
}

.brikk-pattern .brikk-allinone__feedback-list {
    display: flex;
    flex-direction: column;
    gap: 18px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.brikk-pattern .brikk-allinone__feedback-list li {
    display: grid;
    grid-template-columns: 1fr auto auto;
    align-items: center;
    gap: var(--wp--preset--spacing--4);
}

.brikk-pattern .brikk-allinone__feedback-label {
    color: #2b2333;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 13px;
    line-height: 1.3;
}

.brikk-pattern .brikk-allinone__feedback-stars {
    display: inline-flex;
    align-items: center;
    gap: 2px;
}

.brikk-pattern .brikk-allinone__feedback-star {
    display: block;
    width: 12px;
    height: 12px;
    color: var(--wp--custom--gold);
}

.brikk-pattern .brikk-allinone__feedback-star.is-empty {
    color: #d7d3df;
}

.brikk-pattern .brikk-allinone__feedback-score {
    min-width: 24px;
    color: var(--wp--preset--color--dark);
    font-family: var(--wp--preset--font-family--sans);
    font-size: 13px;
    font-weight: 500;
    text-align: right;
}

.brikk-pattern .brikk-allinone__feedback-total {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: var(--wp--preset--spacing--5);
    padding-top: 22px;
    border-top: 1px solid var(--wp--preset--color--line);
}

.brikk-pattern .brikk-allinone__feedback-total-label {
    color: #2b2333;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 13px;
}

.brikk-pattern .brikk-allinone__feedback-total-value {
    color: var(--wp--preset--color--dark);
    font-family: var(--wp--preset--font-family--serif);
    font-size: 38px;
    font-weight: 500;
    line-height: 1;
}

@media (max-width: 1500px) {
    .brikk-pattern .brikk-allinone__rating {
        width: 160px;
        gap: 8px;
        padding: 12px 14px;
    }

    .brikk-pattern .brikk-allinone__rating-chart {
        gap: 8px;
        height: 84px;
        padding: 0 4px;
    }

    .brikk-pattern .brikk-allinone__rating-col {
        gap: 4px;
    }

    .brikk-pattern .brikk-allinone__rating-value {
        font-size: 10px;
    }

    .brikk-pattern .brikk-allinone__rating-bar {
        max-width: 25px;
    }

    .brikk-pattern .brikk-allinone__rating-col:nth-child(1) .brikk-allinone__rating-bar { height: 32px; }
    .brikk-pattern .brikk-allinone__rating-col:nth-child(2) .brikk-allinone__rating-bar { height: 56px; }
    .brikk-pattern .brikk-allinone__rating-col:nth-child(3) .brikk-allinone__rating-bar { height: 37px; }
}

@media (max-width: 1300px) {
    .brikk-pattern .brikk-allinone__feedback {
        transform: scale(.7);
        transform-origin: bottom left;
    }
}

@media (max-width: 1024.98px) {
    .brikk-pattern.brikk-allinone {
        padding-top: 72px;
        padding-bottom: 72px;
    }

    .brikk-pattern .brikk-allinone__grid {
        grid-template-columns: 1fr;
        gap: var(--wp--preset--spacing--7);
    }

    .brikk-pattern .brikk-allinone__media {
        max-width: 640px;
        margin-inline: auto;
        aspect-ratio: 4 / 3;
    }

    .brikk-pattern .brikk-allinone__rating {
        top: 16px;
        right: 16px;
    }

    .brikk-pattern .brikk-allinone__feedback {
        left: 16px;
        bottom: 16px;
        width: 58%;
        max-width: 340px;
    }
}

@media (max-width: 768px) {
    .brikk-pattern .brikk-allinone__heading {
        max-width: none;
        font-size: clamp(28px, 5.4vw, 40px);
    }
}

@media (max-width: 640px) {
    .brikk-pattern.brikk-allinone {
        padding-top: 56px;
        padding-bottom: 56px;
    }

    .brikk-pattern .brikk-allinone__lead {
        font-size: 14.5px;
        line-height: 1.65;
    }

    .brikk-pattern .brikk-allinone__list li {
        font-size: 14.5px;
    }

    .brikk-pattern .brikk-allinone__media {
        max-width: 100%;
        aspect-ratio: 4 / 3;
    }

    .brikk-pattern .brikk-allinone__rating {
        top: 12px;
        right: 12px;
    }

    .brikk-pattern .brikk-allinone__feedback {
        left: 12px;
        bottom: 12px;
        width: 100%;
        max-width: 320px;
        padding: 20px 22px 18px;
    }

    .brikk-pattern .brikk-allinone__feedback-eyebrow {
        margin-bottom: var(--wp--preset--spacing--4);
        font-size: 9.5px;
    }

    .brikk-pattern .brikk-allinone__feedback-list {
        gap: var(--wp--preset--spacing--3);
    }

    .brikk-pattern .brikk-allinone__feedback-label,
    .brikk-pattern .brikk-allinone__feedback-score,
    .brikk-pattern .brikk-allinone__feedback-total-label {
        font-size: 12px;
    }

    .brikk-pattern .brikk-allinone__feedback-total {
        margin-top: var(--wp--preset--spacing--4);
        padding-top: 14px;
    }

    .brikk-pattern .brikk-allinone__feedback-total-value {
        font-size: 30px;
    }

    .brikk-pattern .brikk-allinone__notif {
        top: -16px;
        gap: 10px;
        padding: 9px 14px 8px 12px;
    }

    .brikk-pattern .brikk-allinone__notif-text {
        font-size: 12px;
    }
}

@media (max-width: 500px) {
    /* Two cards over a phone-width screenshot is a pile — the chart goes. */
    .brikk-pattern .brikk-allinone__rating {
        display: none;
    }

    .brikk-pattern .brikk-allinone__feedback {
        left: auto;
        right: 16px;
        bottom: 16px;
        transform: scale(.77);
        transform-origin: bottom right;
    }
}

@media (max-width: 420px) {
    .brikk-pattern .brikk-allinone__notif {
        top: -18px;
        left: 12px;
        right: auto;
        transform: none;
    }

    .brikk-pattern .brikk-allinone__feedback {
        top: auto;
        bottom: -60px;
        left: auto;
        right: 12px;
        width: 100%;
        max-width: 300px;
        transform: scale(.7);
        transform-origin: bottom right;
    }

    /* The feedback card hangs 60px below the screenshot at this size. */
    .brikk-pattern .brikk-allinone__media {
        margin-bottom: 40px;
    }
}


/* --- steps ---------------------------------------------------------------- */

/* ⚠️ CORE'S DEFAULT BLOCK GAP. theme.json enables spacing.blockGap, so core's
   core-block-supports CSS (printed in the FOOTER, at (0,1,0)) gives every layout
   container `> * + * { margin-block-start: 24px }`. These containers space their
   children with CSS grid/flex `gap` or with explicit margins, so that 24px lands
   ON TOP and every one of them grew. Zeroed here rather than with a blockGap
   attribute on the pattern, so the fix cannot be lost by an editor tweaking the
   section's spacing controls. */
.brikk-pattern.brikk-steps > *,
.brikk-pattern .brikk-steps__grid > *,
.brikk-pattern .brikk-step > * {
    margin-block-start: 0;
}


/* Pattern: patterns/steps.php. The six cards are a CSS grid rather than
   core/columns because the design steps 3 → 2 → 1 columns and core's Columns
   block cannot express that ladder (it forces flex-wrap:nowrap above 782px and
   only stacks below it). See the pattern docblock.

   ⚠️ The A/B section padding is 100px, not the design system's 96px section
   rhythm. 96px is used here so the front page's vertical rhythm is uniform —
   DESIGN.md §9 rules the rhythm canonical where landing.css deviates by a few
   px. Everything else is 1:1. */

/* 100px, not the design system's 96px section rhythm: this is one of the
       two sections where landing.css uses 100 and the difference is visible in
       a full-page comparison. Matching the A/B exactly (DESIGN.md §9 prefers 96
       — revisit if the rhythm is ever unified). */
.brikk-pattern.brikk-steps {
    padding-top: 100px;
    padding-bottom: 100px;
}

.brikk-pattern .brikk-steps__head {
    margin-bottom: 56px;
}

.brikk-pattern .brikk-steps__heading {
    margin: 0;
    font-size: clamp(30px, 3.4vw, 42px);
    font-weight: 500;
    line-height: 1.1;
}

.brikk-pattern .brikk-steps__lead {
    margin: 0;
    color: var(--wp--preset--color--muted);
    font-size: var(--wp--preset--font-size--body);
    /* 1.4, not §4's 1.6 for paragraphs: landing.css forces line-height 1.4 on
       every element via `.brikk-ab-page *`, so 1.4 is what the design RENDERS.
       ⚠️ Stated HERE, in the base rule — as a standalone rule appended after the
       ≤640 block it out-ordered that block's 1.6 step and won at every width. */
    line-height: var(--wp--custom--lh-base);
    /* The A/B sets opacity .8 on top of --muted. Folded into a flat colour: an
       opacity on a text block also fades any inline link or <strong> inside it,
       which is not the intent. */
    opacity: .8;
}

/* Hairline grid: top+left on the container, right+bottom on every cell. Collapses
   to single 1px lines with no doubling and no :nth-child arithmetic, and it stays
   correct when the column count changes at each breakpoint. */
.brikk-pattern .brikk-steps__grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0;
    max-width: 1350px;
    margin-inline: auto;
    border-top: 1px solid var(--wp--preset--color--line);
    border-left: 1px solid var(--wp--preset--color--line);
    background: var(--wp--preset--color--card);
    overflow: hidden;
}

.brikk-pattern .brikk-step {
    padding: 36px;
    border-right: 1px solid var(--wp--preset--color--line);
    border-bottom: 1px solid var(--wp--preset--color--line);
    background: var(--wp--preset--color--card);
}

.brikk-pattern .brikk-step__num {
    margin: 0 0 10px;
    color: var(--wp--preset--color--purple);
    font-family: var(--wp--preset--font-family--serif);
    font-size: 30px;
    font-style: italic;
    line-height: 1;
}

.brikk-pattern .brikk-step__title {
    margin: 0 0 15px;
    color: var(--wp--preset--color--dark);
    font-family: var(--wp--preset--font-family--serif);
    font-size: 26px;
    font-weight: 500;
    line-height: var(--wp--custom--lh-heading);
    letter-spacing: var(--wp--custom--ls-heading);
}

.brikk-pattern .brikk-step__desc {
    margin: 0;
    color: var(--wp--preset--color--muted);
    font-size: 14px;
    line-height: 1.5;
    opacity: .8;
}

@media (max-width: 1024.98px) {
    .brikk-pattern.brikk-steps {
        padding-top: 72px;
        padding-bottom: 72px;
    }

    .brikk-pattern .brikk-steps__grid {
        grid-template-columns: repeat(2, 1fr);
    }

    .brikk-pattern .brikk-step {
        padding: 30px;
    }
}

@media (max-width: 768px) {
    .brikk-pattern .brikk-steps__heading {
        font-size: clamp(28px, 5.2vw, 38px);
    }
}

@media (max-width: 640px) {
    .brikk-pattern.brikk-steps {
        padding-top: 56px;
        padding-bottom: 56px;
    }

    .brikk-pattern .brikk-steps__head {
        margin-bottom: 40px;
    }

    .brikk-pattern .brikk-steps__lead {
        font-size: 14.5px;
        line-height: var(--wp--custom--lh-copy);
    }

    /* One column, with the A/B's 20px gap between cards. */
    .brikk-pattern .brikk-steps__grid {
        grid-template-columns: 1fr;
        gap: 20px;
    }

    .brikk-pattern .brikk-step {
        padding: 26px;
    }

    .brikk-pattern .brikk-step__num {
        font-size: 26px;
    }

    .brikk-pattern .brikk-step__title {
        margin-bottom: 12px;
        font-size: 21px;
    }

    .brikk-pattern .brikk-step__desc {
        font-size: 13.5px;
        line-height: var(--wp--custom--lh-copy);
    }
}

/* ⚠️ ...AND IT ZEROES margin-block-END TOO. Core's layout CSS emits
   `> * { margin-block-start: 0; margin-block-end: 0 }` on every layout
   container, at (0,1,0) but printed in the FOOTER — so it beats same-specificity
   theme rules on ORDER. That silently ate the head's bottom margins (which had
   been coming from the block gap) and, in the results section, §12.3d's own
   heading/stat-value margins. They have to be restated at (0,2,0) here. */
.brikk-pattern .brikk-steps__head > .brikk-eyebrow {
    margin-bottom: var(--wp--preset--spacing--4);
}

.brikk-pattern .brikk-steps__heading {
    margin-bottom: var(--wp--preset--spacing--4);
}


/* --- FAQ ------------------------------------------------------------------ */

/* ⚠️ CORE'S DEFAULT BLOCK GAP. theme.json enables spacing.blockGap, so core's
   core-block-supports CSS (printed in the FOOTER, at (0,1,0)) gives every layout
   container `> * + * { margin-block-start: 24px }`. These containers space their
   children with CSS grid/flex `gap` or with explicit margins, so that 24px lands
   ON TOP and every one of them grew. Zeroed here rather than with a blockGap
   attribute on the pattern, so the fix cannot be lost by an editor tweaking the
   section's spacing controls. */
.brikk-pattern.brikk-faq > *,
.brikk-pattern .brikk-faq__list > *,
.brikk-pattern .brikk-faq__list .wp-block-accordion-item > * {
    margin-block-start: 0;
}


/* Pattern: patterns/faq.php — the NATIVE core/accordion block skinned to the A/B
   design. These rules therefore target core's own class names, which no A/B page
   contains (it has no block markup at all), so they are safe unmarked; the
   .brikk-faq* selectors ARE marker-scoped because the live A/B FAQ uses them. */

/* 100px, not the design system's 96px section rhythm: this is one of the
       two sections where landing.css uses 100 and the difference is visible in
       a full-page comparison. Matching the A/B exactly (DESIGN.md §9 prefers 96
       — revisit if the rhythm is ever unified). */
.brikk-pattern.brikk-faq {
    padding-top: 100px;
    padding-bottom: 100px;
}

.brikk-pattern .brikk-faq__head {
    margin-bottom: 56px;
}

.brikk-pattern .brikk-faq__heading {
    margin: 0;
    font-size: calc(clamp(30px, 3.4vw, 42px) * var(--brikk-heading-scale, 1));
    font-weight: 500;
    line-height: 1.1;
}

.brikk-pattern .brikk-faq__list {
    max-width: 840px;
    margin-inline: auto;
}

/* --- the accordion itself ------------------------------------------------- */

/* Hairline per item, plus one on top of the first — the A/B's rule, expressed on
   the block's own element. */
.brikk-pattern .brikk-faq__list .wp-block-accordion-item {
    border-bottom: 1px solid var(--wp--preset--color--line);
}

.brikk-pattern .brikk-faq__list .wp-block-accordion-item:first-child {
    border-top: 1px solid var(--wp--preset--color--line);
}

/* The heading is an <h3> wrapping a <button>. Core gives the button
   `padding: var(--wp--preset--spacing--20, 1em) 0` — that preset does not exist
   in this theme (the scale is 1–9), so it falls back to 1em; overridden here. */
.brikk-pattern .brikk-faq__list .wp-block-accordion-heading {
    margin: 0;
}

.brikk-pattern .brikk-faq__list .wp-block-accordion-heading__toggle {
    gap: var(--wp--preset--spacing--5);
    padding: 22px 4px;
    color: var(--wp--preset--color--dark);
    font-family: var(--wp--preset--font-family--serif);
    font-size: 24px;
    font-weight: 500;
    /* 1.4, NOT the 1.25 landing.css states for .brikk-faq__question: that rule
       is defeated by its own `.brikk-ab-page * { line-height: 1.4 }` reset, and
       33.6px is what the A/B actually renders. Matching the rendering. */
    line-height: var(--wp--custom--lh-base);
    letter-spacing: .005em;
    text-align: left;
}

/* Core underlines the title on hover. The A/B does not — matching shipped
   behaviour, the same call made for the header nav's dropdown links. */
.brikk-pattern .brikk-faq__list .wp-block-accordion-heading__toggle:hover .wp-block-accordion-heading__toggle-title {
    text-decoration: none;
}

.brikk-pattern .brikk-faq__list .wp-block-accordion-heading__toggle:focus-visible {
    outline: 2px solid var(--wp--preset--color--purple);
    outline-offset: -2px;
}

/* The icon is core's literal "+" character in a span, styled into the design's
   30px purple circle. Core already rotates it 45° on .is-open (its own rule), so
   the open state's × comes for free — only the fill and colour are added here. */
.brikk-pattern .brikk-faq__list .wp-block-accordion-heading__toggle-icon {
    flex-shrink: 0;
    width: 30px;
    height: 30px;
    border: 1px solid var(--wp--preset--color--purple);
    border-radius: var(--wp--custom--radius-pill);
    color: var(--wp--preset--color--purple);
    font-family: var(--wp--preset--font-family--sans);
    font-size: 16px;
    font-weight: 400;
    line-height: 1;
    transition: background var(--wp--custom--transition), color var(--wp--custom--transition);
}

.brikk-pattern .brikk-faq__list .wp-block-accordion-item.is-open .wp-block-accordion-heading__toggle-icon {
    background: var(--wp--preset--color--purple);
    color: var(--wp--custom--on-accent);
}

/* Core hides a collapsed panel with `[inert] { display: none }`, which cannot
   animate. Restoring the A/B's 0fr → 1fr grid expansion: the panel becomes the
   grid, its single child does the clipping. The [inert] attribute is written
   SERVER-side by the Interactivity API, so the closed state is correct on first
   paint and without JavaScript. */
.brikk-pattern .brikk-faq__list .wp-block-accordion-panel {
    display: grid;
    grid-template-rows: 1fr;
    padding: 0 4px 22px;
    transition: grid-template-rows 280ms ease, padding-bottom 280ms ease;
}

.brikk-pattern .brikk-faq__list .wp-block-accordion-panel[inert],
.brikk-pattern .brikk-faq__list .wp-block-accordion-panel[aria-hidden="true"] {
    display: grid;
    grid-template-rows: 0fr;
    padding-bottom: 0;
}

.brikk-pattern .brikk-faq__list .wp-block-accordion-panel > * {
    overflow: hidden;
    min-height: 0;
    max-width: 640px;
    margin: 0;
    color: var(--wp--preset--color--muted);
    font-size: 14px;
    line-height: 1.5;
    opacity: .8;
}

@media (prefers-reduced-motion: reduce) {
    .brikk-pattern .brikk-faq__list .wp-block-accordion-panel {
        transition: none;
    }
}

@media (max-width: 1024.98px) {
    .brikk-pattern.brikk-faq {
        padding-top: 72px;
        padding-bottom: 72px;
    }
}

@media (max-width: 768px) {
    .brikk-pattern .brikk-faq__heading {
        font-size: calc(clamp(28px, 5.2vw, 38px) * var(--brikk-heading-scale, 1));
    }
}

@media (max-width: 640px) {
    .brikk-pattern.brikk-faq {
        padding-top: 56px;
        padding-bottom: 56px;
    }

    .brikk-pattern .brikk-faq__head {
        margin-bottom: 40px;
    }

    .brikk-pattern .brikk-faq__list .wp-block-accordion-heading__toggle {
        gap: 14px;
        padding: 18px 4px;
        font-size: 17px;
        /* 1.4, not the 1.3 landing.css states — same trap as the base rule above:
           its own `.brikk-ab-page * { line-height: 1.4 }` reset defeats the 1.3 on
           the inner <span> that actually holds the text, so 1.4 is what the A/B
           RENDERS. The 1.3 here cost 3.4px per wrapped question title. */
        line-height: var(--wp--custom--lh-base);
    }

    .brikk-pattern .brikk-faq__list .wp-block-accordion-heading__toggle-icon {
        width: 26px;
        height: 26px;
        font-size: 15px;
    }

    .brikk-pattern .brikk-faq__list .wp-block-accordion-panel {
        padding-bottom: 20px;
    }

    .brikk-pattern .brikk-faq__list .wp-block-accordion-panel > * {
        font-size: 13.5px;
        line-height: var(--wp--custom--lh-copy);
    }
}

@media (max-width: 420px) {
    .brikk-pattern .brikk-faq__list .wp-block-accordion-heading__toggle {
        font-size: 16px;
    }
}

/* ⚠️ ...AND IT ZEROES margin-block-END TOO. Core's layout CSS emits
   `> * { margin-block-start: 0; margin-block-end: 0 }` on every layout
   container, at (0,1,0) but printed in the FOOTER — so it beats same-specificity
   theme rules on ORDER. That silently ate the head's bottom margins (which had
   been coming from the block gap) and, in the results section, §12.3d's own
   heading/stat-value margins. They have to be restated at (0,2,0) here. */
.brikk-pattern .brikk-faq__head > .brikk-eyebrow {
    margin-bottom: var(--wp--preset--spacing--4);
}

.brikk-pattern .brikk-faq__heading {
    margin-bottom: var(--wp--preset--spacing--4);
}


/* --- bottom CTA ----------------------------------------------------------- */

/* ⚠️ CORE'S DEFAULT BLOCK GAP. theme.json enables spacing.blockGap, so core's
   core-block-supports CSS (printed in the FOOTER, at (0,1,0)) gives every layout
   container `> * + * { margin-block-start: 24px }`. These containers space their
   children with CSS grid/flex `gap` or with explicit margins, so that 24px lands
   ON TOP and every one of them grew. Zeroed here rather than with a blockGap
   attribute on the pattern, so the fix cannot be lost by an editor tweaking the
   section's spacing controls. */
.brikk-pattern.brikk-cta .wp-block-cover__inner-container > * {
    margin-block-start: 0;
}


/* Pattern: patterns/cta.php — a core/cover, so the photo and the overlay
   gradient are editable. These rules only undo cover's defaults (which are built
   for a hero-sized block) and carry the values that step at a breakpoint.

   ⚠️ The .brikk-cta selectors MUST stay marker-scoped: the live A/B landing page
   has its own .brikk-cta section and landing.css loads first at (0,2,0). */

.brikk-pattern.brikk-cta {
    /* Cover ships min-height:430px and padding:1em, sized for a hero. The design
       is a band whose height comes from its content plus 120px of air. */
    min-height: 0;
    padding-top: 120px;
    padding-bottom: 120px;
    text-align: center;
}

.brikk-pattern.brikk-cta .wp-block-cover__inner-container {
    width: 100%;
}

.brikk-pattern .brikk-cta__heading {
    max-width: 300px;
    margin: 0 auto 32px;
    color: var(--wp--custom--on-dark);
    font-size: calc(clamp(36px, 4.4vw, 52px) * var(--brikk-heading-scale, 1));
    font-weight: 500;
    line-height: 1.1;
    letter-spacing: -0.015em;
}

.brikk-pattern .brikk-cta__lead {
    max-width: 480px;
    margin: 22px auto 34px;
    color: var(--wp--custom--on-dark-muted);
    font-size: var(--wp--preset--font-size--body);
    line-height: 1.66;
}

.brikk-pattern .brikk-cta__action {
    margin: 0;
}

@media (max-width: 1024.98px) {
    .brikk-pattern.brikk-cta {
        padding-top: 88px;
        padding-bottom: 88px;
    }
}

@media (max-width: 768px) {
    .brikk-pattern .brikk-cta__heading {
        max-width: 420px;
        font-size: calc(clamp(32px, 6vw, 44px) * var(--brikk-heading-scale, 1));
    }
}

@media (max-width: 640px) {
    .brikk-pattern.brikk-cta {
        padding-top: 72px;
        padding-bottom: 72px;
    }

    .brikk-pattern .brikk-cta__heading {
        max-width: 320px;
        margin-bottom: 22px;
        font-size: calc(clamp(30px, 7vw, 40px) * var(--brikk-heading-scale, 1));
        line-height: 1.1;
    }

    .brikk-pattern .brikk-cta__lead {
        margin: 18px auto 28px;
        font-size: 14.5px;
        line-height: 1.65;
    }
}


/* --- founder (dark split band) -------------------------------------------- */

/* Pattern: patterns/founder.php.
   ⚠️ FULL-BLEED, SO NO .brikk-gutter ON THE SECTION. The photo runs to the
   viewport's right edge and the copy carries the gutter itself as padding —
   `max(--brikk-pad-x, 7vw)`, which keeps the text off the edge on a phone and
   opens up on a wide screen. Putting a gutter on the section would inset the
   photo instead. */

/* ⚠️ CORE'S DEFAULT BLOCK GAP — see the note at §12.4's steps block. Must stay
   ABOVE the component rules below: `.brikk-founder__sign` sets a 36px TOP
   margin, and margin-block-start is the same property as margin-top, so at
   equal specificity source order is what lets the sign keep it. */
.brikk-pattern.brikk-founder > *,
.brikk-pattern .brikk-founder__grid > *,
.brikk-pattern .brikk-founder__copy > *,
.brikk-pattern .brikk-founder__media > * {
    margin-block-start: 0;
}

.brikk-pattern.brikk-founder {
    background: var(--wp--preset--color--dark);
    color: var(--wp--custom--on-dark);
}

/* ⚠️ A GRID GROUP, NOT core/columns — same reason as patterns/steps.php. The
   design stacks at 1024; core's Columns block forces `flex-wrap: nowrap
   !important` above 782px and only stacks below it, so 2-up would survive all
   the way down to 782 and then jump. */
.brikk-pattern .brikk-founder__grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: stretch;
    min-height: 560px;
}

.brikk-pattern .brikk-founder__copy {
    align-self: center;
    max-width: 720px;
    padding: 96px 80px 96px max(var(--brikk-pad-x), 7vw);
}

.brikk-pattern .brikk-founder__eyebrow {
    display: block;
    margin: 0 0 20px;
    color: var(--wp--custom--on-dark-purple);
}

.brikk-pattern .brikk-founder__title {
    margin: 0 0 26px;
    font-family: var(--wp--preset--font-family--serif);
    font-size: clamp(28px, 2.8vw, 38px);
    font-weight: 500;
    line-height: 1.18;
    color: var(--wp--preset--color--bg);
    text-wrap: balance;
}

/* ⚠️ An explicit element class, NOT `.brikk-founder__copy p`. In the A/B markup
   the eyebrow is a <span> and the name/role are <div>s, so a bare `p` selector
   matched only the body copy. In blocks every one of them is a <p> and that
   selector would restyle all five. */
.brikk-pattern .brikk-founder__text {
    margin: 0 0 16px;
    max-width: 520px;
    font-size: var(--wp--preset--font-size--body-sm);
    line-height: 1.75;
    color: color-mix(in srgb, var(--wp--preset--color--bg) 78%, transparent);
}

.brikk-pattern .brikk-founder__sign {
    margin: 36px 0 18px;
    opacity: .95;
}

.brikk-pattern .brikk-founder__sign img {
    display: block;
    width: 180px;
    height: auto;
}

/* ⚠️ BOTH STATE THEIR LEADING. landing.css leaves it to inheritance and its own
   `.brikk-ab-page *` reset then hands them 1.4; these are <p> in blocks, so §4
   would hand them 1.6 instead — 2.6px + 2.1px taller, and the whole band 4.7px
   off. Third variant of the same trap (CLAUDE.md §6e): always match what the A/B
   RENDERS, not what its rule says. */
.brikk-pattern .brikk-founder__name {
    margin: 0 0 6px;
    font-size: var(--wp--preset--font-size--ui);
    font-weight: 600;
    line-height: var(--wp--custom--lh-base);
    color: var(--wp--preset--color--bg);
}

.brikk-pattern .brikk-founder__role {
    margin: 0;
    font-size: var(--wp--preset--font-size--micro);
    font-weight: 500;
    line-height: var(--wp--custom--lh-base);
    letter-spacing: .24em;
    text-transform: uppercase;
    color: var(--wp--custom--on-dark-purple);
}

/* The photo fills its half of the band. Absolute so the column has no intrinsic
   height of its own and the grid row is driven by the copy (or the 560px
   floor), exactly as in the A/B. */
.brikk-pattern .brikk-founder__media {
    position: relative;
    overflow: hidden;
    background: var(--wp--preset--color--dark);
}

.brikk-pattern .brikk-founder__media .wp-block-image {
    position: absolute;
    inset: 0;
    margin: 0;
}

.brikk-pattern .brikk-founder__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

@media (max-width: 1024.98px) {
    .brikk-pattern .brikk-founder__grid {
        grid-template-columns: 1fr;
        min-height: 0;
    }

    .brikk-pattern .brikk-founder__copy {
        margin: 0;
        padding: 72px 32px;
    }

    /* Stacked, the photo has no column to fill, so it gets a box of its own. */
    .brikk-pattern .brikk-founder__media {
        aspect-ratio: 16 / 10;
    }
}

@media (max-width: 768px) {
    .brikk-pattern .brikk-founder__title {
        font-size: clamp(26px, 4.8vw, 32px);
    }
}

@media (max-width: 640px) {
    .brikk-pattern .brikk-founder__copy {
        padding: 56px 24px;
    }
}


/* --- local marketing ------------------------------------------------------ */

/* Pattern: patterns/localmkt.php. Copy + map on top, three numbered steps
   below. Section padding (100/72/56) and both grid gaps step at breakpoints, so
   they are CSS and not block attributes — see §12.4's header. */

/* ⚠️ CORE'S DEFAULT BLOCK GAP — see the note at §12.4's steps block. */
.brikk-pattern.brikk-localmkt > *,
.brikk-pattern .brikk-localmkt__grid > *,
.brikk-pattern .brikk-localmkt__copy > *,
.brikk-pattern .brikk-localmkt__media > *,
.brikk-pattern .brikk-localmkt__steps > *,
.brikk-pattern .brikk-localmkt__step > * {
    margin-block-start: 0;
}

.brikk-pattern.brikk-localmkt {
    padding-top: 100px;
    padding-bottom: 100px;
}

/* Grid groups again, not core/columns: 2 → 1 at 1024 for the intro, and
   3 → 1 at 768 for the steps. Neither ladder is expressible in Columns. */
.brikk-pattern .brikk-localmkt__grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: center;
    gap: 80px;
}

.brikk-pattern .brikk-localmkt__eyebrow {
    display: block;
    margin: 0 0 22px;
}

.brikk-pattern .brikk-localmkt__title {
    margin: 0 0 24px;
    font-family: var(--wp--preset--font-family--serif);
    font-size: clamp(28px, 3.2vw, 42px);
    font-weight: 500;
    line-height: 1.1;
    text-wrap: balance;
}

.brikk-pattern .brikk-localmkt__text {
    margin: 0 0 16px;
    max-width: 520px;
    font-size: 15.5px;
    line-height: 1.7;
    color: var(--wp--preset--color--muted);
}

.brikk-pattern .brikk-localmkt__media {
    position: relative;
    overflow: hidden;
    aspect-ratio: 5 / 4;
    background: var(--wp--custom--bg-dim);
}

.brikk-pattern .brikk-localmkt__media .wp-block-image {
    position: absolute;
    inset: 0;
    margin: 0;
}

.brikk-pattern .brikk-localmkt__media img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.brikk-pattern .brikk-localmkt__steps {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 48px;
    margin-top: 20px;
    padding-top: 36px;
}

.brikk-pattern .brikk-localmkt__step {
    position: relative;
}

/* The hairline between steps is centred in the grid GAP, and the step's content
   is centred inside its column (text stays left-aligned) so the two line up.
   Both offsets are half the gap at that breakpoint; the padding collapses to 0
   wherever the column is already narrower than 300px. */
@media (min-width: 769px) {
    .brikk-pattern .brikk-localmkt__step {
        padding-inline: max(0px, calc((100% - 300px) / 2));
    }

    .brikk-pattern .brikk-localmkt__step:not(:first-child)::before {
        content: '';
        position: absolute;
        top: 0;
        bottom: 0;
        left: -16px;
        width: 1px;
        background: var(--wp--preset--color--line);
    }
}

@media (min-width: 1025px) {
    .brikk-pattern .brikk-localmkt__step:not(:first-child)::before {
        left: -24px;
    }
}

.brikk-pattern .brikk-localmkt__num {
    margin: 0 0 12px;
    font-family: var(--wp--preset--font-family--serif);
    font-style: italic;
    font-size: 38px;
    font-weight: 500;
    line-height: 1;
    color: var(--wp--preset--color--purple);
}

.brikk-pattern .brikk-localmkt__step-title {
    margin: 0 0 12px;
    font-family: var(--wp--preset--font-family--serif);
    font-size: 26px;
    font-weight: 500;
    line-height: 1.15;
    letter-spacing: var(--wp--custom--ls-heading);
    color: var(--wp--preset--color--dark);
}

.brikk-pattern .brikk-localmkt__step-desc {
    margin: 0;
    max-width: 320px;
    font-size: 14px;
    line-height: 1.5;
    opacity: .8;
    color: var(--wp--preset--color--muted);
}

@media (max-width: 1024.98px) {
    .brikk-pattern.brikk-localmkt {
        padding-top: 72px;
        padding-bottom: 72px;
    }

    .brikk-pattern .brikk-localmkt__grid {
        grid-template-columns: 1fr;
        gap: 48px;
    }

    .brikk-pattern .brikk-localmkt__steps {
        gap: 32px;
        margin-top: 56px;
    }
}

@media (max-width: 768px) {
    .brikk-pattern .brikk-localmkt__steps {
        grid-template-columns: 1fr;
        gap: 28px;
    }
}

@media (max-width: 640px) {
    .brikk-pattern.brikk-localmkt {
        padding-top: 56px;
        padding-bottom: 56px;
    }

    .brikk-pattern .brikk-localmkt__steps {
        margin-top: 40px;
        padding-top: 28px;
    }
}


/* --- responsive visibility inside patterns (must come last) --------------- */

/* ⚠️ `.brikk-hide-mobile` / `.brikk-hide-desktop` are §10 utilities at (0,1,0).
   Pattern component rules are (0,2,0) by construction (they carry the
   `.brikk-pattern` marker — see §12.4's header), so ANY of them that sets
   `display` on the same element silently beats the utility and the element
   stays visible. That is exactly what happened to the features pattern's third
   card: `.brikk-features .wp-block-column { display: flex }` won, the card that
   the design hides at ≤640 kept rendering, and the section was 737px too tall
   on a phone.

   Restated here at (0,2,0) AND at the very end of §12.4, so it wins on order
   against every pattern rule above it. Any future "hide at breakpoint" utility
   used inside a pattern needs the same treatment. */

@media (max-width: 640px) {
    .brikk-pattern .brikk-hide-mobile,
    .brikk-pattern.brikk-hide-mobile {
        display: none;
    }
}

@media (min-width: 640.02px) {
    .brikk-pattern .brikk-hide-desktop,
    .brikk-pattern.brikk-hide-desktop {
        display: none;
    }
}


/* --- responsive column gaps for the earlier patterns ---------------------- */

/* ⚠️ A blockGap BLOCK ATTRIBUTE CAN NEVER BE RESPONSIVE — it emits one fixed
   value (as `--wp--style--block-gap` on a generated .wp-container-* rule) that
   applies at every viewport. The hero/features/pricing patterns set their column
   gaps that way, so the desktop 48px stayed 48px on a 390px phone where the
   design steps down to 20px. Features alone was 155px too tall because of it.

   The A/B ladder, from landing.css:
     features   50px  ·  ≤1024 28px  ·  ≤640 20px
     pricing    40px  ·  ≤1024 24px  ·  ≤640 20px

   Restated here because only CSS can express the steps. The desktop values stay
   on the blocks, so the editor's gap control still works there. */

/* 🔴 AND A BLOCK ATTRIBUTE CANNOT EXPRESS A COLUMN-COUNT LADDER AT ALL.
   The design steps features 3-up → 2-up (≤1024) → 1-up (≤640) and pricing
   2-up → 1-up (≤640). core/columns can do NEITHER: it forces
   `flex-wrap: nowrap !important` above 782px (so there is no 2-up band) and
   `flex-basis: 100% !important` below it (so it stacks at 782 — 142px early).
   Measured before this fix: features was 3-up at 782-900 where the design is
   2-up (−426px of height) and 1-up at 641-768 where the design is still 2-up
   (+219px); pricing stacked at 641-768 where the design is 2-up (+547px).

   The container becomes a GRID. Core's `display: flex` is NOT !important, so a
   (0,2,0) rule wins, and `flex-wrap`/`flex-basis` are inert on a grid container.
   `.brikk-price-card--featured { order: -1 }` still works — grid honours order.
   Desktop gaps stay on the blocks so the editor's gap control keeps working. */

.brikk-pattern.brikk-features > .wp-block-columns {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
}

.brikk-pattern.brikk-pricing .wp-block-columns {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
}

@media (max-width: 1024.98px) {
    .brikk-pattern.brikk-features > .wp-block-columns {
        grid-template-columns: repeat(2, 1fr);
        gap: 28px;
    }

    .brikk-pattern.brikk-pricing .wp-block-columns {
        gap: 24px;
    }
}

@media (max-width: 640px) {
    .brikk-pattern.brikk-features > .wp-block-columns,
    .brikk-pattern.brikk-pricing .wp-block-columns {
        grid-template-columns: 1fr;
        gap: 20px;
    }
}


/* --- pricing / features: margins core's layout CSS ate ------------------- */

/* Same root cause as everywhere else in this section: core's layout CSS emits
   `> * { margin-block-start: 0; margin-block-end: 0 }` at (0,1,0) but prints it
   in the FOOTER, so it beats same-specificity theme rules on order and silently
   removes the vertical rhythm the design depends on. Restated at (0,2,0). */

.brikk-pattern.brikk-pricing .brikk-pricing__head > .brikk-eyebrow,
.brikk-pattern.brikk-pricing .brikk-pricing__head > h2 {
    margin-bottom: var(--wp--preset--spacing--4);
}

.brikk-pattern.brikk-pricing .brikk-pricing__lead {
    max-width: 600px;
    margin-inline: auto;
    font-size: var(--wp--preset--font-size--body);
    line-height: 1.7;
}

/* The A/B price list is `display: flex; gap: 15px`. As a core LIST the items are
   normal line boxes (deliberately — see .brikk-check-list's comment), so the
   rhythm is a margin instead. Scoped to the price card: the hero and all-in-one
   lists have their own, tighter spacing. */
.brikk-pattern .brikk-price-card .brikk-check-list {
    margin-top: 0;
}

.brikk-pattern .brikk-price-card .brikk-check-list li + li {
    margin-top: 15px;
}

/* ⚠️ The pricing heading carries NO fontSize preset on the block, on purpose: a
   preset emits a class WordPress marks !important, so the design's 42 → 38px
   step at ≤768 could never have applied. The whole ladder is here instead —
   still reading the same theme.json scale, just as a clamp. */
.brikk-pattern.brikk-pricing .brikk-pricing__head > h2 {
    font-size: calc(clamp(30px, 3.4vw, 42px) * var(--brikk-heading-scale, 1));
    font-weight: 500;
    line-height: 1.1;
}

@media (max-width: 768px) {
    .brikk-pattern.brikk-pricing .brikk-pricing__head > h2 {
        font-size: calc(clamp(28px, 5.2vw, 38px) * var(--brikk-heading-scale, 1));
    }
}


/* The head's bottom margin STEPS 60 -> 40px at ≤640, so it cannot be a block
   attribute: those emit an inline style, which no media query can override. */
.brikk-pattern.brikk-pricing .brikk-pricing__head {
    margin-bottom: 60px;
}

@media (max-width: 640px) {
    .brikk-pattern.brikk-pricing .brikk-pricing__head {
        margin-bottom: 40px;
    }

    .brikk-pattern.brikk-pricing .brikk-pricing__lead {
        font-size: 14.5px;
        line-height: var(--wp--custom--lh-copy);
    }

    /* 12px between price-list items on mobile, down from 15. */
    .brikk-pattern .brikk-price-card .brikk-check-list li + li {
        margin-top: var(--wp--preset--spacing--3);
    }
}


/* --- price card: the last three block-gap / leading leaks ---------------- */

/* The eyebrow and the "Mest valgte" badge are core PARAGRAPHS here, so §4 gives
   them 1.6 leading; the A/B renders both at 1.4 (its `.brikk-ab-page *` reset).
   Matching the rendering, as everywhere else in this section. */
.brikk-pattern .brikk-price-card__eyebrow,
.brikk-pattern .brikk-price-card__badge {
    line-height: var(--wp--custom--lh-base);
}

/* The CTA follows the feature list directly in the A/B; here it is a paragraph
   and picks up the card's 24px block gap on top of the list's own 28px bottom
   margin. */
.brikk-pattern .brikk-price-card .brikk-check-list + p {
    margin-top: 0;
}


/* --- section rhythm for features / pricing / logos ----------------------- */

/* 🔴 THE SAME TRAP, AND THE MOST EXPENSIVE INSTANCE OF IT. These three patterns
   set their vertical padding with a `style.spacing.padding` BLOCK ATTRIBUTE,
   which emits an INLINE style — so the 96px desktop value survived onto a 390px
   phone, where the design steps down to 56px. features and pricing were each
   ~80px too tall on mobile purely because of it.
   The attribute is gone from the patterns; the ladder lives here, where it can
   actually step. (Vertical padding is normally an editor control — this is the
   documented exception for values that change at a breakpoint.) */

/* ⚠️ These two do NOT share a value at desktop — landing.css is
   `.brikk-features { padding: 100px 0 96px }` (the one asymmetric section) and
   `.brikk-pricing { padding: 100px 0 }`. Lumping both at the 96px token cost
   pricing 8px. They only converge on the ≤1024 / ≤640 steps below. */
.brikk-pattern.brikk-features {
    padding-top: 100px;
    padding-bottom: var(--wp--preset--spacing--9);
}

.brikk-pattern.brikk-pricing {
    padding-top: 100px;
    padding-bottom: 100px;
}

/* landing.css gives features `padding: 100px 0 96px` — asymmetric, and the only
   section that is. Stated HERE, with the other base values, not appended after
   the media queries below: equal specificity means source order decides, and an
   override at the end of the file wins at every width. */
.brikk-pattern.brikk-features {
    padding-top: 100px;
}

@media (max-width: 1024.98px) {
    .brikk-pattern.brikk-features,
    .brikk-pattern.brikk-pricing {
        padding-top: 72px;
        padding-bottom: 72px;
    }
}

@media (max-width: 640px) {
    .brikk-pattern.brikk-features,
    .brikk-pattern.brikk-pricing {
        padding-top: 56px;
        padding-bottom: 56px;
    }
}


/* --- logos strip --------------------------------------------------------- */

/* The A/B strip is 28px of padding between two warm hairlines, stepping to 22px
   at ≤640 — so the padding cannot be a block attribute (it emits an inline
   style). The hairlines were missing entirely from the pattern. */

.brikk-pattern.brikk-logos {
    padding-top: 28px;
    padding-bottom: 28px;
    border-top: 1px solid var(--wp--preset--color--line);
    border-bottom: 1px solid var(--wp--preset--color--line);
}

/* 22px between the eyebrow and the logo row (landing.css's .brikk-logos__inner
   gap), not the section's 24px block gap. */
.brikk-pattern.brikk-logos > .brikk-logos__list {
    margin-top: 22px;
}

/* ⚠️ THE LOGOS ARE SIZED BY HEIGHT, NOT WIDTH. Each mark has a different
   cap-height and aspect ratio, so landing.css sets a common optical HEIGHT and
   nudges three of them with a negative bottom margin to sit on one baseline;
   the row is `align-items: flex-end` for exactly that reason. The pattern used
   fixed `width` attributes instead, which (a) emit inline styles no media query
   can override, (b) made every logo 40-50% too wide, and (c) lost the baseline
   alignment. The width attributes are gone from the blocks. */
.brikk-pattern .brikk-logos__list {
    align-items: flex-end;
    gap: 48px;
    flex-wrap: nowrap;
}

.brikk-pattern .brikk-logos__list figure {
    margin: 0;
}

.brikk-pattern .brikk-logos__list img {
    width: auto;
    height: 22px;
}

.brikk-pattern .brikk-logos__list .brikk-logo-boligsiden img {
    height: 27px;
    margin-bottom: -4px;
}

.brikk-pattern .brikk-logos__list .brikk-logo-boliga img {
    margin-bottom: -4px;
}

.brikk-pattern .brikk-logos__list .brikk-logo-instagram img {
    height: 28px;
    margin-bottom: -9px;
    opacity: .8;
}

@media (max-width: 1024.98px) {
    .brikk-pattern .brikk-logos__list {
        gap: 36px;
    }
}

@media (max-width: 640px) {
    .brikk-pattern.brikk-logos {
        padding-top: 22px;
        padding-bottom: 22px;
    }

    /* Wraps onto two rows below this width. */
    .brikk-pattern .brikk-logos__list {
        flex-wrap: wrap;
        gap: 26px 32px;
    }

    .brikk-pattern .brikk-logos__list img {
        height: 18px;
    }

    .brikk-pattern .brikk-logos__list .brikk-logo-boligsiden img {
        height: 22px;
        margin-bottom: -2px;
    }

    .brikk-pattern .brikk-logos__list .brikk-logo-instagram img {
        height: 23px;
        margin-bottom: -5px;
    }
}


/* --- feature card internals --------------------------------------------- */

/* Ported from landing.css's .brikk-feature__body / __title / __desc. Ours used
   a uniform 24px block gap between the card's children, which is close but not
   the design's asymmetric rhythm (30px above the title, 16px to the copy, 26px
   to the arrow link) — the cards ran 23-29px short wherever the copy re-wrapped. */

.brikk-pattern.brikk-features .brikk-feature__title {
    font-size: 25px;
    line-height: 1.18;
    letter-spacing: .005em;
    text-wrap: balance;
}

.brikk-pattern.brikk-features .wp-block-column > .brikk-feature__title {
    margin-top: 30px;
}

/* ⚠️ `margin-block`, NOT the `margin` shorthand — the card's horizontal insets
   come from `.brikk-features .wp-block-column > :not(.brikk-feature__img)
   { margin-inline: 30px }`, and a shorthand here reset those to 0. The copy then
   ran the full 288px card width instead of the design's 228px, wrapped to fewer
   lines, and every card came out ~25px short. */
.brikk-pattern.brikk-features .brikk-feature__desc {
    margin-block: 16px 26px;
    font-size: 14px;
    line-height: 1.66;
}

/* The design's gap above the arrow link IS the description's 26px bottom margin.
   The card's 24px block gap was stacking on top of it, adding ~25px per card. */
.brikk-pattern.brikk-features .wp-block-column > .brikk-link-arrow {
    margin-top: 0;
}

@media (max-width: 1024.98px) {
    .brikk-pattern.brikk-features .wp-block-column > .brikk-feature__title {
        margin-top: 26px;
    }

    .brikk-pattern.brikk-features .wp-block-column {
        padding-bottom: 28px;
    }
}

@media (max-width: 640px) {
    .brikk-pattern.brikk-features .wp-block-column > .brikk-feature__title {
        margin-top: 24px;
    }
}


/* --- features: the ≤640 type/rhythm steps ------------------------------- */

/* The A/B tightens the card at ≤640 (landing.css: .brikk-feature__title 22/1.2,
   .brikk-feature__desc 13.5/1.6 with 12px 0 22px margins, .brikk-feature__body
   padding 24px 24px 26px). Our card is a core Column whose children are spaced
   by a blockGap ATTRIBUTE — one fixed 24px at every viewport — so the tighter
   mobile rhythm has to be restated here. */

@media (max-width: 640px) {
    .brikk-pattern.brikk-features .brikk-feature__title {
        font-size: 22px;
        line-height: 1.2;
    }

    .brikk-pattern.brikk-features .brikk-feature__desc {
        margin-block: var(--wp--preset--spacing--3) 22px;
        font-size: 13.5px;
        line-height: var(--wp--custom--lh-copy);
    }

    .brikk-pattern.brikk-features .wp-block-column > .brikk-link-arrow {
        margin-top: 0;
    }

    .brikk-pattern.brikk-features .wp-block-column {
        padding-bottom: 26px;
    }
}


/* 12px × 1.4 = 16.8px, what the A/B renders. §4 gives paragraphs 1.6, which made
   every arrow link 5px taller and each feature card with it. */
/* ⚠️ THE ARROW-LINK CHROME WAS BEING DRAWN TWICE. Our markup is
   `<p class="brikk-link-arrow"><a>…</a></p>`, so §6's `.brikk-link-arrow`
   (padding-bottom 2px + border-bottom + opacity .6) hits the PARAGRAPH while
   `.brikk-link-arrow a` applies the identical treatment to the anchor inside it
   — two underlines, two paddings, opacity .6 × .6. The A/B puts the class
   directly on the <a>, so it gets it once. The wrapper is neutralised here;
   (0,2,0) beats §6's (0,1,0) and the marker keeps it off A/B markup. */
.brikk-pattern .brikk-link-arrow {
    padding-bottom: 0;
    border-bottom: 0;
    opacity: 1;
    line-height: var(--wp--custom--lh-base);
}


/* =============================================================================
   "HVAD ER INKLUDERET" — the three page-specific sections
   =============================================================================
   Patterns: patterns/inc-why.php · patterns/inc-compare.php · patterns/inc-cta.php
   Ported from landing.css:4385-4950, which is the ONLY place this CSS has ever
   existed — it is scoped `.brikk-ab-included` there and was never part of the
   shared design system. The hero variant lives with the hero family above.

   🔴 THIS SECTION KEEPS TWO NON-LADDER BREAKPOINTS: 900px and 720px. Both were
   swept at 1px resolution and confirmed against the live A/B page, and both are
   load-bearing rather than stray:
     · 900px — the why grid goes 3-up → 1-up with NO 2-up band. Folding it up to
       1024 would stack three cards at 1000px where they still have ~300px each;
       folding it down to 768 would squeeze them to ~219px, which wraps the card
       titles to four lines. The A/B picked the width where 3-up actually stops
       working.
     · 720px — the comparison table stops being a table. Its data columns are a
       fixed 130px each at ≤1024, so what decides the switch is how much room is
       left for the feature column, not the page's type ladder.
   DESIGN.md §9 folds the A/B's other strays (500/478/450/1300) into
   1024/768/640/420 and allows "360/450 component-only" exceptions; these two are
   exactly that. Nothing outside this block may use them.

   Measured section heights on the A/B original at 1440, for the diff:
   inc-why 909.2 · inc-compare 1401.1 · inc-cta 506.6 (all ±0.1px).
   -------------------------------------------------------------------------- */

/* --- "mere for mindre" dark cards ----------------------------------------- */

/* 100px, not the 96px --brikk-section-y token: this is one of the sections where
   landing.css uses 100 and the difference shows in a full-page comparison. Same
   call as .brikk-faq (DESIGN.md §9 prefers 96 — revisit only if the whole rhythm
   is unified). Longhands, never the `padding` shorthand: the horizontal gutter
   comes from .brikk-gutter and a shorthand would wipe it. */
.brikk-pattern.brikk-inc-why {
    padding-top: 100px;
    padding-bottom: 100px;
    /* Flat-dark-band ink: the warm canvas colour, not pure white (DESIGN.md §2 —
       #fff is for text over PHOTOGRAPHY). landing.css says #fff here; .brikk-results
       made the same substitution when the first dark band was ported. */
    color: var(--wp--preset--color--bg);
}

/* The head's bottom margin STEPS 60 → 40px at ≤640, so it cannot be a block
   attribute — those emit an inline style no media query can override. The 720px
   cap is here rather than as the group's contentSize for the reason in the
   pattern's own comment: contentSize caps the CHILDREN and leaves the group full
   width, which measures 1470px against the A/B's 720. */
.brikk-pattern .brikk-inc-why__head {
    max-width: 720px;
    margin-inline: auto;
    margin-bottom: 60px;
}

/* ⚠️ Core's layout CSS emits `> * { margin-block-start: 0; margin-block-end: 0 }`
   at (0,1,0) but prints it in the FOOTER, so it beats same-specificity theme
   rules on ORDER and silently eats a head's vertical rhythm. Restated at (0,2,0),
   as everywhere else in §12.4. */
.brikk-pattern .brikk-inc-why__eyebrow {
    margin-top: 0;
    margin-bottom: var(--wp--preset--spacing--4);
    /* The lighter purple. Its token is named for where it was first needed (on
       dark), not for a restriction — the A/B uses this same #9a73e6 here. */
    color: var(--wp--custom--on-dark-purple);
}

.brikk-pattern .brikk-inc-why__heading {
    margin-top: 0;
    margin-bottom: var(--wp--preset--spacing--4);
    font-size: clamp(30px, 3.4vw, 42px);
    font-weight: 500;
    line-height: 1.1;
    color: var(--wp--preset--color--bg);
}

.brikk-pattern .brikk-inc-why__lead {
    max-width: 600px;
    margin-inline: auto;
    margin-bottom: 0;
    color: color-mix(in srgb, var(--wp--preset--color--bg) 70%, transparent);
    font-size: var(--wp--preset--font-size--body);
    line-height: 1.7;
}

/* ⚠️ A GRID GROUP, NOT core/columns — 3-up → 1-up with no 2-up band is exactly
   the ladder core's Columns block cannot express (§6e lesson 1: it forces
   `flex-wrap: nowrap !important` above 782px and `flex-basis: 100% !important`
   below, so 3-up would survive to 782 where the design is already 1-up). */
.brikk-pattern .brikk-inc-why__grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 30px;
}

/* Grid `gap` already spaces these; core's default block gap would stack on top. */
.brikk-pattern .brikk-inc-why__grid > *,
.brikk-pattern .brikk-inc-why-card > *,
.brikk-pattern .brikk-inc-why-card__body > * {
    margin-block-start: 0;
}

/* ⚠️ DARK OUTSIDE, WHITE INSIDE. The card surface only shows around the photo
   (the body below it is white), so the ink inside the body is the LIGHT-surface
   ink and the numeral/bullets use the light-surface purples. */
.brikk-pattern .brikk-inc-why-card {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--wp--custom--card-raised-dark);
}

.brikk-pattern .brikk-inc-why-card__img {
    height: 200px;
    margin: 0;
    overflow: hidden;
    background: var(--wp--preset--color--dark-2);
}

.brikk-pattern .brikk-inc-why-card__img img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Card 02 is a portrait — hold the top of the frame, not its centre. */
.brikk-pattern .brikk-inc-why-card:nth-child(2) .brikk-inc-why-card__img img {
    object-position: center top;
}

.brikk-pattern .brikk-inc-why-card__body {
    display: flex;
    flex: 1;
    flex-direction: column;
    padding: 28px 28px 30px;
    background: var(--wp--preset--color--card);
    color: var(--wp--preset--color--dark);
}

/* `baseline` — core emits `align-items: center` for every flex-layout group, and
   this row pairs a 28px numeral with a 23px title that must sit on one baseline.
   Same override as .brikk-hero__metrics' `stretch`. */
.brikk-pattern .brikk-inc-why-card__head {
    align-items: baseline;
    padding-bottom: 18px;
    margin-bottom: 18px;
    border-bottom: 1px solid var(--wp--custom--line-ink);
}

/* ⚠️ STATES ITS LEADING, and it changes the row height. In the A/B this numeral
   is a <span> with no line-height of its own, so `.brikk-ab-page * { 1.4 }`
   supplies 1.4. As a core PARAGRAPH here, §4 supplies 1.6 instead — 4.5px taller
   at 28px, and with baseline alignment that moves the whole card. Fourth variant
   of the §6e lesson-12 trap (after .brikk-founder__name, .brikk-review__name and
   .brikk-mock__name). Match what the A/B RENDERS, not what its rule says.

   🟠 ROMAN, NOT ITALIC — and this one was settled by measuring, against DESIGN.md.
   §9's drift log resolves "italic (steps/marketing) vs roman (inc-why)" in favour
   of italic, so italic was built and measured first. Result: an italic "01" in
   Cormorant is **2.1px narrower** than the roman one, which widens the title
   beside it by the same 2.1px — and at 320px that is exactly enough to pull
   "Ingen dyre mellemled" back onto one line, making the card 23.1px shorter and
   the section 23px shorter than the A/B. Invisible at all 24 other measured
   widths, wrong at that one. Roman is Δ0 everywhere.
   Worth raising with Andreas as a system question rather than settling it inside
   one section — if the numerals should be italic everywhere, the thing to change
   is that 320px wrap. One declaration either way. */
.brikk-pattern .brikk-inc-why-card__num {
    flex: none;
    margin: 0;
    font-family: var(--wp--preset--font-family--serif);
    font-size: 28px;
    font-weight: 500;
    line-height: var(--wp--custom--lh-base);
    color: var(--wp--preset--color--purple);
}

/* 23px, NOT the 26px DESIGN.md §9 calls canonical for card titles. Kept at the
   A/B's value on purpose: the brief for these ports is a measured 1:1 against the
   live A/B page, and 26px rewraps every card title and changes each card's
   height. 🟠 Worth putting to Andreas as a system question rather than deciding
   it inside one section — the same choice applies to .brikk-feature__title. */
.brikk-pattern .brikk-inc-why-card__title {
    margin: 0;
    font-size: 23px;
    font-weight: 500;
    line-height: 1.18;
    letter-spacing: .005em;
    color: var(--wp--preset--color--dark);
}

/* The A/B list is `display: flex; gap: 16px`. As a core LIST the items stay
   normal line boxes and the rhythm becomes a margin — same reasoning as
   .brikk-check-list, and it is what lets a bullet's wrapped lines indent past
   the dot. */
.brikk-pattern .brikk-inc-why-card__list {
    margin: 0;
    padding-left: 0;
    list-style: none;
}

.brikk-pattern .brikk-inc-why-card__list li {
    position: relative;
    padding-left: 18px;
    color: var(--wp--preset--color--muted);
    font-size: 14px;
    font-weight: 400;
    line-height: var(--wp--custom--lh-copy);
}

.brikk-pattern .brikk-inc-why-card__list li + li {
    margin-top: var(--wp--preset--spacing--4);
}

.brikk-pattern .brikk-inc-why-card__list li::before {
    content: '';
    position: absolute;
    top: 9px;
    left: 0;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--wp--custom--on-dark-purple);
}


/* --- comparison table ---------------------------------------------------- */

/* Pattern: patterns/inc-compare.php — a real core/table, so `<thead>`,
   `<th scope="col">` and `<th scope="row">` all survive. Read that file's docblock
   before touching these selectors: a core/table CELL cannot carry a className, so
   every one of the A/B's classed value spans is re-expressed as a core inline
   FORMAT and the rules below select on those tags and on column position instead:

     .__feature      → `tr > *:nth-child(1)`
     .__brikk        → `tr > *:nth-child(2)`
     .__trad         → `tr > *:nth-child(3)`
     .__eyebrow      → `thead tr > *:nth-child(1) small`
     .__feature-title→ the head cell's own text
     .__sub          → `tbody tr > *:nth-child(1) small`
     .__value        → the data cell's own text (the default treatment)
     .__mark         → `strong`        (<strong>✓</strong>)
     .__mark--dash   → `s`             (<s>–</s>)
     .__q            → `em`            (<em>?</em>)

   🔴 EVERY COLUMN RULE IS KEYED ON `tr > *:nth-child(n)`, NEVER ON `th` / `td`.
   That is deliberate and it protects an editor: core's "Insert row after" creates a
   row of all-`td` cells with no `scope`, so a feature column keyed on `th` would
   render a newly added row's first cell with the centred purple value type instead
   of the left-aligned feature type. Position-keyed rules render it correctly
   whatever tag it gets. (The shipped markup still uses `th scope="row"` for
   accessibility — the CSS simply does not depend on it.)

   ⚠️ COLUMN POSITION IS LOAD-BEARING. Three cells per row, always. Adding a fourth
   column means revisiting every rule below.
   ⚠️ ROW position is NOT used anywhere, and must not be: inserting or deleting a
   row would renumber every rule below it. */

.brikk-pattern.brikk-inc-compare {
    padding-top: 100px;
    padding-bottom: 100px;
}

.brikk-pattern .brikk-inc-compare__head {
    max-width: 760px;
    margin-inline: auto;
    margin-bottom: 56px;
}

.brikk-pattern .brikk-inc-compare__eyebrow {
    margin-top: 0;
    margin-bottom: var(--wp--preset--spacing--4);
}

/* The 450px cap is the A/B's, and it is what breaks this heading over two lines
   at desktop widths — without it the sentence fits on one and the section is 50px
   shorter. */
.brikk-pattern .brikk-inc-compare__heading {
    max-width: 450px;
    margin: 0 auto var(--wp--preset--spacing--4);
    font-size: clamp(30px, 3.4vw, 46px);
    font-weight: 500;
    line-height: 1.1;
}

/* `opacity: .85` on top of --muted is what the A/B renders, and DESIGN.md §9 says
   never to stack opacity on muted text. Kept anyway for one reason: the sibling
   .brikk-trust__lead in §12.3c kept its own `.8` when it was ported, so dropping
   it here would make the two leads on this page disagree. 🟠 Unify both or
   neither. */
.brikk-pattern .brikk-inc-compare__lead {
    max-width: 600px;
    margin-inline: auto;
    margin-bottom: 0;
    color: var(--wp--preset--color--muted);
    font-size: var(--wp--preset--font-size--body);
    line-height: 1.7;
    opacity: .85;
}

/* The figure IS the A/B's __table-wrap. `margin: 0 auto` is stated rather than
   inherited from the reset: §3 only applies on redesigned pages, and a `figure`
   carries a 1em/40px UA margin everywhere else. Core's own
   `.wp-block-table { overflow-x: auto }` is deliberately left in place — nothing
   overflows it at any measured width, and it is a free guard if a row ever grows. */
.brikk-pattern .brikk-inc-compare__table-wrap {
    max-width: 1000px;
    margin: 0 auto;
}

/* `separate` + zero spacing, not core's `collapse`: the design declares exactly
   ONE side per cell boundary (bottom on every cell, left on the feature column,
   right on the traditional one, and a purple right edge on the Brikk column), so
   nothing doubles up — and `separate` is what keeps the purple BRIKK header cell
   free of a merged neutral line across its top. */
.brikk-pattern .brikk-inc-compare__table-wrap table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    background: var(--wp--preset--color--card);
    text-align: left;
}

/* Core gives thead a 3px bottom border and every cell `border: 1px solid;
   padding: .5em`. All three go. */
.brikk-pattern .brikk-inc-compare__table-wrap thead {
    border-bottom: 0;
}

.brikk-pattern .brikk-inc-compare__table-wrap tr > * {
    padding: 18px 24px;
    border: 0;
    border-bottom: 1px solid var(--wp--custom--line-ink);
    vertical-align: middle;
}

/* Data cells: fixed width plus the "value" treatment (a price, "Nej"). The three
   marker formats below override whatever type they need.

   🔴 THE LEADING IS AN ABSOLUTE 22.4px, NOT A RATIO — and getting this wrong cost
   40px of table height. In the A/B the 20px value type sits on a `__value` SPAN, so
   the CELL keeps the body's 16px/1.4 = a 22.4px strut. Here the value is the cell's
   own text (a core/table cell cannot wrap it in a classed span), so the cell
   carries the 20px itself — and a 1.4 RATIO on 20px is a 28px strut, which made
   every one of the 8 checkmark-only rows 5px taller than the A/B. Pinning the strut
   to the body line box restores it exactly, and the markers below state their own
   leading so they are unaffected. Same shape of bug as the footer's absolute
   22.5px inheritance (§6c) — measure the strut, not the rule. */
.brikk-pattern .brikk-inc-compare__table-wrap tbody tr > *:nth-child(n+2) {
    width: 196px;
    font-family: var(--wp--preset--font-family--serif);
    font-size: 20px;
    font-weight: 500;
    line-height: calc(var(--wp--preset--font-size--body) * var(--wp--custom--lh-base));
    text-align: center;
    white-space: nowrap;
    color: var(--wp--preset--color--purple);
}

/* Feature column, body rows. */
.brikk-pattern .brikk-inc-compare__table-wrap tbody tr > *:nth-child(1) {
    font-family: var(--wp--preset--font-family--sans);
    font-size: 15px;
    font-weight: 400;
    line-height: 1.45;
    text-align: left;
    color: var(--wp--preset--color--dark);
}

.brikk-pattern .brikk-inc-compare__table-wrap tbody tr > *:nth-child(1) small {
    display: block;
    margin-top: 5px;
    font-size: 12.5px;
    line-height: var(--wp--custom--lh-base);
    color: var(--wp--preset--color--muted);
    opacity: .8;
}

/* --- the head row --- */

.brikk-pattern .brikk-inc-compare__table-wrap thead tr > * {
    padding-top: 26px;
    padding-bottom: 22px;
    text-align: center;
    vertical-align: bottom;
}

/* The head's feature cell holds BOTH the small tracked eyebrow and the serif
   title, so the cell itself carries the title's type and the <small> resets what
   it needs. (In the A/B these are two classed spans.) */
.brikk-pattern .brikk-inc-compare__table-wrap thead tr > *:nth-child(1) {
    font-family: var(--wp--preset--font-family--serif);
    font-size: 26px;
    font-weight: 500;
    line-height: 1.05;
    text-align: left;
    color: var(--wp--preset--color--dark);
}

.brikk-pattern .brikk-inc-compare__table-wrap thead tr > *:nth-child(1) small {
    display: block;
    margin-bottom: 12px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: .28em;
    line-height: var(--wp--custom--lh-base);
    text-transform: uppercase;
    color: var(--wp--preset--color--muted);
}

/* The purple BRIKK block. 500, not the A/B's 600: Helvetica Neue has no 600 face,
   so 600 silently faux-bolds (DESIGN.md §9). */
.brikk-pattern .brikk-inc-compare__table-wrap thead tr > *:nth-child(2) {
    padding-top: 26px;
    padding-bottom: 22px;
    border: 0;
    background: var(--wp--preset--color--purple);
    color: var(--wp--custom--on-accent);
    font-family: var(--wp--preset--font-family--sans);
    font-size: 22px;
    font-weight: 500;
    letter-spacing: var(--wp--custom--ls-ui);
    line-height: var(--wp--custom--lh-base);
    text-transform: uppercase;
    vertical-align: middle;
}

.brikk-pattern .brikk-inc-compare__table-wrap thead tr > *:nth-child(3) {
    font-family: var(--wp--preset--font-family--serif);
    font-style: italic;
    font-size: 19px;
    font-weight: 500;
    letter-spacing: 0;
    line-height: 1.15;
    text-transform: none;
    color: var(--wp--preset--color--muted);
}

.brikk-pattern .brikk-inc-compare__table-wrap thead tr > *:nth-child(3) sup {
    font-size: .55em;
    font-style: normal;
    vertical-align: super;
}

/* --- the frame ---
   Built from the edge cells rather than from the table, so the purple BRIKK head
   keeps a clean top edge with no neutral line crossing it. */

.brikk-pattern .brikk-inc-compare__table-wrap tr > *:nth-child(1) {
    border-left: 1px solid var(--wp--custom--line-ink);
}

.brikk-pattern .brikk-inc-compare__table-wrap tr > *:nth-child(3) {
    border-right: 1px solid var(--wp--custom--line-ink);
}

.brikk-pattern .brikk-inc-compare__table-wrap thead tr > *:nth-child(1),
.brikk-pattern .brikk-inc-compare__table-wrap thead tr > *:nth-child(3) {
    border-top: 1px solid var(--wp--custom--line-ink);
}

/* The Brikk column's purple right edge — the band that pulls the eye down it. */
.brikk-pattern .brikk-inc-compare__table-wrap tbody tr > *:nth-child(2) {
    border-left: 1px solid var(--wp--custom--line-soft);
    border-right: 1px solid var(--wp--preset--color--purple);
}

/* --- the three marker formats --- */

/* <strong>✓</strong> — included. A 22px filled circle. `font-weight: 400` undoes
   <strong>'s bold; the glyph is a symbol, not emphasis in the type sense. */
/* ⚠️ `vertical-align: middle`, NOT the A/B's `baseline` — measured, and it is worth
   knowing why. An `inline-flex` badge sits ON the text baseline, so it hangs below
   it and stretches the line box: with `baseline` every checkmark row came out 2px
   taller than the A/B (8 rows = 16px of table). The A/B renders 61px rows with
   baseline alignment; we do not, and the difference survives even with an
   identical strut (tested). `middle` centres the badge on the line instead, which
   lands within 0.1px of the A/B at every width AND is what a centred symbol wants
   anyway. Applies to both markers.
   ⚠️ Both are `inline-flex`: do not "simplify" either to inline-block — the glyph
   is optically centred by the flex box, not by line-height. */
.brikk-pattern .brikk-inc-compare__table-wrap tbody tr > *:nth-child(n+2) strong {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    margin: 0 auto;
    border-radius: 50%;
    vertical-align: middle;
    background: var(--wp--custom--compare-mark);
    color: var(--wp--preset--color--purple);
    font-family: var(--wp--preset--font-family--sans);
    font-size: 10px;
    font-weight: 400;
    line-height: 1;
}

/* Greyer in the traditional column — the whole point of keeping the marker
   colour-free. The two fills are only 3 units apart from --purple-tint and
   --purple-soft respectively, so they are their own tokens: folding either into a
   neighbour would collapse the distinction the column is making.

   🔴 THE INK IS `--compare-ink-muted` (#8b85a0), NOT `--muted`, AND THAT WAS A REAL
   BUG (Andreas spotted it: "some of the icons are not correct"). DESIGN.md §9's drift
   log folds the scattered label greys (#8a8294 / #8b85a0 / #ada3bd) into `--muted`
   on light surfaces — but it also allows "lavender variants if tokenized
   deliberately", and this is one: the whole chip family is lavender-tinted (fills
   #e7ddfa / #ece9f3), and the marker's entire job is to read WEAKER than the purple
   one. `--muted` #6b6b6b is a neutral mid-grey and reads stronger, which made the
   seven greyed checkmarks noticeably darker than the A/B's. Tokenized with the
   fills, where it belongs. */
.brikk-pattern .brikk-inc-compare__table-wrap tbody tr > *:nth-child(3) strong {
    background: var(--wp--custom--compare-mark-muted);
    color: var(--wp--custom--compare-ink-muted);
}

/* <s>–</s> — not included. Same circle, outlined and empty. The strike itself is
   removed; the tag is carrying "not offered", not a visual line-through.

   🔴 ITS INK AND RING ARE THE LAVENDER PAIR, NOT --muted / --line-cool — and working
   out why is the §6e "match what it RENDERS, not what the rule says" lesson in a new
   costume. In landing.css the dash element carries BOTH `__mark` and `__mark--dash`,
   and `__mark--dash`'s own `color: var(--brikk-muted)` NEVER APPLIES: it is (0,2,0)
   and the `td.__trad .__mark` rule that sets #8b85a0 is (0,3,1). So the A/B's
   stylesheet says muted and renders #8b85a0. Folding the declaration that never runs
   is how this got shipped wrong. Its border is #cfc8de, which only the --dash rule
   sets, and which belongs to the same lavender family as the fills — not to
   --line-cool (#d6d3d4), a warmer neutral. */
.brikk-pattern .brikk-inc-compare__table-wrap tbody tr > *:nth-child(n+2) s {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    margin: 0 auto;
    border: 1px solid var(--wp--custom--compare-ring);
    border-radius: 50%;
    vertical-align: middle;
    background: none;
    color: var(--wp--custom--compare-ink-muted);
    font-family: var(--wp--preset--font-family--sans);
    font-size: 13px;
    font-weight: 400;
    line-height: 1;
    text-decoration: none;
}

/* <em>?</em> — unknown. Not a badge: an italic serif glyph. It states the 1.4
   RATIO because the cell above pins an absolute strut, and the A/B's "?" line box
   is 22 × 1.4 = 30.8px — which is what makes rows 1, 3, 4 and 5 as tall as they
   are. Without it the four "?" rows come out 6.2px short each. */
.brikk-pattern .brikk-inc-compare__table-wrap tbody tr > *:nth-child(n+2) em {
    font-family: var(--wp--preset--font-family--serif);
    font-style: italic;
    font-size: 22px;
    font-weight: 400;
    line-height: var(--wp--custom--lh-base);
    color: var(--wp--preset--color--muted);
    opacity: .85;
}

.brikk-pattern .brikk-inc-compare__note {
    max-width: 1000px;
    margin: 18px auto 0;
    font-size: 12.5px;
    font-weight: 300;
    line-height: var(--wp--custom--lh-copy);
    color: var(--wp--preset--color--muted);
}

/* `line-height: 0` so the raised marker cannot inflate the note's line box. The
   A/B renders this footnote FLAT on the baseline — not by choice, but because its
   blanket `.brikk-ab-page * { vertical-align: baseline }` reset flattens every
   sup and sub on the page. That is a defect, not a design decision, so the marker
   stays raised here; zeroing its leading keeps the note at the A/B's 20px instead
   of the 22.2px a raised sup would otherwise force. */
.brikk-pattern .brikk-inc-compare__note sup {
    margin-right: 2px;
    line-height: 0;
}


/* --- mid-CTA dark band ---------------------------------------------------- */

.brikk-pattern.brikk-inc-cta {
    padding-top: 110px;
    padding-bottom: 110px;
    color: var(--wp--preset--color--bg);
}

.brikk-pattern .brikk-inc-cta__inner > * {
    margin-block-start: 0;
}

/* The vertical hairline above the heading. A CSS pseudo, not a block: it is
   `aria-hidden` in the A/B markup, core/separator cannot draw a 1×54px vertical
   rule, and decoration should not be something a page edit can delete. Same call
   as the Trustpilot star in .brikk-hero__stat-value--star.
   `> *` in core's constrained-layout CSS matches ELEMENTS only, so this pseudo
   keeps its own centring. */
.brikk-pattern .brikk-inc-cta__inner::before {
    content: '';
    display: block;
    width: 1px;
    height: 54px;
    margin: 0 auto 36px;
    background: color-mix(in srgb, var(--wp--custom--on-accent) 35%, transparent);
}

.brikk-pattern .brikk-inc-cta__heading {
    max-width: 760px;
    margin: 0 auto 36px;
    font-size: clamp(32px, 4vw, 50px);
    font-weight: 500;
    line-height: 1.12;
    letter-spacing: var(--wp--custom--ls-heading);
    color: var(--wp--preset--color--bg);
}

.brikk-pattern .brikk-inc-cta__action {
    margin: 0;
}


/* --- responsive: all three sections -------------------------------------- */

@media (max-width: 1024.98px) {
    .brikk-pattern.brikk-inc-why,
    .brikk-pattern.brikk-inc-compare {
        padding-top: 72px;
        padding-bottom: 72px;
    }

    .brikk-pattern .brikk-inc-why__grid {
        gap: var(--wp--preset--spacing--5);
    }

    .brikk-pattern .brikk-inc-compare__table-wrap tr > * {
        padding: 15px 16px;
    }

    .brikk-pattern .brikk-inc-compare__table-wrap thead tr > * {
        padding-top: 26px;
        padding-bottom: 22px;
    }

    .brikk-pattern .brikk-inc-compare__table-wrap tbody tr > *:nth-child(n+2) {
        width: 130px;
    }

    .brikk-pattern.brikk-inc-cta {
        padding-top: 88px;
        padding-bottom: 88px;
    }
}

/* 900px — see the 🔴 note at the top of this block. Three properties step
   together: the grid collapses to one column, its gap tightens, and the stack is
   capped at 520px and centred. The photo grows with it. */
@media (max-width: 900px) {
    .brikk-pattern .brikk-inc-why__grid {
        grid-template-columns: 1fr;
        gap: 20px;
        max-width: 520px;
        margin-inline: auto;
    }

    .brikk-pattern .brikk-inc-why-card__img {
        height: 220px;
    }
}

/* 720px — the table stops being a table and becomes a stack of cards, one per
   comparison. This is the single biggest layout event on the page: the section
   grows 1279 → 2388px across that one pixel. See the 🔴 note at the top of this
   block for why the breakpoint is 720 and not 768. */
@media (max-width: 720px) {
    /* The column heads are still the accessible header row — hidden visually, not
       from assistive tech. (Same technique as .screen-reader-text in §9.) */
    .brikk-pattern .brikk-inc-compare__table-wrap thead {
        position: absolute;
        width: 1px;
        height: 1px;
        padding: 0;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
        border: 0;
    }

    .brikk-pattern .brikk-inc-compare__table-wrap table,
    .brikk-pattern .brikk-inc-compare__table-wrap tbody,
    .brikk-pattern .brikk-inc-compare__table-wrap tr,
    .brikk-pattern .brikk-inc-compare__table-wrap tr > * {
        display: block;
        width: 100%;
    }

    /* Let the warm section show between the cards. With the table still white the
       gaps fill in and each card's border reads as a doubled/hollow line. */
    .brikk-pattern .brikk-inc-compare__table-wrap table {
        background: transparent;
    }

    .brikk-pattern .brikk-inc-compare__table-wrap tr {
        margin-bottom: 14px;
        border: 1px solid var(--wp--custom--line-ink);
        background: var(--wp--preset--color--card);
    }

    /* ⚠️ THE LAST CARD'S MARGIN HAS TO GO, and only because of a container
       difference. The A/B's wrap is a plain <div>, so the last row's 14px bottom
       margin collapses straight out of it and the visible gap to the footnote is
       just the note's own 18px. Core's `.wp-block-table { overflow-x: auto }`
       makes OUR wrap a block formatting context, which traps that margin inside —
       so the wrap measured 14px taller and the gap became 32px. Zeroing it is the
       fix rather than unsetting core's overflow: the overflow guard is worth
       keeping, and "no margin after the last card" is the clearer rule anyway. */
    .brikk-pattern .brikk-inc-compare__table-wrap tr:last-child {
        margin-bottom: 0;
    }

    /* The desktop edge frame and the purple side band both go — in a stack they
       would draw lines down the middle of every card. */
    .brikk-pattern .brikk-inc-compare__table-wrap tr > *:nth-child(1),
    .brikk-pattern .brikk-inc-compare__table-wrap tr > *:nth-child(3),
    .brikk-pattern .brikk-inc-compare__table-wrap tbody tr > *:nth-child(2) {
        border-left: 0;
        border-right: 0;
    }

    .brikk-pattern .brikk-inc-compare__table-wrap tbody tr > *:nth-child(1) {
        padding: 15px 18px 12px;
        border-bottom: 1px solid var(--wp--custom--line-ink);
        font-weight: 500;
        font-size: 15px;
        opacity: 1;
    }

    .brikk-pattern .brikk-inc-compare__table-wrap tbody tr > *:nth-child(1) small {
        margin-top: 4px;
    }

    .brikk-pattern .brikk-inc-compare__table-wrap tbody tr > *:nth-child(n+2) {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 12px 18px;
        /* 🔴 `width: 100%` MUST BE RESTATED ON THIS SELECTOR. The block above sets
           `display: block; width: 100%` on `tr > *` — (0,3,1) — but the data cells'
           width is set by `tbody tr > *:nth-child(n+2)` at (0,3,2) (196px base,
           130px ≤1024), which WINS. So the stacked cards' value cells stayed 130px
           wide and the label/value row was squeezed into a third of the card while
           `justify-content: space-between` pushed the value off to the right.
           ⚠️ INVISIBLE TO A HEIGHT SWEEP: the cells are flex with `align-items:
           center`, so `.brikk-inc-compare` measured byte-identical to the A/B at
           every width ≤720. Found by looking at a screenshot. Third instance of the
           same specificity inversion in this block (the other two are the border
           resets below) — when rekeying a selector, re-check every rule the old one
           used to beat. */
        width: 100%;
        /* ⚠️ BACK TO THE 1.4 RATIO HERE, undoing the absolute strut the table-mode
           rule pins. A flex container has no strut — its height comes from the
           tallest ITEM — so the absolute 22.4px stops protecting anything and
           instead shrinks the two value cells by 5.6px each (20px text wants
           28px) while inflating the label pseudo past the 22px badge. The ratio
           gives the label 15.4px, the value 28px and the badge its own 22px,
           which is what the A/B renders. */
        line-height: var(--wp--custom--lh-base);
        /* The A/B's inner divider is rgba(30,23,38,.08) — 57% of the .14 frame ink,
           derived from the token rather than added as a second literal. */
        border-bottom: 1px solid color-mix(in srgb, var(--wp--custom--line-ink) 57%, transparent);
        text-align: right;
    }

    /* ⚠️ Must MATCH the setter's specificity, not undercut it. The rule above is
       `tbody tr > *:nth-child(n+2)` — two classes plus a nth-child, i.e. (0,3,2)
       with two element parts. A shorter `tr > *:last-child` is (0,3,1) and LOSES,
       which put a hairline back under the last value in every card. Same shape
       below. */
    .brikk-pattern .brikk-inc-compare__table-wrap tbody tr > *:last-child {
        border-bottom: 0;
    }

    /* 🔴 THE ROW LABELS ARE CSS, and they have to be: the A/B reads them from a
       per-cell `data-label` attribute, which a core/table cell cannot carry (see
       patterns/inc-compare.php). Structural labels only — never a number.
       ⚠️ These two strings are the ONLY Danish copy this section keeps in CSS. If
       the head labels are ever reworded, reword them here too. */
    .brikk-pattern .brikk-inc-compare__table-wrap tbody tr > *:nth-child(n+2)::before {
        font-family: var(--wp--preset--font-family--sans);
        font-size: 11px;
        font-weight: 500;
        letter-spacing: .14em;
        text-transform: uppercase;
        color: var(--wp--preset--color--muted);
    }

    .brikk-pattern .brikk-inc-compare__table-wrap tbody tr > *:nth-child(2)::before {
        content: 'Brikk';
        color: var(--wp--preset--color--purple);
    }

    .brikk-pattern .brikk-inc-compare__table-wrap tbody tr > *:nth-child(3)::before {
        content: 'Traditionelle mæglere';
    }

    /* Left-aligned in the row now, not centred in a column. */
    .brikk-pattern .brikk-inc-compare__table-wrap tbody tr > *:nth-child(n+2) strong,
    .brikk-pattern .brikk-inc-compare__table-wrap tbody tr > *:nth-child(n+2) s {
        margin: 0;
    }
}

@media (max-width: 640px) {
    .brikk-pattern.brikk-inc-why,
    .brikk-pattern.brikk-inc-compare {
        padding-top: 56px;
        padding-bottom: 56px;
    }

    .brikk-pattern .brikk-inc-why__head,
    .brikk-pattern .brikk-inc-compare__head {
        margin-bottom: 40px;
    }

    .brikk-pattern .brikk-inc-why-card__body {
        padding: 24px 24px 26px;
    }

    .brikk-pattern.brikk-inc-cta {
        padding-top: 72px;
        padding-bottom: 72px;
    }

    .brikk-pattern .brikk-inc-cta__inner::before {
        height: 44px;
        margin-bottom: 28px;
    }
}


/* --- the FAQ closes this page off ---------------------------------------- */

/* landing.css gives the FAQ a bottom hairline on THIS page only
   (`.brikk-ab-included .brikk-faq`), because here it is the last section before
   the footer and both surfaces are the warm canvas — without the rule they merge.
   On the front page the FAQ is followed by the dark bottom-CTA band, which
   supplies its own edge.
   Expressed as "the FAQ when it ENDS the page" rather than as a per-page class:
   the pattern is shared, and this is the actual condition the design responds to.
   Sections are direct children of <main class="brikk-main"> in both render paths
   (composed-from-code and post_content), and :last-child ignores text nodes. */
.brikk-main > .brikk-pattern.brikk-faq:last-child {
    border-bottom: 1px solid var(--wp--preset--color--line);
}

/* <<< BRIKK front-page section patterns */

/* =============================================================================
   12.6  BOLIGER TIL SALG  ·  .brikk-pheader / .brikk-plist / .brikk-card
   -----------------------------------------------------------------------------
   The property list at /boliger-til-salg/.
   Comp: claude-new-designs/properties-for-sale/list.png — a 1440px viewport
   framed inside a 1597px image (page canvas x=79..1518). Every number below was
   measured off it; see CLAUDE.md §6l for the extraction.

   Sections: patterns/properties-hero.php · [brikk-property-list] ·
   patterns/properties-cta.php, composed by
   page-templates/brikk-prebuilt-properties-for-sale.php.

   ⚠️ NOT a block-pattern grid. The list is a shortcode, so its markup is plain
   PHP output rather than core blocks — none of §12.4's `.brikk-pattern` marker
   dance applies to `.brikk-plist*` / `.brikk-card*`, because those class names
   exist nowhere in landing.css, brikk.css or any A/B template (checked
   mechanically). The two PATTERNS do carry the marker, and the only shared
   classes they touch are `.brikk-cta`/`.brikk-btn` behind the `--search` and
   `--light` modifiers, which A/B markup cannot match.

   MEASURED GEOMETRY (1440px viewport, page x 0 = canvas left)
     container ....... 1600 max, 65px gutter -> content 64..1375 (1312 wide)
     grid ............ 3 x 416px, 32px gap, rows 437px, 32px row gap
     card ............ photo 416x228, body 209, 1px border, 28px padding
     filter bar ...... full-bleed, 1px rules top+bottom, interior 93px,
                       controls 50px tall, search input 478x50, button 265x50
     result bar ...... sort control 230x44
     pagination ...... 44x44 boxes, 8px gap
     bottom band ..... 421px tall, ~70px vertical padding

   COLOUR SUBSTITUTIONS (comp -> token; all documented, all imperceptible)
     page bg      #f6f4f0 -> --bg      (#f5f2ee, delta 2)
     ink          #1e1826 -> --dark    (#1a1a1a; the comp's ink is faintly
                                        purple-tinted, the system's is neutral)
     dark surface #211c18 -> --dark    (delta 7; §6c folded #2d313b the same way)
     label greys  #8a8294 / #9c95a3 / #77737a -> --muted   (DESIGN.md §9 folds
                                        the scattered lavender-greys on light
                                        surfaces; §6e did the same for the hero)
   EXACT MATCHES (no substitution needed)
     card surface #fbfaf8 = --card-soft · badge #6a2cdb = --purple ·
     dark-CTA eyebrow/button/rule #9a73e6 = --on-dark-purple
   NEW TOKEN
     --line-card #e0dede — the card border and the filter-bar rules. Genuinely
     between the two existing hairlines (--line-cool #d6d3d4 is 10 units darker,
     --line-soft #e8e8e8 8 lighter) and it is the dominant structural line on
     this page, so it is tokenised rather than fudged. The card's INNER divider
     is a separate, lighter line (#e6e4e4) and folds into --line-soft.
   ============================================================================= */

/* --- 12.6.0  optical centring of all-caps labels -------------------------
   🔴 HELVETICA NEUE'S DECLARED METRICS PUT CAPS ABOVE THE CENTRE OF THEIR BOX.
   The face declares ascent 714 / descent 213, so its content box is 927 units
   tall while the capitals occupy 14..714 — their centre sits at 39.3% of the
   box instead of 50%, i.e. about 0.1em high. `align-items: center` centres the
   BOX, so every all-caps label in a fixed-height container renders ~1-1.5px
   high: measured on the badge, the køberkartotek button and the dark-card CTA.
   The comp does not show it because design tools centre by cap height.

   Fix: with `box-sizing: border-box` and an explicit height, a top padding of P
   moves the centred content down by P/2 — so 0.2em of top padding corrects the
   0.1em offset at any font size, and the box height is unchanged.

   ⚠️ Related to the `Helvetica Neue Input` metrics twin in §1, which fixes the
   same declaration for a different symptom (clipped glyph tops in form fields).
   Do NOT "fix" the metrics globally — the comps were rendered with them and
   every measured baseline on the site would shift. */
.brikk-card__badge,
.brikk-plist__register,
.brikk-plist__reset,
.brikk-plist__apply,
.brikk-plist__cta-btn,
.brikk-plist__drop-trigger,
.brikk-plist__sort-trigger,
.brikk-pattern .brikk-btn--light {
    padding-top: 0.2em;
}

/* --- 12.6.1  page header ------------------------------------------------- */

/* ⚠️ Deliberately not `.brikk-hero`: that is the marketing hero (photo, check
   list, CTAs, metrics panel, dark inversion at 640). This is a plain page
   header and shares none of it. */
.brikk-pattern.brikk-pheader {
    background: var(--wp--preset--color--bg);
    /* Measured: eyebrow ink 82px below the header rule, section 257px tall. */
    padding-block: 80px 46px;
    /* 🔴 THE GUTTER MOVES TO __inner — do not put it back on the outer element.
       The pattern's outer group carries `.brikk-gutter`, which is the right
       idiom for a pattern but the WRONG one for this page: it centres the
       1600px inner inside (100vw − 2×pad), whereas everything else on this page
       (.brikk-plist__filters-inner, __body, the grid, the pager) centres 1600px
       in the FULL viewport and takes the gutter as padding INSIDE it. The two
       agree only while the viewport is under 1600px — which is why 1440 looked
       fine — and diverge above it: measured 65px of misalignment between the h1
       and the search field at 1920, and 50px at 1700. Neutralised here rather
       than by editing the pattern so that an already-inserted copy of the
       markup (which would still carry .brikk-gutter) cannot double the padding. */
    padding-inline: 0;
}

.brikk-pattern .brikk-pheader__inner {
    max-width: var(--wp--custom--max);
    margin-inline: auto;
    padding-inline: var(--brikk-pad-x);
    display: grid;
    /* 1.74 : 1 puts the lead column's left edge at 844px into the container,
       which is where the comp has it. */
    grid-template-columns: minmax(0, 1.74fr) minmax(0, 1fr);
    gap: 32px;
    align-items: start;
}

.brikk-pattern .brikk-pheader__main > * {
    margin-block: 0;
}

/* The eyebrow is an inline-block primitive; as a <p> in a pattern it needs to
   be a block or the constrained layout cannot place it (§6e). */
.brikk-pattern p.brikk-pheader__eyebrow {
    display: block;
    position: relative;
    margin: 0;
    /* Sets the gap to the title: the comp puts the h1's ink 145px below the
       header rule, i.e. 63px under the eyebrow's own ink. */
    padding-bottom: 41px;
    color: var(--wp--preset--color--muted);
    line-height: var(--wp--custom--lh-base);
}

/* The 30x1px purple rule under the eyebrow. CSS, not a core/separator: pure
   decoration, and a page edit must not be able to delete it. */
.brikk-pattern .brikk-pheader__eyebrow::after {
    content: "";
    position: absolute;
    left: 0;
    /* From the TOP, deliberately: anchored to the bottom it would drift every
       time the padding that spaces the title is retuned. */
    top: 34px;
    width: 30px;
    height: 1px;
    background: var(--wp--preset--color--purple);
}

.brikk-pattern .brikk-pheader__title {
    margin: 0;
    font-family: var(--wp--preset--font-family--serif);
    font-size: 70px;
    font-weight: 500;
    line-height: var(--wp--custom--lh-tight);
    letter-spacing: var(--wp--custom--ls-heading);
    color: var(--wp--preset--color--dark);
}

.brikk-pattern .brikk-pheader__lead {
    margin: 0;
    /* 🔴 THE LEAD IS BOTTOM-ALIGNED WITH THE TITLE'S BASELINE, and that is
       measurable in both comps that use this component: the property list's
       2-line lead and the køberkartotek's 3-line lead BOTH end their last line
       at y=291, the same y as the h1's baseline. A fixed `padding-top: 69px`
       against `align-items: start` reproduces that for two lines only — the
       3-line lead then hangs 27px too low, which is exactly what the
       køberkartotek page measured before this changed. Aligning the box
       instead makes the component right for any number of lines.
       ⚠️ `align-self` beats the container's `align-items: start`, which the
       eyebrow/title column still needs. */
    align-self: end;
    /* The row's bottom is the title's BOX bottom; its baseline sits 10px above
       that (70px Cormorant, lh 1.05). Measured against BOTH comps — at 10px the
       property list's last lead line lands exactly and the køberkartotek's is
       within 1px. */
    padding-bottom: 10px;
    max-width: 430px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--body);
    font-weight: 400;
    line-height: var(--wp--custom--lh-copy);
    color: var(--wp--preset--color--muted);
}

@media (max-width: 1024px) {
    .brikk-pattern.brikk-pheader {
        padding-block: 56px 36px;
    }

    .brikk-pattern .brikk-pheader__inner {
        grid-template-columns: minmax(0, 1fr);
        gap: 24px;
    }

    .brikk-pattern .brikk-pheader__title {
        font-size: 56px;
    }

    /* Stacked, the lead no longer needs to drop to the title's cap line. */
    .brikk-pattern .brikk-pheader__lead {
        padding-top: 0;
        max-width: 560px;
    }
}

@media (max-width: 640px) {
    .brikk-pattern.brikk-pheader {
        padding-block: 40px 28px;
    }

    .brikk-pattern .brikk-pheader__title {
        font-size: 40px;
    }

    .brikk-pattern .brikk-pheader__lead {
        font-size: var(--wp--preset--font-size--body-sm);
    }

    /* ⚠️ The eyebrow-to-title gap was the ONE frozen desktop value in this
       header — everything else steps (padding-block 80/46 → 56/36 → 40/28, title
       70/56/40, lead 16/15). At 41px against a 40px title it is 1.117 of the
       type size where desktop is 0.630, i.e. 1.77x more air relative to the
       type, on the screen with the least to spare. 24px is not arbitrary: it is
       the header grid's own gap at <=1024, so the eyebrow→title gap then matches
       the title→lead gap. The rule moves with it and stays optically centred
       (52.5% of the gap above it, against 52.6% today). Worth 17px. */
    .brikk-pattern p.brikk-pheader__eyebrow {
        padding-bottom: 24px;
    }

    .brikk-pattern .brikk-pheader__eyebrow::after {
        top: 25px;
    }
}

/* --- 12.6.2  filter bar --------------------------------------------------- */

.brikk-plist {
    display: block;
    background: var(--wp--preset--color--bg);
}

/* Full-bleed: the bar's surface runs edge to edge, its CONTENT sits in the
   container. Hence the inner wrapper rather than a gutter on the form. */
.brikk-plist__filters {
    background: var(--wp--preset--color--card-soft);
    border-top: 1px solid var(--wp--custom--line-card);
    border-bottom: 1px solid var(--wp--custom--line-card);
    margin: 0;
}

.brikk-plist__filters-inner,
.brikk-plist__body {
    max-width: var(--wp--custom--max);
    margin-inline: auto;
    padding-inline: var(--brikk-pad-x);
}

.brikk-plist__filters-inner {
    display: flex;
    align-items: center;
    gap: 27px;
    min-height: 93px;
    padding-block: 21px;
}

/* Search field ------------------------------------------------------------ */

.brikk-plist__search {
    position: relative;
    display: flex;
    align-items: center;
    /* Fixed, not flexible: the controls beside it would otherwise squeeze the
       field to 445px. */
    flex: 0 0 478px;
    max-width: 478px;
    height: 50px;
    background: var(--wp--preset--color--card);
    border: 1px solid var(--wp--custom--line-card);
    /* ⚠️ STATED, NOT INHERITED. This box was a <label> until the suggestion list
       needed a valid parent, and §7's `label` rule was silently giving it 13px —
       so the switch to a <div> moved it to the body's 16px. Nothing rendered
       differently (the icon and the input both size themselves), but leaving a
       type property to inheritance on a shared control is exactly the §0.1 trap
       that has bitten this project three times. */
    font-size: var(--wp--preset--font-size--ui);
}

.brikk-plist__search-icon {
    position: absolute;
    left: 18px;
    width: 16px;
    height: 16px;
    max-width: none;
    color: var(--wp--preset--color--muted);
    pointer-events: none;
}

.brikk-plist__search input {
    flex: 1 1 auto;
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0 18px 0 48px;
    border: 0;
    background: none;
    font-family: var(--wp--custom--font-input);
    font-size: var(--wp--preset--font-size--ui);
    line-height: 1.2;
    color: var(--wp--preset--color--dark);
    appearance: none;
}

/* ⚠️ NOT --muted. The comp's placeholder is a much lighter grey (measured
   #b4afbb) — the same role the funnel already had a value for, now shared as
   --placeholder. Using --muted here reads as filled-in text, not a hint. */
.brikk-plist__search input::placeholder {
    color: var(--wp--custom--placeholder);
    opacity: 1;
}

.brikk-plist__search input::-webkit-search-cancel-button {
    display: none;
}

.brikk-plist__search:focus-within {
    border-color: var(--wp--preset--color--purple);
}

.brikk-plist__search input:focus {
    outline: none;
}

/* Location tags -----------------------------------------------------------
   Andreas, 2026-08-05: the chosen locations should read as tags, in a grey that
   fits the site, and several should be addable at once.

   ⚠️ GREY, NOT THE KØBERKARTOTEK TAG'S PURPLE (§12.7's `.brikk-kk__tag`:
   purple-tint fill, purple border, purple ink). Two reasons it is a different
   chip rather than a shared one: Andreas asked for grey, and these sit INSIDE a
   white field where a purple fill would compete with the field's own purple
   focus border. `--bg-dim` is the site's existing dim surface — the header
   dropdown and the suggestion row hover already use it.

   ⚠️ The row is `min-width: 0` and the field is a flex container, so the tags
   shrink before the input does rather than pushing it out of the box — the same
   automatic-minimum-size trap as the footer badge row (§6c). */

.brikk-plist__tags {
    display: flex;
    align-items: center;
    flex: 0 1 auto;
    flex-wrap: nowrap;
    gap: 6px;
    min-width: 0;
    /* Clears the 48px the search icon occupies; the input's own left padding is
       dropped in its place when tags are present (below). */
    margin-left: 48px;
    overflow-x: auto;
    scrollbar-width: none;
}

.brikk-plist__tags::-webkit-scrollbar {
    display: none;
}

/* 🔴 THE INPUT HAS TO STOP DEMANDING THE WHOLE BOX, or the tags are squeezed to
   nothing: its base rule is `flex: 1 1 auto; width: 100%`, and with `auto`
   flex-basis that 100% IS the basis — measured, the second chip rendered as
   "28…" with its × off the edge, so a visitor could neither read nor remove
   their own filter. `flex-basis: 90px` + a matching `min-width` lets the chips
   take their natural width first and leaves the field a usable remainder.
   ⚠️ `width: auto` as well — leaving `width: 100%` re-imposes the same demand
   through the width property even after the basis is fixed.
   With tags present the icon's clearance is also the tag row's margin, so the
   input must not repeat it or the caret starts 48px past the last chip. */
.brikk-plist__search:has(.brikk-plist__tags) input {
    flex: 1 1 90px;
    width: auto;
    min-width: 90px;
    padding-left: 10px;
}

/* 🔴 AND THE FIELD ITSELF NEEDS `min-width: 0`, or many tags tear the page open.
   A flex item's automatic minimum size is its MIN-CONTENT, and a nowrap row of
   ten chips has a min-content of ~1127px — so below 1200, where the bar wraps
   and the field becomes a full-width row, the field refused to shrink and the
   document overflowed by up to 827px at 320. (The tag row's own `min-width: 0`
   does not help: it lets the ROW shrink, not the field around it.) With this,
   the chips scroll inside the field instead. Third instance of the same
   automatic-minimum-size trap as the footer badge row — CLAUDE.md §6c. */
.brikk-plist__search:has(.brikk-plist__tags) {
    min-width: 0;
}

.brikk-plist__tag {
    display: inline-flex;
    align-items: center;
    flex: 0 0 auto;
    gap: 6px;
    max-width: 190px;
    height: 30px;
    /* 0.2em of top padding is §12.6.0's cap-centring correction — Helvetica
       Neue's capitals sit ~0.1em high inside its content box, and this row has a
       fixed height, so the label would otherwise ride high. */
    padding: 0.2em 8px 0 11px;
    background: var(--wp--custom--bg-dim);
    border: 1px solid var(--wp--custom--line-ink);
    color: var(--wp--preset--color--dark);
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui-sm);
    line-height: 1;
    white-space: nowrap;
}

.brikk-plist__tag-label {
    overflow: hidden;
    text-overflow: ellipsis;
}

/* THREE OR MORE: one summary instead of the chips. The `is-collapsed` class is
   set by PHP and maintained by the JS — see the note in shortcode-property-list
   for why the count is a class and not a `:has(:nth-child(3))` selector. */

.brikk-plist__tags.is-collapsed {
    /* Nothing scrolls in this state, so the affordance is not needed and the
       row can hold its own width. */
    overflow-x: visible;
}

.brikk-plist__tags.is-collapsed .brikk-plist__tag:not(.brikk-plist__tag--summary) {
    display: none;
}

.brikk-plist__tag--summary {
    /* Present in the markup from TWO tags but only shown when something asks
       for it — the ≤420 rule below cannot create an element PHP did not print. */
    display: none;
    /* Sized by its text, and it never needs truncating: "10 områder valgt" is
       the longest it can be. No × — a summary has nothing single to remove, and
       opening the field is what manages them. */
    max-width: none;
    padding-right: 11px;
    color: var(--wp--preset--color--dark);
}

.brikk-plist__tags.is-collapsed .brikk-plist__tag--summary {
    display: inline-flex;
}

/* 🔴 BELOW 420px, TWO CHIPS ALREADY DO NOT FIT — measured: the row scrolls at
   320 and the placeholder is clipped at 390 (field 350px = 81 + 120 chips + 6
   gap + 48 icon + the input's 90px floor, which is 345 before the placeholder
   needs a single pixel). So the collapse happens one step earlier here.
   ⚠️ A SIBLING COMBINATOR, not `:has()`: the summary is printed FIRST, so
   "the chips that follow a shown summary" is exactly the set to hide — and it
   works on every browser rather than most. */
@media (max-width: 420px) {
    .brikk-plist__tags .brikk-plist__tag--summary {
        display: inline-flex;
    }

    .brikk-plist__tag--summary ~ .brikk-plist__tag {
        display: none;
    }
}

.brikk-plist__tag-remove {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    padding: 0;
    background: none;
    border: 0;
    color: var(--wp--preset--color--muted);
    cursor: pointer;
    /* The × is a <button> with JS and an <a> without it — both need the link
       reset, because §4 gives anchors an underline. */
    text-decoration: none;
}

.brikk-plist__tag-remove:hover,
.brikk-plist__tag-remove:focus-visible {
    color: var(--wp--preset--color--dark);
}

.brikk-plist__tag-remove svg {
    display: block;
    /* 🔴 STATE THE SIZE — §3's reset gives every svg `max-width: 100%`, which
       resolves to 0 against a zero-width parent (§6h). */
    width: 9px;
    height: 9px;
    max-width: none;
}

/* Location autocomplete ---------------------------------------------------
   No comp draws this — the open-state comps that arrived 2026-07-31 cover the
   four filter panels and the sort menu, not the search field. It is therefore
   composed from the panel it hangs beside: same offset below the bar, same
   translucent --line-ink hairline, same surface and shadow, so the two read as
   one family. The rows are the køberkartotek combobox's (§12.7), which is the
   site's other list of this shape.

   ⚠️ `.brikk-plist__search` is already position:relative for the search icon,
   which is what this anchors to.
   ⚠️ It is `hidden` until the script fills it, so it costs nothing without JS. */

.brikk-plist__suggest {
    position: absolute;
    /* The filter panels' own offset, measured off their comps. */
    top: calc(100% + 10px);
    left: 0;
    z-index: var(--wp--custom--z-chrome);
    width: 100%;
    /* The field shrinks to 240px between 1200 and 1440 and the list must stay
       readable; capped so it can never escape the viewport on a phone. */
    min-width: 300px;
    max-width: calc(100vw - 40px);
    max-height: 340px;
    margin: 0;
    padding: 6px 0;
    overflow-y: auto;
    list-style: none;
    background: var(--wp--preset--color--card);
    border: 1px solid var(--wp--custom--line-ink);
    box-shadow: 0 24px 60px rgba(30, 23, 38, 0.14);
}

.brikk-plist__suggest[hidden] {
    /* 🔴 STATE IT. `hidden` is a (0,0,0) UA rule and this block is (0,1,0), so
       `position: absolute` alone would keep painting an empty framed box under
       the field. Same class of trap as the closed <details> panel that still
       occupied layout (§6l). */
    display: none;
}

.brikk-plist__suggest-group {
    padding: 12px 18px 6px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--micro);
    font-weight: 500;
    letter-spacing: var(--wp--custom--ls-ui);
    text-transform: uppercase;
    color: var(--wp--preset--color--muted);
}

.brikk-plist__suggest-option {
    padding: 10px 18px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui);
    line-height: 1.35;
    color: var(--wp--preset--color--dark);
    cursor: pointer;
}

/* `.is-active` is the keyboard's highlight and hover the pointer's — the same
   state, so they must not look different. */
.brikk-plist__suggest-option.is-active,
.brikk-plist__suggest-option:hover {
    background: var(--wp--custom--bg-dim);
}

.brikk-plist__suggest-empty {
    padding: 12px 18px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui);
    line-height: 1.35;
    color: var(--wp--preset--color--muted);
}

/* The "Valgte områder" rows — the dropdown as a MANAGER for what is already
   applied (Andreas, 2026-08-05: with three postcodes in a 50px field only two
   fit, so the third could not be removed without removing the others first).
   Deliberately NOT styled like a suggestion: no pointer cursor and no hover
   fill on the row, because the row itself does nothing — only its × does. */

.brikk-plist__suggest-selected {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 9px 12px 9px 18px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui);
    line-height: 1.35;
    color: var(--wp--preset--color--dark);
}

.brikk-plist__suggest-remove {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    /* 32px, not the chip's 16: this is the control that has to be HITTABLE on a
       phone — the whole reason the list exists is that the chip's × is not. */
    width: 32px;
    height: 32px;
    padding: 0;
    background: none;
    border: 0;
    color: var(--wp--preset--color--muted);
    cursor: pointer;
}

.brikk-plist__suggest-remove:hover,
.brikk-plist__suggest-remove:focus-visible {
    color: var(--wp--preset--color--purple);
}

.brikk-plist__suggest-remove svg {
    display: block;
    /* 🔴 STATE THE SIZE — §3's reset (§6h). */
    width: 10px;
    height: 10px;
    max-width: none;
}

/* Dropdown triggers ------------------------------------------------------- */

.brikk-plist__controls {
    display: flex;
    align-items: center;
    flex: 1 1 auto;
    justify-content: center;
}

.brikk-plist__drop {
    position: relative;
}

/* ⚠️ The separator is a SHORT CENTRED RULE, not a full-height border. It was a
   border-left on the details, so it took the trigger's whole 50px; the comp —
   and the master list.png, which this was supposedly signed off against — both
   draw 26px centred in the bar. Needs the pseudo-element because a border
   cannot be inset.

   ⚠️ IT HANGS OFF THE TRIGGER, NOT OFF THE <details>, and that is load-bearing.
   At <=1024 the panel is re-anchored to the whole bar, which means the
   <details> has to become `position: static` there (§12.6.10) — and a separator
   owned by the <details> would then have resolved against `.brikk-plist__filters`
   and slid to the far left of the page. The trigger's border box is identical to
   the <details>'s (the summary is its only in-flow child and fills it), so this
   renders byte-identically at every width while surviving that change.
   Absolutely positioned, so it is not a flex item of the trigger. */
.brikk-plist__drop + .brikk-plist__drop > .brikk-plist__drop-trigger::before {
    content: "";
    position: absolute;
    left: 0;
    top: 50%;
    width: 1px;
    height: 26px;
    transform: translateY(-50%);
    background: var(--wp--custom--line-card);
}

.brikk-plist__drop-trigger {
    position: relative;
    display: flex;
    align-items: center;
    gap: 9px;
    height: 50px;
    padding: 0.2em 18px 0;
    cursor: pointer;
    list-style: none;
    white-space: nowrap;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui-sm);
    font-weight: 500;
    /* ⚠️ --ls-nav (0.16em), NOT --ls-ui (0.2em). Measured off the comp: at 0.2em
       "BOLIGTYPER" renders 117px against the comp's 110, while the dark button
       beside it matches 0.2em to within 1px. The bar genuinely uses two
       trackings — don't "unify" them. */
    letter-spacing: var(--wp--custom--ls-nav);
    text-transform: uppercase;
    color: var(--wp--preset--color--dark);
}

/* Safari renders a disclosure triangle unless BOTH of these are cleared. */
.brikk-plist__drop-trigger::-webkit-details-marker {
    display: none;
}

.brikk-plist__drop-trigger::marker {
    content: "";
}

.brikk-plist__chevron,
.brikk-plist__filter-icon,
.brikk-plist__sort-icon {
    flex: none;
    /* ⚠️ §3's reset gives every svg `max-width: 100%`, which collapses an icon
       whose parent is narrower than it — the bug that made the nav chevrons
       0x0 (§6h). State the box explicitly, never leave it to an attribute. */
    max-width: none;
    color: currentColor;
}

.brikk-plist__chevron {
    width: 9px;
    height: 6px;
    transition: transform var(--wp--custom--transition);
}

/* 🟠 THE CHEVRON DOES NOT FLIP ON OPEN. All four open-state comps draw it still
   pointing down, so that is what ships. Flagged rather than silently "fixed":
   a static mock-up may simply reuse the closed component, and rotating it is a
   real affordance — restoring it is re-adding `transform: rotate(180deg)` here. */

.brikk-plist__filter-icon {
    width: 16px;
    height: 14px;
}

.brikk-plist__drop-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 17px;
    height: 17px;
    padding: 0 4px;
    background: var(--wp--preset--color--purple);
    color: var(--wp--custom--on-accent);
    /* Was a raw 10px, below the smallest token on the site. The badge appears in
       no comp (none of them show an active filter), so nothing is being matched
       here and the token is simply correct. */
    font-size: var(--wp--preset--font-size--micro);
    letter-spacing: 0;
}

/* 🔴 A CLOSED PANEL MUST NOT PARTICIPATE IN LAYOUT.
   Chrome no longer gives `details:not([open]) > :not(summary)` display:none — it
   uses content-visibility, which keeps a real box. The absolutely-positioned
   panels below therefore still had a rect and pushed document.scrollWidth past
   the viewport at several widths, i.e. a horizontal scrollbar caused by menus
   nobody had opened. Measured, not theoretical. */
.brikk-plist__drop:not([open]) .brikk-plist__panel,
.brikk-plist__sort:not([open]) .brikk-plist__sort-menu {
    display: none;
}

/* ⚠️ An open trigger used to be BYTE-IDENTICAL to a closed one — measured on
   colour, background, weight, border, decoration, opacity and box, for all four
   panels at 320/390/768. Nothing on the page said which filter the open panel
   belonged to: the chevron deliberately does not rotate (see above), and at
   <=1024 the panel spans the whole bar rather than sitting under its control, so
   proximity cannot carry the attribution either. */
.brikk-plist__drop[open] > .brikk-plist__drop-trigger {
    color: var(--wp--preset--color--purple);
}

/* Dropdown panels ---------------------------------------------------------
   Measured 1:1 against the open-state comps that arrived 2026-07-31
   (claude-new-designs/properties-for-sale/Screenshot … 12.14.39 / 12.14.59 /
   12.15.07), all captured at DPR 2 on a 1440px viewport, so every figure below
   is a comp pixel halved. This SUPERSEDES the "no comp exists for the open
   state" note the panels were first built under.

   ⚠️ The comps' CONTENT is dummy (Andreas, 2026-07-31: "it's just there to show
   what the design looks like … use the options we already have on the site
   only, and just copy the design"). So the type list, the filters and the sort
   options stay exactly as they were — only the design is taken from the comps.
   That is why there is no Fritekst field, no amenity checkboxes and no
   Byggeår group here even though the comps show them. */
.brikk-plist__panel {
    position: absolute;
    /* Comp: trigger bottom + 10px, which lands ~12px ABOVE the filter bar's
       bottom hairline — the panel deliberately overlaps the bar and paints over
       that hairline. Confirmed independently on all three panel comps. */
    top: calc(100% + 10px);
    left: 0;
    z-index: var(--wp--custom--z-chrome);
    /* 🔴 EXPLICIT WIDTHS, and this is a bug fix as much as a design change.
       `width: max-content` made the panel's width depend on the font metrics of
       the number inputs inside it — the same page measured 389 / 398 / 420px
       across runs depending on how far the webfonts had settled. A panel with no
       designed width cannot be measured against a comp at all. */
    width: 458px;
    max-width: calc(100vw - 40px);
    padding: 28px;
    background: var(--wp--preset--color--card);
    /* Translucent, not the opaque --line-card: over the bar it reads #d7d3d6,
       over the page #d0cdce, and it darkens over a photo. Solved to alpha .14
       against rgb(30,23,38) on three different backdrops = --line-ink. */
    border: 1px solid var(--wp--custom--line-ink);
    box-shadow: 0 24px 60px rgba(30, 23, 38, 0.14);
}

.brikk-plist__panel--types {
    width: 518px;
}

.brikk-plist__panel--right {
    left: auto;
    right: 0;
    width: 498px;
}

/* Type chips -------------------------------------------------------------
   The comp replaces the checkbox list with bordered chips in a 3-column grid:
   145.33 × 42px over a 460px content width, 12px gaps, 1px hairline, square
   corners, white fill, label 13px/500 centred. The input is still a checkbox —
   it is visually hidden but stays focusable so the filter works without JS. */
.brikk-plist__chips {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 12px;
}

.brikk-plist__chip {
    position: relative;
    display: block;
    cursor: pointer;
}

.brikk-plist__chip input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.brikk-plist__chip-face {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 42px;
    padding: 0 10px;
    text-align: center;
    background: var(--wp--preset--color--card);
    /* --line-ink, matching the panel's own border rather than the bar's
       --line-card. Solving the comp's chip hairline over three backdrops gives
       one consistent alpha-.14 ink for every line inside the panel; over white
       that renders #dfdee0, which is within 2 units of --line-card anyway, so
       this is about keeping one line colour inside the panel, not about hue. */
    border: 1px solid var(--wp--custom--line-ink);
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui);
    font-weight: 500;
    line-height: 1.2;
    color: var(--wp--preset--color--dark);
    transition: border-color var(--wp--custom--transition), color var(--wp--custom--transition);
}

.brikk-plist__chip:hover .brikk-plist__chip-face {
    border-color: var(--wp--preset--color--dark);
}

/* ⚠️ Not :has() — §5b had to back that out once for silently no-opping on
   browsers without support, and a selected filter that does not look selected
   is exactly the kind of failure that is invisible until a user complains.
   The comp shows no selected chip, so the purple is composed from the design
   language. */
.brikk-plist__chip input:checked + .brikk-plist__chip-face {
    border-color: var(--wp--preset--color--purple);
    color: var(--wp--preset--color--purple);
}

.brikk-plist__chip input:focus-visible + .brikk-plist__chip-face {
    outline: 2px solid var(--wp--preset--color--purple);
    outline-offset: 2px;
}

/* Range groups ------------------------------------------------------------ */

.brikk-plist__range + .brikk-plist__range {
    margin-top: 26px;
}

/* ⚠️ SENTENCE CASE, not the tracked uppercase eyebrow this used to be. The comp
   sets every panel group heading in 15px/500 full-strength ink with no
   tracking — measured twice independently (cap height 10.75px and x-height
   7.75px both solve to 15px, and the ink width matches weight 500 at zero
   tracking to within 0.5px). */
.brikk-plist__range-label {
    display: block;
    margin-bottom: 16px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 15px;
    font-weight: 500;
    line-height: 1.25;
    letter-spacing: 0;
    text-transform: none;
    color: var(--wp--preset--color--dark);
}

.brikk-plist__range-fields {
    display: flex;
    gap: 10px;
}

.brikk-plist__range-fields input,
.brikk-plist__range-fields select {
    flex: 1 1 0;
    width: 100%;
    height: 42px;
    margin: 0;
    padding: 0 12px;
    background: var(--wp--preset--color--card);
    border: 1px solid var(--wp--custom--line-card);
    font-family: var(--wp--custom--font-input);
    font-size: var(--wp--preset--font-size--ui);
    color: var(--wp--preset--color--dark);
    appearance: none;
}

/* 🔴 iOS SAFARI ZOOMS THE WHOLE PAGE WHEN A SUB-16px FIELD IS FOCUSED, and does
   not zoom back — so the visitor then reads the results they just filtered
   through a viewport ~23% narrower (16/13) than any of this CSS assumes, and has
   to pinch out. §7 already ships exactly this guard for every other field on the
   site, and `.brikk-broker__search-input` carries it too; this page is the one
   that dropped it, and the fields stayed at --ui (13px).

   ⚠️ IT IS A SOURCE-ORDER TIE, NOT A SPECIFICITY LOSS — and getting that right
   is what dictates where this rule may live. `:where(.brikk-redesign)
   input[type='search']` looks weaker than `.brikk-plist__search input` but is
   not: :where() contributes nothing, yet an ATTRIBUTE selector carries
   class-level weight, so both are (0,1,1). They tie, and §7 loses only because
   it is ~7,000 lines earlier. Verified in isolation: swap the two rules' order
   and the field becomes 16px; place a genuinely (0,0,1) selector last and it
   still loses. So specificity cannot fix this — position is the only lever.

   ⚠️ MUST THEREFORE SIT AFTER BOTH RULES IT CORRECTS. The selectors are
   identical to theirs, so it wins on source order alone — placed any earlier
   (next to the search field, say) the range-field rule above would win it back.

   ⚠️ Deliberately NOT inside a max-width query, unlike §7's copy. iPadOS Safari
   supports -webkit-touch-callout and reports well over 1024px, so a width-scoped
   guard leaves every iPad zooming. `-webkit-touch-callout` matches iOS and
   nothing else, which IS the condition — the width was never part of it. On any
   non-iOS browser this rule does not exist and the comp's 13px is untouched.

   ⚠️ The number inputs matter even though the slider hides them: they are the
   no-JS path, which is this panel's documented fallback. */
@supports (-webkit-touch-callout: none) {
    .brikk-plist__search input,
    .brikk-plist__range-fields input,
    .brikk-plist__range-fields select {
        font-size: var(--wp--preset--font-size--body);
    }
}

/* The value pill + dual-handle slider ------------------------------------
   Built by assets/js/property-filters.js on top of the number inputs, which it
   hides and keeps writing through to — so this whole block only ever applies
   when the JS is running, and the panel degrades to those inputs if it is not.
   Geometry from the Pris and Filtre comps: pill 40px tall, fully rounded, dark
   fill, 14px/500 white, 22px side padding; 14px down to the handle row; rail
   2px; handles 30px white circles with a 1px ring and a soft downward shadow;
   handles flush with the content box at both ends. */

.brikk-plist__range--slider .brikk-plist__range-fields {
    display: none;
}

.brikk-plist__pill {
    display: inline-flex;
    align-items: center;
    height: 40px;
    padding: 0 22px;
    border-radius: var(--wp--custom--radius-pill);
    background: var(--wp--preset--color--dark);
    color: var(--wp--custom--on-accent);
    font-family: var(--wp--preset--font-family--sans);
    font-size: 14px;
    font-weight: 500;
    line-height: 1;
    white-space: nowrap;
}

.brikk-plist__track {
    position: relative;
    display: block;
    /* The row is exactly one handle tall, so the rail can be centred in it and
       the ticks below hang off its bottom edge. */
    height: 30px;
    margin-top: 14px;
}

/* The unselected rail. The comp can only show the selected state (both handles
   sit at the extremes there, so the whole rail is dark), so the lighter
   out-of-range colour is composed from the design language. */
.brikk-plist__track::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 14px;
    height: 2px;
    background: var(--wp--custom--line-card);
}

/* ⚠️ The fill is inset by the handle RADIUS at both ends. A native range input
   travels its thumb CENTRE from 15px to width−15px, so a naive left/right
   percentage would drift from the handles by up to 15px at the extremes.
   --low/--high are unitless 0–1 fractions written by the JS. */
.brikk-plist__track-fill {
    position: absolute;
    top: 14px;
    height: 2px;
    left: calc(15px + var(--low, 0) * (100% - 30px));
    right: calc(15px + (1 - var(--high, 1)) * (100% - 30px));
    background: var(--wp--preset--color--dark);
}

.brikk-plist__thumb {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 30px;
    margin: 0;
    padding: 0;
    background: none;
    border: 0;
    appearance: none;
    /* Both inputs span the whole track, so the upper one would swallow every
       click. Only the thumbs themselves take pointer events. */
    pointer-events: none;
}

.brikk-plist__thumb::-webkit-slider-runnable-track {
    height: 30px;
    background: none;
    border: 0;
}

.brikk-plist__thumb::-moz-range-track {
    height: 30px;
    background: none;
    border: 0;
}

.brikk-plist__thumb::-webkit-slider-thumb {
    appearance: none;
    pointer-events: auto;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: var(--wp--preset--color--card);
    border: 1px solid var(--wp--custom--plist-thumb-ring);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.16);
    cursor: grab;
}

.brikk-plist__thumb::-moz-range-thumb {
    pointer-events: auto;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: var(--wp--preset--color--card);
    border: 1px solid var(--wp--custom--plist-thumb-ring);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.16);
    cursor: grab;
}

.brikk-plist__thumb:focus-visible::-webkit-slider-thumb {
    outline: 2px solid var(--wp--preset--color--purple);
    outline-offset: 2px;
}

.brikk-plist__thumb:focus-visible::-moz-range-thumb {
    outline: 2px solid var(--wp--preset--color--purple);
    outline-offset: 2px;
}

/* The A–G scale under the Energimærke slider. space-between across the full
   content width: the comp's seven ink positions match that model to within
   1.3px at every one of them. */
.brikk-plist__ticks {
    display: flex;
    justify-content: space-between;
    margin-top: 9px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui);
    font-weight: 500;
    line-height: 1.2;
    color: var(--wp--custom--plist-tick);
}

/* ⚠️ NONE of the comps show an apply button — every panel ends with its last
   control and the same 28px of padding, i.e. the design implies the filter
   applies on its own. property-filters.js therefore marks the form enhanced and
   submits when a panel closes with something changed. The button is kept in the
   markup and only hidden HERE, so without JS it is still the way to apply. */
.brikk-plist__filters.is-enhanced .brikk-plist__apply {
    display: none;
}

.brikk-plist__apply {
    display: block;
    width: 100%;
    margin-top: 18px;
    height: 42px;
    padding: 0.2em 18px 0;
    border: 0;
    background: var(--wp--preset--color--purple);
    color: var(--wp--custom--on-accent);
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui-sm);
    font-weight: 500;
    letter-spacing: var(--wp--custom--ls-ui);
    text-transform: uppercase;
    cursor: pointer;
    transition: background var(--wp--custom--transition);
}

.brikk-plist__apply:hover,
.brikk-plist__apply:focus-visible {
    background: var(--wp--custom--purple-hover);
}

/* Køberkartotek button ---------------------------------------------------- */

.brikk-plist__register {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 50px;
    padding: 0.2em 27px 0;
    background: var(--wp--preset--color--dark);
    color: var(--wp--custom--on-accent);
    border: 0;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui-sm);
    font-weight: 500;
    letter-spacing: var(--wp--custom--ls-ui);
    text-transform: uppercase;
    text-decoration: none;
    white-space: nowrap;
    transition: background var(--wp--custom--transition);
}

.brikk-plist__register:hover,
.brikk-plist__register:focus-visible {
    background: var(--wp--preset--color--purple);
    color: var(--wp--custom--on-accent);
}

/* "Ryd filtre" ------------------------------------------------------------
   A text link, not a button: it UNDOES work rather than doing any, so it has to
   read as the quietest control in the bar — the køberkartotek button beside it
   is already the only filled thing here. Rendered by PHP only when at least one
   filter is applied, so it costs no height in the default state. */
.brikk-plist__reset {
    flex: none;
    display: inline-flex;
    align-items: center;
    height: 50px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui-sm);
    font-weight: 500;
    letter-spacing: var(--wp--custom--ls-nav);
    text-transform: uppercase;
    text-decoration: none;
    white-space: nowrap;
    color: var(--wp--preset--color--muted);
    transition: color var(--wp--custom--transition);
}

.brikk-plist__reset:hover,
.brikk-plist__reset:focus-visible {
    color: var(--wp--preset--color--purple);
}

/* --- 12.6.3  result bar --------------------------------------------------- */

.brikk-plist__body {
    padding-block: 47px 64px;
    transition: opacity 120ms ease;
}

/* ⚠️ THE 180ms DELAY IS THE POINT, not decoration. property-filters.js swaps the
   results in place instead of reloading, and locally that round trip is ~50ms —
   so a dim with no delay would itself be the blink this whole mechanism exists
   to remove. Delaying the transition means a fast response finishes and removes
   the class before the fade ever starts, and only a genuinely slow one shows
   any feedback. Removing the class fades back with no delay. */
.brikk-plist__body.is-loading {
    opacity: 0.55;
    transition: opacity 120ms ease 180ms;
}

.brikk-plist__resultbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    /* Lets the flex algorithm pick the layout instead of a breakpoint: the row
       survives to 460px and only then breaks, which is 177px later than the
       hard `flex-direction: column` at <=640 used to give up (see §12.6.10). */
    flex-wrap: wrap;
    gap: 24px;
    margin-bottom: 37px;
}

.brikk-plist__count {
    margin: 0;
    font-family: var(--wp--preset--font-family--sans);
    /* 22px, measured against the comp rendering the IDENTICAL string
       ("Viser 14 boliger"): 16px was 25% narrow and the 20px heading-5 preset
       still 11% narrow. Off-scale on purpose — the brief is a measured 1:1. */
    font-size: 22px;
    line-height: var(--wp--custom--lh-base);
    color: var(--wp--preset--color--muted);
}

.brikk-plist__count strong {
    font-weight: 700;
    color: var(--wp--preset--color--dark);
}

.brikk-plist__sort {
    position: relative;
    flex: none;
}

.brikk-plist__sort-trigger {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 230px;
    height: 44px;
    padding: 0.2em 16px 0;
    cursor: pointer;
    list-style: none;
    background: var(--wp--preset--color--card);
    border: 1px solid var(--wp--custom--line-card);
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui-sm);
    font-weight: 500;
    /* 0.1em, NOT the bar's --ls-nav (0.16em). Measured: "VÆLG SORTERING" spans
       122.5px of ink in the comp, which a 12px/500 render reproduces at 1.19px
       of tracking; at 0.16em it is 132px, i.e. 9.5px too wide. A literal for the
       same reason the 22px count is one — it is this control's value, not a
       system step. */
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--wp--preset--color--dark);
}

.brikk-plist__sort-trigger::-webkit-details-marker {
    display: none;
}

.brikk-plist__sort-trigger::marker {
    content: "";
}

.brikk-plist__sort-icon {
    width: 14px;
    height: 14px;
    color: var(--wp--preset--color--muted);
}

/* ⚠️ §12.6.0's cap-centring `padding-top: 0.2em` on the trigger pushes EVERY
   flex child down, not just the all-caps text — align-items:center then splits
   that padding, leaving both icons ~1.2px low against the comp's dead-centred
   ones. Give the icons back half of it; the text keeps the correction. */
.brikk-plist__sort-trigger .brikk-plist__sort-icon,
.brikk-plist__sort-trigger .brikk-plist__chevron {
    margin-top: -0.1em;
}

.brikk-plist__sort-label {
    flex: 1 1 auto;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ⚠️ The menu is NOT aligned to the trigger. The comp puts its left edge 1px
   OUTSIDE the trigger's and makes it 248px wide, so it overhangs the container's
   right edge by 17px — deliberate, verified at ten scanlines. The 11px gap is
   also nearly double what this had. */
.brikk-plist__sort-menu {
    position: absolute;
    top: calc(100% + 11px);
    left: -1px;
    right: auto;
    z-index: var(--wp--custom--z-chrome);
    width: 248px;
    max-width: calc(100vw - 40px);
    margin: 0;
    /* Asymmetric top/bottom — measured, not a rounding artefact. */
    padding: 14px 0 10px;
    list-style: none;
    background: var(--wp--preset--color--card);
    border: 1px solid var(--wp--custom--line-ink);
    box-shadow: 0 24px 60px rgba(30, 23, 38, 0.14);
}

.brikk-plist__sort-menu li {
    margin: 0;
}

/* ⚠️ The row pitch is a dead-constant 39.5px INCLUDING the current row, which is
   a size and weight larger than the others — so the height has to be fixed
   rather than fall out of padding + line-height, or the menu would grow by 4px
   whenever the current option changed. */
.brikk-plist__sort-option {
    display: flex;
    align-items: center;
    min-height: 39.5px;
    padding: 0 23px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui);
    line-height: 1.3;
    color: var(--wp--preset--color--dark);
    text-decoration: none;
}

.brikk-plist__sort-option:hover,
.brikk-plist__sort-option:focus-visible {
    background: var(--wp--custom--bg-dim);
    color: var(--wp--preset--color--dark);
}

/* The comp marks the active sort by size AND weight as well as colour. */
.brikk-plist__sort-option.is-current {
    font-size: 14px;
    font-weight: 500;
    color: var(--wp--preset--color--purple);
}

/* --- 12.6.4  the grid ----------------------------------------------------- */

.brikk-plist__grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 32px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.brikk-plist__item {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
}

.brikk-plist__item::before,
.brikk-plist__item::marker {
    content: none;
}

/* --- 12.6.5  property card ------------------------------------------------ */

.brikk-card {
    display: flex;
    width: 100%;
    background: var(--wp--preset--color--card-soft);
    border: 1px solid var(--wp--custom--line-card);
}

.brikk-card__link {
    display: flex;
    flex-direction: column;
    width: 100%;
    color: inherit;
    text-decoration: none;
}

.brikk-card__media {
    position: relative;
    display: block;
    /* 416x228 in the comp. An aspect-ratio rather than a fixed height so the
       photo keeps its crop at every column width. */
    aspect-ratio: 416 / 228;
    overflow: hidden;
    background: var(--wp--custom--bg-dim);
}

.brikk-card__img {
    display: block;
    width: 100%;
    height: 100%;
    max-width: 100%;
    object-fit: cover;
    transition: transform 420ms ease;
}

.brikk-card__img--empty {
    display: block;
    width: 100%;
    height: 100%;
    background: var(--wp--custom--bg-dim);
}

.brikk-card__link:hover .brikk-card__img {
    transform: scale(1.03);
}

.brikk-card__badge {
    position: absolute;
    top: 14px;
    left: 14px;
    display: inline-flex;
    align-items: center;
    height: 23px;
    padding: 0.2em 10px 0;
    background: var(--wp--preset--color--purple);
    color: var(--wp--custom--on-accent);
    font-family: var(--wp--preset--font-family--sans);
    font-size: 10px;
    font-weight: 500;
    /* 0.12em renders the label 99px wide against the comp's 106. */
    letter-spacing: var(--wp--custom--ls-nav);
    text-transform: uppercase;
    white-space: nowrap;
}

.brikk-card__body {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    /* Vertical padding is NOT the horizontal 28px: measured, the comp puts the
       title's ink 29px below the photo and leaves 26px under the price. */
    padding: 25px 28px 24px;
}

.brikk-card__title {
    margin: 0;
    font-family: var(--wp--preset--font-family--serif);
    font-size: 26px;
    font-weight: 500;
    line-height: 1.15;
    letter-spacing: var(--wp--custom--ls-heading);
    color: var(--wp--preset--color--dark);
}

.brikk-card__place {
    margin: 6px 0 0;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui);
    line-height: var(--wp--custom--lh-base);
    color: var(--wp--preset--color--muted);
}

/* The hairline between the address block and the specification line. Lighter
   than the card border — measured #e6e4e4 against the border's #e0dede. */
.brikk-card__meta {
    margin: 17px 0 0;
    padding-top: 19px;
    border-top: 1px solid var(--wp--custom--line-soft);
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui);
    line-height: var(--wp--custom--lh-base);
    color: var(--wp--preset--color--muted);
}

.brikk-card__price {
    /* ⚠️ 17px, and it was 8px until measured against the SAME price string.
       Cormorant sets figures OLDSTYLE, so a price's ink top depends on which
       digits it contains — 6 and 8 ascend, 3/4/5/7/9 descend, 0/1/2 sit at
       x-height. Comparing "12.075.000" against the comp's "6.495.000" made the
       gap look 9px smaller than it is. Compare like strings, or the baseline. */
    margin: 17px 0 0;
    font-family: var(--wp--preset--font-family--serif);
    font-size: 32px;
    font-weight: 500;
    line-height: 1;
    letter-spacing: var(--wp--custom--ls-heading);
    color: var(--wp--preset--color--dark);
}

.brikk-card__unit {
    margin-left: 7px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui);
    font-weight: 400;
    letter-spacing: 0;
    color: var(--wp--preset--color--muted);
}

.brikk-card--sold .brikk-card__price {
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui-sm);
    font-weight: 500;
    letter-spacing: var(--wp--custom--ls-ui);
    text-transform: uppercase;
    color: var(--wp--preset--color--muted);
}

.brikk-card--sold .brikk-card__media::after {
    content: "";
    position: absolute;
    inset: 0;
    background: rgba(246, 244, 240, 0.45);
}

/* --- 12.6.6  the inline dark CTA card ------------------------------------- */

.brikk-plist__item--cta {
    display: flex;
}

/* Content is vertically CENTRED — measured: the block sits 99px from both the
   top and the bottom of the 439px card. */
.brikk-plist__cta {
    display: flex;
    flex-direction: column;
    justify-content: center;
    width: 100%;
    padding: 38px;
    background: var(--wp--preset--color--dark);
}

.brikk-plist__cta > * {
    margin: 0;
}

.brikk-plist__cta-eyebrow {
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--eyebrow);
    font-weight: 500;
    letter-spacing: var(--wp--custom--ls-eyebrow);
    text-transform: uppercase;
    line-height: var(--wp--custom--lh-base);
    color: var(--wp--custom--on-dark-purple);
}

.brikk-plist__cta-heading {
    margin-top: 26px;
    font-family: var(--wp--preset--font-family--serif);
    font-size: 30px;
    font-weight: 500;
    line-height: 1.18;
    letter-spacing: var(--wp--custom--ls-heading);
    /* Warm off-white, measured #efe7da — the comp does not use pure white here. */
    color: #efe7da;
}

.brikk-plist__cta-lead {
    margin-top: 22px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--body-sm);
    line-height: var(--wp--custom--lh-copy);
    color: var(--wp--custom--on-dark-muted);
}

.brikk-plist__cta-action {
    margin-top: 32px;
}

.brikk-plist__cta-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 47px;
    padding: 0.2em 26px 0;
    background: var(--wp--custom--on-dark-purple);
    color: var(--wp--custom--on-accent);
    border: 0;
    text-decoration: none;
    transition: background var(--wp--custom--transition);
}

.brikk-plist__cta-btn:hover,
.brikk-plist__cta-btn:focus-visible {
    background: var(--wp--preset--color--purple);
    color: var(--wp--custom--on-accent);
}

/* --- 12.6.7  empty state -------------------------------------------------- */

.brikk-plist__empty {
    padding: 72px 0 88px;
    text-align: center;
}

.brikk-plist__empty-title {
    margin: 0;
    font-family: var(--wp--preset--font-family--serif);
    font-size: 32px;
    font-weight: 500;
    line-height: var(--wp--custom--lh-heading);
    color: var(--wp--preset--color--dark);
}

.brikk-plist__empty-lead {
    margin: 14px auto 28px;
    max-width: 440px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--body-sm);
    line-height: var(--wp--custom--lh-copy);
    color: var(--wp--preset--color--muted);
}

/* --- 12.6.8  pagination --------------------------------------------------- */

.brikk-plist__pager {
    margin-top: 64px;
}

.brikk-plist__pages {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    margin: 0;
    padding: 0;
    list-style: none;
    flex-wrap: wrap;
}

.brikk-plist__page-item {
    margin: 0;
    padding: 0;
    list-style: none;
}

.brikk-plist__page {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    height: 44px;
    padding: 0 6px;
    background: var(--wp--preset--color--bg);
    border: 1px solid var(--wp--custom--line-card);
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--body-sm);
    line-height: 1;
    color: var(--wp--preset--color--dark);
    text-decoration: none;
    transition: background var(--wp--custom--transition), border-color var(--wp--custom--transition);
}

a.brikk-plist__page:hover,
a.brikk-plist__page:focus-visible {
    background: var(--wp--preset--color--card);
    border-color: var(--wp--preset--color--dark);
    color: var(--wp--preset--color--dark);
}

.brikk-plist__page--current,
a.brikk-plist__page--current:hover {
    background: var(--wp--preset--color--purple);
    border-color: var(--wp--preset--color--purple);
    color: var(--wp--custom--on-accent);
}

/* The ellipsis is bare text — no box, matching the comp. */
.brikk-plist__page--gap {
    border-color: transparent;
    background: none;
    min-width: 28px;
    color: var(--wp--preset--color--muted);
}

.brikk-plist__page--disabled {
    color: var(--wp--custom--line-dark);
    background: none;
}

.brikk-plist__page--arrow {
    font-size: var(--wp--preset--font-size--body);
}

/* --- 12.6.9  bottom CTA band (.brikk-cta--search) ------------------------- */

/* Reuses the .brikk-cta skeleton from §12.4 and only restates what differs:
   a shorter band, a light button and the short vertical hairline. */
.brikk-pattern.brikk-cta--search {
    padding-block: 76px;
}

.brikk-pattern.brikk-cta--search .brikk-cta__heading {
    position: relative;
    max-width: 640px;
    padding-top: 56px;
    font-size: 44px;
}

/* 1x28px hairline above the heading — decoration, so CSS not a block. */
.brikk-pattern.brikk-cta--search .brikk-cta__heading::before {
    content: "";
    position: absolute;
    top: 0;
    left: 50%;
    width: 1px;
    height: 28px;
    background: var(--wp--custom--on-dark-purple);
}

.brikk-pattern.brikk-cta--search .brikk-cta__lead {
    max-width: 460px;
    margin-inline: auto;
    font-size: var(--wp--preset--font-size--body-sm);
    color: var(--wp--custom--on-dark-muted);
}

.brikk-pattern.brikk-cta--search .brikk-cta__action {
    margin-top: 36px;
}

/* Light button for dark surfaces. Scoped to the pattern rather than added as a
   global .brikk-btn variant — one use, and a new primitive would apply
   site-wide. */
.brikk-pattern .brikk-btn--light {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 47px;
    padding: 0.2em 28px 0;
    background: var(--wp--custom--on-accent);
    color: var(--wp--preset--color--purple);
    border: 0;
    text-decoration: none;
    transition: background var(--wp--custom--transition), color var(--wp--custom--transition);
}

.brikk-pattern .brikk-btn--light:hover,
.brikk-pattern .brikk-btn--light:focus-visible {
    background: var(--wp--preset--color--purple);
    color: var(--wp--custom--on-accent);
}

/* --- 12.6.10  responsive -------------------------------------------------- */

/* ⚠️ The single-row bar is exactly as wide as the comp's container: 478 search
   + 514 controls + 264 button + 54 gaps = 1310px, which needs a 1440px viewport.
   At 1439 and below the field must shrink or the køberkartotek button is pushed
   out of the viewport — measured as 76px of horizontal overflow at 1280. */
@media (max-width: 1439.98px) and (min-width: 1200.02px) {
    .brikk-plist__search {
        flex: 1 1 240px;
        max-width: none;
    }
}

/* 🔴 ...AND THE BAR STILL OVERFLOWED AT 1440–1466 ONCE A FILTER WAS APPLIED.
   "Ryd filtre" joins the row at that point and nothing above 1440 can absorb it:
   the field is pinned to 478px, so the row needs 1467px and a 1440px viewport
   grows a horizontal scrollbar. Measured at 4px resolution: +27px at 1440 down
   to +3 at 1464, and ZERO at every width with no filters applied — which is why
   the comp state and every earlier sweep missed it (CLAUDE.md §6r).

   ⚠️ PRE-EXISTING, and fixed here rather than left flagged because the search
   field became a TAG field (§6s): searching for a place is now the page's
   primary action, so what used to need a deliberate filter click is the common
   case. Verified independent of the tags — the field stays 478px and the
   overflow is identical with one tag or three.

   Scoped to the state that causes it, so the comp's own measured geometry (no
   filters, 478px at 1440) is untouched. `min-width: 0` because the input's
   intrinsic min-content would otherwise stop the shrink dead. */
@media (min-width: 1440px) {
    .brikk-plist__filters-inner:has(.brikk-plist__reset) .brikk-plist__search {
        flex: 0 1 478px;
        min-width: 0;
    }
}

@media (max-width: 1200px) {
    /* Below this the bar cannot hold one row at all and wraps. */
    .brikk-plist__filters-inner {
        flex-wrap: wrap;
        gap: 16px 20px;
    }

    .brikk-plist__search {
        flex: 1 1 100%;
        max-width: none;
        order: 1;
    }

    .brikk-plist__controls {
        order: 2;
        flex: 1 1 auto;
        justify-content: flex-start;
        /* ⚠️ Cancels the trigger's own horizontal padding so the first LABEL
           lands on the page gutter rather than the trigger's box. It must equal
           that padding, which is 18px here (`padding: 0.2em 18px 0`) — it read
           -22px, so the label overhung the gutter by 4.00px at 769–1200:
           measured labelX 28 against a searchX and card edge of 32. The <=768
           block already gets this right (-14px against 14px of padding). */
        margin-left: -18px;
    }

    /* ⚠️ Once the bar wraps the controls row is left-anchored, so a RIGHT-anchored
       498px panel reaches back past the page gutter — measured 4.1px from the
       viewport's left edge at 1024, i.e. 4px from an overflow that
       `scrollWidth === clientWidth` could never have caught, because a LEFT
       overflow creates no scrollable area. Anchor it to the trigger's left edge
       for as long as the bar wraps; below 768 the fixed bottom sheet takes over. */
    .brikk-plist__panel--right {
        left: 0;
        right: auto;
    }

    /* ⚠️ Explicit, and it has to be. A flex item's default `order` is 0, which
       sorts BEFORE the search field's `order: 1` — so a reset link with no order
       would jump to the front of the bar the moment a filter was applied. */
    .brikk-plist__reset {
        order: 3;
    }

    .brikk-plist__register {
        order: 4;
    }
}

@media (max-width: 1024px) {
    /* 🔴 A ~500px panel anchored to a control in a WRAPPED bar cannot stay inside
       a 1024px viewport from either edge, and both failures were measured:
       right-anchored it came within 4.1px of the left edge (and a left overflow
       creates no scrollable area, so `scrollWidth === clientWidth` can never
       catch it); left-anchored it overflowed the RIGHT by up to 119px at 769px.
       So from here down the panel stops being anchored to its control at all.

       🔴 IT DROPS FROM THE BAR — it is NOT a bottom sheet. It was one until
       2026-07-31 (`position: fixed; bottom: 0`), and that is the defect Andreas
       reported as "they stick to the bottom for some reason, and scroll doesn't
       work properly". Measured, the sheet had NO relationship to the control that
       opened it: the gap between the trigger's bottom edge and the panel's top
       ran from −345px (the sheet covering its own trigger, 320×568) to +352px
       (floating a third of a screen below it, 768×1024) — whatever
       `viewport height − panel height` happened to be. And because it was fixed
       with no scrim and no scroll lock, the page scrolled 35–83px per gesture
       underneath a panel welded to the bottom of the screen.

       Anchoring to `.brikk-plist__filters` instead makes the panel a full-bleed
       band hanging off the bar's bottom edge — the same idea as the desktop
       dropdown, just spanning the bar rather than the control. Nothing is fixed,
       so the page scrolls normally and no scroll lock, scrim or dvh unit is
       needed. Decided with Andreas 2026-07-31 over a true bottom sheet, because
       it keeps the desktop design's behaviour and needs no new interaction
       model. property-filters.js only has to scroll a panel into view when it
       opens below the fold. */
    .brikk-plist__filters {
        position: relative;
    }

    /* ⚠️ This is what re-anchors the panel, and it is why the trigger separator
       had to move off the <details> in §12.6.2. */
    .brikk-plist__drop {
        position: static;
    }

    .brikk-plist__panel,
    .brikk-plist__panel--types,
    .brikk-plist__panel--right {
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        bottom: auto;
        width: auto;
        max-width: none;
        max-height: none;
        overflow: visible;
        /* Full bleed, so the side hairlines would run to the viewport edge and
           read as a box; and the bar's own bottom hairline already draws the
           seam the panel hangs from — a top border here would double it. */
        border-top: 0;
        border-left: 0;
        border-right: 0;
        /* The content lines up with the bar above and the cards below. */
        padding-inline: var(--brikk-pad-x);
        /* ⚠️ THE SURFACE IS FULL BLEED; THE CONTENT IS NOT. Without this the
           controls stretched to the whole band — on a 1024px iPad the price
           slider's rail measured 960px against the comp's 402px, and a type chip
           312px against 145.33px, so a 30px handle travelled a 960px rail and
           the A–G ticks spread seven letters across the screen. 462px is not a
           new number: it is the widest designed panel's content box (518 − 2×28).
           Expressed as a growing RIGHT padding rather than a max-width so the
           content stays anchored to the gutter, in line with the cards below —
           centring it would reintroduce the two-container-idioms mismatch §6l
           had to fix on this very page. It engages continuously from ~502px up,
           so there is no jump at any breakpoint: at 480 the max() picks the
           gutter and nothing changes, at 640 it yields exactly 462px. */
        padding-right: max(var(--brikk-pad-x), calc(100% - var(--brikk-pad-x) - 462px));
        box-shadow: 0 26px 40px rgba(30, 23, 38, 0.12);
    }

    /* 44px is the platform minimum; the comp's dead-constant 39.5px pitch is a
       DESKTOP value and its rule in §12.6.3 explains why it must stay fixed
       rather than fall out of padding, so it is stepped here instead of edited
       at base. Six stacked options at 39.5px is six consecutive small targets. */
    .brikk-plist__sort-option {
        min-height: 44px;
    }

    .brikk-plist__grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 24px;
    }

    .brikk-plist__body {
        padding-block: 36px 48px;
    }

    .brikk-plist__resultbar {
        margin-bottom: 28px;
    }

    .brikk-pattern.brikk-cta--search {
        padding-block: 56px;
    }

    .brikk-pattern.brikk-cta--search .brikk-cta__heading {
        font-size: 36px;
    }
}

@media (max-width: 768px) {
    .brikk-plist__filters-inner {
        min-height: 0;
        padding-block: 18px;
    }

    /* ⚠️ THE WRAPPED TRIGGERS USED TO TOUCH — 0.00px gap in BOTH axes, measured
       at every phone width, with the 26px separator already deleted below. Four
       different filters formed one contiguous 460×84px block with no seam
       anywhere and no space between two 42px targets. `gap` also re-balances the
       wrap: at 390 (the most common phone width) FILTRE used to orphan onto a
       row of its own with 71.5% of it empty, because 141.02 + 81.25 + 133.98
       fitted the 364px row by 8px; with the gap it does not, so the row breaks
       2+2 instead. It does NOT balance 412–480, which would need a 25–59px gap
       — those keep the 3+1 wrap. */
    .brikk-plist__controls {
        flex-wrap: wrap;
        gap: 8px;
        margin-left: -14px;
    }

    /* ⚠️ The separators work only while the controls are all on ONE row. Once the
       group wraps, the first control of every new row inherits a dangling rule
       floating at the left edge — clearly visible before "FILTRE" on a phone.
       Drop them here; the comp is a desktop design and shows separators only in
       the one-row bar.
       🔴 This MUST target the pseudo-element, and it MUST track whichever element
       owns it. It first read `border-left: 0`, which stopped doing anything the
       moment the separator became a ::before; then it named `.brikk-plist__drop`,
       which stopped matching the moment the separator moved onto the trigger
       (§12.6.2, so the panel could be re-anchored to the bar). Both were silent
       no-ops that brought the dangling rule straight back. */
    .brikk-plist__drop + .brikk-plist__drop > .brikk-plist__drop-trigger::before {
        content: none;
    }

    .brikk-plist__drop-trigger {
        height: 42px;
        /* ⚠️ Keep the 0.2em top padding. This was a `padding: 0 14px` shorthand,
           which silently wiped §12.6.0's cap-centring correction — so every
           trigger label on a phone sat ~1px above the centre of its box, on the
           one surface where the labels are largest relative to the screen. Same
           shape of bug as the margin shorthand in §6e. */
        padding: 0.2em 14px 0;
    }

    /* Matches the triggers it sits under. */
    .brikk-plist__reset {
        height: 42px;
    }
}

/* 🔴 THE KØBERKARTOTEK BUTTON IS HIDDEN UNTIL IT CAN SHARE A ROW (Andreas,
   2026-07-31: hide it on mobile). It is a marketing CTA, not a filter, and while
   it is alone on a row it owns 66px of the bar on the screens with the least to
   spare — at <=768 `flex: 1 1 100%` made it a full-width black block, 26% of a
   254px bar, on a page where the first property did not appear until 1.33
   screens down.

   ⚠️ 822.98 IS MEASURED, NOT CHOSEN — a component-only breakpoint in the spirit
   of §12.5's 900/720. Swept at 1px: the controls are a fixed 460.2px and the
   button 264.3px, so with the 20px gap the row needs 744.5px of content; 823 is
   the first viewport that supplies it (823 − 2×32 gutter = 759). Below that the
   button takes a row of its own and the bar measures 226px — its tallest
   anywhere, and 80px TALLER than at 768, so the results started 80px LOWER on an
   810px iPad than on a 768px one. Above it the button costs nothing (bar 160px),
   which is why this is not simply folded into the 1024 ladder step.
   To re-derive after a label or control change: sweep `.brikk-plist__filters`
   height by 1px and take the first width where it drops from 226 to 160.

   ⚠️ Checked before hiding: /koeberkartotek/ stays reachable on a phone from the
   drawer nav, the footer's "Køb Bolig" widget AND this page's own bottom CTA
   band ("Opret søgeagent"), so nothing is orphaned. */
@media (max-width: 822.98px) {
    .brikk-plist__register {
        display: none;
    }
}

@media (max-width: 640px) {
    .brikk-plist__grid {
        grid-template-columns: minmax(0, 1fr);
        gap: 20px;
    }

    /* ⚠️ NOT `flex-direction: column`. Stacking unconditionally at <=640 cost a
       flat 44.8px across the whole 460–640 band (phones in landscape, foldables,
       small tablets) where the row still fits perfectly: count ink 168.28 + 24
       gap + 230 trigger = 422.28, which clears the viewport minus a 40px gutter
       from 462.3px up — confirmed by measurement at 460/462/463/465/480/540/
       600/640. Below ~450 the count wraps and `flex-wrap` breaks the row by
       itself, giving the same stacked result the old rule forced. So the layout
       is chosen by the content, and 640 stops being a cliff. */
    /* Part of clawing back the chrome above the first card — see the note on
       .brikk-plist__body just below. */
    .brikk-plist__resultbar {
        flex-direction: row;
        align-items: center;
        gap: 14px 20px;
        margin-bottom: 20px;
    }

    /* 🔴 668.5px OF CHROME STOOD BETWEEN THE TOP OF <main> AND THE FIRST CARD —
       117.7% of a 320×568 viewport, so a phone user saw zero properties on first
       paint and the card top sat 185.5px BELOW the fold. Measured breakdown:
       page header 261.69 + filter bar 254.00 + this padding 36 + result bar
       88.80 + its margin 28. Hiding the køberkartotek button took 66px off the
       bar (Andreas, above); these two, plus the eyebrow in §12.6.1, take another
       37px, and the result bar keeping its row below 640 takes 44.8 more in the
       460–640 band. */
    .brikk-plist__body {
        padding-block: 24px 40px;
    }

    .brikk-plist__sort {
        flex: 1 1 230px;
    }

    .brikk-plist__sort-trigger {
        width: 100%;
    }

    /* ⚠️ `width: auto` is load-bearing: with left, right AND width all set the box
       is over-constrained, `right` is discarded and the menu stays 248px beside a
       full-width trigger (measured 248 against a 600px trigger at 640px). */
    .brikk-plist__sort-menu {
        left: 0;
        right: 0;
        width: auto;
        min-width: 0;
    }

    .brikk-card__body {
        padding: 22px;
    }

    .brikk-card__title {
        font-size: 23px;
    }

    .brikk-card__price {
        font-size: 28px;
    }

    .brikk-plist__cta {
        padding: 30px;
    }

    .brikk-plist__cta-heading {
        font-size: 26px;
    }

    .brikk-plist__pager {
        margin-top: 44px;
    }

    .brikk-pattern.brikk-cta--search {
        padding-block: 48px;
    }

    .brikk-pattern.brikk-cta--search .brikk-cta__heading {
        font-size: 30px;
        padding-top: 44px;
    }
}

/* ⚠️ A COMPONENT-ONLY BREAKPOINT, measured rather than chosen, in the spirit of
   §12.5's 900/720. The four triggers are 141.0 / 81.3 / 134.0 / 103.9px — a fixed
   460.2px — and 488px is the first viewport where they stop wrapping, so this is
   exactly the band in which they wrap and nowhere else. Left as a rag they split
   2+2 below ~385 but 3+1 above it, leaving the second row 22.9–28.5% full at
   390/412/480 with no breakpoint responsible for the change; and the smallest
   target, "PRIS", is only 81.3px wide. A 2-column grid makes all four equal —
   147px at 320 up to 227px at 480, i.e. +81% on the smallest — and the rows
   balance by construction. `gap` and the negative pull both carry over from the
   flex rule unchanged. */
@media (max-width: 487.98px) {
    .brikk-plist__controls {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 420px) {
    /* 🔴 THE PAGER USED TO SHRINK TO 38x38 HERE, AND IT BOUGHT ALMOST NOTHING.
       Swept at 1px: the shrunken pager needs 336px of content, so at 320/360/375
       — where only 280/320/335 is available — it wrapped to two rows ANYWAY. It
       bought a single row only over 388–420, and paid for it with a 6px tap
       target on every phone at or below 420, against the 44px the base rule
       itself chose and every other control on this page uses.
       It also manufactured an anomaly: at 421 the shrink stopped applying, the
       full-size pager needed 392px of content against 373px available, and the
       pager wrapped to two rows for exactly 12px (421–432) between two one-row
       neighbours — +58px of pager and +77px of document at the 420→424 step.
       Dropping it makes the pager 44px everywhere and two rows CONSISTENTLY
       below 433. It is `flex-wrap: wrap; justify-content: center` already, so
       two rows is a state it was built for. */

    /* 🔴 This used to key off `.brikk-plist__checks`, the pre-chip class — dead
       code the moment the checkbox list became the chip grid, so the chips stayed
       3-up at 320px and their labels ran over their own hairlines. 2-up, not
       1-up: at 320px it gives a 106px chip against a 91px longest label
       ("Fritidslandbrug"), which clears every one of the eleven. */
    .brikk-plist__chips {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* =============================================================================
   12.7  KØBERKARTOTEK  ·  .brikk-kk
   -----------------------------------------------------------------------------
   The buyer-directory sign-up at /koeberkartotek/.
   Comp: claude-new-designs/buyers-directory-koberkartotek/ — a 1440px viewport
   framed in a 1591px image (page canvas x = 76..1515). Every number below was
   measured off it; see CLAUDE.md §6n for the extraction.

   Sections: patterns/koeberkartotek-hero.php · [brikk-koeberkartotek] ·
   patterns/koeberkartotek-cta.php, composed by
   page-templates/brikk-prebuilt-koeberkartotek.php.

   ⚠️ THE PAGE HEADER AND THE BOTTOM BAND ARE §12.6's, REUSED UNCHANGED. The
   header is `.brikk-pheader` and the band is `.brikk-cta--search` — the two
   comps are the same two components with different copy, so there are no
   `.brikk-kk` rules for either. Anything changed in §12.6.1 or §12.6.9 now
   shows up on both pages; that is the intent, but it is the thing to check
   before editing them.

   ⚠️ NOT a block-pattern grid. The form is a shortcode, so its markup is plain
   PHP output rather than core blocks — none of §12.4's `.brikk-pattern` marker
   dance applies. `.brikk-kk*` appears nowhere in landing.css, brikk.css or any
   A/B template (checked mechanically), so these rules cannot reach live A/B
   markup and specificity never comes into it.

   MEASURED GEOMETRY (1440px viewport, page x 0 = canvas left)
     container ....... 1600 max, 65px gutter -> content 64..1375 (1312 wide)
     two columns ..... form 848px (64..911) + 65px gap + summary 398 (977..1374)
     inside the form . marker rail 228px (64..291) + content 620px (292..911)
     step rhythm ..... hairline -> heading ink 51px, hairline spans the FORM
                       column only (848), never the full container
     chips ........... 4 x 146px, 12px gaps, 47px tall
     search field .... 558 x 52
     sliders ......... 2 x 282px columns, 56px gap; pill 39px, handles 30px
     contact fields .. 2 x 300px, 20px gap, 52px tall
     submit .......... 300 x 52
     summary card .... photo 398x260 + body; rows 43px, 28px padding

   COLOUR SUBSTITUTIONS (comp -> token; all documented, all imperceptible)
     page bg        #f6f4f0 -> --bg     (delta 2, as §12.6)
     ink            #1e1826 -> --dark   (the comp's ink is faintly purple-tinted)
     section rules  #dbd8d7 -> --line-card  (delta 5)
     chip + field   #e3e2e4 -> --line-card  (delta 3)
     card + rows    #e0dede  = --line-card  (exact)
   No new token was needed: one structural hairline serves the whole page, the
   same call DESIGN.md §13.5 made for the property list.

   🟠 THE SLIDER RAIL IS UNIFORMLY DARK, WITH NO SELECTED-RANGE FILL — measured,
   not assumed: on the Prisniveau slider the comp's handles sit in the left
   third and the rail is the same #1e1826 to its right as between them. So this
   is NOT the property list's light-rail + dark-fill model (§12.6.2), and the
   two pages' sliders therefore look different. Reproducing the comp is the
   standing rule, but a range control with no visual range is worth a decision:
   giving the track a `--line-card` base and painting `--low/--high` over it
   would align the two pages, and the custom properties are already written by
   the JS for exactly that. Flagged in CLAUDE.md §6n.
   ============================================================================= */

/* --- 12.7.0  layout ------------------------------------------------------- */

.brikk-kk {
    background: var(--wp--preset--color--bg);
    /* The hairline above step 01 is the first thing in the section, so the
       air above it belongs to the page header — except for 4px.
       ⚠️ THE TWO COMPS THAT USE `.brikk-pheader` DISAGREE BY 4px ON ITS HEIGHT:
       the property list's puts the following rule 257px below the site header,
       this one 261px, with the eyebrow, the purple rule and the h1 ink at
       IDENTICAL y in both. The shared component keeps the property list's 257
       (measured and verified there), and this page carries the 4px difference
       itself — same rendering, and §12.6.1 stays the one place the header is
       defined. */
    padding-block: 4px 56px;
}

.brikk-kk__inner {
    box-sizing: border-box;
    max-width: var(--wp--custom--max);
    margin-inline: auto;
    padding-inline: var(--brikk-pad-x);
    display: grid;
    /* 848 + 65 + 398 = 1311 against 1312 of content. Expressed as fr + fixed so
       the form column absorbs the rounding and the card keeps its measured
       width at every viewport. */
    grid-template-columns: minmax(0, 1fr) 398px;
    column-gap: 65px;
    align-items: start;
}

.brikk-kk__main {
    min-width: 0;
}

/* --- 12.7.1  the numbered steps ------------------------------------------- */

/* Each step is a two-column row: the "01 / BOLIGTYPE" rail and the content.
   ⚠️ The hairline is a TOP border on the step, not a bottom one, so the last
   step does not draw a rule against the bottom CTA band — and it spans the
   form column only, which is what the comp shows (the summary card sits in
   the other column and the rule stops short of it). */
.brikk-kk__step {
    display: grid;
    grid-template-columns: 228px minmax(0, 1fr);
    /* Measured: hairline to heading ink 51px. */
    padding-block: 46px 46px;
    border-top: 1px solid var(--wp--custom--line-card);
}

.brikk-kk__marker {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

/* ⚠️ ROMAN, not italic. DESIGN.md §9 calls italic canonical for decorative
   numerals and CLAUDE.md §8.14 records that the same call is still open for
   inc-why's numerals — following the comp keeps this page consistent and
   leaves the system decision in one place. Cormorant sets figures OLDSTYLE, so
   "01" renders with a lowered 0 and a lining 1; that is the face, not a bug. */
.brikk-kk__number {
    font-family: var(--wp--preset--font-family--serif);
    /* Measured: 1.15-1.18x a 30px render on all four numerals. */
    font-size: 35px;
    font-weight: 500;
    line-height: 1;
    color: var(--wp--preset--color--purple);
}

.brikk-kk__marker-label {
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--micro);
    font-weight: 500;
    letter-spacing: 0.24em;
    line-height: 1.4;
    text-transform: uppercase;
    color: var(--wp--preset--color--muted);
}

.brikk-kk__content {
    min-width: 0;
}

.brikk-kk__heading {
    margin: 0;
    font-family: var(--wp--preset--font-family--serif);
    /* 31px is off the type scale and measured, not chosen: the comp's four
       step headings are 1.105x our 28px render at 21, 23, 24 and 28
       characters. A CONSTANT ratio across four lengths is a font-size
       difference — a tracking difference would vary with character count.
       Same call as §12.6.3's flat 22px result count. */
    font-size: 31px;
    font-weight: 500;
    line-height: var(--wp--custom--lh-heading);
    letter-spacing: var(--wp--custom--ls-heading);
    color: var(--wp--preset--color--dark);
}

.brikk-kk__note {
    margin: 4px 0 0;
    max-width: 520px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui);
    font-weight: 300;
    line-height: var(--wp--custom--lh-copy);
    color: var(--wp--preset--color--muted);
}

/* --- 12.7.2  step 01 · the property-type chips ---------------------------- */

.brikk-kk__chips {
    display: grid;
    /* 🔴 auto-fit, NOT `repeat(4, 1fr)` — and the 620px cap is what makes it
       reproduce the comp exactly rather than approximately.
       620 is the comp's content column, so at full width this resolves to
       exactly 4 x 146px with 12px gaps. Below that the grid sheds a column on
       its own, which is the only model that survives this page's THREE-part
       layout: between 1025 and 1440 the 228px marker rail and the 398px
       summary card squeeze the form column continuously, and a breakpoint
       ladder cannot track that — measured, a fixed 4-up wrapped
       "2-families ejendom" onto two lines from 1440 all the way down to 1025
       (71px rows against 47px). `min(146px, 100%)` keeps the column from
       exceeding a container narrower than one chip, which would overflow.

       ⚠️ 140px IS MEASURED, and the comp's own 146 is the wrong number to use:
       the form column at 1440 is 619px, ONE pixel short of the 620 that four
       146px columns need, so a 146 floor dropped the comp's own width to three
       columns. The floor also has to clear the longest label
       ("2-families ejendom" = 110.3px of text + 24px padding = 134.3px) with
       room to spare — at 135 the 1025px viewport landed a 136px column and
       wrapped it anyway, because the grid's sub-pixel rounding eats the
       margin. 140 gives 5.7px of headroom AND still resolves to exactly
       4 x 145.75px at 1440. */
    grid-template-columns: repeat(auto-fit, minmax(min(140px, 100%), 1fr));
    max-width: 620px;
    gap: 12px;
    margin: 20px 0 0;
    padding: 0;
    border: 0;
    /* A <fieldset> ships with a min-width of min-content, which stops the grid
       cells from ever shrinking below their longest label. */
    min-width: 0;
}

.brikk-kk__chip {
    display: flex;
}

/* ⚠️ The checkbox is HIDDEN, NOT REMOVED, and not display:none — it is still
   the form control and still has to take focus and appear in the tab order.
   Clipping it keeps it operable by keyboard while the label carries the chip
   look. */
.brikk-kk__chip-input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: 0;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
}

.brikk-kk__chip-label {
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    /* 🔴 53px, NOT the comp's 47 — and it is uniform on purpose.
       The comp's chips are 47px because the comp shortens "Blandet bolig og
       erhverv" to "Bl. bolig/erhverv". Andreas, 2026-08-03: the site's own
       copy wins over the comp's, and the real label is 141.8px of text, which
       does not fit ONE line of a 146px chip at any column count the comp's
       layout allows (3-up at 198px does not fit it either). So the chip is
       sized for TWO lines: 2 x 16.9 (13px at lh 1.3) + 10.6 top + 8 bottom.
       Uniform rather than per-chip, because a grid row stretches to its
       tallest item and only ONE row would have grown — which reads as a
       rendering fault, not as a layout. Cost: 6px per row, 18px on the
       section. The 4-column grid the comp draws is unchanged.
       54, not the 52.4 the box model predicts: measured, a row holding the
       wrapped chip settles at 54 and anything lower leaves that one row a
       pixel taller than the rest. */
    min-height: 54px;
    /* 0.2em of the top padding is §12.6.0's cap-centring correction; the rest
       is the chip's own air. Helvetica Neue's declared ascent puts capitals
       ~0.1em above the centre of their box, so a centred label renders high. */
    padding: calc(0.2em + 8px) 12px 8px;
    background: var(--wp--preset--color--card);
    border: 1px solid var(--wp--custom--line-card);
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui);
    font-weight: 400;
    line-height: 1.3;
    text-align: center;
    color: var(--wp--preset--color--dark);
    cursor: pointer;
    transition: border-color var(--wp--custom--transition),
        background var(--wp--custom--transition),
        color var(--wp--custom--transition);
}

.brikk-kk__chip-label:hover {
    border-color: var(--wp--preset--color--purple);
}

.brikk-kk__chip-input:checked + .brikk-kk__chip-label {
    background: var(--wp--preset--color--purple);
    border-color: var(--wp--preset--color--purple);
    color: var(--wp--custom--on-accent);
    font-weight: 500;
}

/* The ring is drawn on the LABEL because the input it belongs to is clipped to
   a pixel — without this the chips are focusable but give no sign of it. */
.brikk-kk__chip-input:focus-visible + .brikk-kk__chip-label {
    outline: 2px solid var(--wp--preset--color--purple);
    outline-offset: 2px;
}

.brikk-kk__chips.has-error .brikk-kk__chip-label {
    border-color: var(--wp--custom--error);
}

/* --- 12.7.3  step 02 · the location combobox ------------------------------ */

.brikk-kk__combo {
    position: relative;
    margin-top: 19px;
    max-width: 558px;
}

.brikk-kk__combo-field {
    display: flex;
    align-items: center;
    gap: 12px;
    height: 52px;
    padding-inline: 18px;
    background: var(--wp--preset--color--card);
    border: 1px solid var(--wp--custom--line-card);
    transition: border-color var(--wp--custom--transition);
}

.brikk-kk__combo-field:focus-within {
    border-color: var(--wp--preset--color--purple);
}

.brikk-kk__combo-icon {
    display: flex;
    flex: none;
    color: var(--wp--preset--color--muted);
}

/* ⚠️ Restated rather than inherited from §7: the field's frame is this
   wrapper, so the input itself must have no box of its own.

   🔴 THE TWO-CLASS SELECTOR IS LOAD-BEARING. §7's base field rule is
   `:where(.brikk-redesign) input[type='text']`, and an ATTRIBUTE selector
   carries class-level weight — so that rule is (0,1,1) and beat a single-class
   (0,1,0) rule here no matter how far down the file it sat. The symptom was
   the search input drawing its own hairline INSIDE the combobox frame, i.e. a
   second border. Same trap as §12.6's iOS font-size guard (§6l). */
.brikk-kk__combo .brikk-kk__combo-input {
    flex: 1 1 auto;
    min-width: 0;
    height: 100%;
    padding: 0;
    background: none;
    border: 0;
    font-family: var(--wp--custom--font-input);
    /* 13px, measured: the comp's placeholders are 0.87x a 15px render across
       three different strings. See the field rule in §12.7.5 for why the
       responsive steps have to be restated. */
    font-size: var(--wp--preset--font-size--ui);
    color: var(--wp--preset--color--dark);
}

.brikk-kk__combo .brikk-kk__combo-input::placeholder {
    color: var(--wp--custom--placeholder);
    opacity: 1;
}

.brikk-kk__combo .brikk-kk__combo-input:focus {
    outline: 0;
}

.brikk-kk__combo-spinner {
    flex: none;
    width: 14px;
    height: 14px;
    border: 2px solid var(--wp--custom--line-card);
    border-top-color: var(--wp--preset--color--purple);
    border-radius: 50%;
    animation: brikk-kk-spin 700ms linear infinite;
}

/* The one @keyframes on this page. DESIGN.md §8 says the design has none, and
   that holds for DECORATION — this is a loading state for a live API call,
   where a still ring would read as a broken control. §10's reduced-motion kill
   switch already stops it. */
@keyframes brikk-kk-spin {
    to {
        transform: rotate(360deg);
    }
}

.brikk-kk__combo-list {
    position: absolute;
    z-index: var(--wp--custom--z-raised);
    top: calc(52px + 6px);
    left: 0;
    right: 0;
    max-height: 264px;
    margin: 0;
    padding: 6px 0;
    overflow-y: auto;
    list-style: none;
    background: var(--wp--preset--color--card);
    border: 1px solid var(--wp--custom--line-card);
    box-shadow: 0 12px 28px -18px rgba(20, 14, 50, 0.35);
}

.brikk-kk__combo-option {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding: 11px 18px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui);
    color: var(--wp--preset--color--dark);
    cursor: pointer;
}

.brikk-kk__combo-option.is-active,
.brikk-kk__combo-option:hover {
    background: var(--wp--custom--bg-dim);
}

.brikk-kk__combo-zip {
    color: var(--wp--preset--color--muted);
}

.brikk-kk__tags {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.brikk-kk__tags:not(:empty) {
    margin-top: 12px;
}

.brikk-kk__tag {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 34px;
    padding: 0.2em 12px 0 14px;
    background: var(--wp--custom--purple-tint);
    border: 1px solid var(--wp--preset--color--purple);
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui-sm);
    font-weight: 500;
    letter-spacing: 0.04em;
    color: var(--wp--preset--color--purple);
}

.brikk-kk__tag-remove {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    padding: 0;
    background: none;
    border: 0;
    color: inherit;
    cursor: pointer;
    opacity: 0.7;
    transition: opacity var(--wp--custom--transition);
}

.brikk-kk__tag-remove:hover,
.brikk-kk__tag-remove:focus-visible {
    opacity: 1;
}

/* The live region is announced, not shown: the tags and the list are the
   visible feedback, and a duplicated line of status text under the field is
   noise for everyone who can see them. It stays in the flow (never
   display:none) so screen readers still receive it. */
.brikk-kk__status {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
}

/* --- 12.7.4  step 03 · the range sliders ---------------------------------- */

.brikk-kk__ranges {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 56px;
    row-gap: 34px;
    margin-top: 26px;
}

.brikk-kk__range-label {
    display: block;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 15px;
    font-weight: 500;
    line-height: 1.4;
    color: var(--wp--preset--color--dark);
}

/* The no-JS controls. Visible until koeberkartotek.js takes over, and the only
   way to set a range if it never does — so they are a real, styled pair, not a
   hidden fallback. */
.brikk-kk__range-fields {
    display: flex;
    gap: 10px;
    margin-top: 12px;
}

.brikk-kk__range-fields input {
    box-sizing: border-box;
    width: 100%;
    min-width: 0;
    height: 44px;
    padding: 0.2em 12px 0;
    background: var(--wp--preset--color--card);
    border: 1px solid var(--wp--custom--line-card);
    font-family: var(--wp--custom--font-input);
    font-size: var(--wp--preset--font-size--ui);
    color: var(--wp--preset--color--dark);
}

.brikk-kk__range--slider .brikk-kk__range-fields {
    display: none;
}

.brikk-kk__range-note {
    margin: 15px 0 0;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui-sm);
    font-weight: 300;
    line-height: var(--wp--custom--lh-copy);
    color: var(--wp--preset--color--muted);
}

.brikk-kk__slider {
    margin-top: 10px;
}

.brikk-kk__pill {
    display: inline-flex;
    align-items: center;
    height: 39px;
    padding: 0 22px;
    border-radius: var(--wp--custom--radius-pill);
    background: var(--wp--preset--color--dark);
    color: var(--wp--custom--on-accent);
    font-family: var(--wp--preset--font-family--sans);
    font-size: 14px;
    font-weight: 500;
    line-height: 1;
    white-space: nowrap;
}

.brikk-kk__track {
    position: relative;
    display: block;
    /* One handle tall, so the rail can be centred in it. */
    height: 30px;
    margin-top: 7px;
}

/* 🟠 UNIFORM DARK RAIL — see the section header. The rail is inset by the
   handle RADIUS at both ends because a native range input travels its thumb
   CENTRE from 15px to width−15px; without the inset the line would run past
   the handles at the extremes. --low/--high are written by the JS and are
   currently unused here: they are what a selected-range fill would read. */
.brikk-kk__track::before {
    content: "";
    position: absolute;
    left: 15px;
    right: 15px;
    top: 14px;
    height: 2px;
    background: var(--wp--preset--color--dark);
}

.brikk-kk__thumb {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 30px;
    margin: 0;
    padding: 0;
    background: none;
    border: 0;
    appearance: none;
    -webkit-appearance: none;
    /* Both inputs span the whole track, so the upper one would swallow every
       click. Only the thumbs themselves take pointer events. */
    pointer-events: none;
}

.brikk-kk__thumb::-webkit-slider-runnable-track {
    height: 30px;
    background: none;
    border: 0;
}

.brikk-kk__thumb::-moz-range-track {
    height: 30px;
    background: none;
    border: 0;
}

.brikk-kk__thumb::-webkit-slider-thumb {
    appearance: none;
    -webkit-appearance: none;
    pointer-events: auto;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: var(--wp--preset--color--card);
    border: 1px solid var(--wp--custom--plist-thumb-ring);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.16);
    cursor: grab;
}

.brikk-kk__thumb::-moz-range-thumb {
    pointer-events: auto;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: var(--wp--preset--color--card);
    border: 1px solid var(--wp--custom--plist-thumb-ring);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.16);
    cursor: grab;
}

.brikk-kk__thumb:focus-visible::-webkit-slider-thumb {
    outline: 2px solid var(--wp--preset--color--purple);
    outline-offset: 2px;
}

.brikk-kk__thumb:focus-visible::-moz-range-thumb {
    outline: 2px solid var(--wp--preset--color--purple);
    outline-offset: 2px;
}

/* --- 12.7.5  step 04 · contact ------------------------------------------- */

.brikk-kk__fields {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 23px 20px;
    margin-top: 25px;
}

.brikk-kk__field {
    min-width: 0;
}

/* "Andet vi bør vide?" takes the whole row. The comp pairs it with a telephone
   field, which does not exist here because the API has no phone (see the
   step-04 renderer) — and a half-width field with an empty cell beside it
   reads as something missing rather than as a layout. */
.brikk-kk__field--wide {
    grid-column: 1 / -1;
}

.brikk-kk__label {
    display: block;
    margin-bottom: 6px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--micro);
    font-weight: 500;
    letter-spacing: 0.24em;
    line-height: 1.2;
    text-transform: uppercase;
    color: var(--wp--preset--color--muted);
}

/* ⚠️ NOT purple. Sampled off the comp the asterisk is a lavender-tinted grey
   at the label's own weight — it reads as punctuation, not as an accent.
   DESIGN.md §9 folds the light-surface lavender greys into --muted. */
.brikk-kk__req {
    color: var(--wp--preset--color--muted);
}

/* ⚠️ Restated rather than left to §7's base field rule: that rule uses the
   WARM --line hairline and 15px/16px type, and this page's fields are the cool
   --line-card at a fixed 52px. Stating it here also means the form renders
   identically if §7 ever changes. */
.brikk-kk__field input {
    box-sizing: border-box;
    width: 100%;
    height: 52px;
    padding: 0 18px;
    background: var(--wp--preset--color--card);
    border: 1px solid var(--wp--custom--line-card);
    border-radius: var(--wp--custom--radius);
    font-family: var(--wp--custom--font-input);
    font-size: var(--wp--preset--font-size--ui);
    color: var(--wp--preset--color--dark);
    transition: border-color var(--wp--custom--transition);
}

/* 🔴 §7's FIELD RULES STEP UP AT <=1024 AND AGAIN ON iOS, AND THESE RULES ARE
   MORE SPECIFIC THAN BOTH — so restating the base size silently disabled the
   iOS zoom guard for every field on this page. Safari zooms the page when a
   field under 16px takes focus and never zooms back out, which is a defect a
   comp can never show you. The two steps are therefore restated here at this
   block's own specificity, in this order:
     base   13px  (the comp)
     <=1024 15px  (§7's touch size)
     iOS    16px  (§7's zoom guard; -webkit-touch-callout matches iOS only —
                   NOT width-scoped, because iPadOS reports well over 1024)
   Any future field on this page needs the same three. */
@media (max-width: 1024.98px) {
    .brikk-kk__field input,
    .brikk-kk__combo .brikk-kk__combo-input,
    .brikk-kk__range-fields input {
        font-size: var(--wp--preset--font-size--body-sm);
    }
}

@supports (-webkit-touch-callout: none) {
    .brikk-kk__field input,
    .brikk-kk__combo .brikk-kk__combo-input,
    .brikk-kk__range-fields input {
        font-size: var(--wp--preset--font-size--body);
    }
}

.brikk-kk__field input::placeholder {
    color: var(--wp--custom--placeholder);
    opacity: 1;
}

.brikk-kk__field input:focus {
    border-color: var(--wp--preset--color--purple);
    outline: 0;
}

.brikk-kk__field input.has-error {
    border-color: var(--wp--custom--error);
}

/* ⚠️ The combobox's frame is the WRAPPER, not the input (which has border: 0),
   so the error state has to land there. Driven by a class the JS adds rather
   than by `:has(.has-error)` — `:has()` silently no-ops on pre-2023 browsers
   and the field would then show no error state at all, only the message below
   it. Same lesson as the funnel's `:has()` gate (§5b). */
.brikk-kk__combo-field.has-error {
    border-color: var(--wp--custom--error);
}

.brikk-kk__error {
    display: block;
    margin-top: 8px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui-sm);
    line-height: 1.4;
    color: var(--wp--custom--error);
}

.brikk-kk__error[hidden] {
    display: none;
}

.brikk-kk__consent {
    display: grid;
    grid-template-columns: 22px minmax(0, 1fr);
    align-items: start;
    gap: 12px;
    margin-top: 29px;
}

/* ⚠️ `appearance: none` is what makes this OUR box rather than Chrome's.
   Measured off the comp: 22x22, white, a --line-card hairline. With the native
   appearance the browser paints its own control and every declaration below is
   ignored — which is exactly what happened first time round. The tick is a
   background SVG rather than a ::before so it works in every engine (a
   checkbox is a replaced element until `appearance: none` and generated
   content on it is not universally supported). */
.brikk-kk__consent input {
    box-sizing: border-box;
    appearance: none;
    -webkit-appearance: none;
    flex: none;
    width: 22px;
    height: 22px;
    margin: 0;
    background: var(--wp--preset--color--card);
    border: 1px solid var(--wp--custom--line-card);
    border-radius: var(--wp--custom--radius);
    cursor: pointer;
    transition: background var(--wp--custom--transition), border-color var(--wp--custom--transition);
}

.brikk-kk__consent input:hover {
    border-color: var(--wp--preset--color--purple);
}

.brikk-kk__consent input:checked {
    background: var(--wp--preset--color--purple) center / 12px 9px no-repeat
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='9' viewBox='0 0 12 9'%3E%3Cpath fill='none' stroke='%23fff' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round' d='M1 4.6 4.3 7.9 11 1.2'/%3E%3C/svg%3E");
    border-color: var(--wp--preset--color--purple);
}

.brikk-kk__consent input:focus-visible {
    outline: 2px solid var(--wp--preset--color--purple);
    outline-offset: 2px;
}

.brikk-kk__consent label {
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui);
    font-weight: 300;
    line-height: 1.4;
    color: var(--wp--preset--color--muted);
}

/* 🟠 DELIBERATE DEVIATION: the comp draws "datapolitik" in the label's own
   grey with no underline, i.e. as an invisible link. Keeping it findable is
   worth one pixel of drift — a link distinguished by colour alone also fails
   WCAG 1.4.1, and this one is legally load-bearing. Toned to the label's
   colour so it reads as the comp does, with the underline carrying the
   affordance and purple on hover. */
.brikk-kk__consent a {
    color: inherit;
    text-decoration: underline;
    text-decoration-color: var(--wp--custom--line-dark);
    text-underline-offset: 3px;
    transition: color var(--wp--custom--transition), text-decoration-color var(--wp--custom--transition);
}

.brikk-kk__consent a:hover,
.brikk-kk__consent a:focus-visible {
    color: var(--wp--preset--color--purple);
    text-decoration-color: currentColor;
}

.brikk-kk__consent .brikk-kk__error {
    grid-column: 2;
}

.brikk-kk__submit {
    display: flex;
    align-items: center;
    gap: 27px;
    margin-top: 33px;
}

.brikk-kk__button {
    position: relative;
    box-sizing: border-box;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 300px;
    height: 52px;
    padding: 0.2em 22px 0;
    background: var(--wp--preset--color--purple);
    border: 0;
    color: var(--wp--custom--on-accent);
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui-sm);
    font-weight: 500;
    letter-spacing: var(--wp--custom--ls-ui);
    line-height: 1.3;
    text-transform: uppercase;
    cursor: pointer;
    transition: background var(--wp--custom--transition);
}

.brikk-kk__button:hover,
.brikk-kk__button:focus-visible {
    background: var(--wp--custom--purple-hover);
}

.brikk-kk__button[disabled] {
    cursor: progress;
}

.brikk-kk__button-spinner {
    display: none;
    width: 14px;
    height: 14px;
    margin-left: 10px;
    border: 2px solid var(--wp--custom--on-dark-line);
    border-top-color: var(--wp--custom--on-accent);
    border-radius: 50%;
    animation: brikk-kk-spin 700ms linear infinite;
}

.brikk-kk__form.is-submitting .brikk-kk__button-spinner {
    display: block;
}

.brikk-kk__reassurance {
    margin: 0;
    font-family: var(--wp--preset--font-family--sans);
    /* Fine print (DESIGN.md §3): measured 0.963x a 13px render. */
    font-size: 12.5px;
    font-weight: 300;
    line-height: 1.4;
    color: var(--wp--preset--color--muted);
}

.brikk-kk__form-error {
    margin: 24px 0 0;
    padding: 14px 18px;
    background: var(--wp--preset--color--card);
    border-left: 2px solid var(--wp--custom--error);
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui);
    line-height: var(--wp--custom--lh-copy);
    color: var(--wp--custom--error);
}

.brikk-kk__form-error[hidden] {
    display: none;
}

/* --- 12.7.6  the "Din søgeprofil" card ------------------------------------ */

/* Sticky so the profile stays in view while the form is filled in — the whole
   point of a live summary. `top` clears the sticky header (94px) plus air; the
   header is only sticky itself above 1080px (§12.1), and below 1024 this card
   stops being a column at all. */
.brikk-kk__summary {
    position: sticky;
    top: 118px;
    align-self: start;
    background: var(--wp--preset--color--card-soft);
    border: 1px solid var(--wp--custom--line-card);
    /* The card starts level with step 01's hairline. */
    margin-top: 0;
}

.brikk-kk__summary-image {
    display: block;
    width: 100%;
    height: 260px;
    object-fit: cover;
}

.brikk-kk__summary-body {
    /* 33 vertical / 28 horizontal — measured, not symmetric. */
    padding: 33px 28px;
}

.brikk-kk__summary-eyebrow {
    margin: 0;
    color: var(--wp--preset--color--purple);
}

.brikk-kk__summary-title {
    margin: 11px 0 0;
    font-family: var(--wp--preset--font-family--serif);
    font-size: 26px;
    font-weight: 500;
    line-height: var(--wp--custom--lh-heading);
    letter-spacing: var(--wp--custom--ls-heading);
    color: var(--wp--preset--color--dark);
}

.brikk-kk__summary-rows {
    margin: 24px 0 0;
}

.brikk-kk__summary-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    /* Measured 43px rows: 12px + line + 12px against a 19px line box. */
    padding-block: 12px;
    border-top: 1px solid var(--wp--custom--line-card);
}

.brikk-kk__summary-row dt {
    flex: none;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui);
    font-weight: 400;
    line-height: 1.4;
    color: var(--wp--preset--color--muted);
}

.brikk-kk__summary-row dd {
    margin: 0;
    min-width: 0;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui);
    font-weight: 400;
    line-height: 1.4;
    text-align: right;
    color: var(--wp--preset--color--dark);
}

/* --- 12.7.7  the success state ------------------------------------------- */

.brikk-kk__success {
    padding-block: 34px 46px;
    border-top: 1px solid var(--wp--custom--line-card);
    max-width: 620px;
}

.brikk-kk__success[hidden] {
    display: none;
}

.brikk-kk__success:focus {
    outline: 0;
}

.brikk-kk__success-eyebrow {
    margin: 0;
    color: var(--wp--preset--color--purple);
}

.brikk-kk__success-title {
    margin: 16px 0 0;
    font-family: var(--wp--preset--font-family--serif);
    font-size: var(--wp--preset--font-size--heading-3);
    font-weight: 500;
    line-height: var(--wp--custom--lh-heading);
    letter-spacing: var(--wp--custom--ls-heading);
    color: var(--wp--preset--color--dark);
}

.brikk-kk__success-lead {
    margin: 16px 0 0;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--body-sm);
    line-height: var(--wp--custom--lh-copy);
    color: var(--wp--preset--color--muted);
}

.brikk-kk__success-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin: 32px 0 0;
}

/* --- 12.7.8  responsive --------------------------------------------------- */

/* ⚠️ TWO SEPARATE FOLDS, AND THEY ARE NOT THE SAME BREAKPOINT.
   The page is three columns wide — a 228px marker rail, the form, and a fixed
   398px summary card — so the form is squeezed from BOTH sides as the viewport
   narrows. Folding all of it at 1024 (the design system's 2-col breakpoint)
   left the form with 204px of content at 1025, and the sliders and chips are
   unusable there. So the rail folds first, at 1280, and the card at 1024:
       >=1281   rail + form + card   (the comp, at 1440: 228 / 620 / 398)
       1025-1280 marker inline, card still beside the form
       <=1024   everything stacked
   Measured at 1025 the middle band still leaves 432px of form content — two
   chips of 210px and two 188px slider tracks, both comfortable. */
@media (max-width: 1280.98px) {
    /* The marker rail costs 228px for two short words, and it is the cheapest
       column to give back. It becomes a row above the heading, which also puts
       the number beside its label the way the funnel's step bar does. */
    .brikk-kk__step {
        grid-template-columns: minmax(0, 1fr);
        row-gap: 18px;
    }

    .brikk-kk__marker {
        flex-direction: row;
        align-items: baseline;
        gap: 12px;
    }

    .brikk-kk__number {
        font-size: 24px;
    }
}

/* The summary card folds under the form at 1024, where the design system's
   2-col splits stack. It keeps its measured 398px but does not stretch, so it
   reads as a summary rather than a panel. */
@media (max-width: 1024.98px) {
    .brikk-kk__inner {
        grid-template-columns: minmax(0, 1fr);
        row-gap: 40px;
    }

    .brikk-kk__summary {
        position: static;
        width: 100%;
        max-width: 398px;
    }
}

@media (max-width: 768.98px) {
    /* Type only at 768 — DESIGN.md §7: this breakpoint never changes rhythm. */
    .brikk-kk__heading {
        font-size: 24px;
    }

    .brikk-kk__summary-title {
        font-size: 23px;
    }

}

@media (max-width: 640.98px) {
    .brikk-kk__step {
        padding-block: 28px 40px;
    }

    /* Two slider columns cannot work once the column is 350px wide: the track
       would be 147px for a 30px handle at each end, i.e. 87px of travel. */
    .brikk-kk__ranges {
        grid-template-columns: minmax(0, 1fr);
        row-gap: 28px;
    }

    .brikk-kk__fields {
        grid-template-columns: minmax(0, 1fr);
        gap: 20px;
    }

    /* Full-width stacked buttons is the design system's mobile CTA rule
       (DESIGN.md §7), and it is what stops the reassurance line being squeezed
       to three words beside a 300px button. */
    .brikk-kk__submit {
        flex-direction: column;
        align-items: stretch;
        gap: 16px;
    }

    .brikk-kk__button {
        width: 100%;
    }

    .brikk-kk__reassurance {
        text-align: center;
    }

    .brikk-kk__summary {
        max-width: none;
    }

    .brikk-kk__summary-image {
        height: 200px;
    }

    .brikk-kk__summary-body {
        padding: 24px;
    }

    .brikk-kk__success-actions .brikk-btn {
        width: 100%;
    }
}

@media (max-width: 420.98px) {
    /* ⚠️ Overrides auto-fit back to a hard 2 columns. At 320px there is 280px
       of content, so the 135px floor sheds the second column and stacks all
       eleven chips — 637px of phone for a list that fits in two columns.
       Same call as §12.6.10's chips. */
    .brikk-kk__chips {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    /* …and 2 columns at 320px is a 134px chip against a 134.3px longest label,
       so the chip's own padding gives back the 0.3px rather than letting
       "2-families ejendom" wrap for it. 10px still reads as a chip. */
    .brikk-kk__chip-label {
        padding-inline: 10px;
    }

    /* Last resort. The summary rows cannot hold one line here:
       "Prisniveau" + "1,5 mio. – 6 mio. kr." needs 250px against 232px of
       content. They stack. */
    .brikk-kk__summary-row {
        display: grid;
        grid-template-columns: minmax(0, 1fr);
        gap: 2px;
    }

    .brikk-kk__summary-row dd {
        text-align: left;
    }
}


/* =============================================================================
   12.8  LOKALE BYSIDER  ·  .brikk-citysplit / .brikk-citystats
   -----------------------------------------------------------------------------
   The two components the ~100 city landing pages add on top of the front page's
   sections (/ejendomsmaegler/<region>/<by>/). Everything else on a city page is
   an existing pattern with the city's copy in it — see patterns/city-*.php.

   Design source: claude-new-designs/local-pages/desktop.png + mobile.png.
   ⚠️ BOTH COMPS ARE 1508px WIDE CANVASES, and they are not the same thing: the
   desktop one is a 1508px VIEWPORT (page gutter 65px, content 1378px — measured
   off the logo and the CTA), while the mobile one is a **420px** viewport column
   centred in a 1508px canvas. So desktop figures below are 1:1 CSS px at 1508,
   and mobile figures are 1:1 at 420 — which sits exactly ON the 420px breakpoint,
   so `max-width: 420px` rules DO apply to it. Check 421 as well as 420.

   .brikk-citysplit  — a two-column band, photo one side and copy the other, used
                       three times per page with different content shapes:
                         --why     photo left,  copy right, CTA at the end
                         --about   photo left,  copy right, no CTA
                         --buyers  copy left,   photo right, numbered list below
   .brikk-citystats  — the dark "<By> i tal" band: centred head, four figures
                       divided by hairlines, and a source line.
   ============================================================================= */

/* -----------------------------------------------------------------------------
   12.8a  SPLIT BANDS  ·  .brikk-citysplit
   -------------------------------------------------------------------------- */

.brikk-pattern.brikk-citysplit {
    padding-top: var(--brikk-section-y);
    padding-bottom: var(--brikk-section-y);
    background: var(--wp--preset--color--bg);
}

/* The comp closes the --why band with a full-width hairline — the only rule
   between two same-surface sections on the whole page (verified by scanning
   both comps for near-uniform darker rows: desktop y=5477, mobile y=6159, and
   nowhere else on a shared surface). It belongs to --why rather than to the
   marketing band that follows, because --buyers and --about are drawn WITHOUT
   one and --why is the only band the marketing section ever follows.
   ⚠️ The gutter class puts the section's padding on this element, so the rule
   would inset by --brikk-pad-x if it were drawn on the padding box — it is
   full-bleed in the comp, and .brikk-citysplit is the alignfull group, so the
   border lands on the viewport edge as intended. */
.brikk-pattern.brikk-citysplit--why {
    border-bottom: 1px solid var(--wp--preset--color--line);
}

.brikk-pattern .brikk-citysplit__grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    /* ⚠️ COLUMN GAP ONLY. `gap: 64px` also sets the ROW gap, which in --buyers
       stacked on top of the list's own margin-top and started the numbered list
       98px below the copy where the comp has 41. The rows here are a layout
       device, not a rhythm — spacing between the copy and the list belongs to
       the list. */
    column-gap: 64px;
    row-gap: 0;
    align-items: start;
    max-width: var(--wp--custom--max);
    margin-inline: auto;
}

/* Core's layout CSS emits `> * { margin-block-start: 0; margin-block-end: 0 }`
   from the FOOTER, so it beats a same-specificity theme rule on order. Every
   vertical rhythm inside a pattern has to be restated at (0,2,0) — CLAUDE.md
   §6e. That is what the explicit margins below are doing. */
.brikk-pattern .brikk-citysplit__grid > * {
    margin-block-start: 0;
    margin-block-end: 0;
    min-width: 0;
}

/* --buyers is the mirrored one, and its media sits BETWEEN the head and the list
   in the DOM so the stacked order matches the mobile comp (see the pattern's
   docblock). Placing all three explicitly keeps the desktop layout independent
   of that ordering. */

/* ⚠️ The photo spans both rows and is much taller than the copy beside it, but
   it does NOT inflate row 1 — measured, after an earlier fix that assumed it did
   and changed nothing. Row 1 sizes to the copy; the photo's excess lands in row
   2, which is below the list and invisible. If the list ever starts too low
   again, check the grid's row-gap first. */

.brikk-pattern.brikk-citysplit--buyers .brikk-citysplit__copy {
    grid-column: 1;
    grid-row: 1;
}

.brikk-pattern.brikk-citysplit--buyers .brikk-citysplit__list {
    grid-column: 1;
    grid-row: 2;
}

.brikk-pattern.brikk-citysplit--buyers .brikk-citysplit__media {
    grid-column: 2;
    grid-row: 1 / span 2;
}

/* --buyers and --about make their photo exactly as tall as the copy beside it:
   the media stretches to the row, and the image fills that box and crops.
   (Superseded `align-self: center`, 2026-08-05 — Andreas: the photo must fill
   the band top to bottom. Centring only balanced the leftover space; measured,
   the photo was 117-491px shorter than the column beside it, and the shortfall
   GREW as the viewport narrowed because the copy wraps taller while the photo
   scales down with its column. --why deliberately keeps the grid's `start` —
   Andreas has named these two bands twice now and not that one.)

   ⚠️ THE IMAGE STAYS IN FLOW ON PURPOSE. It is not absolutely positioned, so
   its natural height still feeds the row's intrinsic sizing — i.e. the copy
   wins while it is the taller item (always, in these two bands, at every width
   from 1025 up), and a photo that ever WERE the taller item would set the row
   rather than being silently cropped to a short column. It also means the
   ≤1024 stack needs no undoing: `height: 100%` on a single-column grid item
   resolves to the item's own content height, so the photo keeps its natural
   aspect there. Verified — the whole page is byte-identical at 1024 and below.

   ⚠️ `object-fit: cover` is mandatory with a stretched box; the base rule at
   the top of this block leaves it at the initial `fill`, which would stretch
   the photograph vertically instead of cropping it. */
.brikk-pattern.brikk-citysplit--buyers .brikk-citysplit__media,
.brikk-pattern.brikk-citysplit--about .brikk-citysplit__media {
    align-self: stretch;
}

.brikk-pattern.brikk-citysplit--buyers .brikk-citysplit__media figure,
.brikk-pattern.brikk-citysplit--about .brikk-citysplit__media figure {
    height: 100%;
}

.brikk-pattern.brikk-citysplit--buyers .brikk-citysplit__media img,
.brikk-pattern.brikk-citysplit--about .brikk-citysplit__media img {
    height: 100%;
    object-fit: cover;
}

/* The two photo-left bands cap their copy at a measure rather than filling the
   column: in the comp the title and paragraphs both stop at x=1303 of a column
   that runs to 1443 (517px of a 657px column). --buyers does NOT — its copy
   column carries the numbered list under it and uses the full width. */
.brikk-pattern.brikk-citysplit--why .brikk-citysplit__copy,
.brikk-pattern.brikk-citysplit--about .brikk-citysplit__copy {
    max-width: 520px;
}

.brikk-pattern .brikk-citysplit__media img {
    display: block;
    width: 100%;
    height: auto;
}

.brikk-pattern .brikk-citysplit__media figure {
    margin: 0;
}

.brikk-pattern .brikk-citysplit__eyebrow {
    display: block;
    /* Measured: comp puts 32px between the eyebrow's ink and the title's; at 26
       the gap rendered 42. */
    margin: 0 0 16px;
    /* The eyebrow primitive is an inline-block <span> in hand-written markup and
       a block <p> here, which changes what its line box resolves to. Restate the
       floor rather than the leading — a line-height override looks right on one
       line and is ~14px wrong the moment the label wraps (CLAUDE.md §6i). */
    min-height: calc(var(--wp--preset--font-size--body) * var(--wp--custom--lh-base));
}

.brikk-pattern .brikk-citysplit__title {
    margin: 0 0 26px;
    font-family: var(--wp--preset--font-family--serif);
    font-size: var(--wp--preset--font-size--heading-3);
    font-weight: 500;
    line-height: var(--wp--custom--lh-tight);
    letter-spacing: var(--wp--custom--ls-heading);
    color: var(--wp--preset--color--dark);
}

.brikk-pattern .brikk-citysplit__text {
    margin: 0 0 26px;
    font-size: var(--wp--preset--font-size--body);
    line-height: var(--wp--custom--lh-copy);
    color: var(--wp--preset--color--muted);
}

.brikk-pattern .brikk-citysplit__text:last-child {
    margin-bottom: 0;
}

.brikk-pattern .brikk-citysplit__cta {
    margin: 36px 0 0;
}

/* --- the numbered buyer profiles (--buyers only) -------------------------- */

.brikk-pattern .brikk-citysplit__list {
    margin-top: 41px;
}

.brikk-pattern .brikk-citysplit__item {
    display: grid;
    grid-template-columns: 75px 1fr;
    align-items: baseline;
    padding: 26px 0;
    border-top: 1px solid var(--wp--preset--color--line);
}

.brikk-pattern .brikk-citysplit__item > * {
    margin-block-start: 0;
    margin-block-end: 0;
}

.brikk-pattern .brikk-citysplit__num {
    grid-column: 1;
    grid-row: 1;
    font-family: var(--wp--preset--font-family--serif);
    font-style: italic;
    /* Measured: the comp's "01" is 21×13px of ink, which in Cormorant italic
       oldstyle figures is ~26px — the same size as the title beside it, not the
       17px heading-6 step it looked like. At 17 the numerals read as a footnote
       rather than as part of the item. */
    font-size: calc(26px * var(--brikk-heading-scale, 1));
    font-weight: 500;
    line-height: 1.2;
    color: var(--wp--preset--color--purple);
}

.brikk-pattern .brikk-citysplit__item-title {
    grid-column: 2;
    grid-row: 1;
    margin: 0;
    font-family: var(--wp--preset--font-family--serif);
    /* Off the type scale deliberately: heading-4 resolves to 30px at this
       viewport and the comp's ink measures 26. Same call as §12.6.3's flat 22px
       result count — the brief is a measured 1:1. */
    font-size: calc(26px * var(--brikk-heading-scale, 1));
    font-weight: 500;
    line-height: 1.2;
    letter-spacing: var(--wp--custom--ls-heading);
    color: var(--wp--preset--color--dark);
}

.brikk-pattern .brikk-citysplit__item-desc {
    grid-column: 2;
    grid-row: 2;
    margin: 10px 0 0;
    font-size: var(--wp--preset--font-size--body-sm);
    /* Measured: the comp's description lines are 21px apart, not the 24 that
       --lh-copy gives at 15px. These are short captions under a heading, not
       running prose. */
    line-height: var(--wp--custom--lh-base);
    color: var(--wp--preset--color--muted);
}

/* -----------------------------------------------------------------------------
   12.8b  BYEN I TAL  ·  .brikk-citystats
   -------------------------------------------------------------------------- */

.brikk-pattern.brikk-citystats {
    padding-top: var(--brikk-section-y);
    padding-bottom: var(--brikk-section-y);
    /* Not a backgroundColor attribute: the grid separators below are drawn from
       the same on-dark family and the two must not be editable apart. */
    background: var(--wp--preset--color--dark);
    color: var(--wp--custom--on-dark);
}

.brikk-pattern .brikk-citystats__head {
    /* Measured: the comp's intro spans x=478..1030, i.e. 552px centred on the
       page axis — not the 620px --measure token. */
    max-width: 560px;
    margin: 0 auto 62px;
    text-align: center;
}

.brikk-pattern .brikk-citystats__head > * {
    margin-block-start: 0;
    margin-block-end: 0;
}

.brikk-pattern .brikk-citystats__eyebrow {
    display: block;
    margin: 0 0 16px;
    color: var(--wp--custom--on-dark-accent);
    min-height: calc(var(--wp--preset--font-size--body) * var(--wp--custom--lh-base));
}

.brikk-pattern .brikk-citystats__title {
    margin: 0 0 23px;
    font-family: var(--wp--preset--font-family--serif);
    font-size: var(--wp--preset--font-size--heading-3);
    font-weight: 500;
    line-height: var(--wp--custom--lh-tight);
    letter-spacing: var(--wp--custom--ls-heading);
    color: var(--wp--custom--on-dark);
}

.brikk-pattern .brikk-citystats__intro {
    margin: 0;
    font-size: var(--wp--preset--font-size--body);
    line-height: 1.75;
    color: var(--wp--custom--on-dark-muted);
}

.brikk-pattern .brikk-citystats__grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    max-width: var(--wp--custom--max);
    margin-inline: auto;
    border-top: 1px solid var(--wp--custom--on-dark-line-faint);
    border-bottom: 1px solid var(--wp--custom--on-dark-line-faint);
}

.brikk-pattern .brikk-citystats__grid > * {
    margin-block-start: 0;
    margin-block-end: 0;
}

.brikk-pattern .brikk-citystats__stat {
    /* Measured off the comp's first column (65..409.5): label ink starts at 93
       and wraps by 308, so 28px in and ~100px of trailing air. The generous
       right padding is what makes the two-line label wrap where the comp does —
       at 30px it stayed on one line and the whole row read differently. */
    padding: 52px 100px 46px 28px;
    /* Separators sit BETWEEN the columns only — the comp draws none at the outer
       edges, where the horizontal rules already close the row. */
    border-left: 1px solid var(--wp--custom--on-dark-line-faint);
}

.brikk-pattern .brikk-citystats__stat:first-child {
    border-left: 0;
}

.brikk-pattern .brikk-citystats__stat > * {
    margin-block-start: 0;
    margin-block-end: 0;
}

.brikk-pattern .brikk-citystats__value {
    margin: 0 0 16px;
    font-family: var(--wp--preset--font-family--serif);
    font-size: calc(40px * var(--brikk-heading-scale, 1));
    font-weight: 500;
    line-height: 1;
    letter-spacing: var(--wp--custom--ls-heading);
    color: var(--wp--custom--on-dark);
}

.brikk-pattern .brikk-citystats__label {
    margin: 0;
    font-size: var(--wp--preset--font-size--ui);
    line-height: 1.5;
    color: var(--wp--custom--on-dark-faint);
}

.brikk-pattern .brikk-citystats__source {
    margin: 25px 0 0;
    text-align: center;
    font-size: var(--wp--preset--font-size--ui);
    line-height: 1.4;
    color: var(--wp--custom--on-dark-faint);
}

/* -----------------------------------------------------------------------------
   12.8c  SOLGTE BOLIGER, LYS VARIANT  ·  .brikk-results--city
   -----------------------------------------------------------------------------
   §12.3d's card grid on a light surface with a left-aligned head and no stats
   row. Only the surface-dependent properties are restated — the card, the tag,
   the address overlay and the 4:3 crop are §12.3d's and stay shared, so a change
   to a card there reaches this section too.
   -------------------------------------------------------------------------- */

.brikk-pattern.brikk-results--city {
    background: var(--wp--preset--color--bg-alt);
    color: var(--wp--preset--color--dark);
}

.brikk-pattern.brikk-results--city .brikk-results__head {
    max-width: none;
    margin: 0 0 44px;
    text-align: left;
}

.brikk-pattern.brikk-results--city .brikk-results__head .brikk-eyebrow {
    color: var(--wp--preset--color--muted);
    margin-bottom: 20px;
    /* Block <p> vs the hand-written <span> — see the note on
       .brikk-citysplit__eyebrow above. */
    min-height: calc(var(--wp--preset--font-size--body) * var(--wp--custom--lh-base));
}

.brikk-pattern.brikk-results--city .brikk-results__heading {
    margin: 0;
    color: var(--wp--preset--color--dark);
    text-wrap: initial;
}

/* The location line, italic serif — muted on a light surface where §12.3d uses
   the on-dark lavender. */
.brikk-pattern.brikk-results--city .brikk-results__price {
    color: var(--wp--preset--color--muted);
}

/* 🔴 THE CARD'S POSTCODE LINE SAT FLUSH AGAINST THE PHOTO. §12.3d gives it
   `margin: 18px 0 8px`, but the block-gap neutraliser below
   (`.brikk-pattern .brikk-results__card > *`) is (0,2,0) and zeroes it — the
   §6e trap in its usual costume, where a rule written to defeat core's layout
   CSS also defeats the design's own margin. Restated at (0,3,0) for the city
   variant only; the front page's grid renders flush and measured Δ0 against the
   A/B that way (§6p), so it must not be "fixed" there.
   16px, not §12.3d's 18: measured off the comp, the label's INK starts 19px
   below the photo and the italic's own half-leading already supplies 3. */
.brikk-pattern.brikk-results--city .brikk-results__card > .brikk-results__price {
    margin-top: 16px;
}

/* 🔴 core/image adds a <figure> the shortcode's markup has no equivalent of, and
   §12.3d sizes the <img> at height:100% against the card's 4:3 box. Without this
   the figure is an auto-height box in between and the crop collapses. */
.brikk-pattern .brikk-results__card-img .wp-block-image {
    margin: 0;
    height: 100%;
}

.brikk-pattern .brikk-results__card-img .wp-block-image img {
    height: 100%;
}

/* .brikk-results__tag is a <span> in the shortcode and a <p> here; it is
   absolutely positioned either way, so only the paragraph's own box needs
   neutralising. */
.brikk-pattern .brikk-results__card-img .brikk-results__tag,
.brikk-pattern .brikk-results__card-img .brikk-results__addr {
    margin: 0;
}

/* 🔴 CORE'S BLOCK GAP STAGGERED THE CARDS. As a core/group the grid gets
   `> *:not(:first-child) { margin-block-start: 24px }` from the layout CSS in
   the FOOTER, which beats a same-specificity theme rule on order — so cards
   2-4 sat 24px lower than card 1 and the row looked broken. The shortcode's
   plain <div> never had this. Restated at (0,2,0), the §6e rule: inside a
   pattern, never leave vertical rhythm to the block gap. */
.brikk-pattern .brikk-results__grid > *,
.brikk-pattern .brikk-results__card > *,
.brikk-pattern .brikk-results__card-img > * {
    margin-block-start: 0;
    margin-block-end: 0;
}

/* -----------------------------------------------------------------------------
   12.8d  RESPONSIVE
   -------------------------------------------------------------------------- */

@media (max-width: 1024px) {

    .brikk-pattern .brikk-citysplit__grid {
        grid-template-columns: 1fr;
        gap: 40px;
    }

    /* Stacked, the grid must fall back to DOM order — head, media, list — which
       is exactly what the mobile comp shows. Explicit placement would otherwise
       keep the media welded to a second column that no longer exists. */
    .brikk-pattern.brikk-citysplit--buyers .brikk-citysplit__copy,
    .brikk-pattern.brikk-citysplit--buyers .brikk-citysplit__list,
    .brikk-pattern.brikk-citysplit--buyers .brikk-citysplit__media {
        grid-column: auto;
        grid-row: auto;
    }

    .brikk-pattern .brikk-citysplit__list {
        margin-top: 8px;
    }

    .brikk-pattern .brikk-citystats__grid {
        grid-template-columns: 1fr;
        border-bottom: 0;
    }

    .brikk-pattern .brikk-citystats__stat {
        padding: 30px 0;
        border-left: 0;
        padding-left: 0;
        border-top: 1px solid var(--wp--custom--on-dark-line-faint);
    }

    .brikk-pattern .brikk-citystats__stat:first-child {
        border-top: 0;
    }

    .brikk-pattern .brikk-citystats__head {
        margin-bottom: 44px;
    }

    .brikk-pattern .brikk-citystats__source {
        margin-top: 40px;
    }
}

@media (max-width: 1024px) {

    /* 🔴 THE SOLD ROW IS A HORIZONTAL CAROUSEL BELOW DESKTOP, NOT A STACK, and
       that is what the arrows in the desktop comp are for. Stacked, the four
       cards made this section 1548px tall on a 420px phone against the comp's
       ~470 — a third of the page for four thumbnails. Scroll-snapped, one card
       reads at a time with the next peeking, which is what the mobile comp
       shows.

       ⚠️ No JS: `overflow-x: auto` + scroll snapping is the whole mechanism, so
       there is nothing for an optimisation plugin to break — the same reasoning
       as the CSS-only FAQ accordion (CLAUDE.md §4). The desktop arrows are
       therefore still not wired to anything; see patterns/city-sold.php.

       ⚠️ The track bleeds to the RIGHT viewport edge only. A gutter on both
       sides would hide the peeking card, which is the affordance that tells a
       visitor the row scrolls at all. */
    .brikk-pattern.brikk-results--city .brikk-results__grid {
        display: grid;
        grid-auto-flow: column;
        grid-auto-columns: 72%;
        grid-template-columns: none;
        gap: 16px;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        scroll-padding-left: var(--brikk-pad-x);
        margin-inline-end: calc(var(--brikk-pad-x) * -1);
        padding-inline-end: var(--brikk-pad-x);
        /* The row is swiped, not read as a scrollbar. */
        scrollbar-width: none;
        /* Smooth only for the injected forward button — a swipe is already
           direct. Declared on the track rather than passed as
           scrollTo({behavior}) so §3's reduced-motion block, which resets
           scroll-behavior, still governs it (the §6l rule: never name a
           behavior in JS and duplicate that decision). */
        scroll-behavior: smooth;
    }

    .brikk-pattern.brikk-results--city .brikk-results__grid::-webkit-scrollbar {
        display: none;
    }

    .brikk-pattern.brikk-results--city .brikk-results__card {
        scroll-snap-align: start;
    }
}

/* §3's kill switch resets scroll-behavior on <html>, which is not inherited, so
   the track needs its own reset. */
@media (prefers-reduced-motion: reduce) {
    .brikk-pattern.brikk-results--city .brikk-results__grid {
        scroll-behavior: auto;
    }
}

@media (max-width: 768px) {

    .brikk-pattern .brikk-citysplit__item {
        grid-template-columns: 58px 1fr;
        padding: 22px 0;
    }
}

@media (max-width: 640px) {

    .brikk-pattern .brikk-citysplit__eyebrow,
    .brikk-pattern .brikk-citystats__eyebrow {
        margin-bottom: 18px;
    }

    .brikk-pattern .brikk-citysplit__title,
    .brikk-pattern .brikk-citystats__title {
        margin-bottom: 20px;
    }

    .brikk-pattern .brikk-citysplit__text,
    .brikk-pattern .brikk-citysplit__item-desc {
        font-size: var(--wp--preset--font-size--body-sm);
    }

    .brikk-pattern .brikk-citysplit__cta {
        margin-top: 28px;
    }

    .brikk-pattern .brikk-citystats__value {
        /* Measured on the mobile comp: 32px of ink, and 13px to the label. */
        font-size: calc(32px * var(--brikk-heading-scale, 1));
        margin-bottom: 13px;
    }

    /* The intro is running prose in a 420px column; at 16px/1.75 it took five
       lines with 28px leading where the comp takes four at 23.5. */
    .brikk-pattern .brikk-citystats__intro {
        font-size: var(--wp--preset--font-size--body-sm);
        line-height: 1.6;
    }

    .brikk-pattern .brikk-citystats__eyebrow {
        margin-bottom: 8px;
    }
}


/* -----------------------------------------------------------------------------
   12.8e  BYSIDE-JUSTERINGER  ·  body.page-template-brikk-prebuilt-local-page
   -----------------------------------------------------------------------------
   Everything here is scoped to the CITY PAGE TEMPLATE and nothing else. The
   hook is WordPress's own `page-template-<file>` body class, which is keyed on
   the template FILE — so it survives a page being recreated, exactly like
   brikk_is_redesigned_page(). 🔴 Renaming page-templates/brikk-prebuilt-local-page.php
   silently kills every rule below; it is on the §6f rename checklist.

   These are the four things a city page needs that the shared sections do not
   (Andreas, 2026-08-05), plus the mobile carousel control.
   -------------------------------------------------------------------------- */

/* --- 1. THE TYPE SCALE ----------------------------------------------------
   Every serif display size on the site is written
   `calc(<size> * var(--brikk-heading-scale, 1))`, so ONE declaration here
   rescales the whole page and the sizes themselves stay defined once, where
   they were measured. Nothing else in the codebase sets the variable, so it is
   `1` — i.e. a provable no-op — everywhere except a city page.

   ⚠️ WHY ONLY THE HEADINGS. Body copy, labels and buttons are NOT scaled: at
   .8 the 15px body-sm step lands on 12px, below anything else on the site, and
   the reason for scaling is the headings — a city name inside them ("Hvorfor
   vælge Brikk som din ejendomsmægler i Næstved?") is what runs long.

   ⚠️ THE PRESET OVERRIDE IS THE SECOND HALF OF THE SAME MECHANISM, and it
   cannot be written on one element: `--x: calc(var(--x) * .8)` is a custom-
   property CYCLE and drops the declaration. The source values are therefore
   captured on <body> and the scaled values written on .brikk-main, which is a
   different element — no cycle, and the chrome outside <main> is untouched.

   🟠 .8 is Andreas's number, not the comp's. Measured, the comp's own type is
   ~10% below what we render (its section title's ink is 671px wide against our
   749 for the same string at the same 1508px viewport), so at .8 these pages
   land NOTICEABLY smaller than the design. One number to change if that reads
   too small. */

body.page-template-brikk-prebuilt-local-page {
    --brikk-city-type-scale: .8;

    --brikk-city-type-src-display: var(--wp--preset--font-size--display);
    --brikk-city-type-src-heading-1: var(--wp--preset--font-size--heading-1);
    --brikk-city-type-src-heading-2: var(--wp--preset--font-size--heading-2);
    --brikk-city-type-src-heading-3: var(--wp--preset--font-size--heading-3);
    --brikk-city-type-src-heading-4: var(--wp--preset--font-size--heading-4);
    --brikk-city-type-src-heading-compact: var(--wp--preset--font-size--heading-compact);
}

body.page-template-brikk-prebuilt-local-page .brikk-main {
    --brikk-heading-scale: var(--brikk-city-type-scale);

    --wp--preset--font-size--display: calc(var(--brikk-city-type-src-display) * var(--brikk-city-type-scale));
    --wp--preset--font-size--heading-1: calc(var(--brikk-city-type-src-heading-1) * var(--brikk-city-type-scale));
    --wp--preset--font-size--heading-2: calc(var(--brikk-city-type-src-heading-2) * var(--brikk-city-type-scale));
    --wp--preset--font-size--heading-3: calc(var(--brikk-city-type-src-heading-3) * var(--brikk-city-type-scale));
    --wp--preset--font-size--heading-4: calc(var(--brikk-city-type-src-heading-4) * var(--brikk-city-type-scale));
    --wp--preset--font-size--heading-compact: calc(var(--brikk-city-type-src-heading-compact) * var(--brikk-city-type-scale));
}

/* --- 2. THE LOGO STRIP, MOBILE ONLY ---------------------------------------
   The comp fits all four marks on ONE row; the shared strip wraps Instagram
   onto a second at ≤640. Measured off the mobile comp (a 420px viewport):
   ink widths 56 / 46 / 46 / 42 at ~20px gaps — i.e. .53 of what the shared
   ≤640 rule renders. The heights below are that ratio applied to §12.4's
   18 / 22 / 23, and the baseline nudges scale with them (the strip is sized by
   HEIGHT and hand-nudged onto a common baseline — §6e lesson 3; scaling the
   heights without the margins loses the baseline).

   At this size the row is ~190px of ink plus 3×16px of gap = 238px, so it
   still fits one line inside the 280px content column of a 320px phone. */
@media (max-width: 640px) {

    body.page-template-brikk-prebuilt-local-page .brikk-pattern .brikk-logos__list {
        flex-wrap: nowrap;
        gap: 16px;
    }

    body.page-template-brikk-prebuilt-local-page .brikk-pattern .brikk-logos__list img {
        height: 9.5px;
    }

    body.page-template-brikk-prebuilt-local-page .brikk-pattern .brikk-logos__list .brikk-logo-boligsiden img {
        height: 12px;
        margin-bottom: -1px;
    }

    body.page-template-brikk-prebuilt-local-page .brikk-pattern .brikk-logos__list .brikk-logo-instagram img {
        height: 12px;
        margin-bottom: -3px;
    }
}

/* --- 3. THE MARKETING MOCK-UP MOVES UNDER THE LEAD, MOBILE ONLY -----------
   The comp puts the phone mock-up directly after the lead paragraph and BEFORE
   the numbered list; stacked, the shared pattern puts it after the whole copy
   column, i.e. after all five items.

   ⚠️ THE LIST IS NESTED INSIDE .brikk-marketing__copy, so `order` alone cannot
   interleave the mock-up between two of its siblings' children. `display:
   contents` promotes the copy's four children into the grid, after which
   ordering works — and it is the only mechanism that does, short of moving the
   list out of the copy column, which is markup and therefore a hundred
   per-page edits (§6f).

   ⚠️ ROW GAP MUST GO TO 0 IN THE SAME BREATH. With the copy dissolved, the
   grid's ≤1024 `gap: spacing--7` would land between the eyebrow, the title,
   the lead, the mock-up and the list — five gaps where there was one. Every
   one of those children already carries its own bottom margin, so 0 is the
   correct row gap, and the mock-up's own 8px padding plus the lead's 28px
   margin give the comp's ~35px above it. */
@media (max-width: 640px) {

    body.page-template-brikk-prebuilt-local-page .brikk-pattern .brikk-marketing__grid {
        row-gap: 0;
    }

    body.page-template-brikk-prebuilt-local-page .brikk-pattern .brikk-marketing__copy {
        display: contents;
    }

    body.page-template-brikk-prebuilt-local-page .brikk-pattern .brikk-marketing__media {
        order: 1;
    }

    body.page-template-brikk-prebuilt-local-page .brikk-pattern .brikk-marketing__list {
        order: 2;
    }
}

/* --- 4. THE SOLD-HOMES CAROUSEL CONTROL -----------------------------------
   §12.8d already makes the row a scroll-snapped carousel below 1025px with no
   JS at all. This adds the forward control the desktop comp draws and Andreas
   asked for on mobile: one button, advancing a card at a time and wrapping to
   the first card at the end.

   ⚠️ THE BUTTON IS INJECTED BY assets/js/city-sold.js, NOT by the pattern, and
   that is deliberate twice over. A control that does nothing without JS must
   not exist without JS (the row stays swipeable either way), and markup added
   to the pattern would reach only city pages built AFTER the change — the
   existing ones carry a COPY of it in post_content (§6f). Injecting it reaches
   all of them with no page edits.

   ⚠️ IT IS ABSOLUTELY POSITIONED, NOT A FLEX SIBLING. The head's two children
   are the eyebrow and the heading, stacked; making the head a flex row to push
   the button right also puts the eyebrow BESIDE the heading instead of above
   it. Taking the button out of flow leaves the stack alone, and the reserved
   right padding is what keeps the heading from running under it. */
.brikk-pattern.brikk-results--city .brikk-results__head.has-nav {
    position: relative;
    padding-right: 68px;
}

.brikk-results__nav {
    position: absolute;
    right: 0;
    /* Bottom-aligned with the heading, which is what the comp draws. */
    bottom: 0;
    display: flex;
    gap: 10px;
    margin: 0;
    padding: 0;
}

.brikk-results__nav-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    background: transparent;
    border: 1px solid var(--wp--preset--color--purple);
    border-radius: 999px;
    color: var(--wp--preset--color--purple);
    cursor: pointer;
    /* The one round control in the design language — the comp draws the sold
       row's arrows as circles, unlike every other square-edged surface, so
       --brikk-radius deliberately does not apply. */
    transition: background var(--wp--custom--transition), color var(--wp--custom--transition);
}

.brikk-results__nav-btn:hover,
.brikk-results__nav-btn:focus-visible {
    background: var(--wp--preset--color--purple);
    color: var(--wp--custom--on-accent);
}

.brikk-results__nav-btn svg {
    display: block;
    /* 🔴 STATE THE SIZE. §3's reset gives every svg `max-width: 100%`, and an
       icon that takes its size from its width/height ATTRIBUTES resolves to
       0×0 against a zero-width parent — the bug that made the nav chevrons
       invisible on redesigned pages (§6h). */
    width: 15px;
    height: 15px;
    max-width: none;
}

/* Desktop shows all four cards, so there is nothing to page through — the JS
   only injects the control where the track actually overflows, and this is the
   belt to that braces. */
@media (min-width: 1025px) {
    .brikk-results__nav {
        display: none;
    }
}


/* =============================================================================
   12.9  BOLIGSIDE (SINGLE PROPERTY)  ·  .brikk-sp
   -----------------------------------------------------------------------------
   The single property page (nsa_js_property CPT) at /ejendom/<slug>/.
   Comps: claude-new-designs/single-property/default-view.png (1439px = a 1440
   viewport @1x), after-clicking-flere-billeder.png (same + the thumbnail strip
   expanded — everything else pixel-identical), mobile-view.png (391px = 390 @1x).
   Numbers below are measured off them; extraction notes in CLAUDE.md §6t.

   Template: single-nsa_js_property.php (WP template hierarchy — matched by
   brikk_is_redesigned_page() via is_singular('nsa_js_property'), NOT via
   $redesigned_templates). JS: assets/js/single-property.js. The page renders
   with the real site chrome; the comps' header/footer are dummy chrome.

   ⚠️ NOT a block-pattern page. The markup is plain PHP output — none of §12.4's
   `.brikk-pattern` marker dance applies to `.brikk-sp*`: the vocabulary exists
   nowhere in landing.css, brikk.css or any A/B template (checked mechanically).

   LAYOUT MODEL
     ≥1025px  hero slider 760px tall (clamped to the viewport on short screens)
              with overlaid badge / fullscreen / caption / tab bar; optional
              white thumbnail strip; identity band; main grid = content column +
              412px card rail (81px gutter); photo CTA band above the footer.
     ≤1024px  the comps' mobile structure: hero (aspect 1.3) + 2-up thumb grid +
              floating 3-icon pill; identity/price/buttons in flow; a mobile
              facts card replaces the rail price card; mægler + dark cards
              follow the content. Same DOM, CSS-switched — only image RESIZE
              stays UA-based (legacy behaviour, §6t).
     ≤640px   exact mobile-comp values; the CTA photo band is hidden (absent
              from the mobile comp).

   MEASURED GEOMETRY (1440 viewport)
     hero photo ...... 760px tall, full bleed; arrows ink 18×37 at 37px insets
     badge ........... 28px tall, 22/22 inset, purple, 10px/500/ls-ui
     fuld skærm ...... 105×59 at 21/22, black @ .28 over the photo
     tab bar ......... 96px tall, right-aligned: N tabs × 104px on dark @ .87
                       + 128px purple BOOK FREMVISNING block
     pill ............ 52px tall, r=pill, PAGE-BG fill (not white), straddles
                       the hero bottom edge (26px above / 26px below)
     thumb strip ..... white band, pad 40/20/20, tiles 5-up gap 16, ratio 267:148
     identity band ... pad-block 58/41, columns bottom-aligned (align-items:end),
                       h1 50px serif · price 50px + "kr." 28px same ink ·
                       buttons 47px tall, gap 12 · bottom hairline --line-page
     main grid ....... minmax(0,1fr) + 412px, gap 81, pad-block 58/96
     rail cards ...... card-soft + line-card border, pad 32, gap 24; facts rows
                       13px on a 28px pitch; in-card hairlines border-to-border
     dark card ....... --dark bg, cream serif 28px heading, on-dark-purple
                       eyebrow + button (43px tall, DARK label — comp-measured)
     CTA band ........ 463px tall, bottom-weighted scrim, 1×42px on-dark-purple
                       rule, serif 50px white, white button 49px w/ purple label

   COLOUR SUBSTITUTIONS (comp → token; established folds, all documented)
     #f6f4f0 page bg → --bg (Δ2, §12.6 precedent) · #1e1826 ink → --dark (§6l)
     #211c18 dark card → --dark (§6l) · #8a8294 eyebrows → --muted (DESIGN.md §9)
     #4c4751/#49444e/#4f4a54 body/value ink → --plist-tick (Δ≤4)
     #77737a/#79757b/#68646a secondary text → --muted (§12.6 fold)
   EXACT MATCHES
     #6a2cdb --purple · #9a73e6 --on-dark-purple · #fbfaf8 --card-soft
     #e0dede --line-card · #ffffff --card
   NEW TOKENS (theme.json)
     --line-page #dbd8d7  the page-level hairline — measured identically at 7+
                          positions in all three comps; --line-cool is Δ5 away,
                          just outside the fold threshold, so it gets its own
                          token rather than a silent retune of line-cool.
     --on-dark-cream #efe7da  the dark card's serif heading ink (both
                          viewports); nearest token --bg is Δ(6,11,20) — a
                          visibly different warm cream, not foldable. The dark
                          card's body text derives from it via color-mix (45%).
   ============================================================================= */

/* --- 12.9.0  Page shell ---------------------------------------------------- */

/* The whole page sits on the warm canvas; sections manage their own surfaces. */
.brikk-main--sp {
    display: block;
    background: var(--wp--preset--color--bg);
}

/* Shared container: 1600 max with the responsive gutter INSIDE it (the
   §12.6.1 idiom — never .brikk-gutter on the outer element, so wide screens
   keep every section aligned; §6l's >1600px lesson). */
.brikk-sp-container {
    box-sizing: border-box;
    max-width: var(--wp--custom--max);
    margin-inline: auto;
    padding-inline: var(--brikk-pad-x);
}

/* --- 12.9.1  Hero gallery -------------------------------------------------- */

.brikk-sp-gallery {
    position: relative;
    background: var(--wp--preset--color--dark);
    /* The "Flere billeder" band's fixed height — a local component knob (the
       --brikk-flow-space precedent, not a design token): the strip, its thumbs
       AND the open-state push-up of caption/scrim/tabs all derive from it, so
       they can never drift apart. 140 = 100px thumbs (the live site's nav
       height) + 2×20 padding. */
    --brikk-sp-strip-h: 140px;
}

/* Viewport-filling, the LIVE site's model (Andreas 2026-08-07 — supersedes the
   comp's measured 760px cap): the photo grows with the screen, so a big screen
   gets a big hero. The 125px it leaves = the 94px header + the pill's 26px
   overhang below the stage edge + 5px breathing room, so "+ FLERE BILLEDER" is
   fully inside the fold at scroll 0 (Andreas, same day, round 2). 550px floor
   = live's own min-height, for short laptop windows. ≤1024 overrides to the
   aspect-ratio photo. */
.brikk-sp-gallery__stage {
    position: relative;
    height: max(550px, calc(100vh - 125px));
    /* NO overflow clipping. Two real bugs came from clipping this box:
       overflow:hidden made it SCROLLABLE (clicking/focusing the pill scrolled
       the hero 26px), and overflow:clip cut the pill's designed 26px overhang
       in half. Nothing here needs cropping — every pane is inset:0 and slick
       clips its own slides — and a visible box can never scroll. */
}

/* Panes (photos / video / 3D / map / plans / indretning) fill the stage. */
.brikk-sp-pane {
    display: none;
    position: absolute;
    inset: 0;
}

.brikk-sp-pane.is-active {
    display: block;
}

/* Sliders fill their pane — including UN-slicked ones (a single floorplan
   never initialises slick and would otherwise have zero height). */
.brikk-sp-pane .brikk-sp-slider,
.brikk-sp-pane .slick-slider,
.brikk-sp-pane .slick-list,
.brikk-sp-pane .slick-track {
    height: 100%;
}

/* No-JS / pre-init guard: until slick initialises, only the first slide shows
   — otherwise every photo stacks at full pane height (§11's own rule hides
   slides only once .slick-initialized EXISTS, which without JS is never). */
.brikk-sp-slider:not(.slick-initialized) .brikk-sp-slide:nth-child(n+2) {
    display: none;
}

.brikk-sp-slide {
    position: relative;
    height: 100%;
    background-position: center;
    background-size: cover;
    background-repeat: no-repeat;
}

/* Iframe panes (video / 3D / indretning) and the map fill the stage. */
.brikk-sp-pane iframe,
.brikk-sp-pane .acf-map {
    display: block;
    width: 100%;
    height: 100%;
    border: 0;
}

/* Indretning: several stacked full-height iframes — scroll INSIDE the pane
   (the stage no longer clips, so an unscrolled pane would spill the page). */
.brikk-sp-pane--indretning {
    overflow-y: auto;
}

/* Video/3D/map panes sit on dark so letterboxing never flashes page-bg. */
.brikk-sp-pane--video,
.brikk-sp-pane--tour,
.brikk-sp-pane--map {
    background: var(--wp--preset--color--dark);
}

/* Plans pane: white ground so a portrait drawing reads as a document. */
.brikk-sp-pane--plans {
    background: var(--wp--preset--color--card);
}

.brikk-sp-pane--plans .brikk-sp-slide {
    background-size: contain;
    background-color: var(--wp--preset--color--card);
}

/* Status badge — 22/22 inset, 28px tall, 10px tracked caps on purple. */
.brikk-sp-gallery__badge {
    position: absolute;
    top: 22px;
    left: 22px;
    z-index: var(--wp--custom--z-raised);
    display: inline-flex;
    align-items: center;
    box-sizing: border-box;
    height: 28px;
    /* 0.2em top = the §12.6.0 cap-height centring correction. */
    padding: 0.2em 14px 0;
    background: var(--wp--preset--color--purple);
    color: var(--wp--custom--on-accent);
    font-family: var(--wp--preset--font-family--sans);
    font-size: 10px;
    font-weight: 500;
    letter-spacing: var(--wp--custom--ls-ui);
    text-transform: uppercase;
    white-space: nowrap;
}

/* The badge as the open-house SIGNUP opener (2026-08-07: the identity-band
   notice is gone, so a signup-required open house enters its modal here). */
.brikk-sp-gallery__badge--action {
    border: 0;
    cursor: pointer;
    transition: background var(--wp--custom--transition);
}

.brikk-sp-gallery__badge--action:hover,
.brikk-sp-gallery__badge--action:focus-visible {
    background: var(--wp--custom--purple-hover);
}

/* Fullscreen toggle — 105×59 box at 21/22, black @ .28, icon over label. */
.brikk-sp-gallery__fullscreen {
    position: absolute;
    top: 22px;
    right: 21px;
    z-index: var(--wp--custom--z-raised);
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 7px;
    box-sizing: border-box;
    width: 105px;
    height: 59px;
    padding: 0.2em 8px 0;
    border: 0;
    background: rgba(0, 0, 0, 0.28);
    color: var(--wp--custom--on-dark);
    font-family: var(--wp--preset--font-family--sans);
    font-size: 10px;
    font-weight: 500;
    letter-spacing: var(--wp--custom--ls-ui);
    text-transform: uppercase;
    white-space: nowrap;
    cursor: pointer;
    transition: background var(--wp--custom--transition);
}

.brikk-sp-gallery__fullscreen:hover,
.brikk-sp-gallery__fullscreen:focus-visible {
    background: rgba(0, 0, 0, 0.45);
}

.brikk-sp-gallery__fullscreen svg {
    display: block;
    /* State the size — §6h's chevron rule (svg max-width:100% vs attributes). */
    width: 13px;
    height: 13px;
    max-width: none;
}

/* The button holds both state labels; only one shows. Each is its own
   icon-over-label column. */
.brikk-sp-fs-open,
.brikk-sp-fs-close {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 7px;
}

.brikk-sp-fs-close,
.brikk-sp-gallery.is-fullscreen .brikk-sp-fs-open {
    display: none;
}

.brikk-sp-gallery.is-fullscreen .brikk-sp-fs-close {
    display: inline-flex;
}

/* Prev/next — bare white chevrons, ink 18×37, vertically centred. */
.brikk-sp-gallery__arrow {
    position: absolute;
    top: 50%;
    z-index: var(--wp--custom--z-raised);
    transform: translateY(-50%);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 56px;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--wp--custom--on-dark);
    cursor: pointer;
    opacity: 0.9;
    transition: opacity var(--wp--custom--transition);
}

.brikk-sp-gallery__arrow:hover,
.brikk-sp-gallery__arrow:focus-visible {
    opacity: 1;
}

.brikk-sp-gallery__arrow--prev { left: 24px; }
.brikk-sp-gallery__arrow--next { right: 24px; }

.brikk-sp-gallery__arrow svg {
    display: block;
    width: 18px;
    height: 37px;
    max-width: none;
    filter: drop-shadow(0 1px 6px rgba(0, 0, 0, 0.35));
}

/* Legibility scrim — the caption sits on arbitrary feed photos, and text-shadow
   alone was not enough on bright ones (Andreas, 2026-08-07: the address was
   "still too difficult to see"; the comp's photo is dark at the bottom and
   cannot show the need). Bottom fade only. z-raised lifts it above the fade
   slider (whose inline z-indexes are contained by §11's slick-list/track
   translate3d stacking context); every other overlay is ALSO z-raised and
   comes later in the stage's DOM, so the tie keeps them all above the scrim. */
.brikk-sp-gallery__scrim {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 46%;
    z-index: var(--wp--custom--z-raised);
    background: linear-gradient(to top, rgba(0, 0, 0, 0.55) 0%, rgba(0, 0, 0, 0.26) 48%, rgba(0, 0, 0, 0) 100%);
    pointer-events: none;
    transition: transform 0.25s ease; /* rides up with the strip — see 12.9.2 */
}

/* Caption — address + price/contact over the photo, bottom-left at the page
   gutter. Right inset keeps it clear of the 672px tab bar + breathing room. */
.brikk-sp-gallery__caption {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 44px;
    z-index: var(--wp--custom--z-raised);
    pointer-events: none;
    transition: transform 0.25s ease; /* rides up with the strip — see 12.9.2 */
}

.brikk-sp-gallery__caption-inner {
    box-sizing: border-box;
    max-width: var(--wp--custom--max);
    margin-inline: auto;
    padding-inline: var(--brikk-pad-x);
    /* Clear of the tab bar (up to 6 tabs × 104 + 128 book block) with the
       comp's breathing room; the comp's address runs to 758px at 1440. */
    padding-right: 600px;
}

.brikk-sp-gallery__address {
    margin: 0;
    font-family: var(--wp--preset--font-family--serif);
    font-size: 48px;
    font-weight: 500;
    line-height: var(--wp--custom--lh-tight);
    letter-spacing: var(--wp--custom--ls-heading);
    color: var(--wp--custom--on-dark);
    /* Same dual-shadow treatment as the meta line below: a tight one for edge
       definition on bright photos + the soft ambient one. Works WITH the
       scrim — neither alone carried a white serif on a pale sky. */
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.4), 0 2px 14px rgba(0, 0, 0, 0.3);
}

.brikk-sp-gallery__meta {
    margin: 12px 0 0;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 13.5px;
    font-weight: 400;
    line-height: var(--wp--custom--lh-base);
    /* On-photo overlay ink, measured white @ .85 on the comp — one of the
       §12.9-header "semi-transparent fills (no solid token)" values, like the
       tab bar's .87 dark. Deliberately not a token. */
    color: rgba(255, 255, 255, 0.85);
    /* Two shadows: a tight one for edge definition on BRIGHT photos (the comp's
       photo is dark there and cannot show the need) + the soft ambient one. */
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.45), 0 1px 10px rgba(0, 0, 0, 0.35);
}

.brikk-sp-gallery__meta a {
    color: inherit;
    text-decoration: none;
    pointer-events: auto;
}

.brikk-sp-gallery__meta a:hover {
    text-decoration: underline;
}

/* Caption, scrim, pill and strip only make sense over the PHOTO slider — the
   JS stamps the active pane on the gallery (and closes the strip when leaving
   photos, so aria-expanded stays truthful). White caption text on the white
   plans pane, a dark scrim over the map, or thumbnails over the 3D tour all
   read as defects. */
.brikk-sp-gallery[data-pane]:not([data-pane='photos']) .brikk-sp-gallery__caption,
.brikk-sp-gallery[data-pane]:not([data-pane='photos']) .brikk-sp-gallery__scrim,
.brikk-sp-gallery[data-pane]:not([data-pane='photos']) .brikk-sp-gallery__pill,
.brikk-sp-gallery[data-pane]:not([data-pane='photos']) .brikk-sp-strip-wrap {
    display: none;
}

.brikk-sp-gallery[data-pane]:not([data-pane='photos']):not([data-pane='plans']) .brikk-sp-gallery__arrow {
    display: none;
}

/* Tab bar — pinned to the hero's bottom-right. Dark @ .87 behind the tabs,
   solid purple behind the booking link. 104px per tab, 96px tall. */
.brikk-sp-tabs {
    position: absolute;
    right: 0;
    bottom: 0;
    z-index: var(--wp--custom--z-raised);
    display: flex;
    align-items: stretch;
    height: 96px;
    transition: transform 0.25s ease; /* rides up with the strip — see 12.9.2 */
}

.brikk-sp-tabs__group {
    display: flex;
    align-items: stretch;
    background: color-mix(in srgb, var(--wp--preset--color--dark) 87%, transparent);
}

.brikk-sp-tabs__tab {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 9px;
    box-sizing: border-box;
    width: 104px;
    padding: 0.2em 6px 0;
    border: 0;
    background: transparent;
    color: var(--wp--custom--on-dark);
    font-family: var(--wp--preset--font-family--sans);
    font-size: 10px;
    font-weight: 500;
    letter-spacing: var(--wp--custom--ls-ui);
    text-transform: uppercase;
    white-space: nowrap;
    cursor: pointer;
    transition: background var(--wp--custom--transition);
}

.brikk-sp-tabs__tab:hover,
.brikk-sp-tabs__tab:focus-visible {
    background: rgba(255, 255, 255, 0.08);
}

.brikk-sp-tabs__tab svg {
    display: block;
    width: 20px;
    height: 18px;
    max-width: none;
}

/* Booking link — the solid purple end block, two-line label. */
.brikk-sp-tabs__book {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    width: 128px;
    padding: 0.2em 14px 0;
    background: var(--wp--preset--color--purple);
    color: var(--wp--custom--on-accent);
    font-family: var(--wp--preset--font-family--sans);
    font-size: 10px;
    font-weight: 500;
    line-height: 2.1;
    letter-spacing: var(--wp--custom--ls-ui);
    text-transform: uppercase;
    text-align: center;
    text-decoration: none;
    transition: background var(--wp--custom--transition);
}

.brikk-sp-tabs__book:hover,
.brikk-sp-tabs__book:focus-visible {
    background: var(--wp--custom--purple-hover);
}

/* Fullscreen state — the gallery takes the whole viewport. The JS re-measures
   slick on toggle (slick + resized container = §5b's setPosition rule). */
.brikk-sp-gallery.is-fullscreen {
    position: fixed;
    inset: 0;
    z-index: var(--wp--custom--z-modal);
}

.brikk-sp-gallery.is-fullscreen .brikk-sp-gallery__stage {
    height: 100vh;
}

/* The strip and pill make no sense over a fullscreen photo. */
.brikk-sp-gallery.is-fullscreen .brikk-sp-gallery__pill,
.brikk-sp-gallery.is-fullscreen .brikk-sp-strip-wrap {
    display: none;
}

/* --- 12.9.2  "Flere billeder" pill + thumbnail strip ----------------------- */

/* The pill straddles the hero's bottom edge: 52px tall, centred, PAGE-BG fill
   (measured #f6f4f0 — deliberately not white). */
.brikk-sp-gallery__pill {
    position: absolute;
    left: 50%;
    bottom: -26px;
    z-index: calc(var(--wp--custom--z-raised) + 1);
    transform: translateX(-50%);
    display: inline-flex;
    align-items: center;
    gap: 14px;
    box-sizing: border-box;
    height: 52px;
    padding: 0.2em 30px 0;
    border: 0;
    border-radius: var(--wp--custom--radius-pill);
    background: var(--wp--preset--color--bg);
    color: var(--wp--preset--color--dark);
    font-family: var(--wp--preset--font-family--sans);
    font-size: 10px;
    font-weight: 500;
    letter-spacing: var(--wp--custom--ls-ui);
    text-transform: uppercase;
    white-space: nowrap;
    cursor: pointer;
    box-shadow: 0 12px 24px rgba(26, 26, 26, 0.1);
}

.brikk-sp-gallery__pill svg {
    display: block;
    width: 11px;
    height: 11px;
    max-width: none;
}

/* The pill's two states share one button; JS toggles .is-open on the gallery. */
.brikk-sp-gallery__pill .brikk-sp-pill-close,
.brikk-sp-gallery.is-open .brikk-sp-gallery__pill .brikk-sp-pill-open {
    display: none;
}

.brikk-sp-gallery.is-open .brikk-sp-gallery__pill .brikk-sp-pill-close {
    display: inline-flex;
    align-items: center;
    gap: 14px;
}

.brikk-sp-gallery__pill .brikk-sp-pill-open {
    display: inline-flex;
    align-items: center;
    gap: 14px;
}

/* The strip: a white band that SLIDES UP over the hero's bottom edge — the
   LIVE site's behaviour (Andreas 2026-08-07; supersedes the comp's
   below-the-hero grid, which pushed the whole page down and landed below the
   fold). One row of thumbnails in a NATIVE scroll container (below) — NOT a
   slick carousel: Andreas asked for a smooth, mobile-like trackpad scroll,
   and a stepped carousel cannot give momentum scrolling however it is driven.
   Absolute in the STAGE, so opening moves no page content; closed = translated
   fully below the clip frame + visibility:hidden. The visibility transition
   holds the band visible for the whole slide-down on close, then removes it. */

/* The clip frame (2026-08-07, closing-animation fix): unclipped, the band
   slid DOWN past the hero's edge, floated over the identity band below, then
   popped hidden when the transition ended — "slowly moves down and then goes
   from 100% to 0% visible" (Andreas). Clipped to exactly the band's region,
   the same transition reads as the band sinking into the hero's bottom edge
   (and rising out of it on open — which had the same overlap artifact in
   reverse). overflow: clip, NOT hidden — a hidden box is programmatically
   scrollable and a focus inside it would scroll it (the §6t round-2 stage
   bug); a clip box can never scroll. pointer-events pass through, so the
   caption's phone link underneath stays clickable while the band is closed.
   z ties with the caption/tab bar (all z-raised); the frame is LAST in the
   stage's DOM, so the open band paints above them — moot in practice, since
   .is-open also pushes both up out of the way — and the pill (+1) stays
   clickable above it. */
.brikk-sp-strip-wrap {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: var(--brikk-sp-strip-h);
    overflow: clip;
    pointer-events: none;
    z-index: var(--wp--custom--z-raised);
}

.brikk-sp-strip {
    position: absolute;
    inset: 0;
    box-sizing: border-box;
    background: var(--wp--preset--color--card);
    pointer-events: auto;
    transform: translateY(100%);
    visibility: hidden;
    /* Asymmetric visibility: the 0.25s DELAY here (the closing direction)
       holds the band visible through the whole slide-down; the open state
       flips to visible with NO transition, so a thumb is focusable in the
       same tick the pill handler opens the band — a symmetric `visibility
       .25s` computes hidden at t=0 and a synchronous focus() can silently
       fail. */
    transition: transform 0.25s ease, visibility 0s linear 0.25s;
}

.brikk-sp-gallery.is-open .brikk-sp-strip {
    transform: none;
    visibility: visible;
    transition: transform 0.25s ease, visibility 0s;
}

/* Opening the band pushes the caption, scrim and tab bar UP by its height, so
   the address and BOOK FREMVISNING stay visible above it (Andreas 2026-08-07
   — the first cut covered them, which also made the tabs unreachable by
   mouse). NOT in fullscreen: the strip is hidden there, and a lingering
   is-open must not leave the chrome floating 140px up a 100vh stage. */
.brikk-sp-gallery.is-open:not(.is-fullscreen) .brikk-sp-gallery__caption,
.brikk-sp-gallery.is-open:not(.is-fullscreen) .brikk-sp-gallery__scrim,
.brikk-sp-gallery.is-open:not(.is-fullscreen) .brikk-sp-tabs {
    transform: translateY(calc(-1 * var(--brikk-sp-strip-h)));
}

/* The native scroller. Free momentum scrolling (the point of the 2026-08-07
   rework), no scroll-snap — snapping would reintroduce the stepped feel.
   This flex row is the layout from CSS alone, so the slick-era trap where
   un-initialised thumbs stacked ~18.000px tall (and, translated below the
   stage, EXPANDED THE DOCUMENT'S SCROLLABLE OVERFLOW — transforms move paint,
   not layout) is structurally gone, not guarded against.
   overscroll-behavior-x: hitting either end must not hand the gesture to the
   browser's back/forward swipe. Scrollbar hidden — the arrows, drag and the
   scroll itself are the affordance, like the mobile pattern this copies. */
.brikk-sp-strip__scroller {
    display: flex;
    gap: 16px;
    box-sizing: border-box;
    padding: 20px;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
}

.brikk-sp-strip__scroller::-webkit-scrollbar {
    display: none;
}

/* FIXED height, not an aspect ratio (changed 2026-08-07, "50px less tall"):
   the band is a constant --brikk-sp-strip-h at every width, which is what
   lets the caption/tabs push-up above be a constant too. Same model as the
   live site's nav strip (100px thumbs, width from the column count).
   The basis % resolves against the scroller's VISIBLE content box, so exactly
   6 thumbs fill the view; 80px = the row's 5 gaps. Zero shrink — the overflow
   is the point. */
.brikk-sp-strip__thumb {
    display: block;
    box-sizing: border-box;
    flex: 0 0 calc((100% - 80px) / 6);
    height: calc(var(--brikk-sp-strip-h) - 40px);
    padding: 0;
    border: 0;
    background-position: center;
    background-size: cover;
    background-repeat: no-repeat;
    background-color: var(--wp--custom--bg-dim);
    cursor: pointer;
}

/* Both outlines INSET — the scroller clips at its padding edges, so an outset
   outline would be cut on the first/last visible thumb. */
.brikk-sp-strip__thumb:focus-visible {
    outline: 2px solid var(--wp--preset--color--purple);
    outline-offset: -2px;
}

/* The main slider's current photo, marked by the JS. */
.brikk-sp-strip__thumb.is-current {
    outline: 2px solid var(--wp--preset--color--purple);
    outline-offset: -2px;
}

/* Strip arrows — JS-appended to the BAND, never inside the scroller: an
   absolutely-positioned child of a scroll container is anchored to its
   padding box at scroll 0 and scrolls away with the content. Full-band white
   columns flush with the edges; the JS disables them at the ends. */
.brikk-sp-strip__arrow {
    position: absolute;
    top: 0;
    bottom: 0;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    padding: 0;
    border: 0;
    background: var(--wp--preset--color--card);
    color: var(--wp--preset--color--dark);
    cursor: pointer;
    transition: opacity var(--wp--custom--transition);
}

.brikk-sp-strip__arrow--prev { left: 0; }
.brikk-sp-strip__arrow--next { right: 0; }

.brikk-sp-strip__arrow svg {
    display: block;
    /* State the size — §6h's chevron rule (svg max-width:100% vs attributes). */
    width: 12px;
    height: 22px;
    max-width: none;
}

.brikk-sp-strip__arrow:disabled {
    opacity: 0.25;
    cursor: default;
}

.brikk-sp-strip__arrow:focus-visible {
    outline: 2px solid var(--wp--preset--color--purple);
    outline-offset: -2px;
}

/* --- 12.9.3  (retired 2026-08-07 — the openhouse notice was removed; the
       gallery badge carries the open house and, when signup is required, opens
       the signup modal itself. The modal styles live in 12.9.10.) ------------ */

/* --- 12.9.4  Identity band ------------------------------------------------- */

.brikk-sp-identity {
    background: var(--wp--preset--color--bg);
    border-bottom: 1px solid var(--wp--custom--line-page);
}

/* Columns are BOTTOM-aligned (measured: the left sub-line and the right
   buttons both end 41px above the band's hairline). */
.brikk-sp-identity__grid {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 40px;
    padding-block: 58px 41px;
}

.brikk-sp-identity__eyebrow {
    display: block;
    margin: 0;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--eyebrow);
    font-weight: 500;
    line-height: var(--wp--custom--lh-base);
    letter-spacing: var(--wp--custom--ls-eyebrow);
    text-transform: uppercase;
    color: var(--wp--preset--color--muted);
}

.brikk-sp-identity__title {
    margin: 14px 0 0;
    font-family: var(--wp--preset--font-family--serif);
    font-size: 50px;
    font-weight: 500;
    line-height: var(--wp--custom--lh-tight);
    letter-spacing: var(--wp--custom--ls-heading);
    color: var(--wp--preset--color--dark);
}

.brikk-sp-identity__sub {
    margin: 10px 0 0;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 14px;
    line-height: var(--wp--custom--lh-base);
    color: var(--wp--preset--color--muted);
}

/* Share ("Del bolig", 2026-08-07 — live's block reinstated, under the address
   like live puts it under its h1). Square hairline buttons in the card
   vocabulary; icons inherit currentColor. */
.brikk-sp-share {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 20px;
}

.brikk-sp-share__label {
    margin-right: 8px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 10px;
    font-weight: 500;
    letter-spacing: var(--wp--custom--ls-ui);
    text-transform: uppercase;
    color: var(--wp--preset--color--muted);
}

.brikk-sp-share__btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    width: 40px;
    height: 40px;
    border: 1px solid var(--wp--custom--line-card);
    background: var(--wp--preset--color--card-soft);
    color: var(--wp--preset--color--dark);
    transition: border-color var(--wp--custom--transition), color var(--wp--custom--transition);
}

.brikk-sp-share__btn:hover,
.brikk-sp-share__btn:focus-visible {
    border-color: var(--wp--preset--color--purple);
    color: var(--wp--preset--color--purple);
}

.brikk-sp-share__btn svg {
    display: block;
    /* State the size — §6h's chevron rule (svg max-width:100% vs attributes). */
    width: 15px;
    height: 15px;
    max-width: none;
}

/* Right column: eyebrow + price right-aligned, then the two buttons. */
.brikk-sp-identity__aside {
    flex: 0 0 auto;
    text-align: right;
}

.brikk-sp-price {
    margin: 0;
    font-family: var(--wp--preset--font-family--serif);
    font-weight: 500;
    line-height: 1;
    letter-spacing: var(--wp--custom--ls-heading);
    color: var(--wp--preset--color--dark);
}

.brikk-sp-identity__aside .brikk-sp-identity__eyebrow {
    margin-bottom: 14px;
}

.brikk-sp-price__amount {
    font-size: 50px;
}

/* "kr." rides at 56% of the digits. ⚠️ Its INK differs by surface — pixel-
   sampled in the comps: the identity band's kr. (desktop AND mobile) is the
   lavender-grey #8a8294 (→ our muted fold), while the rail card's kr. is the
   same dark ink as the digits. */
.brikk-sp-price__unit {
    margin-left: 8px;
    font-size: 28px;
}

.brikk-sp-identity__aside .brikk-sp-price__unit {
    color: var(--wp--preset--color--muted);
}

.brikk-sp-price-note {
    margin: 8px 0 0;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 13px;
    line-height: var(--wp--custom--lh-base);
    color: var(--wp--preset--color--muted);
}

.brikk-sp-identity__actions {
    display: flex;
    justify-content: flex-end;
    gap: 12px;
    margin-top: 22px;
}

/* --- 12.9.5  Buttons (measured 47/49px controls; own classes because the
       geometry is fixed-height, unlike §6's padding-driven .brikk-btn) ------- */

.brikk-sp-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    height: 47px;
    /* 26px, not 28: the trailing 0.2em letter-space adds ~2.4px of phantom
       right padding at 12px — 26 lands the comp's 213/224px button widths. */
    padding: 0.2em 26px 0;
    border: 1px solid var(--wp--preset--color--purple);
    background: var(--wp--preset--color--purple);
    color: var(--wp--custom--on-accent);
    font-family: var(--wp--preset--font-family--sans);
    font-size: 12px;
    font-weight: 500;
    letter-spacing: var(--wp--custom--ls-ui);
    text-transform: uppercase;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: background var(--wp--custom--transition), color var(--wp--custom--transition), border-color var(--wp--custom--transition);
}

.brikk-sp-btn:hover,
.brikk-sp-btn:focus-visible {
    background: var(--wp--custom--purple-hover);
    border-color: var(--wp--custom--purple-hover);
    color: var(--wp--custom--on-accent);
}

/* The → arrow inside CTA labels. State the size — §6h's rule: an SVG with no
   width/height attributes collapses under §3's `svg { max-width: 100% }`. */
.brikk-sp-btn svg {
    display: inline-block;
    width: 12px;
    height: 8px;
    max-width: none;
    vertical-align: middle;
    margin-top: -0.2em; /* re-centre against the cap-height padding */
}

/* Outline variant: transparent fill — the surface behind shows through
   (measured on the identity band: page bg, not white). */
.brikk-sp-btn--outline {
    background: transparent;
    color: var(--wp--preset--color--purple);
}

.brikk-sp-btn--outline:hover,
.brikk-sp-btn--outline:focus-visible {
    background: var(--wp--preset--color--purple);
    color: var(--wp--custom--on-accent);
}

/* --- 12.9.6  Main area: content column + card rail ------------------------- */

.brikk-sp-main__grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 412px;
    column-gap: 81px;
    align-items: start;
    padding-block: 58px 96px;
}

/* Content column. */
.brikk-sp-about__eyebrow {
    display: block;
    margin: 0 0 28px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--eyebrow);
    font-weight: 500;
    line-height: var(--wp--custom--lh-base);
    letter-spacing: var(--wp--custom--ls-eyebrow);
    text-transform: uppercase;
    color: var(--wp--preset--color--muted);
}

.brikk-sp-about__heading {
    margin: 0 0 28px;
    max-width: 720px;
    font-family: var(--wp--preset--font-family--serif);
    font-size: 42px;
    font-weight: 500;
    line-height: 1.1;
    letter-spacing: var(--wp--custom--ls-heading);
    color: var(--wp--preset--color--dark);
}

/* Description = raw post_content run through wpautop-style paragraphs.
   16px on a relaxed 29px pitch (measured), plist-tick ink. */
.brikk-sp-about__body {
    max-width: 820px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 16px;
    font-weight: 400;
    line-height: 1.8;
    color: var(--wp--custom--plist-tick);
}

.brikk-sp-about__body p {
    margin: 0;
    /* §4's :where(.brikk-redesign) p matches the paragraph DIRECTLY and beats
       the parent's 1.8 (the §6e lesson-12 inheritance trap) — restate it. */
    line-height: inherit;
}

.brikk-sp-about__body p + p {
    margin-top: 18px;
}

/* Card rail. */
.brikk-sp-rail {
    display: flex;
    flex-direction: column;
    gap: 24px;
    min-width: 0;
}

.brikk-sp-card {
    box-sizing: border-box;
    background: var(--wp--preset--color--card-soft);
    border: 1px solid var(--wp--custom--line-card);
    padding: 32px;
}

.brikk-sp-card__eyebrow {
    display: block;
    margin: 0;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--eyebrow);
    font-weight: 500;
    line-height: var(--wp--custom--lh-base);
    letter-spacing: var(--wp--custom--ls-eyebrow);
    text-transform: uppercase;
    color: var(--wp--preset--color--muted);
}

/* In-card hairlines run border to border (measured); 23/24 vertical
   margins per the comp's portrait->rule->rows gaps. */
.brikk-sp-card__rule {
    height: 1px;
    margin: 23px -32px 24px;
    background: var(--wp--custom--line-card);
}

/* Price card. */
.brikk-sp-card .brikk-sp-price {
    margin-top: 20px;
}

.brikk-sp-card .brikk-sp-price__amount {
    font-size: 42px;
}

.brikk-sp-card .brikk-sp-price__unit {
    font-size: 20px;
    margin-left: 6px;
}

/* Facts table — 13px rows on a 28px pitch, labels muted, values dark-ish. */
.brikk-sp-facts {
    margin: 0;
}

.brikk-sp-facts__row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
}

.brikk-sp-facts__row + .brikk-sp-facts__row {
    margin-top: 10px;
}

.brikk-sp-facts__label {
    margin: 0;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 13px;
    line-height: var(--wp--custom--lh-base);
    color: var(--wp--preset--color--muted);
}

.brikk-sp-facts__value {
    margin: 0;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 13px;
    line-height: var(--wp--custom--lh-base);
    color: var(--wp--custom--plist-tick);
    text-align: right;
}

.brikk-sp-card__actions {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-top: 24px;
}

.brikk-sp-card__actions .brikk-sp-btn {
    width: 100%;
    height: 49px;
}

/* Mægler card. */
.brikk-sp-agent {
    display: flex;
    align-items: flex-start;
    gap: 28px;
    /* 20, not 26 — comp: eyebrow box -> portrait top measures 20px. */
    margin-top: 20px;
}

.brikk-sp-agent__photo {
    flex: 0 0 auto;
    width: 86px;
    height: 86px;
    object-fit: cover;
    background: var(--wp--custom--bg-dim);
}

.brikk-sp-agent__name {
    margin: 6px 0 0;
    font-family: var(--wp--preset--font-family--serif);
    font-size: 25px;
    font-weight: 500;
    line-height: var(--wp--custom--lh-heading);
    letter-spacing: var(--wp--custom--ls-heading);
    color: var(--wp--preset--color--dark);
}

.brikk-sp-agent__role {
    margin: 6px 0 0;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 12.5px;
    line-height: 1.35;
    color: var(--wp--preset--color--muted);
}

.brikk-sp-contact {
    margin: 0;
}

.brikk-sp-contact__row {
    display: flex;
    align-items: baseline;
    gap: 12px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 14px;
    line-height: var(--wp--custom--lh-base);
    color: var(--wp--custom--plist-tick);
    text-decoration: none;
}

.brikk-sp-contact__row + .brikk-sp-contact__row {
    margin-top: 7px;
}

.brikk-sp-contact__row:hover {
    color: var(--wp--preset--color--purple);
}

.brikk-sp-contact__chevron {
    font-family: var(--wp--preset--font-family--sans);
    color: var(--wp--preset--color--purple);
    font-size: 12px;
}

/* Dark "Skal du også sælge?" card. */
.brikk-sp-card--dark {
    background: var(--wp--preset--color--dark);
    border: 0;
    padding: 33px 32px;
}

.brikk-sp-card--dark .brikk-sp-card__eyebrow {
    color: var(--wp--custom--on-dark-purple);
}

.brikk-sp-card--dark__heading {
    margin: 14px 0 0;
    font-family: var(--wp--preset--font-family--serif);
    font-size: 28px;
    font-weight: 500;
    line-height: var(--wp--custom--lh-heading);
    letter-spacing: var(--wp--custom--ls-heading);
    color: var(--wp--custom--on-dark-cream);
}

/* Body derives from the cream heading ink at 45% — solves to the measured
   ≈#78726a over the dark card without a third dark-card token. */
.brikk-sp-card--dark__body {
    margin: 14px 0 0;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 13px;
    line-height: 1.77;
    color: color-mix(in srgb, var(--wp--custom--on-dark-cream) 55%, transparent);
}

/* Lavender button with a DARK label (comp-measured — not white). */
.brikk-sp-card--dark .brikk-sp-btn {
    margin-top: 24px;
    height: 43px;
    border-color: var(--wp--custom--on-dark-purple);
    background: var(--wp--custom--on-dark-purple);
    color: var(--wp--preset--color--dark);
}

.brikk-sp-card--dark .brikk-sp-btn:hover,
.brikk-sp-card--dark .brikk-sp-btn:focus-visible {
    background: color-mix(in srgb, var(--wp--custom--on-dark-purple) 85%, var(--wp--preset--color--card));
    border-color: color-mix(in srgb, var(--wp--custom--on-dark-purple) 85%, var(--wp--preset--color--card));
    color: var(--wp--preset--color--dark);
}

/* --- 12.9.7  Mobile facts card (replaces the rail price card ≤1024) -------- */

.brikk-sp-facts-mobile {
    display: none;
    box-sizing: border-box;
    margin-top: 28px;
    padding: 24px 20px 21px;
    background: var(--wp--preset--color--card-soft);
    border: 1px solid var(--wp--custom--line-card);
}

.brikk-sp-facts-mobile .brikk-sp-facts__row + .brikk-sp-facts__row {
    margin-top: 9px;
}

/* --- 12.9.8  CTA photo band ------------------------------------------------ */

.brikk-sp-cta {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    min-height: 463px;
    padding: 64px var(--brikk-pad-x) 65px;
    background-image:
        linear-gradient(180deg, rgba(26, 26, 26, 0.38) 0%, rgba(26, 26, 26, 0.78) 100%),
        url('../img/cta/house.webp');
    background-size: cover;
    background-position: center;
    border-bottom: 1px solid var(--wp--custom--line-page);
    text-align: center;
}

/* The 1×42px on-dark-purple rule (measured — NOT white). */
.brikk-sp-cta::before {
    content: '';
    display: block;
    width: 1px;
    height: 42px;
    margin-bottom: 34px;
    background: var(--wp--custom--on-dark-purple);
}

.brikk-sp-cta__heading {
    margin: 0;
    max-width: 620px;
    font-family: var(--wp--preset--font-family--serif);
    font-size: 50px;
    font-weight: 500;
    line-height: 1.08;
    letter-spacing: var(--wp--custom--ls-heading);
    color: var(--wp--custom--on-dark);
}

.brikk-sp-cta__lead {
    margin: 28px 0 0;
    max-width: 460px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 14px;
    line-height: 1.85;
    color: var(--wp--custom--on-dark-muted);
}

.brikk-sp-cta .brikk-sp-btn {
    margin-top: 36px;
    height: 49px;
    padding-inline: 34px;
    border-color: var(--wp--preset--color--card);
    background: var(--wp--preset--color--card);
    color: var(--wp--preset--color--purple);
}

.brikk-sp-cta .brikk-sp-btn:hover,
.brikk-sp-cta .brikk-sp-btn:focus-visible {
    background: var(--wp--preset--color--purple);
    border-color: var(--wp--preset--color--purple);
    color: var(--wp--custom--on-accent);
}

/* --- 12.9.9  Modals (bestil dokumenter / åbent hus tilmelding) -------------
   No comp exists — composed from the design language. The FORM CONTRACT is the
   legacy one (field names, hidden action inputs, wpcf7-* wrappers — the SERVER
   returns `invalid_fields[].into` selectors pointing at those wrappers). ---- */

.brikk-sp-modal {
    position: fixed;
    inset: 0;
    z-index: var(--wp--custom--z-modal);
    display: none;
    align-items: flex-start;
    justify-content: center;
    overflow-y: auto;
    padding: 6vh 20px 40px;
    background: var(--wp--custom--scrim);
}

.brikk-sp-modal.is-open {
    display: flex;
}

.brikk-sp-modal__dialog {
    position: relative;
    box-sizing: border-box;
    width: 100%;
    max-width: 480px;
    padding: 40px;
    background: var(--wp--preset--color--card);
    border: 1px solid var(--wp--custom--line-card);
}

.brikk-sp-modal__close {
    position: absolute;
    top: 10px;
    right: 10px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--wp--preset--color--dark);
    cursor: pointer;
}

.brikk-sp-modal__close svg {
    display: block;
    width: 14px;
    height: 14px;
    max-width: none;
}

.brikk-sp-modal__heading {
    margin: 0 0 8px;
    font-family: var(--wp--preset--font-family--serif);
    font-size: 28px;
    font-weight: 500;
    line-height: var(--wp--custom--lh-heading);
    letter-spacing: var(--wp--custom--ls-heading);
    color: var(--wp--preset--color--dark);
}

.brikk-sp-modal__lead {
    margin: 0 0 24px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 14px;
    line-height: var(--wp--custom--lh-copy);
    color: var(--wp--preset--color--muted);
}

/* Fields inherit §7's form styling (the redesigned-page base). Wrappers only
   add rhythm; sizes stay §7's so the iOS zoom guard keeps working. */
.brikk-sp-modal .wpcf7-form-control-wrap {
    display: block;
}

.brikk-sp-modal .wpcf7-form-control-wrap + .wpcf7-form-control-wrap {
    margin-top: 14px;
}

.brikk-sp-modal input[type='text'],
.brikk-sp-modal input[type='email'],
.brikk-sp-modal input[type='tel'] {
    width: 100%;
}

.brikk-sp-modal__checks {
    margin-top: 18px;
}

.brikk-sp-modal__check {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 13px;
    line-height: var(--wp--custom--lh-base);
    color: var(--wp--custom--plist-tick);
}

.brikk-sp-modal__check + .brikk-sp-modal__check {
    margin-top: 10px;
}

.brikk-sp-modal__check a {
    color: var(--wp--preset--color--purple);
}

.brikk-sp-modal .brikk-sp-btn {
    width: 100%;
    margin-top: 24px;
}

/* Server-driven validation chrome (contract classes, styled here because
   form.css never loads on a redesigned page). */
.brikk-sp-modal .wpcf7-not-valid-tip {
    display: block;
    margin-top: 6px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 12px;
    color: var(--wp--custom--error);
}

.brikk-sp-modal .wpcf7-response-output {
    margin-top: 16px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 14px;
    line-height: var(--wp--custom--lh-base);
    color: var(--wp--custom--plist-tick);
}

.brikk-sp-modal form.failed .wpcf7-response-output {
    color: var(--wp--custom--error);
}

.brikk-sp-modal form.submitting input[type='submit'] {
    opacity: 0.55;
}

/* --- 12.9.10  Valuation drawer (scroll-triggered, 24h cookie — the legacy
       .single-property popup restyled; markup now lives in the template) ----- */

.brikk-sp-valuation {
    position: fixed;
    left: 0;
    bottom: 44px;
    z-index: var(--wp--custom--z-chrome);
    display: flex;
    align-items: center;
    gap: 18px;
    box-sizing: border-box;
    max-width: 440px;
    padding: 20px 24px;
    background: color-mix(in srgb, var(--wp--preset--color--dark) 94%, transparent);
    color: var(--wp--custom--on-dark);
    transform: translateX(0);
    transition: transform 260ms ease, visibility 260ms;
    visibility: visible;
}

.brikk-sp-valuation.is-hidden {
    transform: translateX(-105%);
    visibility: hidden;
}

.brikk-sp-valuation__close {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--wp--custom--on-dark-muted);
    cursor: pointer;
}

.brikk-sp-valuation__close svg {
    display: block;
    width: 12px;
    height: 12px;
    max-width: none;
}

.brikk-sp-valuation__copy {
    border-left: 1px solid var(--wp--custom--on-dark-line-faint);
    padding-left: 18px;
}

.brikk-sp-valuation__title {
    margin: 0;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 15px;
    font-weight: 700;
    line-height: var(--wp--custom--lh-base);
    color: var(--wp--custom--on-dark);
}

.brikk-sp-valuation__text {
    margin: 4px 0 0;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 13px;
    line-height: var(--wp--custom--lh-base);
    color: var(--wp--custom--on-dark-muted);
}

.brikk-sp-valuation__go {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 50px;
    height: 50px;
    border-radius: var(--wp--custom--radius-pill);
    background: var(--wp--preset--color--purple);
    color: var(--wp--custom--on-accent);
    text-decoration: none;
    transition: background var(--wp--custom--transition);
}

.brikk-sp-valuation__go:hover,
.brikk-sp-valuation__go:focus-visible {
    background: var(--wp--custom--purple-hover);
}

.brikk-sp-valuation__go svg {
    display: block;
    width: 14px;
    height: 12px;
    max-width: none;
}

/* --- 12.9.11  Mobile photo/map overlays ------------------------------------ */

.brikk-sp-overlay {
    position: fixed;
    inset: 0;
    z-index: var(--wp--custom--z-modal);
    display: none;
    flex-direction: column;
    background: var(--wp--preset--color--card);
}

.brikk-sp-overlay.is-open {
    display: flex;
}

body.brikk-sp-no-scroll {
    overflow: hidden;
}

.brikk-sp-overlay__bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex: 0 0 auto;
    padding: 12px 12px 12px 20px;
    border-bottom: 1px solid var(--wp--custom--line-page);
}

.brikk-sp-overlay__count {
    margin: 0;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 12px;
    font-weight: 500;
    letter-spacing: var(--wp--custom--ls-ui);
    color: var(--wp--preset--color--muted);
}

.brikk-sp-overlay__close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--wp--preset--color--dark);
    cursor: pointer;
}

.brikk-sp-overlay__close svg {
    display: block;
    width: 15px;
    height: 15px;
    max-width: none;
}

.brikk-sp-overlay__scroll {
    flex: 1 1 auto;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}

.brikk-sp-overlay__img {
    display: block;
    width: 100%;
    height: auto;
    margin: 0 0 8px;
}

.brikk-sp-overlay__section-label {
    margin: 24px 20px 12px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: 11.5px;
    font-weight: 500;
    letter-spacing: var(--wp--custom--ls-eyebrow);
    text-transform: uppercase;
    color: var(--wp--preset--color--muted);
}

/* Map overlay: the map fills the scroll area. */
.brikk-sp-overlay--map .brikk-sp-overlay__scroll {
    display: flex;
}

.brikk-sp-overlay--map .acf-map {
    flex: 1 1 auto;
    width: 100%;
    min-height: 0;
}

/* --- 12.9.12  Not-found fallback (enabled/hidden guard) -------------------- */

.brikk-sp-notfound {
    padding-block: 96px;
    text-align: center;
}

.brikk-sp-notfound__heading {
    margin: 0 auto 16px;
    max-width: 720px;
    font-family: var(--wp--preset--font-family--serif);
    font-size: var(--wp--preset--font-size--heading-3);
    font-weight: 500;
    line-height: var(--wp--custom--lh-heading);
    color: var(--wp--preset--color--dark);
}

.brikk-sp-notfound__text {
    margin: 0 auto 28px;
    max-width: 560px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--body-sm);
    line-height: var(--wp--custom--lh-copy);
    color: var(--wp--preset--color--muted);
}

/* --- 12.9.13  Mobile chrome (hidden on desktop) ---------------------------- */

.brikk-sp-mobilegal {
    display: none;
}

/* --- 12.9.14  Responsive --------------------------------------------------- */

@media (max-width: 1024.98px) {

    /* Desktop gallery chrome off; the stage becomes a plain 1.3:1 photo. */
    .brikk-sp-gallery__stage {
        height: auto;
        aspect-ratio: 391 / 300;
    }

    /* The tab BAR stays desktop-only — on mobile the media entries live in the
       floating icon pill below instead ("it should only be the buttons in the
       pill", Andreas 2026-08-07, correcting a full tab-bar-on-mobile detour). */
    .brikk-sp-gallery__arrow,
    .brikk-sp-gallery__fullscreen,
    .brikk-sp-gallery__caption,
    .brikk-sp-gallery__scrim,
    .brikk-sp-tabs,
    .brikk-sp-gallery__pill,
    .brikk-sp-strip-wrap {
        display: none;
    }

    .brikk-sp-gallery__badge {
        top: 14px;
        left: 15px;
        height: 25px;
        padding-inline: 12px;
    }

    /* 2-up thumb grid + floating 3-icon pill (mobile comp). Edge margins are
       the measured 8–9px, deliberately tighter than the content gutter. */
    .brikk-sp-mobilegal {
        display: block;
        position: relative;
        padding: 9px 8px 0 9px;
    }

    .brikk-sp-mobilegal__grid {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 8px;
    }

    /* Only the first two thumbs render in the grid. */
    .brikk-sp-mobilegal__thumb:nth-child(n+3) {
        display: none;
    }

    .brikk-sp-mobilegal__thumb {
        display: block;
        box-sizing: border-box;
        width: 100%;
        aspect-ratio: 183 / 140;
        padding: 0;
        border: 0;
        background-position: center;
        background-size: cover;
        background-repeat: no-repeat;
        background-color: var(--wp--custom--bg-dim);
        cursor: pointer;
    }

    /* The pill straddles the grid's bottom edge: 56px tall, TRUE WHITE
       (measured — unlike the desktop pills), r=pill, centred. */
    .brikk-sp-mobilegal__pill {
        position: absolute;
        left: 50%;
        bottom: -28px;
        z-index: var(--wp--custom--z-raised);
        transform: translateX(-50%);
        display: inline-flex;
        align-items: stretch;
        box-sizing: border-box;
        height: 56px;
        border-radius: var(--wp--custom--radius-pill);
        background: var(--wp--preset--color--card);
        box-shadow: 0 14px 28px rgba(26, 26, 26, 0.14);
    }

    .brikk-sp-mobilegal__pill-btn {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        box-sizing: border-box;
        width: 68px;
        padding: 0;
        border: 0;
        background: transparent;
        color: var(--wp--preset--color--dark);
        cursor: pointer;
    }

    .brikk-sp-mobilegal__pill-btn + .brikk-sp-mobilegal__pill-btn {
        border-left: 1px solid var(--wp--custom--line-card);
    }

    .brikk-sp-mobilegal__pill-btn:first-child { border-radius: var(--wp--custom--radius-pill) 0 0 var(--wp--custom--radius-pill); }
    .brikk-sp-mobilegal__pill-btn:last-child  { border-radius: 0 var(--wp--custom--radius-pill) var(--wp--custom--radius-pill) 0; }

    .brikk-sp-mobilegal__pill-btn svg {
        display: block;
        width: 18px;
        height: 18px;
        max-width: none;
    }

    /* A pill pane-button whose pane is showing (Video / 3D / Indretning —
       marked by showPane). Overlay buttons never get it. */
    .brikk-sp-mobilegal__pill-btn.is-active {
        color: var(--wp--preset--color--purple);
    }

    /* 5+ buttons (video/3D/indretning present): the one-row capsule would run
       344px+ and overflow a 320px phone, so it wraps to rows of three ("just
       make it two rows", Andreas 2026-08-07). PHP stamps the class — a fact
       both layers know, the §6s collapse-threshold precedent, no :has(). The
       nth-child(3n+1) reset kills the separator a row's FIRST button inherits
       from the flat `+` rule; rows below the first draw a top hairline. */
    .brikk-sp-mobilegal__pill--grid {
        flex-wrap: wrap;
        /* 204 = 3 × 68px border-box buttons — the same width three buttons
           give the one-row pill, so the two states line up exactly. */
        width: 204px;
        height: auto;
        border-radius: 28px;
        /* Half the two-row pill's 112px, so the middle hairline sits exactly
           ON the thumb grid's bottom edge — the same straddle the 56px
           one-row pill gets from its bottom: -28px (Andreas 2026-08-07:
           "in the middle of the header and the content below"). */
        bottom: -56px;
    }

    /* The taller pill hangs 28px further into the content below — the wrapper
       (stamped --tall by the SAME PHP conditional that stamps --grid) gives
       that back, so the identity band keeps the one-row case's visual gap. */
    .brikk-sp-mobilegal--tall {
        margin-bottom: 28px;
    }

    /* Buttons FILL their row (a short last row gets wider cells), never keep
       the fixed 68px and centre — centred cells left the row hairline spanning
       only part of the pill and separators floating mid-air against the row
       above ("the border is broken", Andreas). Full cells mean the hairline
       runs edge to edge and every separator meets a line at both ends. */
    .brikk-sp-mobilegal__pill--grid .brikk-sp-mobilegal__pill-btn {
        flex: 1 1 33%;
        width: auto;
        height: 56px;
        border-radius: 0;
    }

    .brikk-sp-mobilegal__pill--grid .brikk-sp-mobilegal__pill-btn:nth-child(3n + 1) {
        border-left: 0;
    }

    .brikk-sp-mobilegal__pill--grid .brikk-sp-mobilegal__pill-btn:nth-child(n + 4) {
        border-top: 1px solid var(--wp--custom--line-card);
    }

    /* Identity band → stacked left-aligned flow. */
    .brikk-sp-identity__grid {
        display: block;
        padding-block: 52px 0;
    }

    .brikk-sp-identity {
        border-bottom: 0;
    }

    .brikk-sp-identity__aside {
        text-align: left;
        margin-top: 24px;
    }

    .brikk-sp-identity__actions {
        flex-direction: column;
        justify-content: flex-start;
        gap: 11px;
        margin-top: 20px;
    }

    .brikk-sp-identity__actions .brikk-sp-btn {
        width: 100%;
    }

    /* Mobile facts card in; rail price card out. */
    .brikk-sp-facts-mobile {
        display: block;
    }

    .brikk-sp-card--price {
        display: none;
    }

    /* Main grid stacks; rail cards flow after the content. */
    .brikk-sp-main__grid {
        display: block;
        padding-block: 48px 64px;
    }

    .brikk-sp-rail {
        margin-top: 48px;
    }

    .brikk-sp-about__heading {
        font-size: 34px;
        line-height: 1.15;
    }

    .brikk-sp-about__body {
        max-width: none;
    }
}

@media (max-width: 640.98px) {

    /* Exact mobile-comp values. */
    .brikk-sp-identity__eyebrow,
    .brikk-sp-about__eyebrow,
    .brikk-sp-card__eyebrow {
        font-size: var(--wp--preset--font-size--micro);
        letter-spacing: 0.28em;
    }

    /* The mobile comp drops the "SAG …" segment from the eyebrow. */
    .brikk-sp-identity__sag {
        display: none;
    }

    .brikk-sp-identity__title {
        font-size: 36px;
    }

    .brikk-sp-price__amount {
        font-size: 40px;
    }

    .brikk-sp-price__unit {
        font-size: 19px;
    }

    .brikk-sp-about__heading {
        font-size: 28px;
        line-height: 1.15;
        margin-bottom: 24px;
    }

    .brikk-sp-about__body {
        font-size: 14px;
        line-height: 1.82;
    }

    .brikk-sp-card {
        padding: 24px 22px;
    }

    .brikk-sp-card__rule {
        margin-inline: -22px;
    }

    .brikk-sp-agent__photo {
        width: 74px;
        height: 74px;
    }

    .brikk-sp-agent__name {
        font-size: 24px;
    }

    .brikk-sp-card--dark__heading {
        font-size: 27px;
    }

    /* The dark card's CTA at the mobile comp's ~254px (11px label, comp shows
       button 254×41 at 390). Its nowrap min-content was 299px, which crossed
       the card edge from ≤361px and the viewport from ≤340px. */
    .brikk-sp-card--dark .brikk-sp-btn {
        font-size: 11px;
        padding-inline: 20px;
    }

    /* The CTA photo band is ABSENT from the mobile comp. */
    .brikk-sp-cta {
        display: none;
    }

    .brikk-sp-valuation {
        max-width: calc(100vw - 32px);
        bottom: 16px;
        left: 16px;
    }

    .brikk-sp-modal__dialog {
        padding: 32px 24px;
    }
}

/* ⚠️ 345.98px is a COMPONENT-ONLY breakpoint (documented like §12.5's 900/720):
   the dark card's CTA is ~262px at its ≤640 size and the card's content box is
   viewport − 84px (20px gutters + 22px card padding), so 346 is the first width
   that still holds the auto-width button. Below it the button goes full width
   with slimmer padding — the §6c shrink-first-then-restructure pattern. At 320
   the content box is 236px and the label needs ~226. Nothing else may use 346. */
@media (max-width: 345.98px) {
    .brikk-sp-card--dark .brikk-sp-btn {
        width: 100%;
        min-width: 0;
        padding-inline: 8px;
    }
}

/* Wide screens: the caption's right inset scales off the tab bar only. */
@media (min-width: 1500px) {
    .brikk-sp-gallery__caption-inner {
        padding-right: 720px;
    }
}


/* =============================================================================
   12.10  EXIT-INTENT POPUP  ·  #brikk-cta-popup  (2026-08-07)
   -----------------------------------------------------------------------------
   The site-wide exit-intent overlay (inc/exit-intent-popup.php + its JS,
   assets/js/exit-intent-popup.js). Restyled in the new design language —
   NOT a port of the legacy look (white sheet + bright-blue #472dfb panel):
   warm white card on the scrim, serif heading, flat dark why-panel with
   circled serif checks, purple CTA. No comp exists — composed from the
   design language like the mobile drawer (§12.1) and the §12.9.9 modals.

   ⚠️ EVERY rule is scoped under `.brikk-redesign` (the <html> class emitted
   only on redesigned pages). On legacy pages brikk.css + form.css still own
   this popup, and this block must be a PROVABLE no-op there — that is why the
   scope is the real class, not :where(). Verified by computed-style diff.

   THE JS CONTRACT (do not break):
   - #brikk-cta-popup ships with inline `opacity:0`; showPopup() sets inline
     visibility/opacity/transition, hidePopup() sets inline
     `transform: scale(0.5)`. Centring therefore must NOT rely on transform
     (the inline one would clobber it) → `inset: 0; margin: auto` instead.
   - #brikk-cta-popup_bg is CREATED BY THE JS (appended to <body> AFTER the
     popup markup), so at equal z-index it would paint on top of the popup.
     The bg takes z-modal − 1 for that reason.
   - #brikk-cta-popup_close is an EMPTY div; the legacy CSS drew its glyph via
     `content: "×"`. Here the × is two pseudo-element bars, same idea.
   - The base state carries `visibility: hidden` — without it the inline
     opacity:0 popup would still sit on top of the page and eat clicks.

   CF7: the exact production markup of form 30690 is UNREACHABLE (2026-08-07 —
   the popup is not rendered on any probed production page or Wayback
   snapshot), so the form chrome below targets CF7's STANDARD output DOM,
   plus the two field wrappers the legacy CSS proves this form has
   (`.tidspunkt`, `.adresse` — both full-width; matched by class for old CF7
   and [data-name] for current CF7). Field inputs themselves inherit §7's
   base form styling, which is part of THIS file and present on every
   redesigned page — same split as the §12.9.9 modals.
   ============================================================================= */

.brikk-redesign #brikk-cta-popup {
    position: fixed;
    inset: 0;
    margin: auto;
    z-index: var(--wp--custom--z-modal);
    box-sizing: border-box;
    width: min(920px, calc(100vw - 40px));
    height: fit-content;
    max-height: calc(100vh - 40px);
    overflow-x: hidden;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 48px;
    background: var(--wp--preset--color--card);
    border: 1px solid var(--wp--custom--line-card);
    border-radius: var(--wp--custom--radius);
    visibility: hidden;
    /* Typographic ground for everything inside — stated, not inherited (§0.1). */
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--body);
    font-weight: 400;
    line-height: var(--wp--custom--lh-base);
    color: var(--wp--preset--color--dark);
    text-align: left;
}

.brikk-redesign #brikk-cta-popup_bg {
    position: fixed;
    inset: 0;
    /* One below the popup: the JS appends this div AFTER the popup markup, so
       a z-index tie would paint the scrim over the dialog. */
    z-index: calc(var(--wp--custom--z-modal) - 1);
    background: var(--wp--custom--scrim);
    visibility: hidden;
}

/* --- Close button: empty div, glyph drawn here (legacy used content:"×") --- */
.brikk-redesign .brikk-cta-popup_close-button {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: var(--wp--custom--z-raised);
    width: 40px;
    height: 40px;
    padding: 0;
    background: transparent;
    border: 0;
    border-radius: var(--wp--custom--radius);
    cursor: pointer;
}

.brikk-redesign .brikk-cta-popup_close-button::before,
.brikk-redesign .brikk-cta-popup_close-button::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 16px;
    height: 1.5px;
    background: var(--wp--preset--color--dark);
    transition: opacity var(--wp--custom--transition);
}

.brikk-redesign .brikk-cta-popup_close-button::before {
    transform: translate(-50%, -50%) rotate(45deg);
}

.brikk-redesign .brikk-cta-popup_close-button::after {
    transform: translate(-50%, -50%) rotate(-45deg);
}

.brikk-redesign .brikk-cta-popup_close-button:hover::before,
.brikk-redesign .brikk-cta-popup_close-button:hover::after {
    opacity: 0.55;
}

/* --- Two-column shell ------------------------------------------------------ */
.brikk-redesign .brikk-cta-popup-content {
    display: flex;
    align-items: stretch;
    gap: 40px;
    width: 100%;
    margin: 0;
    padding: 0;
}

.brikk-redesign .brikk-cta-popup-content-signup {
    flex: 1 1 auto;
    min-width: 0;
}

/* --- Heading + intro ------------------------------------------------------- */
.brikk-redesign .brikk-cta-popup-content-signup > h2 {
    margin: 0 0 12px;
    font-family: var(--wp--preset--font-family--serif);
    font-size: 34px;
    font-weight: 500;
    line-height: var(--wp--custom--lh-heading);
    letter-spacing: var(--wp--custom--ls-heading);
    /* Legacy shouted this in uppercase; serif headings are sentence case. */
    text-transform: none;
    color: var(--wp--preset--color--dark);
}

.brikk-redesign .brikk-cta-popup-content-signup > p {
    margin: 0 0 24px;
    max-width: var(--wp--custom--measure);
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--body-sm);
    font-weight: 400;
    line-height: var(--wp--custom--lh-copy);
    color: var(--wp--preset--color--muted);
    opacity: 1;
}

/* --- CF7 form chrome ------------------------------------------------------- */
/* Field inputs (size, border, focus, placeholder, iOS ≥16px zoom guard) come
   from §7 — present on every redesigned page. Only layout + the CF7-specific
   classes form.css used to supply are stated here. */
.brikk-redesign #brikk-cta-popup .wpcf7 {
    margin: 0;
    padding: 0;
}

.brikk-redesign #brikk-cta-popup .wpcf7-form {
    margin: 0;
    padding: 0;
}

.brikk-redesign #brikk-cta-popup .wpcf7-form p {
    margin: 0 0 12px;
    padding: 0;
    font-size: var(--wp--preset--font-size--body-sm);
    line-height: var(--wp--custom--lh-base);
}

.brikk-redesign #brikk-cta-popup .wpcf7-form-control-wrap {
    position: relative;
    display: block;
}

/* The first paragraph holds the short fields two-up (the legacy 49% layout,
   rebuilt on flex+gap). min-width makes them stack by themselves once a
   column would fall under ~180px. */
.brikk-redesign #brikk-cta-popup form.wpcf7-form p:first-of-type {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
}

.brikk-redesign #brikk-cta-popup form.wpcf7-form p:first-of-type .wpcf7-form-control-wrap {
    flex: 1 1 calc(50% - 6px);
    min-width: 180px;
}

/* Full-width fields — class = old CF7 wrapper markup, [data-name] = current. */
.brikk-redesign #brikk-cta-popup .wpcf7-form-control-wrap.tidspunkt,
.brikk-redesign #brikk-cta-popup .wpcf7-form-control-wrap[data-name='tidspunkt'],
.brikk-redesign #brikk-cta-popup .wpcf7-form-control-wrap.adresse,
.brikk-redesign #brikk-cta-popup .wpcf7-form-control-wrap[data-name='adresse'] {
    flex-basis: 100%;
    min-width: 0;
    max-width: 100%;
    width: 100%;
}

/* Submit: the .brikk-btn--primary recipe (§6 / DESIGN.md), restated because
   this is an <input>, not a .brikk-btn element. */
.brikk-redesign #brikk-cta-popup input.wpcf7-submit {
    display: inline-block;
    width: auto;
    max-width: none;
    margin: 6px 0 0;
    padding: 17px 26px 14px;
    background: var(--wp--preset--color--purple);
    border: 1px solid transparent;
    border-radius: var(--wp--custom--radius);
    box-shadow: none;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui-sm);
    font-weight: 500;
    line-height: 1.3;
    letter-spacing: var(--wp--custom--ls-ui);
    text-transform: uppercase;
    color: var(--wp--custom--on-accent);
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
    transition: background var(--wp--custom--transition);
}

.brikk-redesign #brikk-cta-popup input.wpcf7-submit:hover,
.brikk-redesign #brikk-cta-popup input.wpcf7-submit:focus-visible {
    background: var(--wp--custom--purple-hover);
    color: var(--wp--custom--on-accent);
}

.brikk-redesign #brikk-cta-popup input.wpcf7-submit:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

.brikk-redesign #brikk-cta-popup form.submitting input.wpcf7-submit {
    opacity: 0.55;
}

/* Spinner — both vocabularies: .wpcf7-spinner (current CF7) and .ajax-loader
   (the CF7 generation form.css was written against). */
.brikk-redesign #brikk-cta-popup .wpcf7-spinner,
.brikk-redesign #brikk-cta-popup .ajax-loader {
    visibility: hidden;
    display: inline-block;
    vertical-align: middle;
    width: 22px;
    height: 22px;
    margin: 0 0 0 14px;
    padding: 0;
    background: transparent;
    border: 2px solid var(--wp--custom--line-card);
    border-top-color: var(--wp--preset--color--purple);
    border-radius: var(--wp--custom--radius-pill);
    animation: brikk-cta-spin 900ms linear infinite;
}

.brikk-redesign #brikk-cta-popup form.submitting .wpcf7-spinner,
.brikk-redesign #brikk-cta-popup form.submitting .ajax-loader {
    visibility: visible;
}

@keyframes brikk-cta-spin {
    to {
        transform: rotate(360deg);
    }
}

/* Validation chrome (server-driven contract classes). */
.brikk-redesign #brikk-cta-popup .wpcf7-not-valid-tip {
    display: block;
    margin-top: 6px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui-sm);
    font-weight: 400;
    line-height: var(--wp--custom--lh-base);
    letter-spacing: normal;
    text-transform: none;
    color: var(--wp--custom--error);
}

.brikk-redesign #brikk-cta-popup .wpcf7-form-control.wpcf7-not-valid {
    border-color: var(--wp--custom--error);
}

.brikk-redesign #brikk-cta-popup .wpcf7-response-output {
    margin: 16px 0 0;
    padding: 12px 16px;
    border: 1px solid var(--wp--custom--line-card);
    font-family: var(--wp--preset--font-family--sans);
    font-size: 14px;
    line-height: var(--wp--custom--lh-base);
    color: var(--wp--custom--plist-tick);
}

.brikk-redesign #brikk-cta-popup .wpcf7-form.init .wpcf7-response-output,
.brikk-redesign #brikk-cta-popup .wpcf7-form.resetting .wpcf7-response-output,
.brikk-redesign #brikk-cta-popup .wpcf7-form.submitting .wpcf7-response-output,
.brikk-redesign #brikk-cta-popup .wpcf7-display-none {
    display: none;
}

.brikk-redesign #brikk-cta-popup .wpcf7-form.invalid .wpcf7-response-output,
.brikk-redesign #brikk-cta-popup .wpcf7-form.unaccepted .wpcf7-response-output,
.brikk-redesign #brikk-cta-popup .wpcf7-form.failed .wpcf7-response-output,
.brikk-redesign #brikk-cta-popup .wpcf7-form.aborted .wpcf7-response-output,
.brikk-redesign #brikk-cta-popup .wpcf7-form.spam .wpcf7-response-output {
    border-color: var(--wp--custom--error);
    color: var(--wp--custom--error);
}

.brikk-redesign #brikk-cta-popup .wpcf7-form.sent .wpcf7-response-output {
    border-color: var(--wp--preset--color--green);
}

/* CF7's a11y live region — visually hidden (normally the plugin's own CSS does
   this; on this site that CSS never loads, form.css replaced it). */
.brikk-redesign #brikk-cta-popup .screen-reader-response {
    position: absolute;
    overflow: hidden;
    clip-path: inset(50%);
    width: 1px;
    height: 1px;
    margin: 0;
    padding: 0;
}

/* --- Secondary link under the form (.brikk-link-arrow recipe) -------------- */
.brikk-redesign #brikk-cta-popup .exit-intent-button-wrapper {
    margin-top: 20px;
}

.brikk-redesign #brikk-cta-popup .exit-intent-button-wrapper a {
    display: inline-block;
    padding: 0 0 2px;
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--wp--custom--line-dark);
    border-radius: var(--wp--custom--radius);
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui-sm);
    font-weight: 500;
    line-height: 1.3;
    letter-spacing: var(--wp--custom--ls-ui);
    text-transform: uppercase;
    text-decoration: none;
    text-align: left;
    color: var(--wp--preset--color--dark);
    opacity: 0.6;
    transition: opacity var(--wp--custom--transition);
}

.brikk-redesign #brikk-cta-popup .exit-intent-button-wrapper a:hover {
    opacity: 1;
}

/* --- Why-Brikk panel: flat dark band (DESIGN.md §2 — beige-based ink) ------ */
.brikk-redesign .brikk-cta-popup-content-why-brikk {
    flex: 0 0 280px;
    display: flex;
    align-items: center;
    margin: 0;
    padding: 32px 28px;
    background: var(--wp--preset--color--dark);
    border-radius: var(--wp--custom--radius);
    box-shadow: none;
    color: var(--wp--preset--color--bg);
}

.brikk-redesign .brikk-cta-popup-content-why-brikk ul {
    margin: 0;
    padding: 0;
    list-style: none;
}

.brikk-redesign .brikk-cta-popup-content-why-brikk li {
    position: relative;
    margin: 0 0 16px;
    padding: 0 0 0 30px;
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--body-sm);
    font-weight: 400;
    line-height: var(--wp--custom--lh-base);
    letter-spacing: normal;
    color: var(--wp--preset--color--bg);
}

.brikk-redesign .brikk-cta-popup-content-why-brikk li:last-child {
    margin-bottom: 0;
}

/* The circled serif check (§6 .brikk-check), in the on-dark purple. */
.brikk-redesign .brikk-cta-popup-content-why-brikk li::before {
    content: '✓';
    position: absolute;
    top: 1px;
    left: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    width: 18px;
    height: 18px;
    padding-top: 4px;
    border: 1px solid var(--wp--custom--on-dark-purple);
    border-radius: var(--wp--custom--radius-pill);
    font-family: var(--wp--preset--font-family--serif);
    font-size: 9px;
    line-height: 1;
    color: var(--wp--custom--on-dark-purple);
}

/* The inline Trustpilot SVG: the wordmark path carries this class (its
   attribute fill is near-black); the star paths keep their attribute greens. */
.brikk-redesign .brikk-cta-popup-tp {
    fill: var(--wp--preset--color--bg);
}

/* --- Responsive ------------------------------------------------------------ */
@media (max-width: 1024.98px) {
    .brikk-redesign #brikk-cta-popup {
        padding: 40px 32px;
    }

    .brikk-redesign .brikk-cta-popup-content {
        gap: 32px;
    }

    .brikk-redesign .brikk-cta-popup-content-why-brikk {
        flex-basis: 250px;
        padding: 28px 24px;
    }

    .brikk-redesign .brikk-cta-popup-content-signup > h2 {
        font-size: 30px;
    }
}

/* The side panel goes below 768 (the legacy hid it below 950; 768 is the
   ladder value and the two-column shell still measures comfortably above it). */
@media (max-width: 768px) {
    .brikk-redesign .brikk-cta-popup-content-why-brikk {
        display: none;
    }

    .brikk-redesign #brikk-cta-popup {
        width: calc(100vw - 32px);
    }
}

@media (max-width: 640px) {
    .brikk-redesign #brikk-cta-popup {
        width: calc(100vw - 24px);
        max-height: calc(100vh - 24px);
        padding: 32px 20px;
    }

    .brikk-redesign .brikk-cta-popup-content-signup > h2 {
        font-size: 26px;
    }

    .brikk-redesign .brikk-cta-popup-content-signup > p {
        margin-bottom: 20px;
    }

    .brikk-redesign #brikk-cta-popup form.wpcf7-form p:first-of-type .wpcf7-form-control-wrap {
        flex-basis: 100%;
        min-width: 0;
    }

    .brikk-redesign #brikk-cta-popup input.wpcf7-submit {
        display: block;
        width: 100%;
    }
}


/* =============================================================================
   13. THE BOOKING FUNNEL
   -----------------------------------------------------------------------------
   Page-scoped: restyles the EXISTING funnel markup (brikk-tracking plugin) — no
   classes were renamed, no PHP touched. Where the design needs content that the
   markup does not carry (eyebrows, panel copy, the Trustpilot row), it is
   generated with CSS `content`. Those strings are collected at the top of the
   section so copy changes stay one-place edits.

   Step wrappers (ids from the PHP page classes):
     #screen_1 zipcode · #screen_3 calendar · #screen_4 account · #screen_5 thankyou

   Layout model (desktop ≥1025px):
     .brikk-funnel-layout-right   → fixed full-height image panel on the LEFT
     .funnel-top-bar              → fixed logo over the panel
     .funnel-steps                → fixed vertical step list over the panel
     everything else              → normal flow, pushed right by the panel width
   Below 1025px the panel disappears and the funnel becomes a single column
   with a white top bar + horizontal step indicator (the mobile design).
   ============================================================================= */

/* --- 10.1 Template chrome -------------------------------------------------- */

/* The template wraps ONLY the top bar in a .brikk-container. Neutralise the
   container so the bar can be placed freely at each breakpoint. */
   .brikk-container:has(> .funnel-top-bar) {
    max-width: none;
    padding: 0;
}

/* Second .funnel-top-bar-left holds the help-phone line; the design has no
   equivalent, so it is dropped everywhere (the number reappears on request). */
   .funnel-top-bar-left + .funnel-top-bar-left {
    display: none;
}

/* The funnel renders its own minimal chrome. The template's inline style hides
   the OLD .brikk-navigation/.brikk-footer classes, which no longer exist in
   header.php/footer.php — so the 2026 chrome must be hidden here instead (the
   drawer and overlay sit outside <header> exactly like the legacy offcanvas
   did). ⚠️ Every new chrome class belongs in this list the day it ships. */
.page-template-funnel-template .brikk-header,
.page-template-funnel-template .brikk-drawer,
.page-template-funnel-template .brikk-drawer-overlay,
.page-template-funnel-template .brikk-sitefooter {
    display: none;
}

/* The logo lockup (BRIKK + EJENDOMSMÆGLER) ships as pre-coloured PNGs
   (assets/img/logo-{white,purple}-280.png, 2× for retina) — the template's
   <picture> serves white ≥1025px (dark panel) and purple below (warm canvas). */
   .funnel-top-bar-left .brikk-logo {
    display: block;
    width: 140px;
    height: auto;
}

@media (min-width: 1025px) {
    .funnel-top-bar {
        position: fixed;
        top: 42px;
        left: 48px;
        z-index: calc(var(--wp--custom--z-chrome) + 1);
    }

    /* White wordmark over the dark panel. */
    .funnel-top-bar-left a {
        color: var(--wp--custom--on-dark);
    }
}

@media (max-width: 1024.98px) {
    /* The mobile design keeps the bars on the warm page canvas, separated by
       neutral-grey hairlines — no white surface. */
       .funnel-top-bar {
        display: flex;
        justify-content: center;
        padding: 14px 20px;
        background: var(--wp--preset--color--bg);
        border-bottom: 1px solid var(--wp--custom--funnel-line);
    }

    .funnel-top-bar-left .brikk-logo {
        width: 116px;
    }

    .funnel-top-bar-left a {
        color: var(--wp--preset--color--purple);
    }
}

/* --- 10.2 The split layout ------------------------------------------------- */

@media (min-width: 1025px) {
    .brikk-funnel-layout-right {
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        width: var(--wp--custom--funnel-panel);
        /* Overlay strength measured off the design PNG (α ≈ .76 top → .85
           bottom against the same photo) — noticeably darker than a "legible
           text" scrim; the photo is meant to sit far back. */
           background:
           linear-gradient(180deg, rgba(17, 13, 23, 0.75) 0%, rgba(17, 13, 23, 0.79) 60%, rgba(17, 13, 23, 0.85) 100%),
           url('../img/funnel-agents.webp') center / cover no-repeat;
           z-index: var(--wp--custom--z-raised);
        /* The panel now carries real content (the "Derfor Brikk" checklist),
           pinned to its bottom. */
           display: flex;
           flex-direction: column;
           justify-content: flex-end;
           padding: 0 48px 36px;
       }

       .brikk-funnel-layout-wrapper,
       .funnel-steps + .brikk-funnel-layout-wrapper {
        margin-left: var(--wp--custom--funnel-panel);
    }

    /* Thank-you page has no .funnel-steps sibling but the same wrapper. */
    /* The design centres each step's content vertically in the viewport. */
    .brikk-funnel-layout-left {
        display: flex;
        flex-direction: column;
        justify-content: center;
        min-height: 100vh;
    }

    .brikk-funnel-layout-left-content-inner {
        max-width: 750px;
        padding: 60px 48px 60px 120px;
    }
}

@media (max-width: 1024.98px) {
    .brikk-funnel-layout-right {
        display: none;
    }

    /* The horizontal padding lives on .brikk-container-large — the step bar is
       its direct child and pulls itself full-bleed with a matching negative
       margin (see 10.3). */
       .brikk-container-large {
        padding: 0 20px;
    }

    .brikk-funnel-layout-left-content-inner {
        max-width: 640px;
        margin-inline: auto;
        padding: 22px 0 48px;
    }
}

/* --- 10.3 Left panel: vertical steps + panel copy (desktop) ---------------- */

/* All CSS-generated copy for the panel lives in these few rules. */

@media (min-width: 1025px) {
    .funnel-steps {
        position: fixed;
        top: 160px;
        /* Stops above the fixed "Derfor Brikk" checklist in the panel bottom. */
        bottom: 260px;
        left: 48px;
        width: calc(var(--wp--custom--funnel-panel) - 96px);
        z-index: var(--wp--custom--z-chrome);
        display: flex;
        flex-direction: column;
        /* Short viewports (720p-class laptops, browser zoom): scroll rather
           than silently clipping the step list. */
           overflow-y: auto;
       }

       /* "Din booking" eyebrow — real markup from class-menu-funnel.php. */
       .page-template-funnel-template .steps_heading {
        margin: 0 0 22px;
        font-size: var(--wp--preset--font-size--eyebrow);
        font-weight: 500;
        letter-spacing: var(--wp--custom--ls-eyebrow);
        text-transform: uppercase;
        color: var(--wp--custom--on-dark-muted);
    }

    .page-template-funnel-template ul.steps {
        display: flex;
        flex-direction: column;
        gap: 22px;
    }

    .page-template-funnel-template ul.steps li,
    .page-template-funnel-template ul.steps li > a {
        display: flex;
        align-items: flex-start;
        gap: 20px;
        color: var(--wp--custom--on-dark);
    }

    /* Thin connector line between the step circles (design detail). Circle
       edge to circle edge = list gap (22) + the text block's overhang below
       the circle (~15), with 2px of air at each end. */
       .page-template-funnel-template ul.steps li + li .step::before {
        content: '';
        position: absolute;
        bottom: calc(100% + 2px);
        left: 50%;
        width: 1px;
        height: 33px;
        background: var(--wp--custom--on-dark-line);
    }

    /* Step name + CSS-generated description line. */
    .page-template-funnel-template .step_text {
        padding-top: 3px;
        font-size: 17px;
        font-weight: 500;
        line-height: 1.4;
        color: var(--wp--custom--on-dark);
    }

    .page-template-funnel-template .step_text::after {
        display: block;
        margin-top: 1px;
        font-size: 13.5px;
        font-weight: 400;
        color: var(--wp--custom--on-dark-faint);
    }

    /* (Active/completed circle colours for the dark panel live with the shared
       state model below — they must come AFTER the generic rules to win.) */

    /* "Derfor Brikk" checklist — real markup (GenericPage::RenderRightPanel),
       pinned to the panel bottom by the panel's flex column (see 10.2). */
       .brikk-funnel-why {
        border-top: 1px solid var(--wp--custom--on-dark-line);
        padding-top: 34px;
    }

    .brikk-funnel-why__title {
        margin: 0 0 18px;
        font-size: var(--wp--preset--font-size--eyebrow);
        font-weight: 500;
        letter-spacing: var(--wp--custom--ls-eyebrow);
        text-transform: uppercase;
        color: var(--wp--custom--on-dark-muted);
    }

    .brikk-funnel-why__list {
        display: flex;
        flex-direction: column;
        gap: 10px;
        margin: 0;
        padding: 0;
        list-style: none;
    }

    .brikk-funnel-why__list li {
        position: relative;
        padding-left: 30px;
        font-size: 13px;
        line-height: 1.5;
        color: var(--wp--custom--on-dark-muted);
    }

    .brikk-funnel-why__list li::before {
        content: '✓';
        position: absolute;
        left: 0;
        top: 2px;
        display: flex;
        align-items: center;
        justify-content: center;
        width: 16px;
        height: 16px;
        border-radius: var(--wp--custom--radius-pill);
        background: var(--wp--preset--color--purple);
        color: var(--wp--custom--on-accent);
        font-size: 9px;
        font-weight: 700;
        padding-top: 5px;
    }

    .page-template-funnel-template ul.steps li:nth-child(1) .step_text::after { content: 'Find din lokale ekspert'; }
    .page-template-funnel-template ul.steps li:nth-child(2) .step_text::after { content: 'Vælg et tidspunkt der passer'; }
    .page-template-funnel-template ul.steps li:nth-child(3) .step_text::after { content: 'Bekræft dine oplysninger'; }
}

/* Tighten the panel on height-constrained desktops so the step list and the
   checklist stay fully visible without scrolling. (The design's reference
   viewport is 714px tall — the standard layout must still apply there, so
   this only kicks in below that.) */
   @media (min-width: 1025px) and (max-height: 660px) {
    .funnel-steps {
        top: 116px;
        bottom: 232px;
    }

    .page-template-funnel-template .steps_heading {
        margin-bottom: 22px;
    }

    .page-template-funnel-template ul.steps {
        gap: 14px;
    }

    .page-template-funnel-template ul.steps li + li .step::before {
        height: 25px;
    }

    .brikk-funnel-why {
        padding-top: 20px;
    }

    .brikk-funnel-why__list {
        gap: 6px;
    }

    .brikk-funnel-why__list li {
        font-size: 12.5px;
    }
}

/* Below 570px of height even the tightened step list can't fit between the
   top bar and the checklist — hide it ("Din booking" heading included). */
@media (min-width: 1025px) and (max-height: 570px) {
    .funnel-steps {
        display: none;
    }
    .brikk-funnel-why {
        border-top:0px;
    }
}

/* Step circles — shared between desktop and mobile. */
.page-template-funnel-template .step {
    position: relative;
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border: 1px solid currentColor;
    border-radius: var(--wp--custom--radius-pill);
    font-size: 13px;
    font-weight: 500;
    padding-top:4px;
}

/* State model from class-menu-funnel.php:
     completed  = li.funnel-steps-active WITH a link
     current    = li.funnel-steps-active without a link
     upcoming   = li without the class                                        */

     .page-template-funnel-template ul.steps li.funnel-steps-active:not(:has(a)) .step {
        background: var(--wp--preset--color--purple);
        border-color: var(--wp--preset--color--purple);
        color: var(--wp--custom--on-accent);
    }

/* The number is hidden by making it transparent, which would also erase the
   currentColor border — so the border colour is pinned per breakpoint below. */
   .page-template-funnel-template ul.steps li.funnel-steps-active:has(a) .step {
    color: transparent;
}

.page-template-funnel-template ul.steps li.funnel-steps-active:has(a) .step::after {
    content: '✓';
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding-top:4px;
}

@media (min-width: 1025px) {
    /* On the dark panel the CURRENT circle uses the lifted purple (design
       #9871e2 — the solid brand purple is too dark against the photo). */
       .page-template-funnel-template ul.steps li.funnel-steps-active:not(:has(a)) .step {
        background: var(--wp--custom--funnel-step-active);
        border-color: var(--wp--custom--funnel-step-active);
    }

    /* COMPLETED circles are charcoal-filled with a light check (design fill
       ≈ 17% white over the panel), not hollow. */
       .page-template-funnel-template ul.steps li.funnel-steps-active:has(a) .step {
        background: var(--wp--custom--on-dark-fill);
        border: 1px solid #fff;
    }

    .page-template-funnel-template ul.steps li.funnel-steps-active:has(a) .step::after {
        color: var(--wp--custom--on-dark);
    }

    .page-template-funnel-template ul.steps li:not(.funnel-steps-active) {
        opacity: 0.55;
    }
}

/* --- Mobile step indicator (horizontal, under the logo bar) ---------------- */

@media (max-width: 1024.98px) {
    .funnel-steps {
        margin: 0 -20px;
        padding: 14px 20px 12px;
        background: var(--wp--preset--color--bg);
        border-bottom: 1px solid var(--wp--custom--funnel-line);
    }

    /* The "Din booking" panel eyebrow has no place in the horizontal bar. */
    .page-template-funnel-template .steps_heading {
        display: none;
    }

    /* The mobile bar sits inside the padded content column; the negative
       margin above needs the column padding to match (see 10.2). */

    .page-template-funnel-template ul.steps {
        display: flex;
        justify-content: center;
        gap: 40px;
        width: 100%;
        margin-left: auto;
        margin-right: auto;
    }

    .page-template-funnel-template ul.steps li,
    .page-template-funnel-template ul.steps li > a {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 7px;
        color: var(--wp--preset--color--muted);
    }
        .page-template-funnel-template ul.steps li {
        min-width:86px;
    }
    .page-template-funnel-template .step {
        width: 28px;
        padding-top:3px;
        height: 28px;
        border-color: var(--wp--custom--line-dark);
        color: var(--wp--preset--color--muted);
    }

    .page-template-funnel-template .step_text {
        font-size: 10px;
        font-weight: 500;
        letter-spacing: 0.14em;
        text-transform: uppercase;
    }

    .page-template-funnel-template ul.steps li.funnel-steps-active .step_text {
        color: var(--wp--preset--color--dark);
    }

    /* Completed circles: purple check on the light purple tint (design). */
    .page-template-funnel-template ul.steps li.funnel-steps-active:has(a) .step {
        background: var(--wp--custom--purple-tint);
        border-color: var(--wp--preset--color--purple);
    }

    .page-template-funnel-template ul.steps li.funnel-steps-active:has(a) .step::after {
        color: var(--wp--preset--color--purple);
    }
}

/* --- 10.4 Step content: shared pieces -------------------------------------- */

/* CSS-generated step eyebrows. */
#screen_1 .brikk-funnel-layout-left-content-inner::before { content: 'Trin 1 · Postnummer'; }
#screen_3 .brikk-funnel-layout-left-content-inner::before { content: 'Trin 2 · Dato og tid'; }
#screen_4 .brikk-funnel-layout-left-content-inner::before { content: 'Trin 3 · Dine oplysninger'; }
#screen_5 .brikk-funnel-layout-left-content-inner::before { content: 'Booking bekræftet'; }

.brikk-funnel-layout-left-content-inner::before {
    display: block;
    margin-bottom: 10px;
    font-size: var(--wp--preset--font-size--eyebrow);
    font-weight: 500;
    letter-spacing: var(--wp--custom--ls-eyebrow);
    text-transform: uppercase;
    color: var(--wp--preset--color--muted);
}

/* Responsive copy variants: several funnel strings differ between the desktop
   and mobile designs (headings, leads, label suffixes). The markup carries
   both; these switches pick one per breakpoint. */
   @media (min-width: 1025px) {
    .page-template-funnel-template .brikk-funnel-only-mobile {
        display: none;
    }
}

@media (max-width: 1024.98px) {
    .page-template-funnel-template .brikk-funnel-hide-mobile {
        display: none;
    }
}

/* Step title (the h2 in every step's markup). Design: 53px on steps 1/3
   (step 2 runs smaller — see 10.6), ~24px in the mobile comps. */
   .brikk-funnel-layout-left h2 {
    margin: 0 0 22px;
    font-size: clamp(30px, 3.7vw, 53px);
}

@media (max-width: 1024.98px) {
    .brikk-funnel-layout-left h2 {
        margin-bottom: 14px;
        font-size: 24px;
    }
}

/* Step lead. On step 1 this is semantically an h1 — visually it is body copy,
   hence the font family override. */
   .brikk-funnel-layout-left-description {
    max-width: 470px;
    margin: 0 0 26px;
    font-family: var(--wp--preset--font-family--sans);
    /* Design leads measure ≈16.5px on desktop (between the body tokens). */
    font-size: 16.5px;
    font-weight: 400;
    line-height: var(--wp--custom--lh-copy);
    letter-spacing: 0;
    color: var(--wp--preset--color--muted);
}

@media (max-width: 1024.98px) {
    .brikk-funnel-layout-left-description {
        font-size: 14px;
    }
}

/* Primary action — shared by every step's CTA (#findAddress_btn, the account
   submit and the thank-you/hub links all carry .cta_btn). */
/* Measured off the design: fields are 50px tall, CTAs 55px. Funnel fields use
   the neutral-grey hairline, not the warm site one. */
   .page-template-funnel-template input,
   .page-template-funnel-template select {
    border-color: var(--wp--custom--funnel-line);
}

.page-template-funnel-template input:focus,
.page-template-funnel-template select:focus {
    border-color: var(--wp--preset--color--purple);
}

.page-template-funnel-template ::placeholder {
    color: var(--wp--custom--funnel-placeholder);
}

.page-template-funnel-template input.form-control,
.page-template-funnel-template select.form-control,
#appointmentForm input:not([type='checkbox']),
#appointmentForm select {
    height: 50px;
    /* The base §7 vertical padding (15/13) over-constrains the fixed height:
       content box 20px vs a 21px line box (22.4px on ≤1024 where the iOS
       guard raises fields to 16px) — the glyph tops get clipped. Zero it and
       let the browser centre the text in the fixed height instead. */
    padding-top: 0;
    padding-bottom: 0;
}

@media (max-width: 1024.98px) {
    .page-template-funnel-template input.form-control,
    .page-template-funnel-template select.form-control,
    #appointmentForm input:not([type='checkbox']),
    #appointmentForm select {
        height: 48px;
    }
}

.page-template-funnel-template .cta_btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    min-height: 55px;
    padding: 18px 26px 15px;
    border: 1px solid transparent;
    background: var(--wp--preset--color--purple);
    color: var(--wp--custom--on-accent);
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui-sm);
    font-weight: 500;
    line-height: 1.3;
    letter-spacing: var(--wp--custom--ls-ui);
    text-transform: uppercase;
    cursor: pointer;
    transition: background var(--wp--custom--transition);
}

.page-template-funnel-template .cta_btn:hover {
    background: var(--wp--custom--purple-hover);
    color: var(--wp--custom--on-accent);
}

.page-template-funnel-template .cta_btn::after {
    content: '→';
    font-size: 14px;
    letter-spacing: 0;
}

@media (max-width: 1024.98px) {
    .page-template-funnel-template .cta_btn {
        width: 100%;
        min-height: 50px;
        padding: 16px 22px 14px;
    }
}

/* Action row on steps 2–3: ghost "← Tilbage" + primary "Næste/Bekræft →".
   The mobile design drops the back button and stretches the primary. */
   .brikk-funnel-actions {
    display: flex;
    align-items: stretch;
    gap: 16px;
    margin-top: 28px;
}

.brikk-btn-back {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    min-height: 55px;
    padding: 18px 26px 15px;
    border: 1px solid var(--wp--custom--line-dark);
    background: transparent;
    color: var(--wp--preset--color--dark);
    font-family: var(--wp--preset--font-family--sans);
    font-size: var(--wp--preset--font-size--ui-sm);
    font-weight: 500;
    line-height: 1.3;
    letter-spacing: var(--wp--custom--ls-ui);
    text-transform: uppercase;
    cursor: pointer;
    transition: border-color var(--wp--custom--transition);
}

.brikk-btn-back:hover {
    border-color: var(--wp--preset--color--dark);
    color: var(--wp--preset--color--dark);
}

.brikk-btn-back::before {
    content: '←';
    font-size: 14px;
    letter-spacing: 0;
}

@media (max-width: 1024.98px) {
    .brikk-btn-back {
        display: none;
    }

    .brikk-funnel-actions {
        margin-top: 24px;
    }
}

/* The CSS-generated Trustpilot row under each step's action — steps 1–3
   (screen ids: zipcode=screen_1, calendar=screen_3, account=screen_4).
   One composite SVG (282.42×34.69) replicating the A/B landing page's
   .brikk-tp block pixel-for-pixel: score 14px/500 · "900+ anmeldelser" over
   the stars · wordmark, 12px gaps, vertically centred. It must be a SINGLE
   image: with multiple content pieces ('text' url() url()) browsers wrap
   everything into ONE anonymous flex item, so gap/align-items never apply and
   the pieces sit jammed together on a text baseline. The text is baked in as
   glyph outlines from the theme's own OTFs, so it renders identically on
   every platform (SVG-as-image cannot load webfonts). Copy changes (score,
   review count) therefore mean regenerating the file with
   plugins/brikk-local-dev/tools/gen-trustpilot-row.py. */
   #screen_1 .brikk-funnel-layout-left-content-inner::after,
   #screen_3 .brikk-funnel-layout-left-content-inner::after,
   #screen_4 .brikk-funnel-layout-left-content-inner::after {
    content: url('../img/trustpilot-row.svg');
    display: flex;
    /* Kill the line-box strut so the box hugs the image (the image is an
       anonymous inline box and cannot be styled directly). */
       line-height: 0;
       margin-top: 32px;
   }

   @media (max-width: 1024.98px) {
    #screen_1 .brikk-funnel-layout-left-content-inner::after,
    #screen_3 .brikk-funnel-layout-left-content-inner::after,
    #screen_4 .brikk-funnel-layout-left-content-inner::after {
        justify-content: center;
    }
}

/* --- 10.5 Step 1 — postcode ------------------------------------------------ */

/* The old 4-column "why Brikk" block is replaced by the panel checklist. */
.brikk-funnel-layout-left-why-brikk {
    display: none;
}

.postcode_parent {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 18px;
    max-width: 300px;
}

/* The design gives the CTA more air than the label→input gap (30 vs 18). */
.postcode_parent #findAddress_btn {
    margin-top: 12px;
}

.postcode_parent::before {
    content: 'Dit postnummer';
    font-size: var(--wp--preset--font-size--eyebrow);
    font-weight: 500;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--wp--preset--color--muted);
}

@media (max-width: 1024.98px) {
    .postcode_parent {
        max-width: none;
    }
}

#error_postcode {
    margin-top: 12px;
    font-size: 13px;
    color: var(--wp--custom--error);
}

@media (min-width: 1025px) {
    /* The design breaks the heading "Lad os finde din / lokale ekspert." */
    #screen_1 h2 {
        max-width: 440px;
    }

    /* Two lead paragraphs: tight between themselves, air before the label. */
    #screen_1 h1.brikk-funnel-layout-left-description {
        margin-bottom: 12px;
    }

    #screen_1 p.brikk-funnel-layout-left-description {
        margin-bottom: 30px;
    }
}

/* Step 1 has two lead variants: a long one (desktop) and a short one carrying
   the legacy .hide-desktop class. On mobile the SHORT one is promoted to the
   step heading (matching the mobile design) and the h2 + long lead are hidden. */
   .page-template-funnel-template .hide-desktop {
    display: none;
}

@media (max-width: 1024.98px) {
    #screen_1 h2 {
        display: none;
    }

    /* The short .hide-desktop variant becomes the mobile heading and the long
       lead stays visible below it. DOM order is lead-then-heading, so the
       column is reordered with flex (the ::before eyebrow keeps order 0). */
       #screen_1 .brikk-funnel-layout-left-content-inner {
        display: flex;
        flex-direction: column;
    }

    #screen_1 .hide-desktop {
        display: block;
        order: 1;
        margin: 0 0 12px;
        font-family: var(--wp--preset--font-family--serif);
        font-size: clamp(24px, 6.9vw, 28px);
        font-weight: 500;
        line-height: 1.15;
        letter-spacing: var(--wp--custom--ls-heading);
        color: var(--wp--preset--color--dark);
    }

    #screen_1 .brikk-funnel-mobile-lead {
        order: 2;
        margin-bottom: 22px;
    }

    #screen_1 .postcode_parent { order: 3; }
    #screen_1 #error_postcode { order: 4; }
    #screen_1 .brikk-funnel-layout-left-content-inner::after { order: 5; }
}

/* --- 10.6 Step 2 — calendar ------------------------------------------------ */

/* Agent intro under the (full-width) heading: photo left, name + description
   right. The h2 sits OUTSIDE this block in the markup. */
   .brikk-funnel-layout-left-agent-top {
    display: flex;
    align-items: flex-start;
    gap: 18px;
    margin-bottom: 20px;
}

.brikk-funnel-layout-left-agent-top .brikk-funnel-layout-left-agent-top-left {
    flex: 1;
}

.brikk-funnel-layout-left-agent-top .brikk-funnel-layout-left-description {
    margin-bottom: 0;
    max-width: none;
    font-size: 13.5px;
    line-height: 1.55;
}

.brikk-funnel-agent-name {
    margin: 0 0 4px;
    font-size: 15px;
}

/* The design's "choose date first, then time" hint, purple and emphasised. */
.brikk-funnel-pick-hint {
    font-weight: 500;
    color: var(--wp--preset--color--purple);
}

.cal_img_box {
    flex: none;
    width: 78px;
    border: 0px;
    background: var(--wp--preset--color--card);
}

.cal_img_box img {
    width: 100%;
    height: 84px;
    object-fit: cover;
}

.aggent_first_name {
    font-weight: 700;
    color: var(--wp--preset--color--dark);
}

/* In the mobile comp the inline agent name runs in the same grey/weight as
   the rest of the sentence. */
   .brikk-funnel-only-mobile .aggent_first_name {
    font-weight: 700;
    color: inherit;
}

@media (min-width: 1025px) {
    /* Step 2's heading is smaller than the other steps' (design: ~38px). */
    #screen_3 h2 {
        margin-bottom: 18px;
        font-size: 38px;
    }
}

@media (max-width: 1024.98px) {
    /* The mobile design shows no agent photo. */
    #screen_3 .cal_img_box {
        display: none;
    }
}

/* Calendar widget structure:
   .calendar_select_wrapper > .callendar_top (controls + day grid) + .cal_padd
   (time grid). The loading overlay positions against the wrapper. */
   .calendar_select_wrapper {
    position: relative;
}

/* Loading state (2026-07-23): a content-loader skeleton. While the agent +
   calendar AJAX load, the REAL agent block and calendar are hidden entirely
   (sibling rule below) and shimmering grey boxes mirror the ready layout —
   photo + text lines, a day row, a time grid — sized to the measured ready
   state so the column height barely moves and nothing half-loaded (unstyled
   slick stack, empty agent, all-available cells) ever flashes.
   The skeleton div carries the legacy calendar-load-overlay class on purpose:
   the funnel JS removes that element once everything is ready (or fails over
   to kontakt.os), which un-hides the content via the sibling rule — no JS
   involvement in the reveal. */
.brikk-funnel-skeleton ~ .brikk-funnel-layout-left-agent-top,
.brikk-funnel-skeleton ~ .calendar_select_wrapper {
    display: none;
}

.brikk-funnel-skeleton__box {
    display: block;
    background-color: var(--wp--preset--color--line);
    background-image: linear-gradient(90deg,
        var(--wp--preset--color--line) 42%,
        var(--wp--preset--color--line-2) 50%,
        var(--wp--preset--color--line) 58%);
    background-size: 300% 100%;
    animation: brikk-skeleton-shimmer 1.4s ease-in-out infinite;
}

@keyframes brikk-skeleton-shimmer {
    0%   { background-position: 100% 0; }
    100% { background-position: -100% 0; }
}

/* Agent: photo 78x84 + name + description lines (matches the ready block). */
.brikk-funnel-skeleton__agent {
    display: flex;
    align-items: flex-start;
    gap: 18px;
    margin-bottom: 20px;
}

.brikk-funnel-skeleton__photo {
    flex: 0 0 78px;
    height: 84px;
}

.brikk-funnel-skeleton__agent-lines {
    flex: 1;
    padding-top: 3px;
}

.brikk-funnel-skeleton__line {
    height: 12px;
    margin-bottom: 10px;
}

.brikk-funnel-skeleton__line--name {
    height: 15px;
    max-width: 180px;
    margin-bottom: 13px;
}

.brikk-funnel-skeleton__line--short {
    max-width: 45%;
    margin-bottom: 0;
}

/* The VÆLG DATO / VÆLG TIDSPUNKT eyebrow stand-ins. */
.brikk-funnel-skeleton__label {
    width: 90px;
    height: 11px;
    margin: 0 0 17px;
}

.brikk-funnel-skeleton__cells {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 10px;
    margin-bottom: 26px;
}

.brikk-funnel-skeleton__cells--days .brikk-funnel-skeleton__box {
    height: 90px;
}

.brikk-funnel-skeleton__cells--times {
    gap: 8px;
    margin-bottom: 0;
}

.brikk-funnel-skeleton__cells--times .brikk-funnel-skeleton__box {
    height: 44px;
}

@media (max-width: 1024.98px) {
    /* Mobile ready-state has no photo and a 2-line description; the time grid
       is 4-up (12 boxes -> 3 rows, ≈ the measured ready height). */
    .brikk-funnel-skeleton__photo,
    .brikk-funnel-skeleton__line--name {
        display: none;
    }

    .brikk-funnel-skeleton__cells--days .brikk-funnel-skeleton__box {
        height: 85px;
    }

    .brikk-funnel-skeleton__cells--times {
        grid-template-columns: repeat(4, 1fr);
    }
}

.callendar_top {
    position: relative;
    padding-top: 38px;
}

.callendar_top::before {
    content: 'Vælg dato';
    position: absolute;
    top: 6px;
    left: 0;
    font-size: var(--wp--preset--font-size--eyebrow);
    font-weight: 500;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--wp--preset--color--muted);
}

/* The design shows a static "Denne uge" caption next to the arrows, not the
   selected date. The JS keeps writing the date into #calendar_day_selected —
   the span is hidden and the caption drawn with generated content, so no JS
   behaviour changes. */
   .callendar_controls_wr {
    position: absolute;
    top: 6px;
    right: 76px;
    font-size: 12px;
    color: var(--wp--preset--color--muted);
}

#calendar_day_selected span {
    display: none;
}

#calendar_day_selected::before {
    content: 'Denne uge';
}

/* Old per-weekday header row — day names now live inside each cell. */
.days_th {
    display: none;
}

/* Slick navigation arrows, docked in the label row above the carousel. Slick
   appends them inside #calendar_funnel, which is position:relative via the
   slick core — hence the negative top offset (the label strip is the
   .callendar_top padding of 38px directly above the carousel). */
   .slick-prev,
   .slick-next {
    position: absolute;
    top: -40px;
    width: 30px;
    height: 30px;
    border: 1px solid var(--wp--custom--funnel-line);
    background: var(--wp--preset--color--card);
    font-size: 0;
    cursor: pointer;
    transition: border-color var(--wp--custom--transition);
    z-index: var(--wp--custom--z-raised);
}

.slick-prev { right: 36px; }
.slick-next { right: 0; }

.slick-prev:hover,
.slick-next:hover {
    border-color: var(--wp--preset--color--purple);
}

.slick-prev::before,
.slick-next::before {
    font-size: 16px;
    line-height: 1;
    color: var(--wp--preset--color--dark);
}

.slick-prev::before { content: '‹'; }
.slick-next::before { content: '›'; }

.slick-prev.slick-disabled,
.slick-next.slick-disabled {
    background: #f8f7f4;
    border-color: #e6e3e1;
    cursor: default;
}

.slick-prev.slick-disabled::before,
.slick-next.slick-disabled::before {
    color: var(--wp--preset--color--muted);
}

/* Day cells. Each slide is one row of 6 weekdays; border-spacing = the gaps. */
.days_nr {
    /* border-spacing also pads the outer edges — bleed it off so the first
       and last cell align flush with the content column. */
       width: calc(100% + 10px);
       margin: 0 -5px;
       border-collapse: separate;
       border-spacing: 5px 0;
       table-layout: fixed;
   }

   td.day_calendar {
    position: relative;
    padding: 13px 2px 12px;
    border: 1px solid var(--wp--custom--funnel-line);
    background: var(--wp--preset--color--card);
    text-align: center;
    cursor: pointer;
    transition: border-color var(--wp--custom--transition);
}

td.day_calendar:hover {
    border-color: var(--wp--preset--color--purple);
}

/* Abbreviated day/month (the design shows "ONS / 22 / jul"). The *-abbrev
   attributes are display-only extras on the cells; the full-name attributes
   stay untouched for the booking JS. */
   td.day_calendar::before {
    content: attr(data-day-abbrev);
    display: block;
    margin-bottom: 6px;
    font-size: 9.5px;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--wp--preset--color--muted);
    overflow: hidden;
    white-space: nowrap;
}

td.day_calendar::after {
    content: attr(data-month-abbrev);
    display: block;
    margin-top: 4px;
    font-size: 11px;
    color: var(--wp--preset--color--muted);
    overflow: hidden;
    white-space: nowrap;
}

td.day_calendar a {
    display: block;
    font-family: var(--wp--preset--font-family--serif);
    font-size: 24px;
    font-weight: 500;
    line-height: 1;
    color: var(--wp--preset--color--dark);
    cursor: pointer;
}

/* The JS binds clicks to the <a>; stretch its hit area across the cell. */
td.day_calendar a::after {
    content: '';
    position: absolute;
    inset: 0;
}

td.day_calendar.day_selected {
    border-color: var(--wp--preset--color--purple);
    box-shadow: inset 0 0 0 1px var(--wp--preset--color--purple);
    background: var(--wp--custom--purple-tint);
}

td.day_calendar.day_selected a {
    color: var(--wp--preset--color--purple);
}

/* Unselectable days are SHOWN, greyed to 0.4, and unclickable (decided
   2026-07-23 — supersedes the earlier display:none on .day_disabled). Two
   classes, both applied by the funnel JS after the calendar loads:
     .day_disabled        not yet bookable (before the first available day)
     .day_no_availability the agent has no free slot that day
   The JS unbinds their click handlers; pointer-events here is the
   belt-and-braces guard against selection. */
td.day_calendar.day_disabled,
td.day_calendar.day_no_availability {
    opacity: 0.4;
    pointer-events: none;
    cursor: default;
}

@media (max-width: 640px) {
    td.day_calendar a {
        font-size: 19px;
    }

    .days_nr {
        width: calc(100% + 6px);
        margin: 0 -3px;
        border-spacing: 3px 0;
    }
}

/* Small phones: the step bar is wider than the column. (The Trustpilot row is
   a single 282px SVG; it fits every viewport ≥ ~325px and on anything smaller
   its right edge is harmlessly clipped by the body clip.) */
   @media (max-width: 380px) {
    .page-template-funnel-template ul.steps {
        gap: 24px;
    }
}

/* Time grid. */
.cal_padd {
    position: relative;
    margin-top: 26px;
    padding-top: 30px;
}

.cal_padd::before {
    content: 'Vælg tidspunkt';
    position: absolute;
    top: 0;
    left: 0;
    font-size: var(--wp--preset--font-size--eyebrow);
    font-weight: 500;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--wp--preset--color--muted);
}

#calendar_hours_select {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 8px;
}

.pick_time {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 13px 4px 11px;
    border: 1px solid var(--wp--custom--funnel-line);
    background: var(--wp--preset--color--card);
    font-size: 13.5px;
    letter-spacing: 0.04em;
    color: var(--wp--preset--color--dark);
    cursor: pointer;
    transition: border-color var(--wp--custom--transition), background var(--wp--custom--transition);
}

.pick_time:hover {
    border-color: var(--wp--preset--color--purple);
    background: var(--wp--preset--color--purple-soft);
}

/* Chosen slot (set by the funnel JS; confirmed via the Næste button). */
.pick_time.time_selected {
    border-color: var(--wp--preset--color--purple);
    box-shadow: inset 0 0 0 1px var(--wp--preset--color--purple);
    background: var(--wp--custom--purple-tint);
    font-weight: 500;
    color: var(--wp--preset--color--purple);
}

/* The design hides unavailable slots entirely instead of greying them out. */
.pick_time.is_disabled {
    display: none;
}

@media (max-width: 1024.98px) {
    #calendar_hours_select {
        grid-template-columns: repeat(4, 1fr);
    }
}

/* --- 10.7 Step 3 — account form -------------------------------------------- */

/* The whole form is one 2-column grid and the .form_row wrappers are dissolved
   with display:contents, so every field auto-places 2-up in DOM order:
   (Fornavn·Efternavn)(mail·Telefon)(Adresse·Type) — which is exactly the design,
   including Adresse + Ejendomstype sharing a row even though the markup puts
   them in separate .form_row.full wrappers. The design keeps two columns on
   mobile as well, so there is deliberately no single-column collapse.

   Unknown direct children (the production-only [elementor-template] output, the
   hidden field row, the submit button) span the full width by default — only
   .input_row items flow into the columns. */
   .appointment_form {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 18px 16px;
    text-align: left;
}

.appointment_form > * {
    grid-column: 1 / -1;
}

.form_row {
    display: contents;
}

.input_row {
    /* relative: anchors the DAWA suggestion dropdown (below). */
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 7px;
    grid-column: auto;
    min-width: 0;
}

/* On narrow phones the address and Ejendomstype rows each get the full row —
   long Danish street names don't fit a half column. */
@media (max-width: 375px) {
    .input_row:has(#adresse),
    .input_row:has(select[name='Type']) {
        grid-column: 1 / -1;
    }
}

/* DAWA address autocomplete (dawa-autocomplete2, initialised on first click
   of #adresse by themes/brikk/assets/js/autocomplete.js). The lib inserts
   .dawa-autocomplete-suggestions as a sibling of the input inside .input_row;
   absolute-position it under the field so the flex column doesn't grow. */
.dawa-autocomplete-suggestions {
    position: absolute;
    top: 100%;
    left: 0;
    /* Full form width (both grid columns + the 16px column gap): addresses
       are long and would wrap cramped inside the half-width address column. */
    width: calc(200% + 16px);
    z-index: var(--wp--custom--z-raised);
    margin-top: -1px; /* fuse with the field's bottom border */
    /* Cap against small screens with the keyboard up: never taller than 45%
       of the visible viewport. */
    max-height: min(264px, 45dvh);
    overflow-y: auto;
    overscroll-behavior: contain;
    background: var(--wp--preset--color--card);
    border: 1px solid var(--wp--custom--funnel-line);
    box-shadow: 0 12px 24px rgba(26, 26, 26, 0.08);
}

/* ≤375px the address row itself is full-width — so is the dropdown. */
@media (max-width: 375px) {
    .dawa-autocomplete-suggestions {
        width: 100%;
    }
}

.dawa-autocomplete-suggestions .dawa-autocomplete-suggestion {
    padding: 13px 16px;
    font-size: 14px;
    line-height: 1.35;
    color: var(--wp--preset--color--dark);
    cursor: pointer;
}

.dawa-autocomplete-suggestions .dawa-autocomplete-suggestion + .dawa-autocomplete-suggestion {
    border-top: 1px solid var(--wp--custom--funnel-line);
}

.dawa-autocomplete-suggestions .dawa-autocomplete-suggestion:hover,
.dawa-autocomplete-suggestions .dawa-autocomplete-suggestion.dawa-selected {
    background: var(--wp--custom--purple-tint);
}

/* The consent row is an .input_row too but must span both columns. */
.input_row:has(.brikk-funnel-layout-wrapper-compliance) {
    grid-column: 1 / -1;
}

.input_row > label {
    font-size: var(--wp--preset--font-size--eyebrow);
    font-weight: 500;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--wp--preset--color--muted);
}

/* Validation: jQuery Validate's highlight() puts .error on both the field and
   its .input_row; the message span is pre-rendered in the markup. */
   .input_row span.error {
    display: none;
    font-size: 12px;
    color: var(--wp--custom--error);
}

.input_row.error span.error {
    display: block;
}

.input_row.error input,
.input_row.error select {
    border-color: var(--wp--custom--error);
}

/* Consent checkbox row. */
.brikk-funnel-layout-wrapper-compliance {
    display: flex;
    align-items: flex-start;
    gap: 10px;
}

.brikk-funnel-layout-wrapper-compliance label {
    font-size: 13px;
    line-height: 1.5;
    color: var(--wp--preset--color--muted);
}

.brikk-funnel-layout-wrapper-compliance a {
    color: var(--wp--preset--color--purple);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.brikk-funnel-layout-wrapper-compliance input[type='checkbox'] {
    margin-top: 2px;
}

.brikk-funnel-layout-wrapper-compliance.error label {
    color: var(--wp--custom--error);
}

/* Confirmation line. The prefix copy differs per breakpoint (desktop: "Vi
   bekræfter din vurdering på …", mobile: "Du har valgt følgende: …"), so it is
   CSS-generated into an empty span; the date/time spans are JS-filled. */
   .brikk-funnel-confirm-prefix::before {
    content: 'Vi bekræfter din vurdering på ';
}

#screen_4 #time_selected,
#screen_4 #date_selected {
    font-weight: 500;
    color: var(--wp--preset--color--dark);
}

@media (max-width: 1024.98px) {
    .brikk-funnel-confirm-prefix::before {
        content: 'Du har valgt følgende: ';
    }

    /* The mobile comp labels this step "Trin 3 · Info". */
    #screen_4 .brikk-funnel-layout-left-content-inner::before {
        content: 'Trin 3 · Info';
    }

    /* On mobile the whole "Tir d. 28. jul kl. 10:00" tail is bold. */
    #screen_4 .brikk-funnel-confirm-when {
        font-weight: 700;
        color: var(--wp--preset--color--dark);
    }
}

/* The action row is a full-width grid child; the buttons hug their labels. */
#screen_4 .brikk-funnel-actions {
    margin-top: 10px;
}

@media (max-width: 1024.98px) {
    #screen_4 .brikk-funnel-actions {
        margin-top: 6px;
    }
}

/* --- 10.8 Step 4 — thank you ----------------------------------------------- */
/* Design: claude-new-designs/funnel/{desktop,mobile}/step-4-funnel-confirmation.png
   Two cards: booking summary (.thanks_right, first) and the local expert
   (.thanks_left, second). The legacy Brikk Hub block and the raw
   #time_selected/#date_selected spans stay in the DOM but are hidden — the
   comp has no Hub CTA (deliberate deviation, confirm with Andreas). */

/* The comp centres a ~688px block in the area right of the panel instead of
   the other steps' 120px indent. */
@media (min-width: 1025px) {
    #screen_5 .brikk-funnel-layout-left-content-inner {
        width: 100%;
        max-width: 768px;
        margin-inline: auto;
        padding: 60px 40px;
    }

    #screen_5 h2 {
        margin-bottom: 18px;
        font-size: 38px;
    }

    /* Step 4 is the one step whose comp shows the top-bar help line —
       pinned to the viewport's top right, mirroring the fixed top bar. */
    .page-id-72647 .funnel-top-bar-left + .funnel-top-bar-left {
        display: block;
        position: fixed;
        top: 34px;
        right: 48px;
        z-index: var(--wp--custom--z-chrome);
        font-size: 13px;
        color: var(--wp--preset--color--muted);
    }

    .page-id-72647 .funnel-top-bar-left + .funnel-top-bar-left a {
        font-weight: 500;
        color: var(--wp--preset--color--purple);
        text-decoration: none;
    }
}

.thanks_ctn {
    display: grid;
    grid-template-columns: 1.5fr 1fr;
    gap: 18px;
    margin-top: 34px;
}

.thanks_left,
.thanks_right {
    padding: 30px;
    border: 1px solid var(--wp--custom--funnel-line);
    background: var(--wp--preset--color--card-soft);
}

/* --- Booking card ---------------------------------------------------------- */

.funnel_thanks_intro {
    margin-bottom: 16px;
    font-size: var(--wp--preset--font-size--eyebrow);
    font-weight: 500;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--wp--preset--color--muted);
}

.brikk-funnel-booked-slot {
    display: block;
    font-family: var(--wp--preset--font-family--serif);
    font-size: 33px;
    font-weight: 500;
    line-height: 1.35;
    color: var(--wp--preset--color--dark);
}

/* Desktop comp breaks before "kl. 16:00"; mobile keeps one line. */
.brikk-funnel-booked-slot-time {
    display: block;
}

/* Replaced by .brikk-funnel-booked-slot (comp format); kept in the DOM. */
#screen_5 #time_selected,
#screen_5 #date_selected {
    display: none;
}

.brikk-funnel-confirm-note {
    margin-top: 14px;
    padding-bottom: 20px;
    border-bottom: 1px solid var(--wp--custom--funnel-line);
    font-size: 13.5px;
    color: var(--wp--preset--color--muted);
}

/* The Brikk Hub description + CTA are not in the comp. */
.funnel_thanks_hub_description,
#screen_5 .tr_respons .cta_btn {
    display: none;
}

/* Lowercase muted line per the comp — unlike the card eyebrow above it. */
.funnel_thanks_export {
    margin: 20px 0 12px;
    font-size: 12.5px;
    color: var(--wp--preset--color--muted);
}

.export_list {
    display: flex;
    gap: 28px;
}

.export_list li a {
    font-size: 14.5px;
    font-weight: 500;
    color: var(--wp--preset--color--purple);
    transition: color var(--wp--custom--transition);
}

.export_list li a:hover {
    color: var(--wp--custom--purple-hover);
}

/* --- Local expert card ----------------------------------------------------- */

.thanks_left {
    text-align: center;
}

.funnel_agent_intro {
    margin-bottom: 16px;
    font-size: var(--wp--preset--font-size--micro);
    font-weight: 500;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--wp--preset--color--muted);
}

#screen_5 .cal_img_box {
    width: 76px;
    margin: 0 auto 14px;
    padding: 0;
    border: 0;
}

#screen_5 .cal_img_box img {
    width: 76px;
    height: 90px;
    object-fit: cover;
}

.agent_name {
    display: block;
    font-size: 15.5px;
    font-weight: 700;
    color: var(--wp--preset--color--dark);
}

.agent_phone {
    display: block;
    margin: 10px 0 4px;
    font-size: 14px;
    font-weight: 500;
    color: var(--wp--preset--color--purple);
}

.agent_phone::before {
    content: 'Tel. ';
    font-weight: 400;
    color: var(--wp--preset--color--muted);
}

.brikk-funnel-agent-email {
    font-size: 14px;
    color: var(--wp--preset--color--muted);
}

.brikk-funnel-agent-email .agent_email {
    font-weight: 500;
    color: var(--wp--preset--color--purple);
}

.funnel_contact_anytime {
    font-size: 13px;
    line-height: 1.5;
    color: var(--wp--preset--color--muted);
}

/* The comp runs the name in the same weight as the sentence. */
.funnel_contact_anytime .aggent_first_name {
    font-weight: 400;
    color: inherit;
}

.thanks_left .funnel_contact_anytime {
    margin-top: 16px;
}

/* JS reveals .tr_respons blocks by toggling .tr_show. */
.tr_respons {
    display: none;
}

.tr_respons.tr_show {
    display: block;
}

/* --- Mobile ---------------------------------------------------------------- */

@media (max-width: 1024.98px) {
    /* The mobile comp shows no step bar on the confirmation page. */
    .thankyou-page .funnel-steps {
        display: none;
    }

    .thanks_ctn {
        grid-template-columns: 1fr;
        gap: 16px;
        margin-top: 26px;
    }

    .thanks_left,
    .thanks_right {
        padding: 22px 20px;
    }

    .brikk-funnel-booked-slot {
        font-size: 24px;
    }

    .brikk-funnel-booked-slot-time {
        display: inline;
    }

    /* Expert card flips horizontal: photo left, text right. */
    .thanks_left {
        display: grid;
        grid-template-columns: 64px 1fr;
        column-gap: 16px;
        align-items: start;
        text-align: left;
    }

    #screen_5 .cal_img_box {
        grid-column: 1;
        grid-row: 1 / span 4;
        width: 64px;
        margin: 0;
    }

    #screen_5 .cal_img_box img {
        width: 64px;
        height: 80px;
    }

    .funnel_agent_intro,
    .agent_name,
    .agent_phone,
    .brikk-funnel-agent-email {
        grid-column: 2;
    }

    .funnel_agent_intro {
        margin-bottom: 4px;
    }

    .agent_phone {
        margin: 6px 0 2px;
    }

    /* The "kontakt når som helst" line moves below the cards. */
    .brikk-funnel-only-mobile.funnel_contact_anytime {
        margin-top: 18px;
        text-align: center;
    }
}

/* --- 10.9 Error popup ------------------------------------------------------ */
/* Hidden until the funnel JS calls .show() on it. */

#error_popup {
    display: none;
    position: fixed;
    inset: 0;
    background: var(--wp--custom--scrim);
    z-index: var(--wp--custom--z-modal);
}

.error_inner {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: calc(100% - 40px);
    max-width: 440px;
    padding: 36px 32px;
    background: var(--wp--preset--color--card);
    text-align: center;
}

.error_inner h2 {
    margin-bottom: 20px;
    font-size: 24px;
}
