/* Generic content wrapper + simple post listing. */

/* Top inset only: the content clears the hero above. No bottom padding here —
   the footer's wave laps up over #main's reserved bottom padding instead, so the
   last content row stays clear (see components/wave.css, #main:has(+ .wave--overlap)). */
.entry-content {
  padding-block-start: var(--section-spacing);
}

/* No opening hero: add the header's footprint on top of the section spacing so
   the first row clears the fixed header instead of sitting cramped under it.

   A hero bleeds up behind the header and clears it itself — page.php's Hero
   builder row zeroes this padding (see components/hero.css), and the templates
   that auto-render a hero (single post, archive, search, 404) put it BEFORE
   .entry-content, pushing the content past :first-child. So this matches only a
   .entry-content that opens #main AND doesn't lead with a hero row: a page (or
   builder-enabled CPT) whose body starts straight in on content. */
#main > .entry-content:first-child:not(:has(> .wpb-content-wrapper > .vc_row:first-child .hero)) {
  padding-block-start: calc(var(--section-spacing) + var(--header-spacer));
}

/* Plain (non page-builder) content gets a readable container; Page Builder
   rows manage their own width, so don't constrain them. */
.entry-content:not(:has(.vc_row)) {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--distance-to-edge);
}

/* ── Page Builder layout: a full-bleed CSS grid ──────────────────────────────
   WPBakery normally stretches "full width" rows with JavaScript that measures
   the row's pixel offset from the viewport on load/resize and writes inline
   width/left/margins. Those pixels go stale whenever the layout reflows WITHOUT
   a resize event — notably the accessibility font-size control, which changes
   the root rem and shifted the (full-width) hero sideways. That measurement JS
   is switched off on the front end via WPBakery's own opt-out flag (see
   inc/Hooks/PageBuilder.php::disable_full_width_row_js).

   Instead we lay the builder canvas out with a CSS grid whose centre column is
   the content width and whose outer columns are the gutters. Contained rows sit
   in the centre column; stretched rows span edge to edge. Placement keys off the
   server-rendered data-vc-full-width marker (not the JS), is unit-agnostic, and
   reflows correctly at any font size — no JS measurement. (Pattern borrowed from
   the northc-24 theme.) */

/* The builder canvas must span the full viewport so stretched rows can reach the
   edges. .entry-content carries the .container cap for plain bodies (above); a
   builder body cancels it and lets the grid own the widths instead. */
.entry-content:has(.vc_row) {
  max-width: none;
  padding-inline: 0;
}

.wpb-content-wrapper {
  display: grid !important;
  /* Centre track = the exact width .entry-content.container produced before this
     grid (border-box: min(container,100%) minus a gutter each side), so contained
     rows don't shift. The 1fr edge tracks become the gutters. */
  grid-template-columns:
    [full-start] 1fr
    [content-start] calc(min(var(--container-max), 100%) - var(--distance-to-edge) * 2) [content-end]
    1fr [full-end];
}

/* Contained rows sit in the centred content column. */
.wpb-content-wrapper > .vc_row {
  grid-column: content;
}

/* Stretched rows span the full track. The inline-px resets below are a safety
   net: the front-end measurement JS is disabled (see the block above), but the
   WPBakery backend editor preview still runs it, so keep neutralising any inline
   width/left/right/margins it writes there so the grid alone positions the row. */
.wpb-content-wrapper > .vc_row[data-vc-full-width="true"] {
  grid-column: full;
  width: auto !important;
  max-width: none !important;
  margin-inline: 0 !important;
  left: auto !important;
  right: auto !important;
}

/* "Stretch row" (full-bleed background, content kept at container width) — inset
   the content to the content column. No current row uses this mode (every
   stretched row is "stretch row and content"), but keep it correct for editors. */
.wpb-content-wrapper > .vc_row[data-vc-full-width="true"]:not([data-vc-stretch-content="true"]) {
  padding-inline: calc((100% - min(var(--container-max), 100%)) / 2 + var(--distance-to-edge));
}

/* WPBakery emits an empty .vc_row-full-width.vc_clearfix spacer between
   full-width rows for its float-based layout; the grid doesn't need it. It stays
   in the DOM (the inter-row spacing + footer-wave selectors below still match it
   as a sibling), it just paints nothing. */
.wpb-content-wrapper > .vc_row-full-width.vc_clearfix {
  display: none;
}

/* Vertical rhythm between stacked Page Builder rows. The .vc_clearfix variant
   covers full-width rows, which emit an empty .vc_clearfix div between rows. */
.vc_row + .vc_row,
.vc_row + .vc_clearfix + .vc_row {
  margin-block-start: var(--row-spacer);
}

/* Below WPBakery's column breakpoint the columns STACK, so the last column
   drops to the bottom of the row. WPBakery gives every .wpb_content_element a
   default bottom margin; on the last element of that last column it would stack
   on top of the --row-spacer above, doubling the gap under the row. Drop it so
   the row ends flush — the earlier columns keep their trailing margin, which now
   correctly spaces the stacked columns from one another. Matches the theme's
   mobile breakpoint (base.css / tokens.css). */
@media (max-width: 47.999rem) {
  .wpb_column:last-child > .vc_column-inner > .wpb_wrapper > .wpb_content_element:last-child {
    margin-block-end: 0;
  }
}

/* Full-width filled rows get the spacer as inner padding so the colour fills the
   row with breathing room above and below the content. Scoped to WPBakery's
   stretched + filled state (vc_row-has-fill is added by RowBackground.php;
   data-vc-full-width is rendered server-side by WPBakery on a stretched row).
   --surface-reserve-end is
   the per-edge wave reserve (0 unless a wave laps over this row's bottom — see the
   wave-clearance rules below); adding it here keeps the row's COLOUR extending
   under the crest rather than opening a transparent gap beneath the band. */
.vc_row-has-fill[data-vc-full-width=true] {
  padding-block: var(--row-padding-block-start)
                 calc(var(--row-padding-block-end) + var(--surface-reserve-end, 0px));
}

/* A hero row manages its own height and bleeds up behind the header, so it
   doesn't want the filled-row padding. */
.vc_row-has-fill[data-vc-full-width=true]:has(.hero) {
  padding-block: 0;
}

/* A Call to action is a self-contained band — it brings its own vertical padding
   and wavy edges — so the row that holds it must not add the standard row
   padding on top. (Placed after the filled-row rule above so it wins on equal
   specificity.) Its top wave also laps UP over the previous row, so the row must
   not clip it — WPBakery sets overflow:hidden on stretched rows
   (.vc_row[data-vc-full-width]); force it visible (the attribute variant
   out-specifies it, mirroring components/wave-band.css). */
.vc_row:has(.cta),
.vc_row[data-vc-full-width]:has(.cta) {
  padding-block: 0;
  overflow: visible;
}

/* When the CTA is the row's first child, its top wave laps up over the PREVIOUS
   row — drop the inter-row spacer so the two butt together and the wave paints
   across the seam (rather than over a gap). */
.vc_row:has(.cta:first-child) {
  margin-block-start: 0;
}

/* …and move that lost spacer into the PREVIOUS row as bottom padding, so its
   content still clears the wave now lapping up over it (mirrors
   .hero:has(+ .wave-band)). Forward-looking :has — nested :has() is invalid, so
   the relative arg "+ .vc_row .cta:first-child" matches a row immediately
   followed by a CTA-first row. The .vc_clearfix variant covers full-width rows.

   Scoped to PLAIN previous rows only: a filled row already carries --row-spacer
   of bottom padding (enough to clear the crest), and a CTA previous row must keep
   its row at padding:0 and let its own .cta__body provide the clearance instead —
   adding padding to that wrapper would open a transparent gap below the CTA's
   colour where the next CTA's wave laps up. */
.vc_row:not(.vc_row-has-fill):not(:has(.cta)):has(+ .vc_row .cta:first-child),
.vc_row:not(.vc_row-has-fill):not(:has(.cta)):has(+ .vc_clearfix + .vc_row .cta:first-child) {
  padding-block-end: var(--row-spacer);
}

/* Two adjacent full-width filled rows butt together — their padding already
   provides the spacing, so drop the top margin between them (also across a
   clearfix). */
.vc_row-has-fill[data-vc-full-width=true] + .vc_row-has-fill[data-vc-full-width=true],
.vc_row-has-fill[data-vc-full-width=true] + .vc_clearfix + .vc_row-has-fill[data-vc-full-width=true] {
  margin-block-start: 0;
}

.vc_column-inner {
  padding-block-start: 0 !important;
}

/* ── Footer-wave clearance ───────────────────────────────────────────────────
   The footer wave (components/wave.css, .wave--overlap) laps UP over #main by
   --footer-wave-height. Whatever it laps over must reserve that height at its
   bottom so the dark-green crest paints over empty/extended surface, never over
   content. HOW the reserve is applied depends on whether the last row is a
   FULL-BLEED band or a CONTAINED row — the two read very differently:

   WPBakery renders PB rows in .entry-content > .wpb-content-wrapper (the chain is
   pinned to TOP-LEVEL rows so a nested inner row can't match). The footer always
   renders the wave, but :has(+ .wave--overlap) keeps the intent explicit.

   1. FULL-BLEED band (data-vc-full-width — a stretched filled row, or the
      full-bleed CTA). Its colour should extend UNDER the crest so the band reads
      as flowing into the footer. The reserve flows through --surface-reserve-end,
      which the painted surfaces (filled rows above; .cta__body in
      components/call-to-action.css) add to their OWN bottom padding — set on the
      row, it inherits into a nested .cta__body so the padding lands on the CTA
      component, not its padding:0 wrapper. Full-width rows are always trailed by a
      .vc_clearfix, so they match via that (or :last-child as a fallback). */
#main:has(+ .wave--overlap) > .entry-content > .wpb-content-wrapper > .vc_row[data-vc-full-width="true"]:last-child,
#main:has(+ .wave--overlap) > .entry-content > .wpb-content-wrapper > .vc_row[data-vc-full-width="true"]:has(+ .vc_clearfix:last-child) {
  --surface-reserve-end: var(--footer-wave-height);
}

/* 1b. TEMPLATERA. A Templatera template renders its rows inside a
      .templatera_shortcode wrapper (nested in a column of the last top-level row),
      so the real last band is one or two levels deeper than the chain above can
      reach — setting the reserve on the wrapper row would land the padding in the
      empty space BELOW the band. Reach the band inside instead: the last full-bleed
      filled row in the template (the one trailed by Templatera's closing
      .vc_clearfix) and extend ITS surface. The wrapper row is excluded from the
      contained rule below so it doesn't also take a tail. */
#main:has(+ .wave--overlap) > .entry-content > .wpb-content-wrapper > .vc_row:last-child .templatera_shortcode > .vc_row[data-vc-full-width="true"]:has(+ .vc_clearfix:last-child) {
  --surface-reserve-end: var(--footer-wave-height);
}

/* 2. CONTAINED last row (fluid — incl. a contained CTA, which is NOT full-bleed).
      Bleeding its container-width surface into the full-width wave looks broken,
      so instead reserve a TRANSPARENT tail on the row itself: the content lifts
      clear of the crest and the band keeps its own size. Higher specificity than
      .vc_row:has(.cta){padding-block:0}, so it restores the bottom edge on a
      contained CTA row (a contained row is never trailed by a clearfix). Skip a row
      that wraps a Templatera template — rule 1b handles the band nested inside it. */
#main:has(+ .wave--overlap) > .entry-content > .wpb-content-wrapper > .vc_row:not([data-vc-full-width="true"]):last-child:not(:has(.templatera_shortcode)) {
  padding-block-end: var(--footer-wave-height);
}

/* Non-builder content (plain post/page body, no PB rows / no wrapper): reserve on
   the content element itself, since there is no row surface to carry it. A normal
   section-spacing gap below the content PLUS the wave height, so the last element
   keeps its breathing room and the crest still paints over cleared surface. */
#main:has(+ .wave--overlap) > .entry-content:not(:has(.vc_row)) {
  padding-block-end: calc(var(--section-spacing) + var(--footer-wave-height));
}

/* Row background surfaces, chosen via the row's "Achtergrond" dropdown
   (inc/Hooks/RowBackground.php maps the choice to one of these classes). The
   colour sits on the .vc_row, so it fills the full viewport when the row uses
   WPBakery's "Stretch row" option, and the container width otherwise. */
.bg-vibrant {
  color: var(--color-text);
  background-color: var(--color-green-light);
}

.bg-green-pale {
  background-color: var(--color-green-pale);
}

.bg-beige {
  background-color: var(--color-cream);
}

.bg-light {
  background-color: var(--color-light);
}

/* Brand-orange headings only read on white; on every coloured light surface
   they drop to pure black. (The dark-green surface flips them to white instead
   — see below.) */
.bg-vibrant,
.bg-green-pale,
.bg-beige,
.bg-light {
  --color-heading: var(--color-black);
}

/* Links on the GREEN light surfaces: the interactive dark green (#245c2d) sits
   too close to the green background to meet WCAG AA — only ~4.46:1 on bg-vibrant
   (#7fd75d), so green-on-green fails. Inherit the (black) text colour instead
   (~11.8:1); the underline still marks them as links, so no colour cue is lost.
   bg-beige/bg-light are pale enough that the green link clears AA (~7:1), so they
   keep it. See assets/css/WCAG-NOTES.md. */
.bg-vibrant a,
.bg-green-pale a {
  color: inherit;
}

/* Dark surface: re-enter inheritance like the footer so text, headings, links
   and primary buttons stay AA-legible on the dark green. */
.bg-green-dark {
  --color-text: var(--color-white);
  --color-heading: var(--color-white);
  --color-link: var(--color-white);
  /* The default focus colour (--color-green-dark) is this surface's own
     background — an invisible 1:1 ring. Flip it to white so keyboard focus
     stays visible on the footer and any dark-green row (WCAG 2.4.7). */
  --color-focus: var(--color-white);
  color: var(--color-text);
  background-color: var(--color-green-dark);
}

.post-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-m);
}

.post-list-item a {
  text-decoration: none;
}
