/*
Theme Name: Magnolis
Author: SU—F Studio
Description: Custom theme for Magnolis
Version: 0.0.1
Text Domain: magnolis-text-domain
Tags: custom, su-f, souncalledfor, design studio, design, studio
*/


:root {
  --dur-sm: 0.25s;
  --dur-md: 0.5s;

  --spacing-xs: 0.2rem;
  --spacing-sm: 0.7rem;
  --spacing-md: 1rem;
  --spacing-md-plus: 1.2rem;
  --spacing-lg: 2.25rem;
  --spacing-lg-plus: 2.7rem;
  --spacing-xl: 4.5rem;
  --spacing-2xl: 6.5rem;
  --spacing-3xl: 9rem;
  --spacing-4xl: 12rem;

  --max-w-xxs: 25rem;
  --max-w-xs: 28rem;
  --max-w-xs-plus: 32rem;
  --max-w-sm: 40rem;
  --max-w-md: 48rem;
  --max-w-lg: 64rem;
  --max-w-xl: 80rem;
  --max-w-2xl: 96rem;
  --max-w-screen: 100rem;

  --radius-md: 0.5rem;

  --text-xxs: clamp(0.4375rem, 0.42rem + 0.09vw, 0.5rem);
  --text-xs: clamp(0.625rem, 0.6rem + 0.13vw, 0.6875rem);
  --text-sm: clamp(0.75rem, 0.72rem + 0.15vw, 0.8125rem);
  --text-sm-plus: clamp(0.8125rem, 0.78rem + 0.17vw, 0.9375rem);
  /* sans body */
  --text-base: clamp(0.875rem, 0.84rem + 0.19vw, 1rem);
  --text-base-plus: clamp(1.0625rem, 1rem + 0.33vw, 1.1875rem);
  --text-md: clamp(1.125rem, 1.06rem + 0.36vw, 1.25rem);
  --text-lg: clamp(1.25rem, 1.17rem + 0.4vw, 1.375rem);
  --text-lg-plus: clamp(1.375rem, 1.2rem + 0.5vw, 1.5rem);
  /* serif body */
  --text-lg-xl: clamp(1.5rem, 1.2rem + 1.5vw, 1.875rem);
  --text-xl-sm: clamp(1.625rem, 1.4rem + 1.0vw, 2.125rem);
  --text-xl: clamp(1.875rem, 1.4rem + 2.35vw, 2.375rem);
  --text-2xl: clamp(2.5rem, 1.6rem + 4.22vw, 3rem);

  --leading-none: 1;
  --leading-tight: 1.22;
  --leading-normal: 1.33;
  --leading-relaxed: 1.66;
  --leading-loose: 2;

  --p-header: var(--spacing-lg);
  --p-button: calc(var(--spacing-sm) / 2.5) var(--spacing-sm);
  --size-play: var(--spacing-xl);

  --opacity-muted: 0.5;

  --color-light: #FFEDE4;
  --color-xlight: #EFE8E2;
  --color-dark: #5F3E24;

  --font-serif: 'Kazimir', Georgia, serif;
  --font-sans: 'Area', system-ui, sans-serif;
}

.section {
  position: relative;
  height: 100%;
}

.section:has(.scheme--light),
.section.scheme--light {
  --color: var(--color-dark);
  color: var(--color);
}

.section:has(.scheme--dark),
.section.scheme--dark {
  --color: var(--color-light);
  color: var(--color);
}



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

body {
  margin: 0;
  padding: 0;
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--color-dark);
  line-height: var(--leading-normal);
  overflow-x: hidden;
  scrollbar-width: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

html::-webkit-scrollbar {
  display: none;
}

main {
  position: relative;
  z-index: 1;
}

.hide {
	display: none !important;
}

/* Page transition overlay — fades the page out on exit and in on load so
   per-page background images never "pop". Cream so the fade reads as premium. */
.page-transition {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background-color: var(--color-xlight);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-md) ease;
}

/* With JS the overlay covers the page until the entry reveal lifts it.
   Without JS it stays invisible so the page is never left blank. */
.js .page-transition {
  opacity: 1;
  pointer-events: auto;
}

.js .page-transition.is-hidden {
  opacity: 0;
  pointer-events: none;
}

.layer--1 {
  position: relative;
  z-index: 2;
}

.layer--2 {
  position: sticky;
  z-index: 1;
}

p {
  font-size: var(--text-sm);
}

p:has(a) {
  margin-top: var(--spacing-lg);
}

a {
  color: inherit;
}

.font-serif {
  font-family: var(--font-serif);
}

.font-sans {
  font-family: var(--font-sans);
}

.text-xs {
  font-size: var(--text-xs);
}

.text-sm {
  font-size: var(--text-sm);
}

.text-base {
  font-size: var(--text-base);
}

.text-base-plus {
  font-size: var(--text-base-plus);
}

.text-lg {
  font-size: var(--text-lg);
}

.text-lg-xl {
  font-size: var(--text-lg-xl);
}

.text-xl {
  font-size: var(--text-xl);
}

.text-2xl {
  font-size: var(--text-2xl);
}

.bold {
  font-weight: bold;
}

.italic {
  font-style: italic;
}

h1,
h2 {
  font-family: var(--font-serif);
  line-height: var(--leading-tight);
  font-weight: 400;
}

h3,
h4 {
  font-family: var(--font-serif);
  line-height: var(--leading-normal);
  font-weight: 400;
}

h5,
h6 {
  font-family: var(--font-sans);
  line-height: var(--leading-normal);
  font-weight: 400;
}

h1:first-of-type,
h2:first-of-type,
h3:first-of-type,
h4:first-of-type {
  margin-top: 0;
}

h1 {
  font-size: var(--text-2xl);
  margin: 0;
}

h2 {
  font-size: var(--text-xl);
}

h3 {
  font-size: var(--text-lg-xl);
}

h4 {
  font-size: var(--text-base-plus);
}

h5 {
  font-size: var(--text-base);
}

h6 {
  font-size: var(--text-sm);
}

/* ── Font overrides ── */

.section-container--s-scroll h2.wp-block-heading {
  font-size: var(--text-lg-plus);
}

.section-container--h-o-scroll>.wp-block-columns>.wp-block-column>.wp-block-columns .wp-block-heading {
  font-size: var(--text-lg-plus);
}

.section-container--h-o-scroll>.wp-block-columns>.wp-block-column>.wp-block-heading {
  font-size: var(--text-xl);
}

.t-reveal--group .wp-block-heading {
  font-size: var(--text-xl);
}

/* Reveal chars, created by splitReveal() in js/script.js.

   Kazimir's ink does not fit inside its own advance width: the `j` tail reaches
   0.112em past the left edge of its box and `f` 0.068em past the right. Animating a
   char puts that box on its own compositing layer, and the layer is sized to the
   box — so Safari clips the overhanging ink for as long as the layer exists, which
   is exactly the "tails glitching / descenders arrive late" the client reported.
   Chrome sizes its layers to include the overflow, which is why it never showed it.

   The bleed pads the box out until it contains the ink; the equal negative margin
   takes the padding back out of layout, so nothing moves. Horizontal only —
   measured vertical overflow is zero, and a negative vertical margin on an
   inline-block would disturb the line box. */
:root {
  --reveal-char-bleed: 0.15em;
}

.reveal-char {
  padding-left: var(--reveal-char-bleed);
  padding-right: var(--reveal-char-bleed);
  margin-left: calc(-1 * var(--reveal-char-bleed));
  margin-right: calc(-1 * var(--reveal-char-bleed));
  will-change: opacity, transform;
}

.c-swiper-texts h2.wp-block-heading {
  font-size: var(--text-xl-sm);
}

.c-swiper-texts h3.wp-block-heading {
  font-size: var(--text-lg-plus);
}

.team>.wp-block-column>h2.wp-block-heading {
  font-family: var(--font-serif);
  font-size: var(--text-xl-sm);
  font-weight: bold;
  margin-bottom: var(--spacing-lg);
}

.team>.wp-block-column>.wp-block-heading,
.team>.wp-block-column>.wp-block-paragraph {
  font-family: var(--font-sans);
  font-size: var(--text-lg);
}

button {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}

ul {
  margin: 0;
  padding: 0;
}

li {
  list-style: none;
}

.with-icon a::before {
  content: '';
  display: inline-block;
  width: var(--text-base);
  height: var(--text-base);
  -webkit-mask-image: url('svgs/magnolis--chevron-circle-right.svg');
  mask-image: url('svgs/magnolis--chevron-circle-right.svg');
  mask-size: contain;
  mask-repeat: no-repeat;
  mask-position: center;
  background-color: currentColor;
  vertical-align: middle;
  margin-right: var(--spacing-sm);
}

details>summary {
  list-style: none;
}

details>summary::marker {
  content: none
}

/* Safari (incl. iOS) draws its own triangle in the summary UA shadow tree and
   ignores ::marker / list-style before v18. Keep this in its own rule — an
   unknown -webkit- pseudo invalidates any selector list it is grouped with. */
details>summary::-webkit-details-marker {
  display: none;
}

details>summary::before {
  content: '';
  display: inline-block;
  width: var(--text-xs);
  height: var(--text-xs);
  -webkit-mask-image: url('svgs/magnolis--chevron-down.svg');
  mask-image: url('svgs/magnolis--chevron-down.svg');
  mask-size: contain;
  mask-repeat: no-repeat;
  mask-position: center;
  background-color: currentColor;
  vertical-align: middle;
  margin-right: var(--spacing-sm);
}

details[open]>summary::before {
  transform: rotate(180deg);
}

/* The toggle sits BELOW the revealed text, at every breakpoint. Flex column +
   `order` does the reordering, which rules out taking the content out of flow —
   an out-of-flow element can't be ordered against one that's in flow. The
   pinned components add a fixed collapsed height on top of this (see
   .c-swiper-texts / .v-swiper) so expanding can't reflow their grids; here
   there's no pin, so it just pushes what follows. */
.wp-block-details {
  display: flex;
  flex-direction: column;
}

/* flex-shrink: 0 so the fixed height those components set can't squash the
   items back into it. */
.wp-block-details>* {
  flex-shrink: 0;
}

.wp-block-details>summary {
  order: 1;
}

/* Breathing room above the toggle, but only once it sits under the revealed
   text — collapsed, the summary is the whole block and the gap would read as
   stray space under the paragraph above it. */
.wp-block-details[open]>summary {
  margin-top: var(--spacing-md);
}

figure img {
  width: 100%;
  height: auto;
  display: block;
}

/* ── Video play button ──────────────────────────────────────────────────────
   Videos without `autoplay` get a centered play button (js/script.js) that
   starts playback and then fades out. Native controls are left to the Video
   block's own editor setting — nothing here turns them on or replaces them.

   While paused the figure also carries a dim scrim, so the icon stays legible
   over bright footage and a stopped video reads as stopped. Both are driven by
   one `.is-playing` class on the figure. */
figure.wp-block-video {
  /* Neutral black, not --color-dark: the brand brown tints the footage warm
     instead of just darkening it. Matches how .popup-overlay dims the page. */
  --video-scrim-color: #000;
  --video-scrim-opacity: 0.45;
  position: relative;
}

/* Scoped to figures that actually got a button: autoplaying videos are
   decorative backgrounds, never carry .is-playing, and would otherwise sit
   under a scrim that never lifts. */
figure.wp-block-video:has(.video-play)::before {
  content: '';
  position: absolute;
  inset: 0;
  background-color: var(--video-scrim-color);
  opacity: var(--video-scrim-opacity);
  pointer-events: none;
  transition: opacity var(--dur-md) ease;
}

/* The scrim and the button are the only positioned things before the caption,
   so paint order alone stacks caption and button above the scrim — no z-index. */
figure.wp-block-video.is-playing::before {
  opacity: 0;
}

.video-play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: var(--size-play);
  height: var(--size-play);
  padding: 0;
  border: 0;
  cursor: pointer;
  color: var(--color-light);
  background-color: currentColor;
  -webkit-mask-image: url('svgs/magnolis--play.svg');
  mask-image: url('svgs/magnolis--play.svg');
  mask-size: contain;
  mask-repeat: no-repeat;
  mask-position: center;
  transition: opacity var(--dur-md) ease, scale var(--dur-md) ease;
}

/* Playing → the button gets out of the way entirely. Pausing is the Video
   block's own "Playback controls" setting; nothing here re-implements it. */
figure.wp-block-video.is-playing .video-play {
  opacity: 0;
  pointer-events: none;
}

@media (hover: hover) {
  .video-play:hover {
    scale: 1.08;
  }
}

.h-scroll {
  gap: 0;
  opacity: 1;
  transition: opacity var(--dur-md) ease;
}

.h-scroll>div {
  min-width: max-content;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Keep the pinned hero panel full-bleed; the rest shrink to their content
   so the horizontal blocks sit closer together. travelX (js/script.js)
   derives from scrollWidth, so the scroll distance scales automatically. */
.h-scroll>div:first-child {
  min-width: calc(100svw - var(--spacing-xl));
}

.h-scroll .wp-block-heading {
  max-width: var(--max-w-md);
  margin-bottom: 0;
}

/* The panel is min-width: max-content, so media intrinsic width sets the panel
   width. WP caps images at the "large" size but ships video at full resolution,
   so cap both here — otherwise a 2000px video doubles the panel. */
.h-scroll .wp-block-video,
.h-scroll .wp-block-image {
  position: relative;
  margin: 0;
  max-width: var(--max-w-lg);
}

/* The panel is sized by the video and the strip has gap: 0, so without
   this the video butts straight up against the neighbouring panel.
   Matches the .section-container inline gutter. */
.h-scroll .wp-block-video {
  margin: var(--spacing-lg);
}

.h-scroll .wp-block-image figcaption,
.h-scroll .wp-block-video figcaption {
  display: flex;
  gap: var(--spacing-md);
  position: absolute;
  right: 0;
  bottom: 0;
  margin: 0;
  padding: var(--spacing-lg);
  font-size: var(--text-base);
}

.section-container--s-scroll .wp-block-heading {
  margin-bottom: var(--spacing-lg);
  margin-top: var(--spacing-2xl);
}

.section-container--s-scroll .wp-block-image,
.section-container--s-scroll .wp-block-video {
  margin: 0;
}

.section-container--h-o-scroll>.wp-block-columns {
  align-self: stretch;
  width: 100%;
  max-width: calc(var(--max-w-screen) - var(--spacing-lg) * 2);
  margin: 0 auto;
}

.section-container--h-o-scroll>.wp-block-columns>.wp-block-column {
  display: flex;
  flex-direction: column;
  align-self: stretch;
  justify-content: space-between;
}

.section-container--h-o-scroll p:has(a) {
  margin-top: 0;
}


/* Masonry grid — add `.masonry` to a Columns block in the editor. Laid out by
   masonry.js (see script.js), which reads the column count back off the item
   width via `percentPosition`. Gutter is item padding, so spacing stays here;
   the negative margin pulls the outer half-gutters off the edges. */
.masonry>.wp-block-column {
  margin: 0 calc(var(--spacing-lg) / -2) calc(var(--spacing-lg) * -1);
}

/* Items are the column's own children, EXCEPT when the column holds a gallery —
   then the gallery is the grid and its images are the items (script.js resolves
   the same way). The gallery itself is never an item, or it would be laid out as
   a single 33% tile with the real items hidden inside it. */
.masonry>.wp-block-column>*:not(.wp-block-gallery) {
  box-sizing: border-box;
  width: 33.3333%;
  padding: 0 calc(var(--spacing-lg) / 2) var(--spacing-lg);
}

/* Gallery items need their own selector, and a heavy one. Core sizes them with
   `.wp-block-gallery.has-nested-images.columns-default figure.wp-block-image:not(#individual-image)`
   — (1,4,1), the id coming from that :not() — and its width is
   `calc(33.33333% - var(--gap,16px)*.66667)`, which is both the wrong track
   count below 1024 and the reason the last column landed ~13px short of the
   grid's right edge. Pairing .masonry with .wp-block-columns (same element)
   takes ours to (1,5,1) so it wins on specificity rather than load order. */
.masonry.wp-block-columns .wp-block-gallery.has-nested-images figure.wp-block-image:not(#individual-image) {
  box-sizing: border-box;
  width: 33.3333%;
  padding: 0 calc(var(--spacing-lg) / 2) var(--spacing-lg);
}

/* Core lays a gallery out as flex with its own gap. Masonry positions the items
   absolutely, so both have to go — the gutter is item padding here, same as the
   iframe grid, and the column above already carries the negative margin that
   pulls the outer half-gutters off the edges. */
.masonry .wp-block-gallery {
  display: block;
  gap: 0;
  margin: 0;
  max-width: none;
}

.masonry.wp-block-columns .wp-block-gallery.has-nested-images figure.wp-block-image:not(#individual-image) {
  display: block;
  max-width: none;
  margin: 0;
}

.masonry .wp-block-gallery>.wp-block-image img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-md);
}

/* "Crop images" forces object-fit: cover + height: 100% at (1,4,2) specificity —
   the :not(#individual-image) in core's selector is what makes it that high.
   Screenshots must keep their own aspect ratio, and matching the selector with
   `.masonry` in front beats it without reaching for !important. */
.masonry .wp-block-gallery.has-nested-images.is-cropped figure.wp-block-image:not(#individual-image) img {
  height: auto;
  object-fit: initial;
}

/* The frame keeps its authored width and is scaled by script.js; this box is
   what sizes and clips it. */
.masonry-embed {
  overflow: hidden;
}

.masonry iframe {
  display: block;
  border: 0;
  transform-origin: top left;
}

@media (max-width: 1024px) {

  .masonry>.wp-block-column>*:not(.wp-block-gallery),
  .masonry.wp-block-columns .wp-block-gallery.has-nested-images figure.wp-block-image:not(#individual-image) {
    width: 50%;
  }
}

@media (max-width: 768px) {

  .masonry>.wp-block-column>*:not(.wp-block-gallery),
  .masonry.wp-block-columns .wp-block-gallery.has-nested-images figure.wp-block-image:not(#individual-image) {
    width: 100%;
  }
}



.section-container--h-o-scroll>.wp-block-columns>.wp-block-column>.wp-block-columns>.wp-block-column>.wp-block-columns>.wp-block-column:not(:first-child) {
  opacity: 0.2;
}

.section-container--h-o-scroll>.wp-block-columns>.wp-block-column>.wp-block-columns,
.section-container--s-scroll>.wp-block-columns {
  gap: var(--spacing-2xl);
}

.team .wp-block-columns {
  gap: var(--spacing-xl);
  margin-bottom: var(--spacing-xl);
}

.team .wp-block-columns:last-of-type {
  margin-bottom: 0;
}

.team .wp-block-image {
  width: 100%;
  margin-bottom: var(--spacing-lg);
}

.section-container--h-o-scroll>.wp-block-columns>.wp-block-column>.wp-block-columns>.wp-block-column>.wp-block-columns {
  gap: var(--spacing-2xl);
  counter-reset: step-counter;
  padding-top: var(--spacing-xl);
}


.section-container--h-o-scroll>.wp-block-columns>.wp-block-column>.wp-block-columns>.wp-block-column>.wp-block-columns>.wp-block-column {
  counter-increment: step-counter;
}

.section-container--h-o-scroll>.wp-block-columns>.wp-block-column>.wp-block-columns>.wp-block-column>.wp-block-columns>.wp-block-column::before {
  content: counter(step-counter, decimal-leading-zero);
  display: block;
  font-size: var(--text-base);
  margin-bottom: var(--spacing-md);
}

.header-container,
.footer-container,
.section-container {
  padding: 0 var(--spacing-lg);
  max-width: var(--max-w-screen);
  margin: 0 auto;
}

/* The v-swiper supplies its own 100svh frame, so it takes no block padding.
   Keyed to the swiper itself, not to :first-of-type — hide the swiper and the
   next block inherits the position, not the frame, and would lose its padding. */
.home .section-wrapper .section-container:first-of-type:has(.v-swiper)>div {
  padding-block: 0;
}

.wp-block-column:nth-child(odd) .with-icon a {
  margin-left: var(--spacing-xl);
}

.section-container--h-o-scroll .wp-block-column:nth-child(odd) a {
  margin-left: 0;
}

.section-container>div {
  margin: 0;
  width: 100%;
  padding: var(--spacing-2xl) 0;
}

.section-container>div.cazimir {
  padding-block: var(--spacing-4xl);
}

div.t-reveal--group,
/* .section-container--contact>div {
  max-width: calc(100% - var(--spacing-xl) * 2);
  margin-inline: auto;
} */

.t-reveal--group>.wp-block-column>.wp-block-columns>.wp-block-column:nth-child(even) {
  display: flex;
  justify-content: flex-end;
}

.t-reveal--group>.wp-block-column>.wp-block-columns {
  gap: 0;
}


.section-container>.wp-block-columns {
  gap: var(--spacing-4xl);
}

.section-container--s-scroll>.wp-block-columns {
  gap: var(--spacing-xl);
  width: 100%;
  max-width: calc(var(--max-w-screen) - var(--spacing-lg) * 2);
  margin: 0 auto;
}


.section-container:has(.are-vertically-aligned-center) {
  min-height: 100svh;
  display: grid;
}

.section-container:first-of-type>div {
  padding-top: var(--spacing-4xl);
}

.section-container:last-of-type>div {
  padding-bottom: var(--spacing-4xl);
}

.section-container--s-scroll:first-of-type>div {
  padding-top: var(--spacing-2xl);
}

.section-container--s-scroll:last-of-type>div {
  padding-bottom: var(--spacing-2xl);
}


.section-container--h-o-scroll:last-of-type>div {
  padding-bottom: var(--spacing-2xl);
}

/* .section-container--contact>.wp-block-columns {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0;
}

.section-container--contact>.wp-block-columns>.wp-block-column:nth-child(2) {
  display: flex;
  align-items: flex-start;
  justify-content: center;
}

.section-container--contact .wp-block-heading {
  font-size: var(--text-lg-plus);
  max-width: var(--max-w-sm);
  line-height: var(--leading-normal);
} */

/* Contact section (new structure): centred heading + button. */
.section-container--contact .wp-block-heading {
  max-width: var(--max-w-md);
  margin-inline: auto;
  font-size: var(--text-xl-sm);
}


.grid {
  display: grid;
  gap: var(--spacing-md);
  width: 100%;
}

.grid--1 {
  grid-template-columns: repeat(1, 1fr);
}

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

.grid--3 {
  grid-template-columns: repeat(3, 1fr);
}

.grid--4 {
  grid-template-columns: repeat(4, 1fr);
}

.menu-item.privacy a {
  opacity: var(--opacity-muted);
}

.section--s-scroll .section-container,
.section--h-o-scroll .section-container {
  min-height: 100svh;
  display: flex;
  align-items: center;
  justify-content: center;
}

.section--map {
  height: 70vh;
}

.mapboxgl-control-container {
  display: none;
}

.section-container--map {
  --map-overlay-opacity: 0.85;
  position: relative;
  padding: 0;
  max-width: 100%;
  height: 100%;
}

#map {
  width: 100%;
  height: 100%;
}

/* Click-to-interact gate: a hover veil blocks the map until it is clicked away.
   Pointer devices only — on touch the map is live and the veil never renders. */
.map-overlay {
  position: absolute;
  inset: 0;
  z-index: 20;
  background-color: var(--color-xlight);
  opacity: 0;
  pointer-events: none;
  cursor: pointer;
  transition: opacity var(--dur-sm) ease;
}

.map-hover-state {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 21;
  color: var(--color-dark);
  font-family: var(--font-serif);
  font-size: var(--text-md);
  letter-spacing: 0.05em;
  opacity: 0;
  pointer-events: none;
  user-select: none;
  transition: opacity var(--dur-sm) ease;
}

@media (hover: hover) {
  .section-container--map:hover .map-overlay {
    opacity: var(--map-overlay-opacity);
    pointer-events: auto;
  }

  .section-container--map:hover .map-hover-state {
    opacity: 1;
  }
}

/* Touch: no hover to reveal the veil, so it sits visible until the map is tapped. */
@media (hover: none) {
  .map-overlay {
    opacity: var(--map-overlay-opacity);
    pointer-events: auto;
  }

  .map-hover-state {
    opacity: 1;
  }
}

.section-container--map.is-map-active .map-overlay,
.section-container--map.is-map-active .map-hover-state {
  display: none;
}

.map-marker {
  width: 8rem;
  height: 2.5rem;
}

.map-marker::before {
  content: '';
  display: block;
  width: 100%;
  height: 100%;
  background-image: url('svgs/magnolis--map-marker.svg');
  background-repeat: no-repeat;
  background-size: contain;
  background-position: center;
}

.header {
  position: fixed;
  top: var(--spacing-lg);
  left: 0;
  width: 100%;
  z-index: 100;
  color: var(--color-dark);
  transition: color var(--dur-sm) ease;
}

.header--light {
  color: var(--color-light);
}

.header a,
.header button,
.header label {
  color: inherit;
  text-decoration: none;
}

.header svg,
.header svg * {
  fill: currentColor !important;
  transition: fill var(--dur-sm) ease;
}

.header-container {
  display: flex;
  align-items: center;
}

.header .nav {
  display: grid;
  grid-template-columns: 2fr 1fr 2fr;
  width: 100%;
  z-index: 10;
}

.header .nav .nav--center {
  justify-content: center;
}

.header .nav .nav--right {
  justify-content: flex-end;
  gap: var(--spacing-lg-plus);
}

#menu-language-menu {
  position: relative;
  display: flex;
  align-items: center;
}

#menu-language-menu a {
  text-decoration: none;
}

#menu-language-menu>.wpml-ls-menu-item>a {
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  opacity: var(--opacity-muted);
  display: flex;
  align-items: center;
  gap: 0.3em;
  transition: opacity var(--dur-sm) ease;
}

#menu-language-menu>.wpml-ls-menu-item>a::after {
  content: '';
  display: inline-block;
  width: var(--text-xs);
  height: var(--text-xs);
  -webkit-mask-image: url('svgs/magnolis--chevron-down.svg');
  mask-image: url('svgs/magnolis--chevron-down.svg');
  mask-size: contain;
  mask-repeat: no-repeat;
  mask-position: center;
  background-color: currentColor;
}

#menu-language-menu>.wpml-ls-menu-item:hover>a,
#menu-language-menu>.wpml-ls-menu-item:focus-within>a {
  opacity: 1;
}

#menu-language-menu>.wpml-ls-menu-item:hover>a::after,
#menu-language-menu>.wpml-ls-menu-item:focus-within>a::after {
  transform: rotate(180deg);
}

#menu-language-menu .sub-menu {
  position: absolute;
  top: 100%;
  left: 0;
  width: 100%;
  padding-top: var(--spacing-xs);
  pointer-events: none;
}

#menu-language-menu>.wpml-ls-menu-item:hover .sub-menu,
#menu-language-menu>.wpml-ls-menu-item:focus-within .sub-menu {
  pointer-events: auto;
}

#menu-language-menu .sub-menu li {
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity var(--dur-sm) ease, transform var(--dur-sm) ease;
}

#menu-language-menu>.wpml-ls-menu-item:hover .sub-menu li,
#menu-language-menu>.wpml-ls-menu-item:focus-within .sub-menu li {
  opacity: var(--opacity-muted);
  transform: translateY(0);
}

#menu-language-menu>.wpml-ls-menu-item:hover .sub-menu li:hover,
#menu-language-menu>.wpml-ls-menu-item:focus-within .sub-menu li:hover {
  opacity: 1;
}

#menu-language-menu .sub-menu a {
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  white-space: nowrap;
}

#menu-language-menu .wpml-ls-native {
  font-size: 0;
}

#menu-language-menu .wpml-ls-native::before {
  content: attr(lang);
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

#menu-language-menu .wpml-ls-display {
  display: none;
}

/* ── Mobile lang switch (inside burger overlay, bottom-left) ── */
.lang-switch--mobile {
  display: none;
}

.header .nav>* {
  display: flex;
  align-items: center;
}

.footer-container {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-end;
  /* padding-top: var(--spacing-2xl); */
  padding-bottom: var(--spacing-lg);
  gap: var(--spacing-3xl);
}

.footer .inner-container:first-of-type {
  display: grid;
  gap: var(--spacing-lg-plus);
  width: 100%;
}

.section-container--h-o-scroll>.wp-block-columns>.wp-block-column>.wp-block-columns>.wp-block-column::before,
.footer .inner-container:first-of-type::before {
  content: '';
  display: block;
  width: 100%;
  height: var(--spacing-xs);
  -webkit-mask-image: url('svgs/magnolis--separator-full.svg');
  mask-image: url('svgs/magnolis--separator-full.svg');
  mask-repeat: no-repeat;
  mask-size: 100%;
  background-color: currentColor;
}

/* Scroll-progress separator (desktop): a dim full-width track (::before)
   with a bright fill (::after) that draws in left-to-right over it as the
   steps fade in. --line-progress (0..1) is driven by GSAP. Mobile uses
   ::after for the vertical separator, so this is desktop-only. */
@media (min-width: 769px) {
  .section-container--h-o-scroll>.wp-block-columns>.wp-block-column>.wp-block-columns>.wp-block-column {
    position: relative;
  }

  /* Dim track — always visible. */
  .section-container--h-o-scroll>.wp-block-columns>.wp-block-column>.wp-block-columns>.wp-block-column::before {
    opacity: 0.2;
  }

  /* Bright fill — overlays the track, revealed by scroll progress. */
  .section-container--h-o-scroll>.wp-block-columns>.wp-block-column>.wp-block-columns>.wp-block-column::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: var(--spacing-xs);
    -webkit-mask-image: url('svgs/magnolis--separator-full.svg');
    mask-image: url('svgs/magnolis--separator-full.svg');
    mask-repeat: no-repeat;
    mask-size: 100%;
    background-color: currentColor;
    clip-path: inset(0 calc((1 - var(--line-progress, 0)) * 100%) 0 0);
  }
}

.footer .inner-container:last-of-type {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: var(--spacing-md);
  width: 100%;
}

.footer-logo {
  display: flex;
  align-items: center;
  gap: var(--spacing-lg);
}

.footer-menu {
  display: grid;
}

.footer .grid--4>ul:last-of-type {
  text-align: right;
}

.wp-block-button,
.button--outline {
  position: relative;
  display: inline-flex;
  height: min-content;
  color: currentColor;
  font-family: var(--font-sans);
}

.wp-block-buttons .wp-block-button__link,
.button--outline {
  padding: var(--spacing-md) var(--spacing-lg);
}

.wp-block-button::before,
.button--outline::before {
  content: '';
  position: absolute;
  inset: 0;
  -webkit-mask-image: url('svgs/magnolis--button.svg');
  mask-image: url('svgs/magnolis--button.svg');
  mask-size: 100% 100%;
  mask-repeat: no-repeat;
  background-color: currentColor;
  pointer-events: none;
}

.wp-block-button>.wp-block-button__link,
.button--outline>span {
  color: inherit;
  background-color: transparent;
  text-transform: uppercase;
  font-size: var(--text-xs);
  border: 0;
}



.menu-item.instagram a::before,
.menu-item.linkedin a::before {
  content: '';
  display: inline-block;
  width: var(--text-sm);
  height: var(--text-sm);
  background-color: currentColor;
  mask-size: contain;
  mask-repeat: no-repeat;
  mask-position: center;
  margin-right: var(--spacing-md);
}

.wp-block-navigation-item.instagram a::before,
.menu-item.instagram a::before {
  -webkit-mask-image: url('svgs/magnolis--instagram.svg');
  mask-image: url('svgs/magnolis--instagram.svg');
}

.menu-item.linkedin a::before {
  -webkit-mask-image: url('svgs/magnolis--linkedin.svg');
  mask-image: url('svgs/magnolis--linkedin.svg');
}

.wp-block-navigation-item.linkedin a::before {
  -webkit-mask-image: url('svgs/magnolis--linkedin-2.svg');
  mask-image: url('svgs/magnolis--linkedin-2.svg');
}

.wp-block-navigation-item.email a::before {
  -webkit-mask-image: url('svgs/magnolis--email.svg');
  mask-image: url('svgs/magnolis--email.svg');
}

.menu-item.instagram a,
.menu-item.linkedin a {
  align-items: anchor-center;
}

.wp-block-navigation-item.email span,
.wp-block-navigation-item.instagram span,
.wp-block-navigation-item.linkedin span {
  display: none;
}

.wp-block-navigation-item.email a::before,
.wp-block-navigation-item.linkedin a::before,
.wp-block-navigation-item.instagram a::before {
  content: '';
  display: flex;
  width: var(--text-lg-xl);
  min-height: var(--text-lg-xl);
  background-color: currentColor;
  mask-size: contain;
  mask-repeat: no-repeat;
  mask-position: center;
}


nav.wp-block-navigation {
  gap: 0 var(--spacing-xl);
  margin-top: var(--spacing-xl);
  flex-direction: column;
}

.page-template-page-over-ons .wp-block-navigation__container {
  gap: var(--spacing-md-plus);
}

.page-template-page-over-ons .wp-block-navigation-item a::before {
  width: var(--text-base-plus);
  height: var(--text-base-plus);
}

.page-template-page-aanpak .section-container--hero>.wp-block-columns>.wp-block-column::after,
.page-template-page-over-ons .section-container--hero>.wp-block-columns>.wp-block-column::after,
.section-container--hero nav.wp-block-navigation.items-justified-center::after {
  opacity: 0;
  transition: opacity var(--dur-md) ease;
}

.page-template-page-aanpak .section-container--hero>.wp-block-columns>.wp-block-column.revealed::after,
.page-template-page-over-ons .section-container--hero>.wp-block-columns>.wp-block-column.revealed::after,
.section-container--hero nav.wp-block-navigation.items-justified-center.revealed::after {
  opacity: 1;
}

.section-container--hero nav.wp-block-navigation.items-justified-center::after {
  margin-top: var(--spacing-lg);
}

.page-template-page-aanpak .section-container--hero>.wp-block-columns>.wp-block-column::after,
.page-template-page-over-ons .section-container--hero>.wp-block-columns>.wp-block-column::after,
nav.wp-block-navigation.items-justified-center::after {
  content: '';
  display: block;
  width: 100%;
  height: var(--spacing-xs);
  -webkit-mask-image: url('svgs/magnolis--separator-short.svg');
  mask-image: url('svgs/magnolis--separator-short.svg');
  mask-repeat: no-repeat;
  background-color: currentColor;
  max-width: var(--max-w-xxs);
  margin: var(--spacing-xl) auto auto;

}



.bg--fixed {
  background-attachment: fixed;
}

/* .section-container:has(.cazimir) {
  position: relative;
  max-width: var(--max-w-screen);
  display: flex;
  align-items: center;
  justify-content: center;
} */

.cazimir .wp-block-column:empty {
  position: relative;
}



.cazimir .wp-block-column:empty::before {
  content: '';
  position: absolute;
  top: 50%;
  left: calc((max(0px, (100vw - var(--max-w-screen)) / 2) + var(--spacing-lg)) * -1);
  transform: translateY(-50%);
  width: 100%;
  aspect-ratio: 4 / 3;
  background-image: url(assets/magnolis--cazimir-2-2.webp);
  background-size: 100% auto;
  background-repeat: no-repeat;
  background-position: bottom left;
  z-index: -1;
  pointer-events: none;
}

@media (min-width: 1920px) {
  .cazimir .wp-block-image::before {
    left: 0;
  }
}

.cazimir .wp-block-heading {
  max-width: var(--max-w-xs);
}

.cazimir p {
  max-width: var(--max-w-xs);
}

.burger-button {
  text-transform: uppercase;
  font-size: var(--text-sm);
  display: flex;
  align-items: center;
}


.burger-menu-container.open {
  visibility: visible;
  opacity: 1;
}

.burger-menu .menu-item a:not(.button--appointment) {
  text-decoration: none;
  font-family: var(--font-serif);
  font-size: var(--text-2xl);

}

.burger-menu .menu {
  display: grid;
  gap: var(--spacing-lg);
}

.burger-menu .menu-item {
  display: flex;
  gap: var(--spacing-md);
}

.burger-menu .menu-item:nth-child(1) {
  margin-left: calc(var(--spacing-lg) * -1);
}

.burger-menu .menu-item:nth-child(2) {
  margin-left: var(--spacing-2xl);
}

.burger-menu .menu-item:nth-child(3) {
  margin-left: var(--spacing-4xl);
}

.burger-menu .menu-item:nth-child(4) {
  margin-left: var(--spacing-lg);
}

.burger-menu .menu-item-counter {
  display: block;
  font-size: var(--text-base);
  margin-top: var(--spacing-sm);
}

.header:has(.burger-menu-container.open) {
  color: var(--color-dark);
}

body:has(.burger-menu-container.open) {
  overflow: hidden;
}

.burger-button {
  position: relative;
}

.burger-icon {
  display: none;
}

.header:has(.burger-menu-container.open) .burger-button::before {
  content: '';
  position: absolute;
  left: calc(var(--spacing-md) * -1);
  top: 50%;
  transform: translateY(-50%);
  width: var(--text-xxs);
  height: var(--text-xxs);
  -webkit-mask-image: url('svgs/magnolis--close.svg');
  mask-image: url('svgs/magnolis--close.svg');
  mask-size: contain;
  mask-repeat: no-repeat;
  mask-position: center;
  background-color: currentColor;
}

.header:has(.burger-menu-container.open) .nav .button--appointment {
  opacity: 0;
  transition: opacity var(--dur-md) ease;
}

.nav .button--appointment {
  transition: opacity var(--dur-md) ease;
}

.header .button-container {
  display: flex;
  align-items: center;
  margin-left: var(--spacing-lg);
}

.section-container.hidden {
  opacity: 0;
  transition: opacity var(--dur-md) ease;
}

.section-container {
  opacity: 1;
  transition: opacity var(--dur-md) ease;
}

.h-scroll.hidden {
  opacity: 0;
  transition: opacity var(--dur-md) ease;
}

/* script.js only marks `.section-container` and `.h-scroll`, so the band —
   a `::before` on the section — never faded with the menu. Descendant, not
   child: a pinned container sits inside GSAP's `.pin-spacer`. */
.section::before {
  opacity: 1;
  transition: opacity var(--dur-md) ease;
}

.section:has(.section-container.hidden)::before,
.section:has(.h-scroll.hidden)::before {
  opacity: 0;
}

.burger-menu {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  opacity: 0;
  transition: opacity var(--dur-md) ease;
}

.burger-menu-container.open .burger-menu {
  opacity: 1;
  transition: opacity var(--dur-md) ease var(--dur-md);
}

.section--sticky {
  position: sticky;
  top: 0;
  overflow: hidden;
}

.wp-block-gallery.swiper {
  display: block !important;
  height: 100svh;
  width: 100%;
}

body .swiper-pagination-vertical.swiper-pagination-bullets,
body .swiper-vertical>.swiper-pagination-bullets {
  right: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--spacing-sm) / 2);
  --swiper-pagination-bullet-vertical-gap: 0;
}

body .swiper-pagination-bullet {
  opacity: 1;
  background: transparent;
  border: 1px solid var(--color-dark);
  margin: 0;
}

body .swiper-pagination-bullet-active {
  background: var(--color-dark);
}


.wp-block-gallery .swiper-slide {
  display: flex;
  align-items: center;
  justify-content: center;
}

.wp-block-gallery .swiper-slide figure {
  max-width: var(--max-w-sm) !important;
  height: auto;
}

.wp-block-gallery .swiper-slide img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.section-container:first-of-type>div.c-swiper {
  padding-top: 0;
}

.c-swiper {
  display: grid !important;
  grid-template-columns: 1fr 1fr;
  gap: var(--spacing-xl);
}

.c-swiper-left {
  display: flex;
  gap: var(--spacing-xl);
}

.c-swiper-pagination {
  position: sticky;
  top: 0;
  height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: calc(var(--spacing-sm) / 2);
}

.c-swiper-texts>div {
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.team>.wp-block-column>:not(.wp-block-heading):not(.wp-block-columns) {
  font-family: var(--font-serif);
  font-size: var(--text-lg-plus);
  max-width: var(--max-w-xs);
  margin-inline: auto;
  margin-bottom: var(--spacing-xl);
}


.team>.wp-block-column>.wp-block-columns>.wp-block-column {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.team .wp-block-group__inner-container>*:last-child {
  margin: 0;
}

.team .wp-block-columns .wp-block-heading {
  font-size: var(--text-lg-plus);
  margin: 0;
}

/* Expanding must not reflow this component's pinned grid, so the block keeps a
   collapsed footprint — the summary's single line — and lets the expansion
   overflow visibly. Ordering and spacing are unscoped, further up. */
.c-swiper-texts .wp-block-details {
  position: relative;
  margin-top: var(--spacing-md);
  height: 1lh;
}

.c-swiper-texts .wp-block-details>summary {
  text-decoration: underline;
}

.c-swiper-images {
  position: sticky;
  top: 0;
  height: 100svh;
}

.c-swiper-images>.wp-block-column {
  position: absolute;
  inset: 0;
  opacity: 0;
  display: flex;
  align-items: center;
}

/* v-swiper: c-swiper with a third column. Left scroll track | sticky centred
   sketch (cross-fades) | right scroll track. Restructured by JS on desktop. */
.v-swiper {
  display: grid !important;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 100svh;
  gap: var(--spacing-xl);
  align-items: start;
  height: 100svh;
  /* Clip the tracks' vertical overflow to one viewport WITHOUT clipping the
     figures' horizontal bleed — negative left/right insets keep the sides open
     so the portraits still reach the screen edges. */
  clip-path: inset(0 -100vw);
}

.v-swiper-left>.wp-block-column,
.v-swiper-right>.wp-block-column {
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.v-swiper-sketches {
  position: relative;
  height: 100svh;
}

.v-swiper-sketches>.wp-block-column {
  position: absolute;
  inset: 0;
  opacity: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Expanding "Lees meer" must not reflow the grid (it would shift the sticky
   sketch + the other column). Same fix as c-swiper: float the revealed
   content out of flow. */
/* Expanding must not reflow this component's pinned grid, so the block keeps a
   collapsed footprint — the summary's single line — and lets the expansion
   overflow visibly. Ordering and spacing are unscoped, further up. */
.v-swiper .wp-block-details {
  position: relative;
  margin-top: var(--spacing-md);
  height: 1lh;
}

.v-swiper .wp-block-details>summary {
  text-decoration: underline;
}

/* Portrait column: pin its image full-height to the track edge, bleeding out of
   the centred text flow. The COLUMN stays in flow (keeps its 100svh slot so the
   two tracks stay the same height and slides line up); only the FIGURE is taken
   out and pinned — left edge in the left track, right edge in the right track. */
.v-swiper-left .wp-block-column:has(figure),
.v-swiper-right .wp-block-column:has(figure) {
  position: relative;
}

/* Offset that cancels the section-container inset (its --spacing-lg padding plus
   the max-width auto-margin on wide screens) so the figure reaches the viewport
   edge. min(0px, …) zeroes the auto-margin term when the viewport is narrower
   than --max-w-screen. */
.v-swiper {
  --v-edge-bleed: calc(min(0px, (var(--max-w-screen) - 100vw) / 2) - var(--spacing-lg));
}

.v-swiper-left .wp-block-column:has(figure) figure,
.v-swiper-right .wp-block-column:has(figure) figure {
  position: absolute;
  top: 0;
  height: 100svh;
  margin: 0;
}

.v-swiper-left .wp-block-column:has(figure) figure {
  left: var(--v-edge-bleed);
}

.v-swiper-right .wp-block-column:has(figure) figure {
  right: var(--v-edge-bleed);
}

.v-swiper-left .wp-block-column:has(figure) img,
.v-swiper-right .wp-block-column:has(figure) img {
  display: block;
  height: 100svh;
  width: auto;
}

.wp-block-column:has(.wpcf7) {
  margin-top: calc(var(--text-base-plus) * -1);
}

form p {
  display: contents;
}

form .wpcf7-spinner {
  display: none;
}

form .grid input {
  min-width: 100%;
}

form,
form .wpcf7-checkbox {
  display: grid;
}

form {
  gap: var(--spacing-lg-plus);
}

.form .grid--2 {
  gap: var(--spacing-md) var(--spacing-xl);
}

form .wpcf7-list-item {
  margin: 0;
}

.button--outline input[type="submit"] {
  background: transparent;
  border: none;
  font-size: var(--text-sm);
  padding: 0;
  color: currentColor;
}


input[type="checkbox"] {
  -webkit-appearance: none;
  appearance: none;
}

.wpcf7-not-valid-tip {
  position: absolute;
}

input[type="checkbox"]::before {
  content: '';
  display: block;
  width: var(--text-base);
  height: var(--text-base);
  -webkit-mask-image: url(svgs/magnolis--checkbox.svg);
  mask-image: url(svgs/magnolis--checkbox.svg);
  mask-size: contain;
  background-color: var(--color-light);
}

input[type="checkbox"] {
  position: relative;
}

input[type="checkbox"]::after {
  content: '';
  display: block;
  position: absolute;
  inset: 0;
  -webkit-mask-image: url(svgs/magnolis--close.svg);
  mask-image: url(svgs/magnolis--close.svg);
  mask-size: var(--text-xxs) var(--text-xxs);
  mask-repeat: no-repeat;
  mask-position: center;
  background-color: var(--color-light);
  opacity: 0;
}

input[type="checkbox"]:checked::after {
  opacity: 1;
}

form input[type="text"],
form input[type="email"],
form input[type="tel"] {
  border: none;
  border-bottom: 1px solid currentColor;
  border-radius: 0;
  background: transparent;
  padding: 0.25em 0;
  width: 100%;
  display: block;
  outline: none;
  color: currentColor;
  font-size: inherit;
  font-family: inherit;
  box-shadow: none;
  -webkit-appearance: none;
  appearance: none;
}

form input[type="text"]::placeholder,
form input[type="email"]::placeholder,
form input[type="tel"]::placeholder {
  opacity: 0;
}

.wpcf7-form-control-wrap[data-placeholder] {
  position: relative;
  display: block;
  padding-top: var(--text-base-plus);
}

.wpcf7-form-control-wrap[data-placeholder]::before {
  content: attr(data-placeholder);
  position: absolute;
  left: 0;
  top: var(--text-base-plus);
  transform-origin: left top;
  transition: top var(--dur-sm) ease, transform var(--dur-sm) ease, opacity var(--dur-sm) ease;
  pointer-events: none;
  line-height: 1;
}

.wpcf7-form-control-wrap:has(input:focus)::before,
.wpcf7-form-control-wrap:has(input:not(:placeholder-shown))::before {
  top: 0;
  transform: scale(0.75);
}

.form-checkboxes-container {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-md);
}

.form-checkboxes-container br {
  display: contents;
}

.form-checkboxes-container>p {
  font-style: italic;
  font-size: var(--text-base-plus);
}

.form-checkboxes {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-md);
}

.form-checkbox-item {
  display: flex;
  align-items: flex-start;
  gap: var(--spacing-md);
}

.form-checkbox-check .wpcf7-list-item-label {
  display: none;
}

.form-checkbox-text {
  display: flex;
  flex-direction: column;
  font-family: var(--font-sans);
}

.form-checkbox-text .bold {
  font-weight: bold;
}

.form-checkbox-desc {
  opacity: 0.7;
}

.form-footer {
  display: flex;
  gap: var(--spacing-xl);
}

.form-acceptance {
  display: flex;
  align-items: flex-start;
  gap: var(--spacing-md);
  flex: 1;
}

/* CF7 wraps its success / error message in a 2px coloured box. Keep the
   message, drop the box. Its own rules are `.wpcf7 form .wpcf7-response-output`
   (0,2,1 — carries the border shorthand) plus `.wpcf7 form.sent|.failed|…`
   (0,3,1 — border-COLOUR only), so matching form.wpcf7-form outweighs the
   first; the state rules then recolour a border that no longer has a style. */
.wpcf7 form.wpcf7-form .wpcf7-response-output {
  margin: var(--spacing-md) 0 0;
  padding: 0;
  border: 0;
}

/* ── Page overrides ── */

.page-template-page-over-ons .wp-block-navigation-item a::before {
  width: var(--text-lg);
  height: var(--text-lg);
  opacity: var(--opacity-muted);
  transition: opacity var(--dur-sm) ease;
}

.page-template-page-over-ons .wp-block-navigation-item a:hover::before {
  opacity: 1;
}

.home .section--hero .wp-block-heading {
  font-size: var(--text-xl);
}


.section--hero .wp-block-heading {
  font-size: var(--text-lg-xl);
  max-width: var(--max-w-xl);
  margin: auto;
}

/* Same measure as the hero heading above — both run at --text-lg-xl, so
   without this the statement stretches the full section-container width
   (1528px at a 1728px viewport) and reads wider than every other heading
   on the page. Capped on the heading, not on .bg-statement itself: the
   backgrounds sit on .section / .section-wrapper and must stay full-bleed. */
.bg-statement .wp-block-heading {
  max-width: var(--max-w-xl);
  margin-inline: auto;
}

.section--form {
  height: 100svh;
  display: flex;
  align-items: center;
}

.section--form .wp-block-column:not(.wpcf7) .wp-block-paragraph {
  font-family: var(--font-serif);
  font-size: var(--text-lg);
}

.page-template-page-contact .section-container--hero>.wp-block-columns>.wp-block-column>.wp-block-columns {
  margin-top: var(--spacing-xl);
}

.page-template-page-contact .section-container--hero>.wp-block-columns>.wp-block-column>.wp-block-heading {
  font-size: var(--text-lg);
}

.page-template-page-contact .section-container--hero>.wp-block-columns>.wp-block-column>.wp-block-columns .wp-block-heading {
  font-size: var(--text-md);
}

.page-template-page-contact .section-container--hero>.wp-block-columns>.wp-block-column>.wp-block-columns a {
  font-size: var(--text-sm-plus);
}

.page-template-page-contact .section-container--hero>.wp-block-columns>.wp-block-column>.wp-block-columns p:has(a) {
  margin-top: var(--spacing-sm);
}


/* Home backgrounds */
.home .section--hero {
  z-index: 0;
  background-image: url('assets/magnolis--home-hero.webp');
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center center;
}

.section--h-scroll::before,
.section--s-scroll::before {
  content: '';
  display: block;
  min-width: 100svw;
  /* Must match the asset's own ratio (2500 x 169) so the band renders at the
     same horizontal scale as the slab below it and the texture stays continuous. */
  aspect-ratio: 2500 / 169;
  background-image: url('assets/magnolis--brown-cut--2500.webp');
  background-size: 100% auto;
  background-repeat: no-repeat;
  background-position: bottom center;
}

.section--h-scroll .section-container:first-of-type>div {
  padding: initial;
}

/* Guarantees the --spacing-lg gutter survives a viewport narrower than the
   video's natural width, where the margin alone would just be overrun. */
.h-scroll .wp-block-video {
  max-width: min(var(--max-w-lg), calc(100svw - var(--spacing-lg) * 2));
}

/* Mirrored so the tear doesn't read as the same edge twice across the site.
   Baked into the asset — `scaleX(-1)` would mirror the content with it and,
   on a pinned container, fight ScrollTrigger. Same for the slab below. */
.section--s-scroll::before {
  background-image: url('assets/magnolis--brown-cut--flip--2500.webp');
}

.section--h-scroll .section-container,
.section--s-scroll .section-container,
.section-container--masonry {
  min-height: 100svh;
  min-width: 100svw;
  background-size: 100% 100%;
  background-repeat: no-repeat;
  background-position: top center;
  display: flex;
  align-items: center;
}

.section--h-scroll .section-container {
  /* background-image: url('assets/magnolis--brown.webp'); */
  background-image: url('assets/magnolis--brown--2500.webp');
}

.section--s-scroll .section-container,
.section-container--masonry {
  background-image: url('assets/magnolis--brown--flip--2500.webp');
}

/* The slab is full-bleed and has to stay ON this container: script.js pins it,
   so the container goes position: fixed for the pin's duration and the
   background rides along, holding still behind the grid. Painting it on the
   section instead lets it scroll away and the slab runs out mid-grid.
   So `min-width: 100svw` stays, and only the GRID is capped — to the same
   content box every other .section-container gives its children. */
/* `>div`, not `>*`, to match the specificity of `.section-container>div` above —
   its `margin: 0` would otherwise win and the grid would sit hard against the
   left gutter instead of centring. */
.section-container--masonry>div {
  flex: 1;
  max-width: calc(var(--max-w-screen) - var(--spacing-lg) * 2);
  margin-inline: auto;
}

/* Pinned by script.js: one viewport tall, top-aligned since the grid is taller
   than the frame, clipped so rows don't show past the slab. */
@media (min-width: 769px) {
  .section-container--masonry {
    height: 100svh;
    align-items: flex-start;
    overflow: hidden;
  }
}

.home .section-wrapper {
  position: relative;
  z-index: 1;
  min-height: 100%;
  background-image: url('assets/magnolis--home-wrapper.webp');
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center center;
  background-attachment: fixed;
}

/* Aanpak backgrounds */
.page-template-page-aanpak .section--hero {
  z-index: 0;
  background-image: url('assets/magnolis--aanpak-hero.webp');
  /* background-color: var(--color-light); */
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center center;
}


.section--h-o-scroll .section-container {
  background-image: url('assets/magnolis--brown.webp');
  min-height: 100svh;
  min-width: 100svw;
  background-size: cover;
  background-repeat: no-repeat;
  background-position: top center;
  display: flex;
  align-items: center;
}

.page-template-page-aanpak .section:has(.bg-statement) {
  background-image: url('assets/magnolis--statement.webp');
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center center;
}


.page-template-page-aanpak .section-wrapper {
  position: relative;
  z-index: 1;
  min-height: 100%;
  background-image: url('assets/magnolis--aanpak-wrapper.webp');
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center center;
  background-attachment: fixed;
}


/* Over ons backgrounds */
.page-template-page-over-ons .section--hero {
  z-index: 0;
  background-image: url('assets/magnolis--overons-hero.webp');
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center center;
}

.page-template-page-over-ons .section-wrapper {
  position: relative;
  z-index: 1;
  min-height: 100%;
  background-image: url('assets/magnolis--overons-wrapper.webp');
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center center;
  background-attachment: fixed;
}

/* Inzichten backgrounds */
.page-template-page-inzichten .section--hero {
  z-index: 0;
  background-image: url('assets/magnolis--inzichten-hero.webp');
  /* background-color: var(--color-light); */
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center center;
}

.page-template-page-inzichten .section-wrapper {
  position: relative;
  z-index: 1;
  min-height: 100%;
  background-image: url('assets/magnolis--inzichten-wrapper.webp');
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center center;
  background-attachment: fixed;
}

/* Contact backgrounds */
.page-template-page-contact .section--hero {
  z-index: 0;
  background-image: url('assets/magnolis--brown.webp');
  /* background-color: var(--color-light); */
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center center;
}

.page-template-page-contact .section--form {
  z-index: 1;
  background-image: url('assets/magnolis--brown.webp');
  background-size: cover;
  background-repeat: repeat;
  background-position: center center;
  background-size: auto 100vh;
  background-attachment: fixed;
}

/* Footer backgrounds */
.footer {
  width: 100%;
  background-image: url('assets/magnolis--footer.webp');
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

/* Menu backgrounds */
.burger-menu-container {
  background-image: url('assets/magnolis--bg-menu.webp');
  background-size: cover;
  background-repeat: no-repeat;
  background-position: top center;
  width: 100svw;
  /* dvh, not svh: svh is the viewport with Safari's toolbar expanded, so once
     the toolbar collapses this overlay falls short and leaks a white strip at
     the bottom. The body is locked while the menu is open, so the toolbar can't
     change state mid-view and dvh's usual resize jank never happens. */
  height: 100dvh;
  position: fixed;
  top: 0;
  left: 0;
  visibility: hidden;
  opacity: 0;
  transition: opacity var(--dur-md) ease;
}


/* ---------------------------------------------------------------- Mobile backgrounds */
/* Uncomment each rule once its mobile-* asset exists in /assets. */
@media (max-width: 768px) {

  /* Home */
  .home .section--hero {
    background-image: url('assets/magnolis--mobile-hero-1.webp');
  }

  /* .section--h-scroll::before {
    background-image: url('assets/magnolis--mobile-horizontal-top.webp');
  } */

  /* .section--h-scroll .section-container {
    background-image: url('assets/magnolis--mobile-horizontal.webp');
  } */

  /* iOS Safari treats `background-attachment: fixed` as `scroll`, so the desktop
     rule sizes the crop to the full page height instead of the viewport, and
     these pages also carry page-wide `.section--sticky` sections that the
     wrapper's own background is the only thing covering.
     A sticky pseudo solves both: viewport-anchored while the wrapper scrolls,
     bounded to the wrapper's box so the hero still shows above it, `z-index: -1`
     inside the wrapper's own stacking context so it paints over the stickies,
     and `margin-bottom` cancels its height so the flow is untouched.
     Sticky is honoured by iOS Safari; `background-attachment: fixed` is not. */
  .home .section-wrapper,
  .page-template-page-aanpak .section-wrapper,
  .page-template-page-over-ons .section-wrapper,
  .page-template-page-inzichten .section-wrapper {
    background-image: none;
    /* Anything the pseudo fails to cover falls through to the html background,
       which is white. Keep the miss on-palette. */
    /* background-color: var(--color-light); */
  }

  .home .section-wrapper::before,
  .page-template-page-aanpak .section-wrapper::before,
  .page-template-page-over-ons .section-wrapper::before,
  .page-template-page-inzichten .section-wrapper::before {
    content: '';
    display: block;
    position: sticky;
    top: 0;
    /* lvh, not svh: svh is the viewport with Safari's toolbar expanded, so once
       the toolbar collapses the pseudo falls short by exactly the toolbar's
       height and leaves an unpainted strip. lvh always covers; the overhang
       when the toolbar is showing is simply clipped. */
    height: 100lvh;
    margin-bottom: -100lvh;
    z-index: -1;
    background-size: cover;
    background-position: center center;
    background-repeat: no-repeat;
    pointer-events: none;
  }

  .home .section-wrapper::before {
    background-image: url('assets/magnolis--mobile-home-wrapper.webp');
  }

  .page-template-page-aanpak .section-wrapper::before {
    background-image: url('assets/magnolis--aanpak-wrapper.webp');
  }

  .page-template-page-over-ons .section-wrapper::before {
    background-image: url('assets/magnolis--overons-wrapper.webp');
  }

  .page-template-page-inzichten .section-wrapper::before {
    background-image: url('assets/magnolis--inzichten-wrapper.webp');
  }

  /* Aanpak */
  /* .page-template-page-aanpak .section--hero {
    background-image: url('assets/magnolis--mobile-hero-2.webp');
  } */

  /* .section--h-o-scroll .section-container {
    background-image: url('assets/magnolis--mobile-horizontal.webp');
  } */

  /* .page-template-page-aanpak .section:has(.bg) {
    background-image: url('assets/magnolis--mobile-hero-2.webp');
  } */

  /* .page-template-page-aanpak .section-wrapper::before {
    background-image: url('assets/magnolis--mobile-neutral-1-vertical.webp');
  } */

  /* Over ons */
  /* .page-template-page-over-ons .section--hero {
    background-image: url('assets/magnolis--mobile-hero-3.webp');
  } */

  /* .section--s-scroll::before {
    background-image: url('assets/magnolis--mobile-slide-in-top.webp');
  } */

  /* .section--s-scroll .section-container {
    background-image: url('assets/magnolis--mobile-slide-in.webp');
  } */

  /* .page-template-page-over-ons .section-wrapper::before {
    background-image: url('assets/magnolis--mobile-bg-2.webp');
  } */

  /* Inzichten */
  /* .page-template-page-inzichten .section--hero {
    background-image: url('assets/magnolis--mobile-hero-2.webp');
  } */

  /* .page-template-page-inzichten .section-wrapper::before {
    background-image: url('assets/magnolis--mobile-hero-2.webp');
  } */

  /* Contact */
  /* .page-template-page-contact .section--hero {
    background-image: url('assets/magnolis--mobile-horizontal.webp');
  } */

  /* .page-template-page-contact .section--form {
    background-image: url('assets/magnolis--mobile-horizontal.webp');
  } */

  /* Footer */
  /* The wrappers are z-index: 1 stacking contexts, so their sticky background
     pseudo still paints once the footer has scrolled into view. The footer sits
     after them with no z-index of its own, so lift it clear. */
  .footer {
    position: relative;
    z-index: 2;
    background-image: url('assets/magnolis--mobile-footer.webp');
  }

  /* Same problem, same fix: third-party banners render as bare <body> children
     after the footer with no z-index, so the pseudo's overhang buries them.
     Add any other injected banner here — they must stay readable. */
  .otgs-development-site-front-end {
    position: relative;
    z-index: 2;
  }

  /* Menu */
  /* .burger-menu-container {
    background-image: url('assets/magnolis--mobile-bg-menu.webp');
  } */
}




/* ---------------------------------------------------------------- Popup */
body:has(.popup--open) {
  overflow: hidden;
}

.popup {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--spacing-md);
}

.popup[hidden] {
  display: none;
}

.popup-overlay {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  opacity: 0;
  transition: opacity var(--dur-md) ease;
}

.popup-card {
  position: relative;
  width: 100%;
  max-width: var(--max-w-sm);
  padding: var(--spacing-2xl);
  color: var(--color-light);
  display: flex;
  background-image: url('assets/magnolis--bg-popup.webp');
  background-size: cover;
  background-repeat: no-repeat;
  background-position: top center;
  opacity: 0;
  transition: opacity var(--dur-md) ease;
}

.popup-card * {
  color: currentColor;
  margin: 0;
}

.popup--open .popup-overlay {
  opacity: 1;
}

.popup--open .popup-card {
  opacity: 1;
  transform: translateY(0);
}

.popup-close {
  position: absolute;
  top: var(--spacing-lg);
  right: var(--spacing-xl);
  padding: var(--spacing-xs);
  background: none;
  border: none;
  cursor: pointer;
}

.popup-close svg {
  width: 1rem;
  height: 1rem;
}

.popup-body {
  height: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--spacing-lg);

}

.popup-body .wp-block-heading {
  font-size: var(--text-lg-plus);
}

/* .popup-body .wp-block-column:nth-child(odd) .with-icon a {
  margin-left: 0;
} */

/* .popup-body .wp-block-column {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-md);
} */

/* .popup-body p {
  margin: 0;
} */

/* CF7 form: reuses the global field styling (underline + floating label).
   The global multi-field gap is too large here, and the column's contact-page
   negative margin must not leak in. */
.popup form {
  gap: var(--spacing-lg);
}

.popup .wp-block-column:has(.wpcf7) {
  margin-top: 0;
}

/* The .grid--1 that holds the email + submit lays them out on one underline
   row, with the submit rendered as an inline chevron arrow. */
.popup .grid:has(input[type="submit"]) {
  display: flex;
  align-items: flex-end;
  gap: var(--spacing-md);
}

.popup .grid:has(input[type="submit"]) br {
  display: none;
}

.popup .grid:has(input[type="submit"]) .wpcf7-form-control-wrap {
  flex: 1;
}

.popup .grid input[type="submit"] {
  flex-shrink: 0;
  min-width: 0;
  /* opt out of the contact-grid's `min-width: 100%` */
  width: var(--text-xs);
  height: var(--text-xs);
  margin-bottom: var(--spacing-xs);
  padding: 0;
  border: 0;
  background-color: currentColor;
  -webkit-mask: url('svgs/magnolis--chevron-right.svg') center / contain no-repeat;
  mask: url('svgs/magnolis--chevron-right.svg') center / contain no-repeat;
  font-size: 0;
  color: inherit;
  cursor: pointer;
}

.popup-body .wpcf7-response-output {
  margin: var(--spacing-md) 0 0;
  padding: var(--spacing-sm) 0 0;
  border: 0;
  font-size: var(--text-xs);
}


/* ================================================================
   Responsive — contact pair (≤1260px). Desktop-first override.

   The two advisers sit in a nested wp-block-columns whose width works out
   to (viewport - 264px) / 2, so each address gets barely half the gutter-
   less width. mieke.vanzandweghe@magnolis.be is the longer of the two and
   starts wrapping mid-address at 1243px. Stacking them keeps each address
   on one line; the breakpoint sits just above the measured wrap so a
   slightly wider address still clears it.

   Contact only — the landing page carries these addresses in the footer
   menu, not in this block.
   ================================================================ */
@media (max-width: 1260px) {

  .page-template-page-contact .section-container--hero>.wp-block-columns>.wp-block-column>.wp-block-columns {
    flex-direction: column;
    gap: var(--spacing-lg);
  }

  /* WP gives each column flex-basis: 0; stacked that collapses them, so
     let content set the height. */
  .page-template-page-contact .section-container--hero>.wp-block-columns>.wp-block-column>.wp-block-columns>.wp-block-column {
    flex-basis: auto;
  }
}


/* ================================================================
   Responsive — tablet (≤1024px). Desktop-first overrides.

   .nav is a 390/195/390 grid, so .nav--right gets 2/5 of the content
   width and the appointment button is the only child that can give way.
   It never loses its side padding — the label wraps to two lines
   instead — and that happens at 992px in EN, ~952px in NL. Hiding at
   1024px clears the wider of the two with room for a longer label in a
   third language; the same link stays reachable in the burger menu.
   ================================================================ */
@media (max-width: 1024px) {

  /* ── Header / nav ── */
  .header .nav .button--appointment {
    display: none;
  }

  /* ── Form ── */
  /* Beside the submit the acceptance text is down to ~95px and breaks
     mid-word, so stack the two instead of squeezing them onto one row.
     The row gap is sized for side-by-side columns; stacked it reads as a
     gulf between the consent line and its submit, so tighten it. */
  .form-footer {
    flex-direction: column;
    gap: var(--spacing-lg);
  }
}


/* ================================================================
   Responsive — mobile (≤768px). Desktop-first overrides.

   Type already scales fluidly via clamp(), so this block only handles
   layout reflow, gutters and vertical rhythm. The pinned / horizontal
   scroll choreography (h-scroll, s-scroll, h-o-scroll, c-swiper) is
   disabled in js/script.js via gsap.matchMedia(MQ_DESKTOP) — that file's
   BP_MOBILE constant is the other half of this breakpoint, so change both
   together, and keep both in px (an em breakpoint would drift with the
   browser's default font size while the JS side would not).
   here we undo the desktop pin layout so content flows as plain stacks.
   ================================================================ */
@media (max-width: 768px) {

  /* ── Popup ── */
  .popup-card {
    padding: var(--spacing-2xl) var(--spacing-lg);
  }

  .popup-close {
    top: var(--spacing-lg);
    right: var(--spacing-md-plus);
  }

  /* ── Video ── */
  .video-play {
    --size-play: var(--spacing-lg-plus);
  }

  /* ── Header / nav ── */
  .header {
    top: var(--spacing-md);
  }

  .header-container {
    padding-inline: var(--spacing-md);
  }

  /* Mobile header keeps only the burger on the right — the appointment
     button is already hidden by the ≤1024px block above. */
  #menu-language-menu {
    display: none;
  }

  .burger-label {
    display: none;
  }

  .burger-icon {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    width: 22px;
    transition: gap var(--dur-md) var(--dur-md) ease;
  }

  .burger-line {
    display: block;
    height: 1.4px;
    width: 100%;
    background: currentColor;
    transition: transform var(--dur-md) ease, width var(--dur-md) ease;
  }

  .header:has(.burger-menu-container.open) .burger-icon {
    gap: 0px;
    transition: gap var(--dur-md) ease; 
  }

  .header:has(.burger-menu-container.open) .burger-line:first-child,
  .header:has(.burger-menu-container.open) .burger-line:last-child {
    width: 16px;
    transition: transform var(--dur-md) var(--dur-md) ease, width var(--dur-md) var(--dur-md) ease;
  }

  .header:has(.burger-menu-container.open) .burger-line:first-child {
    transform: rotate(45deg);
  }

  .header:has(.burger-menu-container.open) .burger-line:last-child {
    transform: translateY(-1.5px) rotate(-45deg);
  }

  /* suppress desktop SVG close icon on mobile */
  .header:has(.burger-menu-container.open) .burger-button::before {
    display: none;
  }

  /* ── Burger overlay: cascade flows left → center (item 4 anchors at center) ── */
  .burger-menu {
    justify-content: center;
    padding-inline: var(--spacing-lg);
  }

  .burger-menu .menu {
    justify-content: center;
    gap: var(--spacing-lg-plus);
  }

  .burger-menu .menu-item {
    gap: var(--spacing-sm);
  }

  .burger-menu .menu-item-counter {
    margin-top: var(--spacing-xs);
    font-size: var(--text-xs);
  }

  .burger-menu .menu-item a {
    font-size: var(--text-2xl);
  }

  .burger-menu .menu-item:nth-child(n) {
    margin-left: 0;
  }

  .burger-menu .menu-item:nth-child(1) {
    justify-content: flex-start;
  }

  .burger-menu .menu-item:nth-child(2) {
    justify-content: center;
  }

  .burger-menu .menu-item:nth-child(3) {
    justify-content: flex-end;
  }

  .burger-menu .menu-item:nth-child(4) {
    justify-content: center;
    row-gap: var(--spacing-lg-plus);
  }

  /* Contact item: counter + label on one row, the appointment button wraps
     to a full-width row beneath (the .menu-item is already display:flex). */
  .menu-item.contact {
    flex-wrap: wrap;
  }

  .menu-item.contact .button-container {
    flex-basis: 100%;
    margin-left: 0;
    justify-content: center;
  }

  .lang-switch--mobile {
    display: block;
    position: absolute;
    bottom: var(--spacing-lg);
    left: var(--spacing-md);
  }

  /* Flatten the WPML structure: current lang (top-level a) + others (sub-menu)
     all in one row inside the single li.wpml-ls-menu-item */
  #menu-language-menu-mobile {
    display: flex;
  }

  #menu-language-menu-mobile .wpml-ls-menu-item {
    display: flex;
    align-items: center;
    gap: var(--spacing-md);
  }

  #menu-language-menu-mobile .sub-menu {
    position: static;
    display: flex;
    align-items: center;
    gap: var(--spacing-md);
    padding-top: 0;
    pointer-events: auto;
  }

  /* Inactive languages */
  #menu-language-menu-mobile .sub-menu li {
    opacity: var(--opacity-muted);
    transform: none;
    transition: none;
  }

  /* Active language: full opacity, no chevron */
  #menu-language-menu-mobile .wpml-ls-menu-item>a {
    opacity: 1;
  }

  #menu-language-menu-mobile .wpml-ls-menu-item>a::after {
    display: none;
  }

  /* Lang code display (same as desktop) */
  #menu-language-menu-mobile .wpml-ls-native {
    font-size: 0;
  }

  #menu-language-menu-mobile .wpml-ls-native::before {
    content: attr(lang);
    font-size: var(--text-sm);
    text-transform: uppercase;
    letter-spacing: 0.05em;
  }

  #menu-language-menu-mobile .wpml-ls-display {
    display: none;
  }

  /* ── Section gutters & vertical rhythm ── */
  .section-container,
  .footer-container {
    padding-inline: var(--spacing-md);
  }

  .section-container>div {
    padding-block: var(--spacing-xl);
  }

  .section-container:first-of-type>div,
  .section-container:first-of-type>div.c-swiper {
    padding-top: var(--spacing-2xl);
  }

  .section-container:last-of-type>div {
    padding-bottom: var(--spacing-2xl);
  }

  /* Desktop zeroes the block padding on the wrapper's first section because the
     pinned v-swiper supplies its own 100svh frame. Stacked on mobile there is no
     frame, so restore the first-of-type spacing the rules above would have given
     it (that .home rule outranks them outside a media query too). Same :has()
     as the desktop rule, so the pair stays matched. */
  .home .section-wrapper .section-container:first-of-type:has(.v-swiper)>div {
    padding-block: var(--spacing-2xl);
  }

  .section-container>div.cazimir {
    padding-block: var(--spacing-2xl);
  }

  /* .section-container:has(.are-vertically-aligned-center) {
    min-height: auto;
  } */

  /* Desktop insets content by --spacing-xl per side; go full width on mobile. */
  div.t-reveal--group {
    max-width: 100%;
  }

  /* .section-container--contact>div {
    max-width: 100%;
  } */

  /* ── Columns → single-column stacks ── */
  /* Force every content column full width, overriding is-not-stacked-on-mobile. */
  .section-wrapper .wp-block-columns {
    flex-wrap: wrap;
    gap: var(--spacing-md);
  }

  .section-wrapper .wp-block-columns>.wp-block-column {
    flex-basis: 100% !important;
  }

  .section-container>.wp-block-columns {
    gap: var(--spacing-lg);
  }

  /* .section-container--contact>.wp-block-columns {
    grid-template-columns: 1fr;
  } */

  /* Custom grid system → single column. */
  .grid--2,
  .grid--3,
  .grid--4 {
    grid-template-columns: 1fr;
  }


  .team>.wp-block-column>.wp-block-columns>.wp-block-column {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--spacing-md);
    align-items: start;
    /* Team page has a nested 2-column layout for each member (image + text), which becomes a single column on mobile. To avoid the image and text stacking in a weird order, we switch to a 2-column grid with centered items, so the image and text sit side by side but still centered within the full width. */
  }

  .team .wp-block-group__inner-container {
    margin-top: var(--spacing-md);
  }

  .team .wp-block-group__inner-container .has-text-align-center {
    text-align: left;
  }

  .team .wp-block-image {
    margin-bottom: 0;
  }

  /* Drop the desktop odd-column icon-link indent. */
  .cazimir .wp-block-image,
  .wp-block-column:nth-child(odd) .with-icon a {
    margin-left: 0;
  }

  .section-container:has(.cazimir) {
    display: grid;
    padding-block: var(--spacing-2xl);
    /* gap: var(--spacing-3xl); */
  }

  .section-container .cazimir {
    display: contents;
  }

  /* Parent is display:contents on mobile, so its ::before would anchor to the
     section-container. Move the texture onto the first (image) column instead. */
  .cazimir::before {
    content: none;
  }

  .cazimir .wp-block-image {
    max-width: 40%;
    margin: auto;
  }

  /* Parent is display:contents, so the columns are grid items and the image
     one is empty — zero height. An absolutely positioned pseudo has no box to
     sit in: the desktop rule's `top: 50%` resolves against 0 and its
     translateY(-50%) then pulls the pseudo up by half its own height, so the
     lower half lands on the heading below. Paint the texture on the column
     itself instead — it takes a real grid row and nothing can overlap. */
  .cazimir>.wp-block-column:first-child {
    position: relative;
    margin-left: calc(var(--spacing-lg) * -1);
    aspect-ratio: 4 / 3;
    background-image: url(assets/magnolis--cazimir-2-2.webp);
    background-size: 100% auto;
    background-repeat: no-repeat;
    background-position: bottom left;
  }


  /* .cazimir>.wp-block-column:first-child::before {
    content: '';
    position: absolute;
    top: calc(var(--spacing-xl) * -1);
    left: calc(var(--spacing-lg) * -1);
    width: 95svw;
    aspect-ratio: 4 / 3;
    background-image: url(assets/magnolis--texture-bg-cazimir.webp);
    background-size: 100% 100%;
  } */

  /* Superseded by the column background above. Killed explicitly because the
     unscoped desktop rule at .cazimir .wp-block-column:empty::before still
     matches at this width. */
  .cazimir>.wp-block-column:first-child::before {
    content: none;
  }


  /* LinkedIn block (home): design order is heading → embed → link, but the
     heading + link share one column while the embed sits in the next. Flatten
     the text column with display:contents so all three become flex siblings,
     then reorder. Desktop layout and the DB block stay untouched.
     Hook: `block--linkedin` class added to the Columns block in the editor. */

  .section-container:has(.are-vertically-aligned-center):has(.block--linkedin) {
    min-height: auto;
  }

  /* Tighter than the --spacing-lg every other stacked columns block gets: the
     flattened column above makes heading / embed / link direct flex siblings,
     so this gap is the spacing *within* one component, not between blocks. */
  .section-container>.wp-block-columns.block--linkedin {
    gap: var(--spacing-md);
  }

  .section-container>.wp-block-columns.block--linkedin * {
    margin: 0;
  }

  .block--linkedin>.wp-block-column {
    flex-basis: auto !important;
  }

  .block--linkedin>.wp-block-column:first-child {
    display: contents;
  }

  .block--linkedin .wp-block-heading {
    order: 1;
  }

  .block--linkedin>.wp-block-column:last-child {
    order: 2;
  }

  .block--linkedin .with-icon {
    order: 3;
  }

  /* The embed carries a fixed width="504" attribute, wider than the column. */
  .block--linkedin iframe {
    width: 100%;
  }

  /* ── Scroll / sticky sections → static vertical stacks ── */
  .section--s-scroll .section-container,
  .section--h-o-scroll .section-container,
  .section:has(.h-scroll) .section-container {
    min-height: 0;
    min-width: 0;
    display: block;
  }



  .section-container--h-scroll,
  .h-scroll {
    min-height: 100svh;
  }

  /* Horizontal-scroll panels stack vertically. */
  .h-scroll {
    display: flex;
    flex-direction: column;
  }

  .h-scroll>div {
    min-width: 0;
    width: 100%;
  }

  /* Full-bleed video on mobile. Desktop gives it a --spacing-lg margin so it
     can't butt against the neighbouring panel in the horizontal strip, but the
     panels stack here — the margin only costs width, and --max-w-lg caps it
     well below the phone's. */
  .h-scroll .wp-block-video {
    margin: 0;
    max-width: 100%;
  }

  /* Desktop's --spacing-lg inset is ~1/5 of a phone's width, so the caption
     stretches across the media instead of sitting in its corner. */
  .h-scroll .wp-block-image figcaption,
  .h-scroll .wp-block-video figcaption {
    padding: var(--spacing-md-plus);
    gap: var(--spacing-md);
  }

  .wp-block-gallery .swiper-slide {
    padding-inline: var(--spacing-lg);
  }

  /* Case swiper isn't restructured on mobile — render its slides as a stack. */
  .c-swiper>div {
    display: grid;
    gap: var(--spacing-xl);
  }

  .c-swiper>div>.wp-block-columns .wp-block-column:has(.wp-block-image) {
    order: -1;
  }

  .c-swiper {
    grid-template-columns: 1fr;
  }

  /* Home vertical swiper isn't restructured on mobile (the .v-swiper-left /
     -sketches / -right tracks are never built), but the .v-swiper class is
     authored on the block so its desktop grid still lands. Undo the pinned
     one-viewport frame and render the slides as a stack. */
  .v-swiper {
    grid-template-columns: 1fr;
    grid-template-rows: auto;
    gap: var(--spacing-2xl);
    height: auto;
    clip-path: none;
  }

  /* Each slide stacks. Order is set per column POSITION, not per content, so it
     survives the editor flipping which side the text sits on. */
  /* .v-swiper>.wp-block-column>.wp-block-columns {
    display: grid;
    gap: var(--spacing-xl);
  } */

  /* Portrait photo (the edge column holding a figure) is dropped on mobile —
     only the text and the centre sketch remain. Targeted by column POSITION so
     it survives the editor flipping which side the text sits on; the sketch is
     always the middle column, so it is never matched. */
  .v-swiper>.wp-block-column>.wp-block-columns>.wp-block-column:first-child:has(figure),
  .v-swiper>.wp-block-column>.wp-block-columns>.wp-block-column:last-child:has(figure) {
    display: none;
  }

  /* Undo the desktop 100svh-tall, width:auto portrait sizing. */
  .v-swiper figure {
    margin: 0;
  }

  .v-swiper figure img {
    display: block;
    width: 100%;
    height: auto;
  }

  /* Sketch first on mobile, same as .c-swiper and the over-ons s-scroll. The
     portrait photos are the only other figure columns and they're hidden above,
     so the centre illustration is all this can match. */
  .v-swiper>.wp-block-column>.wp-block-columns>.wp-block-column:has(.wp-block-image) {
    order: -1;
  }

  /* "Lees meer" keeps a collapsed footprint on desktop so expanding it can't
     reflow the pinned grid. No pin here, so let it push content down instead.
     The summary stays ordered last. */
  .v-swiper .wp-block-details {
    height: auto;
  }

  /* Stepped "samenwerking" list: scroll-driven focus on mobile.
     JS adds .is-active to the step currently in view; others stay dimmed. */
  .section-container--h-o-scroll>.wp-block-columns>.wp-block-column>.wp-block-columns>.wp-block-column>.wp-block-columns>.wp-block-column {
    opacity: 0.25;
    transition: opacity 0.3s ease;
  }

  .section-container--h-o-scroll>.wp-block-columns>.wp-block-column>.wp-block-columns>.wp-block-column>.wp-block-columns>.wp-block-column.is-active {
    opacity: 1;
  }

  /* Scroll-progress separator (mobile): same two-layer mechanism as desktop,
     rotated. A dim vertical track (::before) with a bright fill (::after) that
     draws in top-to-bottom over it as the steps light up. --line-progress
     (0..1) is driven by JS. Both sit on the level-5 column (reliable
     containing block — its height = steps content height); the desktop
     ::before is horizontal, so its width/height/mask are overridden here. */
  .section-container--h-o-scroll>.wp-block-columns>.wp-block-column>.wp-block-columns>.wp-block-column {
    position: relative;
  }

  .section-container--h-o-scroll>.wp-block-columns>.wp-block-column>.wp-block-columns>.wp-block-column::before,
  .section-container--h-o-scroll>.wp-block-columns>.wp-block-column>.wp-block-columns>.wp-block-column::after {
    content: '';
    display: block;
    position: absolute;
    left: 0;
    top: var(--spacing-xl);
    bottom: 0;
    width: var(--spacing-xs);
    height: auto;
    -webkit-mask-image: url('svgs/magnolis--separator-full-vertical.svg');
    mask-image: url('svgs/magnolis--separator-full-vertical.svg');
    mask-repeat: no-repeat;
    mask-size: 100% 100%;
    background-color: currentColor;
  }

  /* Dim track — always visible. */
  .section-container--h-o-scroll>.wp-block-columns>.wp-block-column>.wp-block-columns>.wp-block-column::before {
    opacity: 0.2;
  }

  /* Bright fill — overlays the track, revealed by scroll progress. */
  .section-container--h-o-scroll>.wp-block-columns>.wp-block-column>.wp-block-columns>.wp-block-column::after {
    clip-path: inset(0 0 calc((1 - var(--line-progress, 0)) * 100%) 0);
  }

  /* Tighten step gap and indent steps away from the separator. */

  .section-container--h-o-scroll {
    padding-inline: var(--spacing-lg);
  }

  .section-container--h-o-scroll>.wp-block-columns>.wp-block-column>.wp-block-columns>.wp-block-column>.wp-block-columns {
    gap: var(--spacing-xl);
    padding-left: var(--spacing-lg);
  }

  /* ── Contact / map ── */
  .section--form {
    height: auto;
    min-height: 100svh;
  }

  .section--map .section-container {
    width: 100%;
    padding-inline: 0;
  }

  /* The desktop pill is 8rem — a third of a 390px viewport, and three of them
     now crowd the frame. Scaled to 5rem at the same 3.2:1 ratio so the SVG
     doesn't distort. Stays under MAP_CONFIG['padding'] (72px) at half-width,
     so fitBounds still clears the outermost marker. */
  .map-marker {
    width: 5rem;
    height: 1.5625rem;
  }

  /* ── Separator ── */
  .page-template-page-aanpak .section-container--hero>.wp-block-columns>.wp-block-column::after,
  .page-template-page-over-ons .section-container--hero>.wp-block-columns>.wp-block-column::after,
  nav.wp-block-navigation.items-justified-center::after {
    max-width: 75%;
    -webkit-mask-size: 100%;
    mask-size: 100%;
  }

  /* ── Logo ── */
  .logo--full svg,
  .footer-logo svg:last-of-type {
    max-width: var(--spacing-2xl);
  }

  .logo--mono svg,
  .footer-logo svg:first-of-type {
    max-width: var(--spacing-md);
  }

  .footer-logo {
    gap: var(--spacing-md-plus);
  }

  /* ── Typography ── */
  :root {
    --text-xl: clamp(1.375rem, 1rem + 1.5vw, 1.75rem);
    --text-2xl: clamp(1.625rem, 1.2rem + 2vw, 2.25rem);
  }

  .home .section--hero .wp-block-heading {
    font-size: var(--text-lg-xl);
  }

  .section--hero .wp-block-heading {
    font-size: var(--text-xl);
  }

  /* ── Over-ons s-scroll: accordion ── */
  .section--s-scroll .wp-block-column .wp-block-heading {
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
    margin-bottom: var(--spacing-md);
    margin-top: var(--spacing-md);
  }

  .section--s-scroll .wp-block-column .wp-block-heading::before {
    content: '';
    display: inline-block;
    flex-shrink: 0;
    width: var(--text-xs);
    height: var(--text-xs);
    -webkit-mask-image: url('svgs/magnolis--plus.svg');
    mask-image: url('svgs/magnolis--plus.svg');
    mask-size: contain;
    mask-repeat: no-repeat;
    mask-position: center;
    background-color: currentColor;
    transition: transform var(--dur-md) ease;
  }

  .section--s-scroll .wp-block-column.is-open .wp-block-heading::before {
    -webkit-mask-image: url('svgs/magnolis--minus.svg');
    mask-image: url('svgs/magnolis--minus.svg');
  }

  .section--s-scroll .accordion-body {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows var(--dur-md) ease;
  }

  .section--s-scroll .accordion-body>div {
    overflow: hidden;
  }

  .section--s-scroll .wp-block-column.is-open .accordion-body {
    grid-template-rows: 1fr;
  }


  /* ── Over-ons s-scroll: image first on mobile ── */
  .page-template-page-over-ons .section--s-scroll .wp-block-column:has(.wp-block-image),
  .page-template-page-over-ons .section--s-scroll .wp-block-column:has(.wp-block-video) {
    order: -1;
  }

  /* ── Over-ons s-scroll: nav items always inline, no overlay ── */
  .page-template-page-over-ons .section--s-scroll .wp-block-navigation__responsive-container-open svg,
  .page-template-page-over-ons .section--s-scroll .wp-block-navigation__responsive-close svg {
    display: none;
  }



  .section--s-scroll .wp-block-navigation {
    align-items: flex-start;
  }

  .page-template-page-over-ons .section--s-scroll .wp-block-navigation__responsive-container {
    display: block;
    position: static;
    height: auto;
    overflow: visible;
    background: transparent;
    padding: 0;
    inset: auto;
  }

  .page-template-page-over-ons .section--s-scroll .wp-block-navigation__responsive-dialog {
    position: static;
  }

  /* ── Footer ── */
  .footer-container {
    gap: var(--spacing-2xl);
  }

  .footer .grid--4 {
    grid-template-columns: 1fr 1fr;
  }

  .footer .grid--4>ul:last-of-type {
    text-align: left;
  }

  .footer .inner-container:last-of-type {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--spacing-lg);
  }

}