/*
 * Styles for the theme's ACF blocks.
 * Everything expressible in theme.json lives there; this file covers only
 * layout that presets cannot describe (carousel grid, timeline, whale tail).
 */

/* ---------- Fiche d'identité ---------- */
.beluga-identite { margin: 0 0 var(--wp--preset--spacing--50); }
.beluga-identite__row { display: flex; gap: .5ch; font-size: var(--wp--preset--font-size--small); }
.beluga-identite dt { font-weight: 600; }
.beluga-identite dt::after { content: " :"; }
.beluga-identite dd { margin: 0; }

/* ---------- Carrousel ---------- */
.beluga-carousel { display: grid; grid-template-columns: 5rem 1fr; gap: var(--wp--preset--spacing--40); }
.beluga-carousel__thumbs { display: flex; flex-direction: column; gap: var(--wp--preset--spacing--30); }
.beluga-carousel__thumb { display: block; border-radius: 12px; overflow: hidden; line-height: 0; opacity: .6; transition: opacity .2s; outline-offset: 2px; }
.beluga-carousel__thumb:hover,
.beluga-carousel__thumb:focus-visible,
.beluga-carousel__thumb.is-active { opacity: 1; }
.beluga-carousel__thumb img { width: 100%; height: auto; aspect-ratio: 4/3; object-fit: cover; }
.beluga-carousel__main { margin: 0; }
.beluga-carousel__main img { width: 100%; height: auto; border-radius: 16px; }
.beluga-carousel__main figcaption { margin-top: var(--wp--preset--spacing--30); font-size: var(--wp--preset--font-size--small); color: var(--wp--preset--color--grey); }

/* No-JS: every slide is visible and stacked, so nothing is unreachable.
	The script adds [data-enhanced] and only then do we hide inactive slides. */
.beluga-carousel__slide + .beluga-carousel__slide { margin-top: var(--wp--preset--spacing--40); }
[data-enhanced] .beluga-carousel__slide { display: none; margin-top: 0; }
[data-enhanced] .beluga-carousel__slide.is-active { display: block; }

@media (max-width: 781px) {
	.beluga-carousel { grid-template-columns: 1fr; }
	.beluga-carousel__thumbs { flex-direction: row; overflow-x: auto; }
	.beluga-carousel__thumb { flex: 0 0 4.5rem; }
}

/* ---------- Historique des observations ---------- */
.beluga-timeline { padding-block: var(--wp--preset--spacing--60); }
.beluga-timeline__track { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--wp--preset--spacing--40); list-style: none; margin: 0; padding: 0; position: relative; }
.beluga-timeline__track::before { content: ""; position: absolute; inset-inline: 0; top: .45rem; height: 2px; background: var(--wp--preset--color--primary-light); }
.beluga-timeline__item { position: relative; display: flex; flex-direction: column; align-items: center; gap: var(--wp--preset--spacing--30); }
.beluga-timeline__dot { width: 1rem; height: 1rem; border-radius: 100px; background: var(--wp--preset--color--base); border: 2px solid var(--wp--preset--color--contrast); }
.beluga-timeline__item.is-observed .beluga-timeline__dot { background: var(--wp--preset--color--contrast); }
.beluga-timeline__year { font-size: var(--wp--preset--font-size--small); }
.beluga-timeline__legend { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: .5ch var(--wp--preset--spacing--40); margin-top: var(--wp--preset--spacing--50); font-size: var(--wp--preset--font-size--small); }
.beluga-timeline__key { width: .75rem; height: .75rem; border-radius: 100px; border: 2px solid var(--wp--preset--color--contrast); display: inline-block; }
.beluga-timeline__key.is-observed { background: var(--wp--preset--color--contrast); }

/* ---------- Dernières nouvelles ---------- */
.beluga-accordion__item { border-bottom: 1px solid var(--wp--preset--color--primary-light); }
.beluga-accordion__summary { cursor: pointer; font-weight: 600; padding: var(--wp--preset--spacing--50) 0; list-style: none; display: flex; justify-content: space-between; align-items: center; gap: var(--wp--preset--spacing--40); }
.beluga-accordion__summary::-webkit-details-marker { display: none; }
.beluga-accordion__summary::after { content: "⌄"; transition: transform .2s; }
.beluga-accordion__item[open] .beluga-accordion__summary::after { transform: rotate(180deg); }
.beluga-accordion__body { padding-bottom: var(--wp--preset--spacing--50); }

/* ---------- Participez à l'adoption ---------- */
.beluga-progression { display: grid; grid-template-columns: 1fr 1fr; align-items: center; gap: var(--wp--preset--spacing--70); padding-block: var(--wp--preset--spacing--80); }
.beluga-progression__eyebrow { font-size: var(--wp--preset--font-size--small); margin: 0 0 var(--wp--preset--spacing--30); }
.beluga-progression__title { margin: 0 0 var(--wp--preset--spacing--40); }
.beluga-progression__cta { border: 0; border-radius: 100px; padding: .75rem 1.5rem; font: inherit; font-weight: 500; cursor: pointer; background: var(--wp--preset--color--primary); color: var(--wp--preset--color--contrast); }
.beluga-progression__cta:hover { background: var(--wp--preset--color--primary-dark); color: var(--wp--preset--color--base); }
.beluga-progression__meter { position: relative; display: grid; place-items: center; background: var(--wp--preset--color--surface); border-radius: 16px; padding: var(--wp--preset--spacing--60); }

/* The fluke silhouette is the authentic asset from the source site
   (assets/images/baleine-adopt.png), re-exported with its alpha inverted so it
   works as a CSS mask: the mask makes only the fluke visible, and a hard-stop
   gradient underneath fills it bottom-up to --beluga-fill. */
.beluga-progression__tail { position: relative; width: min(20rem, 100%); aspect-ratio: 643 / 941; }
.beluga-progression__tail::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to top,
    var(--wp--preset--color--primary) 0 var(--beluga-fill),
    var(--wp--preset--color--base) var(--beluga-fill) 100%
  );
  -webkit-mask: url("../img/queue-baleine-mask.png") no-repeat center / contain;
  mask: url("../img/queue-baleine-mask.png") no-repeat center / contain;
}
.beluga-progression__tail img { display: none; }

.beluga-progression__number {
  position: absolute;
  /* block, not grid/flex: those would make the "%" a sibling item and stack it
     under the number instead of keeping it an inline superscript. */
  display: block;
  text-align: center;
  line-height: 9rem;
  width: 9rem;
  height: 9rem;
  border-radius: 100px;
  border: 3px solid var(--wp--preset--color--primary);
  background: var(--wp--preset--color--base);
  font-size: var(--wp--preset--font-size--xx-large);
  font-weight: 600;
  margin: 0;
}
.beluga-progression__number sup { font-size: .5em; }

.beluga-progression__modal { border: 0; border-radius: 16px; padding: var(--wp--preset--spacing--60); max-width: 32rem; }
.beluga-progression__modal::backdrop { background: rgb(0 0 0 / .5); }
.beluga-progression__close { float: right; border: 0; background: none; font-size: 1.5rem; cursor: pointer; }

@media (max-width: 781px) {
	.beluga-progression { grid-template-columns: 1fr; }
}

/* ---------- Centre d'adoption: frame gaps ---------- */
/* Every value below is transcribed from the approved frames — desktop
   10372:9158, mobile 10372:8745. The site block gap (24px) was standing in for
   all of them, which is what made the hero, the section head, the card grid and
   the pagination read tighter than the design at both breakpoints. Selectors are
   qualified with the block class because core's .wp-container-* layout rules
   have equal specificity and later source order. */

/* Hero copy: eyebrow -> h1 is 16 (12 mobile), h1 -> lead is 24 (20). */
.wp-block-group.beluga-hero-copy > * + * { margin-block-start: 24px; }
.wp-block-group.beluga-hero-copy > h1 { margin-block-start: 16px; }

/* Frame "Portfolio / 13 /" is ONE band: pad 80/64 desktop, 64/20 mobile, with
   80 between the section head, the filter row and the grid. */
.wp-block-group.beluga-portfolio {
  padding-block: 80px;
  padding-inline: clamp(20px, 5vw, 64px);
}
.wp-block-group.beluga-portfolio > * + * { margin-block-start: 80px; }

/* Section head: tagline -> h2 is 16 (12 mobile), h2 -> lead is 24 (20). */
.wp-block-group.beluga-section-head > * + * { margin-block-start: 24px; }
.wp-block-group.beluga-section-head > h2 { margin-block-start: 16px; }

/* Frame "Row": 32 between columns, 64 between rows; stacked 48 on mobile. */
.wp-block-post-template.beluga-grid { gap: 64px 32px; }

/* Frame leaves 64 between the last card row and the numerals (40 mobile). */
.beluga-portfolio .wp-block-query-pagination { margin-block-start: 64px; }

@media (max-width: 781px) {
  .wp-block-group.beluga-hero-copy > * + * { margin-block-start: 20px; }
  .wp-block-group.beluga-hero-copy > h1 { margin-block-start: 12px; }
  .wp-block-group.beluga-portfolio { padding-block: 64px; }
  .wp-block-group.beluga-portfolio > * + * { margin-block-start: 48px; }
  .wp-block-group.beluga-section-head > * + * { margin-block-start: 20px; }
  .wp-block-group.beluga-section-head > h2 { margin-block-start: 12px; }
  .wp-block-post-template.beluga-grid { gap: 48px; }
  .beluga-portfolio .wp-block-query-pagination { margin-block-start: 40px; }
}

/* ---------- Centre d'adoption grid ---------- */
.beluga-card__meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--wp--preset--spacing--30); margin: 0; font-size: var(--wp--preset--font-size--small); }
/* The design's neutral, `grey` #808081. NOTE: 3.95:1 on white and 3.41:1 on the
   pale band, both under the 4.5:1 AA floor for text this size. Kept as designed
   by explicit decision — raise with the designer, do not darken it here. */
.beluga-card__id { color: var(--wp--preset--color--grey); }
/* Completes the frame's 24 between the tag row and the read-more (16 gap + 8). */
.beluga-card__meta { margin-bottom: 8px; }
/* Shape only. Colour lives with the per-status modifiers further down — keeping
   the fills here too meant the two blocks resolved by source order alone. */
.beluga-card__tag { display: inline-block; border-radius: 100px; }
.beluga-card .wp-block-post-title { margin-block: var(--wp--preset--spacing--20) 0; }

/* ---------- Pagination ---------- */
/* Approved frame: `1 - 2 - 3 - 4 - 5 ... 23`, centred, current page in teal,
   plain numerals with no underline and no prev/next text links. Core ships this
   as underlined links with no separators, so all of it is theme-side.
   Current page is the design's `primary` #66C0C1. NOTE: that is 2.13:1 on
   white, well under AA for text — kept as designed by explicit decision, raise
   with the designer rather than darkening it here. */
.wp-block-query-pagination { gap: 0.5rem; font-size: var(--wp--preset--font-size--large); }
.wp-block-query-pagination .page-numbers {
  color: var(--wp--preset--color--contrast);
  text-decoration: none;
}
.wp-block-query-pagination .page-numbers:hover { text-decoration: underline; }
.wp-block-query-pagination .page-numbers.current {
  color: var(--wp--preset--color--primary);
  text-decoration: none;
}
/* Dash between two adjacent numerals, but never touching the `...` gap marker:
   the first half excludes a dots predecessor, the second a dots self. */
.wp-block-query-pagination .page-numbers:not(.dots) + .page-numbers:not(.dots)::before {
  content: "–";
  margin-inline-end: 0.5rem;
  color: var(--wp--preset--color--grey);
}

/* ---------- Checklist (design uses a check glyph, not a bullet) ---------- */
.beluga-checklist { list-style: none; padding-left: 0; }
.beluga-checklist li { position: relative; padding-left: 1.75rem; margin-bottom: .5rem; }
.beluga-checklist li::before { content: "✓"; position: absolute; left: 0; color: var(--wp--preset--color--primary-dark); font-weight: 700; }
.has-deep-background-color .beluga-checklist li::before { color: var(--wp--preset--color--primary); }

/* ---------- Numbered steps (Processus d'adoption) ---------- */
/* (An earlier .beluga-step__num variant lived here. It was unused markup-wise
   but its margin-bottom stacked on .beluga-steps' grid gap — 32 + 32 = 64
   against the frame's 32 — and its padding-left indented every step by 64px.
   Removed 2026-08-20; the live rules are .beluga-step / .beluga-step__n.) */

/* ---------- FAQ accordion ---------- */
.beluga-faq .wp-block-details { border-bottom: 1px solid var(--wp--preset--color--primary-light); padding-block: var(--wp--preset--spacing--40); }
.beluga-faq .wp-block-details summary { cursor: pointer; font-weight: 600; list-style: none; }
.beluga-faq .wp-block-details summary::-webkit-details-marker { display: none; }

/* ---------- Stat blocks (À propos du GREMM) ---------- */
.beluga-stat { border-left: 1px solid rgb(1 2 3 / .15); padding-left: var(--wp--preset--spacing--60); }
.beluga-stat__num { font-weight: 700; line-height: 1; margin: 0 0 var(--wp--preset--spacing--30); }

/* ---------- Header ---------- */
/* Below the navigation breakpoint the CTA competes with the hamburger for
   space; hide it there — the overlay menu still reaches the same page. */
/* Between the nav breakpoint (600px) and ~900px the five inline links plus the
   CTA wrap onto a second row, making the header taller on tablet than on
   desktop. Drop the CTA there; the nav still reaches the same page. */
@media (max-width: 899px) {
  .wp-block-buttons.beluga-header-cta { display: none; }
}

@media (max-width: 599px) {
}

/* ---------- Mobile navigation overlay ---------- */
/* The CTA is a menu item so it exists inside the overlay; on desktop the
   header already shows the same button, so hide the duplicate there.
   Needs .wp-block-navigation-item too: core sets display:flex on that class,
   which outranks a bare .beluga-nav-cta selector. */
.wp-block-navigation-item.beluga-nav-cta { display: none; }

/* Between the nav breakpoint (600px) and ~900px the five inline links plus the
   CTA wrap onto a second row, making the header taller on tablet than on
   desktop. Drop the CTA there; the nav still reaches the same page. */
@media (max-width: 899px) {
  .wp-block-buttons.beluga-header-cta { display: none; }
}

@media (max-width: 599px) {
  .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
    align-items: flex-start;
    padding-top: var(--wp--preset--spacing--70);
  }
  .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container {
    gap: 0;
    width: 100%;
    /* The header nav is laid out justifyContent:right for desktop; that leaks
       into the overlay and pushes items off the right edge. */
    justify-content: flex-start;
    align-items: stretch;
    /* width:100% + padding on the same box overflows unless border-box. */
    box-sizing: border-box;
    padding-inline: var(--wp--preset--spacing--50);
  }
  .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content {
    justify-content: flex-start;
  }
  .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item {
    width: 100%;
    border-bottom: 1px solid var(--wp--preset--color--surface);
  }
  .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content {
    display: flex;
    align-items: center;
    /* 48px keeps every menu row a comfortable touch target. */
    min-height: 48px;
    font-size: 1.125rem;
  }
  .wp-block-navigation-item.beluga-nav-cta { display: block; border-bottom: 0; margin-top: var(--wp--preset--spacing--50); }
  .beluga-nav-cta .wp-block-navigation-item__content {
    justify-content: center;
    background: var(--wp--preset--color--primary);
    color: var(--wp--preset--color--contrast);
    border-radius: 100px;
    padding-inline: 1.5rem;
    font-weight: 500;
    text-decoration: none;
  }
}

/* ---------- Link contrast on dark bands ---------- */
/* The design's link teal (#51999A) is only 1.34:1 on the deep band, i.e.
   effectively invisible. The approved frames show pale links on dark sections
   anyway, so keep the light teal here (5.56:1) — this is a legibility floor,
   not the AA substitution that was reverted elsewhere. */
.has-deep-background-color a,
.has-contrast-background-color a {
  color: var(--wp--preset--color--primary-light);
}
.wp-block-cover a:not(.wp-block-button__link) {
  color: var(--wp--preset--color--primary-light);
}

/* ---------- Contact Form 7 ---------- */
/* CF7 ships almost no styling, so without this the form renders as raw browser
   inputs next to a fully designed page. */
/* Metrics below are taken from the approved frame's node tree
   (docs/design/nodes/nous-joindre.json), not eyeballed: inputs 48px tall with
   r=12 and a 1px #010203 stroke, textarea 180px, checkbox 18px r=4,
   submit 44px r=100 with 10/24 padding. */
.wpcf7-form p { margin-bottom: var(--wp--preset--spacing--50); }
.wpcf7-form label { display: block; font-weight: 400; margin-bottom: var(--wp--preset--spacing--20); }
.wpcf7-form input[type="text"],
.wpcf7-form input[type="email"],
.wpcf7-form input[type="tel"],
.wpcf7-form textarea {
  box-sizing: border-box;
  width: 100%;
  margin-top: var(--wp--preset--spacing--20);
  padding: .5rem .75rem;
  font: inherit;
  color: var(--wp--preset--color--contrast);
  background: var(--wp--preset--color--base);
  border: 1px solid var(--wp--preset--color--contrast);
  border-radius: 12px;
}
.wpcf7-form input[type="text"],
.wpcf7-form input[type="email"],
.wpcf7-form input[type="tel"] { height: 48px; }
.wpcf7-form textarea { min-height: 180px; padding: .75rem; resize: vertical; }
.wpcf7-form input:focus-visible,
.wpcf7-form textarea:focus-visible {
  outline: 2px solid var(--wp--preset--color--primary-dark);
  outline-offset: 1px;
  border-color: var(--wp--preset--color--primary-dark);
}
.wpcf7-form .wpcf7-acceptance label { display: flex; gap: .5rem; align-items: center; font-weight: 400; }
.wpcf7-form .wpcf7-acceptance input {
  appearance: none;
  flex: 0 0 auto;
  width: 18px; height: 18px; margin: 0;
  background: var(--wp--preset--color--base);
  border: 1px solid var(--wp--preset--color--contrast);
  border-radius: 4px;
  cursor: pointer;
}
.wpcf7-form .wpcf7-acceptance input:checked {
  background: var(--wp--preset--color--primary);
  border-color: var(--wp--preset--color--primary);
}
.wpcf7-form .wpcf7-list-item { margin: 0; }
.wpcf7-form .wpcf7-submit {
  border: 0;
  border-radius: 100px;
  min-height: 44px;
  padding: 10px 24px;
  font: inherit;
  font-weight: 500;
  cursor: pointer;
  background: var(--wp--preset--color--primary);
  color: var(--wp--preset--color--contrast);
}
.wpcf7-form .wpcf7-submit:hover {
  background: var(--wp--preset--color--primary-dark);
  color: var(--wp--preset--color--base);
}
.wpcf7-form .wpcf7-submit:disabled { opacity: .6; cursor: not-allowed; }
/* Validation + response messages: CF7's defaults are unreadable on this palette. */
.wpcf7-not-valid-tip { color: #b3261e; font-size: var(--wp--preset--font-size--small); margin-top: .35rem; }
.wpcf7-response-output {
  margin: var(--wp--preset--spacing--50) 0 0 !important;
  padding: .75rem 1rem !important;
  border-radius: 8px;
  border-width: 1px !important;
}

/* ---------- Nous joindre — contact column ---------- */
/* Geometry from the approved frame: icon 32px, heading→desc gap 16px,
   desc→value gap 8px, items 40px apart, two 280px columns then a 240px block. */
.beluga-contact-item + .beluga-contact-item { margin-top: var(--wp--preset--spacing--65); }
.beluga-contact-icon {
  display: block;
  width: 32px;
  height: 32px;
  color: var(--wp--preset--color--contrast);
  margin-bottom: var(--wp--preset--spacing--40);
  /* The wrapping group is a constrained-layout group, and core's
     `.is-layout-constrained > :where(:not(.alignleft)...)` rule sets
     `margin-left: auto !important; margin-right: auto !important`. Every other
     child is full-width so the centring is invisible, but this 32px block
     child gets pushed to the middle of the column — 124px in from the heading
     in the two-up row, 276px in the full-width one. !important is the only way
     to beat an !important, so it is deliberate here. */
  margin-left: 0 !important;
  margin-right: auto !important;
}
.beluga-contact-icon svg { display: block; width: 100%; height: 100%; }
.beluga-contact-item h3 { margin: 0 0 var(--wp--preset--spacing--40); }
.beluga-contact-item p { margin: 0; }
.beluga-contact-item p + p { margin-top: var(--wp--preset--spacing--20); }
.beluga-contact-value a { color: inherit; text-decoration: underline; }
.beluga-contact-row { margin-bottom: var(--wp--preset--spacing--65); }

/* The two columns are 616 / 584 in the design; let them stack early enough
   that the form never gets squeezed below a usable width. */
@media (max-width: 900px) {
  .beluga-contact-cols { flex-wrap: wrap; }
  .beluga-contact-cols > .wp-block-column { flex-basis: 100% !important; }
  .beluga-contact-cols > .wp-block-column + .wp-block-column { margin-top: var(--wp--preset--spacing--90); }
}

/* CTA card: 1280x317 at r=16 in the design, photo behind a dark scrim.
   Built as a group with a CSS background rather than wp:cover — hand-authored
   cover markup renders its inner container twice. */
.beluga-cta-card {
  position: relative;
  border-radius: 16px;
  overflow: hidden;
  min-height: 317px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* Photo is per-instance via --beluga-cta-image so one class serves all six
     cards. It must be the CLEAN photo: cta-faq.png was a flattened export of
     the whole design card — heading, body copy and both buttons baked into the
     bitmap, with the 40% scrim already burned in — so live text rendered on top
     of a ghost copy of itself, double-darkened. */
  background-image: var(--beluga-cta-image, url("../img/hero-don.jpg"));
  background-size: cover;
  background-position: center;
}
.beluga-cta-card::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgb(0 0 0 / .40);
}
.beluga-cta-card > * { position: relative; margin-block: 0; }
.beluga-cta-card > * + * { margin-top: var(--wp--preset--spacing--50); }
.beluga-cta-card .wp-block-buttons { margin-top: var(--wp--preset--spacing--60); }

/* ---------- Site logo ---------- */
/* The lockup is a raster asset (a placed image in Figma), shipped at 2x for a
   278x33 slot. Cap the height so the header band stays 92px as designed. */
.wp-block-site-logo img { display: block; height: auto; max-height: 33px; width: auto; }
.wp-block-site-logo a { display: block; line-height: 0; }

/* ---------- Footer ---------- */
/* Approved frame: 880 + 400 columns, link grid 480 wide wrapping at gap 30,
   newsletter input 280x40 r=12 with a white stroke, outline submit 104x44. */
.beluga-footer-main { gap: 0; }
.beluga-footer-main > .wp-block-column:first-child { display: flex; flex-direction: column; gap: var(--wp--preset--spacing--60); }
.beluga-footer-main > .wp-block-column:last-child { display: flex; flex-direction: column; gap: var(--wp--preset--spacing--40); }

.beluga-footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 30px;
  max-width: 480px;
  margin: 0;
}
.beluga-footer-links a { text-decoration: none; }
.beluga-footer-links a:hover { text-decoration: underline; }

.beluga-newsletter-title,
.beluga-newsletter-note { margin: 0; }
.beluga-newsletter .wpcf7 { margin: 0; }
.beluga-newsletter form.wpcf7-form { position: relative; display: flex; align-items: center; gap: var(--wp--preset--spacing--40); flex-wrap: nowrap; }
/* CF7's spinner is a third flex item. It is invisible until submit but still
   reserves ~88px of the 400px row, which starves the input. Take it out of
   flow instead of removing it, so the loading state still works. */
.beluga-newsletter .wpcf7-spinner { position: absolute; right: 0; top: 100%; margin: 4px 0 0; }
/* The design's row is 280 + 16 + 104 = exactly the 400px column. Our "Envoyer"
   renders ~11px wider than Figma's, so the input must be allowed to shrink or
   the button wraps to its own line. */
.beluga-newsletter .wpcf7-form-control-wrap { flex: 1 1 0; min-width: 0; display: block; }
.beluga-newsletter .wpcf7-submit { flex: 0 0 auto; }
.beluga-newsletter .wpcf7-form p { margin: 0; display: contents; }
.beluga-newsletter input[type="email"] {
  width: 100%;
  max-width: 280px;
  box-sizing: border-box;
  height: 40px;
  margin-top: 0;
  padding: .5rem .75rem;
  border-radius: 12px;
  background: transparent;
  border: 1px solid var(--wp--preset--color--base);
  color: var(--wp--preset--color--base);
}
.beluga-newsletter input[type="email"]::placeholder { color: var(--wp--preset--color--base); opacity: .8; }
/* Design: the footer submit is an OUTLINE button on the dark ground, unlike
   the solid turquoise submit on the contact form. */
.beluga-newsletter .wpcf7-submit {
  background: transparent;
  border: 1px solid var(--wp--preset--color--base);
  color: var(--wp--preset--color--base);
}
.beluga-newsletter .wpcf7-submit:hover {
  background: var(--wp--preset--color--base);
  color: var(--wp--preset--color--contrast);
}
.beluga-newsletter .wpcf7-response-output { flex-basis: 100%; }

.beluga-footer-rule { border: 0; border-top: 1px solid var(--wp--preset--color--base); opacity: .35; margin: 0; }
.beluga-footer-legal { display: flex; flex-wrap: wrap; gap: var(--wp--preset--spacing--50); margin: 0; }

@media (max-width: 900px) {
  .beluga-footer-main { flex-wrap: wrap; }
  .beluga-footer-main > .wp-block-column { flex-basis: 100% !important; }
  .beluga-footer-main > .wp-block-column + .wp-block-column { margin-top: var(--wp--preset--spacing--80); }
  .beluga-newsletter input[type="email"] { width: 100%; box-sizing: border-box; }
}

/* Footer links are #FFFFFF in the design, but the site-wide dark-band rule
   (.has-contrast-background-color a -> primary-light) matches with equal
   specificity and later source order, so it wins over the block's own link
   colour. Same trap as .wp-block-buttons — qualify to beat it. */
/* Every link in the footer is white in the design. */
.wp-block-group.has-contrast-background-color .beluga-footer-links a,
.wp-block-group.has-contrast-background-color .beluga-footer-legal a,
.wp-block-group.has-contrast-background-color .beluga-newsletter-note a,
.wp-block-group.has-contrast-background-color .wp-block-site-logo a {
  color: var(--wp--preset--color--base);
}
/* The credits block sits in a constrained group, so its children would cap at
   contentSize (768px) instead of spanning the 1280px container. */
.beluga-footer-credits > * { max-width: none; width: 100%; }

/* ---------- Current nav item ---------- */
/* Design highlights the page you are on in turquoise. Qualified with the
   background class because the site-wide `.has-contrast-background-color a`
   rule matches at equal specificity and later source order. */
.wp-block-group.has-contrast-background-color .wp-block-navigation-item.current-menu-item a,
.wp-block-navigation-item.current-menu-item > a.wp-block-navigation-item__content {
  color: var(--wp--preset--color--primary);
}

/* ---------- Accueil: "Tout savoir avant d'adopter" ---------- */
/* Design: 48px icon, 24px to the heading, columns 395 wide at gap 48. */
.beluga-savoir-icon {
  display: block;
  width: 48px;
  height: 48px;
  color: var(--wp--preset--color--base);
  margin-bottom: var(--wp--preset--spacing--50);
}
.beluga-savoir-icon svg { display: block; width: 100%; height: 100%; }
/* ---------- Text action link ("En savoir plus ›", "Découvrir ›") ----------
   The design draws this as a plain dark label with a trailing chevron — not a
   themed link. It has to override theme.json's elements.link colour and the
   browser's default underline, so both are stated explicitly. On the navy band
   it inherits white from the band instead of the green, which also clears AA
   there (the green link token is only 1.74:1 on navy). */
.beluga-savoir-more a {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  color: inherit;
  font-weight: 500;
  text-decoration: none;
}
.beluga-savoir-more a::after,
.beluga-card__more::after {
  content: "";
  width: 1em;
  height: 1em;
  flex: none;
  background-color: currentColor;
  /* The Figma asset points up; the design uses it as a right chevron. */
  transform: rotate(90deg);
  -webkit-mask: var(--beluga-chevron) no-repeat center / contain;
  mask: var(--beluga-chevron) no-repeat center / contain;
}
/* Underline on hover only — the resting state is undecorated in the design,
   but the affordance still has to exist for pointer users. */
.beluga-savoir-more a:hover { text-decoration: underline; }
.wp-block-group.has-navy-background-color .beluga-savoir-more a {
  color: var(--wp--preset--color--base);
}
/* The hero headline runs 72px desktop / 40px mobile in the frames; that is the
   `hero` preset's own fluid clamp now, so no breakpoint override belongs here. */

/* ---------- Section eyebrows ---------- */
/* The small label above every section heading is semibold in the design. The
   `small` preset carries no weight of its own, so it inherited body 400. */
.beluga-eyebrow { font-weight: 600; }

/* ---------- Accueil: "Impacts positifs" ---------- */
/* The design pairs a 600x640 portrait image with the text column. The photo is
   the wide 2400x1594 design shot, so crop it to that proportion here. */
.beluga-impacts .wp-block-image img {
  width: 100%;
  aspect-ratio: 15 / 16;
  object-fit: cover;
  object-position: center center;
  border-radius: 16px;
}
/* Each benefit is a checkmark in a left gutter with the heading and its
   paragraph both indented to the same edge. The ::before is the first grid
   item, so it lands in row 1 / column 1; every real child is forced to
   column 2 and stacks underneath. */
.beluga-impacts__item {
  display: grid;
  grid-template-columns: 3rem 1fr;
  column-gap: var(--wp--preset--spacing--50, 1.5rem);
  margin-block-start: var(--wp--preset--spacing--50);
}
.beluga-impacts__item::before {
  content: "";
  /* 48px box, 32px glyph — the frame draws the tick inset inside its slot. */
  width: 3rem;
  height: 3rem;
  -webkit-mask-size: 2rem auto;
  mask-size: 2rem auto;
  margin-block-start: 0.15em;
  background-color: currentColor;
  -webkit-mask: var(--beluga-check) no-repeat center / contain;
  mask: var(--beluga-check) no-repeat center / contain;
}
.beluga-impacts__item > * { grid-column: 2; }
.beluga-impacts__item > h3 { margin-block-start: 0; }
/* Block-gap between the heading and its own paragraph is section-sized; the
   design keeps the pair tight and separates the items instead. */
.beluga-impacts__item > p { margin-block-start: var(--wp--preset--spacing--20, 0.5rem); }
:root {
  --beluga-chevron: url('../icons/ui-chevron.svg');
  --beluga-check: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"%3E%3Cpath fill="none" stroke="%23000" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" d="M5 17.5 12 24.5 27 8"/%3E%3C/svg%3E');
}
/* The pill and the "En savoir plus" link share a row in the design; the flex
   layout's default gap is too tight against a 100px-radius pill. */
.beluga-impacts__actions { gap: var(--wp--preset--spacing--40); }
.beluga-impacts__actions .beluga-savoir-more { margin: 0; }
@media (max-width: 900px) {
  .beluga-impacts { flex-wrap: wrap; }
  .beluga-impacts > .wp-block-column { flex-basis: 100% !important; }
  .beluga-impacts .wp-block-image img { aspect-ratio: 16 / 9; }
}

/* ---------- Full-bleed section seams ---------- */
/* Sections that span the viewport carry their own 80px padding and their own
   background. WP's constrained layout still puts a 24px block gap between
   them, which shows the page background as a white seam between every band.
   Design has the bands butting directly against each other. */
/* Same seam at the site level, but ONLY where main opens with a full-bleed
   band that paints its own background (the front page hero). Zeroing this
   globally removes the sole clearance under the header on templates whose
   first block has no padding of its own — the legal pages, single posts and
   404 all went flush. Opt in per template with `beluga-flush` instead.
   The footer is safe unconditionally: it carries 80px of its own padding. */
.wp-site-blocks > main.beluga-flush,
/* Page content whose first block is full-bleed (a cover hero, a coloured band)
   has the same seam. The cover is nested inside .entry-content, so match on the
   wrapper rather than the cover itself. Templates whose first block is ordinary
   flow content keep the 24px — it is their only clearance under the header. */
.wp-site-blocks > main:has(> .entry-content.alignfull > .wp-block-cover:first-child),
.wp-site-blocks > main:has(> .entry-content.alignfull > .alignfull:first-child) {
  margin-block-start: 0;
}
.wp-site-blocks > footer {
  margin-block-start: 0;
}
/* Descendant combinator, not child: in a template the bands are direct
   children of <main>, but in page content they sit inside .entry-content, so
   `main > …` silently missed every page-built section. */
main .alignfull + .alignfull,
main .alignfull + .alignwide,
main .alignwide + .alignfull,
main .alignfull + .wp-block-cover,
main .wp-block-cover + .alignfull {
  margin-block-start: 0;
}


/* ---------- FAQ page ---------- */
/* Design: 500 + 80 + 700 columns, accordion items separated by a 1px rule with
   no gap, question 18px/600, chevron flips on open. <details> keeps it working
   without JS. */
.beluga-faq { align-items: flex-start; }
.beluga-faq__item { border-top: 1px solid rgb(1 2 3 / .15); }
.beluga-faq__item:last-of-type { border-bottom: 1px solid rgb(1 2 3 / .15); }
.beluga-faq__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--wp--preset--spacing--50);
  padding: var(--wp--preset--spacing--50) 0;
  font-size: var(--wp--preset--font-size--large);
  font-weight: 700;
  cursor: pointer;
  list-style: none;
}
.beluga-faq__q::-webkit-details-marker { display: none; }
.beluga-faq__chev {
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  color: var(--wp--preset--color--contrast);
  transition: transform .2s ease;
}
/* The exported glyph points up; the design shows it down when collapsed.
   Inlined in the markup rather than a data URI — currentColor does not resolve
   inside content:url(), which renders the icon invisible. */
.beluga-faq__chev svg { display: block; width: 100%; height: 100%; transform: rotate(180deg); transition: transform .2s ease; }
.beluga-faq__item[open] .beluga-faq__chev svg { transform: rotate(0deg); }
.beluga-faq__label { flex: 1 1 auto; }
.beluga-faq__a { padding-bottom: var(--wp--preset--spacing--50); }
.beluga-faq__a p { margin: 0; }
.beluga-faq__a p + p { margin-top: var(--wp--preset--spacing--40); }

@media (max-width: 900px) {
  .beluga-faq { flex-wrap: wrap; }
  .beluga-faq > .wp-block-column { flex-basis: 100% !important; }
  .beluga-faq > .wp-block-column + .wp-block-column { margin-top: var(--wp--preset--spacing--80); }
}

/* ---------- Portrait: "Ce que vous recevez" ---------- */
/* Static band, identical on all 201 portraits. Icons 48px, centred, four
   columns at a 48px gap per the approved frame. */
.beluga-avantage-icon {
  display: block;
  width: 48px;
  height: 48px;
  margin: 0 auto var(--wp--preset--spacing--50);
  color: var(--wp--preset--color--base);
}
.beluga-avantage-icon svg { display: block; width: 100%; height: 100%; }
.beluga-avantages .wp-block-column > * { margin-block: 0; }
/* These two need to outrank the reset above (0,2,0), or the card renders as one
   undifferentiated block — icon flush on heading, heading flush on body. */
.beluga-avantages .wp-block-column > .beluga-avantage-icon { margin-bottom: 24px; }
.beluga-avantages .wp-block-column > h3 {
  margin-bottom: clamp(12px, 10.59px + 0.3756vw, 16px);
}
/* A text-only action next to the filled pill — no border, no fill. */
.wp-block-button.beluga-btn-bare .wp-block-button__link { background: none; border: 0; }
@media (max-width: 900px) {
  .beluga-avantages { flex-wrap: wrap; }
  .beluga-avantages > .wp-block-column { flex-basis: 45% !important; }
}
@media (max-width: 600px) {
  .beluga-avantages > .wp-block-column { flex-basis: 100% !important; }
}

/* ---------- Shared page sections (don / processus) ---------- */
/* Design pairs a 600px image with a 600px text column at an 80px gap. */
.beluga-split > .wp-block-column > * { margin-block: 0; }
.beluga-split > .wp-block-column > * + * { margin-top: var(--wp--preset--spacing--50); }
/* Stretch the image column and let the photo fill it, so a tall text column
   (don / processus) leaves no dead space beside it.
   The floor is the design's own 600x400 image, NOT 640: on the Centre
   d'adoption CTA the text column is only a heading, one line and a button, so a
   640px floor drove the band to 800px against the design's 550px and put the
   dead space back — just on the other side. At 400 the short band matches the
   design and the tall ones still stretch past it. */
.beluga-split { align-items: stretch; }
.beluga-split > .wp-block-column { align-self: stretch; }
.beluga-split .wp-block-image { height: 100%; margin: 0; }
.beluga-split .wp-block-image img {
  width: 100%;
  height: 100%;
  min-height: 400px;
  object-fit: cover;
  border-radius: 16px;
}
/* Centre the text column's own content within the stretched row. */
.beluga-split > .wp-block-column:not(:has(> .wp-block-image)) {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* Benefit lists: the design marks each item with a turquoise check. */
.beluga-checklist { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--wp--preset--spacing--30); }
.beluga-checklist li { position: relative; padding-left: 1.75rem; }
.beluga-checklist li::before {
  content: "";
  position: absolute;
  left: 0; top: .45em;
  width: .55rem; height: .9rem;
  border: solid var(--wp--preset--color--primary);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.beluga-checklist--dark li::before { border-color: var(--wp--preset--color--primary); }

/* Numbered adoption steps. */
.beluga-steps { list-style: none; margin: 0; padding: 0; display: grid;
  gap: clamp(24px, 21.18px + 0.7512vw, 32px); }
.beluga-step { display: flex; gap: var(--wp--preset--spacing--50); align-items: flex-start; }
.beluga-step__n {
  flex: 0 0 auto;
  display: block;
  width: 48px; height: 48px;
  color: var(--wp--preset--color--contrast);
}
.beluga-step__n svg { display: block; width: 100%; height: 100%; }
.beluga-step__body h3 {
  /* Frame: 16px under the heading on desktop, 12 on mobile. */
  margin: 0 0 clamp(12px, 10.59px + 0.3756vw, 16px);
  /* Design: 28px/400. Nothing >=22px is weight 600 in any approved frame. */
  font-size: var(--wp--preset--font-size--x-large);
  font-weight: 400;
}
.beluga-step__body p { margin: 0; }
.beluga-faq-narrow { margin-inline: auto; }

@media (max-width: 900px) {
  .beluga-split { flex-wrap: wrap; }
  .beluga-split > .wp-block-column { flex-basis: 100% !important; }
  .beluga-split > .wp-block-column + .wp-block-column { margin-top: var(--wp--preset--spacing--80); }
}

/* ---------- Portrait: image / text split ---------- */
/* Design is 600 / 80 / 600. Stack before the columns get too narrow to hold
   the carousel thumbnails alongside the main image. */
@media (max-width: 900px) {
  .beluga-fiche { flex-wrap: wrap; }
  .beluga-fiche > .wp-block-column { flex-basis: 100% !important; }
  .beluga-fiche > .wp-block-column + .wp-block-column { margin-top: var(--wp--preset--spacing--80); }
}

/* ---------- Beluga card (Accueil + Centre d'adoption) ---------- */
/* Approved frame "Bel/Cards/beluga": 405x408, #FFF, 2px #C6C5C4, radius 16;
   image 405x228 (16:9) full-bleed at the top with only the top corners rounded;
   content padded 24 with a 24px gap; title 28px/400. */
.beluga-card {
  background: var(--wp--preset--color--base);
  /* The frame's 2px stroke is drawn INSIDE the 405.33 card, so the image still
     spans the full width and the card still closes at 408. A CSS border would
     eat 4px of both. `outline` with a negative offset paints in the same place
     without taking part in layout. */
  outline: 2px solid #C6C5C4;
  outline-offset: -2px;
  border-radius: 16px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.beluga-card .wp-block-post-featured-image { margin: 0; }
.beluga-card .wp-block-post-featured-image img { display: block; width: 100%; border-radius: 0; }
.beluga-card__body {
  display: flex;
  flex-direction: column;
  /* Frame "Content Top" groups the title and the tag 16 apart, then leaves 24
     to the actions. Flattened here: 16 everywhere plus 8 under the meta row. */
  gap: 16px;
  padding: var(--wp--preset--spacing--50);
  flex: 1 1 auto;
}
.beluga-card .wp-block-post-title { margin: 0; }
.beluga-card .wp-block-post-title a { color: var(--wp--preset--color--contrast); text-decoration: none; }
.beluga-card .wp-block-post-title a:hover { text-decoration: underline; }
/* Design's read-more is a borderless text action with a trailing chevron. */
.beluga-card__more {
  margin-top: auto;
  font-size: var(--wp--preset--font-size--medium);
  font-weight: 500;
  color: var(--wp--preset--color--contrast);
  text-decoration: none;
}
.beluga-card__more { display: inline-flex; align-items: center; gap: 0.5em; }
.beluga-card__more:hover { text-decoration: underline; }

/* ---------- Responsive gutter ---------- */
/* Sections are authored with the desktop 64px inset (spacing|80) because that
   is what the desktop frames specify, but it never changed at any breakpoint —
   at 375px that left 247px of usable width against the mobile frames' 335px
   (20px gutters), clipping headings mid-word. clamp() keeps the approved
   desktop value and lands on the approved mobile one. */
main section[style*="padding-left"],
main .alignfull[style*="padding-left"],
.wp-block-template-part > .alignfull[style*="padding-left"] {
  padding-inline: clamp(20px, 5vw, 64px) !important;
}
.beluga-cta-card[style*="padding-left"] {
  padding-inline: clamp(32px, 20.73px + 3.0047vw, 64px) !important;
}
/* The card is 64px padded on desktop and 32px on mobile in every frame that
   uses it; the block's inline `spacing|80` is a flat 64 and is too tight a
   card at 375. */
.beluga-cta-card[style*="padding-top"] {
  padding-block: clamp(32px, 20.73px + 3.0047vw, 64px) !important;
}

/* ---------- Design fidelity vs WCAG AA ---------- */
/* The approved frames use #66C0C1 for outline borders and list ticks on light
   grounds (2.13:1 on white, 1.84:1 on the pale band) and #2683D8 for tag text
   (3.95:1) — all below the thresholds that apply to them (3:1 for non-text UI,
   4.5:1 for text). Rather than choosing between the frame and AA, keep the
   design's hue and saturation and lower lightness by the minimum that passes:
   #66C0C1 -> #3D9697 (3.02:1 on the pale band) and #2683D8 -> #2379C8 (4.53:1).
   The shift is 3.7-16.2% lightness; hue is unchanged. */
.beluga-checklist li::before { border-color: var(--wp--preset--color--primary-aa); }

/* Outline buttons carry a teal border in every approved frame; we shipped black
   on light grounds and white on dark. The AA-safe teal clears the 3:1 non-text
   threshold on both (3.02:1 on the pale band, 4.68:1 on navy), so one value
   restores the design everywhere. !important is required because WP emits its
   own has-*-border-color utilities with !important. */
.wp-block-button.is-style-outline:not(.beluga-btn-bare) .wp-block-button__link:not(.has-border-color) {
  border-color: var(--wp--preset--color--primary-aa) !important;
  border-width: 1px;
}
/* A button that names its own border colour keeps it. The approved frames draw
   these hairlines as #010203@15% on light grounds and #FFFFFF@20% on dark, both
   below the 3:1 WCAG 1.4.11 floor; the client-approved design takes precedence
   (decision 2026-08-20, recorded in
   docs/figma-qa-processus-dadoption-2026-08-20.md). */

/* Adoption status pill: design is an outlined transparent chip, one hue per
   status — the chip is the only at-a-glance availability signal in the grid,
   so the statuses must NOT share a colour.
   These are the approved swatches exactly as drawn, cross-checked against
   docs/design/tokens.json (`palette_by_usage`) rather than eyeballed:
     dispo    #2683D8  tag-blue   (12 uses)
     enadopt  #0EAEC3  accent     (13 uses)
     encours  #112A41  tag-navy   (4 uses)
     adopte   #808081  grey       (7 uses)
   NOTE: at 14px/600 the pill label is below the WCAG large-text threshold, so
   dispo (3.95:1), enadopt (2.67:1) and adopte (3.95:1) sit under the 4.5:1 AA
   floor on the white card. Kept as designed by explicit decision — raise with
   the designer, do not "fix" here.
   `meriscope` has no design swatch and falls through to the neutral base. */
.beluga-card__tag {
  background: transparent;
  border: 1px solid currentColor;
  color: var(--wp--preset--color--tag-navy);
  font-weight: 600;
  font-size: var(--wp--preset--font-size--small);
  /* 21px line-height + 6 + 2px border = the frame's 29. */
  padding: 3px 10px;
}
.beluga-card__tag--dispo   { color: var(--wp--preset--color--tag-blue); }
.beluga-card__tag--enadopt { color: var(--wp--preset--color--accent); }
.beluga-card__tag--encours { color: var(--wp--preset--color--tag-navy); }
.beluga-card__tag--adopte  { color: var(--wp--preset--color--grey); }

/* ---------- Stat band (Pourquoi adopter) ---------- */
/* Approved frame: three columns divided by hairlines, numeral ~80px/400,
   label 16px below it. The 900 / 47 / 35 figures come from the client-approved
   design and ship as-is. */
/* The hairline belongs to .beluga-stat (above) and to EVERY stat including the
   first -- the frame draws one 1px #010203@15% rule per Stat frame. A second
   rule on the column drew a duplicate hairline 33px away on stats 2 and 3. */
.beluga-stats { gap: 48px; }
.beluga-stats > .wp-block-column { padding-inline: 0; flex-basis: 0; flex-grow: 1; }
.beluga-stat__n {
  display: block;
  font-size: clamp(56px, 47.55px + 2.2535vw, 80px);
  font-weight: 700;
  line-height: 1.3;
  color: var(--wp--preset--color--contrast);
}
.beluga-stat__l {
  margin: var(--wp--preset--spacing--20) 0 0;
  font-size: clamp(18px, 16.59px + 0.3756vw, 22px);
  line-height: 1.4;
  letter-spacing: -0.01em;
}
@media (max-width: 900px) {
  /* Stacked, but the rule stays on the left edge as drawn, at a 32px gap. */
  .beluga-stats { flex-wrap: wrap; gap: var(--wp--preset--spacing--60); }
  .beluga-stats > .wp-block-column { flex-basis: 100% !important; }
}

/* ---------- Concept icons (Pourquoi adopter / À propos) ---------- */
/* The 17 exported project SVGs are named after these exact concepts, so the
   mapping is 1:1. They inherit colour via currentColor, which lets the same
   file serve the pale, white and navy bands. */
.beluga-concept-icon {
  display: block;
  width: 48px;
  height: 48px;
  margin-bottom: var(--wp--preset--spacing--40);
  color: currentColor;
}
.beluga-concept-icon svg { display: block; width: 100%; height: 100%; }
.has-navy-background-color .beluga-concept-icon { color: var(--wp--preset--color--base); }

/* ---------- Adoption-status filter ---------- */
/* Approved frame: select ~218x44 on the left, "Réinitialiser" pill ~207x45 on
   the right, both above the grid. */
.beluga-filter {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--wp--preset--spacing--50);
  flex-wrap: wrap;
}
.beluga-filter__select {
  box-sizing: border-box;
  min-height: 44px;
  min-width: 218px;
  /* Frame: 44px tall, radius 10, 1px #C6C5C4, text inset 10/13 from the box
     edge. The stroke is drawn inside there, so in CSS that is 9px of padding
     plus the 1px border. The right inset is widened to clear the caret. */
  padding: 9px 44px 9px 13px;
  font: inherit;
  font-weight: 500;
  color: var(--wp--preset--color--contrast);
  background-color: transparent;
  border: 1px solid #C6C5C4;
  border-radius: 10px;
  cursor: pointer;
  /* Native arrow varies wildly across platforms; draw the frame's solid caret
     (arrow_drop_down), not a stroked chevron. */
  appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23010203'%3E%3Cpath d='M7 10l5 5 5-5z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 13px center;
  background-size: 24px 24px;
}
.beluga-filter__select:focus-visible {
  outline: 2px solid var(--wp--preset--color--primary-aa);
  outline-offset: 2px;
}
.beluga-filter__reset,
.beluga-filter__go {
  display: inline-flex;
  align-items: center;
  /* Without this the element is content-box, so min-height applies to the
     content and the 10px padding + 1px border stack on top: 44+20+2 = 66px
     against the frame's 45. */
  box-sizing: border-box;
  min-height: 44px;
  padding: 10px 24px;
  font: inherit;
  font-weight: 500;
  text-decoration: none;
  color: var(--wp--preset--color--contrast);
  background: transparent;
  /* AA-safe teal: the frame's #66C0C1 is 2.13:1 on white, below the 3:1 that
     applies to a control's boundary. */
  border: 1px solid var(--wp--preset--color--primary-aa);
  border-radius: 100px;
  cursor: pointer;
}
.beluga-filter__reset:hover,
.beluga-filter__go:hover { background: var(--wp--preset--color--surface); }
@media (max-width: 600px) {
  .beluga-filter { flex-direction: column; align-items: stretch; }
  .beluga-filter__select { min-width: 0; width: 100%; }
  .beluga-filter__reset { justify-content: center; }
}

/* ---------- Accueil hero: partner logos ---------- */
/* Two white-on-transparent marks sit under the CTA in the design. They are
   different aspect ratios (GREMM is nearly square, Projet Béluga is a wide
   lockup), so they are matched on height rather than width. */
.beluga-hero__partners {
  gap: var(--wp--preset--spacing--60);
  margin-block-start: var(--wp--preset--spacing--60);
}
.beluga-hero__partners img {
  height: 3.5rem;
  width: auto;
}

/* ---------- Écosystème cards: organisation logo ---------- */
/* The design repeats the GREMM lockup in all three cards; Baleines en direct
   and the CIMM have their own marks, which the GREMM has not supplied yet.
   Sized on height so a swapped-in asset of any aspect ratio still lines up. */
.beluga-orgcard__logo { margin: 0 0 var(--wp--preset--spacing--50); }
.beluga-orgcard__logo img { height: 3rem; width: auto; }

/* ---------- Footer: partner strip ---------- */
/* The footer band is a constrained layout, so its children are capped at the
   theme contentSize (768px) — seven 120px marks plus gaps need the full 1152px
   container, which is what wrapped them onto a second row. */
.beluga-partners > * { max-width: none; }
.beluga-partners__row {
  gap: var(--wp--preset--spacing--50) var(--wp--preset--spacing--60);
  margin-block-start: var(--wp--preset--spacing--60);
}
/* Masked, not <img>: an external SVG loaded through <img src> is its own
   document and cannot inherit currentColor, so the placeholders rendered
   black-on-black in the footer. The mask takes its colour from the band. */
.beluga-partners__logo {
  display: block;
  width: 6.25rem;
  aspect-ratio: 140 / 56;
  background-color: currentColor;
  -webkit-mask: var(--beluga-partner-logo) no-repeat center / contain;
  mask: var(--beluga-partner-logo) no-repeat center / contain;
}
.beluga-partners__logo--a { --beluga-partner-logo: url('../img/logo-placeholder-a.svg'); }
.beluga-partners__logo--b { --beluga-partner-logo: url('../img/logo-placeholder-b.svg'); }

/* ---------- Figma fidelity pass, Accueil — 2026-08-19 ---------- */
/* Measured against the cached node trees for the approved frames
   10372:9911 (desktop 1440) and 10372:9458 (mobile 375), not from the PNG
   renders. Every value below is a number read out of one of those two frames. */

/* `xx-large` is 36/46.8 desktop and 24/31.2 mobile — 1.3 at both, where the
   h3 element default is 1.4 (correct for `x-large`, which is 1.4 at both). */
.has-xx-large-font-size { line-height: 1.3; }

/* Section intro — eyebrow, heading and lead sit in a 768px centred column in
   the frames, not the section's full 1280px, so each of these wraps to two
   lines rather than one. `.beluga-eyebrow` also appears inside the 600px
   Impacts column, where a 48rem cap cannot bind. */
.beluga-eyebrow,
.beluga-intro { max-width: 48rem; margin-inline: auto; }

/* "Prochaines étapes": the three columns are centre-aligned in both frames
   (counterAxisAlignItems: CENTER), including the icon above each heading. */
.beluga-steps > .wp-block-column { text-align: center; }
.beluga-steps > .wp-block-column .beluga-savoir-icon { display: block; }
.beluga-steps > .wp-block-column .beluga-savoir-more { justify-content: center; }

/* The partner strip heading is 18/27 w700 desktop, 16/24 w700 mobile. */
.beluga-partners__title { font-weight: 700; }

/* Mobile section rhythm: the frames use 64px block padding and a 20px inline
   gutter, against the desktop 80/64. The Engagement band is tighter still at
   48px. Authored values stay desktop-correct; these only apply below the
   mobile breakpoint the frames were drawn at. */
@media (max-width: 600px) {
  main > .alignfull[style*="padding-top"],
  main .wp-block-post-content > .alignfull[style*="padding-top"] {
    padding-top: var(--wp--preset--spacing--80) !important;
    padding-bottom: var(--wp--preset--spacing--80) !important;
  }
  main > .beluga-engagement[style*="padding-top"] {
    padding-top: var(--wp--preset--spacing--70) !important;
    padding-bottom: var(--wp--preset--spacing--70) !important;
  }
}

/* ---------- Pourquoi adopter — Figma fidelity (2026-08-19) ---------- */
/* Every value below is measured off the two approved frames (desktop
   10372:6047, mobile 10372:5632) and written as a clamp ramped between the
   widths those frames are drawn at — 375 and 1440 — exactly like the type
   scale in theme.json. A single spacing preset cannot serve both ends: the
   frames alternate 112 and 80 px of band padding on desktop and use a flat
   64 px on mobile. See docs/figma-qa-pourquoi-adopter-2026-08-19.md. */

/* Band padding. The class replaces the block's inline padding rather than
   fighting it, so there is no !important here. */
.beluga-band-lg   { padding-block: clamp(64px, 47.10px + 4.5070vw, 112px); }
.beluga-band-sm   { padding-block: clamp(64px, 58.37px + 1.5023vw, 80px); }
.beluga-band-hero { padding-block: clamp(64px, 47.10px + 4.5070vw, 112px)
                                  clamp(64px, 58.37px + 1.5023vw, 80px); }

/* Eyebrow → heading is 16 desktop / 12 mobile, and heading → lead is 24 / 20;
   the global 24px block gap was standing in for both. These need !important
   because `.beluga-split > .wp-block-column > * + *` (0,2,0) already sets the
   margin and would otherwise outrank a single-class selector. */
.beluga-eyebrow-tight + * {
  margin-block-start: clamp(12px, 10.59px + 0.3756vw, 16px) !important;
}
.beluga-lead-tight {
  margin-block-start: clamp(20px, 18.59px + 0.3756vw, 24px) !important;
}

/* "Et ce n'est pas tout…": 80px from the intro to the first card row (48 on
   mobile), 64px between the two rows (48 on mobile), and 48px between cards.
   row-gap only bites once the columns stack. */
.beluga-advantages .beluga-intro + .wp-block-columns {
  margin-block-start: clamp(48px, 36.73px + 3.0047vw, 80px);
}
.beluga-advantages .wp-block-columns + .wp-block-columns {
  margin-block-start: clamp(48px, 42.37px + 1.5023vw, 64px);
}
.beluga-advantages .wp-block-columns { column-gap: 48px; row-gap: 48px; }

/* The frames centre the concept icon over its centred heading and body copy
   (counterAxisAlignItems: CENTER); `display:block` alone left it hard left. */
.beluga-advantages .beluga-concept-icon { margin-inline: auto; }

/* The hero's two inline sub-heads are 28/39.2 — the `x-large` preset at ×1.4.
   They are marked up as h2, and the h2 rule's 1.2 was winning. Only this page
   uses h2 at x-large. */
h2.has-x-large-font-size { line-height: 1.4; }


/* ---------- Processus d'adoption — Figma fidelity (2026-08-20) ---------- */
/* Measured off desktop 10372:6960 and mobile 10372:6471. Values that differ
   between the frames are clamps ramped 375 -> 1440, as elsewhere in this file.
   See docs/figma-qa-processus-dadoption-2026-08-20.md. */

/* The CTA band's top padding is 31 in the frame (it closes the gap to the
   parrains band above) and 80 at the bottom; 64/64 on mobile. */
.beluga-band-cta {
  padding-block: clamp(31px, 75.62px - 3.0986vw, 64px)
                 clamp(64px, 58.37px + 1.5023vw, 80px);
}

/* This page's two split bands draw the image at a FIXED 640 (348 mobile) and
   centre it, rather than stretching it to the text column. `.beluga-split`
   stretches by default and must keep doing so — the Centre d'adoption CTA
   depends on it — so this is a page-scoped modifier, not a change to the base. */
.beluga-split--fixed-image { align-items: center; }
.beluga-split--fixed-image > .wp-block-column { align-self: center; }
.beluga-split--fixed-image .wp-block-image { height: auto; }
.beluga-split--fixed-image .wp-block-image img {
  height: clamp(348px, 245.15px + 27.4178vw, 640px);
  min-height: 0;
}

/* « Impacts positifs »: the frame marks each item with a 35px check glyph and
   carries no body copy under it. */
.beluga-impacts-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 20px; }
.beluga-impacts-list li { display: flex; gap: 24px; align-items: flex-start; }
.beluga-impacts-list .beluga-check {
  flex: 0 0 auto; display: block; width: 35px; height: 35px;
  color: var(--wp--preset--color--contrast);
}
.beluga-impacts-list .beluga-check svg { display: block; width: 100%; height: 100%; }
.beluga-impacts-list h3 { margin: 0; font-weight: 400; }

/* « Merci aux parrains et marraines » — Gallery / 15 /. A 768px centred title
   column at a 24px gap, then the partner strip. */
.beluga-parrains__title { max-width: 48rem; margin-inline: auto; }
.beluga-parrains__title > * + * { margin-block-start: 24px !important; }
.beluga-parrains__strip {
  display: flex; flex-wrap: wrap; justify-content: center; align-items: center;
  gap: 24px; margin-block-start: 48px;
}
.beluga-parrains__strip img { max-height: 56px; width: auto; }
.beluga-parrains__lead { font-weight: 700; text-align: center; }

/* The frame's Actions rows pair the filled pill with a bare chevron link at a
   24px gap (`.beluga-impacts__actions` is the same component at 16). */
.beluga-actions-row { gap: 24px; }
.beluga-actions-row .beluga-savoir-more { margin: 0; }

/* ---------- À propos du GREMM — Figma fidelity (2026-08-20) ---------- */
/* Measured off desktop 10372:4898 and mobile 10372:4520. Values that differ
   between the frames ship as clamps ramped 375 -> 1440, as elsewhere here.
   See docs/figma-qa-a-propos-du-gremm-2026-08-20.md. */

/* Hero: the frame's Container puts 21px between the lead and the pill on
   desktop and 24 on mobile, where the button sits in its own column. The
   global 24px block gap only ever produced the mobile figure. */
.wp-block-buttons.beluga-hero-actions {
  margin-block-start: clamp(21px, 25.06px - 0.2817vw, 24px);
}

/* "Notre engagement": the concept icon sits 24px above its heading on desktop
   and 20 on mobile, and the heading is the same distance off its paragraph.
   `.beluga-concept-icon`'s flat 24px margin covered only the desktop half, and
   the heading gap was falling through to the 24px block default. */
.beluga-engagement .beluga-concept-icon { margin-bottom: 0; }
.beluga-engagement .beluga-concept-icon + h3 {
  margin-block-start: clamp(20px, 18.59px + 0.3756vw, 24px);
}
.beluga-engagement .wp-block-column h3 + p {
  margin-block-start: clamp(20px, 18.59px + 0.3756vw, 24px);
}
/* The closing pill is 80px under the last card row (48 on mobile) — the same
   rhythm the band uses everywhere else, which the block gap alone did not
   reach because `.wp-block-buttons` carries its own margin. */
.beluga-engagement > .wp-block-buttons {
  margin-block-start: clamp(48px, 36.73px + 3.0047vw, 80px);
}

/* Écosystème cards (Layout / 396 /). The frame draws a 2px #C6C5C4 stroke, and
   a Figma stroke paints INSIDE the box: as a `border` it would grow the card
   past the 405.33 the row allots and eat 4px of the content width. Same
   finding as the Centre d'adoption card — ship it as an outline pulled back
   over its own edge. */
.beluga-eco { column-gap: 32px; row-gap: 24px; }
.beluga-eco > .wp-block-column {
  background: var(--wp--preset--color--base);
  border-radius: 16px;
  outline: 2px solid #C6C5C4;
  outline-offset: -2px;
  padding: clamp(24px, 21.18px + 0.7512vw, 32px);
}
/* Card internals: logo 84x70, then 24/20 to the heading, 16/12 to the body and
   24/20 to the "Découvrir" link. */
.beluga-eco__logo {
  display: block;
  width: 84px;
  height: 70px;
  object-fit: contain;
  object-position: left center;
  margin-block-end: clamp(20px, 18.59px + 0.3756vw, 24px);
}
.beluga-eco h3 { margin-block: 0; }
.beluga-eco h3 + p {
  margin-block-start: clamp(12px, 10.59px + 0.3756vw, 16px);
}
.beluga-eco .beluga-savoir-more {
  margin-block-start: clamp(20px, 18.59px + 0.3756vw, 24px);
}
@media (max-width: 781px) {
  /* Stacked, at the frame's 24px card gap rather than the 48 core falls back
     to once `.wp-block-columns` wraps. */
  .beluga-eco { gap: 24px; }
}

/* Stacked, the frame's Bilan intro keeps its two groups 20px apart, not the
   64 that `.beluga-split` falls back to for an image/text pair. */
@media (max-width: 900px) {
  /* blockGap was stated only for `left`, so the wrapped row keeps core's
     24px row-gap and it adds to the margin below. State the gap once. */
  .beluga-bilan { row-gap: 0; }
  .beluga-bilan > .wp-block-column + .wp-block-column { margin-top: 20px; }
}

.beluga-stats > .wp-block-column.beluga-stat {
  padding-left: var(--wp--preset--spacing--60);
}

/* Stats band: the frame's two intro columns are 600/600 at an 80px gap, so the
   left one must not keep core's 24px block gap between eyebrow and heading —
   `.beluga-eyebrow-tight` already states 16/12 and needs to win here too. */
.beluga-split > .wp-block-column > .beluga-eyebrow-tight + * {
  margin-block-start: clamp(12px, 10.59px + 0.3756vw, 16px) !important;
}

/* Outline buttons: every frame draws the 1px hairline INSIDE the 44px pill, so
   the CSS border has to come out of the padding — 9+1 is the frame's 10px
   inset, 23+1 its 24. Left at 10/24 the pill measured 46 tall and 2px wide of
   the frame. Same convention as the tag pill (3px+1px) and the adoption select
   (9px+1px). */
.wp-block-button.is-style-outline .wp-block-button__link[style*="padding"] {
  padding: 9px 23px !important;
}

/* ---------- Faire un don (frames 10372:5367 desktop / 10372:5120 mobile) ----
   Fidelity pass 2026-08-20. Every value below is transcribed from those two
   frames; scripts/qa_figma_faire_un_don.py asserts them.

   Scoped to .beluga-don / .beluga-don-hero on purpose: .beluga-split and
   .beluga-checklist are shared with Pourquoi adopter, Processus d'adoption and
   À propos du GREMM, all three already certified against their own frames.
   The frames state their gaps explicitly (16/20/21/24/32) where the site's
   24px block default had been standing in for all of them. */

/* -- hero: the frame's three gaps are all different, so state each one -- */
.beluga-don-hero > * + * { margin-top: 0; }
.beluga-don-hero > p:first-child + h1 {
  /* eyebrow -> h1: 16 desktop, 12 mobile */
  margin-top: clamp(12px, 10.59px + 0.3756vw, 16px);
}
.beluga-don-hero > h1 + p {
  /* h1 -> lead: 24 desktop, 20 mobile */
  margin-top: clamp(20px, 18.59px + 0.3756vw, 24px);
}
.beluga-don-hero > .wp-block-buttons {
  /* lead -> actions: 21 desktop, 24 mobile (a DECREASING ramp, so the vw
     coefficient is negative -- a normal rising clamp yields the inverse). */
  margin-top: clamp(21px, 25.06px + -0.2817vw, 24px);
}

/* -- band text groups -- */
.beluga-don > .wp-block-column > * + * { margin-top: 0; }
.beluga-don > .wp-block-column > p:first-child + h2 {
  /* eyebrow -> h2: 16 desktop, 12 mobile */
  margin-top: clamp(12px, 10.59px + 0.3756vw, 16px);
}
.beluga-don > .wp-block-column > h2 + p {
  /* h2 -> body: 24 desktop, 20 mobile */
  margin-top: clamp(20px, 18.59px + 0.3756vw, 24px);
}
.beluga-don > .wp-block-column > p + p {
  /* The frame holds each band's body as ONE text node whose paragraphs are
     separated by a blank line, i.e. exactly one line-height: 27 desktop
     (18/27), 24 mobile (16/24). */
  margin-top: clamp(24px, 21.88px + 0.5634vw, 27px);
}
.beluga-don > .wp-block-column > .beluga-checklist {
  /* body -> list: 20 at both breakpoints */
  margin-top: 20px;
}
.beluga-don > .wp-block-column > .beluga-checklist + .wp-block-buttons {
  /* list -> actions: 32 desktop, 24 mobile */
  margin-top: clamp(24px, 21.18px + 0.7512vw, 32px);
}

/* -- checklist: the frame's own marks, not the shared teal tick --
   Band 1 draws a 16px check box in #010203; band 2 a 24px mark in #FFFFFF.
   Both clear AA comfortably, so there is no frame/accessibility conflict here
   and the shared .beluga-checklist AA override is simply not wanted. */
.beluga-don .beluga-checklist {
  display: grid;
  gap: 16px;
  padding-block: 8px;   /* the frame's List component carries 8px top/bottom */
}
.beluga-don .beluga-checklist li {
  margin-bottom: 0;     /* kill the legacy .5rem that stacked on the grid gap */
  padding-left: 32px;   /* 16px mark + 16px gap */
  min-height: 16px;
}
.beluga-don .beluga-checklist li::before {
  border-color: var(--wp--preset--color--contrast);
  top: .3em;
  width: .5rem;
  height: .85rem;
}
.beluga-don .beluga-checklist--dark li {
  padding-left: 40px;   /* 24px mark + 16px gap */
}
.beluga-don .beluga-checklist--dark li::before {
  border-color: var(--wp--preset--color--base);
  left: 4px;
  top: .22em;
  width: .65rem;
  height: 1.05rem;
}

/* -- photography: the frame fixes the image box, it does not stretch it -- */
.beluga-don.beluga-split { align-items: center; }
.beluga-don.beluga-split > .wp-block-column { align-self: center; }
.beluga-don.beluga-split .wp-block-image { height: auto; }
.beluga-don.beluga-split .wp-block-image img {
  width: 100%;
  height: 640px;
  min-height: 0;
  object-fit: cover;
  border-radius: 16px;
}

@media (max-width: 900px) {
  .beluga-don.beluga-split .wp-block-image img { height: 348px; }
  /* Both mobile frames stack the TEXT first. Band 2 draws the image on the
     left at 1440, so below the breakpoint its columns need an order flip. */
  .beluga-don.beluga-split > .wp-block-column:has(> .wp-block-image) { order: 2; }
  .beluga-don.beluga-split > .wp-block-column:not(:has(> .wp-block-image)) { order: 1; }
  /* Frame gap between the text group and the photo is 48 on both bands. */
  .beluga-don.beluga-split > .wp-block-column + .wp-block-column { margin-top: 0; }
  .beluga-don.beluga-split > .wp-block-column:has(> .wp-block-image) { margin-top: 48px; }
}

/* The 579px min-height is the DESKTOP frame's hero band. The mobile frame
   draws the same band at 420 = 64 + 292 content + 64, i.e. content-driven at
   that width, so release the desktop floor below the breakpoint. (We keep the
   photo + scrim here, which the mobile frame drops -- that deviation is about
   the background treatment only, not about the band's height.) */
@media (max-width: 900px) {
  .wp-block-cover:has(.beluga-don-hero) { min-height: 0 !important; }
}
