:root {
    --color-primary: #178289;
    --color-primary-dark: #106065;
    --color-primary-light: #e3f1f1;
    --color-accent: #d9cbb0;
    --color-accent-dark: #a89066;
    --color-text: #4a3b2a;
    --color-text-muted: #6b5d4a;
    --color-bg: #f7f6f4;
    --color-bg-alt: rgb(247, 242, 234);
    --color-border: #b0d9db;
    --radius-lg: 1.75rem;
    --radius-md: 1.25rem;
    --shadow-card: 0 10px 30px rgba(23, 130, 137, 0.12);
    --font-base: "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --font-display: "Fredoka", sans-serif;
}

* { box-sizing: border-box; }

html { height: 100%; }

/* Sticky footer: body is the flex column (header/main/footer, in source order), .site-main is
   the only item allowed to grow — on a short page it stretches to fill the leftover viewport
   height and pushes .site-footer down to the bottom instead of leaving a gap under it. */
body {
    margin: 0;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    font-family: var(--font-base);
    color: var(--color-text);
    background: var(--color-bg);
    line-height: 1.6;
    overflow-x: hidden;
}

.site-main { flex: 1 0 auto; }
.site-footer { flex-shrink: 0; }

.container {
    max-width: 1180px;
    margin: 0 auto;
    padding: 0 1.5rem;
}

/* CmsPageController::renderPage() bakes the page's auto-title <h1> directly into the same HTML
   string as the block tree (see cms-core), both now inside the same .container the block tree's
   own sections sit in (cms-page.php) — nothing left to constrain here, just the extra breathing
   room below the header that only the very first element (when it's this h1) has ever had. */
.container > h1:first-child {
    padding-top: 1.5rem;
}

/* A bare top-level richtext block still ends up with visible space below it even at
   .cms-richtext's own margin:0 — its *inner* <p> (see cms-blocks/richtext.php's tag=null case)
   keeps its normal browser margin, which collapses through the childless-of-padding/border div
   and reads as spacing after the block. .cms-image has no such inner paragraph to borrow from —
   a bare top-level Image immediately followed by another block touches it with zero gap. */
.container > .cms-image {
    margin-bottom: 1.5rem;
}

a { color: var(--color-primary); }
a:hover { color: var(--color-primary-dark); }

h1, h2, h3, h4 { line-height: 1.25; font-family: var(--font-display); font-weight: 600; }
/* Shared heading defaults, generalized from what 2+ sections below were already setting
   identically per section-scoped selector (.mission h2, .cms-section--mission h2 { font-size:
   1.9rem; color: ...; margin: ...; }, repeated near-verbatim for .activities/.quality/
   .formule-card/etc.) — every section rule further down now only overrides what's genuinely
   different for that one variant (a dark background needing a different color, a size unique to
   one component, extra breathing room before a grid…), never the whole block. This also means
   any heading typed inside a plain "Cadre" — with no section variant of its own to inherit a
   look from — gets this same baseline instead of the browser's own unstyled default.
   h4 is deliberately excluded from the color line below: its one existing use
   (.formule-card/.cms-section--card h4) is a plainer sub-heading that reads as body text, by
   design, not a second dark-teal heading level. h1 is excluded from all three: its only two uses
   (home-hero's oversized hero title, .hero's white banner title) are each a unique, deliberate
   size/color with nothing in common to generalize from, and the page's own plain auto-title
   <h1> (CmsPageController, "Afficher le titre") is deliberately left at the browser default. */
/* .cms-richtext's own margin:0 reset just above (0,1,0) outranks a bare h2/h3/h4 (0,0,1) — every
   CMS-rendered heading carries that class alongside its tag, so the compound h2.cms-richtext
   selectors below are load-bearing, not redundant with the bare ones (which still do the job on
   the static utility pages' hand-written headings, which never carry that class at all). */
h2, h3, h4,
h2.cms-richtext, h3.cms-richtext, h4.cms-richtext {
    /* Unconditional on the heading itself, not left to margin collapse through some inner
       element the way a paragraph gets its spacing — a heading has no inner element to borrow
       from, so one immediately followed by a block that doesn't either (.cms-list, .cms-image, a
       button…) would otherwise touch it directly. Collapse already keeps a heading-then-
       paragraph pair at the larger of the two margins (not the sum), so this can't double up
       spacing anywhere that already worked. */
    margin: 0 0 1rem;
}
h2, h3 { color: var(--color-primary-dark); }
h2 { font-size: 1.9rem; }
/* A "Texte" block set to a markup other than its default <p>/<div> (see cms-core's
   templates/cms-blocks/richtext.php) still needs to read as plain body text, not gain a
   heading's or a paragraph's own default browser margin out of nowhere — spacing between blocks
   is controlled by each section/group's own gap/margin setting, not by this. Placed before the
   variant rules below (.cms-richtext--lead etc., which set their own real margins) so their
   later, equal-specificity declaration still wins over this reset for those specific blocks. */
.cms-richtext { margin: 0; }

/* Header */
.site-header {
    position: sticky;
    top: 0;
    z-index: 20;
    background: var(--color-primary);
}

.site-header__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 1.5rem;
    flex-wrap: wrap;
    gap: 1.5rem;
}

.logo img { width: 240px; height: auto; display: block; }

.menu-toggle {
    display: none;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    background: none;
    border: none;
    cursor: pointer;
    padding: 0.5rem;
    margin-left: auto;
}
.menu-toggle__bar {
    width: 26px;
    height: 3px;
    border-radius: 2px;
    background: #fff;
}

.main-nav {
    display: flex;
    align-items: center;
    gap: 1.75rem;
    flex-wrap: wrap;
}

.main-nav a {
    color: #fff;
    text-decoration: none;
    font-weight: 600;
    font-size: 0.95rem;
    padding-bottom: 0.5rem;
    border-bottom: 3px solid transparent;
    display: flex;
    align-items: center;
    gap: 0.25rem;
}

.main-nav a:hover { color: #c6fcff; }

.main-nav a.is-active { border-bottom-color: var(--color-accent); }

.main-nav .dropdown-toggle-arrow { font-size: 0.65rem; color: rgba(255, 255, 255, 0.75); }

.nav-cta {
    font-family: var(--font-display);
    color: var(--color-primary-dark) !important;
    background: #fff;
    padding: 0.6rem 1.3rem;
    border-radius: 999px;
    border-bottom: none !important;
}
.nav-cta:hover,
.nav-cta.is-active { background: var(--color-accent); color: var(--color-text) !important; }

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
}

.nav-item-dropdown { position: relative; display: inline-flex; align-items: center; }

/* Hidden on desktop, where hover/focus-within already opens the dropdown — becomes a real,
   visible tap target in the mobile nav (see the max-width breakpoint below), since there's no
   hover on touch and the parent <a> itself always navigates on tap. */
.dropdown-toggle {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    background: none;
    border: none;
    padding: 0;
}

.dropdown-menu {
    position: absolute;
    top: 100%;
    left: 0;
    margin: 0;
    padding: 0;
    overflow: hidden;
    list-style: none;
    background: #fff;
    border: 1px solid var(--color-border);
    border-radius: 1rem;
    box-shadow: var(--shadow-card);
    min-width: 230px;
    width: max-content;
    display: none;
    z-index: 20;
}

.nav-item-dropdown:hover .dropdown-menu,
.nav-item-dropdown:focus-within .dropdown-menu,
.nav-item-dropdown.is-open .dropdown-menu {
    display: block;
}

.dropdown-menu li a {
    display: block;
    padding: 0.85rem 1.1rem;
    color: var(--color-text);
    font-weight: 500;
    font-size: 0.92rem;
    border: none;
}
.dropdown-menu li a:hover { background: var(--color-bg-alt); color: var(--color-primary); }

/* Home hero */
.home-hero, .cms-section--home-hero { margin-top: 3.5rem; }
.home-hero, .cms-section--home-hero .cms-section__inner {
    display: grid;
    grid-template-columns: 1.1fr 0.9fr;
    gap: 3rem;
    align-items: center;
}

.home-hero__badge {
    display: inline-block;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 0.8rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-primary-dark);
    background: var(--color-primary-light);
    padding: 0.4rem 0.9rem;
    border-radius: 999px;
    margin-bottom: 1.25rem;
}

.home-hero h1, .cms-section--home-hero h1 { font-size: 2.9rem; line-height: 1.12; margin: 0 0 1.25rem; color: var(--color-primary-dark); }
.home-hero__lead, .cms-richtext--lead { font-size: 1.15rem; font-weight: 600; color: var(--color-text-muted); max-width: 46ch; margin: 0 0 2rem; }

.home-hero__actions { display: flex; gap: 1rem; flex-wrap: wrap; margin-bottom: 2.25rem; }

.btn, .cms-button--cta, .cms-button--cta-outline {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 1rem;
    text-decoration: none;
    padding: 0.9rem 1.9rem;
    border-radius: 999px;
    display: inline-block;
    cursor: pointer;
    border: none;
}
.btn-primary, .cms-button--cta { color: #fff; background: var(--color-primary); box-shadow: 0 4px 12px rgba(23, 130, 137, 0.16); }
.btn-primary:hover, .cms-button--cta:hover { background: var(--color-primary-dark); color: #fff; }
.btn-outline, .cms-button--cta-outline { color: var(--color-primary-dark); background: #fff; border: 2px solid var(--color-primary); padding: 0.85rem 1.8rem; }
.btn-outline:hover, .cms-button--cta-outline:hover { background: var(--color-primary-light); color: var(--color-primary-dark); }
.btn:disabled, .btn:disabled:hover { background: #ccc; color: #777; box-shadow: none; cursor: not-allowed; }

.home-hero__media, .cms-group--hero-media { position: relative; }
.home-hero__media .blob, .cms-group--hero-media::before, .cms-group--hero-media::after { content: ''; position: absolute; border-radius: 50%; z-index: 0; }
.home-hero__media .blob--accent, .cms-group--hero-media::before { top: -2rem; right: -2rem; width: 150px; height: 150px; background: var(--color-accent); opacity: 0.4; }
.home-hero__media .blob--primary, .cms-group--hero-media::after { bottom: -1.5rem; left: -1.5rem; width: 110px; height: 110px; background: var(--color-primary); opacity: 0.15; }
.home-hero__media .frame, .cms-group--hero-media .cms-image {
    position: relative;
    z-index: 1;
    margin: 0;
    border-radius: var(--radius-lg);
    overflow: hidden;
    box-shadow: 0 20px 45px rgba(23, 130, 137, 0.2);
    aspect-ratio: 4 / 5;
}
.home-hero__media .frame img, .cms-group--hero-media .cms-image img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Infographic */
.infographic { margin-top: 3.5rem; }
.infographic img { width: 100%; height: auto; display: block; border-radius: var(--radius-lg); box-shadow: var(--shadow-card); }

/* Mission */
.mission { margin-top: 5rem; }
/* [data-cms-columns] added purely to out-specificity the generic
   .cms-group--layout-columns[data-cms-columns="2"] engine rule below (same 2-selector
   specificity would otherwise make this a file-order coin flip). */
.mission, .cms-section--mission .cms-group--layout-columns[data-cms-columns] {
    display: grid;
    grid-template-columns: 1.1fr 0.9fr;
    gap: 3rem;
    align-items: center;
}
/* h2's font-size/color/margin are all the shared default now (see the h2/h3/h4 rules up top) —
   nothing here needs its own override. */
.mission p { font-size: 1.1rem; font-weight: 600; color: var(--color-text-muted); margin: 0; }

.stat-list, .cms-stat-list { display: flex; flex-direction: column; gap: 1rem; }
.stat-card, .cms-stat-item {
    display: flex;
    align-items: center;
    gap: 1rem;
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border);
    border-radius: 1rem;
    padding: 1rem 1.25rem;
}
.stat-card__value, .cms-stat-item__value { font-family: var(--font-display); font-weight: 700; font-size: 1.5rem; color: var(--color-primary); min-width: 5rem; }
.stat-card__label, .cms-stat-item__label { font-size: 0.9rem; color: var(--color-text-muted); }

/* Divider */
.divider { margin-top: 4rem; }
.divider hr { border: none; border-top: 1px solid var(--color-border); margin: 0; }

/* Activities — .cms-section--activities is the CMS alias, same rationale as .hero/.formule-card
   above (matsports.be's "Grille" block). */
.activities, .cms-section--activities { margin-top: 4rem; }
.activities h2, .cms-section--activities h2 { text-align: center; margin-bottom: 2.5rem; }

.activity-grid, .cms-activity-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.75rem; }

.activity-card, .cms-activity-card { background: var(--color-bg-alt); border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; }
/* A linked card (matsports.be's "Grille" block, when an editor sets a link per card) renders
   as <a> instead of <article>/<div> — reset its inline default and inherited link styling so
   it looks identical to the non-linked case. */
a.cms-activity-card { display: block; color: inherit; text-decoration: none; }
.activity-card__image, .cms-activity-card__image { width: 100%; height: 160px; }
.activity-card__image img, .cms-activity-card__image img { width: 100%; height: 100%; object-fit: cover; display: block; }
.activity-card__body, .cms-activity-card__body { padding: 1.75rem 2rem 2rem; }
.activity-card h3, .cms-activity-card h3 { font-size: 1.35rem; margin-bottom: 0.75rem; }
.activity-card p, .cms-activity-card p { color: var(--color-text-muted); margin: 0; font-size: 0.98rem; }

/* Quality + schools */
.quality, .cms-section--quality {
    background: var(--color-primary-dark);
    border-radius: var(--radius-lg);
    padding-top: 3rem;
    padding-bottom: 3rem;
    color: #fff;
    position: relative;
    overflow: hidden;
    margin-top: 4.5rem;
}
/* Left/right padding diverges here: .quality (the static utility pages) has never sat inside
   .cms-section__inner and needs nothing extra. .cms-section--quality (CMS-rendered) used to get
   an extra 1.5rem/24px each side from .cms-section__inner's own padding stacked on top of this
   rule's — now that .cms-section__inner carries no padding of its own (.container, the CMS page
   wrapper, provides that layer once for every top-level block instead), reproducing that same
   1.5rem here keeps this variant's text sitting exactly where it always has. */
.quality { padding-left: 3rem; padding-right: 3rem; }
.cms-section--quality { padding-left: 4.5rem; padding-right: 4.5rem; }
/* No grid on .cms-section--quality itself: the 2-column split is the nested
   group(layout=columns,columns=2) — see bin/seed-cms-content.php's home page build.
   [data-cms-columns] added purely to out-specificity the generic
   .cms-group--layout-columns[data-cms-columns="2"] engine rule below (same 2-selector
   specificity would otherwise make this a file-order coin flip). */
.quality, .cms-section--quality .cms-group--layout-columns[data-cms-columns] {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 3rem;
    align-items: start;
}
.quality::before, .cms-section--quality::before {
    content: '';
    position: absolute;
    top: -60px;
    left: -60px;
    width: 180px;
    height: 180px;
    background: var(--color-accent);
    opacity: 0.18;
    border-radius: 50%;
}
.quality__content, .quality__schools, .cms-section--quality .cms-section__inner { position: relative; z-index: 1; }
/* On the dark background here, the shared h2 default's dark-teal color would be nearly
   invisible — stay with the section's own white text instead. */
.quality h2, .cms-section--quality h2 { color: inherit; }
.quality p, .cms-section--quality p { font-size: 1.05rem; opacity: 0.92; margin: 0 0 1.5rem; }

.tag-list, .cms-list--tags { display: flex; gap: 0.75rem; flex-wrap: wrap; }
/* color: inherit beats :where(.cms-list)'s color (further down this file) — that generic
   base rule is meant for plain lists, not this dark-background pill/tag variant, but as a
   direct declaration on the same element it would otherwise win over inheriting the
   section's white text regardless of specificity. */
.cms-list--tags { list-style: none; padding: 0; margin: 0; color: inherit; }
.tag, .cms-list--tags li {
    background: rgba(255, 255, 255, 0.12);
    border: 1px solid rgba(255, 255, 255, 0.25);
    border-radius: 999px;
    padding: 0.5rem 1.1rem;
    font-size: 0.9rem;
    font-weight: 600;
}

.quality__eyebrow {
    display: inline-block;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 0.8rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-primary-dark);
    background: var(--color-accent);
    padding: 0.4rem 0.9rem;
    border-radius: 999px;
    margin-bottom: 1rem;
}
.quality__schools h3, .cms-section--quality h3 { font-size: 1.3rem; color: inherit; }

.school-pills, .cms-list--pills { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.cms-list--pills { list-style: none; padding: 0; margin: 0; color: inherit; }
.school-pill, .cms-list--pills li {
    background: rgba(255, 255, 255, 0.1);
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 999px;
    padding: 0.4rem 0.85rem;
    font-size: 0.82rem;
    font-weight: 600;
}

/* Contact mini CTA */
.contact-mini, .cms-section--contact-mini { margin-top: 4.5rem; }
.contact-mini__inner, .cms-section--contact-mini .cms-section__inner {
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 1.5rem 2rem;
}
.contact-mini__inner { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 1rem; }
.contact-mini__inner span, .cms-section--contact-mini .cms-section__inner p { font-family: var(--font-display); font-weight: 600; font-size: 1.15rem; color: var(--color-primary-dark); margin: 0; }
.contact-mini .btn-primary, .cms-section--contact-mini .cms-button--cta { font-size: 0.95rem; padding: 0.65rem 1.5rem; }

/* Hero (generic page-title banner used on all pages except the homepage) */
/* .cms-section--hero is the CMS page-builder's generic equivalent of this same component
   (see cms-core's section.php "variant" setting) — kept as an alias so migrated pages render
   pixel-identical to these hardcoded templates without ever editing the rules below. Left/right
   padding is set separately for the two (see below): .hero (the static utility pages) never sat
   inside .cms-section__inner and needs nothing extra; .cms-section--hero used to get an extra
   1.5rem/24px each side stacked from .cms-section__inner's own padding — now that
   .cms-section__inner carries none of its own (.container, the CMS page wrapper, provides that
   layer once for every top-level block instead), reproducing that same 1.5rem here keeps this
   variant's text sitting exactly where it always has. */
.hero, .cms-section--hero {
    background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-primary-dark) 100%);
    color: #fff;
    border-radius: var(--radius-lg);
    padding-top: 3rem;
    padding-bottom: 3rem;
    margin-top: 2rem;
    margin-bottom: 2rem;
    position: relative;
    overflow: hidden;
}
.hero { padding-left: 2rem; padding-right: 2rem; }
.cms-section--hero { padding-inline: clamp(1rem, 4.5vw, 3.5rem); }

.hero::before, .cms-section--hero::before {
    content: '';
    position: absolute;
    top: -70px;
    right: -70px;
    width: 220px;
    height: 220px;
    background: var(--color-accent);
    opacity: 0.35;
    border-radius: 50%;
}

.hero::after, .cms-section--hero::after {
    content: '';
    position: absolute;
    bottom: -90px;
    left: 8%;
    width: 170px;
    height: 170px;
    background: var(--color-accent);
    opacity: 0.18;
    border-radius: 50%;
}

.hero h1, .hero p, .hero a,
.cms-section--hero h1, .cms-section--hero p, .cms-section--hero a {
    position: relative;
    z-index: 1;
}

.hero h1, .cms-section--hero h1 { font-size: clamp(1.4rem, 4.5vw, 2rem); margin-top: 0; }
.hero p, .cms-section--hero p { font-size: 1.1rem; max-width: 60ch; }
.hero a, .cms-section--hero a {
    color: #fff;
    text-decoration: underline;
}

/* Formule (pricing) card — .cms-section--card is the CMS alias, same rationale as .hero above
   (including the same left/right padding split, same reasoning: compensates for the 1.5rem
   .cms-section__inner no longer contributes on the CMS-rendered side only). */
.formule-card, .cms-section--card {
    background: #fff;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-card);
    padding-top: 2rem;
    padding-bottom: 2rem;
    margin-top: 2rem;
    margin-bottom: 2rem;
}
.formule-card { padding-left: 2rem; padding-right: 2rem; }
.cms-section--card { padding-left: 3.5rem; padding-right: 3.5rem; }

/* h3's color and h3/h4's margin are all the shared default now (see the h2/h3/h4 rules up
   top) — h4 stays uncolored on purpose, reading as a plainer sub-heading, not a second h3. */

.notice-unavailable, .cms-richtext--notice {
    background: var(--color-bg-alt);
    border-left: 4px solid var(--color-accent-dark);
    border-radius: var(--radius-md);
    padding: 0.75rem 1rem;
    margin-bottom: 1rem;
    font-style: italic;
    color: var(--color-text-muted);
}

.price-badge, .cms-richtext--badge {
    display: flex;
    max-width: max-content;
    background: var(--color-accent);
    color: var(--color-text);
    font-weight: 700;
    border-radius: 999px;
    padding: 0.35rem 1rem;
    margin: 0.5rem 0 1rem;
}

.price-tiers, .cms-list--tiers {
    list-style: none;
    padding: 0;
    margin: 0 0 1rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.price-tiers li, .cms-list--tiers li {
    background: var(--color-primary-light);
    border-radius: var(--radius-md);
    padding: 0.6rem 1rem;
    font-weight: 600;
    color: var(--color-primary-dark);
}

.terms-list, .cms-list--terms, .cms-richtext--muted { padding-left: 1.2rem; color: var(--color-text-muted); }

/* Forms */
.form-field { margin-bottom: 1.1rem; display: flex; flex-direction: column; gap: 0.35rem; }
.form-row { display: flex; gap: 1rem; }
.form-row .form-field { flex: 1; min-width: 0; }
@media (max-width: 640px) {
    .form-row { flex-direction: column; gap: 0; }
}
.form-field label { font-weight: 600; }
.form-field input,
.form-field textarea {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 0.65rem 0.85rem;
    font-family: inherit;
    font-size: 1rem;
}
.form-field .error,
.form-field.error {
    color: #b3261e;
    font-size: 0.9rem;
}
.form-honeypot { position: absolute; left: -9999px; }
.form-success {
    background: var(--color-primary-light);
    border: 1px solid var(--color-primary);
    border-radius: var(--radius-md);
    padding: 1rem 1.25rem;
    margin-bottom: 1.5rem;
}

.form-field--checkbox label { display: flex; align-items: center; gap: 0.5rem; font-weight: 500; cursor: pointer; }
.form-field--checkbox input[type="checkbox"] { width: 18px; height: 18px; margin: 0; accent-color: var(--color-primary); cursor: pointer; }

fieldset.form-field { border: none; padding: 0; margin: 0 0 1.1rem; }
fieldset.form-field legend { font-weight: 600; padding: 0; margin-bottom: 0.35rem; }
.form-field__option { display: flex; align-items: center; gap: 0.5rem; font-weight: 500; margin-bottom: 0.4rem; cursor: pointer; }

/* Booking (reservation) form */
.booking-form-page, .booking-form { max-width: 640px; }
.booking-form__errors {
    background: #fdecea;
    border: 1px solid #b3261e;
    border-radius: var(--radius-md);
    padding: 0.85rem 1.1rem;
    margin-bottom: 1.25rem;
    color: #b3261e;
}
.booking-form__errors p { margin: 0.2rem 0; }
.booking-form__full {
    background: var(--color-bg-alt);
    border-radius: var(--radius-md);
    padding: 1rem 1.25rem;
    color: var(--color-text-muted);
}
.booking-form-inline {
    max-width: 640px;
    margin-top: 1.5rem;
    background: #f1f7f7;
    padding: 2rem;
    border-radius: 1rem;
}

/* Footer */
.site-footer {
    background: var(--color-primary);
    margin-top: 4.5rem;
    padding: 2.5rem 1.5rem 0;
}
.site-footer__inner {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 1rem 2rem;
    padding-bottom: 1.75rem;
}
.site-footer__brand { display: flex; align-items: center; gap: 0.75rem; }
.site-footer__brand img { height: 34px; }
.site-footer p, .site-footer span { color: rgba(255, 255, 255, 0.85); font-size: 0.9rem; margin: 0; }
.site-footer a { color: var(--color-accent); }

/* Admin-picked list (Configuration > Liens du pied de page) — a plain flex-wrap row rather than
   a fixed count of columns, so it keeps reading cleanly whether one page is picked or a dozen:
   short lists sit on one line, long ones wrap without ever overflowing or squeezing the brand
   block on the other side of .site-footer__inner. */
.site-footer__links {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.5rem;
    list-style: none;
    margin: 0;
    padding: 0;
}
.site-footer__links a { font-weight: 500; font-size: 0.8rem; }
.site-footer__bottom {
    /* padding-top/bottom only — a shorthand `padding` here would overwrite (not merge with)
       .container's own left/right padding, since both rules carry equal specificity and this
       one is declared later: the exact bug that misaligned the copyright line 24px left of the
       brand/links row above it during review. */
    border-top: 1px solid rgba(255, 255, 255, 0.15);
    padding-top: 1.25rem;
    padding-bottom: 1.25rem;
}
.site-footer__bottom span { font-size: 0.8rem; }

/* Cookie consent notice (public/assets/js/cookie-consent.js) — shown once until a choice is
   made, reopenable any time via the "Gérer les cookies" footer link above. */
.cookie-banner {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 30;
    background: #fff;
    box-shadow: 0 -10px 30px rgba(23, 130, 137, 0.16);
}
.cookie-banner__inner {
    max-width: 1180px;
    margin: 0 auto;
    padding: 1.25rem 1.5rem;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 1rem 2rem;
}
.cookie-banner__inner p { flex: 1 1 420px; margin: 0; font-size: 0.9rem; color: var(--color-text); }
.cookie-banner__actions { display: flex; gap: 0.75rem; flex-wrap: wrap; flex-shrink: 0; }
.cookie-banner__actions .btn { padding: 0.6rem 1.4rem; font-size: 0.9rem; }

@media (max-width: 900px) {
    .home-hero, .mission, .quality, .activity-grid,
    .cms-section--home-hero .cms-section__inner,
    .cms-activity-grid,
    .cms-section--mission .cms-group--layout-columns[data-cms-columns],
    .cms-section--quality .cms-group--layout-columns[data-cms-columns] { grid-template-columns: 1fr; }
    .home-hero__media, .cms-group--hero-media { order: -1; }
}

/* Nav gets its own breakpoint, well above the 900px content one: at 900-1120px the desktop nav
   (~726px wide) no longer fits next to the 300px logo and wraps onto its own row instead of
   collapsing into the burger menu — this is measured against the actual nav width, not guessed. */
@media (max-width: 1180px) {
    .site-header__inner { justify-content: flex-start; }

    .menu-toggle { display: flex; order: -1; margin-left: 0; }

    .main-nav {
        display: none;
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        flex-direction: column;
        align-items: stretch;
        gap: 0;
        background: var(--color-primary-dark);
        padding: 0.5rem 1.5rem 1.5rem;
    }

    .main-nav.is-open { display: flex; }

    .main-nav a {
        padding: 0.85rem 0;
        border-bottom: 1px solid rgba(255, 255, 255, 0.15);
    }

    /* The CTA pill keeps its own horizontal padding — the generic rule above would otherwise
       squash it down to a near-circle (padding: 0.85rem 0 zeroes out its left/right space). */
    .main-nav a.nav-cta { padding: 0.6rem 1.3rem; }

    .nav-item-dropdown {
        display: flex;
        flex-wrap: wrap;
        align-items: stretch;
        justify-content: space-between;
        flex-direction: row;
        width: 100%;
    }

    .nav-item-dropdown > a { flex: 1; }

    /* The arrow inside the link is purely decorative on desktop (hover opens the dropdown) — on
       mobile the real, tappable control is .dropdown-toggle below, so this would just be a
       confusing second, non-functional chevron next to it. */
    .dropdown-toggle-arrow { display: none; }

    /* Now the actual visible/tappable control (overrides the desktop hidden state above): a
       real touch target separate from the link, which always navigates on tap and never opens
       the submenu by itself. */
    .dropdown-toggle {
        position: static;
        width: 44px;
        height: 44px;
        overflow: visible;
        clip: auto;
        white-space: normal;
        display: flex;
        align-items: center;
        justify-content: center;
        flex-shrink: 0;
        color: #fff;
        cursor: pointer;
    }

    .dropdown-toggle__icon { font-size: 0.9rem; transition: transform .15s; }
    .nav-item-dropdown.is-open .dropdown-toggle__icon { transform: rotate(180deg); }

    .dropdown-menu {
        position: static;
        display: none;
        background: transparent;
        border: none;
        box-shadow: none;
        padding: 0 0 0.5rem 1rem;
        margin: 0;
        min-width: 0;
        width: 100%;
    }

    .nav-item-dropdown:hover .dropdown-menu,
    .nav-item-dropdown:focus-within .dropdown-menu {
        display: none;
    }

    .nav-item-dropdown.is-open .dropdown-menu { display: block; }

    .dropdown-menu li a {
        color: #fff;
        padding: 0.75rem 0;
        border-bottom: none;
    }
    .dropdown-menu li a:hover { background: none; color: var(--color-accent); }

    .nav-cta { align-self: flex-start; margin-top: 0.75rem; }
}

@media (max-width: 640px) {
    .logo img { width: 220px; }
    .hero { padding: 2rem 1.25rem; }
}

/* Below 500px, the hardcoded "cadre" look (border/shadow/background/padding) on
   .formule-card/.cms-section--card just eats space a small screen can't spare — drop it and let
   the surrounding page/container padding carry the edge instead. !important on the shorthand is
   needed because .cms-section--card can carry an inline padding-top/bottom style from the
   section's own admin-configurable "Espacement interne" setting (see cms-core's section.php). */
@media (max-width: 500px) {
    .formule-card, .cms-section--card {
        padding: 0 !important;
        background: transparent;
        box-shadow: none;
        border: none;
    }

    .booking-form-inline {
        background: #fff;
        padding: 1rem;
    }

    .price-badge, .cms-richtext--badge {
        border-radius: 10px;
    }

    .site-header__inner { padding: 0 1rem; }

    .site-footer { padding: 1rem 0 0; }
}

/* CMS block structure (added by cms-core integration, Task 18) */
/* Sections briefly carried their own horizontal containment here (max-width/margin/padding on
   .cms-section__inner, independent of the page) so a section's background could bleed edge to
   edge if a variant wanted that — no variant ever actually did except the 3 that already have
   a border-radius'd card look of their own (hero/card/quality, which set their own padding
   earlier in this file), so that flexibility bought nothing and cost every OTHER top-level block (the page's
   own <h1>, a bare image/text promoted out of a "Cadre") a second, separately-maintained
   containment rule to stay visually aligned with it. All of that now lives in one place —
   .container, wrapped around the whole page in cms-page.php — and .cms-section__inner is back to
   being a plain flow/grid wrapper with no width or padding of its own. Rules that still target it
   for a specific variant (the home-hero grid, quality's z-index) are unaffected by this and
   remain below. */

.cms-group--layout-stack { display: flex; flex-direction: column; }
/* Same fix as the align-start/-center/-end block below for columns/grid, same reason: without
   it a stack group defaults to align-items:stretch, so an inline-block child (a chip/badge, a
   button) gets stretched to the group's full width instead of shrink-wrapping its own content. */
.cms-group--layout-stack.cms-group--align-start { align-items: flex-start; }
.cms-group--layout-stack.cms-group--align-center { align-items: center; }
.cms-group--layout-stack.cms-group--align-end { align-items: flex-end; }
.cms-group--layout-row { display: flex; flex-direction: row; flex-wrap: wrap; gap: 1rem; }
.cms-group--layout-row.cms-group--align-center { justify-content: center; }
.cms-group--layout-row.cms-group--align-end { justify-content: flex-end; }
.cms-group--layout-row.cms-group--align-space-between { justify-content: space-between; align-items: center; }
.cms-group--layout-columns,
.cms-group--layout-grid { display: grid; gap: 1.5rem; }
/* Without this, a grid cell defaults to align-items:stretch — a short item (e.g. a button)
   sharing a row with a taller one (e.g. an image) gets its own box stretched to match, and a
   pill-shaped button stretched tall turns into a huge oval with its label stuck at the top
   instead of centered. "start" mirrors group.php's own default so most groups get the fix
   without having to touch the Align field at all. */
.cms-group--layout-columns.cms-group--align-start,
.cms-group--layout-grid.cms-group--align-start { align-items: start; }
.cms-group--layout-columns.cms-group--align-center,
.cms-group--layout-grid.cms-group--align-center { align-items: center; }
.cms-group--layout-columns.cms-group--align-end,
.cms-group--layout-grid.cms-group--align-end { align-items: end; }
.cms-group--layout-columns[data-cms-columns="2"],
.cms-group--layout-grid[data-cms-columns="2"] { grid-template-columns: repeat(2, 1fr); }
.cms-group--layout-columns[data-cms-columns="3"],
.cms-group--layout-grid[data-cms-columns="3"] { grid-template-columns: repeat(3, 1fr); }
.cms-group--layout-columns[data-cms-columns="4"],
.cms-group--layout-grid[data-cms-columns="4"] { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 640px) {
    .cms-group--layout-columns[data-cms-columns],
    .cms-group--layout-grid[data-cms-columns] { grid-template-columns: 1fr; }
}

.cms-button--primary { display: inline-block; background: var(--color-primary); color: #fff; font-weight: 700; font-size: 0.9rem; line-height: 1; border: none; border-radius: 999px; padding: 0.75rem 1.75rem; text-decoration: none; cursor: pointer; }
.cms-button--primary:hover {
    color: #fff;
    background: #22979f;
}
.cms-button--secondary { display: inline-block; background: transparent; color: var(--color-primary-dark); font-weight: 700; border: 2px solid var(--color-primary); border-radius: 999px; padding: 0.7rem 1.7rem; text-decoration: none; cursor: pointer; }
.cms-button--secondary:hover { background: var(--color-primary-light); color: var(--color-primary-dark); }
.cms-button-align--center { text-align: center; }
.cms-button-align--right { text-align: right; }

.cms-galerie { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; }
.cms-galerie__item img { width: 100%; border-radius: var(--radius-md); }
.cms-galerie[data-cms-columns="2"] { grid-template-columns: repeat(2, 1fr); }
.cms-galerie[data-cms-columns="3"] { grid-template-columns: repeat(3, 1fr); }
.cms-galerie[data-cms-columns="4"] { grid-template-columns: repeat(4, 1fr); }
/* "structurée" fit: every thumbnail forced into the same fixed-shape box (cropped, not
   letterboxed) instead of each keeping its own natural aspect ratio — ratio only matters here,
   since "auto" fit has no box for it to apply to. */
.cms-galerie[data-cms-fit="structuree"] .cms-galerie__item { aspect-ratio: 4 / 3; overflow: hidden; }
.cms-galerie[data-cms-fit="structuree"][data-cms-ratio="carre"] .cms-galerie__item { aspect-ratio: 1; }
.cms-galerie[data-cms-fit="structuree"] .cms-galerie__item img { width: 100%; height: 100%; object-fit: cover; }
@media (max-width: 640px) {
    .cms-galerie[data-cms-columns="3"],
    .cms-galerie[data-cms-columns="4"] { grid-template-columns: repeat(2, 1fr); }
}

.cms-video-facade { position: relative; display: block; width: 100%; border: none; padding: 0; cursor: pointer; background: none; }
.cms-video-facade img { width: 100%; border-radius: var(--radius-md); }
.cms-video-facade__play { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 3rem; color: #fff; text-shadow: 0 2px 8px rgba(0,0,0,0.4); }
.cms-video-iframe { width: 100%; aspect-ratio: 16 / 9; border: none; border-radius: var(--radius-md); }
.cms-video-facade--no-thumbnail { aspect-ratio: 16 / 9; background: var(--color-primary-dark); border-radius: var(--radius-md); }
.cms-video { width: 100%; border-radius: var(--radius-md); }

.cms-table { width: 100%; border-collapse: collapse; margin: 0 0 1.5rem; }
.cms-table td { padding: 0.6rem 0.9rem; border: 1px solid var(--color-border); }

/* Zero-specificity on purpose (same :where() technique used elsewhere in this file): a plain
   .cms-list (no variant) should get this base look, but must always lose to any
   .cms-list--{variant} modifier rule regardless of which appears later in the file — the exact
   trap that other margin/padding shorthand collisions in this file caused before. list-style is
   split off by tag so an <ol class="cms-list"> (numbered) doesn't inherit the <ul> bullet. */
:where(.cms-list) { padding-left: 1.2rem; margin: 0 0 1.5rem; color: var(--color-text); }
:where(ul.cms-list) { list-style: disc; }
:where(ol.cms-list) { list-style: decimal; }

.cms-image-texte { display: flex; gap: 1.5rem; align-items: center; flex-wrap: wrap; }
.cms-image-texte--image-right { flex-direction: row-reverse; }
.cms-image-texte__image { max-width: 320px; border-radius: var(--radius-md); flex: 1 1 280px; }
.cms-image-texte__text { flex: 1 1 320px; }

.cms-separateur { border: none; border-top: 1px solid var(--color-border); }
.cms-separateur--epais { border-top-width: 3px; }

.cms-image { margin: 0; }
.cms-image img { display: block; max-width: 100%; max-height: 700px; border-radius: 1rem; }
.cms-image--compact img { max-width: 320px; }
.cms-image--showcase img { border-radius: var(--radius-lg); box-shadow: var(--shadow-card); }

/* Homepage "chip" badge — .home-hero__badge and .quality__eyebrow are two separate,
   pre-existing static rules (never sharing a selector with each other, different background
   colors). cms-richtext--chip is the single generic abstraction for both; kept standalone
   rather than merged into either static rule so neither original is touched. */
.cms-richtext--chip {
    display: inline-block;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 0.8rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-primary-dark);
    padding: 0.4rem 0.9rem;
    border-radius: 999px;
    margin-bottom: 1rem;
}
.cms-section--home-hero .cms-richtext--chip { background: var(--color-primary-light); margin-bottom: 1.25rem; }
.cms-section--quality .cms-richtext--chip { background: var(--color-accent); }

/* Shown only when a logged-in admin previews an inactive page at its own slug (see
   App\Content\PublicPageRenderer) — a visiting public user never sees this, since
   CmsPageController::renderPage() itself still refuses to render an inactive page at all. */
.page-inactive-banner {
    margin: 0;
    padding: 0.65rem 1.5rem;
    background: #fff3cd;
    color: #664d03;
    text-align: center;
    font-size: 0.9rem;
    font-weight: 600;
}
