/*
Theme Name: Henk & Fred 2026
Theme URI: https://www.henkenfred.nl
Author: Mull2media
Author URI: https://www.mull2media.nl
Description: Blokthema voor het vakbladplatform Henk & Fred van Media Vakman B.V. Gebouwd naar de goedgekeurde ontwerpconcepten van juli 2026.
Requires at least: 6.7
Tested up to: 7.0
Requires PHP: 8.1
Version: 0.1.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: henkenfred-2026
Tags: full-site-editing, blog, news, block-patterns
*/

/*
 * De opmaak staat in assets/css/concept.css, gegenereerd uit de
 * ontwerpconcepten door bouw-stylesheet.py. Dit bestand bevat alleen de
 * themametadata en de regels die WordPress-specifiek zijn.
 */

/* Rubriekskleur als accent.
 *
 * Het magazine geeft elke rubriek een eigen kleur en gebruikt die consequent:
 * het interview met Mark Harbers is volledig in het rood opgemaakt, een
 * testpanel in ball blue. Online volgen we dat. Alle accenten (quote-vlakken,
 * kleurvlakken over beeldranden, kaderverhalen, sectiestrepen, agendablokjes)
 * erven --accent, zodat één klasse op de body de hele pagina meekleurt.
 * De klasse wordt gezet door henkenfred_body_classes() in functions.php. */
body { --accent: var(--hf-rood); }
body.rubriek-nieuws      { --accent: var(--rub-nieuws); }
body.rubriek-innovaties  { --accent: var(--rub-innovaties); }
body.rubriek-testpanel   { --accent: var(--rub-testpanel); }
body.rubriek-blogs       { --accent: var(--rub-blogs); }
body.rubriek-gadgets     { --accent: var(--rub-gadgets); }
body.rubriek-agenda      { --accent: var(--rub-agenda); }
body.rubriek-interview   { --accent: var(--rub-interview); }

/* h3 is in het ontwerp contextafhankelijk: in een kaart is het Source Serif 900
 * zonder kapitalen, in een eventblok Anton in kapitalen. theme.json mag h3
 * daarom niet globaal stylen — een kale `h3{text-transform:uppercase}` daaruit
 * sloeg door naar alle artikeltitels, omdat `.kaart h3` in de concept-stylesheet
 * zelf geen text-transform declareert en dus terugvalt op die globale regel.
 * De titels stáán normaal in de database; het was puur weergave. */
h3 { text-transform: none; }
.ev h3,
.mag-item h3 { text-transform: uppercase; }

/* WordPress-eigen elementen die het accent moeten volgen. */
.wp-block-quote,
.wp-block-pullquote { border-left-color: var(--accent); }

/* ---------------------------------------------------------------------------
 * Brug van het navigatieblok naar de opmaak uit het concept.
 *
 * Het concept gebruikt een handgeschreven <ul class="nav"> met <a class="nav-lnk">.
 * Het wp:navigation-blok maakt een eigen structuur. We stylen die structuur in
 * plaats van de markup te bevriezen, zodat de redactie het menu in de
 * site-editor kan blijven beheren.
 * ------------------------------------------------------------------------- */
.site-nav { margin-left: auto; }

.site-nav .wp-block-navigation__container {
	display: flex;
	align-items: center;
	gap: 2px;
	margin: 0;
	padding: 0;
}

.site-nav .wp-block-navigation-item { position: relative; list-style: none; }

.site-nav .wp-block-navigation-item__content {
	display: flex;
	align-items: center;
	gap: 6px;
	padding: 10px 13px;
	border-radius: var(--radius);
	font-weight: 700;
	font-size: 15px;
	color: var(--inkt);
	text-decoration: none;
	transition: background .18s, color .18s;
}

.site-nav .wp-block-navigation-item__content:hover,
.site-nav .wp-block-navigation-item:focus-within > .wp-block-navigation-item__content {
	background: var(--grijs-100);
	color: var(--hf-rood);
}

/* Het submenu krijgt de vormgeving van .mega uit het concept. WordPress zet
   zelf inline `left`/`top` op het submenu; die overschrijven we hier. */
.site-nav .wp-block-navigation__submenu-container {
	min-width: 300px;
	padding: 8px;
	background: #fff;
	border: 1px solid var(--grijs-200);
	border-radius: var(--radius);
	box-shadow: var(--schaduw-lift);
}

.site-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
	font-size: 14.5px;
	padding: 9px 10px;
}

.site-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content:hover {
	background: var(--grijs-100);
}

/* Megamenu-item met stip en toelichting, gevuld vanuit het beschrijvingsveld
   van het menu-item (zie henkenfred_menu_beschrijving in functions.php). */
.site-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
	align-items: flex-start;
	gap: 10px;
}

.site-nav .mega-tekst { display: block; }

.site-nav .dot {
	width: 9px;
	height: 9px;
	flex: 0 0 auto;
	margin-top: 7px;
	background: var(--grijs-500);
}

.site-nav .t {
	display: block;
	font-weight: 700;
	font-size: 14.5px;
	line-height: 1.3;
}

.site-nav .d {
	display: block;
	font-size: 12.5px;
	font-weight: 500;
	line-height: 1.4;
	color: var(--grijs-500);
}

/* Stipkleur per rubriek. Een menu-item dat naar een rubriek wijst krijgt
   automatisch de kleur die het magazine aan die rubriek geeft. */
.site-nav .dot-nieuws      { background: var(--rub-nieuws); }
.site-nav .dot-innovaties  { background: var(--rub-innovaties); }
.site-nav .dot-testpanel   { background: var(--rub-testpanel); }
.site-nav .dot-blogs       { background: var(--rub-blogs); }
.site-nav .dot-gadgets     { background: var(--rub-gadgets); }
.site-nav .dot-agenda      { background: var(--rub-agenda); }
.site-nav .dot-interview   { background: var(--rub-interview); }

/* ---------------------------------------------------------------------------
 * Megamenu onder Nieuws en Techniek.
 *
 * De tegels komen uit henkenfred_megamenu() in functions.php, met dezelfde
 * tegelfunctie als de rubriekenstrook boven de footer. Hier alleen de opmaak
 * van het uitklapvak en een compactere tegel.
 *
 * Alle klassen met hf-: concept.css heeft een eigen megamenu-component met
 * de klasse mega (absoluut, left 50%, translate -50%, onzichtbaar tot hover).
 * WordPress zet de className van een submenu op li en ul, dus die raakte ook
 * de menu-items Nieuws en Techniek zelf en brak op 10-9 de hele balk.
 *
 * Het vak loopt over de volle breedte van de menubalk in plaats van onder zijn
 * eigen menu-item te hangen: de <li> gaat op position: static, zodat het vak
 * zich op de <nav> uitlijnt (die zet WordPress zelf op position: relative).
 * Drie en vier klassen diep om de regels uit de navigatiestylesheet van
 * WordPress (.wp-block-navigation .has-child ...) voor te blijven.
 * ------------------------------------------------------------------------- */
.header-menu .site-nav .wp-block-navigation-item.hf-mega {
	position: static;
}

.header-menu .site-nav .hf-mega > .wp-block-navigation__submenu-container {
	left: 0;
	right: 0;
	top: 100%;
	min-width: 0;
	padding: 16px;
}

.site-nav .hf-mega-vak {
	list-style: none;
}

.site-nav .hf-mega-tegels {
	display: grid;
	grid-template-columns: repeat(5, 1fr);
	gap: 12px;
}

/* Kleur en onderstreping expliciet: de navigatiestylesheet zet links op
   `color: inherit`, en dan zou de tekst op een rode tegel donker worden. */
.site-nav .hf-mega-tegels .rub {
	min-height: 108px;
	padding: 16px 16px 14px;
	color: #fff;
	text-decoration: none;
}

.site-nav .hf-mega-tegels .ico {
	width: 24px;
	height: 24px;
}

.site-nav .hf-mega-tegels .rub-titel {
	display: block;
	margin-top: 12px;
	font-family: var(--display);
	font-weight: 400;
	text-transform: uppercase;
	font-size: 17px;
	line-height: 1.05;
}

.site-nav .hf-mega-tegels .aantal {
	display: block;
	margin-top: 4px;
	font-size: 12px;
	font-weight: 600;
	opacity: .8;
}

/* Techniek: tien onderwerpen zonder eigen rubriekskleur, allemaal in
   --grijs-100 (#f1f4f6) op verzoek van Rick. Op die lichte ondergrond moeten
   tekst en icoon donker. Tien tegels in vijf kolommen = twee rijen van vijf. */
.site-nav .hf-mega-techniek .hf-mega-tegels .rub {
	background: var(--grijs-100);
	color: var(--inkt);
}


/* ---------------------------------------------------------------------------
 * Header in twee rijen, met een plakkende menubalk.
 *
 * Boven: logo links, sociale iconen en de abonneeknop rechts. Daaronder een
 * eigen balk met het hoofdmenu op een regel. Bij het scrollen loopt de logorij
 * weg en blijft alleen de menubalk bovenaan staan -- hetzelfde idee als
 * installatieenbouw.nl, maar zonder JavaScript en dus zonder sprong: daar zet
 * een scroll-handler de balk op `position: fixed` en compenseert hij met
 * padding op de body.
 *
 * Hier doet `position: sticky` met een negatieve `top` ter grootte van de
 * logorij (--header-h) hetzelfde werk. De header plakt pas als die rij er
 * precies uit gelopen is.
 *
 * Voorwaarde is wel dat de header niet in een even hoge wrapper zit.
 * WordPress zet een template-part in <div class="wp-block-template-part">, en
 * omdat die div exact zo hoog is als de header had `position: sticky` nul
 * speelruimte: de header plakte helemaal niet, ook niet voor deze wijziging.
 * De vijf sjablonen geven die wrapper nu de klasse `header-part`, en
 * `display: contents` haalt hem uit de opmaak zodat <body> het containing
 * block wordt.
 * ------------------------------------------------------------------------- */
.header-part { display: contents; }

.header { top: calc(-1 * var(--header-h)); }

.header-boven-in {
	max-width: var(--max);
	margin-inline: auto;
	padding: 0 24px;
	height: var(--header-h);
	display: flex;
	align-items: center;
	gap: 24px;
}

/* Het logo duwt met een automatische rechtermarge alles wat erna komt naar
   rechts. De logorij stond op `space-between` (uit het blok), en met drie
   kinderen -- logo, acties, burger -- kwam het actieblok daardoor in het
   midden te hangen in plaats van tegen de burger aan.

   Let op: geen `margin-left: auto` meer op .header-acties. Twee automatische
   marges tegenover elkaar verdelen de vrije ruimte samen, en dan staat het
   blok weer precies in het midden. Eén auto-marge, op het logo. */
.header .header-boven-in {
	justify-content: flex-start;
}

.header .header-boven-in > .logo {
	margin-right: auto;
}

.header-acties {
	display: flex;
	align-items: center;
	gap: 18px;
}

.header-soc { display: flex; gap: 8px; }

/* Zelfde vorm als .f-soc in de footer, maar op een lichte ondergrond. */
.header-soc a {
	display: grid;
	place-items: center;
	width: 34px;
	height: 34px;
	color: var(--inkt);
	background: var(--grijs-100);
	transition: background .18s, color .18s;
}

.header-soc a:hover { background: var(--hf-rood); color: #fff; }
.header-soc svg { width: 17px; height: 17px; }

/* Topmenu in de logorij: "Over Henk & Fred" en "Contact". Het draagt ook de
   klasse site-nav, zodat de opmaak van het submenu meekomt; alleen kleiner en
   zonder balk eromheen. */
.header-acties .site-nav { margin-left: 0; }

.header-acties .top-nav > .wp-block-navigation__container
	> .wp-block-navigation-item > .wp-block-navigation-item__content {
	padding: 8px 10px;
	font-size: 14px;
	white-space: nowrap;
}

.header-menu { border-top: 1px solid var(--grijs-200); }

.header-menu-in {
	max-width: var(--max);
	margin-inline: auto;
	padding: 0 24px;
}

/* Het menu vult de balk. Krappere items dan in de oude eenregelige header:
   negen onderdelen met lange labels passen er anders niet naast elkaar. */
.header-menu .site-nav { margin-left: 0; }

.header-menu .site-nav > .wp-block-navigation__container {
	justify-content: space-between;
	gap: 0;
}

.header-menu .site-nav > .wp-block-navigation__container
	> .wp-block-navigation-item > .wp-block-navigation-item__content {
	padding: 13px 10px;
	font-size: 14.5px;
	white-space: nowrap;
}

@media (max-width: 1100px) {
	/* Onder deze breedte neemt het eigen off-canvas menu het over. Het
	   breekpunt lag op 782px, maar met negen onderdelen is de balk daar al
	   lang te krap; mobile-menu.js hanteert dezelfde grens.

	   Allebei de navigaties dragen .site-nav, en WordPress zet die klasse op
	   zowel de <nav> als de <ul> daarbinnen. Vandaar ook de variant met twee
	   klassen: geen enkele regel uit de blokstylesheets kan er dan nog
	   overheen, ongeacht de volgorde waarin de stylesheets binnenkomen. */
	.site-nav,
	.header .site-nav,
	.header-acties .site-nav { display: none; }
	.header-menu { display: none; }
	.burger { display: grid; }

	/* Zonder menubalk is er niets om te laten plakken: de logorij zelf blijft
	   dan gewoon boven staan, zoals hij deed. */
	.header { top: 0; }

	/* De burger als echte knop, in dezelfde vorm als de sociale iconen ernaast:
	   vierkant vlakje in grijs-100, rood bij hover en zolang het menu open
	   staat. De hoogte en tussenruimte van de streepjes blijven zoals ze zijn,
	   want de X-animatie in concept.css rekent met precies die 7,5px. */
	.burger {
		width: 42px;
		height: 42px;
		background: var(--grijs-100);
		transition: background .18s;
	}

	/* Het menu-icoon is de bars-staggered van Font Awesome Free (CC BY 4.0,
	   attributie staat als commentaar bij de SVG in parts/header.html): drie
	   streepjes van gelijke lengte met de middelste naar rechts verschoven.
	   Aangeleverd door Rick.

	   Daarmee vervalt de streepjesanimatie uit concept.css helemaal -- er zijn
	   geen <span>'s meer. Bij het openen wisselt het icoon naar een kruisje;
	   dat is een tweede SVG in dezelfde knop, puur met CSS omgezet, dus
	   mobile-menu.js hoeft er niets voor te doen. */
	.burger {
		width: 42px;
		height: 42px;
		background: var(--grijs-100);
		color: var(--inkt);
		transition: background .18s, color .18s;
	}

	.burger svg {
		display: block;
		width: 21px;
		height: 21px;
	}

	.burger .burger-sluit { display: none; }
	.burger[aria-expanded="true"] .burger-menu { display: none; }
	.burger[aria-expanded="true"] .burger-sluit { display: block; }

	.burger:hover,
	.burger[aria-expanded="true"] {
		background: var(--hf-rood);
		color: #fff;
	}
}

@media (max-width: 600px) {
	.header-soc { display: none; }
	.logo { width: 140px; }
	.header-boven-in { gap: 14px; }
}

/* ---------------------------------------------------------------------------
 * Knoppen.
 *
 * Het ontwerp gebruikt `<a class="knop">`. Het button-blok maakt
 * `<div class="wp-block-button knop"><a class="wp-block-button__link">`, dus de
 * klasse landt op de wrapper terwijl de <a> zijn eigen padding en lettergrootte
 * van WordPress meekrijgt. De wrapper wordt daarom doorzichtig en de opmaak
 * verhuist naar de link.
 * ------------------------------------------------------------------------- */
.wp-block-button.knop,
.wp-block-button.knop-licht,
.wp-block-button.knop-sm {
	background: none;
	padding: 0;
	font-size: inherit;
}

.wp-block-button.knop > .wp-block-button__link,
.wp-block-button.knop-licht > .wp-block-button__link,
.wp-block-button.knop-sm > .wp-block-button__link {
	display: inline-flex;
	align-items: center;
	gap: 9px;
	padding: 12px 22px;
	border-radius: var(--radius);
	border: 1.5px solid transparent;
	background: var(--hf-rood);
	color: #fff;
	font-weight: 700;
	font-size: 15px;
	line-height: 1.6;
	text-decoration: none;
	transition: transform .18s, box-shadow .18s, background .18s;
}

.wp-block-button.knop > .wp-block-button__link:hover {
	transform: translateY(-2px);
	background: #b00727;
	box-shadow: 0 8px 20px rgba(202, 8, 46, .32);
}

.wp-block-button.knop-licht > .wp-block-button__link {
	background: #fff;
	color: var(--inkt);
	border: 1.5px solid var(--grijs-200);
}

.wp-block-button.knop-licht > .wp-block-button__link:hover {
	background: var(--grijs-100);
	box-shadow: none;
}

/* ---------------------------------------------------------------------------
 * Knoppenrij en video in een artikel (sinds 22-9).
 *
 * theme.json zet blockGap op 0, dus wp:buttons zet de knoppen tegen elkaar aan
 * en er staat niets boven de rij. Hetzelfde geldt onder een wp:embed.
 * Twee klassen diep vanwege .art-body.
 * ------------------------------------------------------------------------- */
.art-body .wp-block-buttons {
	gap: 12px;
	margin: 28px 0 0;
}

.art-body .wp-block-embed {
	margin: 0 0 40px;
}

.wp-block-button.knop-sm > .wp-block-button__link {
	padding: 10px 16px;
	font-size: 14px;
}

/* Pill: de rubrieksklasse komt van henkenfred_pill_rubriekskleur(); de link
   erbinnen moet de kleur en het gewicht van de pill overnemen. */
.pill.wp-block-post-terms a {
	color: inherit;
	text-decoration: none;
	font: inherit;
}

/* `.kaart-pill` is in het ontwerp absoluut gepositioneerd linksboven óp de foto.
   In het ontwerp zit hij binnen `.beeld` (die relatief staat), maar een
   uitgelichte afbeelding is één blok waar niets in kan. De pill staat bij ons
   dus in de tekst, en zonder een eigen positioneringscontext zocht hij een
   voorouder verderop en landde half achter het beeld. De kaart wordt daarom de
   context. */
.kaart { position: relative; }
.kaart .kaart-pill { top: 12px; left: 12px; }

/* ---------------------------------------------------------------------------
 * Footerlogo.
 *
 * Vervangt de witte "chip" uit het concept (.f-logo-chip in concept.css: het
 * blauw/rode logo op een wit vlakje). De klant leverde op 7 september een witte
 * versie aan; die staat rechtstreeks op het donkerblauw, want een wit vlakje
 * eronder zou hem juist onzichtbaar maken.
 *
 * Breedte en ondermarge zijn gelijk gehouden aan de chip (186px + 18px), zodat
 * de rest van de footerkolom niet verspringt. Het bestand is 480px breed en dus
 * ruim scherp genoeg op een retina-scherm.
 * ------------------------------------------------------------------------- */
.f-logo {
	width: 186px;
	margin-bottom: 18px;
}

.f-logo img {
	display: block;
	width: 100%;
	height: auto;
}

/* ---------------------------------------------------------------------------
 * Advertentieplekken (AdSanity).
 *
 * De plekken zelf komen uit het blok henkenfred/advertentie in functions.php;
 * hier staat alleen de opmaak. De maat komt van AdSanity, via de klasse
 * .ad-{maat} op zijn eigen wrapper -- het thema legt dus geen hoogte op.
 *
 * De placeholders uit het concept (.adslot met stippellijn en streepjes) worden
 * niet meer gebruikt. Die regels blijven in concept.css staan omdat dat bestand
 * gegenereerd wordt en niet met de hand bewerkt mag worden.
 * ------------------------------------------------------------------------- */
.advertentie {
	margin-inline: auto;
}

/* Hoort bij de billboard: die bracht in het sjabloon een eigen .wrap mee met
   24px erboven. Dat zit nu in het blok, zodat bij een lege plek ook die
   witruimte verdwijnt. */
.advertentie-wrap {
	padding-top: 24px;
}

/* De billboard staat in de volle .wrap (~1192px) maar mag niet groter worden
   dan zijn eigen formaat; anders wordt een 970x250-banner uitgerekt. */
.adv-billboard { max-width: 970px; }

.adv-in-text { margin-block: 30px 34px; }

/* De advertentie tussen de kaarten van een rubrieksarchief; ingevoegd door
   henkenfred_advertentie_in_archief() in functions.php. Het kaartenraster is
   tweekoloms, dus hij pakt de volle breedte -- anders zou hij als halve kaart
   naast een artikel komen te staan. De eigen boven- en ondermarge van de
   in-text-plek vervalt: het raster heeft zijn eigen gap van 30px. */
.rub-kaarten .rub-advertentie {
	grid-column: 1 / -1;
	list-style: none;
}

.rub-advertentie .adv-in-text {
	margin-block: 0;
}


/* AdSanity zet bij zijn eigen vaste maten een harde `height` op de buitenste
   div, terwijl de creative erbinnen op ratio meeschaalt. Is de kolom smaller
   dan de creative, dan blijft daar ruimte onder de banner staan. Dat is hier
   geen randgeval: de tekstkolom is ~600px en de in-text is 728x90, dus dat
   scheelt altijd zo'n 16px. De ratio zit al in .adsanity-inner, dus de
   buitenste div mag gewoon om zijn inhoud sluiten. */
.advertentie .ad-728x90,
.advertentie .ad-300x600,
.advertentie .ad-300x250 {
	height: auto;
	max-height: none;
}

/* Eigen maten: voor 970x250, 320x100 en 320x50 levert AdSanity geen CSS mee.
   Bewust zonder vaste hoogte -- die zet de plugin bij zijn eigen maten wel, en
   dan blijft er in een smallere kolom lege ruimte onder de banner staan. */
.ad-970x250 { max-width: 970px; }
.ad-320x100 { max-width: 320px; }
.ad-320x50 { max-width: 320px; }

.ad-970x250 img,
.ad-320x100 img,
.ad-320x50 img {
	display: block;
	width: 100%;
	height: auto;
}

/* Aparte creative voor smalle schermen. Deze splitsing bestaat alleen als
   beide groepen gevuld zijn; is er maar een, dan zet het blok die neer zonder
   deze klassen en blijft hij overal staan. 640px is het breekpunt dat de
   advertentieregels in concept.css al aanhouden. */
.adv-mobiel { display: none; }

@media (max-width: 640px) {
	.adv-desktop { display: none; }
	.adv-mobiel { display: block; }
}

/* ---------------------------------------------------------------------------
 * Kopblok van een magazineartikel.
 *
 * concept.css kapt .art-kop af op 62ch; hier mag het blok de volle breedte
 * gebruiken en houdt alleen het quotekader zelf een maat. Zo aangeleverd door
 * Rick (7-9).
 *
 * Dit raakt alleen de magazineartikelen. Op een gewoon bericht draagt de
 * <header> ook de klasse .ah-tekst, en die staat hierboven (.art-hoofd
 * .ah-tekst) al op max-width: none.
 * ------------------------------------------------------------------------- */
.art-kop {
	max-width: 100%;
}

.art-kop .hf-quotekader {
	max-width: 60%;
}

/* ---------------------------------------------------------------------------
 * Quotekaders zonder kaderlijn.
 *
 * Op verzoek van Rick (7-9) staat .hf-quotekader zonder rand. De aanhalings-
 * tekens blijven staan: die zitten als ::before/::after op het element en zijn
 * de kern van het component.
 *
 * De witte achtergrond achter die tekens gaat wel weg. Die had precies een
 * taak -- de kaderlijn onderbreken waar een teken eroverheen valt, zie het
 * commentaar bij het component in concept.css -- en zonder lijn zou het een
 * wit blokje worden zodra er iets gekleurds achter staat.
 *
 * Hier en niet in concept.css: dat bestand wordt gegenereerd door
 * bouw-stylesheet.py, dus een wijziging daar is bij de volgende deploy weg.
 * ------------------------------------------------------------------------- */
.hf-quotekader {
	border: 0;
}

.hf-quotekader::before,
.hf-quotekader::after {
	background: none;
	padding: 0;
}

/* Aanhalingsteken linksboven binnen het kader in plaats van op de weggevallen
   kaderlijn. Zo aangeleverd door Rick. Let op: `translate: 0 -50%` uit
   concept.css blijft gelden, dus het teken steekt nog half boven deze positie
   uit; het sluitende teken (::after) is bewust ongemoeid gelaten. */
.hf-quotekader::before {
	left: 0;
	top: 16px;
}

/* ---------------------------------------------------------------------------
 * De naam bij "8 brutale vragen" naast het introvlak in plaats van op de foto.
 *
 * In het magazine ligt de naam in wit displayschrift over het beeld
 * (.bv-naam, een figcaption in de art-beeld-figure). Op verzoek van Rick (7-9)
 * komt hij eruit en naast de introtekst te staan, in de ruimte rechts van
 * .hf-vlak-onder -- dat vlak is min(78%, 760px) breed met 40px links.
 *
 * De figcaption blijft waar hij staat in de HTML: die zit in de artikelinhoud
 * en hoort binnen zijn <figure>. Verplaatsen zou betekenen dat de inhoud van
 * elk artikel apart bewerkt moet worden.
 *
 * Wit met een schaduw kan niet meer -- dat was voor leesbaarheid op de foto.
 * Op wit wordt het de inktkleur, zonder schaduw.
 * ------------------------------------------------------------------------- */
.bv-naam {
	color: var(--inkt);
	text-shadow: none;
}

/* Alleen breed genoeg vanaf 1024px: het introvlak loopt tot 78% en daaronder
   blijft er te weinig over om de naam naast te zetten zonder dat hij in
   losse letters uiteenvalt. */
@media (min-width: 1024px) {
	.bv-naam {
		left: auto;
		right: 0;
		bottom: -75px;
		width: calc(100% - min(78%, 760px) - 40px - 24px);
		font-size: clamp(20px, 2.1vw, 32px);
	}
}

/* Smaller: geen ruimte ernaast, dus de naam loopt gewoon mee onder de foto en
   het introvlak pakt de volle breedte. Daarmee vervalt ook de negatieve
   bovenmarge waarmee dat vlak op bredere schermen de onderrand van het beeld
   kruist -- gestapeld heeft die overlap geen betekenis meer. Marges zo
   afgesteld door Rick. */
@media (max-width: 1023px) {
	.bv-naam {
		position: static;
		margin: 25px 0 0;
		font-size: clamp(22px, 3.4vw, 34px);
	}

	.hf-vlak-onder {
		width: 100%;
		margin: 16px 0 0;
	}
}


/* Specificatiekader zonder de bovenmarge van 56px uit concept.css. */
.tp-specs {
	margin: 0;
}

/* ---------------------------------------------------------------------------
 * Testpanel: de antwoorden gegroepeerd per vraag.
 *
 * Alle panelleden krijgen dezelfde vragen, dus stond de vraagtekst vier keer in
 * het artikel -- 40% van de zichtbare tekst in dat blok was duplicaat, en de
 * vragen samen waren twee keer zo lang als alle antwoorden bij elkaar. Nu staat
 * de vraag één keer met de vier antwoorden eronder; de ledenkaarten (naam,
 * bedrijf, sterren, plus/min) staan daarboven, ook één keer.
 *
 * De vraagkoppen hergebruiken .hf-vragen / .bv-vraag / .bv-nr uit "8 brutale
 * vragen": het grote genummerde cijfer in de marge, dat op mobiel boven de vraag
 * klapt en automatisch de rubriekskleur pakt.
 *
 * Twee klassen diep, niet uit gewoonte: `.art-body h2` is 0-1-1 en wint van één
 * klasse -- zie de waarschuwingen op vijf plekken in concept.css.
 * ------------------------------------------------------------------------- */
.art-body .tp-vragen {
	margin: 34px 0 0;
}

/* De vraag is hier een kop boven vier antwoorden in plaats van een regeltje in
   een kaart, en mag dus wat meer gewicht dan de basis-.tp-v (14,5px / 600). */
.tp-vragen .tp-v {
	margin: 0 0 16px;
	font-size: 17px;
	font-weight: 700;
	line-height: 1.4;
	color: var(--tp-diep);
}

/* Vast twee per rij. Eerst stond hier auto-fit met minmax(230px), maar in de
   volle tekstkolom paste dat er drie naast elkaar en dan valt het vierde
   antwoord alleen op een tweede rij. Twee kolommen houdt de antwoorden ook
   breed genoeg om te lezen. Onder 820px één kolom, hetzelfde breekpunt waarop
   de ledenkaarten (.tp-panel) eenkoloms worden. */
.tp-vragen .tp-antwoorden {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 18px 28px;
}

@media (max-width: 820px) {
	.tp-vragen .tp-antwoorden {
		grid-template-columns: 1fr;
	}
}

/* Gegroepeerd per vraag moet bij elk antwoord staan wie het zegt. Zelfde
   idioom als de veldlabels bij "CV van" (.cv-rij dt). */
.tp-vragen .tp-a-naam {
	margin: 0 0 3px;
	font-size: 11.5px;
	font-weight: 800;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--accent);
}

/* Alleen voor schermlezers. Verving <span class="skip">, want .skip is de
   klasse van de skip-link: die heeft een rode achtergrond en komt met
   .skip:focus in beeld. Een span is niet focusbaar dus het ging goed, maar het
   was de verkeerde klasse. */
.tp-verborgen {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}


/* ---------------------------------------------------------------------------
 * Scroll-reveal.
 *
 * In het ontwerp komen blokken bij het scrollen omhoog en in beeld (.reveal
 * start op opacity 0). Zonder dit staat alles direct hard op de pagina, wat een
 * zichtbaar ander gevoel geeft dan het concept. Wordt aangezet door
 * assets/js/reveal.js; zonder JavaScript blijft alles gewoon zichtbaar.
 * ------------------------------------------------------------------------- */
.js-reveal .reveal {
	opacity: 0;
	transform: translateY(16px);
	transition: opacity .6s cubic-bezier(.22, .61, .36, 1), transform .6s cubic-bezier(.22, .61, .36, 1);
	transition-delay: calc(var(--d, 0) * 90ms);
}

.js-reveal .reveal.in {
	opacity: 1;
	transform: none;
}

@media (prefers-reduced-motion: reduce) {
	.js-reveal .reveal {
		opacity: 1;
		transform: none;
		transition: none;
	}
}

/* ---------------------------------------------------------------------------
 * Query-blokken doorzichtig maken.
 *
 * De opmaak uit het ontwerp gaat uit van directe kindrelaties: .hero-grid heeft
 * .hero-groot en .hero-zij als grid-items, .kaarten heeft .kaart als items.
 * Het query-blok schuift daar drie lagen tussen (<div class="wp-block-query">,
 * <ul class="wp-block-post-template">, <li class="wp-block-post">), waardoor
 * díe de grid-items worden en de layout niet meer klopt.
 *
 * display:contents laat die lagen uit de layoutboom verdwijnen zonder ze uit de
 * DOM te halen, zodat de kaarten weer directe kinderen van hun grid zijn.
 * ------------------------------------------------------------------------- */
/* De in-feed advertentie staat in het ontwerp op de tweede rij, dus na de
   eerste twee kaarten, en niet onderaan waar hij in de bronvolgorde belandt.
   `order` moet op de .kaart zelf staan: de <li> eromheen heeft display:contents
   en staat daarmee buiten de layoutboom, waar order geen effect heeft. */
.kaarten .wp-block-post-template > li .kaart { order: 3; }
.kaarten .wp-block-post-template > li:nth-child(-n+2) .kaart { order: 1; }
.kaarten > .kaart-native { order: 2; grid-column: 1 / -1; }

.hero-grid > .wp-block-query,
.hero-grid .wp-block-post-template,
.hero-grid .wp-block-post-template > li,
.hero-zij > .wp-block-query,
.stroom > .wp-block-query,
.kaarten > .wp-block-query,
.kaarten .wp-block-post-template,
.kaarten .wp-block-post-template > li,
.partnerlijst > li {
	display: contents;
}

/* De post-template met klasse .kaarten moet zijn eigen grid juist wél houden;
   alleen de li's eronder zijn doorzichtig (hierboven geregeld). */

/* Hero: beeld en tekst over elkaar, zoals in het ontwerp. Een donker vlak als
   bodem, want de hero-tekst is wit en lang niet elk artikel heeft beeld —
   zonder bodem staat er witte tekst op wit. */
/* Let op: hier géén display of min-height zetten. Het concept maakt
   .hero-beeldvlak flex met min-height 480px en positioneert .beeld absoluut
   daarbinnen; style.css laadt ná concept.css, dus een eigen display:grid of
   min-height wint en breekt precies die opzet. Alleen het donkere vlak
   toevoegen, als bodem voor artikelen zonder uitgelichte afbeelding — de
   hero-tekst is wit en zou anders onzichtbaar zijn. */
.hero-beeldvlak { background: var(--blue-zodiac); }

/* Het uitgelichte-afbeeldingblok rendert <figure><a><img></a></figure>. Die <a>
   is inline en rekt niet mee, waardoor de foto zijn eigen breedte houdt en het
   donkere vlak eromheen zichtbaar blijft. De <a> en de <img> moeten de
   absoluut gepositioneerde .beeld dus helemaal vullen. */
.hero-beeldvlak .beeld a,
.hero-beeldvlak .beeld img {
	display: block;
	width: 100%;
	height: 100%;
	margin: 0;
	object-fit: cover;
}

.hero-beeldvlak .hero-tekst a { color: #fff; text-decoration: none; }

/* Zelfde <a>-tussenlaag bij de zijkaarten en de gewone kaarten. */
.zij-kaart .beeld a,
.kaart .beeld a,
.partnerbijdrage .beeld a {
	display: block;
	width: 100%;
	height: 100%;
}

.zij-kaart .beeld img,
.kaart .beeld img { width: 100%; display: block; }

/* ---------------------------------------------------------------------------
 * Artikelkop met beeld ernaast (single.html).
 *
 * Op verzoek van de klant staat het beeld naast de kop in plaats van eronder op
 * volle breedte. Het rode vlak kruist de onderrand van de foto en steekt de
 * kolomgoot in, zoals de kleurvlakken in het magazine.
 * ------------------------------------------------------------------------- */
.art-hoofd {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 430px);
	gap: 56px;
	align-items: start;
	padding-bottom: 34px;
}

.art-hoofd .ah-tekst { max-width: none; padding-bottom: 0; }
.art-hoofd .ah-beeld { position: relative; margin: 0; }

.art-hoofd .ah-beeld .beeld,
.art-hoofd .ah-beeld img {
	display: block;
	width: 100%;
	margin: 0;
}

@media (max-width: 880px) {
	.art-hoofd { grid-template-columns: 1fr; gap: 22px; padding-bottom: 10px; }
}

/* ---------------------------------------------------------------------------
 * Rubriekspagina: kleur volgt de rubriek.
 *
 * De concept-stylesheet zet hier de kleur van Nieuws vast, omdat het concept
 * alleen die variant laat zien. Wij laten kop en actief filter --accent volgen,
 * die via de body-klasse al op de juiste rubriek staat.
 * ------------------------------------------------------------------------- */
.rub-kop h1 { color: var(--accent); }

.filter[aria-current] {
	background: var(--accent);
	border-color: var(--accent);
	color: #fff;
}

/* De archiefkop is één blok; zonder dit staat de telling los onder de titel. */
.rub-kop .balk { align-items: flex-end; }
.rub-kop .wp-block-query-title { margin: 0; }

/* `.tekstkant` is een flex-kolom en stretcht zijn kinderen over de volle
   breedte. De pill is inline-block en zou dus meerekken tot een balk van rand
   tot rand; hij moet zich naar zijn eigen inhoud voegen. Zelfde geldt voor de
   metaregel eronder. */
.uitgelicht .tekstkant > .pill,
.uitgelicht .tekstkant > .meta { align-self: flex-start; }

/* ---------------------------------------------------------------------------
 * Kaart als één kliktarget.
 *
 * In het ontwerp is de hele kaart één <a>. Dat kan een blok-template niet
 * maken: je kunt geen link om losse blokken heen zetten. Zonder ingreep krijg
 * je daarom twee links naar hetzelfde artikel (beeld én titel), wat met
 * toetsenbord twee tabstops per kaart kost en een schermlezer het artikel twee
 * keer laat voorlezen.
 *
 * Oplossing: de titel is de enige link naar het artikel en krijgt een
 * onzichtbare laag over de hele kaart. Het rubriekslabel ligt daar bovenop en
 * blijft dus zijn eigen doorklik naar de rubriek houden.
 * ------------------------------------------------------------------------- */
.kaart,
.zij-kaart { position: relative; }

.kaart .wp-block-post-title > a::after,
.zij-kaart .wp-block-post-title > a::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
}

/* Het label blijft klikbaar naar de rubriek. */
.kaart .pill,
.zij-kaart .pill {
	position: relative;
	z-index: 2;
}

/* De absoluut geplaatste pill op het beeld houdt zijn eigen positie. */
.kaart .kaart-pill { position: absolute; }

/* Tekst in de kaart moet selecteerbaar blijven; de overlay vangt anders elke
   muisactie af. Alleen de laag zelf is aanklikbaar. */
.kaart .kaart-tekst p,
.zij-kaart .zij-tekst p { position: relative; z-index: 2; }

/* Zichtbare focus voor toetsenbordgebruik: de link is klein, de kaart groot. */
.kaart:focus-within,
.zij-kaart:focus-within { outline: 3px solid var(--accent); outline-offset: 3px; }

.kaart .wp-block-post-title > a:focus,
.zij-kaart .wp-block-post-title > a:focus { outline: none; }

/* "Meest gelezen": de titel moet bovenaan uitlijnen met het nummer. Het
   post-title-blok brengt een eigen kopmarge mee die de tekst omlaag duwt, en
   zonder expliciete uitlijning centreert de flexregel de twee ten opzichte van
   elkaar zodra de titel over twee regels loopt. */
.lijst li { align-items: flex-start; }

.lijst .wp-block-post-title {
	margin: 0;
	font-size: 14px;
	font-weight: 700;
	line-height: 1.35;
}

/* Paginering: het nummerblok is standaard een block-container, waardoor de
   nummers onder elkaar komen te staan in plaats van naast elkaar. */
.pagineer .wp-block-query-pagination-numbers {
	display: flex;
	gap: 8px;
	flex-wrap: wrap;
	align-items: center;
}

.pagineer .page-numbers.current {
	background: var(--inkt);
	border-color: var(--inkt);
	color: #fff;
}

.pagineer .page-numbers.dots {
	border: 0;
	min-width: 20px;
	padding: 0;
	color: var(--grijs-500);
}

/* Uitgelicht artikel: het beeldblok moet de halve kolom vullen. */
.uitgelicht .beeldkant .beeld,
.uitgelicht .beeldkant .beeld a,
.uitgelicht .beeldkant img {
	display: block;
	width: 100%;
	height: 100%;
	margin: 0;
	object-fit: cover;
}

/* ---------------------------------------------------------------------------
 * Partnerbijdragen — vier à zes onder elkaar.
 *
 * Uit het overleg van 23 juli: niet één groot uitgelicht bericht, maar een
 * compacte lijst zoals AM-web die heeft. Dit zijn kennispartners; een ander
 * soort partner dan de zichtbaarheidspartners in de logostrook.
 * ------------------------------------------------------------------------- */
.partnerlijst {
	display: grid;
	gap: 2px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.partnerbijdrage {
	gap: 18px;
	align-items: flex-start;
	padding: 16px;
	background: var(--grijs-100);
	transition: background .18s;
}

.partnerbijdrage:hover { background: var(--grijs-200); }

.partnerbijdrage .beeld { flex: 0 0 160px; margin: 0; }
.partnerbijdrage .beeld img { display: block; width: 100%; height: 110px; object-fit: cover; }

.partnerbijdrage h3 {
	margin: 8px 0 6px;
	font-size: clamp(17px, 1.7vw, 20px);
	line-height: 1.15;
}

.partnerbijdrage p { margin: 0; font-size: 14.5px; color: var(--grijs-700); }

@media (max-width: 700px) {
	.partnerbijdrage { flex-wrap: wrap; }
	.partnerbijdrage .beeld { flex-basis: 100%; }
	.partnerbijdrage .beeld img { height: 180px; }
}

/* ---------------------------------------------------------------------------
 * Logostrook zichtbaarheidspartners.
 *
 * Staat op de plek waar in het concept de stats-tellers stonden. Marcel wilde
 * die tellers niet ("dit hoeft niet voor ons") en vond de plek te prominent
 * voor deze partners; vandaar eerst onderaan, en alleen logo's. Op verzoek
 * van Rick is de strook op 7 september alsnog met de rubriekenstrook
 * gewisseld en staat hij weer direct onder de hero; alleen logo's is
 * gebleven.
 * ------------------------------------------------------------------------- */
.logostrook-kop {
	margin: 0 0 14px;
	font-weight: 700;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--grijs-500);
}

.logo-carousel {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
	gap: 2px;
}

.logo-carousel .logo-vak {
	display: grid;
	place-items: center;
	min-height: 82px;
	padding: 12px;
	background: var(--grijs-100);
	font-size: 12.5px;
	font-weight: 700;
	color: var(--grijs-500);
}

/* Echte logo's (sinds 16-9): het hele vak is de link naar het dossier. */
.logo-carousel .logo-vak a {
	display: grid;
	place-items: center;
	width: 100%;
	height: 100%;
}

.logo-carousel .logo-vak img {
	width: auto;
	height: auto;
	max-width: 80%;
	max-height: 46px;
	object-fit: contain;
	transition: transform .18s;
}

.logo-carousel .logo-vak a:hover img {
	transform: scale(1.05);
}

/* Meer dan zes partners (sinds 16-9): doorlopende carrousel. Het spoor bevat de
   rij twee keer en schuift een halve breedte op; daarna begint hij naadloos
   opnieuw. Vakken hebben een vaste breedte (zes per rij op desktop). */
.logo-carousel.hf-logocarrousel {
	display: block;
	overflow: hidden;
}

.hf-logocarrousel .hf-logospoor {
	display: flex;
	width: max-content;
	animation: hf-logo-schuif var(--hf-logo-duur, 28s) linear infinite;
}

.hf-logocarrousel .hf-logorij {
	display: flex;
	gap: 2px;
	padding-right: 2px;
}

.hf-logocarrousel .logo-vak {
	flex: 0 0 197px;
}

.hf-logocarrousel:hover .hf-logospoor,
.hf-logocarrousel:focus-within .hf-logospoor {
	animation-play-state: paused;
}

@keyframes hf-logo-schuif {
	from { transform: translateX(0); }
	to   { transform: translateX(-50%); }
}

@media (max-width: 640px) {
	.hf-logocarrousel .logo-vak {
		flex-basis: 150px;
	}
}

@media (prefers-reduced-motion: reduce) {
	.logo-carousel.hf-logocarrousel {
		overflow-x: auto;
	}

	.hf-logocarrousel .hf-logospoor {
		animation: none;
	}

	.hf-logocarrousel .hf-logorij[aria-hidden="true"] {
		display: none;
	}
}

/* ---------------------------------------------------------------------------
 * Veelgestelde vragen.
 *
 * Het concept gebruikt een button met een JS-accordeon. Hier staat een
 * <details>-blok: dat klapt open zonder JavaScript, is toegankelijk zonder
 * eigen aria-werk, en de redactie kan het in de editor beheren. De opmaak
 * volgt het concept.
 * ------------------------------------------------------------------------- */
/* Twee lichtgrijze secties breken het wit van de pagina.
   In het concept deed de stats-strook dat, maar die is op verzoek van de klant
   verwijderd; de rubriekenstrook nam die rol over.
   Sinds 7 september staat de rubriekenstrook in parts/footer.html en dus onder
   elke pagina, vlak boven de donkere footer. Binnen <main> op de homepage is
   "Even praktisch" daarmee de enige grijze onderbreking. */
.rubriekenblok,
.vragen { background: var(--grijs-100); }

.wrap-smal { max-width: 880px; }

/* Waarden overgenomen uit de concept-stylesheet (.acc / .acc-item / .acc-btn):
   alleen dunne scheidingslijnen, geen witte kaarten. De markup is <details> in
   plaats van de button-met-JS uit het concept, omdat dat zonder JavaScript
   werkt en toegankelijk is zonder eigen aria-werk; de opmaak is identiek. */
.acc { border-top: 1px solid var(--grijs-200); }

.acc-item {
	border-bottom: 1px solid var(--grijs-200);
	background: none;
}

.acc-item > summary {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 18px;
	padding: 20px 2px;
	text-align: left;
	font-weight: 800;
	font-size: 17px;
	line-height: 1.35;
	cursor: pointer;
	list-style: none;
}

.acc-item > summary::-webkit-details-marker { display: none; }
.acc-item > summary:hover { color: var(--hf-rood); }

/* Plus van 26px in currentColor, wordt een min bij openen. Twee gradients in
   plaats van ::before + ::after, want ::before op een summary botst met de
   standaardmarker. */
.acc-item > summary::after {
	content: "";
	flex: 0 0 auto;
	width: 26px;
	height: 26px;
	background:
		linear-gradient(currentColor, currentColor) center / 22px 2.5px no-repeat,
		linear-gradient(currentColor, currentColor) center / 2.5px 22px no-repeat;
	transition: background-size .28s;
}

.acc-item[open] > summary::after {
	background: linear-gradient(currentColor, currentColor) center / 22px 2.5px no-repeat;
}

.acc-item > :not(summary) {
	margin: 0 0 20px;
	padding: 0 2px;
	max-width: 70ch;
	color: var(--grijs-700);
	font-size: 15.5px;
}

@media (prefers-reduced-motion: reduce) {
	.acc-item > summary::after { transition: none; }
}

/* ---------------------------------------------------------------------------
 * Off-canvas mobiel menu (opgebouwd door assets/js/mobile-menu.js).
 * ------------------------------------------------------------------------- */
.mobiel-overlay {
	position: fixed;
	inset: 0;
	z-index: 998;
	background: rgba(15, 39, 61, .55);
	opacity: 0;
	transition: opacity .25s;
}

.mobiel-menu {
	position: fixed;
	top: 0;
	right: 0;
	bottom: 0;
	z-index: 999;
	width: 80%;
	max-width: 380px;
	padding: 24px 22px;
	overflow-y: auto;
	background: #fff;
	transform: translateX(100%);
	transition: transform .26s ease;
}

body.menu-open .mobiel-overlay { opacity: 1; }
body.menu-open .mobiel-menu { transform: translateX(0); }
body.menu-open { overflow: hidden; }

.mobiel-menu__sluit {
	position: absolute;
	top: 16px;
	right: 16px;
	display: grid;
	place-items: center;
	width: 40px;
	height: 40px;
	background: none;
	border: 0;
	cursor: pointer;
}

.mobiel-menu__sluit span {
	position: absolute;
	width: 20px;
	height: 2px;
	background: var(--inkt);
}

.mobiel-menu__sluit span:first-child { transform: rotate(45deg); }
.mobiel-menu__sluit span:last-child { transform: rotate(-45deg); }

.mobiel-menu__lijst {
	margin: 48px 0 0;
	padding: 0;
	list-style: none;
}

.mobiel-menu__lijst > li { border-bottom: 1px solid var(--grijs-200); }

.mobiel-menu__lijst a {
	display: block;
	padding: 14px 2px;
	font-weight: 700;
	color: var(--inkt);
	text-decoration: none;
}

.mobiel-menu__sub {
	margin: 0 0 10px;
	padding: 0 0 0 14px;
	list-style: none;
}

.mobiel-menu__sub a {
	padding: 9px 2px;
	font-weight: 500;
	font-size: 14.5px;
	color: var(--grijs-700);
}

@media (prefers-reduced-motion: reduce) {
	.mobiel-menu,
	.mobiel-overlay { transition: none; }
}

/* De blok-editor plaatst afbeeldingen in een <figure>; zonder dit krijgen
   uitgelijnde afbeeldingen een marge die de kleurvlak-overlap breekt. */
.wp-block-image figure { margin: 0; }

/* Skip-link zichtbaar maken zodra hij focus krijgt. */
.skip-link:focus {
	position: fixed;
	top: 8px;
	left: 8px;
	z-index: 999999;
	padding: 12px 20px;
	background: var(--inkt);
	color: #fff;
}

/* Footer met drie kolommen (logo, Over Henk & Fred, Media Vakman) sinds 10-9;
   concept.css rekent op vier. Alleen breed: onder 940px zet concept.css het
   raster zelf op twee en onder 640px op een kolom, en dat klopt nog steeds. */
@media (min-width: 941px) {
	.footer .f-grid {
		grid-template-columns: 1.5fr 1fr 1.2fr;
	}
}

/* ---------------------------------------------------------------------------
 * Partners: dossierblok onder een artikel, dossierpagina en overzicht.
 *
 * Sinds 10-9. Het dossierblok gebruikt de .dossier uit concept.css; de rest
 * heeft eigen klassen met hf-, want concept.css claimt veel korte namen.
 * ------------------------------------------------------------------------- */
.dossier .logo-vak img {
	width: auto;
	height: auto;
	max-width: 80%;
	max-height: 64px;
	object-fit: contain;
}

.hf-partner-kop {
	display: grid;
	grid-template-columns: 220px 1fr;
	gap: 36px;
	align-items: center;
	padding-block: 40px 28px;
}

.hf-partner-kop:not(:has(.hf-partner-logo)) {
	grid-template-columns: 1fr;
}

.hf-partner-logo {
	margin: 0;
	padding: 18px;
	aspect-ratio: 3 / 2;
	display: grid;
	place-items: center;
	background: var(--grijs-100);
}

.hf-partner-logo img {
	width: auto;
	height: auto;
	max-width: 100%;
	max-height: 100%;
	object-fit: contain;
}

.hf-partner-bovenkop {
	margin: 0 0 6px;
	font-size: 12px;
	font-weight: 800;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--hf-rood);
}

.hf-partner-kop h1 {
	margin: 0;
	font-family: var(--display);
	font-weight: 400;
	text-transform: uppercase;
	font-size: clamp(34px, 4.6vw, 56px);
	line-height: .95;
}

.hf-partner-lijf {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 300px;
	gap: 60px;
	align-items: start;
	padding-bottom: 20px;
}

/* Tussenkopjes op een partnerdossier kleiner (Rick, 22-9): 20px in plaats van de
   clamp van 23-30px die theme.json aan h3 geeft. */
.hf-partner-lijf .art-body h3 {
	font-size: 20px;
	margin-top: 26px;
}

.hf-partner-contact ul {
	margin: 0;
	padding: 0;
	list-style: none;
}

.hf-partner-contact li {
	padding: 8px 0;
	border-bottom: 1px solid var(--grijs-200);
	font-size: 14.5px;
}

.hf-partner-contact li span {
	display: block;
	font-size: 11.5px;
	font-weight: 800;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--grijs-500);
}

.hf-partner-archief .sec-kop h1 {
	margin: 0;
	font-family: var(--display);
	font-weight: 400;
	text-transform: uppercase;
	font-size: clamp(34px, 4.6vw, 56px);
	line-height: .95;
}

.hf-partner-overzicht {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 20px;
	margin: 0;
	padding: 0;
	list-style: none;
}

/* Logo in de partnerkaart gecentreerd (14-9). In het overzicht is het logo een
   link (isLink), en WordPress maakt die <a> even hoog als de tegel
   (.wp-block-post-featured-image a {height:100%}). Het beeld stond dan bovenin
   in plaats van in het midden. In het dossier is er geen link, daar ging het goed. */
.hf-partner-kaart .hf-partner-logo a {
	display: grid;
	place-items: center;
	width: 100%;
	height: 100%;
}

.hf-partner-kaart .hf-partner-logo img {
	width: auto;
	max-height: 100%;
}

.hf-partner-kaart h3 {
	margin: 10px 0 0;
	font-size: 16px;
	font-weight: 800;
}

@media (max-width: 820px) {
	.hf-partner-kop,
	.hf-partner-lijf {
		grid-template-columns: 1fr;
		gap: 24px;
	}

	.hf-partner-overzicht {
		grid-template-columns: repeat(2, 1fr);
	}
}

/* ===== Fotogalerij in een artikel (sinds 10-9) =====
   theme.json zet blockGap op 0, waardoor de galerij van WordPress zijn beelden
   tegen elkaar aan zet. De galerij rekent de beeldbreedte uit met deze variabele,
   dus die zetten en niet alleen gap. Twee klassen diep vanwege .art-body. */
.art-body .wp-block-gallery{--wp--style--unstable-gallery-gap:12px;gap:12px;margin:40px 0 0}
.art-body .wp-block-gallery .blocks-gallery-caption{width:100%;margin:2px 0 0;font-size:13px;opacity:.7;text-align:left}

/* ===== Leesbreedte op de inhoud, niet op de kolom (25-9) =====
   `.art-body` had in concept.css `max-width:66ch` (623px), zodat een regel tekst
   niet te lang wordt. Daarmee werd ook de in-text-advertentie tot 623px geknepen,
   terwijl de gridkolom 832px breed is (`.art-grid` = minmax(0,1fr) 300px, gap 60,
   wrap 1240). Een 728x90-leaderboard schaalde daardoor naar 623x77: 86% van het
   verkochte formaat.

   De leesbreedte staat nu op de kinderen van `.art-body`, zodat de tekst precies
   even breed blijft als daarvoor en alleen de advertentie de volle kolom pakt. Die
   krijgt 100%% en niet none: op mobiel is de kolom smaller dan 728px, en met
   overflow-x clip op de body zou een te brede banner stil worden afgekapt.
   De eerste regel overschrijft concept.css; dat mag hier, want style.css hangt
   in henkenfred_assets() af van henkenfred-concept en wordt dus later geladen. */
.art-body { max-width: none; }
.art-body > * { max-width: 66ch; }
.art-body > .advertentie { max-width: 100%; }

/* ===== Partnerportaal (25-9) =====
   De eigen omgeving van een partner: inloggen, overzicht, schrijven en het
   eigen dossier. Alles op de pagina /mijn-omgeving/, gerenderd door het blok
   henkenfred/partnerportaal (inc/partnerportaal.php).

   Kleuren en knoppen komen uit de tokens van het concept; de knop hieronder is
   dezelfde als .knop maar met een eigen naam, omdat .knop in concept.css staat
   en dat bestand gegenereerd wordt. */
.hf-portaal {
	max-width: 940px;
	margin-inline: auto;
	padding: 48px 0 72px;
}

.hf-portaal-kop {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 20px;
	margin-bottom: 26px;
	padding-bottom: 18px;
	border-bottom: 2px solid var(--grijs-200);
}

.hf-portaal-bovenkop {
	margin: 0 0 4px;
	font-weight: 800;
	font-size: 13px;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--hf-rood);
}

.hf-portaal h1 { margin: 0; }
.hf-portaal h2 { margin: 0 0 14px; font-size: 22px; }

.hf-portaal-lead {
	margin: 0 0 22px;
	color: var(--grijs-700);
}

.hf-portaal-uit {
	font-weight: 700;
	font-size: 15px;
	white-space: nowrap;
	color: var(--grijs-700);
	border-bottom: 2px solid var(--grijs-200);
}
.hf-portaal-uit:hover { color: var(--hf-rood); border-bottom-color: var(--hf-rood); }

/* Kaart */
.hf-portaal-kaart {
	background: #fff;
	border: 1.5px solid var(--grijs-200);
	padding: 28px 30px;
	margin-bottom: 26px;
}
.hf-portaal-smal { max-width: 460px; margin-inline: auto; }

/* Knoppenrij boven het overzicht */
.hf-portaal-acties {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	margin-bottom: 26px;
}

.hf-portaal-knop {
	display: inline-flex;
	align-items: center;
	gap: 9px;
	background: var(--hf-rood);
	color: #fff;
	font-weight: 800;
	font-size: 15px;
	padding: 12px 22px;
	border: 1.5px solid transparent;
	cursor: pointer;
	transition: transform .18s, box-shadow .18s, background .18s;
}
.hf-portaal-knop:hover {
	transform: translateY(-2px);
	box-shadow: 0 8px 20px rgba(202, 8, 46, .32);
	background: #b00727;
	color: #fff;
}
.hf-portaal-knop-licht {
	background: #fff;
	color: var(--inkt);
	border-color: var(--grijs-200);
}
.hf-portaal-knop-licht:hover {
	background: var(--grijs-100);
	box-shadow: none;
	border-color: var(--grijs-500);
	color: var(--inkt);
}

/* Formuliervelden */
.hf-portaal label {
	display: block;
	margin-bottom: 6px;
	font-weight: 800;
	font-size: 14px;
}
.hf-portaal input[type="text"],
.hf-portaal input[type="url"],
.hf-portaal input[type="email"],
.hf-portaal input[type="password"],
.hf-portaal textarea {
	width: 100%;
	padding: 11px 13px;
	font: inherit;
	font-size: 16px;
	color: var(--inkt);
	background: #fff;
	border: 1.5px solid var(--grijs-200);
}
.hf-portaal input:focus,
.hf-portaal textarea:focus,
.hf-portaal-vlak:focus {
	outline: 2px solid var(--hf-blauw);
	outline-offset: 1px;
	border-color: var(--hf-blauw);
}
.hf-portaal form p { margin: 0 0 18px; }
.hf-portaal-onthoud label { font-weight: 400; font-size: 15px; }
.hf-portaal-onthoud input { margin-right: 6px; }

.hf-portaal-hulp {
	display: block;
	margin-top: 5px;
	font-size: 13.5px;
	color: var(--grijs-500);
}
.hf-portaal-klein { font-size: 14px; color: var(--grijs-500); }
.hf-portaal-klein a { color: var(--grijs-700); border-bottom: 2px solid var(--grijs-200); font-weight: 700; }
.hf-portaal-klein a:hover { color: var(--hf-rood); border-bottom-color: var(--hf-rood); }

/* Opmaakbalk */
.hf-portaal-editor { margin-bottom: 22px; }
.hf-portaal-balk {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	padding: 8px;
	background: var(--grijs-100);
	border: 1.5px solid var(--grijs-200);
	border-bottom: 0;
}
.hf-portaal-balk button {
	padding: 6px 12px;
	font-weight: 700;
	font-size: 13.5px;
	background: #fff;
	color: var(--inkt);
	border: 1.5px solid var(--grijs-200);
	cursor: pointer;
}
.hf-portaal-balk button:hover { border-color: var(--grijs-500); }

.hf-portaal-vlak {
	min-height: 260px;
	padding: 16px 18px;
	background: #fff;
	border: 1.5px solid var(--grijs-200);
	font-size: 16.5px;
	line-height: 1.7;
}
.hf-portaal-vlak p { margin: 0 0 16px; }
.hf-portaal-vlak h2 { font-size: 21px; margin: 24px 0 10px; }
.hf-portaal-vlak h3 { font-size: 18px; margin: 20px 0 8px; }
.hf-portaal-vlak ul,
.hf-portaal-vlak ol { margin: 0 0 16px; padding-left: 22px; }
.hf-portaal-vlak a { color: var(--hf-rood); text-decoration: underline; }

/* Beeld */
.hf-portaal-beeld { margin-bottom: 22px; }
.hf-portaal-voorbeeld { margin: 0 0 12px; }
.hf-portaal-voorbeeld img { max-width: 260px; height: auto; border: 1.5px solid var(--grijs-200); }
.hf-portaal-voorbeeld-logo img { background: #fff; padding: 10px; }

/* Velden bij elkaar */
.hf-portaal fieldset {
	margin: 0 0 22px;
	padding: 18px 20px;
	border: 1.5px solid var(--grijs-200);
}
.hf-portaal legend {
	padding: 0 8px;
	font-weight: 800;
	font-size: 14px;
}
.hf-portaal-knoprij {
	display: grid;
	grid-template-columns: 1fr 1.4fr;
	gap: 14px;
	margin-bottom: 12px;
}
.hf-portaal-knoprij label { font-weight: 400; }
.hf-portaal-knoprij span { display: block; margin-bottom: 4px; font-weight: 800; font-size: 13px; }

.hf-portaal-verzenden {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	margin: 26px 0 10px;
}

/* Lijst met bijdragen */
.hf-portaal-lijst { width: 100%; border-collapse: collapse; }
.hf-portaal-lijst th {
	text-align: left;
	padding: 0 12px 10px 0;
	font-size: 13px;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--grijs-500);
	border-bottom: 2px solid var(--grijs-200);
}
.hf-portaal-lijst td {
	padding: 14px 12px 14px 0;
	border-bottom: 1px solid var(--grijs-200);
	font-size: 15.5px;
}
.hf-portaal-rechts { text-align: right; }
.hf-portaal-lijst a { font-weight: 700; color: var(--hf-rood); }

.hf-portaal-status {
	display: inline-block;
	padding: 3px 10px;
	font-weight: 800;
	font-size: 12px;
	letter-spacing: .04em;
	text-transform: uppercase;
	background: var(--grijs-100);
	color: var(--grijs-700);
}
.hf-portaal-status-publish { background: var(--mint-20); color: var(--jungle-green); }
.hf-portaal-status-pending { background: var(--lemon-20); color: var(--golden-bell); }

/* Melding na een handeling */
.hf-portaal-melding {
	margin: 0 0 22px;
	padding: 14px 18px;
	font-weight: 700;
	border-left: 4px solid var(--jungle-green);
	background: var(--mint-20);
}
.hf-portaal-melding-fout {
	border-left-color: var(--hf-rood);
	background: var(--rood-20);
}

@media (max-width: 781px) {
	.hf-portaal { padding: 30px 0 52px; }
	.hf-portaal-kaart { padding: 22px 18px; }
	.hf-portaal-kop { flex-direction: column; align-items: flex-start; gap: 10px; }
	.hf-portaal-knoprij { grid-template-columns: 1fr; }
	.hf-portaal-lijst thead { display: none; }
	.hf-portaal-lijst tr { display: block; padding: 12px 0; border-bottom: 1px solid var(--grijs-200); }
	.hf-portaal-lijst td { display: block; padding: 2px 0; border: 0; }
	.hf-portaal-rechts { text-align: left; margin-top: 6px; }
}

/* Een bijdrage die de redactie voor deze partner heeft ingevoerd; staat onder
   de titel in het overzicht, zodat duidelijk is waarom er geen Bewerken-link
   naast staat. */
.hf-portaal-door {
	display: block;
	margin-top: 3px;
	font-size: 13px;
	color: var(--grijs-500);
}
