﻿/* ==========================================================================
   F.A.M.E Fitness - DNN Theme
   Ported from the FameFitness.Portal (ASP.NET Core) design system:
   wwwroot/scss/base/_variables.scss, _mixins.scss, _page.scss
   wwwroot/scss/components/_navbar.scss, _buttons.scss, _footer.scss, _form.scss
   wwwroot/scss/layout/_home.scss
   Kleuren geverifieerd tegen https://famefitness.nl
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Fonts (Urbanist)
   Eén familie met echte gewichten, in WOFF2. Daardoor werkt font-weight
   overal zoals bedoeld en is de payload ~88KB in plaats van ~780KB TTF.
   -------------------------------------------------------------------------- */
@font-face {
    font-family: 'Urbanist';
    src: url('fonts/Urbanist-Regular.woff2') format('woff2');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Urbanist';
    src: url('fonts/Urbanist-Italic.woff2') format('woff2');
    font-weight: 400;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: 'Urbanist';
    src: url('fonts/Urbanist-SemiBold.woff2') format('woff2');
    font-weight: 600;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Urbanist';
    src: url('fonts/Urbanist-ExtraBold.woff2') format('woff2');
    font-weight: 800;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Urbanist';
    src: url('fonts/Urbanist-Black.woff2') format('woff2');
    font-weight: 900;
    font-style: normal;
    font-display: swap;
}

/* Compatibiliteit: de oude familienamen blijven werken voor bestaande
   module-inhoud. Een browser haalt een face pas op als hij gebruikt wordt,
   dus deze regels kosten niets zolang niemand ze aanroept. */
@font-face { font-family: 'urbanist-regular';   src: url('fonts/Urbanist-Regular.woff2') format('woff2');   font-display: swap; }
@font-face { font-family: 'urbanist-italic';    src: url('fonts/Urbanist-Italic.woff2') format('woff2');    font-display: swap; }
@font-face { font-family: 'urbanist-semibold';  src: url('fonts/Urbanist-SemiBold.woff2') format('woff2');  font-display: swap; }
@font-face { font-family: 'urbanist-extrabold'; src: url('fonts/Urbanist-ExtraBold.woff2') format('woff2'); font-display: swap; }
@font-face { font-family: 'urbanist-black';     src: url('fonts/Urbanist-Black.woff2') format('woff2');     font-display: swap; }

/* --------------------------------------------------------------------------
   2. Design tokens
   Kleuren ongewijzigd overgenomen uit _variables.scss en geverifieerd tegen
   famefitness.nl. Typografie, ruimte en randen zijn opnieuw gezet.
   -------------------------------------------------------------------------- */
:root {
    /* Kleur - onveranderd */
    --ff-primary: #25c0ff;
    --ff-primary-dark: #0099d8; /* darken($primary, 15%) - knopkleur */
    /* Wit op #0099d8 haalt 3.21:1. Dat is genoeg voor grote vette knoptekst
       (drempel 3:1), maar niet voor kleine tekst op een gevuld vlak. Dit is
       het lichtste blauw uit dezelfde reeks dat wel 4.5:1 haalt. */
    --ff-primary-deep: #007eb4;
    --ff-primary-hover: #00abf1; /* darken($primary, 7.5%) */
    --ff-black: #000;
    --ff-harmony: #0d0d0d; /* kaart-/tegelvlak */
    --ff-white: #fff;
    --ff-gray: #dbdcde;
    --ff-gray-100: #dedede;
    --ff-text: #696969;
    --ff-muted: rgba(0,0,0,.5);
    --ff-summer-green: #7acf1c;
    --ff-carrot-orange: #f29200;
    --ff-autumn-red: #c73535;

    /* Nieuw: gedempte tekst op donker, en de hairline die tegels
       losmaakt van de zwarte achtergrond. */
    --ff-on-dark-muted: #a7adb4;
    --ff-hairline: rgba(255,255,255,.08);
    --ff-hairline-strong: rgba(255,255,255,.16);

    /* Meldingen: donkere tekst op de signaalkleuren, zodat ze leesbaar zijn */
    --ff-on-signal: #10230a;

    --ff-radius: .25rem;
    --ff-radius-md: .5rem;
    --ff-radius-lg: 16px;
    --ff-radius-xl: 45px;
    --ff-nav-height: 80px;
    /* Hoogte van de ledenbalk. Staat op 0 zolang er niemand is ingelogd; de
       regel bij .member-bar hieronder zet hem op 44px zodra die balk in de
       pagina staat. Alles wat onder de vaste balken door moet - de inhoud, de
       hero, het uitschuifmenu, scroll-padding - rekent met --ff-chrome-height,
       zodat er maar een plek is waar die twee hoogtes bij elkaar komen. */
    --ff-member-bar-height: 0px;
    --ff-chrome-height: calc(var(--ff-nav-height) + var(--ff-member-bar-height));
    --ff-maxwidth: 1440px;

    /* Typografie ------------------------------------------------------------
       Basis 17px op mobiel, 18px vanaf tablet. De koppen volgen een
       ratio van ~1.22, zodat h2, h3 en h4 duidelijk van elkaar verschillen. */
    --ff-font-body: 'Urbanist', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
    --ff-font-heading: var(--ff-font-body);
    --ff-font-button: var(--ff-font-body);
    --ff-weight-body: 400;
    --ff-weight-medium: 600;
    --ff-weight-heading: 800;
    --ff-weight-button: 900;

    --ff-leading-tight: 1.15;
    --ff-leading-heading: 1.18;
    --ff-leading-body: 1.65;

    --ff-text-sm: clamp(.875rem, .84rem + .16vw, .95rem);
    --ff-text-base: clamp(1rem, .96rem + .2vw, 1.125rem);
    --ff-text-lead: clamp(1.125rem, 1.05rem + .35vw, 1.3rem);
    --ff-h6: clamp(1.05rem, 1rem + .25vw, 1.2rem);
    --ff-h5: clamp(1.2rem, 1.1rem + .45vw, 1.45rem);
    --ff-h4: clamp(1.4rem, 1.24rem + .72vw, 1.8rem);
    --ff-h3: clamp(1.65rem, 1.4rem + 1.12vw, 2.25rem);
    --ff-h2: clamp(1.95rem, 1.56rem + 1.75vw, 2.9rem);
    --ff-h1: clamp(2.3rem, 1.75rem + 2.45vw, 3.6rem);
    --ff-h1-hero: clamp(2.5rem, 1.7rem + 3.6vw, 4.25rem);

    /* Ruimte ----------------------------------------------------------------
       De sectieritmiek schaalt vloeiend in plaats van in vier harde stappen
       van 60 naar 150px. */
    --ff-space-2xs: .25rem;
    --ff-space-xs: .5rem;
    --ff-space-sm: .75rem;
    --ff-space-md: 1rem;
    --ff-space-lg: 1.5rem;
    --ff-space-xl: 2rem;
    --ff-space-2xl: 3rem;
    --ff-section-y: clamp(3.5rem, 2.2rem + 5.4vw, 6.5rem);
    --ff-gutter: clamp(1rem, .7rem + 1.2vw, 1.5rem);

    /* Beweging - één curve voor het hele thema */
    --ff-ease: cubic-bezier(.22, .61, .36, 1);
    --ff-dur: .28s;
    --ff-dur-slow: .5s;
    --ff-trans: all .5s ease-in-out;

    /* Diepte */
    --ff-shadow-sm: 0 1px 2px rgba(0,0,0,.4);
    --ff-shadow-md: 0 6px 20px rgba(0,0,0,.45);
    --ff-shadow-lg: 0 16px 40px rgba(0,0,0,.55);
    --ff-glow: 0 0 0 1px rgba(37,192,255,.35), 0 12px 32px rgba(37,192,255,.14);
}

/* --------------------------------------------------------------------------
   3. Basis / page
   -------------------------------------------------------------------------- */
html {
    overflow-y: auto;
    scroll-behavior: smooth;
    height: 100%;
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

body {
    margin: 0;
    padding: 0;
    min-height: 100%;
    background-color: var(--ff-black);
    color: var(--ff-white);
    font-family: var(--ff-font-body);
    font-weight: var(--ff-weight-body);
    font-size: var(--ff-text-base);
    line-height: var(--ff-leading-body);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
}

/* Op zeer brede schermen groeit alleen de basis mee, niet de regelafstand */
@media (min-width: 120em) {
    body { font-size: 1.2rem; }
}

/* Bladeren op slot terwijl het uitschuifmenu of het cookievenster openstaat.
   overflow:hidden alleen houdt Safari op iOS niet tegen; position:fixed wel.
   fame.js bewaart hoe ver de pagina stond en zet die stand in top, zodat het
   niet naar de bovenkant springt en bij het sluiten weer terugkomt. */
body.stop-scrolling {
    position: fixed;
    left: 0;
    right: 0;
    width: 100%;
    overflow: hidden;
}

.fame-layout {
    display: flex;
    flex-direction: column;
    /* vh telt de adresbalk van een mobiele browser mee, dvh niet: zonder de
       tweede regel springt de voettekst op een telefoon een balk omlaag. */
    min-height: 100vh;
    min-height: 100dvh;
}

/* De navigatiebalk is fixed; de inhoud schuift er standaard onderdoor vandaan.
   Een hero heft dit weer op met een negatieve marge, zodat de achtergrond
   wel onder de balk doorloopt - net als op famefitness.nl. */
.fame-layout > .content {
    flex: 1 0 auto;
    padding-top: var(--ff-chrome-height);
}

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

/* Vertel de browser dat dit een donkere pagina is. Schuifbalken, keuzelijsten,
   datumkiezers en het invulgeel van een wachtwoordmanager komen dan in het
   donker terug in plaats van als een wit vlak op zwart. De aanmeldschermen
   draaien het weer om, want die zijn met opzet licht. */
:root {
    color-scheme: dark;
    accent-color: var(--ff-primary);
}

.fame-light { color-scheme: light; }

/* Terugzetten wat default.css van DNN weghaalt.
   Die stylesheet opent met een reset die marge en padding van vrijwel elk
   element afhaalt, en staat op elke DNN-pagina vóór skin.css.
   Documentation/Preview.html laadt hem niet, dus daar golden de
   browserwaarden nog: de preview toonde lucht rond lijsten en citaten die de
   site niet had. Alles hieronder staat op elementniveau (specificiteit 0,0,1),
   zodat elke themaregel met een klasse er nog steeds overheen gaat en de
   preview zelf niet verandert. */
ul, ol, dl, blockquote, figure, pre { margin-block: 1em; }
:is(ul, ol) :is(ul, ol) { margin-block: 0; }
ul, ol { padding-inline-start: 40px; }
blockquote, figure { margin-inline: 40px; }
dd { margin-inline-start: 40px; }

img {
    max-width: 100%;
    height: auto;
    /* DNN zet middle, de browser baseline. Zonder eigen waarde stond een
       afbeelding op de site een paar pixels anders dan in de preview; middle
       haalt bovendien de witruimte onder een inline afbeelding weg. */
    vertical-align: middle;
}

hr {
    margin-top: .5rem;
    margin-bottom: .7rem;
    border: 0;
    border-top: 1px solid var(--ff-primary);
}

/* --------------------------------------------------------------------------
   4. Typografie
   -------------------------------------------------------------------------- */
/* Koppen: één ratio van ~1.22, zodat elk niveau zichtbaar verschilt van
   het volgende. Het gewicht komt nu uit een echte ExtraBold-snede. */
.fame h1, .fame h2, .fame h3, .fame h4, .fame h5, .fame h6,
.fame .h1, .fame .h2, .fame .h3, .fame .h4, .fame .h5, .fame .h6 {
    font-family: var(--ff-font-heading);
    font-weight: var(--ff-weight-heading);
    line-height: var(--ff-leading-heading);
    letter-spacing: -.015em;
    color: var(--ff-white);
    margin-top: 0;
    margin-bottom: var(--ff-space-sm);
    text-wrap: balance;
    overflow-wrap: break-word;
}

.fame h1, .fame .h1 { font-size: var(--ff-h1); line-height: var(--ff-leading-tight); letter-spacing: -.025em; }
.fame h2, .fame .h2 { font-size: var(--ff-h2); letter-spacing: -.02em; }
.fame h3, .fame .h3 { font-size: var(--ff-h3); }
.fame h4, .fame .h4 { font-size: var(--ff-h4); letter-spacing: -.01em; }
.fame h5, .fame .h5 { font-size: var(--ff-h5); letter-spacing: -.005em; }
.fame h6, .fame .h6 { font-size: var(--ff-h6); letter-spacing: 0; }

/* Een kop die op een alinea volgt heeft lucht nodig, de eerste kop niet */
.fame * + h2, .fame * + h3, .fame * + h4 { margin-top: var(--ff-space-xl); }
.fame h2 + h3, .fame h3 + h4, .fame h4 + h5 { margin-top: var(--ff-space-sm); }

.fame p {
    line-height: var(--ff-leading-body);
    margin-top: 0;
    margin-bottom: var(--ff-space-md);
    color: var(--ff-white);
    text-wrap: pretty;
}

.fame p:last-child { margin-bottom: 0; }

/* Introalinea onder een sectiekop */
.fame .lead {
    font-size: var(--ff-text-lead);
    color: var(--ff-on-dark-muted);
    max-width: 60ch;
}

.fame a {
    color: var(--ff-white);
    text-decoration: none;
    transition: color var(--ff-dur) var(--ff-ease);
}

.fame a:hover { color: var(--ff-primary); }

/* Toetsenbordfocus: één ring, overal zichtbaar, ook op de zwarte
   achtergrond. :focus-visible raakt alleen toetsenbordgebruikers, dus de
   muisklik blijft schoon. */
.fame :focus-visible,
.fame-light :focus-visible,
.fame-popup :focus-visible {
    outline: 3px solid var(--ff-primary);
    outline-offset: 3px;
    border-radius: var(--ff-radius);
}

/* Op een lichte kaart of witte knop is de primaire kleur te licht */
.card-default :focus-visible,
.fame-light .fame-panel :focus-visible {
    outline-color: var(--ff-primary-dark);
}

/* Direct-naar-inhoud-link: onzichtbaar tot hij focus krijgt */
.skip-link {
    position: absolute;
    left: 50%;
    top: 0;
    transform: translate(-50%, -120%);
    z-index: 200;
    padding: .75rem 1.25rem;
    background-color: var(--ff-primary-deep);
    color: var(--ff-white);
    font-family: var(--ff-font-button);
    font-weight: var(--ff-weight-button);
    border-radius: 0 0 var(--ff-radius) var(--ff-radius);
    text-decoration: none;
    transition: transform var(--ff-dur) var(--ff-ease);
}

.skip-link:focus { transform: translate(-50%, 0); }

.fame strong { color: var(--ff-white); }

.fame .text-primary { color: var(--ff-primary); }
.fame .text-center { text-align: center; }
.fame .text-right { text-align: right; }
.fame .mx-auto { margin-left: auto; margin-right: auto; }
.fame .text--max-width { max-width: 33.75em; margin: 0 auto; }
.fame .active { color: var(--ff-white); }

/* check-list uit _page.scss */
.fame ul.list {
    position: relative;
    list-style: none;
    margin-left: 0;
    padding: 2rem 0 2rem 2em;
}

.fame ul.list li {
    position: relative;
    color: var(--ff-white);
    list-style: none;
}

.fame ul.list li::before {
    content: url('img/check.svg');
    top: 5px;
    position: absolute;
    left: -2em;
}

.fame .list-unstyled {
    list-style: none;
    padding-left: 0;
    color: var(--ff-white);
}

/* --------------------------------------------------------------------------
   5. Secties
   -------------------------------------------------------------------------- */
/* De sectieritmiek schaalt vloeiend mee met het scherm in plaats van in
   vier harde stappen. Zie --ff-section-y in de tokens.

   Ritme aan één kant. Elke sectie zet alleen ruimte bóven zich; de afsluiting
   onderaan de pagina komt van main.content. Dat scheelt de hele reeks
   "+ .page-section { padding-top: 0 }"-uitzonderingen die hier stond en die
   in DNN toch niet aansloeg: DNN zet om elke module een .DnnModule-div, dus
   twee page-sections in dezelfde pane zijn nooit elkaars buren. Gevolg was
   dubbele ruimte tussen secties en géén ruimte tussen modules zonder Fame-
   container. Zo blijft de afstand overal precies één --ff-section-y, ook als
   een sectie ertussenuit valt. */
.page-section {
    background-color: var(--ff-black);
    padding-top: var(--ff-section-y);
    padding-bottom: 0;
}

/* Een module zonder Fame-container (of met Blank.ascx) brengt zelf geen
   sectieritme mee en plakte daardoor tegen de vorige sectie aan. */
.section-pane > .DnnModule:not(:has(.page-section)) { padding-top: var(--ff-section-y); }

/* De onderkant van de laatste sectie tegen de footer aan. */
.fame-layout > .content { padding-bottom: var(--ff-section-y); }

.page-section h2 {
    margin-top: 0;
    margin-bottom: var(--ff-space-md);
}

/* Alleen een expliciet gemarkeerde intro krijgt de grote maat; een <strong>
   midden in een zin blijft gewoon een <strong>. */
.page-section .section-title strong,
.page-section .lead strong,
.page-section strong.underline {
    font-size: var(--ff-text-lead);
    font-weight: var(--ff-weight-heading);
}

/* Skin-secties zijn statische opmaak in de .ascx: staan alle panes erin leeg,
   dan blijft er anders een zwarte band over waar niets in staat. In de
   bewerkmodus blijven ze zichtbaar, anders valt er niets in te slepen. */
.fame .content > .page-section:has(.container .row > .DNNEmptyPane):not(:has(.container .row > :not(.DNNEmptyPane))),
.fame .content > .page-section.is-empty,
.fame .section-pane > .DnnModule.is-empty { display: none; }

.dnnEditState .fame .content > .page-section,
.dnnEditState .fame .section-pane > .DnnModule.is-empty { display: block; }

/* Een sectie direct onder de paginakop hoeft er niet nog eens 100px bij */
.inner-header + .page-section,
.inner-header + .hero-pane:empty + .page-section,
.inner-header + .hero-pane.DNNEmptyPane + .page-section { padding-top: var(--ff-space-2xl); }

/* Dezelfde ingetogen aanloop bij FullWidth. Daar is de eerste buur van de
   paginakop geen <section> uit de skin maar een pane, met daarin de lagen
   die DNN en de Fame-container eromheen zetten. Drie gevallen: een module
   zonder sectie (Blank), de Section-container zelf, en een module die de
   sectie in de inhoud meebrengt. */
.inner-header + .notice-pane + .section-pane > .DnnModule:not(:has(.page-section)),
.inner-header + .notice-pane + .section-pane > .DnnModule > .page-section,
.inner-header + .notice-pane + .section-pane > .DnnModule .Normal > .page-section { padding-top: var(--ff-space-2xl); }

.section-title {
    display: flex;
    flex-direction: column;
    margin-bottom: var(--ff-space-xl);
    justify-content: center;
    align-items: center;
    text-align: center;
    gap: var(--ff-space-xs);
}

/* Fijn accentstreepje onder de sectiekop, in de primaire kleur - hetzelfde
   motief als de streep onder .card__title, nu ook op sectieniveau. */
.section-title > h1::after,
.section-title > h2::after,
.section-title > h3::after {
    content: '';
    display: block;
    width: 64px;
    height: 3px;
    margin: var(--ff-space-md) auto 0;
    border-radius: 3px;
    background-color: var(--ff-primary);
}

.section-title h1, .section-title h2, .section-title h3,
.section-title h4, .section-title h5 {
    text-align: center;
    font-weight: 700;
    margin-top: 0;
    margin-bottom: 0;
}

.section-title p { text-align: center; }
.section-title span { margin-left: auto; }

.page-title {
    display: flex;
    flex-direction: column;
    margin-bottom: var(--ff-space-md);
    justify-content: left;
}

.page-title h1, .page-title h2, .page-title h3,
.page-title h4, .page-title h5 {
    text-align: left;
    font-weight: 700;
}

.page-title p { text-align: left; }
.page-title span { margin-left: auto; }

.page-bottom {
    display: flex;
    justify-content: center;
}

/* Hero (uit layout/_home.scss)
   De achtergrondfoto komt van de redacteur, dus de leesbaarheid van de tekst
   mag er niet van afhangen: een verloop van links donker naar rechts open
   houdt de kop leesbaar zonder de foto plat te drukken. */
.hero-image {
    margin-top: calc(-1 * var(--ff-chrome-height));
    padding-top: var(--ff-chrome-height);
    min-height: max(520px, 80vh);
    background-color: var(--ff-black);
    background-size: cover;
    background-position: center;
    position: relative;
    overflow: hidden;
    isolation: isolate;
}

.hero-image::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background:
        linear-gradient(180deg, rgba(0,0,0,.75) 0%, rgba(0,0,0,0) 28%),
        linear-gradient(90deg, rgba(0,0,0,.88) 0%, rgba(0,0,0,.62) 38%, rgba(0,0,0,.15) 72%, rgba(0,0,0,0) 100%);
}

/* Zachte overgang naar de eerste zwarte sectie eronder */
.hero-image::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 120px;
    z-index: 0;
    pointer-events: none;
    background: linear-gradient(180deg, rgba(0,0,0,0) 0%, var(--ff-black) 100%);
}

/* De Home-skin zet de heropmaak zelf om de HeroPane heen, zodat het niet
   uitmaakt welke container aan de module hangt. Hangt de redacteur er tóch
   de Hero-container aan, dan zit er een .hero-image in een .hero-image;
   de binnenste wordt dan een gewone doorgeefluik zonder eigen hoogte,
   verloop of watermerk. Hetzelfde geldt in de paginakop van FullWidth: daar
   hoort de titel in de zwarte balk te staan, niet in een scherm hoge hero. */
:is(.hero-image, .inner-header) .hero-image {
    margin-top: 0;
    padding-top: 0;
    min-height: 0;
    overflow: visible;
    isolation: auto;
    background: none;
}

:is(.hero-image, .inner-header) .hero-image::before,
:is(.hero-image, .inner-header) .hero-image::after { content: none; }
:is(.hero-image, .inner-header) .hero-image > .container { padding: 0; max-width: none; }
:is(.hero-image, .inner-header) .hero-image .wrap-text { min-height: 0; display: block; }
:is(.hero-image, .inner-header) .hero-image .unstoppable,
:is(.hero-image, .inner-header) .hero-image #unstoppable { display: none; }

/* In de paginakop is de tekst geen hero maar een paginatitel: geen tekstschaduw
   over een foto die er niet is, geen hero-maat en geen kolom van 34rem. */
.inner-header .hero-image .hero-text {
    max-width: none;
    padding: 0;
}

.inner-header .hero-image .hero-text h1 {
    font-size: var(--ff-h1);
    letter-spacing: -.025em;
    margin-bottom: var(--ff-space-sm);
    text-shadow: none;
}

.inner-header .hero-image .hero-text p {
    font-size: inherit;
    max-width: none;
    text-shadow: none;
}

.inner-header .hero-image .btn { max-width: none; }

/* Een lege HeroPane mag geen scherm hoog zwart vlak achterlaten. DNN zet
   DNNEmptyPane op elke pane waar geen module in zit; daar sturen we op,
   en niet op "bevat geen .DnnModule" - dat zou de offline preview in
   Documentation/Preview.html ook wegpoetsen. */
.hero-section:has(.hero-pane.DNNEmptyPane) { display: none; }
.dnnEditState .hero-section { display: block; }

/* Zet de foto op de pane of op de sectie zelf. Beide werken:
   <div id="HeroPane" style="--ff-hero-image:url(/Portals/0/hero.jpg)"> */
.hero-pane[style*="--ff-hero-image"] .hero-image,
.hero-image[style*="--ff-hero-image"] { background-image: var(--ff-hero-image); }

/* Sinds de heropmaak in de skin staat, kan een redacteur er niet meer van
   buitenaf een CSS-variabele op zetten. De foto mag daarom ook uit de
   module-inhoud komen:
     <img class="hero-bg" src="/Portals/0/hero.jpg" alt="" />
     <div class="hero-bg" style="background-image:url(/Portals/0/hero.jpg)"></div>
   Hij loopt van rand tot rand en tot onder de navigatiebalk door. */
.hero-image .hero-bg {
    position: absolute;
    top: calc(-1 * var(--ff-chrome-height));
    bottom: 0;
    left: 50%;
    width: 100vw;
    max-width: none;
    height: auto;
    margin: 0;
    transform: translateX(-50%);
    z-index: -2;
    object-fit: cover;
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    pointer-events: none;
}

/* .wrap-text maakt bewust géén eigen stapelcontext (geen z-index): anders
   komen het watermerk en de achtergrondfoto boven het verloop uit en is de
   kop niet meer leesbaar. De tekst tilt zichzelf op met z-index 1. */
.hero-image .wrap-text {
    display: flex;
    align-items: center;
    min-height: calc(max(520px, 80vh) - var(--ff-chrome-height));
    width: 100%;
    max-width: var(--ff-maxwidth);
    margin: auto;
    position: relative;
}

.hero-image .hero-text {
    position: relative;
    z-index: 1;
    max-width: 34rem;
    /* Alleen verticaal. Zijdelings stond hier ook var(--ff-space-md), waardoor
       de hero-kop 16px verder inspringt dan de rest van de pagina: op de
       startpagina begon de h1 op 69px en de voettekst op 53px. De paginakop van
       .inner-header zet die padding al op 0; nu lopen ze allebei gelijk met de
       kolom. */
    padding: var(--ff-space-md) 0;
}

.hero-image .hero-text h1 {
    font-size: var(--ff-h1-hero);
    line-height: var(--ff-leading-tight);
    letter-spacing: -.03em;
    margin-bottom: var(--ff-space-md);
    text-shadow: 0 2px 24px rgba(0,0,0,.5);
}

/* Wit blijft wit, op elk formaat. De vorige regel maakte deze alinea vanaf
   768px grijs, precies waar er een foto achter staat. */
.hero-image .hero-text p {
    color: var(--ff-white);
    font-size: var(--ff-text-lead);
    max-width: 46ch;
    text-shadow: 0 1px 12px rgba(0,0,0,.55);
}

.hero-image .btn { max-width: 225px; }

.hero-image .hero-text .btn + .btn { margin-left: var(--ff-space-sm); }

/* "GET FIT STAY FIT" watermerk - achter de tekst, boven de scrim.
   De klasse is leidend; het id blijft erbij voor pagina's waar een redacteur
   de oude opmaak in de module-inhoud heeft staan. */
.hero-image .unstoppable,
.hero-image #unstoppable {
    z-index: -1;
    position: absolute;
    top: 50%;
    right: 0;
    transform: translateY(-50%) rotate(-90deg);
    opacity: .1;
    min-width: 280px;
    pointer-events: none;
    user-select: none;
}

.hero-image .unstoppable ul,
.hero-image #unstoppable ul { list-style: none; margin: 0; padding: 0; }

.hero-image .unstoppable li,
.hero-image #unstoppable li {
    color: var(--ff-white);
    font-size: 28pt;
    font-family: var(--ff-font-heading);
    font-weight: var(--ff-weight-heading);
    letter-spacing: -.02em;
    white-space: nowrap;
}

@media (min-width: 30em) {
    .hero-image .unstoppable, .hero-image #unstoppable { min-width: 410px; }
    .hero-image .unstoppable li, .hero-image #unstoppable li { font-size: 38pt; }
}
@media (min-width: 48em) {
    .hero-image .unstoppable, .hero-image #unstoppable { right: 10px; }
    .hero-image .unstoppable li, .hero-image #unstoppable li { font-size: 65pt; }
}
@media (min-width: 64em) {
    .hero-image .unstoppable, .hero-image #unstoppable { right: 100px; }
    .hero-image .unstoppable li, .hero-image #unstoppable li { font-size: 75pt; }
}
@media (min-width: 85.375em) {
    .hero-image .unstoppable, .hero-image #unstoppable { right: 200px; }
    .hero-image .unstoppable li, .hero-image #unstoppable li { font-size: 80pt; }
}
@media (min-width: 120em) {
    .hero-image .unstoppable, .hero-image #unstoppable { right: 500px; }
    .hero-image .unstoppable li, .hero-image #unstoppable li { font-size: 90pt; }
}

/* Op een telefoon staat het watermerk anders dwars over de knop heen. */
@media (max-width: 29.99em) {
    .hero-image .unstoppable,
    .hero-image #unstoppable { top: 22%; opacity: .07; }
}

/* Quote-blok. Ook bruikbaar op een <blockquote>: de browser geeft dat element
   standaard 40px marge links en rechts, wat samen met width:100% op een
   telefoon een horizontale schuifbalk oplevert. */
.quote,
.testimonials .item {
    margin-left: 0;
    margin-right: 0;
}

.quote {
    display: flex;
    flex-direction: column;
    justify-content: center;
    background-color: var(--ff-black);
    width: 100%;
}

.quote .text, .quote .author {
    text-align: center;
    color: var(--ff-white);
}

/* --------------------------------------------------------------------------
   6. Navigatie (uit components/_navbar.scss)
   -------------------------------------------------------------------------- */
nav.nav {
    position: fixed;
    left: 0;
    top: var(--ff-member-bar-height);
    z-index: 100;
    width: 100%;
    height: var(--ff-nav-height);
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--ff-black);
    border-bottom: 1px solid transparent;
    transition: background-color var(--ff-dur) var(--ff-ease),
                border-color var(--ff-dur) var(--ff-ease),
                box-shadow var(--ff-dur) var(--ff-ease);
}

/* Bovenaan de pagina loopt de balk over de hero door; zodra je scrolt
   krijgt hij een eigen vlak met een hairline eronder. */
nav.nav.affixed {
    background-color: rgba(0,0,0,.88);
    backdrop-filter: saturate(140%) blur(12px);
    -webkit-backdrop-filter: saturate(140%) blur(12px);
    border-bottom-color: var(--ff-hairline);
    box-shadow: 0 2px 24px rgba(0,0,0,.6);
}

@supports not (backdrop-filter: blur(1px)) {
    nav.nav.affixed { background-color: rgba(0,0,0,.96); }
}

.menu {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
    padding: 0 15px;
    max-width: var(--ff-maxwidth);
}

/* De balk moet dezelfde kolom aanhouden als de inhoud en de voettekst, anders
   staat het logo niet boven de paginatitel. .container uit grid.css schakelt in
   stappen (540/720/960/1140/1440) terwijl .menu vloeiend was tot 1440: daardoor
   liepen ze alleen onder 576px en boven 1400px gelijk, en zat het logo er
   daartussen tot 38px naast. Zelfde breekpunten, zelfde padding van 15px, dus
   nu delen kop, inhoud en voet een kolom op elke breedte.
   De donkere balk zelf blijft schermbreed: die achtergrond zit op nav.nav. */
@media (min-width: 576px) { .menu { max-width: 540px; } }
@media (min-width: 768px) { .menu { max-width: 720px; } }
@media (min-width: 992px) { .menu { max-width: 960px; } }
@media (min-width: 1200px) { .menu { max-width: 1140px; } }
@media (min-width: 1400px) { .menu { max-width: var(--ff-maxwidth); } }

.menu .menu-item { display: flex; align-items: center; }

/* Het woordmerk en het beeldmerk zitten in een enkele link */
.menu .brand {
    display: flex;
    align-items: center;
    min-height: 44px;
}

.menu #beeldmerk { width: 50px; height: auto; }

/* 184px is de werkelijke breedte van het bestand; op 200px werd het
   opgeschaald en dus zachter. */
.menu #logo {
    width: 184px;
    height: auto;
    padding-left: 1rem;
    display: none;
}

@media (min-width: 768px) {
    .menu #logo { display: block; }
}

.navbar { display: flex; align-items: center; }

.navbar .nav-items {
    list-style-type: none;
    display: none;
    margin: 0;
    padding: 0;
    align-items: center;
}

.navbar .nav-items > li { list-style: none; }

.navbar .nav-items > li:not(:last-child) > a { margin-right: 28px; }

.navbar .nav-items a {
    color: var(--ff-white);
    text-decoration: none;
    font-weight: var(--ff-weight-medium);
    font-size: var(--ff-text-sm);
    letter-spacing: .01em;
    position: relative;
}

.navbar .nav-items a:hover,
.navbar .nav-items a.active { color: var(--ff-primary); }

/* Een uitgeschakelde menupagina was een <a href="#">: een focusbare link die
   naar de bovenkant sprong. Nu een <span>, dus geen doodlopende link meer. */
.navbar .nav-items .nav-disabled,
.main-menu .nav-disabled,
footer.fame-footer .nav-disabled {
    color: var(--ff-on-dark-muted);
    cursor: default;
}

/* Fijne onderstreping bij de actieve pagina, in plaats van alleen kleur */
.navbar .nav-items > li > a:not(.btn)::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 6px;
    height: 2px;
    border-radius: 2px;
    background-color: var(--ff-primary);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--ff-dur) var(--ff-ease);
}

.navbar .nav-items > li > a:not(.btn):hover::after,
.navbar .nav-items > li > a:not(.btn).active::after { transform: scaleX(1); }

/* De contactpagina is de call to action en hoort als knop in de balk te staan.
   Vroeger kwam die klasse uit het veld "CSS Class Name" bij de pagina-instel-
   lingen, via het token [=CSSCLASS] in FameNav.txt. DNN 10 heeft dat veld niet
   meer: TabInfo kent geen CssClass, de Pages-API van de Persona Bar heeft er
   geen veld voor, en in DotNetNuke.Web.DDRMenu.dll komt de naam niet eens meer
   voor. Het token blijft dus altijd leeg.

   Vandaar deze url-selector. Krijgt de contactpagina een andere naam, dan valt
   de knop terug op een gewone menulink: zichtbaar anders, maar niet stuk. Het
   schuifmenu (FameSideMenu) doet hier niet aan mee; daar staan de items al
   onder elkaar en heeft een knop geen functie. */
.navbar .nav-items > li > a[href$="/Contact"]::after { content: none; }

.navbar .nav-items .btn,
.navbar .nav-items > li > a[href$="/Contact"] {
    white-space: nowrap;
    min-height: 44px;
    padding: .5rem 1.25rem;
    /* Blijft klein in de balk, dus hier het blauw dat ook bij kleine tekst
       4.5:1 haalt. */
    background-color: var(--ff-primary-deep);
    font-size: var(--ff-text-sm);
}

.navbar .nav-items .btn:hover,
.navbar .nav-items > li > a[href$="/Contact"]:hover {
    background-color: var(--ff-primary-dark);
    color: var(--ff-white);
}

/* Hamburger - is nu een echte <button>, dus de browserstijl gaat eraf */
.menuToggle {
    background: var(--ff-harmony);
    border: 1px solid var(--ff-hairline);
    height: 48px;
    padding: 10px;
    display: flex;
    justify-content: center;
    align-items: center;
    border-radius: var(--ff-radius-lg);
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
    position: relative;
    z-index: 2;
    transition: border-color var(--ff-dur) var(--ff-ease);
}

.menuToggle:hover { border-color: var(--ff-hairline-strong); }

.nav-icon {
    width: 30px;
    height: 24px;
    position: relative;
    background-color: transparent;
    transform: rotate(0deg);
    transition: .5s ease-in-out;
    cursor: pointer;
}

.nav-icon span {
    display: block;
    position: absolute;
    height: 4px;
    width: 100%;
    background-color: var(--ff-primary);
    opacity: 1;
    left: 0;
    transform: rotate(0deg);
    transition: .25s ease-in-out;
    border-radius: 5px;
}

.nav-icon span:nth-child(1) { top: 0; }
.nav-icon span:nth-child(2), .nav-icon span:nth-child(3) { top: 10px; }
.nav-icon span:nth-child(4) { top: 20px; }

.menuToggle[aria-expanded="true"] .nav-icon span:nth-child(1),
.menuToggle[aria-expanded="true"] .nav-icon span:nth-child(4) {
    top: 18px;
    width: 0;
    left: 50%;
}

.menuToggle[aria-expanded="true"] .nav-icon span:nth-child(2) { transform: rotate(45deg); }
.menuToggle[aria-expanded="true"] .nav-icon span:nth-child(3) { transform: rotate(-45deg); }

/* Waas achter het uitschuifmenu.
   Het paneel schoof eerder over een pagina die gewoon zichtbaar bleef: twee
   lagen tekst door elkaar, en niets dat liet zien dat de pagina even niet aan
   de beurt is. De waas ligt in de stapelcontext van nav.nav (z-index 100), dus
   boven de hele pagina maar onder de balk zelf. Hij vangt ook de tik die het
   menu weer sluit. */
.side-menu-scrim {
    position: absolute;
    left: 0;
    right: 0;
    top: var(--ff-nav-height);
    height: calc(100dvh - var(--ff-chrome-height));
    background-color: rgba(0,0,0,.66);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--ff-dur-slow) var(--ff-ease),
                visibility 0s linear var(--ff-dur-slow);
}

.side-menu-scrim[data-open="true"] {
    opacity: 1;
    visibility: visible;
    transition: opacity var(--ff-dur-slow) var(--ff-ease), visibility 0s;
}

/* Uitschuifmenu
   Het paneel stond buiten beeld geparkeerd maar bleef bereikbaar met Tab,
   terwijl aria-hidden="true" erop stond. visibility haalt het nu echt uit
   de tabvolgorde en uit de toegankelijkheidsboom.

   Het schuift met transform in plaats van met right: -100%. Dat scheelt niet
   alleen een herberekening van de opmaak bij elke stap van de overgang - het
   paneel stak op right: -100% ook een schermbreedte buiten de rand uit, en dat
   is precies het soort element dat een browser met een horizontale schuifbalk
   beantwoordt.

   Paneel en waas staan op position:absolute en niet op fixed. Ze hangen in
   nav.nav, en die krijgt bij het scrollen backdrop-filter voor het matglas.
   Een filter maakt van dat element het containing block voor alles wat eronder
   fixed staat: het paneel zou dan vanaf de bovenkant van een balk van 80px
   gaan rekenen in plaats van vanaf het venster, en bij de eerste scroll
   omhoog schieten. nav.nav staat zelf al vast, dus absolute levert hetzelfde
   op zonder die val - alleen rekent het vanaf de balk, en dus met
   --ff-nav-height in top en --ff-chrome-height in de hoogte. */
.side-menu-container {
    display: flex;
    flex-direction: column;
    gap: var(--ff-space-lg);
    position: absolute;
    right: 0;
    top: var(--ff-nav-height);
    background-color: var(--ff-black);
    border-left: 1px solid var(--ff-hairline);
    height: calc(100dvh - var(--ff-chrome-height));
    width: 100%;
    max-width: 380px;
    transform: translateX(100%);
    visibility: hidden;
    transition: transform var(--ff-dur-slow) var(--ff-ease),
                visibility 0s linear var(--ff-dur-slow);
    padding: var(--ff-space-lg) var(--ff-gutter)
             max(var(--ff-space-lg), env(safe-area-inset-bottom));
    overflow-y: auto;
    overscroll-behavior: contain;
}

/* Bij het openen krijgt het paneel zelf de focus in plaats van de eerste link.
   Dat scheelt een toetsenbord dat op een telefoon meteen omhoog komt voor het
   zoekveld, maar de omranding eromheen hoort niemand te zien. */
.side-menu-container:focus { outline: none; }

.side-menu-container[data-open="true"] {
    transform: none;
    visibility: visible;
    box-shadow: -9px 2px 24px 0 rgba(37,192,255,.18);
    transition: transform var(--ff-dur-slow) var(--ff-ease), visibility 0s;
}

/* Staat beweging uit, dan mag het paneel ook niet een halve seconde onzichtbaar
   blijven nadat het al dicht is: die vertraging hoort bij de schuifbeweging die
   er dan niet is. Sectie 18 zet alleen de duur op nul, niet de vertraging. */
@media (prefers-reduced-motion: reduce) {
    .side-menu-container,
    .side-menu-scrim,
    .js-submenu .main-submenu > ul { transition-delay: 0s !important; }
}

/* Zoeken staat bovenaan in plaats van onderaan tussen de kleine lettertjes.
   DNN levert hier een kale <input> plus een losse link als knop; zonder deze
   regels is dat een wit vlak op zwart. 1rem is geen smaak maar een eis: onder
   16px zoomt Safari op iOS in zodra je in het veld tikt. */
/* Twee flexrijen en niet een: DNN zet het zoekveld en de knop samen in nog een
   <span> (ClassicSearch). Alleen .searchBox opmaken laat die span als enig
   flexitem over, en dan viel de knop onder het veld. */
.side-menu-search .searchBox,
.side-menu-search .searchBox > span {
    display: flex;
    align-items: center;
    gap: var(--ff-space-xs);
}

.side-menu-search .searchBox > span {
    flex: 1 1 auto;
    min-width: 0;
}

.side-menu-search .searchInputContainer {
    position: relative;
    display: block;
    flex: 1 1 auto;
    min-width: 0;
}

.side-menu-search input[type="text"] {
    width: 100%;
    min-height: 44px;
    padding: .5rem 2rem .5rem .75rem;
    background-color: var(--ff-harmony);
    border: 1px solid var(--ff-hairline-strong);
    border-radius: var(--ff-radius-md);
    color: var(--ff-white);
    font-family: var(--ff-font-body);
    font-size: 1rem;
}

.side-menu-search input[type="text"]::placeholder { color: var(--ff-on-dark-muted); }

.side-menu-search .dnnSearchBoxClearText {
    position: absolute;
    right: .5rem;
    top: 50%;
    transform: translateY(-50%);
}

.side-menu-search .btn {
    flex: 0 0 auto;
    min-height: 44px;
    padding: .5rem 1rem;
    font-size: var(--ff-text-sm);
}

.main-menu {
    align-self: stretch;
    display: block;
    font-size: 1.5rem;
    font-weight: 300;
    line-height: 1;
    list-style: none;
    margin: 0;
    padding: 0;
}

.main-menu li {
    margin-bottom: var(--ff-space-md);
    list-style: none;
    position: relative;
}

.main-menu li a {
    display: flex;
    align-items: center;
    min-height: 48px;
    color: var(--ff-white);
    font-size: clamp(1.5rem, 1.25rem + 1.2vw, 1.9rem);
    font-weight: var(--ff-weight-heading);
    letter-spacing: -.01em;
    position: relative;
    text-decoration: none;
    transition: color var(--ff-dur) var(--ff-ease);
    padding: 2px 0;
}

.main-menu li a.active,
.main-menu li a:hover { color: var(--ff-primary); }

/* Een pagina met onderliggende pagina's is nu ook gewoon een pagina: de link
   gaat erheen en de knop ernaast vouwt de kinderen uit. Eerder stond het
   tweede niveau altijd open - vijf lessen en vier tarieven maakten van het
   menu een lijst waar je doorheen moest scrollen voordat je Contact zag.

   Uitgangspunt is de open lijst zonder knop. Pas als fame.js draait zet het
   .js-submenu op <html> en klapt alles dicht - net als .js-reveal in sectie 19.
   Zo blijft het tweede niveau bereikbaar als het script niet laadt, in plaats
   van dicht te staan met een knop die niemand bedient. */
.js-submenu .main-menu .has-children > a,
.js-submenu .main-menu .has-children > .nav-disabled { padding-right: 3.5rem; }

.submenu-toggle {
    display: none;
    position: absolute;
    top: 0;
    right: 0;
    width: 48px;
    height: 48px;
    align-items: center;
    justify-content: center;
    background-color: transparent;
    border: 1px solid var(--ff-hairline);
    border-radius: var(--ff-radius-md);
    color: var(--ff-white);
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
    transition: border-color var(--ff-dur) var(--ff-ease),
                color var(--ff-dur) var(--ff-ease);
}

.submenu-toggle:hover,
.submenu-toggle[aria-expanded="true"] {
    border-color: var(--ff-hairline-strong);
    color: var(--ff-primary);
}

.submenu-toggle svg {
    width: 14px;
    height: 14px;
    fill: currentColor;
    transition: transform var(--ff-dur) var(--ff-ease);
}

.submenu-toggle[aria-expanded="true"] svg { transform: rotate(180deg); }

/* Tweede niveau in het uitschuifmenu.
   0fr naar 1fr vouwt uit tot precies de eigen hoogte, zonder een max-height te
   moeten raden die bij zes items te krap is en bij twee een trage lege
   overgang oplevert. visibility haalt de dichte lijst uit de tabvolgorde, net
   als bij het paneel zelf. */
.main-submenu {
    display: grid;
    grid-template-rows: 1fr;
    transition: grid-template-rows var(--ff-dur) var(--ff-ease);
}

.main-submenu > ul {
    overflow: hidden;
    min-height: 0;
    list-style: none;
    margin: 0;
    padding: 0 0 0 1rem;
}

.js-submenu .submenu-toggle { display: flex; }

.js-submenu .main-submenu { grid-template-rows: 0fr; }

.js-submenu .main-submenu > ul {
    visibility: hidden;
    transition: visibility 0s linear var(--ff-dur);
}

.js-submenu .main-submenu[data-open="true"] { grid-template-rows: 1fr; }

.js-submenu .main-submenu[data-open="true"] > ul {
    visibility: visible;
    transition: visibility 0s;
}

.main-submenu li { margin-bottom: 0; }

.main-submenu li a {
    font-size: var(--ff-text-base);
    font-weight: var(--ff-weight-medium);
    letter-spacing: 0;
    min-height: 44px;
    color: var(--ff-gray);
}

/* De kleine lettertjes onderin: voorwaarden, privacy en - zolang er niemand is
   ingelogd - inloggen. Stonden rechts uitgelijnd met 6,65rem lucht eronder,
   wat op een telefoon in liggende stand betekende dat je ervoor moest
   scrollen. Nu links, tegen de onderrand, met een lijn ertussen. */
.sub-menu {
    margin: auto 0 0;
    padding-top: var(--ff-space-md);
    border-top: 1px solid var(--ff-hairline);
    list-style: none;
}

.sub-menu li {
    list-style: none;
    color: var(--ff-white);
    font-size: var(--ff-text-sm);
    text-align: left;
}

.sub-menu li a {
    display: inline-flex;
    align-items: center;
    justify-content: flex-start;
    min-height: 44px;
    text-decoration: none;
    color: var(--ff-on-dark-muted);
    text-align: left;
}

.sub-menu li a.active,
.sub-menu li a:hover { color: var(--ff-primary); }

.side-menu-login a {
    color: var(--ff-white);
    font-weight: var(--ff-weight-medium);
}

/* Wie is ingelogd heeft de ledenbalk; dan hoeft "Uitloggen" niet ook nog eens
   onderin het uitschuifmenu en in de voettekst te staan. */
:root:has(.member-bar) .side-menu-login,
:root:has(.member-bar) .footer-login { display: none; }

@media (min-width: 992px) {
    .navbar .nav-items { display: flex; }
    .menuToggle { display: none; }
    .side-menu-container,
    .side-menu-scrim { display: none; }
}

/* Tussen 992 en 1200px is er weinig ruimte naast het logo: kleinere tussenruimte
   en tekst, zodat de balk niet omvalt of horizontaal gaat scrollen. */
@media (min-width: 992px) and (max-width: 1199px) {
    .navbar .nav-items > li:not(:last-child) > a { margin-right: 16px; }
    .navbar .nav-items a { font-size: .9rem; }
    .navbar .nav-items .btn,
    .navbar .nav-items > li > a[href$="/Contact"] { font-size: .9rem; padding: .5rem 1rem; }
    .menu #logo { width: 150px; padding-left: .5rem; }
}

/* Aanraakdoelen minimaal 44px - ook de links die eerder 21 tot 26px waren */
.menuToggle { min-width: 44px; min-height: 44px; }

.side-menu-container a,
.navbar .nav-items a,
.blog-filter a,
.blog-sidebar li a,
.pagination .page-link,
.card__readmore a,
.breadcrumb a,
.infoCard .block a {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
}

.blog-sidebar li a,
.navbar .nav-items .nav-dropdown li a { display: flex; }

/* --------------------------------------------------------------------------
   6b. Ledenbalk

   Inloggen, uitloggen en de naam van wie is ingelogd zaten onderin het
   uitschuifmenu. Dat menu staat vanaf 992px op display:none, dus op een
   laptop was er geen enkele plek waar je zag dat je was ingelogd, laat staan
   waar je weer uit kon. En wie wel bij dat lijstje kwam, vond het account
   tussen de menupagina's - terwijl het over de bezoeker gaat, niet over de
   site.

   De ledenbalk haalt dat uit de navigatie: een eigen strook boven de
   navigatiebalk, alleen aanwezig voor wie is ingelogd. De skins zetten hem
   met <% if (IsAuthenticated) %> in de pagina; staat hij er, dan schuift de
   :has()-regel hieronder de navigatiebalk en alles wat daaronder valt 44px
   omlaag. Eén hoogte, op één plek, in plaats van dezelfde 44px op zeven
   plekken herhalen.
   -------------------------------------------------------------------------- */
:root:has(.member-bar) { --ff-member-bar-height: 44px; }

.member-bar {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 101;
    width: 100%;
    height: var(--ff-member-bar-height);
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--ff-harmony);
    border-bottom: 1px solid var(--ff-hairline);
    font-size: var(--ff-text-sm);
}

/* Dezelfde kolom en dezelfde breekpunten als .menu en .container, zodat de
   naam links en de navigatiebalk eronder dezelfde rand delen. */
.member-bar-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ff-space-md);
    width: 100%;
    max-width: var(--ff-maxwidth);
    padding: 0 15px;
    min-width: 0;
}

@media (min-width: 576px) { .member-bar-inner { max-width: 540px; } }
@media (min-width: 768px) { .member-bar-inner { max-width: 720px; } }
@media (min-width: 992px) { .member-bar-inner { max-width: 960px; } }
@media (min-width: 1200px) { .member-bar-inner { max-width: 1140px; } }
@media (min-width: 1400px) { .member-bar-inner { max-width: var(--ff-maxwidth); } }

.member-bar .member-bar-who {
    display: flex;
    align-items: center;
    gap: var(--ff-space-xs);
    min-width: 0;
    margin: 0;
}

/* Initialen in plaats van een profielfoto: DNN heeft er wel een, maar dan
   staat er voor de meeste accounts een grijze silhouetafbeelding van 32px in
   de balk. Twee letters zeggen op die maat meer. */
.member-avatar {
    flex: 0 0 auto;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background-color: var(--ff-primary-deep);
    color: var(--ff-white);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--ff-font-heading);
    font-size: .7rem;
    font-weight: var(--ff-weight-heading);
    letter-spacing: .02em;
    line-height: 1;
}

.member-greeting { color: var(--ff-on-dark-muted); }

/* Een lange naam moet kunnen afbreken met een beletselteken, en dat werkt
   alleen op een blok - niet op de inline-flex die .member-bar a eronder zet.
   Maar een blok van 44px zet de tekst op de eerste regel, dus bovenin: de naam
   stond 11px hoger dan het rondje ernaast. De regelhoogte gelijk aan de
   balkhoogte zet hem terug op dezelfde lijn. */
.member-bar .member-name {
    color: var(--ff-white);
    font-weight: var(--ff-weight-medium);
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    display: block;
    line-height: var(--ff-member-bar-height);
}

.member-bar-actions {
    display: flex;
    align-items: center;
    gap: var(--ff-space-md);
    list-style: none;
    margin: 0;
    padding: 0;
    flex: 0 0 auto;
}

.member-bar-actions li {
    list-style: none;
    margin: 0;
}

.member-bar a {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    min-height: 44px;
    color: var(--ff-on-dark-muted);
    text-decoration: none;
    white-space: nowrap;
}

.member-bar a:hover,
.member-bar a:focus-visible { color: var(--ff-primary); }

.member-bar svg {
    width: 15px;
    height: 15px;
    fill: currentColor;
    flex: 0 0 auto;
}

.member-bar .member-logout { color: var(--ff-white); }
.member-bar .member-logout:hover { color: var(--ff-primary); }

/* Op een telefoon is 44px hoogte krap voor vier stukjes tekst. De begroeting
   valt als eerste weg, daarna de losse profiellink - de naam zelf gaat naar
   diezelfde pagina, dus die link is dan dubbelop. Uitloggen blijft altijd
   staan; dat is het enige dat je hier echt moet kunnen. */
@media (max-width: 575px) {
    .member-greeting { display: none; }
    .member-bar-actions { gap: var(--ff-space-sm); }
}

@media (max-width: 420px) {
    .member-bar-actions .member-profile { display: none; }
    .member-bar .member-logout span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}

/* --------------------------------------------------------------------------
   7. Knoppen (uit components/_buttons.scss)
   -------------------------------------------------------------------------- */
.btn,
.btn-primary,
.btn-sec,
.btn-default,
.btn-save,
.btn-delete,
.btn-danger,
/* De contactknop in de balk. Zie sectie 6 voor waarom dit een url-selector is
   en geen klasse. */
.navbar .nav-items > li > a[href$="/Contact"] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5em;
    border: 2px solid transparent;
    border-radius: var(--ff-radius);
    cursor: pointer;
    padding: .7rem 1.5rem;
    min-height: 48px;
    transition: background-color var(--ff-dur) var(--ff-ease),
                border-color var(--ff-dur) var(--ff-ease),
                color var(--ff-dur) var(--ff-ease),
                transform var(--ff-dur) var(--ff-ease),
                box-shadow var(--ff-dur) var(--ff-ease);
    position: relative;
    font-family: var(--ff-font-button);
    font-weight: var(--ff-weight-button);
    /* Minimaal 18.8px: samen met gewicht 900 telt dit als grote tekst, en
       dan volstaat 3:1 voor wit op de knopkleur. */
    font-size: clamp(1.175rem, 1.12rem + .28vw, 1.3rem);
    letter-spacing: .01em;
    line-height: 1.2;
    color: var(--ff-white);
    text-decoration: none;
    text-align: center;
}

.btn:active,
.btn-primary:active,
.btn-sec:active,
.navbar .nav-items > li > a[href$="/Contact"]:active { transform: translateY(1px); }

.btn-primary {
    background: var(--ff-primary-dark);
    border-color: var(--ff-primary);
    color: var(--ff-white);
}

.btn-primary:hover {
    background: var(--ff-primary-hover);
    border-color: var(--ff-primary);
    color: var(--ff-white);
    box-shadow: var(--ff-glow);
}

.btn-sec {
    background-color: transparent;
    color: var(--ff-white);
    border-color: var(--ff-white);
}

.btn-sec:hover {
    background-color: var(--ff-white);
    color: var(--ff-black);
}

/* Knop met alleen tekst, voor secundaire acties in een kaart of sectie */
.btn-link {
    display: inline-flex;
    align-items: center;
    gap: .4em;
    font-family: var(--ff-font-button);
    font-weight: var(--ff-weight-button);
    color: var(--ff-primary);
    text-decoration: none;
    text-transform: uppercase;
    letter-spacing: .08em;
    font-size: var(--ff-text-sm);
}

.btn-link::after {
    content: '';
    width: .5em;
    height: .5em;
    border-top: 2px solid currentColor;
    border-right: 2px solid currentColor;
    transform: rotate(45deg);
    transition: transform var(--ff-dur) var(--ff-ease);
}

.btn-link:hover::after { transform: rotate(45deg) translate(2px, -2px); }

.btn-default {
    background: transparent;
    color: var(--ff-white);
    border: 2px solid var(--ff-primary);
}

.btn-default:hover { background: var(--ff-primary-dark); border-color: var(--ff-primary); }

.btn-save { background: var(--ff-summer-green); }
.btn-save:hover { background: #6bb518; }

.btn-delete, .btn-danger { background: var(--ff-autumn-red); }
.btn-delete:hover, .btn-danger:hover { background: #b52f2f; }

@media (max-width: 600px) {
    .page-bottom .btn {
        width: 100%;
        max-width: 250px;
        text-align: center;
        margin: 10px auto;
    }
}

/* Ronde pijlknop */
.next {
    cursor: pointer;
    border-radius: 50%;
    background-color: var(--ff-white);
    color: var(--ff-primary);
    background-image: url('img/arrow.svg');
    background-position: center;
    background-repeat: no-repeat;
    background-size: 20px;
    width: 48px;
    height: 48px;
    border: none;
    transition: transform var(--ff-dur) var(--ff-ease);
}

.next:hover { transform: scale(1.06); }

/* --------------------------------------------------------------------------
   8. Tegels / kaarten (uit layout/_home.scss)
   -------------------------------------------------------------------------- */
/* Tegels staan op #0d0d0d tegen een #000 achtergrond - dat verschil is te
   klein om de rand te zien. Een hairline maakt ze los zonder de huisstijl
   te veranderen. */
.tile,
.lessons .lesson,
.testimonials .item,
.slider .item {
    background-color: var(--ff-harmony);
    border: 1px solid var(--ff-hairline);
    border-radius: var(--ff-radius-lg);
    padding: var(--ff-space-lg);
    transition: border-color var(--ff-dur) var(--ff-ease),
                transform var(--ff-dur) var(--ff-ease),
                background-color var(--ff-dur) var(--ff-ease);
}

.tile:hover,
.lessons .lesson:hover,
.testimonials .item:hover {
    border-color: var(--ff-hairline-strong);
    transform: translateY(-2px);
}

.lessons {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ff-gutter);
    margin-bottom: var(--ff-space-lg);
}

/* 1 -> 2 -> 3 -> 4 kolommen; gap-berekening voorkomt overloop op elke breedte */
.lessons .lesson { width: 100%; }

@media (min-width: 576px) { .lessons .lesson { width: calc((100% - var(--ff-gutter)) / 2); } }
@media (min-width: 992px) { .lessons .lesson { width: calc((100% - 2 * var(--ff-gutter)) / 3); } }
@media (min-width: 1200px) { .lessons .lesson { width: calc((100% - 3 * var(--ff-gutter)) / 4); } }

/* De tegeltitel is een niveau onder de sectiekop, dus h3. h2 blijft werken
   voor bestaande module-inhoud. */
.lessons .lesson h2,
.lessons .lesson h3 {
    color: var(--ff-primary);
    font-size: var(--ff-h5);
    margin-top: 0;
    margin-bottom: var(--ff-space-xs);
}

.lessons .lesson p { color: var(--ff-on-dark-muted); font-size: var(--ff-text-sm); }

.testimonials .item { padding: clamp(1rem, .5rem + 2vw, 2rem); }
.testimonials .item strong { color: var(--ff-white); font-size: var(--ff-text-lead); font-weight: var(--ff-weight-heading); }

.slider .item {
    width: 100%;
    max-width: 320px;
    margin: 1rem;
    border-radius: 12px;
}

.slider .item svg {
    fill: var(--ff-primary-dark);
    height: 50px;
    width: 100%;
}

.slider .item:hover {
    background-color: var(--ff-primary-dark);
    cursor: pointer;
}

.slider .item:hover svg { fill: var(--ff-white); }

/* Partnerlogo's

   Zolang er geen logo in de container staat blijft het hele blok weg: anders
   staat er een kop "Onze partners" boven een lege balk. Dezelfde aanpak als
   bij .hero-section hierboven, dus in de bewerkmodus blijft hij wel staan -
   daar moet je er juist een logo in kunnen zetten. */
.logos:not(:has(.logos_container .logo_item)) { display: none; }
.dnnEditState .logos:not(:has(.logos_container .logo_item)) { display: block; }

.logos_container {
    border-radius: var(--ff-radius-lg);
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    min-height: 100px;
    padding: 1.5rem 0;
}

.logos_container .logo_item { padding: .75rem; }

/* max-height: 100% had niets om zich aan te meten - de rij is zo hoog als zijn
   inhoud, dus een logo van 400px maakte de rij 400px hoog en bleef zelf even
   groot. Een vaste bovengrens houdt logo's van verschillende afmetingen op
   dezelfde ooghoogte, passend bij de min-height van 100px van de rij. */
.logos_container .logo_image {
    max-height: 64px;
    max-width: 100%;
    transition: opacity .5s;
    width: auto;
}

/* Flexgrid uit _grid.scss, nu met gap in plaats van negatieve procentmarges.
   Die -1.5% rekende over de breedte van de ouder: binnen een .container van
   1425px is dat 21px tegen 15px padding, dus het reviewblok stak op een breed
   scherm 6px links en rechts buiten elke andere sectie uit. Met een vaste gap
   klopt de uitlijning op elke breedte, en het is dezelfde berekening als
   .lessons hierboven. */
.flexgrid-3 {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--ff-gutter);
}

.flexgrid-3._flex-start { justify-content: flex-start; }
.flexgrid-3 > * { margin: 0; width: 100%; }

@media (min-width: 480px) { .flexgrid-3 > * { width: calc((100% - var(--ff-gutter)) / 2); } }
@media (min-width: 768px) { .flexgrid-3 > * { width: calc((100% - 2 * var(--ff-gutter)) / 3); } }

/* --------------------------------------------------------------------------
   9. Formulieren (uit components/_form.scss)
   -------------------------------------------------------------------------- */
.fame input[type="text"],
.fame input[type="email"],
.fame input[type="password"],
.fame input[type="tel"],
.fame input[type="number"],
.fame input[type="search"],
.fame input[type="date"],
.fame select,
.fame textarea {
    font-family: var(--ff-font-body);
    font-size: var(--ff-text-base);
    color: var(--ff-white);
    background-color: var(--ff-harmony);
    border: 1px solid #2f2f2f;
    border-radius: var(--ff-radius-md);
    padding: .7rem .9rem;
    min-height: 48px;
    width: 100%;
    max-width: 100%;
    transition: border-color var(--ff-dur) var(--ff-ease),
                box-shadow var(--ff-dur) var(--ff-ease);
}

.fame input:focus,
.fame select:focus,
.fame textarea:focus {
    border-color: var(--ff-primary);
    box-shadow: 0 0 0 3px rgba(37,192,255,.2);
}

.fame input:focus:not(:focus-visible),
.fame select:focus:not(:focus-visible),
.fame textarea:focus:not(:focus-visible) { outline: 0; }

.fame label {
    color: var(--ff-white);
    display: inline-block;
    margin-bottom: .35rem;
    font-weight: var(--ff-weight-medium);
    font-size: var(--ff-text-sm);
}

/* #6c6b6b op #0d0d0d haalde 3.6:1 - net te weinig voor placeholdertekst */
.fame ::placeholder { color: #8b8b8b; font-family: var(--ff-font-body); opacity: 1; }

/* Aanmeldbalk (#subscribe) */
.subscribe {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
    gap: var(--ff-space-lg);
    border: 1px solid var(--ff-hairline);
    border-radius: var(--ff-radius-xl);
    padding: var(--ff-space-lg) var(--ff-space-xl);
    background: linear-gradient(100.66deg, #0099d8 23.13%, rgba(13,13,13,.86) 97.79%);
}

.subscribe p { color: var(--ff-white); text-align: center; margin: 0; }

@media (max-width: 600px) {
    .subscribe {
        flex-direction: column;
        /* 32px zijruimte at op een scherm van 320px een kwart van de kaart op */
        padding: var(--ff-space-lg) var(--ff-space-md);
    }

    .subscribe p { margin: 1em 0; }
}

/* --------------------------------------------------------------------------
   10. Meldingen (uit components/_alerts.scss)
   -------------------------------------------------------------------------- */
/* Wit op de signaalkleuren haalde 1.95:1 (groen) en 3.1:1 (oranje). De
   kleuren zelf blijven, de tekst wordt donker en de melding krijgt een
   gekleurde rand zodat hij ook op zwart afgebakend is. */
.alert {
    position: relative;
    padding: .875rem 2.5rem .875rem 1rem;
    margin-bottom: var(--ff-space-md);
    border-radius: var(--ff-radius-md);
    border-left: 4px solid transparent;
    color: var(--ff-on-signal);
    font-weight: var(--ff-weight-medium);
    line-height: 1.5;
}

.alert p, .alert a, .alert strong, .alert li { color: inherit; }
.alert a { text-decoration: underline; }

.alert-success {
    background-color: var(--ff-summer-green);
    border-left-color: #4e8a0d;
}

.alert-warning {
    background-color: var(--ff-carrot-orange);
    border-left-color: #9a5e00;
}

.alert-error, .alert-danger {
    background-color: var(--ff-autumn-red);
    border-left-color: #8a2020;
    color: var(--ff-white);
}

.alert-info {
    background-color: var(--ff-primary);
    border-left-color: var(--ff-primary-dark);
}

.alert .close {
    position: absolute;
    right: .5rem;
    top: 50%;
    transform: translateY(-50%);
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: inherit;
    opacity: .7;
}

.alert .close:hover { opacity: 1; }

/* --------------------------------------------------------------------------
   11. Footer (uit components/_footer.scss)
   -------------------------------------------------------------------------- */
footer.fame-footer {
    background-color: var(--ff-black);
    flex-shrink: 0;
    border-top: 1px solid var(--ff-hairline);
}

footer.fame-footer .container {
    padding-top: clamp(40px, 6vw, 75px);
    padding-bottom: clamp(40px, 6vw, 75px);
}

@media (max-width: 767px) {
    footer.fame-footer .row > [class*="col-"]:not(:last-child) { margin-bottom: 2.5rem; }
}

footer.fame-footer a,
footer.fame-footer p,
footer.fame-footer h2,
footer.fame-footer h3,
footer.fame-footer li { color: var(--ff-white); }

footer.fame-footer h2,
footer.fame-footer h3,
footer.fame-footer .footer-heading {
    font-size: var(--ff-h5);
    margin-top: 0;
    margin-bottom: var(--ff-space-md);
}

footer.fame-footer .footer-logo { margin-bottom: var(--ff-space-md); }

footer.fame-footer .footer-address {
    font-style: normal;
    color: var(--ff-on-dark-muted);
    line-height: 1.9;
}

footer.fame-footer .footer-address a { color: var(--ff-white); }
footer.fame-footer .footer-address a:hover { color: var(--ff-primary); }

footer.fame-footer a:hover {
    text-decoration: none;
    color: var(--ff-primary);
}

/* Footerlinks zijn aanraakdoelen, geen tekstregels */
footer.fame-footer .list-unstyled a,
footer.fame-footer .socials a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
}

footer.fame-footer ul { list-style: none; padding-left: 0; }

footer.fame-footer .socials .iconHolder { display: flex; gap: var(--ff-space-sm); margin-top: var(--ff-space-md); }
footer.fame-footer .socials svg { fill: var(--ff-white); }
footer.fame-footer .jump { display: inline-flex; transition: transform .2s ease-in-out; }
footer.fame-footer .jump:hover { transform: translateY(-4px); }

footer.fame-footer .footer-copyright {
    font-size: var(--ff-text-sm);
    color: var(--ff-on-dark-muted);
    text-align: center;
    padding: var(--ff-space-md);
    border-top: 1px solid var(--ff-hairline);
}

footer.fame-footer .footer-copyright p { margin-bottom: 0; }

/* Inloggen in de copyrightregel. Het uitschuifmenu had die link ook, maar dat
   menu is er vanaf 992px niet meer; hier staat hij op elke breedte. Zelfde
   opmaak als de cookieknop ernaast, zodat het een regel blijft en geen rij
   losse knoppen wordt.

   De link staat naast de <p> en niet erin: het Login-skinobject levert een
   <div class="loginGroup">, en een <div> in een <p> sluit die alinea in de
   parser voortijdig af. Alle drie op display:inline zetten voegt ze weer samen
   tot een gecentreerde regel. Een flexrij van deze twee blokken werkt niet: de
   <p> wordt dan shrink-to-fit, en text-wrap:pretty uit hoofdstuk 4 breekt de
   copyrightregel dan over twee regels terwijl er ruimte zat is. */
footer.fame-footer .footer-copyright p,
.footer-login,
.footer-login .loginGroup { display: inline; }

.footer-login::before {
    content: '·';
    margin-right: .35rem;
}

footer.fame-footer .footer-login a {
    color: inherit;
    font-size: inherit;
    text-decoration: underline;
}

footer.fame-footer .footer-login a:hover { color: var(--ff-primary); }

/* Skin-objecten in de footer (Copyright / Terms / Privacy / Login) */
.SkinLink,
.SkinLink a,
.SkinObject,
.SkinObject a {
    color: var(--ff-white);
    font-family: var(--ff-font-body);
    font-size: 15px;
    text-decoration: none;
}

.SkinLink a:hover, .SkinObject a:hover { color: var(--ff-primary); }

/* --------------------------------------------------------------------------
   12. Zoeken / login / gebruiker in de navigatiebalk
   -------------------------------------------------------------------------- */
.nav-utility {
    display: flex;
    align-items: center;
    gap: 15px;
}

.nav-utility .searchBox input[type="text"] {
    background-color: var(--ff-harmony);
    border: 1px solid #2a2a2a;
    border-radius: var(--ff-radius);
    color: var(--ff-white);
    padding: .35rem .6rem;
    font-family: var(--ff-font-body);
    font-size: 14px;
}

.nav-utility a,
.nav-utility .SkinObject { color: var(--ff-white); font-size: 15px; }

.nav-utility a:hover { color: var(--ff-primary); }

/* --------------------------------------------------------------------------
   13. DNN-specifiek
   -------------------------------------------------------------------------- */
/* Panes */
.fame .DNNEmptyPane { display: none; }

/* Een lege pane wordt verborgen, maar de kolom ernaast hield zijn breedte:
   een Inner-pagina zonder LeftPane liet 25% dood vlak rechts staan. De
   overgebleven kolommen vullen de rij nu zelf op. */
.fame .row:has(> .DNNEmptyPane) > [class*="col-"]:not(.DNNEmptyPane) {
    flex: 1 1 0%;
    max-width: 100%;
}

/* In bewerkmodus zijn de lege panes juist wel zichtbaar, dus dan niet */
.dnnEditState .fame .row:has(> .DNNEmptyPane) > [class*="col-"]:not(.DNNEmptyPane) {
    flex: none;
}

/* Een rij waarin alles leeg is, hoeft geen ruimte te kosten */
.fame .row:not(:has(> [class*="col-"]:not(.DNNEmptyPane))) { display: none; }

.dnnEditState .fame .DNNEmptyPane {
    display: block;
    min-height: 60px;
    border: 1px dashed rgba(37,192,255,.5);
    margin-bottom: 10px;
}

/* Containers */
.fame-container { position: relative; }

.fame-container .fame-container-title h2,
.fame-container .fame-container-title h3 {
    font-family: var(--ff-font-heading);
    font-weight: var(--ff-weight-heading);
    color: var(--ff-white);
    margin-top: 0;
}

/* Een module zonder titel mag geen lege regel achterlaten.
   De oude controle keek of de titelbalk alleen lege elementen bevatte, en
   sloeg daardoor nooit aan: DNN rendert de moduletitel altijd, ook als er geen
   titel is ingevuld, als <h2><span class="Head"></span></h2>. Die h2 heeft een
   kind en is dus nooit :empty. Op een sectiecontainer zonder titel bleef zo
   een los blauw accentstreepje staan met 51px ruimte eromheen. Kijk daarom
   naar de .Head zelf. */
.fame :is(.section-title, .fame-container-title) > :is(h1, h2, h3, h4, h5, h6):is(:empty, :has(> .Head:empty)) { display: none; }

/* Stond er verder niets in de titelbalk, dan hoeft die ook geen ruimte en
   geen ondermarge te kosten. Een ondertitel houdt het blok wel overeind.
   Twee selectors, want :has() mag niet in :has() staan: de lege kop en de kop
   met een lege .Head moeten elk hun eigen regel hebben. */
.fame :is(.section-title, .fame-container-title):not(:has(> :not(h1, h2, h3, h4, h5, h6))):has(> :is(h1, h2, h3, h4, h5, h6):empty),
.fame :is(.section-title, .fame-container-title):not(:has(> :not(h1, h2, h3, h4, h5, h6))):has(> :is(h1, h2, h3, h4, h5, h6) > .Head:empty) { display: none; }

/* De standaardcontainer had geen enkele regel, dus twee modules in dezelfde
   pane plakten tegen elkaar. */
.fame-container-main + .fame-container-main,
.fame-container-main + .fame-container-card,
.fame-container-card + .fame-container-card,
.fame-container-card + .fame-container-main,
.fame-container-blank + .fame-container-main,
.fame-container-main + .fame-container-blank { margin-top: var(--ff-space-xl); }

/* Section.ascx zet zowel .fame-container-section als .page-section op
   hetzelfde element. Twee paddingschalen naast elkaar gaven tussen 768 en
   991px 150px waar de schaal 100px bedoelde; nu is er nog één bron.
   Hij volgt hetzelfde eenzijdige ritme als .page-section - deze regel staat
   later in het bestand en zou de padding daar anders weer overschrijven. */
.fame-container-section {
    padding-top: var(--ff-section-y);
    padding-bottom: 0;
    padding-left: 0;
    padding-right: 0;
    background-color: var(--ff-black);
}

.fame-container-card {
    background-color: var(--ff-harmony);
    border: 1px solid var(--ff-hairline);
    border-radius: var(--ff-radius-lg);
    padding: var(--ff-space-lg);
    margin-bottom: var(--ff-space-md);
}

/* Module-actiemenu leesbaar houden op donkere achtergrond */
.fame .dnnActionMenu,
.fame .actionMenu,
.fame .dnnEditState .dnnModuleTitle { color: initial; }

.fame .actionMenu li a,
.fame .dnnActionMenu a { color: #333; }

/* DNN-formulieren binnen modules (module settings, login, register)
   krijgen hun eigen leesbare basis terug. */
.fame .dnnForm,
.fame .dnnForm p,
.fame .dnnForm label,
.fame .dnnForm td,
.fame .dnnForm th,
.fame .dnnForm li,
.fame .dnnFormItem label,
.fame .dnnLabel label { color: #333; }

.fame .dnnForm a { color: #1e6fa8; }

.fame .dnnForm input[type="text"],
.fame .dnnForm input[type="password"],
.fame .dnnForm input[type="email"],
.fame .dnnForm select,
.fame .dnnForm textarea {
    background-color: #fff;
    color: #333;
    border: 1px solid #c9c9c9;
}

/* HTML-module content erft de site-typografie.

   Dit is het grootste verschil tussen Documentation/Preview.html en een echte
   DNN-pagina. DNN's default.css zet:

       .Normal { font-size: 1rem; line-height: 1.125rem; }

   en elke HTML-module rendert zijn inhoud in <div class="Normal">. Met
   html op 16px komt dat neer op 16px tekst met 18px regelafstand - een
   regelhoogte van 1,125 waarbij de regels bijna tegen elkaar aan liggen.
   Het thema zet 18px met 1,65. In de preview klopte het dus wel en op de
   site niet, want daar zit die wrapper om alles heen.

   De vorige versie van deze regel pakte alleen kleur en lettertype, dus de
   maat en de regelafstand bleven van DNN. */
.fame .DnnModule .Normal,
.fame .DnnModule .NormalDeleted,
.fame .DnnModule .NormalDisabled,
.fame .DnnModule .SubHead,
.fame .DnnModule .Head {
    color: var(--ff-white);
    font-family: var(--ff-font-body);
    font-size: inherit;
    line-height: var(--ff-leading-body);
}

/* De containers zetten de moduletitel neer als <span class="Head"> binnen een
   kop. Twee dingen gingen daar mis, allebei alleen op de site en niet in de
   preview: default.css van DNN maakt van .Head een inline-block met 6px marge
   eronder, en de regel hierboven gaf hem de regelafstand van bodytekst (1,65).
   Een sectiekop werd daardoor 102px hoog in plaats van de 74px van de preview,
   met het accentstreepje net zoveel te laag. Binnen een kop hoort de titel
   simpelweg de maat, het gewicht en de regelafstand van die kop te volgen. */
/* Beide selectors zijn nodig: de regel hierboven staat op .fame .DnnModule
   .Head en is met drie klassen specifieker dan een variant zonder .DnnModule. */
.fame .DnnModule :is(h1, h2, h3, h4, h5, h6) > .Head,
.fame :is(h1, h2, h3, h4, h5, h6) > .Head {
    display: inline;
    margin: 0;
    font-size: inherit;
    font-weight: inherit;
    line-height: inherit;
}

/* Bewerkbalk niet onder de vaste navigatiebalk laten vallen */
.dnnEditState .fame-layout > .content { padding-top: 0; }

/* --------------------------------------------------------------------------
   14. Login-/registratiepagina's (Edit-skin, lichte variant)
   -------------------------------------------------------------------------- */
/* fame-light staat op hetzelfde element als fame-layout, niet op body en
   niet erboven. De vorige twee selectors matchten daardoor nooit, waardoor
   de inlogpagina donkergrijs op zwart werd (1.9:1). */
.fame-light,
body:has(> form .fame-light) { background-color: #f4f5f7; }

.fame-light {
    min-height: 100vh;
    min-height: 100dvh;
}

.fame-light,
.fame-light p,
.fame-light li,
.fame-light td { color: #333; }

.fame-light h1, .fame-light h2, .fame-light h3,
.fame-light h4, .fame-light h5, .fame-light h6 { color: #111; }

.fame-light a { color: var(--ff-primary-dark); }

.fame-light .fame-panel {
    background-color: #fff;
    border-radius: var(--ff-radius-lg);
    padding: 1.5rem;
    box-shadow: 0 4px 16px 0 rgba(22,42,90,.15);
}

/* --------------------------------------------------------------------------
   15. Hulpklassen
   -------------------------------------------------------------------------- */
.mt-3 { margin-top: 1rem; }
.mb-3 { margin-bottom: 1rem; }
.pt-0 { padding-top: 0; }
.pb-0 { padding-bottom: 0; }
.bg-black { background-color: var(--ff-black); }
.bg-harmony { background-color: var(--ff-harmony); }
.sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0,0,0,0);
    border: 0;
}

/* Terug naar boven. Stond eerder altijd in de tabvolgorde, ook geparkeerd
   op right:-70px. Nu echt verborgen tot .is-visible erop staat. */
.scrollTop {
    position: fixed;
    bottom: 25px;
    right: 15px;
    z-index: 90;
    background-color: var(--ff-primary-dark);
    border: 1px solid var(--ff-primary);
    border-radius: 50%;
    width: 48px;
    height: 48px;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    visibility: hidden;
    transform: translateY(12px);
    transition: opacity var(--ff-dur) var(--ff-ease),
                transform var(--ff-dur) var(--ff-ease),
                background-color var(--ff-dur) var(--ff-ease),
                visibility 0s linear var(--ff-dur);
}

.scrollTop.is-visible {
    opacity: 1;
    visibility: visible;
    transform: none;
    transition: opacity var(--ff-dur) var(--ff-ease),
                transform var(--ff-dur) var(--ff-ease),
                background-color var(--ff-dur) var(--ff-ease),
                visibility 0s;
}

.scrollTop:hover { background-color: var(--ff-primary-hover); }
.scrollTop svg { fill: var(--ff-white); width: 18px; }

/* --------------------------------------------------------------------------
   16. Skin-layouts: panes en koppen
   -------------------------------------------------------------------------- */
/* Panes over de volle breedte */
.hero-pane,
.notice-pane,
.section-pane { width: 100%; }

.notice-pane { background-color: var(--ff-primary-dark); }

.notice-pane:empty { display: none; }

.notice-pane p,
.notice-pane h2,
.notice-pane h3 { color: var(--ff-white); }

/* Paginakop van de Inner-layout: kruimelpad boven de titel, en een fijne
   lijn eronder zodat de kop van de inhoud loskomt. */
.inner-header {
    background-color: var(--ff-black);
    padding-top: clamp(2rem, 1.4rem + 2.4vw, 3.5rem);
    padding-bottom: clamp(1.5rem, 1.1rem + 1.6vw, 2.5rem);
    border-bottom: 1px solid var(--ff-hairline);
}

.inner-header .page-title { gap: var(--ff-space-sm); margin-bottom: 0; }
.inner-header .page-title h1 { margin-top: 0; margin-bottom: 0; }

.inner-header .breadcrumb,
.inner-header .breadcrumb a {
    color: var(--ff-on-dark-muted);
    font-size: var(--ff-text-sm);
}

.inner-header .breadcrumb { order: -1; margin-bottom: var(--ff-space-xs); }

/* Bij FullWidth komt de titel uit de module in HeroPane. De laatste regel
   daarvan - meestal de knop - hoeft geen eigen ondermarge meer: de balk
   heeft er al padding voor. */
.inner-header .hero-pane .Normal > :last-child,
.inner-header .hero-pane > .DnnModule > :last-child { margin-bottom: 0; }

/* Staat er geen module in HeroPane, dan blijft er anders een zwarte balk met
   alleen een kruimelpad over. In de bewerkmodus blijft hij staan, want daar
   moet de redacteur er iets in kunnen slepen. */
.inner-header:has(.hero-pane.DNNEmptyPane) { display: none; }
.dnnEditState .inner-header:has(.hero-pane.DNNEmptyPane) { display: block; }

/* Kleine bovenkop, bijvoorbeeld boven de blogtitel */
.page-kicker {
    color: var(--ff-primary);
    font-family: var(--ff-font-button);
    font-weight: var(--ff-weight-button);
    font-size: var(--ff-text-sm);
    text-transform: uppercase;
    letter-spacing: .12em;
    margin: 0 0 var(--ff-space-xs);
}

.inner-header .breadcrumb a:hover { color: var(--ff-primary); }

/* Dropdown in de bovenbalk (tweede menuniveau) */
.navbar .nav-items li.has-children { position: relative; }

.navbar .nav-items .nav-dropdown {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    min-width: 220px;
    background-color: var(--ff-harmony);
    border-radius: var(--ff-radius);
    padding: .5rem 0;
    margin: 0;
    list-style: none;
    box-shadow: 0 8px 24px rgba(0,0,0,.5);
    z-index: 110;
}

/* .is-open komt van js/fame.js: de tik-variant voor schermen zonder muis. */
.navbar .nav-items li.has-children:hover > .nav-dropdown,
.navbar .nav-items li.has-children.is-open > .nav-dropdown,
.navbar .nav-items li.has-children:focus-within > .nav-dropdown { display: block; }

.navbar .nav-items .nav-dropdown li a {
    display: block;
    padding: .4rem 1rem;
    margin-right: 0;
    white-space: nowrap;
}

/* Footernavigatie uit DDRMenu */
footer.fame-footer .list-unstyled li { margin-bottom: .25rem; }

/* --------------------------------------------------------------------------
   17. Edit-/popup-layout
   -------------------------------------------------------------------------- */
.edit-header {
    background-color: var(--ff-black);
    padding: 15px 0;
}

.edit-header .container {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.edit-header-utility { display: flex; align-items: center; gap: 15px; }
.edit-header-utility a { color: var(--ff-white); }
.edit-header-utility a:hover { color: var(--ff-primary); }

.fame-light .content { padding: 30px 0 60px; }

.fame-light .breadcrumb,
.fame-light .breadcrumb a { color: #6c6b6b; font-size: 14px; }

.edit-footer {
    background-color: var(--ff-black);
    padding: 15px 0;
    text-align: center;
}

.edit-footer a, .edit-footer span { color: var(--ff-white); }

.fame-popup { padding: 15px; background-color: #fff; }
.fame-popup, .fame-popup p, .fame-popup label, .fame-popup td { color: #333; }

/* Nieuwsbriefveld in de aanmeldbalk (uit layout/_home.scss #subscribe) */
/* De pil hield zijn maten met vaste hoogtes: 75px op de balk, 150px op een
   telefoon, en het invoerveld erfde die hoogte. Op een smal scherm bleef er
   dan een invoerveld van 95px over met de tekst er verloren in het midden.
   Nu bepalen de knop (60px) en de rand van 7,5px de hoogte, en groeit de rest
   mee: op de balk komt dat op dezelfde 75px uit, op een telefoon op wat er
   werkelijk nodig is. */
.mini-form {
    background-color: #ececec;
    border-radius: 40px;
    min-height: 75px;
    width: 100%;
    display: flex;
    align-items: stretch;
    padding: 7.5px;
    max-width: 450px;
}

.mini-form input {
    border-radius: inherit;
    border: none;
    background-color: transparent;
    flex: 1 1 auto;
    min-width: 0;
    min-height: 48px;
    /* 15pt = 20px; als rem schaalt hij mee met de tekstinstelling */
    font-size: 1.25rem;
    padding-left: 7.5px;
    color: #333;
}

.mini-form input:focus:not(:focus-visible) { outline: 0; }
.mini-form:focus-within { box-shadow: var(--ff-glow); }

.mini-form button {
    /* Kleine tekst op een gevuld vlak, dus het diepere blauw */
    background-color: var(--ff-primary-deep);
    border-radius: 40px;
    border: none;
    color: var(--ff-white);
    min-height: 60px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: .8rem 1.6rem;
    margin-left: auto;
    font-size: var(--ff-text-base);
    font-family: var(--ff-font-button);
    font-weight: var(--ff-weight-button);
    cursor: pointer;
}

.mini-form button:hover { background-color: var(--ff-primary-dark); }

@media (max-width: 600px) {
    .mini-form {
        flex-direction: column;
        border-radius: 30px;
        gap: .5rem;
    }

    .mini-form input {
        padding-left: 1rem;
        padding-right: 1rem;
    }

    .mini-form button { margin-left: 0; }
}

/* --------------------------------------------------------------------------
   18. Responsive vangnet voor module-inhoud
   Modules leveren HTML die de skin niet kent. Deze regels voorkomen dat die
   inhoud de pagina horizontaal laat scrollen.
   -------------------------------------------------------------------------- */
html { scroll-padding-top: calc(var(--ff-chrome-height) + 20px); }

.fame img,
.fame video,
.fame canvas,
.fame iframe,
.fame embed,
.fame object {
    max-width: 100%;
}

.fame iframe { border: 0; }

.fame pre {
    overflow-x: auto;
    max-width: 100%;
}

.fame p,
.fame li,
.fame dd,
.fame td { overflow-wrap: break-word; }

/* Inhoudstabellen (het lesrooster, de openingstijden). Het thema tekende
   tabellen niet, en de reset van DNN haalt de celpadding weg en zet de
   uitlijning op baseline: op famefitness.nl plakten de kolommen van het
   rooster tegen elkaar. Deze regels staan bewust vóór sectie 21.8, want de
   tabelopmaak van Form and List heeft dezelfde specificiteit en moet die van
   een inhoudstabel blijven overschrijven. */
.fame .content table {
    width: 100%;
    margin-block: 1em;
    border-collapse: collapse;
}

.fame .content caption {
    padding-bottom: var(--ff-space-xs);
    color: var(--ff-on-dark-muted);
    text-align: left;
}

.fame .content :is(th, td) {
    padding: .6rem .9rem;
    text-align: left;
    vertical-align: middle;
    border-bottom: 1px solid var(--ff-hairline);
}

.fame .content thead th {
    color: var(--ff-primary);
    font-weight: var(--ff-weight-heading);
    letter-spacing: .02em;
}

.fame .content tbody th { font-weight: var(--ff-weight-heading); }

.fame .content tbody tr:last-child :is(th, td) { border-bottom: 0; }

/* Brede tabellen scrollen binnen hun eigen kader in plaats van de pagina */
.fame .table-scroll,
.fame .dnnTableWrapper {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    max-width: 100%;
}

@media (max-width: 767px) {
    .fame .ContainerPane table,
    .fame .DnnModule table {
        display: block;
        width: 100%;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
}

/* Responsieve video-embed (YouTube, Vimeo) */
.embed-responsive {
    position: relative;
    width: 100%;
    padding-top: 56.25%;
    overflow: hidden;
    border-radius: var(--ff-radius);
}

.embed-responsive > iframe,
.embed-responsive > video,
.embed-responsive > object,
.embed-responsive > embed {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}

/* Bewerkmodus op mobiel: DNN-panelen mogen niet buiten beeld vallen */
@media (max-width: 767px) {
    .dnnEditState .fame .DnnModule { max-width: 100%; overflow-x: hidden; }
}

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

    .fame *,
    .fame *::before,
    .fame *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }

    /* De reveal mag nooit inhoud verborgen laten als beweging uit staat */
    .fame [data-reveal] { opacity: 1 !important; transform: none !important; }
}

/* --------------------------------------------------------------------------
   Zachte reveal bij het in beeld scrollen. fame.js zet data-reveal op de
   secties; zonder JavaScript blijft alles gewoon zichtbaar.
   -------------------------------------------------------------------------- */
.js-reveal .fame [data-reveal] {
    opacity: 0;
    transform: translateY(16px);
    transition: opacity .6s var(--ff-ease), transform .6s var(--ff-ease);
    will-change: opacity, transform;
}

.js-reveal .fame [data-reveal].is-revealed {
    opacity: 1;
    transform: none;
    will-change: auto;
}

/* --------------------------------------------------------------------------
   19. Blog / nieuws
   Geport uit wwwroot/scss/components/_news.scss, _pagination.scss en
   layout/_nieuws.scss van FameFitness.Portal.
   -------------------------------------------------------------------------- */

/* 19.1 Layout van de blogpagina */
.blog-layout { width: 100%; }

.blog-sidebar > div:not(:empty) { margin-bottom: 1.5rem; }

.blog-sidebar h2,
.blog-sidebar h3 {
    font-size: clamp(1.15rem, .9rem + .9vw, 1.5rem);
    margin-top: 0;
}

.blog-sidebar ul {
    list-style: none;
    padding-left: 0;
    margin: 0;
}

.blog-sidebar li { border-bottom: 1px solid #1e1e1e; }
.blog-sidebar li:last-child { border-bottom: 0; }

.blog-sidebar li a {
    padding: .5rem 0;
    color: var(--ff-white);
    font-size: var(--ff-text-sm);
}

.blog-sidebar li a:hover { color: var(--ff-primary); }

/* 19.2 Kaartenraster
   Werkt met de markup uit het bronproject:
   .blog-deck > .card-default > .figure-link > figure.figure.figurebg._square */
/* Grid in plaats van flex: gelijke hoogtes en één gutter in beide
   richtingen. De kaarten hadden eerder 24px tussen kolommen en 66px
   tussen rijen, door een margin-bottom bovenop de gap. */
.blog-deck {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--ff-gutter);
}

@media (min-width: 576px) { .blog-deck { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 992px) { .blog-deck { grid-template-columns: repeat(3, 1fr); } }

.blog-deck > * { width: auto; min-width: 0; }

.card-default {
    display: flex;
    flex-direction: column;
    background: var(--ff-white);
    border: 1px solid transparent;
    border-radius: var(--ff-radius-lg);
    overflow: hidden;
    height: 100%;
    transition: transform var(--ff-dur) var(--ff-ease),
                box-shadow var(--ff-dur) var(--ff-ease),
                border-color var(--ff-dur) var(--ff-ease);
}

.card-default:hover {
    transform: translateY(-4px);
    box-shadow: var(--ff-shadow-md);
    border-color: var(--ff-primary);
}

.card-default .figure { transition: transform var(--ff-dur-slow) var(--ff-ease); }
.card-default:hover .figure { transform: scale(1.03); }

.card-default .figure-link { display: block; }

.card-default .figure,
.card-default figure {
    margin: 0;
    aspect-ratio: 5 / 4;
    background-size: cover;
    background-position: 50%;
    background-repeat: no-repeat;
    overflow: hidden;
}

.card-default .figure._square { aspect-ratio: 1 / 1; }

.card-default .figure img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Bij .figurebg staat de afbeelding al als achtergrond. De img blijft staan
   voor zoekmachines en schermlezers - visibility:hidden haalde hem juist uit
   de toegankelijkheidsboom, inclusief de alt-tekst. */
.card-default .figurebg img {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.card-default .figurebg { position: relative; }

.card-default .card__title {
    position: relative;
    text-align: center;
    color: #111;
    font-size: clamp(1.05rem, .9rem + .6vw, 1.35rem);
    margin: 0;
    padding: 1.25rem 1rem .75rem;
}

.card-default .card__title::after {
    content: '';
    width: 75px;
    height: 3px;
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    background-color: var(--ff-primary);
}

.card-default .card__meta {
    text-align: center;
    color: var(--ff-muted);
    font-size: .8125em;
    padding: .75rem 1rem 0;
}

.card-default .card__teasertext {
    padding: var(--ff-space-md) var(--ff-space-md) 0;
    line-height: 1.55;
    text-align: center;
    color: #5a5a5a;
    font-size: var(--ff-text-sm);
}

.card-default .card__teasertext p { color: inherit; margin: .5em 0; }

.card-default .card__readmore {
    margin-top: auto;
    padding: 1rem;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    font-size: .875em;
}

.card-default .card__title,
.card-default a,
.card-default .card__readmore a { color: #111; }

.card-default .card__readmore a:hover { color: var(--ff-primary-dark); }

.card-default .readmore {
    text-decoration: none;
    text-transform: uppercase;
    font-weight: 700;
    letter-spacing: 2px;
}

.card-default .card__sharebuttons { display: none; }

/* Donkere variant, past bij de tegels elders op de site */
.card-default._dark {
    background: var(--ff-harmony);
    border-color: var(--ff-hairline);
}

.card-default._dark .card__title,
.card-default._dark a,
.card-default._dark .card__readmore a { color: var(--ff-white); }

.card-default._dark .card__teasertext { color: var(--ff-on-dark-muted); }
.card-default._dark .card__readmore a:hover { color: var(--ff-primary); }

/* 19.3 Artikelpagina
   Een regellengte van ~68 tekens leest het prettigst; de artikelkop mag
   groter dan de rest, of de module nu h1 of h2 gebruikt. */
.blog-article {
    max-width: 68ch;
    margin: 0 auto;
}

.blog-article > h1:first-child,
.blog-article > h2:first-child {
    font-size: var(--ff-h1);
    line-height: var(--ff-leading-tight);
    letter-spacing: -.025em;
    margin-top: 0;
}

.blog-article .article-meta {
    color: var(--ff-on-dark-muted);
    font-size: var(--ff-text-sm);
    text-transform: uppercase;
    letter-spacing: .08em;
    margin-bottom: var(--ff-space-xl);
}

.blog-article p,
.blog-article li { line-height: var(--ff-leading-body); }

.blog-article > p:first-of-type {
    font-size: var(--ff-text-lead);
    color: var(--ff-gray);
}

.blog-article a {
    color: var(--ff-primary);
    text-decoration: underline;
}

.blog-article ul,
.blog-article ol {
    padding-left: 1.5rem;
    margin-bottom: 1em;
}

.blog-article ul li { list-style: disc; }
.blog-article ol li { list-style: decimal; }

.blog-article img {
    border-radius: var(--ff-radius);
    margin: 1.5rem 0;
}

.blog-article figure { margin: 1.5rem 0; }

.blog-article figcaption {
    color: var(--ff-gray);
    font-size: .85rem;
    text-align: center;
}

.blog-article blockquote {
    margin: var(--ff-space-xl) 0;
    padding: var(--ff-space-md) 0 var(--ff-space-md) var(--ff-space-lg);
    border-left: 3px solid var(--ff-primary);
    color: var(--ff-white);
    font-size: var(--ff-text-lead);
    font-style: italic;
}

.blog-article blockquote p:last-child { margin-bottom: 0; }

.blog-article hr { margin: 2rem 0; }

/* 19.4 Paginering (bronproject _pagination.scss, omgezet naar donkere achtergrond) */
.pagination {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    padding-left: 0;
    margin: 2rem 0 0;
    list-style: none;
}

.pagination .page-item .page-link {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: .5rem .75rem;
    margin-left: -1px;
    line-height: 1.25;
    font-weight: var(--ff-weight-medium);
    color: var(--ff-primary);
    background-color: var(--ff-harmony);
    border: 1px solid #2f2f2f;
    min-width: 44px;
    min-height: 44px;
    text-align: center;
    transition: background-color var(--ff-dur) var(--ff-ease), color var(--ff-dur) var(--ff-ease);
}

.pagination .page-item .page-link:hover {
    color: var(--ff-white);
    background-color: var(--ff-primary-deep);
}

.pagination .page-item .page-link:focus:not(:focus-visible) { box-shadow: none; }

.pagination .page-item.active .page-link {
    color: var(--ff-white);
    background-color: var(--ff-primary-deep);
    border-color: var(--ff-primary);
}

/* #6c757d op #0d0d0d haalde 4.14:1; net onder de grens voor kleine tekst */
.pagination .page-item.disabled .page-link {
    color: #8b9199;
    pointer-events: none;
    cursor: auto;
}

.pagination .page-item:first-child .page-link {
    margin-left: 0;
    border-top-left-radius: var(--ff-radius);
    border-bottom-left-radius: var(--ff-radius);
}

.pagination .page-item:last-child .page-link {
    border-top-right-radius: var(--ff-radius);
    border-bottom-right-radius: var(--ff-radius);
}

/* DNN's eigen pager */
.fame .dnnPager,
.fame .dnnPager a,
.fame .dnnPager span { color: var(--ff-white); }

.fame .dnnPager a:hover { color: var(--ff-primary); }

/* 19.5 Categoriebalk (bronproject #articles .nav) */
/* Categoriebalk als rij pillen: op elke breedte horizontaal scrollbaar in
   plaats van een kolom op mobiel. */
.blog-filter {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ff-space-xs);
    margin-bottom: var(--ff-space-xl);
    padding-left: 0;
    list-style: none;
}

.blog-filter li { list-style: none; }

.blog-filter a {
    color: var(--ff-on-dark-muted);
    padding: .35rem .9rem;
    border: 1px solid var(--ff-hairline);
    border-radius: 999px;
    font-size: var(--ff-text-sm);
    font-weight: var(--ff-weight-medium);
    white-space: nowrap;
    transition: color var(--ff-dur) var(--ff-ease),
                border-color var(--ff-dur) var(--ff-ease),
                background-color var(--ff-dur) var(--ff-ease);
}

.blog-filter a:hover {
    color: var(--ff-white);
    border-color: var(--ff-hairline-strong);
}

.blog-filter a.active {
    color: var(--ff-black);
    background-color: var(--ff-primary);
    border-color: var(--ff-primary);
}

/* 19.6 Vangnet voor onbekende blogmodules
   Zolang een module zijn eigen klassen gebruikt, pakt dit blok de kale
   HTML-elementen binnen de blogpanes op. */
.blog-pane .DnnModule h1 a,
.blog-pane .DnnModule h2 a,
.blog-pane .DnnModule h3 a,
.blog-pane .DnnModule h4 a { color: var(--ff-white); }

.blog-pane .DnnModule h1 a:hover,
.blog-pane .DnnModule h2 a:hover,
.blog-pane .DnnModule h3 a:hover,
.blog-pane .DnnModule h4 a:hover { color: var(--ff-primary); }

.blog-pane .DnnModule ul,
.blog-pane .DnnModule ol { padding-left: 1.5rem; }

.blog-pane .DnnModule ul li { list-style: disc; }
.blog-pane .DnnModule ol li { list-style: decimal; }

.blog-pane .DnnModule img { border-radius: var(--ff-radius); }

/* --------------------------------------------------------------------------
   20. Contactpagina
   Hoort bij Contact.ascx. De pagina leest van boven naar beneden als een
   gesprek: eerst hoe je ons het snelst bereikt, dan het formulier met de
   gegevens ernaast, dan pas de kaart. De kaart stond eerder bovenaan, maar
   die is zonder toestemming voor marketingcookies een grijs vlak met een
   knop - geen begin van een contactpagina.
   -------------------------------------------------------------------------- */

/* 20.1 Kop met snelle acties ------------------------------------------- */
/* Bellen, mailen en langskomen zijn op een telefoon de drie dingen die
   iemand hier komt doen. Ze staan daarom boven het formulier, als echte
   links: tel:, mailto: en de route. */
.contact-intro { max-width: 46rem; }

.contact-intro h1 { margin-top: 0; }

.contact-intro .lead { margin-bottom: 0; }

.contact-actions {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--ff-gutter);
    margin: var(--ff-space-xl) 0 0;
    padding: 0;
    list-style: none;
}

@media (min-width: 576px) { .contact-actions { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.contact-action {
    display: flex;
    align-items: center;
    gap: var(--ff-space-md);
    height: 100%;
    padding: var(--ff-space-md) var(--ff-space-lg);
    border: 1px solid var(--ff-hairline);
    border-radius: var(--ff-radius-lg);
    background-color: var(--ff-harmony);
    color: var(--ff-white);
    text-decoration: none;
    transition: border-color var(--ff-dur) var(--ff-ease),
                transform var(--ff-dur) var(--ff-ease);
}

.contact-action:hover,
.contact-action:focus-visible {
    border-color: var(--ff-primary);
    color: var(--ff-white);
    transform: translateY(-2px);
}

.contact-action svg {
    flex: none;
    width: 28px;
    height: 28px;
    fill: var(--ff-primary);
}

.contact-action-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.contact-action-label {
    color: var(--ff-on-dark-muted);
    font-size: var(--ff-text-sm);
}

/* De waarde mag breken in plaats van buiten de tegel steken: een
   e-mailadres is op 320px breder dan de kolom. */
.contact-action-value {
    font-family: var(--ff-font-heading);
    font-size: var(--ff-h6);
    font-weight: var(--ff-weight-heading);
    line-height: var(--ff-leading-heading);
    overflow-wrap: anywhere;
}

/* 20.2 Formulier en zijkolom -------------------------------------------- */
.contact-section {
    background-color: var(--ff-black);
    padding-top: var(--ff-space-2xl);
}

/* Eén kolom tot 992px. Het formulier eerst: wie hier komt, komt om iets te
   vragen; de gegevens ernaast zijn het alternatief. */
.contact-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--ff-space-xl);
    align-items: start;
}

@media (min-width: 992px) {
    .contact-grid {
        grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
        gap: var(--ff-space-2xl);
    }
}

/* Het formulier in een eigen paneel, zodat de velden niet los op het zwart
   zweven. Op een telefoon een slag minder padding: daar is de breedte van
   het invoerveld belangrijker dan de lucht eromheen. */
.contact-main {
    padding: var(--ff-space-lg);
    border: 1px solid var(--ff-hairline);
    border-radius: var(--ff-radius-lg);
    background-color: var(--ff-harmony);
    box-shadow: var(--ff-shadow-md);
}

@media (min-width: 768px) { .contact-main { padding: var(--ff-space-xl); } }

/* Staat er (nog) geen module in, dan geen leeg paneel op de pagina. In de
   bewerkmodus blijft het staan, anders valt er niets in te slepen. */
.contact-main.DNNEmptyPane {
    padding: 0;
    border: 0;
    background: transparent;
    box-shadow: none;
}

.dnnEditState .contact-main.DNNEmptyPane {
    padding: var(--ff-space-lg);
    border: 1px dashed var(--ff-hairline-strong);
    background-color: var(--ff-harmony);
}

/* De container van de module brengt zijn eigen tegel niet mee: het paneel
   hierboven is de tegel. */
.contact-main .fame-container-card,
.contact-main .fame-container.fame-form {
    padding: 0;
    border: 0;
    background: transparent;
    box-shadow: none;
    margin-bottom: 0;
}

.contact-main .fame-container-title h2,
.contact-main .fame-container-title h3 {
    margin-top: 0;
    margin-bottom: var(--ff-space-md);
    font-size: var(--ff-h4);
}

/* De kleine letters onder het formulier. Een losse klasse verliest het van
   .fame p uit hoofdstuk 4, vandaar de tweede selector. */
.fame .form-note,
.form-note {
    margin: var(--ff-space-md) 0 0;
    color: var(--ff-on-dark-muted);
    font-size: var(--ff-text-sm);
}

/* 20.3 Gegevenskaart in de zijkolom ------------------------------------- */
.contact-card {
    padding: var(--ff-space-lg);
    border: 1px solid var(--ff-hairline);
    border-top: 3px solid var(--ff-primary);
    border-radius: var(--ff-radius-lg);
    background-color: var(--ff-harmony);
}

.contact-card + .contact-card { margin-top: var(--ff-gutter); }

.contact-card h2,
.contact-card h3 {
    margin-top: 0;
    margin-bottom: var(--ff-space-md);
    color: var(--ff-white);
    font-size: var(--ff-h5);
}

.contact-card h3 + * { margin-top: 0; }

.contact-card p { color: var(--ff-on-dark-muted); }

.contact-card .btn { width: 100%; }

/* Rijtje gegevens: label boven de waarde, want "Bezoekadres" en een adres
   naast elkaar passen op 320px niet zonder af te breken. */
.contact-list {
    margin: 0 0 var(--ff-space-lg);
    padding: 0;
    list-style: none;
}

.contact-list > li + li {
    margin-top: var(--ff-space-md);
    padding-top: var(--ff-space-md);
    border-top: 1px solid var(--ff-hairline);
}

.contact-list dt,
.contact-list .contact-label {
    display: block;
    color: var(--ff-on-dark-muted);
    font-size: var(--ff-text-sm);
    letter-spacing: .02em;
    text-transform: uppercase;
}

.contact-list a,
.contact-list address {
    display: block;
    margin: var(--ff-space-2xs) 0 0;
    min-height: 44px;
    color: var(--ff-white);
    font-family: var(--ff-font-heading);
    font-size: var(--ff-h6);
    font-weight: var(--ff-weight-medium);
    font-style: normal;
    line-height: var(--ff-leading-heading);
    overflow-wrap: anywhere;
}

/* Bellen en mailen zijn hier de belangrijkste handelingen; op een telefoon
   moeten ze ook echt aan te tikken zijn. Vandaar een regel van 44 pixels
   hoog in plaats van alleen de hoogte van de letters. */
.contact-list a {
    display: flex;
    align-items: center;
    text-decoration: none;
}

.contact-list a:hover,
.contact-list a:focus-visible { color: var(--ff-primary); text-decoration: underline; }

/* Openingstijden als definitielijst en niet als tabel: het is hier een
   samenvatting naast het formulier, geen rooster om in te zoeken. De tabel
   met alle tijden staat op zijn eigen pagina. */
.contact-hours {
    margin: 0 0 var(--ff-space-md);
    font-size: var(--ff-text-sm);
}

.contact-hours div {
    display: flex;
    justify-content: space-between;
    gap: var(--ff-space-md);
    padding: .35rem 0;
    border-bottom: 1px solid var(--ff-hairline);
}

.contact-hours div:last-child { border-bottom: 0; }

.contact-hours dt { color: var(--ff-white); margin: 0; }

.contact-hours dd {
    margin: 0;
    color: var(--ff-on-dark-muted);
    text-align: right;
    white-space: nowrap;
}

.contact-hours .is-closed { font-style: italic; }

/* 20.4 De kaart --------------------------------------------------------- */
/* Volle breedte, met een rand boven en onder zodat hij niet als een gat in
   de pagina leest. De hoogte groeit mee met het scherm. */
.map-section { padding-top: var(--ff-section-y); }

.map-pane {
    width: 100%;
    height: 320px;
    overflow: hidden;
    border-top: 1px solid var(--ff-hairline);
    border-bottom: 1px solid var(--ff-hairline);
    background-color: var(--ff-harmony);
}

.map-pane iframe { display: block; width: 100%; height: 100%; border: 0; }

/* DNN zet lagen om de inhoud van een module heen, en welke dat zijn hangt af
   van de container die bij de module is gekozen: met Blank.ascx komen daar
   .fame-container en .ContainerPane bij, zonder container staat er alleen een
   naamloze ContentPane-div. Een hoogte van 100% zakt maar door zolang elke
   laag hem doorgeeft, dus geven we hem aan elke div in deze paal in plaats
   van aan een lijstje klassen dat een laag kan missen. Zet in deze paal dan
   ook alleen de kaart, geen bijschrift ernaast. */
.map-pane > div,
.map-pane > div div { height: 100%; }

@media (min-width: 768px) { .map-pane { height: 420px; } }
@media (min-width: 992px) { .map-pane { height: 520px; } }

/* Zonder kaartmodule geen strook van 320 pixels met niets erin. */
.map-pane.DNNEmptyPane { display: none; }
.dnnEditState .map-pane.DNNEmptyPane { display: block; }

/* De uitleg die in plaats van de kaart staat zolang er geen toestemming is
   voor marketingcookies, moet zichzelf kunnen centreren in die 320px. */
.map-pane .cookie-placeholder {
    display: flex;
    height: 100%;
    align-items: center;
    justify-content: center;
    margin: 0;
    border-radius: 0;
}

/* 20.5 Oude opmaak: layout-1 en de infoCard ----------------------------- */
/* Deze markup zat tot 01.11.00 op de contactpagina en kan nog in bestaande
   modules staan. Ze blijft werken, maar zonder de negatieve marge waarmee
   het formulier over de kaart heen schoof. */
.contact-section .layout-1 {
    padding: 1rem 0 3rem;
    color: var(--ff-white);
}

.contact-section .layout-1 strong { color: inherit; }
.contact-section .layout-1 .text { margin: 1rem 0; color: var(--ff-white); }

.infoCard {
    margin-left: auto;
    margin-right: auto;
    display: flex;
    flex-direction: column;
    gap: var(--ff-space-md);
    padding: var(--ff-space-lg) var(--ff-space-md);
    background-color: var(--ff-harmony);
    max-width: 420px;
    border-radius: var(--ff-radius-lg);
    border: 1px solid var(--ff-hairline);
    border-top: 3px solid var(--ff-primary);
}

.infoCard .block { width: 100%; padding: .25rem 0; }

.infoCard .block h2,
.infoCard .block h3 {
    color: var(--ff-white);
    font-size: var(--ff-h5);
    margin-top: 0;
    margin-bottom: var(--ff-space-2xs);
}

.infoCard .block .text,
.infoCard .block p { color: var(--ff-on-dark-muted); }

.infoCard .block a { color: var(--ff-white); text-decoration: none; }
.infoCard .block a:hover { color: var(--ff-primary); text-decoration: underline; }

.infoCard .block ul { list-style: none; padding-inline-start: 0; margin: 0; }
.infoCard .block li { color: var(--ff-white); }

/* Afbeelding met blauwe balk (layout-2 uit het bronproject) */
.img-holder {
    position: relative;
    overflow: hidden;
    padding: 1rem;
    margin: 1rem 0;
}

.img-holder::after {
    content: ' ';
    background-color: var(--ff-primary);
    position: absolute;
    top: 0;
    left: 0;
    width: 30px;
    height: 100%;
}

.img-holder img {
    position: relative;
    z-index: 1;
    border-radius: var(--ff-radius);
    box-shadow: 0 4px 16px 0 rgba(22,42,90,.35);
}

/* --------------------------------------------------------------------------
   21. Formuliermodules (.fame-form)
   Alles binnen de container Form.ascx krijgt de vormgeving van het
   contactformulier van famefitness.nl. Werkt met 2sxc / Mobius Forms,
   met Form and List (UserDefinedTable) en met kale HTML-formulieren.

   Let op: sectie 13 geeft .dnnForm bewust een lichte, leesbare opmaak voor
   beheerschermen. Dit blok staat later en wint binnen .fame-form.
   -------------------------------------------------------------------------- */
.fame-form { width: 100%; }

/* 21.1 Rijen en velden -------------------------------------------------- */
.fame-form .form-row {
    display: flex;
    flex-wrap: wrap;
    margin-right: -5px;
    margin-left: -5px;
}

.fame-form .form-row:not(:last-child) { margin-bottom: 1rem; }
.fame-form .form-row > [class*="col-"] { padding-right: 5px; padding-left: 5px; }

.fame-form .form-group,
.fame-form .mobius-group,
.fame-form .dnnFormItem { margin-bottom: 1rem; }

/* 21.2 Invoervelden ----------------------------------------------------- */
.fame-form input[type="text"],
.fame-form input[type="email"],
.fame-form input[type="tel"],
.fame-form input[type="url"],
.fame-form input[type="number"],
.fame-form input[type="date"],
.fame-form input[type="time"],
.fame-form input[type="search"],
.fame-form input[type="password"],
.fame-form select,
.fame-form textarea,
.fame-form .formBox,
.fame-form .form-control,
.fame-form .dnnForm input[type="text"],
.fame-form .dnnForm input[type="email"],
.fame-form .dnnForm input[type="password"],
.fame-form .dnnForm select,
.fame-form .dnnForm textarea {
    position: relative;
    display: block;
    width: 100%;
    max-width: 100%;
    padding: 16px 14px;
    font-size: 17px;
    font-family: var(--ff-font-body);
    color: var(--ff-white);
    background-color: #212121;
    border: 3px solid var(--ff-primary);
    border-radius: var(--ff-radius);
    box-shadow: 0 4px 16px 0 rgba(22,42,90,.35);
    outline: 0;
    -webkit-appearance: none;
    appearance: none;
    margin-bottom: 1rem;
}

.fame-form select,
.fame-form select.form-control {
    /* eigen pijltje, want appearance staat uit */
    background-image: linear-gradient(45deg, transparent 50%, var(--ff-primary) 50%),
                      linear-gradient(135deg, var(--ff-primary) 50%, transparent 50%);
    background-position: calc(100% - 22px) calc(50% + 2px), calc(100% - 15px) calc(50% + 2px);
    background-size: 7px 7px, 7px 7px;
    background-repeat: no-repeat;
    padding-right: 44px;
}

.fame-form textarea {
    resize: vertical;
    min-height: 160px;
    line-height: normal;
}

.fame-form ::placeholder {
    color: var(--ff-white);
    font-weight: bold;
    opacity: .85;
}

.fame-form input:focus,
.fame-form select:focus,
.fame-form textarea:focus,
.fame-form .form-control:focus {
    border-color: var(--ff-white);
    box-shadow: 0 0 0 3px rgba(37,192,255,.35);
}

/* Autofill niet wit laten worden */
.fame-form input:-webkit-autofill,
.fame-form input:-webkit-autofill:hover,
.fame-form input:-webkit-autofill:focus {
    -webkit-text-fill-color: var(--ff-white);
    -webkit-box-shadow: 0 0 0 1000px #212121 inset;
}

/* 21.3 Labels ----------------------------------------------------------- */
.fame-form label,
.fame-form .dnnLabel label,
.fame-form .dnnFormItem > label,
.fame-form .form-label {
    display: inline-block;
    margin-bottom: .35rem;
    color: var(--ff-white);
    font-family: var(--ff-font-body);
    font-size: 1rem;
    width: auto;
    float: none;
    text-align: left;
}

.fame-form .app-mobius6-field-required::after,
.fame-form label.required::after {
    content: ' *';
    color: var(--ff-primary);
}

.fame-form .small-infotext,
.fame-form .dnnFormHelp,
.fame-form .form-text {
    color: var(--ff-gray);
    font-size: .85rem;
}

/* 21.4 Keuzevakjes en keuzerondjes -------------------------------------- */
.fame-form input[type="checkbox"],
.fame-form input[type="radio"] {
    width: 1.35em;
    height: 1.35em;
    min-height: 0;
    margin-right: .6rem;
    accent-color: var(--ff-primary);
    vertical-align: -3px;
    flex: none;
}

/* Het vakje zelf is klein, dus het label eromheen levert het aanraakdoel.
   Klikken op de tekst schakelt het vakje mee. */
.fame-form .form-check,
.fame-form .checkbox,
.fame-form .radio { margin-bottom: .5rem; }

.fame-form .form-check-label,
.fame-form .checkbox label,
.fame-form .radio label {
    color: var(--ff-white);
    display: flex;
    align-items: center;
    min-height: 44px;
    cursor: pointer;
    font-size: var(--ff-text-base);
    font-weight: var(--ff-weight-body);
}

/* 21.5 Knoppen ---------------------------------------------------------- */
.fame-form button[type="submit"],
.fame-form input[type="submit"],
.fame-form .dnnPrimaryAction,
.fame-form a.dnnPrimaryAction {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    border: 2px solid var(--ff-primary);
    border-radius: var(--ff-radius);
    cursor: pointer;
    padding: .7rem 1.5rem;
    min-height: 48px;
    transition: background-color var(--ff-dur) var(--ff-ease), box-shadow var(--ff-dur) var(--ff-ease);
    font-family: var(--ff-font-button);
    font-weight: var(--ff-weight-button);
    font-size: clamp(1.175rem, 1.12rem + .28vw, 1.3rem);
    line-height: 1.2;
    color: var(--ff-white);
    background: var(--ff-primary-dark);
    text-shadow: 1px 1px 3px #0c0c0c;
    text-decoration: none;
}

.fame-form button[type="submit"]:hover,
.fame-form input[type="submit"]:hover,
.fame-form .dnnPrimaryAction:hover { background: var(--ff-primary-hover); color: var(--ff-white); }

.fame-form button[type="submit"][disabled],
.fame-form input[type="submit"][disabled] { opacity: .6; cursor: not-allowed; }

.fame-form button svg.icon,
.fame-form button svg {
    width: 20px;
    max-height: 30px;
    fill: var(--ff-white);
}

.fame-form .dnnSecondaryAction,
.fame-form a.dnnSecondaryAction {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: .7rem 1.5rem;
    min-height: 48px;
    border: 2px solid var(--ff-white);
    border-radius: var(--ff-radius);
    background: transparent;
    color: var(--ff-white);
    font-family: var(--ff-font-button);
    font-weight: var(--ff-weight-button);
    font-size: clamp(1.175rem, 1.12rem + .28vw, 1.3rem);
    text-decoration: none;
}

@media (max-width: 600px) {
    .fame-form button[type="submit"],
    .fame-form input[type="submit"],
    .fame-form .dnnPrimaryAction { width: 100%; }
}

/* 21.6 Validatie en meldingen ------------------------------------------- */
.fame-form .pristine-error,
.fame-form .field-validation-error,
.fame-form .dnnFormMessage.dnnFormError,
.fame-form span[id*="Validator"],
.fame-form .invalid-feedback {
    display: block;
    color: #ff8a8a;
    font-size: .9rem;
    margin: -.5rem 0 1rem;
}

.fame-form .has-error input,
.fame-form .has-error textarea,
.fame-form .invalid,
.fame-form input.invalid,
.fame-form textarea.invalid,
.fame-form select.invalid,
.fame-form .input-validation-error {
    border-color: var(--ff-autumn-red);
    animation: fame-shake .82s cubic-bezier(.36,.07,.19,.97) both;
}

.fame-form .app-mobius6-message,
.fame-form .alert,
.fame-form .dnnFormMessage {
    display: block;
    padding: .85rem 1rem;
    margin-bottom: var(--ff-space-md);
    border-radius: var(--ff-radius-md);
    color: var(--ff-white);
    background-color: var(--ff-harmony);
    border: 1px solid #2f2f2f;
}

/* Groen en oranje zijn te licht voor witte tekst (1.95:1 en 3.1:1), dus daar
   staat de tekst donker. Rood houdt wel wit. */
.fame-form .alert-success,
.fame-form .dnnFormMessage.dnnFormSuccess {
    background-color: var(--ff-summer-green);
    border-color: #4e8a0d;
    color: var(--ff-on-signal);
}

.fame-form .alert-warning {
    background-color: var(--ff-carrot-orange);
    border-color: #9a5e00;
    color: var(--ff-on-signal);
}

.fame-form .alert-success a,
.fame-form .alert-success strong,
.fame-form .alert-warning a,
.fame-form .alert-warning strong { color: inherit; }

.fame-form .alert-danger,
.fame-form .alert-error,
.fame-form .dnnFormMessage.dnnFormValidationSummary { background-color: var(--ff-autumn-red); border-color: var(--ff-autumn-red); }

.fame-form .validation-summary-errors ul { list-style: none; padding-left: 0; margin: 0; }

@keyframes fame-shake {
    10%, 90% { transform: translate3d(-1px, 0, 0); }
    20%, 80% { transform: translate3d(2px, 0, 0); }
    30%, 50%, 70% { transform: translate3d(-4px, 0, 0); }
    40%, 60% { transform: translate3d(4px, 0, 0); }
}

/* 21.7 2sxc / Mobius Forms --------------------------------------------- */
.fame-form .app-mobius6-wrapper { width: 100%; }

.fame-form .mobius-groups { width: 100%; }

.fame-form .mobius-group.row {
    margin-right: -15px;
    margin-left: -15px;
}

/* Mobius zet kolombreedtes zonder responsive prefix (col-6 blijft ook op een
   telefoon 50%). Onder 576px zetten we de velden onder elkaar. */
@media (max-width: 575px) {
    .fame-form .mobius-group > [class*="col-"] {
        flex: 0 0 100%;
        max-width: 100%;
    }
}

/* Stappenbalk van het formulier met meerdere stappen */
.fame-form .app-mobius-steps {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    list-style: none;
    padding-left: 0;
    margin-bottom: 1.5rem;
}

.fame-form .app-mobius-step {
    padding: .35rem .85rem;
    border-radius: var(--ff-radius);
    background-color: var(--ff-harmony);
    color: var(--ff-gray);
    font-size: .9rem;
}

.fame-form .app-mobius-step.active,
.fame-form .app-mobius-step.finished {
    background-color: var(--ff-primary-dark);
    color: var(--ff-white);
}

.fame-form .recaptcha { margin-bottom: 1rem; }
.fame-form .hiddenInputStyle { display: none; }

/* De reCAPTCHA-badge mag niet onder de terug-naar-boven-knop vallen */
.grecaptcha-badge { z-index: 2; }

/* 21.8 Form and List (UserDefinedTable) --------------------------------- */
/* Het formulier van Form and List is een .dnnForm, en sectie 13 geeft elke
   .dnnForm juist een lichte opmaak met donkere tekst - dat is precies goed
   in de beheerschermen en precies fout op een zwarte contactpagina. Deze
   regels zetten dat binnen .fame-form terug, met dezelfde specificiteit als
   sectie 13 en later in het bestand.

   De markup komt uit Form.ascx van de module:
     div.dnnForm.fnlForm > div.dnnFormItem
       > div.dnnFormLabelWithoutHelp > label > span   (of .dnnLabel bij hulptekst)
       > het invoerveld
     ul.dnnActions > li > a.dnnPrimaryAction                                  */
.fame-form .fnlForm,
.fame-form .fnlForm p,
.fame-form .fnlForm li,
.fame-form .fnlForm td,
.fame-form .fnlForm th { color: var(--ff-white); }

.fame-form .fnlForm { width: 100%; }

/* Label boven het veld, niet ernaast: DNN's eigen formulieropmaak zet het
   label op 30% breedte links, en dan blijft er op een telefoon een kolom
   van twee woorden over. */
.fame-form .fnlForm .dnnFormItem {
    display: block;
    width: 100%;
    margin-bottom: var(--ff-space-md);
}

.fame-form .fnlForm .dnnFormItem > .dnnFormLabelWithoutHelp,
.fame-form .fnlForm .dnnFormItem > .dnnLabel {
    display: block;
    width: 100%;
    float: none;
    margin: 0 0 var(--ff-space-2xs);
    text-align: left;
}

.fame-form .fnlForm :is(.dnnFormLabelWithoutHelp, .dnnLabel) label,
.fame-form .fnlForm :is(.dnnFormLabelWithoutHelp, .dnnLabel) span {
    display: inline;
    width: auto;
    color: var(--ff-white);
    font-family: var(--ff-font-body);
    font-size: var(--ff-text-sm);
    font-weight: var(--ff-weight-medium);
    letter-spacing: .01em;
}

/* Verplicht veld: de module zet dnnFormRequired op het invoerveld, dus de
   ster hoort bij het label ernaast. Zonder :has() blijft alles zoals het
   is - het veld is dan nog steeds verplicht, alleen zonder aankondiging. */
.fame-form .fnlForm .dnnFormItem:has(.dnnFormRequired) :is(.dnnFormLabelWithoutHelp, .dnnLabel) label::after {
    content: ' *';
    color: var(--ff-primary);
}

/* De velden zelf. Sectie 21.2 pakt input en textarea al, maar niet de
   breedte binnen deze module en niet de select van een keuzelijst. */
.fame-form .fnlForm :is(input[type="text"], input[type="email"], input[type="tel"], input[type="url"], input[type="number"], input[type="date"], select, textarea) {
    width: 100%;
    max-width: 100%;
}

.fame-form .fnlForm textarea { min-height: 9rem; resize: vertical; }

.fame-form .fnlForm .dnnFormItem > input[type="checkbox"],
.fame-form .fnlForm .dnnFormItem > input[type="radio"] { width: auto; }

/* Hulptekst als regel onder het label, niet als uitklapper opzij.

   DNN hangt de tekst in een <div class="dnnTooltip"> van 200 pixels breed, met
   een inline `position:absolute; right:-29%` erop, en zet de inhoud daarvan op
   visibility:hidden tot je op het vraagtekentje klikt - een postback. Op de
   contactpagina ging dat twee keer mis: de tekst die de redacteur invoert was
   nergens te zien, en dat blokje stak 72 pixels buiten het scherm, waardoor de
   hele pagina zijwaarts schoof. Gemeten op famefitness.nl op 807px:
   scrollWidth 878 tegen clientWidth 807.

   De inline stijl is de reden voor !important; die kan een stylesheet niet op
   een andere manier overrulen. */
.fame-form .fnlForm .dnnLabel .dnnFormHelp,
.fame-form .fnlForm .dnnLabel .pinHelp { display: none; }

.fame-form .fnlForm .dnnLabel .dnnTooltip {
    position: static !important;
    right: auto !important;
    left: auto !important;
    top: auto !important;
    width: auto;
}

.fame-form .fnlForm .dnnLabel .dnnFormHelpContent,
.fame-form .fnlForm .dnnLabel .dnnFormHelpContent span {
    position: static;
    visibility: visible;
    width: auto;
    max-width: none;
    color: var(--ff-on-dark-muted);
}

.fame-form .fnlForm .dnnLabel .dnnFormHelpContent {
    display: block;
    margin: var(--ff-space-2xs) 0 0;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    font-size: var(--ff-text-sm);
    font-weight: var(--ff-weight-body);
    line-height: var(--ff-leading-body);
}

/* Losse hulptekst zonder tooltip (andere DNN-versies, en de beheerschermen
   van de module zelf). */
.fame-form .fnlForm .dnnFormHelp .dnnHelpText,
.fame-form .fnlForm .dnnTooltip .dnnHelpText {
    position: static;
    display: block;
    width: auto;
    max-width: none;
    margin-top: var(--ff-space-2xs);
    padding: 0;
    border: 0;
    background: transparent;
    box-shadow: none;
    color: var(--ff-on-dark-muted);
    font-size: var(--ff-text-sm);
}

/* Kop tussen de velden (een veld van het type Separator). */
.fame-form .fnlForm .dnnFormSectionHead {
    margin: var(--ff-space-lg) 0 var(--ff-space-md);
    color: var(--ff-white);
    font-size: var(--ff-h5);
}

.fame-form .fnlForm .dnnFormSectionHead:first-child { margin-top: 0; }

/* De controlevraag tegen spam. De afbeelding staat naast een smal veld;
   op 320px past dat naast elkaar niet meer. */
.fame-form .fnlForm .dnnFormItem img {
    display: block;
    max-width: 100%;
    height: auto;
    margin-bottom: var(--ff-space-xs);
    border-radius: var(--ff-radius);
}

/* Knoppenrij. De module levert links met de klasse van een DNN-knop; sectie
   21.5 geeft die al de vorm van een themaknop, hier alleen de plaatsing. */
.fame-form .fnlForm .dnnActions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ff-space-sm);
    margin: var(--ff-space-lg) 0 0;
    padding: 0;
    list-style: none;
}

.fame-form .fnlForm .dnnActions li { margin: 0; }

@media (max-width: 575px) {
    .fame-form .fnlForm .dnnActions { flex-direction: column; }
    .fame-form .fnlForm .dnnActions li,
    .fame-form .fnlForm .dnnActions .dnnPrimaryAction,
    .fame-form .fnlForm .dnnActions .dnnSecondaryAction { width: 100%; text-align: center; }
}

/* Bevestiging na het versturen. Die komt in een eigen div ná het formulier;
   sectie 21.6 geeft hem de kleuren, hier de ruimte. */
.fame-form .dnnFormMessage.dnnFormSuccess { margin-top: var(--ff-space-md); }

/* Lijstweergave van Form and List, en de oudere tabelmarkup. Die blijft in
   het thema staan: een Form and List die als lijst is ingesteld gebruikt hem
   nog steeds. */
.fame-form .dnnFormAndList { width: 100%; }

.fame-form .dnnFormAndList table,
.fame-form table.UDT_Table {
    width: 100%;
    border-collapse: collapse;
    background: transparent;
}

.fame-form .dnnFormAndList td,
.fame-form .dnnFormAndList th {
    padding: .25rem 0;
    vertical-align: top;
    color: var(--ff-white);
    background: transparent;
    border: 0;
}

@media (max-width: 767px) {
    .fame-form .dnnFormAndList table,
    .fame-form .dnnFormAndList tbody,
    .fame-form .dnnFormAndList tr,
    .fame-form .dnnFormAndList td {
        display: block;
        width: 100%;
    }
}

.fame-form .UDT_Caption,
.fame-form .UDT_UponSubmit { color: var(--ff-white); }

.fame-form .UDT_UponSubmit {
    padding: .85rem 1rem;
    border-radius: var(--ff-radius);
    background-color: var(--ff-harmony);
    border: 1px solid #2a2a2a;
}

.fame-form .UDT_Table_Head,
.fame-form .dnnGridHeader,
.fame-form .DataGrid_Header {
    background-color: var(--ff-primary-dark);
    color: var(--ff-white);
    font-family: var(--ff-font-heading);
    font-weight: var(--ff-weight-heading);
    padding: .5rem .75rem;
    text-align: left;
}

.fame-form .UDT_Table_Item,
.fame-form .DataGrid_Item { background-color: var(--ff-harmony); }

.fame-form .UDT_Table_AlternateItem,
.fame-form .DataGrid_AlternatingItem { background-color: #141414; }

.fame-form .UDT_Table_Item td,
.fame-form .UDT_Table_AlternateItem td,
.fame-form .DataGrid_Item td,
.fame-form .DataGrid_AlternatingItem td { padding: .5rem .75rem; }

/* DNN's eigen tekstklassen binnen het formulier */
.fame-form .Normal,
.fame-form .NormalBold,
.fame-form .SubHead,
.fame-form .Head { color: var(--ff-white); font-family: var(--ff-font-body); }

.fame-form .NormalBold,
.fame-form .SubHead { font-weight: 700; }

/* 21.9 Lichte variant, voor een formulier op een lichte achtergrond ----- */
.fame-form._light input[type="text"],
.fame-form._light input[type="email"],
.fame-form._light input[type="tel"],
.fame-form._light select,
.fame-form._light textarea,
.fame-form._light .form-control {
    background-color: var(--ff-white);
    color: #333;
    box-shadow: none;
}

.fame-form._light ::placeholder { color: var(--ff-muted); font-weight: normal; }
.fame-form._light label { color: #333; }


/* --------------------------------------------------------------------------
   22. Cookiebanner en -voorkeuren (js/fame-cookieconsent.js)
   De banner en het voorkeurenvenster worden door dat script opgebouwd; hier
   staat alleen de vormgeving. Dezelfde tokens als de rest van het thema, dus
   de banner erft automatisch de kleuren en de knopstijlen.
   -------------------------------------------------------------------------- */

/* 22.1 Banner ------------------------------------------------------------
   Onderaan het scherm, boven de "terug naar boven"-knop (z-index 90) maar
   onder een geopend voorkeurenvenster. */
.cookie-banner {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 120;
    background-color: var(--ff-harmony);
    border-top: 1px solid var(--ff-hairline-strong);
    box-shadow: var(--ff-shadow-lg);
    color: var(--ff-white);
    padding: var(--ff-space-lg) var(--ff-gutter);
    opacity: 0;
    transform: translateY(100%);
    transition: opacity var(--ff-dur) var(--ff-ease),
                transform var(--ff-dur) var(--ff-ease);
}

.cookie-banner.is-visible {
    opacity: 1;
    transform: none;
}

.cookie-banner-inner {
    max-width: var(--ff-maxwidth);
    margin: 0 auto;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--ff-space-lg);
}

.cookie-banner-text {
    flex: 1 1 min(30rem, 100%);
    min-width: 0;
}

.cookie-banner-title {
    font-family: var(--ff-font-heading);
    font-weight: var(--ff-weight-heading);
    font-size: var(--ff-h5);
    line-height: var(--ff-leading-heading);
    margin: 0 0 var(--ff-space-2xs);
}

.cookie-banner-text p {
    margin: 0;
    font-size: var(--ff-text-sm);
    color: var(--ff-gray);
}

.cookie-banner-text a {
    color: var(--ff-primary);
    text-decoration: underline;
}

.cookie-banner-text a:hover { color: var(--ff-white); }

/* De drie knoppen hebben bewust hetzelfde formaat: weigeren mag niet
   moeilijker zijn dan accepteren. */
.cookie-banner-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ff-space-sm);
    align-items: center;
}

.cookie-banner-actions .btn { flex: 1 1 auto; }

/* Onder de tabletgrens onder elkaar, elk over de volle breedte. */
@media (max-width: 767px) {
    .cookie-banner { padding: var(--ff-space-md); }
    .cookie-banner-inner { gap: var(--ff-space-md); }
    .cookie-banner-actions { width: 100%; }
    .cookie-banner-actions .btn { flex: 1 1 100%; }
}

/* De banner ligt over de "terug naar boven"-knop heen. Die knop een stukje
   verplaatsen helpt niet - de banner is op mobiel bijna een half scherm hoog -
   dus hij blijft weg zolang de melding open staat. */
html.has-cookie-banner .scrollTop {
    opacity: 0;
    visibility: hidden;
}

/* De focusring uit hoofdstuk 4 is bereikt via .fame; banner en venster hangen
   los in de body, dus die krijgen hem hier. */
.cookie-banner :focus-visible,
.cookie-dialog :focus-visible,
.cookie-placeholder :focus-visible {
    outline: 3px solid var(--ff-primary);
    outline-offset: 3px;
    border-radius: var(--ff-radius);
}

/* 22.2 Voorkeurenvenster ------------------------------------------------- */
.cookie-dialog {
    position: fixed;
    inset: 0;
    z-index: 130;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--ff-gutter);
    opacity: 0;
    transition: opacity var(--ff-dur) var(--ff-ease);
}

.cookie-dialog[hidden] { display: none; }
.cookie-dialog.is-open { opacity: 1; }

.cookie-dialog-backdrop {
    position: absolute;
    inset: 0;
    background-color: rgba(0,0,0,.75);
}

.cookie-dialog-panel {
    position: relative;
    width: min(46rem, 100%);
    max-height: calc(100vh - 2 * var(--ff-gutter));
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    background-color: var(--ff-harmony);
    border: 1px solid var(--ff-hairline-strong);
    border-radius: var(--ff-radius-lg);
    box-shadow: var(--ff-shadow-lg);
    padding: clamp(1.25rem, 1rem + 1.2vw, 2rem);
    transform: translateY(12px);
    transition: transform var(--ff-dur) var(--ff-ease);
}

.cookie-dialog.is-open .cookie-dialog-panel { transform: none; }

.cookie-dialog-title {
    font-family: var(--ff-font-heading);
    font-weight: var(--ff-weight-heading);
    font-size: var(--ff-h4);
    line-height: var(--ff-leading-heading);
    margin: 0 2.5rem var(--ff-space-xs) 0;
}

.cookie-dialog-intro,
.cookie-dialog-more {
    font-size: var(--ff-text-sm);
    color: var(--ff-on-dark-muted);
    margin: 0 0 var(--ff-space-lg);
}

.cookie-dialog-more { margin: var(--ff-space-md) 0 0; }

.cookie-dialog-more a {
    color: var(--ff-primary);
    text-decoration: underline;
}

.cookie-dialog-close {
    position: absolute;
    top: var(--ff-space-sm);
    right: var(--ff-space-sm);
    width: 44px;
    height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 0;
    border-radius: 50%;
    color: var(--ff-white);
    cursor: pointer;
    transition: background-color var(--ff-dur) var(--ff-ease);
}

.cookie-dialog-close:hover { background-color: rgba(255,255,255,.1); }
.cookie-dialog-close svg { width: 20px; height: 20px; }

/* 22.3 Categorieën ------------------------------------------------------- */
.cookie-groups {
    display: flex;
    flex-direction: column;
    gap: var(--ff-space-md);
}

.cookie-group {
    background-color: rgba(255,255,255,.03);
    border: 1px solid var(--ff-hairline);
    border-radius: var(--ff-radius-md);
    padding: var(--ff-space-md);
}

.cookie-group-text {
    margin: var(--ff-space-2xs) 0 0;
    font-size: var(--ff-text-sm);
    color: var(--ff-on-dark-muted);
}

/* Schakelaar. Onder de vormgeving zit een gewone checkbox: die kent de
   browser al, dus toetsenbord, schermlezer en formulierstatus kloppen
   vanzelf. Het vinkje zelf staat buiten beeld in plaats van op display:none,
   want dan is het niet meer focusbaar. */
.cookie-switch {
    display: flex;
    align-items: center;
    gap: var(--ff-space-sm);
    cursor: pointer;
    font-family: var(--ff-font-heading);
    font-weight: var(--ff-weight-medium);
}

.cookie-switch-input {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0,0,0,0);
    border: 0;
}

.cookie-switch-track {
    flex: 0 0 auto;
    position: relative;
    width: 46px;
    height: 26px;
    border-radius: 13px;
    background-color: #2a2a2a;
    border: 1px solid var(--ff-hairline-strong);
    transition: background-color var(--ff-dur) var(--ff-ease),
                border-color var(--ff-dur) var(--ff-ease);
}

.cookie-switch-track::after {
    content: '';
    position: absolute;
    top: 2px;
    left: 2px;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background-color: var(--ff-white);
    transition: transform var(--ff-dur) var(--ff-ease);
}

.cookie-switch-input:checked + .cookie-switch-track {
    background-color: var(--ff-primary-dark);
    border-color: var(--ff-primary);
}

.cookie-switch-input:checked + .cookie-switch-track::after { transform: translateX(20px); }

.cookie-switch-input:focus-visible + .cookie-switch-track {
    outline: 2px solid var(--ff-primary);
    outline-offset: 2px;
}

/* Noodzakelijk staat vast aan: wel zichtbaar aan, niet bedienbaar. */
.cookie-switch-input:disabled + .cookie-switch-track {
    background-color: var(--ff-primary-dark);
    border-color: var(--ff-primary);
    opacity: .55;
}

.cookie-switch-input:disabled ~ .cookie-switch-label { color: var(--ff-on-dark-muted); }
.cookie-switch-input:disabled { cursor: default; }

.cookie-dialog-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ff-space-sm);
    margin-top: var(--ff-space-lg);
}

.cookie-dialog-actions .btn { flex: 1 1 12rem; }

@media (max-width: 600px) {
    .cookie-dialog-actions .btn { flex: 1 1 100%; }
}

/* 22.4 Geblokkeerde inhoud ----------------------------------------------
   Staat in de plaats van een kaart of video zolang de bijbehorende categorie
   niet is toegestaan. */
.cookie-placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--ff-space-md);
    min-height: 220px;
    padding: var(--ff-space-xl) var(--ff-space-md);
    text-align: center;
    background-color: var(--ff-harmony);
    border: 1px dashed var(--ff-hairline-strong);
    border-radius: var(--ff-radius-md);
}

.cookie-placeholder-text {
    margin: 0;
    max-width: 34rem;
    font-size: var(--ff-text-sm);
    color: var(--ff-gray);
}

.cookie-placeholder-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--ff-space-md);
}

.cookie-placeholder-link {
    background: transparent;
    border: 0;
    cursor: pointer;
    padding: 0;
    min-height: 44px;
}

iframe.is-blocked { display: none; }

/* De cookielink in de footer staat tussen de copyrightregel; als knop
   opgemaakt zodat hij ook zonder javascript-url werkt. */
.cookie-settings-link {
    background: transparent;
    border: 0;
    padding: 0;
    margin-left: .35rem;
    color: inherit;
    font: inherit;
    text-decoration: underline;
    cursor: pointer;
}

.cookie-settings-link:hover { color: var(--ff-primary); }

/* 22.5 Minder beweging --------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    .cookie-banner,
    .cookie-dialog,
    .cookie-dialog-panel,
    .cookie-switch-track,
    .cookie-switch-track::after { transition: none; }

    .cookie-banner { transform: none; }
}

/* --------------------------------------------------------------------------
   23. Aanmeldschermen (Auth.ascx en de DNN-modules erin)
   Dekt de markup die DNN zelf levert voor Account Login (inclusief de
   DNN-aanbieder), Wachtwoord vergeten (SendPassword), Wachtwoord opnieuw
   instellen (PasswordReset) en Wachtwoord wijzigen (Password) - dat laatste
   is het scherm dat een uitgenodigde gebruiker bij zijn eerste aanmelding
   krijgt. Zelf registreren kan op deze site niet, dus het registratie-
   formulier van DNN staat hier bewust niet bij.

   Bereik: .fame:not(.fame-light). Daarmee geldt het ook wanneer de
   inlogmodule op een gewone donkere pagina staat, terwijl de Edit-layout -
   die voor beheerschermen bewust licht is - erbuiten blijft. Sectie 13 geeft
   .dnnForm daar donkere tekst; op een zwarte pagina is dat onleesbaar, dus
   hieronder wint de donkere variant met een klasse extra specificiteit.

   DNN laadt op elke pagina zijn eigen default.css
   (Resources/Shared/stylesheets/dnndefault/8.0.0/). Daar staan een zwevend
   label van 32% breed, rechts uitgelijnd, witte velden van 12px en blauwe
   verloopknoppen. Die regels worden hieronder gericht overschreven.
   -------------------------------------------------------------------------- */

/* 23.1 De layout zelf ---------------------------------------------------- */
/* Geen vaste navigatiebalk op deze layout, dus ook geen ruimte ervoor.
   De gloed bovenin is dezelfde blauwtint als de rest van het thema. */
.fame-auth > .content {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--ff-space-2xl) var(--ff-gutter);
    background-image: radial-gradient(70% 45% at 50% 0%, rgba(37,192,255,.16) 0%, rgba(37,192,255,0) 70%);
}

.auth-shell {
    width: 100%;
    max-width: 520px;
    margin: 0 auto;
}

.auth-logo {
    display: block;
    text-align: center;
    margin-bottom: var(--ff-space-xl);
}

.auth-card {
    background-color: var(--ff-harmony);
    border: 1px solid var(--ff-hairline);
    border-radius: var(--ff-radius-lg);
    padding: clamp(1.25rem, .85rem + 2vw, 2.5rem);
    box-shadow: var(--ff-shadow-lg);
}

.fame-auth .auth-title {
    margin: 0 0 var(--ff-space-lg);
    font-size: var(--ff-h3);
    line-height: var(--ff-leading-heading);
    color: var(--ff-white);
    text-align: center;
}

.auth-pane:not(:empty) + .auth-pane:not(:empty) { margin-top: var(--ff-space-lg); }

.auth-back {
    margin: var(--ff-space-lg) 0 0;
    text-align: center;
    font-size: var(--ff-text-sm);
}

.auth-back a { color: var(--ff-on-dark-muted); }
.auth-back a:hover { color: var(--ff-primary); }

.auth-footer {
    flex: none;
    padding: var(--ff-space-md) var(--ff-gutter) var(--ff-space-xl);
    text-align: center;
    color: var(--ff-on-dark-muted);
    font-size: var(--ff-text-sm);
}

.auth-footer a,
.auth-footer .cookie-settings-link { color: var(--ff-on-dark-muted); }

.auth-footer a:hover,
.auth-footer .cookie-settings-link:hover { color: var(--ff-primary); }

/* De skinobjecten in de voettekst staan zonder scheiding achter elkaar; een
   punt ertussen scheelt een wrapper per object. */
.auth-footer > * + *::before {
    content: "\00b7";
    margin: 0 .5rem;
    color: var(--ff-hairline-strong);
}

/* 23.2 De modulewrapper -------------------------------------------------- */
.fame:not(.fame-light) :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword),
.fame:not(.fame-light) :is(.loginContent, .LoginPanel, .LoginContainerGroup, .LoginContainer, .dnnSendPasswordContent, .dnnPasswordResetContent, .associateContent) {
    width: 100%;
    max-width: 100%;
    margin: 0;
    color: var(--ff-white);
}

/* label staat hier ook in: sectie 13 zet alle labels binnen .dnnForm op
   #333, en een keuzevakjeslabel zit niet in een .dnnLabel-wrapper. */
.fame:not(.fame-light) :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword) :is(p, li, td, span, label, h2, h3, h4) { color: var(--ff-white); }

.fame:not(.fame-light) :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword) :is(h2, h3, h4) {
    margin: 0 0 var(--ff-space-md);
    font-family: var(--ff-font-heading);
    font-weight: var(--ff-weight-heading);
    font-size: var(--ff-h4);
}

.fame:not(.fame-light) :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword) a:not(.dnnPrimaryAction):not(.dnnSecondaryAction) {
    color: var(--ff-primary);
    text-decoration: underline;
}

/* 23.3 Labels boven het veld --------------------------------------------- */
/* DNN laat het label naast het veld zweven op 32% breedte, rechts
   uitgelijnd. Op een kaart van 520px levert dat twee smalle kolommen op. */
.fame:not(.fame-light) :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword) .dnnFormItem {
    position: relative;
    display: block;
    clear: both;
    margin-bottom: var(--ff-space-md);
}

.fame:not(.fame-light) :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword) .dnnLabel {
    float: none;
    display: block;
    position: relative;
    width: 100%;
    padding-right: 20px;
    margin: 0 0 .35rem;
    text-align: left;
}

.fame:not(.fame-light) :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword) :is(.dnnLabel label, label.dnnFormLabel, .dnnLabel span) {
    display: inline-block;
    margin: 0;
    color: var(--ff-white);
    font-family: var(--ff-font-body);
    font-weight: var(--ff-weight-medium);
    font-size: var(--ff-text-sm);
    text-align: left;
}

/* Verplicht veld: rood op zwart valt uit de toon, dus dezelfde ster als in
   het contactformulier. */
.fame:not(.fame-light) div.dnnFormItem.dnnFormRequired > div.dnnLabel span:after,
.fame:not(.fame-light) :is(.dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword) span.dnnFormRequired:after { color: var(--ff-primary); }

/* Lege labels laten anders een gat vallen: het aanmeldformulier heeft er drie
   (bij "onthoud mij", bij de knop en boven de links). */
.fame:not(.fame-light) :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset) label.dnnFormLabel:empty { display: none; }
.fame:not(.fame-light) .dnnFormItem > span.dnnFormLabel:has(+ .dnnLoginActions) { display: none; }

/* Het vraagtekentje van de helptekst hangt rechtsboven in het label */
.fame:not(.fame-light) :is(.dnnLoginService, .dnnSendPassword, .dnnPassword) a.dnnFormHelp { top: 0; }

/* 23.4 Velden ------------------------------------------------------------ */
.fame:not(.fame-light) :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword) :is(input[type="text"], input[type="email"], input[type="password"], input[type="tel"], input[type="search"], select, textarea) {
    display: block;
    width: 100%;
    max-width: 100%;
    min-height: 48px;
    margin: 0;
    padding: .7rem .9rem;
    font-family: var(--ff-font-body);
    font-size: var(--ff-text-base);
    color: var(--ff-white);
    background: #151515;
    border: 1px solid var(--ff-hairline-strong);
    border-radius: var(--ff-radius-md);
    box-shadow: none;
    transition: border-color var(--ff-dur) var(--ff-ease),
                box-shadow var(--ff-dur) var(--ff-ease);
}

.fame:not(.fame-light) :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword) :is(input, select, textarea):focus {
    border-color: var(--ff-primary);
    box-shadow: 0 0 0 3px rgba(37,192,255,.25);
}

.fame:not(.fame-light) :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword) ::placeholder { color: #8b8b8b; opacity: 1; }

/* Chrome kleurt een ingevuld veld anders lichtblauw, met donkere tekst die
   op deze achtergrond niet meer te lezen is. */
.fame:not(.fame-light) :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword) :is(input:-webkit-autofill, input:-webkit-autofill:hover, input:-webkit-autofill:focus) {
    -webkit-text-fill-color: var(--ff-white);
    -webkit-box-shadow: 0 0 0 1000px #151515 inset;
    caret-color: var(--ff-white);
}

/* Onthoud mij: het vakje is klein, het label eromheen levert het doelvlak */
.fame:not(.fame-light) .dnnLoginRememberMe {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    min-height: 44px;
}

.fame:not(.fame-light) .dnnLoginRememberMe input[type="checkbox"] {
    /* zonder font-size erbij rekent 1.35em met de 13px van het besturings-
       systeem, en dan is het vakje 18px in plaats van 24px */
    font-size: inherit;
    width: 1.35em;
    height: 1.35em;
    min-height: 0;
    margin: 0;
    flex: none;
    accent-color: var(--ff-primary);
}

.fame:not(.fame-light) .dnnLoginRememberMe label {
    margin: 0;
    color: var(--ff-white);
    cursor: pointer;
    font-size: var(--ff-text-base);
    font-weight: var(--ff-weight-body);
}

/* 23.5 Knoppen en acties -------------------------------------------------- */
/* input[type="submit"] staat bewust naast de :is()-lijst en niet erin: een
   attribuutselector binnen :is() telt mee voor de hele selector, en dan
   verliezen de uitzonderingen verderop het van deze basisregel. */
.fame:not(.fame-light) :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword) :is(.dnnPrimaryAction, .dnnSecondaryAction),
.fame:not(.fame-light) :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword) input[type="submit"] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 48px;
    min-width: 0;
    margin: 0;
    padding: .7rem 1.5rem;
    border: 2px solid var(--ff-primary);
    border-radius: var(--ff-radius);
    background: var(--ff-primary-dark);
    color: var(--ff-white);
    font-family: var(--ff-font-button);
    font-weight: var(--ff-weight-button);
    font-size: clamp(1.175rem, 1.12rem + .28vw, 1.3rem);
    line-height: 1.2;
    text-align: center;
    text-decoration: none;
    text-shadow: none;
    box-shadow: none;
    cursor: pointer;
    transition: background-color var(--ff-dur) var(--ff-ease),
                border-color var(--ff-dur) var(--ff-ease),
                color var(--ff-dur) var(--ff-ease);
}

.fame:not(.fame-light) :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword) .dnnPrimaryAction:hover,
.fame:not(.fame-light) :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword) input[type="submit"]:hover {
    background: var(--ff-primary-hover);
    border-color: var(--ff-primary);
    color: var(--ff-white);
}

.fame:not(.fame-light) :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword) .dnnSecondaryAction {
    background: transparent;
    border-color: var(--ff-white);
}

.fame:not(.fame-light) :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword) .dnnSecondaryAction:hover {
    background: var(--ff-white);
    color: var(--ff-black);
}

/* Aanmelden is bezig: DNN zet dnnDisabledAction op de knop */
.fame:not(.fame-light) .dnnDisabledAction,
.fame:not(.fame-light) :is(.dnnPrimaryAction, .dnnSecondaryAction)[disabled] {
    opacity: .6;
    pointer-events: none;
}

.fame:not(.fame-light) :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword) ul.dnnActions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ff-space-sm);
    margin: 0;
    padding: 0;
    list-style: none;
}

.fame:not(.fame-light) :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword) ul.dnnActions > li {
    float: none;
    margin: 0;
    list-style: none;
}

/* Op de smalle kaart staan de knoppen onder elkaar over de volle breedte;
   dat is op een telefoon het verschil tussen mikken en raken. */
.fame-auth :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword) ul.dnnActions { flex-direction: column; }

.fame-auth :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword) ul.dnnActions > li,
.fame-auth :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword) ul.dnnActions :is(.dnnPrimaryAction, .dnnSecondaryAction),
.fame-auth :is(.dnnLoginService, .dnnPasswordReset) .dnnFormItem > :is(.dnnPrimaryAction, .dnnSecondaryAction) { width: 100%; }

/* De knoprij van het aanmeldformulier: "Aanmelden", met eronder eventueel
   "Annuleren". */
.fame-auth .dnnLoginService .dnnFormItem:has(> .dnnPrimaryAction) {
    display: flex;
    flex-direction: column;
    gap: var(--ff-space-sm);
    margin-top: var(--ff-space-lg);
}

/* "Wachtwoord vergeten?" is geen tweede hoofdactie: als knop naast
   "Aanmelden" trekt hij evenveel aandacht als het inloggen zelf. */
.fame:not(.fame-light) .dnnLoginActions { display: block; width: 100%; }

.fame:not(.fame-light) .dnnLoginActions ul.dnnActions {
    flex-direction: row;
    justify-content: center;
    gap: var(--ff-space-md);
    margin-top: var(--ff-space-md);
}

.fame:not(.fame-light) .dnnLoginActions ul.dnnActions > li { width: auto; }

.fame:not(.fame-light) .dnnLoginActions ul.dnnActions .dnnSecondaryAction {
    display: inline-flex;
    width: auto;
    min-height: 44px;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--ff-primary);
    font-family: var(--ff-font-body);
    font-weight: var(--ff-weight-medium);
    font-size: var(--ff-text-base);
    text-decoration: underline;
}

.fame:not(.fame-light) .dnnLoginActions ul.dnnActions .dnnSecondaryAction:hover {
    background: transparent;
    color: var(--ff-white);
}

/* Het wachtwoordscherm zet zijn velden in een fieldset met de standaardrand
   en -marge van de browser, en zijn kop krijgt van DNN #222 mee. */
.fame:not(.fame-light) .dnnPassword fieldset {
    margin: 0;
    padding: 0;
    border: 0;
}

.fame:not(.fame-light) :is(.dnnLogin, .dnnPassword) .dnnFormSectionHead,
.fame:not(.fame-light) :is(.dnnLogin, .dnnPassword) .dnnFormSectionHead span {
    color: var(--ff-white);
    font-family: var(--ff-font-heading);
    font-weight: var(--ff-weight-heading);
    font-size: var(--ff-h4);
}

/* 23.6 Meldingen en validatie -------------------------------------------- */
.fame:not(.fame-light) :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword) .dnnFormMessage {
    display: block;
    margin: 0 0 var(--ff-space-md);
    padding: .875rem 1rem;
    border: 1px solid rgba(37,192,255,.45);
    border-radius: var(--ff-radius-md);
    background: rgba(37,192,255,.12);
    color: var(--ff-white);
    font-size: var(--ff-text-sm);
    line-height: 1.5;
}

.fame:not(.fame-light) :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword) .dnnFormMessage:empty { display: none; }

.fame:not(.fame-light) :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword) .dnnFormMessage.dnnFormSuccess {
    background: rgba(122,207,28,.14);
    border-color: var(--ff-summer-green);
}

.fame:not(.fame-light) :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword) .dnnFormMessage.dnnFormWarning {
    background: rgba(242,146,0,.14);
    border-color: var(--ff-carrot-orange);
}

.fame:not(.fame-light) :is(.dnnLogin, .dnnLoginService, .dnnSendPassword, .dnnPasswordReset, .dnnPassword) :is(.dnnFormMessage.dnnFormError, .dnnFormMessage.dnnFormValidationSummary) {
    background: rgba(199,53,53,.2);
    border-color: var(--ff-autumn-red);
}

/* DNN toont een validatiefout als tekstballon boven het veld, absoluut
   gepositioneerd en 200px breed. Op de kaart past dat niet; hieronder staat
   de melding gewoon onder het veld waar hij bij hoort. */
.fame:not(.fame-light) .dnnFormItem span.dnnFormMessage.dnnFormError {
    position: static;
    width: auto;
    margin-top: .35rem;
    padding: .5rem .75rem;
    border: 1px solid var(--ff-autumn-red);
    background: rgba(199,53,53,.2);
    color: var(--ff-white);
    font-size: var(--ff-text-sm);
    text-align: left;
}

.fame:not(.fame-light) .dnnFormItem span.dnnFormMessage.dnnFormError:after { display: none; }

.fame:not(.fame-light) .dnnFormError :is(input[type="text"], input[type="password"], input[type="email"], input[type="tel"], select, textarea) { border-color: var(--ff-autumn-red); }

/* 23.7 Wachtwoordmeter ---------------------------------------------------- */
/* Onder elk wachtwoordveld hangt DNN een sterktemeter
   (dnn.PasswordStrength.js). Die staat op 45% breed en met grijstinten die
   op zwart wegvallen. */
.fame:not(.fame-light) .password-strength-container {
    display: block;
    width: 100%;
    max-width: 100%;
}

.fame:not(.fame-light) .password-strength-container .min-length-text { color: var(--ff-on-dark-muted); }

.fame:not(.fame-light) .password-strength-container .meter div span { background-color: rgba(255,255,255,.18); }

.fame:not(.fame-light) .password-strength-container .meter label {
    color: var(--ff-white);
    font-size: var(--ff-text-sm);
}

/* Een goedgekeurd veld krijgt van DNN een wit vlak met een vinkje erin, met
   !important erachter. Alleen de kleur gaat terug; het vinkje blijft. */
.fame:not(.fame-light) .dnnFormItem input:is(.validate-success, .validate-fail, .matched, .unmatched) { background-color: #151515 !important; }

/* 23.8 Aanbieders: tabbladen en sociale knoppen --------------------------- */
.fame:not(.fame-light) .dnnLogin .LoginTabGroup {
    display: flex;
    gap: .25rem;
    height: auto;
    margin: 0 0 var(--ff-space-lg);
    border-bottom: 1px solid var(--ff-hairline-strong);
}

.fame:not(.fame-light) .dnnLogin .LoginTabGroup span {
    min-width: 0;
    margin: 0;
    padding: .5rem 1rem;
    border: 1px solid var(--ff-hairline);
    border-bottom: 0;
    border-radius: var(--ff-radius) var(--ff-radius) 0 0;
    background: transparent;
    color: var(--ff-white);
    font-family: var(--ff-font-body);
    font-weight: var(--ff-weight-medium);
}

.fame:not(.fame-light) .dnnLogin .LoginTabGroup span.LoginTabSelected {
    background: rgba(37,192,255,.12);
    border-color: var(--ff-primary);
    color: var(--ff-primary);
}

.fame:not(.fame-light) .dnnSocialRegistration ul.buttonList {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--ff-space-sm);
    margin: var(--ff-space-md) 0 0;
    padding: 0;
    list-style: none;
}

.fame:not(.fame-light) .dnnSocialRegistration ul.buttonList li { margin: 0; list-style: none; }

/* 23.9 Smalle schermen ---------------------------------------------------- */
@media (max-width: 480px) {
    .fame-auth > .content { padding: var(--ff-space-lg) var(--ff-space-md); }

    .auth-card { border-radius: var(--ff-radius-md); }

    .fame:not(.fame-light) .dnnLoginActions ul.dnnActions {
        flex-direction: column;
        align-items: center;
        gap: var(--ff-space-xs);
    }
}

/* --------------------------------------------------------------------------
   24. Afwerking: aanwijzers, systeeminstellingen en aanraakdoelen
   -------------------------------------------------------------------------- */
/* 24.1 Links in lopende tekst ---------------------------------------------
   Een link in een alinea was wit en zonder streep: precies dezelfde tekst als
   de rest van de zin. Kleur alleen mag het verschil niet dragen (WCAG 1.4.1),
   en hier deed zelfs de kleur niets. Het primaire blauw haalt tegen wit maar
   2,1:1, dus ook op hover is de streep de duidelijkste aanwijzing. Navigatie,
   knoppen en kaarten houden hun schone uiterlijk: die staan al los van de
   tekst en verraden zich door hun vorm. */
.fame :is(.Normal, .blog-article) :is(p, li, dd, td, address, blockquote) a:not(:where(.btn, [class*="btn-"], .page-link, .jump, .figure-link)),
.fame .footer-address a {
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: .18em;
    text-decoration-color: rgba(255,255,255,.45);
    text-decoration-color: color-mix(in srgb, currentColor 55%, transparent);
}

.fame :is(.Normal, .blog-article) :is(p, li, dd, td, address, blockquote) a:hover,
.fame :is(.Normal, .blog-article) :is(p, li, dd, td, address, blockquote) a:focus-visible,
.fame .footer-address a:hover,
.fame .footer-address a:focus-visible { text-decoration-color: currentColor; }

/* De hele kaart is al een link; een streep door de teaser maakt het rommelig. */
.fame .card-default :is(p, li) a { text-decoration: none; }

/* 24.2 Aanraakdoelen -------------------------------------------------------
   Hoofdstuk 6 bracht de navigatie, de filters en de paginering al op 44px.
   Dit zijn de laatste twee die eronder bleven: het telefoonnummer en het
   e-mailadres in de voettekst (19px hoog) en de knop naar de
   cookievoorkeuren (23px). */
.fame .footer-address a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
}

.fame .cookie-settings-link {
    padding: .7rem .3rem;
    margin-left: .1rem;
}

/* 24.3 Zweven alleen waar een aanwijzer is ---------------------------------
   Op een touchscreen blijft :hover na een tik hangen tot je ergens anders
   tikt. Een tegel die dan opgelicht blijft staan, lijkt geselecteerd. De
   kleurwissels mogen blijven - die vallen weg zodra de pagina wisselt - maar
   verschuiven en vergroten hoort niet zonder muis. */
@media (hover: none) {
    .next:hover,
    footer.fame-footer .jump:hover,
    .card-default:hover .figure,
    .lessons .lesson:hover,
    .testimonials .item:hover { transform: none; }

    .btn-link:hover::after { transform: rotate(45deg); }
}

/* 24.4 Brede tabellen ------------------------------------------------------
   Een tabel op display:block is voor een schermlezer geen tabel meer: rijen
   en kolommen verdwijnen uit de voorlezing. Staat er een .table-scroll
   omheen, dan doet die wrapper het schuiven al en mag de tabel een tabel
   blijven. De schaduw aan de rand laat zien dat er meer naast staat: de
   dekkende laag schuift met de inhoud mee (local) en glijdt bij het schuiven
   van de gekleurde laag af (scroll). Past alles, dan blijft de schaduw
   onzichtbaar. */
@media (max-width: 767px) {
    .fame .table-scroll > table {
        display: table;
        overflow-x: visible;
    }
}

.fame .table-scroll {
    background-image:
        linear-gradient(to right, var(--ff-black), rgba(0,0,0,0)),
        linear-gradient(to left, var(--ff-black), rgba(0,0,0,0)),
        linear-gradient(to right, rgba(37,192,255,.35), rgba(37,192,255,0)),
        linear-gradient(to left, rgba(37,192,255,.35), rgba(37,192,255,0));
    background-position: left center, right center, left center, right center;
    background-repeat: no-repeat;
    background-size: 32px 100%, 32px 100%, 10px 100%, 10px 100%;
    background-attachment: local, local, scroll, scroll;
}

/* 24.5 Formulieren: pas een fout tonen als er iets ingevuld is -------------
   :user-invalid slaat pas aan nadat iemand het veld heeft verlaten, in
   tegenstelling tot :invalid dat een leeg verplicht veld meteen rood maakt. */
.fame :is(input, select, textarea):user-invalid {
    border-color: var(--ff-autumn-red);
}

.fame :is(input, select, textarea):user-invalid:focus {
    box-shadow: 0 0 0 3px rgba(255,138,138,.25);
}

/* 24.6 Hoog contrast (Windows) --------------------------------------------
   In deze stand gooit het systeem alle kleuren overboord, ook de
   achtergronden waarmee dit thema tegels en knoppen van de pagina scheidt.
   Zonder rand vallen ze samen met alles eromheen. */
@media (forced-colors: active) {
    .fame :focus-visible,
    .fame-light :focus-visible,
    .fame-popup :focus-visible {
        outline: 2px solid Highlight;
        outline-offset: 2px;
    }

    .fame :is(.btn, .lesson, .card-default, .infoCard, .subscribe, .auth-card),
    .fame .testimonials .item,
    .fame .table-scroll { border: 1px solid CanvasText; }

    .fame .table-scroll { background-image: none; }
}

/* 24.7 Afdrukken -----------------------------------------------------------
   Het lesrooster en de openingstijden zijn de twee pagina's die mensen
   uitprinten. Zwart op zwart levert een lege pagina op. */
@media print {
    /* De balk staat niet op papier, dus de ruimte die hij openhoudt ook niet. */
    :root:has(.member-bar) { --ff-member-bar-height: 0px; }

    .fame,
    .fame .content { background: #fff; color: #000; }

    nav.nav,
    .side-menu-container,
    .side-menu-scrim,
    .member-bar,
    .skip-link,
    .scrollTop,
    .socials,
    .blog-filter,
    .pagination,
    .cookie-banner,
    .cookie-dialog,
    .subscribe { display: none !important; }

    .fame-layout > .content { padding-top: 0; }

    .fame :is(h1, h2, h3, h4, h5, h6, p, li, dd, td, th, address, strong, .lead) { color: #000; }

    .fame :is(.page-section, .hero-section) { padding: 0 0 1rem; margin: 0; }

    .fame :is(.lesson, .card-default, .subscribe, .infoCard),
    .fame .testimonials .item {
        background: transparent;
        border: 1px solid #999;
        break-inside: avoid;
    }

    .fame .content table { border: 1px solid #666; }
    .fame .content :is(th, td) { border-bottom: 1px solid #999; }
    .fame .content thead th { color: #000; }
    .fame .table-scroll { overflow: visible; background-image: none; }

    .fame a { color: #000; text-decoration: underline; }
    .fame .content a[href^="http"]::after {
        content: " (" attr(href) ")";
        font-size: .8em;
        word-break: break-all;
    }
}

/* --------------------------------------------------------------------------
   25. Inhoudstabellen: dagen, vandaag en kaarten op een telefoon
   -------------------------------------------------------------------------- */
/* Hoort bij initContentTables() in js/fame.js. De inhoud blijft zoals de
   redacteur hem invoert; dit gaat alleen over wat je ervan ziet. Zonder het
   script blijft de tabel gewoon een tabel met de opmaak uit hoofdstuk 18. */

/* Waar een nieuwe dag begint een lijn, zodat twintig lesregels uiteenvallen
   in zes dagen in plaats van één lange rij. */
.fame .content tbody tr.is-groupstart > :is(th, td) {
    border-top: 1px solid rgba(37,192,255,.35);
}

/* Vandaag. De rij zelf zegt alleen wélke dag het is; of we nu open zijn staat
   boven de tabel, waar initOpeningsstatus() de feestdagen meerekent. */
.fame .content tbody tr.is-today > :is(th, td) { background-color: rgba(37,192,255,.09); }
.fame .content tbody tr.is-today > th { color: var(--ff-primary); }

/* De open/gesloten-melding boven de openingstijden. Hoort bij
   initOpeningsstatus() in js/fame.js: zonder script staat hij er niet, en dan
   is de tabel eronder nog steeds het volledige antwoord.

   Het bolletje is versiering en staat daarom in ::before, niet in de tekst -
   "Nu open" en "Nu gesloten" staan er voluit, dus een schermlezer heeft het
   niet nodig en kleur is nooit de enige drager van de betekenis. */
.fame .hours-status {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: .15rem .5rem;
    margin-bottom: 1rem;
    padding: .6rem .9rem;
    border-radius: var(--ff-radius);
    background-color: var(--ff-harmony);
    border: 1px solid var(--ff-hairline);
    color: var(--ff-on-dark-muted);
}

.fame .hours-status::before {
    content: "";
    width: .6rem;
    height: .6rem;
    border-radius: 50%;
    flex: 0 0 auto;
    /* Op de basislijn van de tekst ernaast in plaats van bovenaan de regel. */
    align-self: center;
}

.fame .hours-status.is-open::before { background-color: var(--ff-primary); }
.fame .hours-status.is-closed::before { background-color: var(--ff-on-dark-muted); }

.fame .hours-status strong {
    color: var(--ff-white);
    font-family: var(--ff-font-heading);
    letter-spacing: .02em;
    text-transform: uppercase;
}

.fame .hours-status.is-open strong { color: var(--ff-primary); }

.table-today-badge {
    display: inline-block;
    margin-left: .5rem;
    padding: .1em .55em;
    border-radius: 999px;
    background-color: var(--ff-primary);
    color: var(--ff-black);
    font-family: var(--ff-font-body);
    /* Meeschalen met de kop waar hij naast staat, maar nooit onder de
       14px die de rest van het thema als ondergrens aanhoudt. */
    font-size: max(.72em, .875rem);
    font-weight: var(--ff-weight-heading);
    letter-spacing: .04em;
    text-transform: uppercase;
    white-space: nowrap;
    vertical-align: middle;
}

/* "Gesloten" is een uitzondering, geen openingstijd. Gedempt in plaats van
   rood: het rood van het thema haalt op zwart te weinig contrast. */
.fame .content td.is-closed {
    color: var(--ff-on-dark-muted);
    font-style: italic;
}

/* De dag die het script meedraagt naar de herhaalrijen. Op een breed scherm
   blijft de cel er leeg uitzien - zo is de tabel ook ingevoerd - maar een
   schermlezer noemt nu wel de dag bij elke les. */
.table-repeat-label {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* Filterbalk boven een weekrooster: één rijtje knoppen per handvat, met
   dezelfde pilvorm als de categoriebalk van het nieuws. Wat er te filteren
   valt bepaalt het script; zie initContentTables() in js/fame.js. */
.table-filters {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--ff-space-xs) var(--ff-space-lg);
    margin-bottom: var(--ff-space-md);
}

.table-filterset {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--ff-space-xs);
}

.table-filterset-label {
    color: var(--ff-on-dark-muted);
    font-size: var(--ff-text-sm);
    font-weight: var(--ff-weight-medium);
}

/* De teller staat op een eigen regel en meldt zich bij een schermlezer via
   role="status", zodat ook zonder de tabel te zien duidelijk is dat er iets
   veranderde - en dat een combinatie niets oplevert. */
.table-filter-count {
    flex-basis: 100%;
    margin: 0;
    color: var(--ff-on-dark-muted);
    font-size: var(--ff-text-sm);
}

.table-filter-count:empty { display: none; }


.table-filters button {
    min-height: 44px;
    padding: .35rem .9rem;
    border: 1px solid var(--ff-hairline);
    border-radius: 999px;
    background: transparent;
    color: var(--ff-on-dark-muted);
    font-family: var(--ff-font-body);
    font-size: var(--ff-text-sm);
    font-weight: var(--ff-weight-medium);
    white-space: nowrap;
    cursor: pointer;
    transition: color var(--ff-dur) var(--ff-ease),
                border-color var(--ff-dur) var(--ff-ease),
                background-color var(--ff-dur) var(--ff-ease);
}

.table-filters button:hover {
    color: var(--ff-white);
    border-color: var(--ff-hairline-strong);
}

.table-filters button.is-active {
    background-color: var(--ff-primary);
    border-color: var(--ff-primary);
    color: var(--ff-black);
}

/* Op een telefoon wordt elke rij een kaart. Vier kolommen passen daar niet,
   en zijwaarts schuiven om te zien wie de les geeft is geen lezen. */
@media (max-width: 767px) {

    .fame .table-scroll:has(> table.is-stacked) {
        overflow-x: visible;
        background-image: none;
    }

    .fame .content table.is-stacked,
    .fame .content table.is-stacked > tbody,
    .fame .content table.is-stacked > tbody > tr {
        display: block;
        width: 100%;
    }

    /* De kolomkoppen staan straks voor elke waarde; de rij zelf mag weg,
       maar blijft in de toegankelijkheidsboom staan. */
    .fame .content table.is-stacked > thead {
        position: absolute;
        width: 1px;
        height: 1px;
        margin: -1px;
        overflow: hidden;
        clip-path: inset(50%);
    }

    .fame .content table.is-stacked > tbody > tr {
        margin-bottom: var(--ff-space-sm);
        padding: var(--ff-space-md);
        border-radius: var(--ff-radius-lg);
        background-color: var(--ff-harmony);
    }

    .fame .content table.is-stacked > tbody > tr > :is(th, td) {
        border: 0;
        padding: 0;
        background-color: transparent;
    }

    .fame .content table.is-stacked > tbody > tr > th {
        display: block;
        margin-bottom: var(--ff-space-xs);
        color: var(--ff-primary);
        font-family: var(--ff-font-heading);
        font-size: var(--ff-h5);
        font-weight: var(--ff-weight-heading);
        line-height: var(--ff-leading-heading);
    }

    .fame .content table.is-stacked .table-repeat-label {
        position: static;
        width: auto;
        height: auto;
        margin: 0;
        overflow: visible;
        clip-path: none;
    }

    .fame .content table.is-stacked > tbody > tr > td {
        display: flex;
        gap: var(--ff-space-sm);
        justify-content: space-between;
        align-items: baseline;
        padding: .2rem 0;
    }

    .fame .content table.is-stacked > tbody > tr > td[data-label]::before {
        content: attr(data-label);
        flex: 0 0 auto;
        color: var(--ff-on-dark-muted);
        font-size: .9em;
    }

    .fame .content table.is-stacked > tbody > tr > td:not([data-label])::before { content: none; }

    /* De kaart van vandaag krijgt een rand in plaats van een vlak, anders
       vecht de tint met het tegelvlak eronder. */
    .fame .content table.is-stacked > tbody > tr.is-today {
        outline: 2px solid var(--ff-primary);
        outline-offset: -2px;
    }

    .fame .content table.is-stacked > tbody > tr.is-groupstart > :is(th, td) { border-top: 0; }
}

/* Weggefilterde regels. Deze regel staat met opzet achteraan: de
   kaartweergave hierboven zet dezelfde rijen op display:block met evenveel
   specificiteit, en bij gelijke specificiteit wint wie het laatst komt. */
.fame .content table > tbody > tr.is-filtered-out { display: none; }

/* --------------------------------------------------------------------------
   26. Prijskaarten (de tarievenpagina)
   -------------------------------------------------------------------------- */
/* De abonnementen stonden in .lessons-tegels: dezelfde tegel als een
   groepsles, met de prijs als lead-tekst. Een prijs is geen alinea - je
   vergelijkt hem met de prijs ernaast. Vandaar een eigen kaart met de prijs
   als grootste element, de voorwaarden eronder in een lijst en de knop
   onderaan, op dezelfde hoogte in elke kaart. */
.plans {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--ff-gutter);
    margin-bottom: var(--ff-space-lg);
}

@media (min-width: 576px) { .plans { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 992px) { .plans { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.plan {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: var(--ff-space-lg);
    border: 1px solid var(--ff-hairline);
    border-radius: var(--ff-radius-lg);
    background-color: var(--ff-harmony);
    transition: border-color var(--ff-dur) var(--ff-ease),
                transform var(--ff-dur) var(--ff-ease);
}

.plan:hover {
    border-color: var(--ff-hairline-strong);
    transform: translateY(-2px);
}

/* De kaart met de laagste prijs krijgt de accentkleur. Het vlaggetje staat
   in de rand en niet erboven, zodat de kaarten even hoog blijven. */
.plan--featured {
    border-color: var(--ff-primary);
    box-shadow: var(--ff-glow);
}

.fame .plan-flag,
.plan-flag {
    position: absolute;
    top: 0;
    right: var(--ff-space-lg);
    transform: translateY(-50%);
    margin: 0;
    padding: .15em .7em;
    border-radius: 999px;
    background-color: var(--ff-primary);
    color: var(--ff-black);
    font-family: var(--ff-font-body);
    font-size: var(--ff-text-sm);
    font-weight: var(--ff-weight-heading);
    letter-spacing: .04em;
    text-transform: uppercase;
    white-space: nowrap;
}

.plan-name {
    margin: 0 0 var(--ff-space-xs);
    color: var(--ff-white);
    font-size: var(--ff-h5);
}

.plan-price {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .35rem .5rem;
    margin: 0 0 var(--ff-space-md);
    padding-bottom: var(--ff-space-md);
    border-bottom: 1px solid var(--ff-hairline);
}

.plan-amount {
    color: var(--ff-primary);
    font-family: var(--ff-font-heading);
    font-size: var(--ff-h3);
    font-weight: var(--ff-weight-heading);
    line-height: var(--ff-leading-tight);
}

.plan-period { color: var(--ff-on-dark-muted); font-size: var(--ff-text-sm); }

.plan-features {
    margin: 0 0 var(--ff-space-lg);
    padding: 0;
    list-style: none;
    color: var(--ff-white);
}

.plan-features li {
    display: flex;
    align-items: flex-start;
    gap: var(--ff-space-xs);
    margin-bottom: var(--ff-space-2xs);
    font-size: var(--ff-text-sm);
}

/* Het vinkje als masker in plaats van als teken: zo heeft het de kleur van
   het thema en leest een schermlezer geen losse "V" voor. */
.plan-features li::before {
    content: '';
    flex: none;
    width: 1.15em;
    height: 1.15em;
    margin-top: .1em;
    background-color: var(--ff-primary);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'/%3E%3C/svg%3E") center / contain no-repeat;
}

.plan-body { color: var(--ff-on-dark-muted); }
.plan-body p { color: var(--ff-on-dark-muted); font-size: var(--ff-text-sm); }
.plan-body strong { color: var(--ff-white); }

/* De knop onderaan, op gelijke hoogte in elke kaart van de rij. */
.plan-action { margin: auto 0 0; padding-top: var(--ff-space-md); }
.plan-action .btn { width: 100%; }

.fame .plan-note,
.plan-note {
    margin: var(--ff-space-xs) 0 0;
    color: var(--ff-on-dark-muted);
    font-size: var(--ff-text-sm);
    text-align: center;
}

/* Een abonnement met een uitleg in plaats van een rijtje voorwaarden - het
   Volwassenenfonds - krijgt de volle breedte van het raster. */
@media (min-width: 576px) { .plan--wide { grid-column: 1 / -1; } }

@media (min-width: 992px) {
    .plan--wide { flex-direction: row; flex-wrap: wrap; align-items: flex-start; gap: var(--ff-space-xl); }
    .plan--wide > .plan-body { flex: 1 1 22rem; }
    .plan--wide > :is(.plan-name, .plan-price, .plan-action) { flex: 0 0 14rem; }
    .plan--wide > .plan-name { flex-basis: 100%; }
    .plan--wide > .plan-price { border-bottom: 0; padding-bottom: 0; margin-bottom: 0; }
    .plan--wide > .plan-action { margin: 0; padding-top: 0; }
}

/* Voetnoot onder een reeks kaarten */
.fame .plans-note,
.plans-note {
    margin: 0;
    color: var(--ff-on-dark-muted);
    font-size: var(--ff-text-sm);
    text-align: center;
}

/* --------------------------------------------------------------------------
   27. Veelgestelde vragen
   -------------------------------------------------------------------------- */
/* Een <details> per vraag: open- en dichtklappen zonder script, en met de
   zoekfunctie van de browser ook in een dichtgeklapte vraag te vinden. */
.faq {
    max-width: 48rem;
    margin-inline: auto;
}

.faq-item {
    border: 1px solid var(--ff-hairline);
    border-radius: var(--ff-radius-md);
    background-color: var(--ff-harmony);
    margin-bottom: var(--ff-space-xs);
}

.faq-item[open] { border-color: var(--ff-hairline-strong); }

.faq-item > summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ff-space-md);
    min-height: 56px;
    padding: var(--ff-space-md) var(--ff-space-lg);
    color: var(--ff-white);
    font-family: var(--ff-font-heading);
    font-size: var(--ff-h6);
    font-weight: var(--ff-weight-medium);
    line-height: var(--ff-leading-heading);
    cursor: pointer;
    list-style: none;
}

/* Het standaarddriehoekje weg in beide smaken; er komt een eigen teken voor
   in de plaats dat meedraait. */
.faq-item > summary::-webkit-details-marker { display: none; }
.faq-item > summary::marker { content: ''; }

.faq-item > summary::after {
    content: '';
    flex: none;
    width: 1.1em;
    height: 1.1em;
    background-color: var(--ff-primary);
    transition: transform var(--ff-dur) var(--ff-ease);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m7.4 8.6 4.6 4.6 4.6-4.6L18 10l-6 6-6-6z'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m7.4 8.6 4.6 4.6 4.6-4.6L18 10l-6 6-6-6z'/%3E%3C/svg%3E") center / contain no-repeat;
}

.faq-item[open] > summary::after { transform: rotate(180deg); }

.faq-item > summary:hover { color: var(--ff-primary); }

.faq-item > summary:focus-visible {
    outline: 2px solid var(--ff-primary);
    outline-offset: -2px;
    border-radius: var(--ff-radius-md);
}

.faq-answer {
    padding: 0 var(--ff-space-lg) var(--ff-space-lg);
    color: var(--ff-on-dark-muted);
}

.faq-answer > :first-child { margin-top: 0; }
.faq-answer > :last-child { margin-bottom: 0; }
.faq-answer p { color: var(--ff-on-dark-muted); }
