/* ==========================================================================
   Autive Starter Theme — core CSS
   --------------------------------------------------------------------------
   Structural + component CSS. References only semantic tokens defined in the
   translation layer below; semantic tokens in turn alias WP preset vars
   generated from theme.json. Child themes override theme.json palette/fonts
   and everything downstream adapts without touching this file.
   ========================================================================== */

/* 0. Translation layer: WP preset vars -> semantic role vars ------------- */
:root {
  /* Backgrounds */
  --bg-page:         var(--wp--preset--color--background);
  --bg-surface:      var(--wp--preset--color--surface);
  --bg-inverse:      var(--wp--preset--color--secondary);
  --bg-chip:         var(--wp--preset--color--background);

  /* Text */
  --text-body:       var(--wp--preset--color--foreground);
  --text-muted:      color-mix(in srgb, var(--wp--preset--color--foreground) 72%, var(--wp--preset--color--background));
  --text-heading:    var(--wp--preset--color--secondary);
  --text-accent:     var(--wp--preset--color--primary);
  --text-highlight:  var(--wp--preset--color--accent);
  --text-on-inverse: var(--wp--preset--color--background);
  --text-on-accent:  var(--wp--preset--color--background);

  /* Derived backgrounds */
  --bg-surface-soft: color-mix(in srgb, var(--wp--preset--color--surface) 78%, var(--wp--preset--color--foreground));

  /* Borders */
  --border-subtle:   color-mix(in srgb, var(--wp--preset--color--foreground) 18%, var(--wp--preset--color--background));
  --border-strong:   var(--wp--preset--color--foreground);
  --border-accent:   var(--wp--preset--color--primary);

  /* Brand roles */
  --brand-primary:         var(--wp--preset--color--primary);
  --brand-primary-dark:    color-mix(in srgb, var(--wp--preset--color--primary) 80%, black);
  --brand-primary-tint:    color-mix(in srgb, var(--wp--preset--color--primary) 14%, var(--wp--preset--color--background));
  /* Primary carries text at 4.75:1 on surface, which the paper grain drops to
     4.45:1 - under AA for the small eyebrows and dates that sit on cream cards.
     This is the same rust, darkened just enough to clear it at 5.01:1 grained. */
  --brand-primary-on-surface: color-mix(in srgb, var(--wp--preset--color--primary) 90%, var(--wp--preset--color--foreground));
  --brand-secondary:       var(--wp--preset--color--secondary);
  --brand-secondary-mid:   color-mix(in srgb, var(--wp--preset--color--secondary) 70%, var(--wp--preset--color--background));
  --brand-secondary-light: color-mix(in srgb, var(--wp--preset--color--secondary) 45%, var(--wp--preset--color--background));
  --brand-secondary-tint:  color-mix(in srgb, var(--wp--preset--color--secondary) 12%, var(--wp--preset--color--background));
  --brand-tertiary:        var(--wp--preset--color--accent);
  --brand-tertiary-bright: color-mix(in srgb, var(--wp--preset--color--accent) 82%, white);

  /* Status */
  --status-error:   var(--wp--preset--color--error);
  /* The error red is a background and border colour: #DC2626 carries text at
     4.20:1 on a form card, under the 4.5:1 small text needs, and the paper
     grain takes it lower still. This darker derivation is the one that carries
     text - 5.47:1 on surface, 5.20:1 on the error summary's own tint. */
  --status-error-text: color-mix(in srgb, var(--wp--preset--color--error) 82%, var(--wp--preset--color--foreground));
  --status-warning: var(--wp--preset--color--warning);
  --status-success: var(--wp--preset--color--success);

  /* Typography
     Core.css references --font-display / --font-sans / --font-serif throughout.
     Child themes ship fontFamilies with slugs `display`, `body`, `accent-serif`
     (the convention). The parent ships `system` + `system-serif` as fallbacks
     for when no child is active. The var() fallback chain handles both. */
  --font-display: var(--wp--preset--font-family--display, var(--wp--preset--font-family--system, -apple-system, BlinkMacSystemFont, sans-serif));
  --font-sans:    var(--wp--preset--font-family--body,    var(--wp--preset--font-family--system, -apple-system, BlinkMacSystemFont, sans-serif));
  --font-serif:   var(--wp--preset--font-family--accent-serif, var(--wp--preset--font-family--system-serif, ui-serif, Georgia, serif));
  --font-display-vars:      normal;
  --font-display-vars-soft: normal;

  /* Custom theme.json tokens aliased to short names */
  --container:        var(--wp--custom--container--wide);
  --container-narrow: var(--wp--custom--container--narrow);
  --gutter:           var(--wp--custom--gutter);
  --section-y:        var(--wp--custom--section--y);
  --section-y-sm:     var(--wp--custom--section--y-sm);
  --section-y-xs:     var(--wp--custom--section--y-xs);

  --radius-xs:   var(--wp--custom--radius--xs);
  --radius-sm:   var(--wp--custom--radius--sm);
  --radius-md:   var(--wp--custom--radius--md);
  --radius-lg:   var(--wp--custom--radius--lg);
  --radius-pill: var(--wp--custom--radius--pill);
  --radius-blob: var(--wp--custom--radius--blob);

  --stroke-hair: var(--wp--custom--stroke--hair);
  --stroke-firm: var(--wp--custom--stroke--firm);

  --motion-quick:  var(--wp--custom--motion--quick);
  --motion-smooth: var(--wp--custom--motion--smooth);
  --motion-rise:   var(--wp--custom--motion--rise);

  --tracking-tight:   var(--wp--custom--tracking--tight);
  --tracking-normal:  var(--wp--custom--tracking--normal);
  --tracking-label:   var(--wp--custom--tracking--label);
  --tracking-eyebrow: var(--wp--custom--tracking--eyebrow);

  --leading-heading: var(--wp--custom--leading--heading);
  --leading-body:    var(--wp--custom--leading--body);
  --leading-lead:    var(--wp--custom--leading--lead);

  /* Shadows */
  --shadow-card:    var(--wp--preset--shadow--card);
  --shadow-listing: var(--wp--preset--shadow--listing);
  --shadow-btn:     var(--wp--preset--shadow--button);

  /* Focus */
  /* Solid, not 45% alpha. Composited over the page the old ring measured
     1.97:1, over a primary button 1.00:1 - the same colour as the button.
     1.4.11 asks 3:1. Solid primary on the page background is 5.10:1. */
  --focus-ring-color: var(--wp--preset--color--primary);
  --focus-ring:       0 0 0 3px var(--focus-ring-color);
  /* A single-colour ring cannot serve both grounds; dark contexts opt in. */
  --focus-ring-color-inverse: var(--wp--preset--color--background);
  --focus-offset:     var(--wp--custom--focus--offset);

  /* Layers */
  --z-nav:       50;
  --z-sticky:    40;
  --z-grain:     100;
  --z-skip-link: 200;
}

/* 1. Reset + body ------------------------------------------------------- */
:where(h1, h2, h3, h4, h5, h6) { scroll-margin-top: calc(82px + 1.5rem); }

body {
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  position: relative;
}

/* 2. Utility: containers + section rhythm ------------------------------- */
.nlbs-wrap {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.nlbs-wrap-narrow { max-width: var(--container-narrow); }

/* Measure utilities — cap heading/text line length without inline styles.
   Use the `className` block attribute (valid) instead of an inline max-width
   (not a block attribute → invalid block content). */
.nlbs-u-measure-14 { max-width: 14ch; }
.nlbs-u-measure-18 { max-width: 18ch; }
.nlbs-u-measure-20 { max-width: 20ch; }
.nlbs-u-measure-22 { max-width: 22ch; }
.nlbs-u-measure-24 { max-width: 24ch; }
.nlbs-u-balance    { text-wrap: balance; }
.nlbs-lead  { max-width: 48ch; }

.nlbs-section         { padding-block: var(--section-y); }
.nlbs-section-tight   { padding-block-start: 1.5rem; }
.nlbs-section-seamless{ padding-block-start: 0; }
.is-style-nlbs-surface {
  background: var(--bg-surface);
  border-block: var(--stroke-hair) solid var(--border-subtle);
}
.is-style-nlbs-inverse {
  background: var(--bg-inverse);
  color: var(--text-on-inverse);
}

/* Vertical rhythm fallback: any full-width <section> that doesn't set its own
   vertical padding (heroes, bands, stats opt out via their own class / inline
   padding, which win over this zero-specificity rule) gets a comfortable
   block padding. This also guarantees breathing room above the flush footer. */
:where(section.wp-block-group.alignfull) { padding-block: var(--section-y-sm); }
/* Keep the reduced top for tight sections, but give them a real bottom. */
.nlbs-section-tight { padding-block-end: var(--section-y-sm); }

hr.nlbs-rule {
  border: 0;
  block-size: var(--stroke-hair);
  background: var(--border-subtle);
  margin-block: 2rem;
}

/* 3. Eyebrow ------------------------------------------------------------ */
.nlbs-eyebrow {
  font-family: var(--font-sans);
  font-size: 0.72rem !important;
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  font-weight: 500;
  color: var(--text-accent);
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
}
.nlbs-eyebrow::before {
  content: "";
  width: 28px;
  block-size: 1px;
  background: currentColor;
  display: inline-block;
}
/* On dark backgrounds the accent has too little contrast, so switch to the
   highlight colour. Done by context rather than by an extra class, so the
   Eyebrow block just works wherever an editor drops it. The explicit
   modifier stays supported for content saved before this rule existed. */
.is-style-nlbs-inverse .nlbs-eyebrow,
.nlbs-cta-band .nlbs-eyebrow,
.nlbs-site-footer .nlbs-eyebrow,
.is-style-nlbs-eyebrow-inverse { color: var(--text-highlight); }

/* 4. Italic display inline accent (headline pull) ----------------------- */
.nlbs-em-serif,
h1 em, h2 em, h3 em {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  color: var(--text-accent);
  letter-spacing: var(--tracking-tight);
}

/* 5. Drop cap for long prose ------------------------------------------- */
.has-drop-cap:not(:focus)::first-letter,
.nlbs-drop::first-letter {
  font-family: var(--font-serif);
  font-size: 4.6em;
  float: left;
  line-height: 0.85;
  padding: 0.08em 0.12em 0 0;
  color: var(--text-accent);
  font-weight: 500;
}

/* 6. Prose --------------------------------------------------------------- */
.is-style-nlbs-prose p {
  font-size: 1.06rem;
  color: var(--text-muted);
  margin-bottom: 1em;
  max-width: 62ch;
  text-wrap: pretty;
}
.is-style-nlbs-prose p.is-style-nlbs-intro {
  font-family: var(--font-serif);
  font-size: 1.35rem;
  font-style: italic;
  color: var(--text-body);
  max-width: 38ch;
  line-height: var(--leading-lead);
}
.is-style-nlbs-prose h2 { margin-top: 1rem; }
.is-style-nlbs-prose h3 { margin-top: 2rem; margin-bottom: 0.75rem; color: var(--text-heading); }

.nlbs-prose-two {
  column-count: 2;
  column-gap: 3rem;
  column-rule: var(--stroke-hair) solid var(--border-subtle);
}
@media (max-width: 760px) { .nlbs-prose-two { column-count: 1; } }
.nlbs-prose-two p { break-inside: avoid; margin-bottom: 0.9em; }

/* 7. Pullquote ---------------------------------------------------------- */
.is-style-nlbs-quote {
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 2.5vw, 2.4rem);
  line-height: 1.15;
  color: var(--text-heading);
  max-width: 22ch;
  border-top: var(--stroke-hair) solid var(--border-accent);
  border-bottom: var(--stroke-hair) solid var(--border-accent);
  padding: 1.5rem 0;
  margin: 2.5rem 0;
}
.is-style-nlbs-quote::before {
  content: "\276E\276F";
  display: block;
  color: var(--text-accent);
  font-size: 1rem;
  margin-bottom: 0.5rem;
}
.nlbs-quote-wide { max-width: none; }

/* 8. Flourish separator ------------------------------------------------ */
.is-style-nlbs-flourish {
  display: block;
  text-align: center;
  color: var(--text-accent);
  font-size: 1.2rem;
  margin: 2rem 0;
  letter-spacing: 1em;
}
.is-style-nlbs-flourish::before { content: "\2767 \2766 \2767"; }

/* 9. Site header + footer scaffolding ---------------------------------- */
/* Sticky footer: make the page a full-height column so the footer never
   floats up on short pages — it sits at least at the bottom of the viewport. */
.wp-site-blocks {
  display: flex;
  flex-direction: column;
  min-block-size: 100dvh;
}
.wp-site-blocks > main { flex: 1 0 auto; }

/* The header template-part wraps the nav and is a direct child of the page
   root, so sticky must live HERE (sticking the inner bar to its own wrapper
   gives no scroll room). */
header.wp-block-template-part {
  position: sticky;
  top: 0;
  z-index: var(--z-nav);
}
/* When logged in, the WP admin bar is fixed at the top (z-index 99999), so a
   sticky header at top:0 slides behind it — covering the top of the nav and
   killing hover on the links. Offset the stick point by the admin-bar height.
   At <=600px the admin bar is position:absolute (scrolls away), so no offset. */
.admin-bar header.wp-block-template-part { top: 32px; }
@media screen and (min-width: 601px) and (max-width: 782px) {
  .admin-bar header.wp-block-template-part { top: 46px; }
}
@media screen and (max-width: 600px) {
  .admin-bar header.wp-block-template-part { top: 0; }
}
.nlbs-nav {
  background: color-mix(in srgb, var(--bg-page) 88%, transparent);
  border-bottom: var(--stroke-hair) solid var(--border-subtle);
  transition: box-shadow var(--motion-smooth), background var(--motion-smooth), padding var(--motion-smooth);
  position: relative;
}
/* The frosting lives on a pseudo-element, not on .nlbs-nav itself.
   A non-none backdrop-filter makes its element the containing block for every
   position:fixed descendant - which included the mobile menu overlay. The
   overlay resolved against the 34px header box instead of the viewport: 287px
   of menu clipped, and the close button at y = -49, off screen. There was no
   visible way to shut the menu on a phone. Keep the effect here. */
.nlbs-nav::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  backdrop-filter: saturate(1.1) blur(8px);
  pointer-events: none;
}
/* Elevate + condense the sticky header once the page scrolls.
   Scroll-driven animation where supported; harmless no-op otherwise. */
@supports (animation-timeline: scroll()) {
  .nlbs-nav {
    animation: nlbs-nav-elevate linear both;
    animation-timeline: scroll(root block);
    animation-range: 2rem 9rem;
  }
  @keyframes nlbs-nav-elevate {
    to {
      box-shadow: 0 10px 30px -22px color-mix(in srgb, var(--text-heading) 55%, transparent);
      background: color-mix(in srgb, var(--bg-page) 96%, transparent);
    }
  }
}

/* Footer template-part wrapper inherits the root blockGap margin; remove it
   so the footer sits flush against the section above. */
footer.wp-block-template-part { margin-block-start: 0; }

.nlbs-site-footer {
  background: var(--bg-inverse);
  color: var(--text-on-inverse);
  padding: clamp(3rem, 5vw, 5rem) 0 2rem;
  position: relative;
  overflow: hidden;
}
/* theme.json's link colour (primary) landed on the dark footer at 2.14:1 -
   worse than its own hover state. The footer sets its own text colour and must
   set its own link colour with it. */
.nlbs-site-footer a {
  color: var(--text-on-inverse);
  transition: color var(--motion-quick);
}
.nlbs-site-footer a:hover,
.nlbs-site-footer a:focus-visible { color: var(--text-highlight); }
/* Everything sitting on --bg-inverse needs the light ring: primary on the dark
   green measures 2.14:1, under 1.4.11's 3:1. */
.nlbs-site-footer :focus-visible,
.is-style-nlbs-inverse :focus-visible,
.nlbs-cta-band :focus-visible,
/* The dropdown only. Unscoped, this fires in the mobile overlay too, where core
   paints the ground white and the inverse ring is #fbf7ec on #ffffff - 1.07:1,
   the same failure as the text colour, one layer up. */
.wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__submenu-container :focus-visible {
  outline-color: var(--focus-ring-color-inverse);
}

.nlbs-site-footer .wp-block-columns { margin-bottom: 3rem; }
/* Matched on level AND on the old levels. These rules were written for h4/h5;
   raising the footer headings to h2/h3 for the document outline orphaned both,
   and the headings fell back to theme.json's global heading colour - secondary
   on a secondary background, 1.00:1, invisible. Keep both sets of selectors so
   the next outline change cannot do it again silently. */
.nlbs-site-footer h2,
.nlbs-site-footer h4 {
  color: var(--text-on-inverse);
  font-size: var(--wp--preset--font-size--large);
  font-weight: 400;
  line-height: 1.1;
}
.nlbs-site-footer h3,
.nlbs-site-footer h5 {
  font-family: var(--font-sans);
  font-size: 0.72rem;
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  font-weight: 500;
  color: var(--text-highlight);
  margin-bottom: 1.25rem;
}
.nlbs-site-footer ul {
  /* Not `none`: Safari and VoiceOver drop list semantics when the marker is
     removed that way, so a marked-up list stops being announced as one. An
     empty string removes the marker and keeps the role. */
  list-style-type: "";
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  font-size: 0.92rem;
}

.nlbs-site-footer__bottom {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-top: 2rem;
  border-top: var(--stroke-hair) solid color-mix(in srgb, var(--text-on-inverse) 15%, transparent);
  font-size: 0.78rem;
  color: color-mix(in srgb, var(--text-on-inverse) 65%, transparent);
  flex-wrap: wrap;
  gap: 1rem;
}

/* 9b. Navigation -------------------------------------------------------- */
.wp-block-navigation { font-size: 0.82rem; letter-spacing: 0.12em; text-transform: uppercase; }

/* The submenu arrow is a real button, and on a touch device wider than the
   overlay breakpoint it is the only route to the five destinations under
   Vereniging - there is no hover to fall back on. Core sizes it at .6em
   against the nav's 0.82rem, which lands at roughly 8x8 CSS pixels. The arrow
   keeps its size; the target grows around it. WCAG 2.2 SC 2.5.8 asks 24x24. */
.wp-block-navigation .wp-block-navigation-submenu__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-inline-size: 28px;
  min-block-size: 44px;
  padding-block: 0;
  padding-inline: 0.35rem;
}
.wp-block-navigation .wp-block-navigation-item__content {
  font-weight: 500;
  color: var(--text-muted);
  display: flex;
  align-items: center;
  padding-block: 1.3rem;          /* full bar height: link top→bottom = bar */
  padding-inline: 0;
  position: relative;
  transition: color var(--motion-quick);
}
/* Centre the logo and let the (taller) nav define the bar height, so each
   link spans the whole bar — the dropdown then drops exactly under the bar
   edge and the active/hover underline sits right on it. */
.nlbs-nav > .wp-block-group { align-items: center; }
/* Animated underline — grows from the left on hover and stays put on the
   current page. Same bar drives hover + active so the cue reads instantly. */
.wp-block-navigation .wp-block-navigation-item__content::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  block-size: 2px;
  background: var(--text-accent);
  border-radius: 2px;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--motion-smooth);
}
.wp-block-navigation .wp-block-navigation-item__content:hover { color: var(--text-heading); }
.wp-block-navigation .wp-block-navigation-item__content:hover::after { transform: scaleX(1); }

/* Active page (and its parent when on a sub-page): stronger weight + colour
   and a persistent underline. */
.wp-block-navigation .current-menu-item > .wp-block-navigation-item__content,
.wp-block-navigation .current-menu-ancestor > .wp-block-navigation-item__content {
  color: var(--text-heading);
  font-weight: 600;
}
.wp-block-navigation .current-menu-item > .wp-block-navigation-item__content::after,
.wp-block-navigation .current-menu-ancestor > .wp-block-navigation-item__content::after {
  transform: scaleX(1);
}

/* Submenu / dropdown panels — fully self-contained (positioning + show/hide)
   so behaviour never depends on core's view CSS loading. Dark, on-brand
   (matches the footer), high-contrast light text (WCAG AA). Opens on hover,
   keyboard focus, AND the block's click toggle (.is-menu-open). */
.wp-block-navigation .wp-block-navigation-item.has-child { position: relative; }
/* Simplest universal dropdown: display none -> block on hover/focus/open.
   Attached to the bar (no gap) so hover never drops, and no visibility/
   opacity/transform/pointer-events tricks that render differently across
   browsers.

   EVERY selector here is scoped to :not(.is-menu-open). This is the desktop
   dropdown, a dark panel floating over a light page. The mobile overlay is a
   different component - core paints it white and governs it - and these rules
   applied there hid five destinations outright, then, once the display rule
   was scoped, painted them cream-on-white at 1.07:1. Scoping the display rule
   alone is not enough: the colour rules need it too.

   The same block is inlined in functions.php as critical CSS. Change both. */
.wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__submenu-container {
  display: none;
  position: absolute;
  inset-block-start: 100%;
  inset-inline-start: 0;
  z-index: calc(var(--z-nav) + 1);
  min-inline-size: 15rem;
  margin: 0;
  padding: 0.45rem;
  list-style: none;
  background-color: var(--bg-inverse);
  border: var(--stroke-hair) solid color-mix(in srgb, var(--text-on-inverse) 16%, transparent);
  border-radius: var(--radius-md);
  box-shadow: 0 22px 44px -26px color-mix(in srgb, var(--text-heading) 80%, transparent);
}
.wp-block-navigation__responsive-container:not(.is-menu-open) .has-child:hover > .wp-block-navigation__submenu-container,
/* Note: this :focus-within branch is currently dead. Core's style.min.css keeps
   the panel at visibility:hidden/opacity:0, and this rule only overrides
   `display`, so tabbing to the parent link does not reveal the dropdown. The
   working keyboard route is core's own: Tab to the arrow toggle, press Enter.
   Left in place because a core change could revive it, but do not rely on it -
   measured 2026-08-26. */
.wp-block-navigation__responsive-container:not(.is-menu-open) .has-child:focus-within > .wp-block-navigation__submenu-container,
.wp-block-navigation__responsive-container:not(.is-menu-open) .has-child.is-menu-open > .wp-block-navigation__submenu-container {
  display: block;
}
.wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
  display: block;
  inline-size: 100%;
  padding: 0.55rem 0.8rem;
  border-radius: var(--radius-sm);
  color: var(--text-on-inverse);
  text-transform: none;          /* readable: drop the bar's uppercase tracking */
  letter-spacing: normal;
  font-size: 0.9rem;
  transition: background var(--motion-quick), padding-inline-start var(--motion-quick);
}
.wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__submenu-container .wp-block-navigation-item__content::after { content: none; }
.wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__submenu-container .wp-block-navigation-item__content:hover,
.wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__submenu-container .wp-block-navigation-item:focus-within > .wp-block-navigation-item__content,
.wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation__submenu-container .current-menu-item > .wp-block-navigation-item__content {
  background-color: color-mix(in srgb, var(--text-on-inverse) 16%, transparent);
  color: var(--text-on-inverse);
  padding-inline-start: 1.1rem;
}

/* 9c. Site logo — cap height so a horizontal wordmark keeps the bar compact. */
.nlbs-nav .wp-block-site-logo img,
.nlbs-nav .custom-logo {
  /* Fixed height + auto width so an SVG (no intrinsic size) scales by its
     viewBox instead of collapsing to 0. */
  height: clamp(34px, 4.6vw, 44px);
  width: auto;
  max-width: min(72vw, 320px);
}

/* 9d. Hero media + anniversary seal ------------------------------------ */
.nlbs-hero-media { position: relative; display: inline-block; }

/* Stamped anniversary seal — inline SVG so it uses the theme display font.
   Circular text wraps a large serif "20". Sits, slightly askew, over the
   top-right of the hero blob like a wax stamp. */
.nlbs-seal {
  position: absolute;
  inset-block-start: clamp(-3rem, -3vw, -1.5rem);
  inset-inline-end: clamp(-1.25rem, -1.5vw, -0.25rem);
  z-index: 2;
  inline-size: clamp(6.5rem, 16vw, 9.75rem);
  rotate: -7deg;
  filter: drop-shadow(0 14px 22px color-mix(in srgb, var(--text-heading) 38%, transparent));
  transition: rotate var(--motion-smooth), scale var(--motion-smooth);
}
/* Gated like every other motion rule in this file. It was the one that was not. */
@media (prefers-reduced-motion: no-preference) {
  .nlbs-hero-media:hover .nlbs-seal { rotate: -3deg; scale: 1.04; }
}
.nlbs-seal svg { display: block; inline-size: 100%; block-size: auto; }
.nlbs-seal__disc  { fill: var(--bg-page); }
.nlbs-seal__ring  { fill: none; stroke: var(--brand-primary); stroke-width: 1.4; }
.nlbs-seal__hair  { fill: none; stroke: color-mix(in srgb, var(--brand-secondary) 55%, transparent); stroke-width: 0.75; }
.nlbs-seal__arc {
  fill: var(--brand-secondary);
  font-family: var(--font-sans);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 1.6px;
  text-transform: uppercase;
}
.nlbs-seal__num {
  fill: var(--brand-primary);
  font-family: var(--font-display);
  font-size: 60px;
  font-weight: 500;
  font-variation-settings: var(--font-display-vars);
}
.nlbs-seal__label {
  fill: var(--brand-secondary);
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 6px;
  text-transform: uppercase;
}
.nlbs-seal__star { fill: var(--brand-tertiary); font-size: 13px; }

/* 10. Buttons (core/button overrides) ---------------------------------- */
.wp-block-button__link {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  border-radius: var(--radius-pill);
  white-space: nowrap;
  transition: transform var(--motion-quick), background var(--motion-quick), color var(--motion-quick), box-shadow var(--motion-quick);
}
.wp-block-button__link:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-btn);
}
.wp-block-button.is-style-outline .wp-block-button__link {
  border: var(--stroke-hair) solid var(--border-strong);
  background: transparent;
  color: var(--text-body);
}
.wp-block-button.is-style-outline .wp-block-button__link:hover {
  background: var(--border-strong);
  color: var(--text-on-inverse);
}

/* Focus rings ----------------------------------------------------------- */
:where(a, button, input, textarea, select, summary):focus-visible {
  outline: 2px solid var(--focus-ring-color);
  outline-offset: var(--focus-offset);
  border-radius: var(--radius-sm);
}
.wp-block-button__link:focus-visible {
  /* No box-shadow here: --focus-ring is primary, which is also the button's own
     fill, so the halo touched the fill at 1.00:1 and read as the button growing
     rather than as focus. The outline from the :where() base rule does the work,
     separated from the fill by its offset. */
  /* No border-radius here. `inherit` takes it from .wp-block-button, which has
     none, so it resolved to 0 and squared every button on the site the moment
     it took focus - at (0,2,0) it beat the pill radius at (0,1,0). An outline
     follows the element's own radius by itself in every current browser. */
  outline-offset: var(--focus-offset);
}

/* 11. Stats strip ------------------------------------------------------- */
.nlbs-stats {
  border-block: var(--stroke-hair) solid var(--border-subtle);
  background: var(--bg-surface);
  padding-block: var(--section-y-xs);
}
.nlbs-stats__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2rem;
}
@media (max-width: 720px) {
  .nlbs-stats__grid { grid-template-columns: 1fr; gap: 1.5rem; }
}
.nlbs-stat { padding: 0 1rem; }
.nlbs-stat + .nlbs-stat { border-left: var(--stroke-hair) dashed var(--border-subtle); }
@media (max-width: 720px) {
  .nlbs-stat + .nlbs-stat {
    border-left: 0;
    border-top: var(--stroke-hair) dashed var(--border-subtle);
    padding-top: 1.5rem;
  }
}
.nlbs-stat__num {
  font-family: var(--font-display);
  font-size: clamp(2.4rem, 3vw + 1rem, 4rem);
  color: var(--text-heading);
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  font-variation-settings: var(--font-display-vars-soft);
}
.nlbs-stat__num small {
  font-family: var(--font-serif);
  font-style: italic;
  color: var(--text-accent);
  font-size: 0.55em;
  margin-left: 0.2em;
  vertical-align: middle;
}
.nlbs-stat__label {
  font-size: 0.72rem;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 500;
  margin-top: 0.5rem;
}

/* 12. Section split ----------------------------------------------------- */
.nlbs-split {
  display: grid;
  grid-template-columns: 1fr 1.2fr;
  gap: clamp(2rem, 5vw, 5rem);
  align-items: start;
}
.nlbs-split--media-right { grid-template-columns: 1.2fr 1fr; }
@media (max-width: 860px) {
  .nlbs-split,
  .nlbs-split--media-right { grid-template-columns: 1fr; }
}

/* 13. Card grid --------------------------------------------------------- */
.nlbs-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2rem;
}
@media (max-width: 900px) { .nlbs-cards { grid-template-columns: 1fr 1fr; } }
@media (max-width: 620px) { .nlbs-cards { grid-template-columns: 1fr; } }

.nlbs-card {
  background: var(--bg-surface);
  border: var(--stroke-hair) solid var(--border-subtle);
  border-radius: var(--radius-sm);
  padding: 1.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  transition: transform var(--motion-smooth), box-shadow var(--motion-smooth);
  position: relative;
  overflow: hidden;
}
@media (prefers-reduced-motion: no-preference) {
  .nlbs-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-card);
  }
}
.nlbs-card__date {
  font-size: 0.72rem;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-accent);
  font-weight: 500;
}
/* Equal-size news cards: stretch every card to the tallest in its row, clamp
   the excerpt, and pin the read-more link to the bottom. */
.nlbs-cards { align-items: stretch; }
.nlbs-cards > li { display: flex; }
.nlbs-cards > li > .nlbs-card { inline-size: 100%; block-size: 100%; }
.nlbs-card .wp-block-post-excerpt {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.nlbs-card .wp-block-read-more,
.nlbs-card .wp-block-post-excerpt .wp-block-post-excerpt__more-link { margin-top: auto; }

/* 14. Agenda list ------------------------------------------------------- */
.nlbs-agenda-row {
  display: grid;
  grid-template-columns: 100px 1fr auto;
  gap: 2rem;
  align-items: center;
  padding-block: 1.5rem;
  border-bottom: var(--stroke-hair) solid var(--border-subtle);
  transition: padding var(--motion-quick);
}
/* The row carries no layout attribute on purpose: the theme owns these three
   tracks. With layout:grid core printed its own auto-fill rule for the same
   class, and the editor - where that rule loads last - drew six columns. A
   group without layout is flow, whose block-gap margins would misalign the
   grid children, so zero them. */
.wp-block-group.nlbs-agenda-row > * { margin-block: 0; }
@media (prefers-reduced-motion: no-preference) {
  .nlbs-agenda-row:hover { padding-left: 1rem; }
}
.nlbs-agenda-row__date {
  font-family: var(--font-display);
  font-size: 1.5rem;
  color: var(--text-heading);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.nlbs-agenda-row__date small {
  display: block;
  font-family: var(--font-sans);
  font-size: 0.7rem;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-accent);
  margin-top: 0.3rem;
}
@media (max-width: 640px) {
  .nlbs-agenda-row { grid-template-columns: 80px 1fr; }
}

/* 15. CTA band ---------------------------------------------------------- */
.nlbs-cta-band {
  background: var(--bg-inverse);
  color: var(--text-on-inverse);
  padding-block: clamp(3rem, 6vw, 5rem);
  position: relative;
  overflow: hidden;
}
.nlbs-cta-band__grid {
  position: relative;
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 3rem;
  align-items: center;
}
@media (max-width: 780px) {
  .nlbs-cta-band__grid { grid-template-columns: 1fr; }
}
.nlbs-cta-band h2 { color: var(--text-on-inverse); max-width: 16ch; }
.nlbs-cta-band p  {
  color: color-mix(in srgb, var(--text-on-inverse) 82%, transparent);
  max-width: 52ch;
  margin-top: 1rem;
}

/* 16. Page hero --------------------------------------------------------- */
.nlbs-page-hero {
  padding-block: clamp(3.5rem, 7vw, 6rem) clamp(2rem, 4vw, 3.5rem);
}
.nlbs-page-hero h1 {
  font-size: var(--wp--preset--font-size--display);
  margin-top: 1rem;
  max-width: 18ch;
  text-wrap: balance;
}
.nlbs-page-hero__lead {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: clamp(1.2rem, 1vw + 1rem, 1.55rem);
  color: var(--text-muted);
  margin-top: 1.5rem;
  max-width: 46ch;
  line-height: var(--leading-lead);
}
.nlbs-page-hero__split {
  display: grid;
  grid-template-columns: 1.3fr 1fr;
  gap: 3rem;
  align-items: end;
}
@media (max-width: 780px) {
  .nlbs-page-hero__split { grid-template-columns: 1fr; }
}

/* 17. Timeline ---------------------------------------------------------- */
/* One milestone per row. Each step carries its own left border, so stacked
   they read as a single continuous rule with a dot per milestone. It was a
   four-column grid, which broke the moment a fifth milestone was added: four
   on the first row and one orphan on the second. A chronicle is a sequence,
   and a sequence reads down. */
.nlbs-timeline {
  display: grid;
  grid-template-columns: 1fr;
  max-inline-size: 46rem;
  margin-top: 2rem;
}
/* The parent selector is load-bearing. Each step group carries
   layout:constrained, so core marks it `has-global-padding` and ships
   `.has-global-padding :where(...) { padding-left: 0 }` at (0,1,0) - a tie with
   a bare `.nlbs-timeline__step`, decided by source order. On the front end
   core.css comes last and wins; in the editor iframe core's layout styles come
   last and the indent collapsed, stamping the dot straight over the year.
   (0,2,0) settles it in both. */
.nlbs-timeline .nlbs-timeline__step {
  padding: 0 0 2.75rem 2.25rem;
  border-left: var(--stroke-firm) solid var(--border-subtle);
  position: relative;
  /* Grid items default to min-width: auto, so a step could not shrink below
     the min-content width of its title. At a 125% browser text size that put
     the steps 60px past a 320px viewport - the only elements on the page doing
     so - which is SC 1.4.10 Reflow. */
  min-width: 0;
}
.nlbs-timeline__step :is(h2, h3, h4, p) { overflow-wrap: break-word; }
.nlbs-timeline .nlbs-timeline__step:last-child { padding-bottom: 0; }
.nlbs-timeline__step::before {
  content: "";
  position: absolute;
  left: -9px;
  top: 0.3em;
  inline-size: 16px;
  block-size: 16px;
  border-radius: 50%;
  background: var(--bg-page);
  border: var(--stroke-firm) solid var(--border-accent);
}
/* The step selector below is not decoration: `.nlbs-timeline__step p` is
   (0,1,1) and beats a bare `.nlbs-timeline__year` at (0,1,0), so the year has
   never rendered at its own size or colour - it came out identical to the body
   paragraph, and only the display face gave it away. Measured 2026-09-02:
   15.2px in --text-muted where the rule asked for 2.2rem in --text-heading.
   --brand-primary-on-surface rather than --text-accent, because the year sits
   on `surface` under the paper grain, where plain primary is 4.46:1. */
.nlbs-timeline__step p.nlbs-timeline__year {
  font-family: var(--font-display);
  font-size: 1.5rem;
  color: var(--brand-primary-on-surface);
  line-height: 1.1;
  margin-top: 0;
  margin-bottom: 0.25rem;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}
/* Was h4, while every timeline in the theme and in content uses h3, so the
   heading was the one part of a step that never lined up. */
.nlbs-timeline__step :is(h2, h3, h4) { margin-top: 0; }
.nlbs-timeline__step p {
  margin-top: 0.5rem;
  font-size: 0.95rem;
  color: var(--text-muted);
}

/* 18. Trait grid -------------------------------------------------------- */
.nlbs-traits {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2rem;
  margin-top: 2rem;
}
@media (max-width: 860px) { .nlbs-traits { grid-template-columns: 1fr 1fr; } }
@media (max-width: 520px) { .nlbs-traits { grid-template-columns: 1fr; } }
.nlbs-trait {
  padding: 1.5rem;
  border: var(--stroke-hair) solid var(--border-subtle);
  border-radius: var(--radius-sm);
  background: var(--bg-page);
}
.nlbs-trait__num {
  font-family: var(--font-display);
  font-size: 2.5rem;
  color: var(--text-accent);
  line-height: 1;
  font-weight: 400;
  font-style: italic;
  font-variation-settings: var(--font-display-vars-soft);
}
/* Trait description — muted (replaces inline opacity on the paragraph). */
.nlbs-trait p:not(.nlbs-trait__num) { color: var(--text-muted); }

/* 19. Breed / attributes card ------------------------------------------ */
.nlbs-attributes-card {
  background: var(--bg-surface);
  border: var(--stroke-hair) solid var(--border-subtle);
  border-radius: var(--radius-sm);
  padding: clamp(2rem, 3vw, 3rem);
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: 2.5rem;
  align-items: center;
}
@media (max-width: 780px) {
  .nlbs-attributes-card { grid-template-columns: 1fr; }
}
.nlbs-attributes-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.nlbs-attributes-list li {
  display: grid;
  grid-template-columns: 140px 1fr;
  gap: 1rem;
  padding-block: 0.75rem;
  border-bottom: var(--stroke-hair) dashed var(--border-subtle);
  font-size: 0.95rem;
}
.nlbs-attributes-list li > *:first-child {
  font-family: var(--font-display);
  font-weight: 430;
  color: var(--text-accent);
}
.nlbs-attributes-list li > *:last-child {
  font-family: var(--font-serif);
  font-style: italic;
  color: var(--text-muted);
}

/* 20. Photo strip (3-up asymmetric) ------------------------------------ */
.nlbs-photo-strip {
  display: grid;
  grid-template-columns: 2fr 1fr 1.4fr;
  gap: 1rem;
  block-size: 360px;
  margin-top: 3rem;
}
@media (max-width: 680px) {
  .nlbs-photo-strip { grid-template-columns: 1fr 1fr; block-size: auto; }
  .nlbs-photo-strip > * { aspect-ratio: 4/3; }
}
.nlbs-photo-strip > * {
  background: var(--bg-surface);
  border-radius: var(--radius-xs);
  overflow: hidden;
  position: relative;
}

/* 21. FAQ (core/details stack) ----------------------------------------- */
.nlbs-faq .wp-block-details {
  border-bottom: var(--stroke-hair) solid var(--border-subtle);
  padding-block: 1.25rem;
}
.nlbs-faq .wp-block-details:last-child { border-bottom: 0; }
.nlbs-faq .wp-block-details summary {
  font-family: var(--font-display);
  font-size: 1.3rem;
  color: var(--text-heading);
  list-style: none;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
}
.nlbs-faq .wp-block-details summary::marker { content: ""; }
.nlbs-faq .wp-block-details summary::after {
  content: "+";
  color: var(--text-accent);
  font-size: 1.5rem;
  line-height: 1;
  transition: transform var(--motion-quick);
}
.nlbs-faq .wp-block-details[open] summary::after { content: "\2013"; }

.nlbs-faq-layout {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: 3rem;
  align-items: start;
}
@media (max-width: 760px) {
  .nlbs-faq-layout { grid-template-columns: 1fr; }
}

/* 21b. Post-terms chips (Query Loop taxonomy badges) -------------------- */
/* Universal chip rendering for any pattern that drops a wp:post-terms or
   manual .nlbs-chip-tag element. One color, one shape — child themes
   can override the bg via the role token --bg-chip if they want.       */
.nlbs-chip-tag,
.wp-block-post-terms a {
  display: inline-block;
  padding: 0.3rem 0.85rem;
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--brand-primary) 14%, var(--bg-page));
  color: var(--brand-primary);
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  text-decoration: none;
  line-height: 1.2;
  transition: background var(--motion-quick), color var(--motion-quick);
}
.wp-block-post-terms { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.wp-block-post-terms a:hover,
.wp-block-post-terms a:focus-visible,
.nlbs-chip-tag:hover {
  background: var(--brand-primary);
  color: var(--text-on-accent);
}

/* 21c. Ghost arrow link — replaces nested-underline patterns ----------- */
.nlbs-arrow-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--brand-primary);
  font-weight: 700;
  text-decoration: none;
  border-bottom: 2px solid color-mix(in srgb, var(--brand-primary) 35%, transparent);
  padding-bottom: 0.15rem;
  transition: color var(--motion-quick), border-color var(--motion-quick), gap var(--motion-quick);
}
.nlbs-arrow-link::after {
  content: "→";
  display: inline-block;
  transition: transform var(--motion-quick);
}
.nlbs-arrow-link:hover,
.nlbs-arrow-link:focus-visible {
  color: var(--brand-secondary);
  border-bottom-color: var(--brand-secondary);
  gap: 0.65rem;
}
.nlbs-arrow-link:hover::after,
.nlbs-arrow-link:focus-visible::after {
  transform: translateX(2px);
}

/* 23. Category duo ------------------------------------------------------ */
.nlbs-cat-duo {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
  margin-bottom: 3rem;
  align-items: stretch;
}
@media (max-width: 720px) { .nlbs-cat-duo { grid-template-columns: 1fr; } }
.nlbs-cat-card {
  padding: 2rem;
  border: var(--stroke-hair) solid var(--border-subtle);
  border-radius: var(--radius-sm);
  background: var(--bg-surface);
  display: grid;
  grid-template-columns: 1fr 80px;
  gap: 1rem;
  align-items: center;
  transition: transform var(--motion-quick), border-color var(--motion-quick);
}
@media (prefers-reduced-motion: no-preference) {
  .nlbs-cat-card:hover { transform: translateY(-2px); }
}
.nlbs-cat-card--primary {
  background: linear-gradient(135deg, var(--brand-primary-tint) 0%, var(--bg-surface) 100%);
  border-color: var(--brand-primary);
}
.nlbs-cat-card--secondary {
  background: linear-gradient(135deg, var(--bg-surface) 0%, var(--brand-secondary-tint) 100%);
  border-color: var(--brand-secondary-light);
}
.nlbs-cat-count {
  font-family: var(--font-display);
  font-size: 2.5rem;
  color: var(--brand-primary-on-surface);
  text-align: center;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  min-width: 0;
}
/* The unit goes under the number rather than beside it: the column is 80px and
   "documenten" next to an 8 simply left the card. */
.nlbs-cat-count small {
  display: block;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 0.28em;
  line-height: 1.3;
  margin-block-start: 0.35em;
}

/* 24. Benefits list (icon checklist) ----------------------------------- */
.nlbs-benefits {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
/* Not a grid. A list item is rich text: <strong>lead.</strong> followed by a
   bare text node is two children, and as grid items the text landed in the 28px
   icon column and wrapped one word per line. Positioning the check instead
   means the item can hold any number of inline children. */
.nlbs-benefits li {
  position: relative;
  padding-inline-start: 2.375rem;
  font-size: 0.95rem;
  color: var(--text-muted);
}
.nlbs-benefits li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: 2px;
  inline-size: 24px;
  block-size: 24px;
  background-color: var(--text-accent);
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2'><path d='M20 6L9 17l-5-5'/></svg>") no-repeat center / contain;
          mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2'><path d='M20 6L9 17l-5-5'/></svg>") no-repeat center / contain;
}

/* 25. Pill note --------------------------------------------------------- */
.nlbs-pill-note {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  background: var(--bg-surface-soft);
  color: var(--text-muted);
  padding: 0.35rem 0.85rem;
  border-radius: var(--radius-pill);
  font-size: 0.78rem;
  border: var(--stroke-hair) solid var(--border-subtle);
}
.nlbs-pill-note::before {
  content: "\2022";
  color: var(--text-accent);
  font-size: 0.85rem;
  line-height: 1;
}

/* 26. Inline link (underlined small accent) ---------------------------- */
a.nlbs-inline-link {
  border-bottom: var(--stroke-hair) solid var(--text-accent);
  transition: color var(--motion-quick);
}
a.nlbs-inline-link:hover { color: var(--text-accent); }

/* 27. Form card wrapper ------------------------------------------------ */
.nlbs-form-card {
  background: var(--bg-surface);
  border: var(--stroke-hair) solid var(--border-subtle);
  border-radius: var(--radius-sm);
  padding: clamp(1.75rem, 3vw, 2.5rem);
}
/* Form-card intro line — muted + capped (replaces inline opacity/max-width).
   Excludes the eyebrow, which keeps its own accent color. */
.nlbs-form-card p:not(.nlbs-eyebrow) { color: var(--text-muted); max-width: 48ch; }

/* 28. Skip link --------------------------------------------------------- */
.skip-link {
  position: absolute;
  top: 0;
  left: 1rem;
  transform: translateY(-150%);
  z-index: var(--z-skip-link);
  background: var(--brand-primary);
  color: var(--text-on-accent);
  padding: 0.75rem 1.5rem;
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
  font-size: 0.85rem;
  font-weight: 500;
  transition: transform var(--motion-quick);
}
.skip-link:focus { transform: translateY(0); }


/* Safari and VoiceOver drop list semantics when list-style-type is `none`, so a
   marked-up list stops being announced as one. An empty string removes the
   marker without removing the role. Done here rather than with role="list" in
   the markup, because a hand-written attribute the block does not declare
   breaks block validation - see standards/20-fse.md. */
.wp-block-list.is-style-nlbs-none,
ul.is-style-nlbs-none {
  list-style-type: "";
  padding-inline-start: 0;
}

/* Pattern media framing.
   These declarations used to sit inline on the <img> inside four patterns.
   Only border-radius is a real core/image attribute, so save() never generated
   the rest and Gutenberg rejected the saved markup: the front end looked
   perfect and an editor opening the page got "attempt recovery". Same reason
   as .is-style-nlbs-none above - see standards/20-fse.md. */
.nlbs-media-5x4 img,
.nlbs-media-4x5 img,
.nlbs-media-hero img,
.nlbs-media-fill img {
  display: block;
  inline-size: 100%;
  object-fit: cover;
}
.nlbs-media-5x4 img  { aspect-ratio: 5 / 4; }
.nlbs-media-4x5 img  { aspect-ratio: 4 / 5; filter: saturate(0.92); }
.nlbs-media-hero img { aspect-ratio: 5 / 5.4; filter: contrast(1.02) saturate(0.95); }
.nlbs-media-fill img { block-size: 100%; filter: saturate(0.92); }

/* Category cards: the whole card is clickable, but only the heading link is in
   the accessibility tree. The card used to be a core/group with tagName "a" and
   an href, neither of which core/group declares - two invalid blocks, and a
   link whose accessible name was the entire card read out in one breath. */
.nlbs-cat-card { position: relative; }
.nlbs-cat-card h3 a {
  color: inherit;
  text-decoration: none;
}
.nlbs-cat-card h3 a::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

/* Reduced motion.
   Four blocks in this file guard their own animation and the rest did not,
   which is an oversight rather than a decision - nothing here is motion the
   design depends on. One guard for the whole stylesheet, plus forms.css and
   anything core brings, is more reliable than remembering it per rule. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Rust on cream, measured.
   `primary` is 4.75:1 on `surface` and the paper grain takes that to 4.45:1,
   just under AA for the small text that actually sits on the cards - the
   eyebrow, the card date, the read-more link. The darkened derivation clears it
   at 5.01:1 grained without leaving the brand. On the page background the plain
   token is 5.10:1 and stays as it is. */
.is-style-nlbs-surface .nlbs-eyebrow,
.nlbs-card .nlbs-eyebrow,
.nlbs-cat-card .nlbs-eyebrow,
.nlbs-form-card .nlbs-eyebrow,
.nlbs-card__date,
.nlbs-card .wp-block-read-more,
.nlbs-card time {
  color: var(--brand-primary-on-surface);
}

/* Reflow.
   Grid items default to min-width:auto, so a 1fr track cannot shrink below the
   longest word in it. At a 320px viewport the agenda row pushed the page 8px
   wide, and at text-only 200% the news cards pushed it 293px. WCAG 1.4.10 and
   1.4.4 both. */
.nlbs-cards > *,
.nlbs-agenda-row > * {
  min-width: 0;
}
/* The 8px of sideways scroll at 320px was one word - "afstammingsregistratie."
   at 196px in a 168px track - not the grid tracks, which shrink correctly.
   Dutch stacks nouns, so this will happen again; hyphenation breaks at
   syllables with a visible hyphen instead of mid-word, which is the readable
   answer in this language rather than merely the compliant one. */
.nlbs-cards :is(h2, h3, p),
.nlbs-agenda-row :is(h2, h3, p),
.nlbs-cards .wp-block-post-excerpt__excerpt,
.nlbs-agenda-row .wp-block-post-excerpt__excerpt {
  overflow-wrap: break-word;
  hyphens: auto;
}

/* Mobile overlay.
   Core zeroes the padding the nav bar carries, so the links fell back to line
   height: 21px tall, 13px uppercase, in the only navigation a phone has. The
   spacing exception means this was not a hard 2.5.8 failure; it was still the
   wrong size for an audience of volunteers and older members. */
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content {
  display: flex;
  align-items: center;
  min-block-size: 44px;
  font-size: 1rem;
  text-transform: none;
  letter-spacing: normal;
}


/* Grid children get no flow margin.
   These are grid containers, but core's layout CSS still emits
   `> * + * { margin-block-start }` for the group, which lands on the second
   child of each row and leaves tile one sitting about 14px higher than its
   neighbours. Visible as "the cards are wonky" on the traits grid, the
   timeline and the category duo. */
.nlbs-traits > *,
.nlbs-timeline > *,
.nlbs-cat-duo > *,
.nlbs-stats__grid > *,
.nlbs-cards > * {
  margin-block-start: 0;
}

/* Inverse sections, the rest of the look.
   Deliberately last, and deliberately with the class doubled. A background
   colour is not a look: the style used to set only background and color, so
   headings kept --text-heading - the same green as the ground, and the title
   disappeared - the outline button kept its dark text, and light cards nested
   inside inherited the pale body colour. The button and card rules further up
   are specific enough that source order alone did not settle it, and this has
   to hold whatever an editor stacks on the section. One click from the Styles
   panel used to make a section unreadable. */
.is-style-nlbs-inverse.is-style-nlbs-inverse :is(h1, h2, h3, h4, h5, h6) {
  color: var(--text-on-inverse);
}
.is-style-nlbs-inverse.is-style-nlbs-inverse .nlbs-eyebrow {
  color: var(--text-highlight);
}
.is-style-nlbs-inverse.is-style-nlbs-inverse .wp-block-button.is-style-outline .wp-block-button__link {
  border-color: color-mix(in srgb, var(--text-on-inverse) 55%, transparent);
  /* !important, and I want to be straight about why: the border from this same
     rule applies and the colour does not, which should not be possible on
     specificity alone. I could not identify the declaration that wins, and I
     am not willing to ship a one-click Styles-panel action that leaves dark
     text on a dark ground at 1.51:1. Worth returning to. */
  color: var(--text-on-inverse) !important;
}
.is-style-nlbs-inverse.is-style-nlbs-inverse .wp-block-button.is-style-outline .wp-block-button__link:hover {
  background: var(--text-on-inverse);
  color: var(--text-heading);
}
.is-style-nlbs-inverse.is-style-nlbs-inverse :focus-visible {
  outline-color: var(--focus-ring-color-inverse);
}

/* Nested light surfaces keep their own colours. */
.is-style-nlbs-inverse.is-style-nlbs-inverse :is(.nlbs-card, .nlbs-cat-card, .nlbs-form-card, .nlbs-attributes-card) {
  color: var(--text-body);
}
.is-style-nlbs-inverse.is-style-nlbs-inverse :is(.nlbs-card, .nlbs-cat-card, .nlbs-form-card, .nlbs-attributes-card)
  :is(h1, h2, h3, h4, h5, h6) {
  color: var(--text-heading);
}
.is-style-nlbs-inverse.is-style-nlbs-inverse :is(.nlbs-card, .nlbs-cat-card, .nlbs-form-card, .nlbs-attributes-card)
  .nlbs-eyebrow {
  color: var(--brand-primary-on-surface);
}
