@layer components {
  /* brand lockup */
  .brand {
    display: inline-flex;
    align-items: center;
    gap: var(--space-sm);
    color: var(--color-text);
    text-decoration: none;
  }
  .brand .logo-mark { inline-size: 1.5rem; block-size: auto; color: var(--color-text); }
  .brand__name { font-family: var(--font-heading); font-weight: 600; font-size: var(--fs-0); white-space: nowrap; }
  @media (min-width: 480px) {
    .brand__name { font-size: var(--fs-1); }
  }

  /* nav: hamburger disclosure on small screens (full-height overlay panel),
     inline row from 768px (js forces the disclosure open) */
  .nav-disclosure > summary {
    list-style: none;
    cursor: pointer;
    inline-size: 44px;
    min-block-size: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-sm);
  }
  .nav-disclosure > summary::-webkit-details-marker { display: none; }
  .nav-icon { display: block; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
  .nav-icon line {
    /* M28 (D9): fill-box makes transform-origin: center each line's own centre,
       not the SVG's, which is what Safari needs to draw a straight X. */
    transform-box: fill-box;
    transform-origin: center;
    transition: transform var(--dur-mid) var(--ease), opacity var(--dur-fast) var(--ease);
  }
  /* open state: the three lines morph into an X (the universal close) */
  .nav-disclosure[open] .nav-icon__top { transform: translateY(6px) rotate(45deg); }
  .nav-disclosure[open] .nav-icon__mid { opacity: 0; }
  .nav-disclosure[open] .nav-icon__bot { transform: translateY(-6px) rotate(-45deg); }
  /* absolute (not fixed): the header's backdrop-filter makes it the containing
     block for fixed descendants, which would clip the panel to the header.
     M22: the panel holds the link list and a foot (the next evening, the social links). */
  .nav-panel {
    position: absolute;
    inset-inline: 0;
    inset-block-start: var(--header-h);
    block-size: calc(100svh - var(--header-h));
    z-index: var(--z-overlay);
    overflow-y: auto;
    display: grid;
    align-content: start;
    gap: var(--space-xl);
    padding: var(--space-xl) var(--gutter) max(var(--space-xl), env(safe-area-inset-bottom));
    background: var(--color-bg);
  }
  .nav-panel > ul { display: grid; gap: var(--space-xs); }
  .nav-panel > ul a {
    display: flex;
    align-items: center;
    min-block-size: 48px;
    color: var(--color-text);
    text-decoration: none;
    font-family: var(--font-heading);
    font-size: var(--fs-2);
    font-weight: 600;
  }
  .nav-panel > ul a:hover { color: var(--color-accent); }
  .nav-panel > ul a[aria-current="page"] {
    color: var(--color-accent);
    text-decoration: underline;
    text-underline-offset: .3em;
  }
  .nav-foot { display: grid; gap: var(--space-md); border-block-start: var(--border); padding-block-start: var(--space-lg); }
  .nav-foot__label { font-size: var(--fs--1); font-weight: 600; text-transform: uppercase; letter-spacing: .08em; color: var(--color-text-muted); }
  body.panel-open { overflow: hidden; }
  /* M28 (D9): the panel slides and fades in, its links cascading behind it, and
     the close reverses it (js/nav.js holds the disclosure open for the closing
     animation). Reduced motion gets a panel that is simply there. */
  @media (max-width: 767px) and (prefers-reduced-motion: no-preference) {
    .nav-disclosure[open] .nav-panel { animation: nav-panel-in var(--dur-mid) var(--ease) both; }
    .nav-disclosure[open] .nav-panel > ul > li,
    .nav-disclosure[open] .nav-panel .nav-foot { animation: nav-item-in var(--dur-mid) var(--ease) both; }
    .nav-disclosure[open] .nav-panel > ul > li:nth-child(1) { animation-delay: 60ms; }
    .nav-disclosure[open] .nav-panel > ul > li:nth-child(2) { animation-delay: 100ms; }
    .nav-disclosure[open] .nav-panel > ul > li:nth-child(3) { animation-delay: 140ms; }
    .nav-disclosure[open] .nav-panel > ul > li:nth-child(4) { animation-delay: 180ms; }
    .nav-disclosure[open] .nav-panel > ul > li:nth-child(5) { animation-delay: 220ms; }
    .nav-disclosure[open] .nav-panel .nav-foot { animation-delay: 260ms; }
    .nav-disclosure.is-closing .nav-panel { animation: nav-panel-out var(--dur-fast) var(--ease) both; }
    .nav-disclosure.is-closing .nav-panel > ul > li,
    .nav-disclosure.is-closing .nav-panel .nav-foot { animation: nav-item-out var(--dur-fast) var(--ease) both; animation-delay: 0s; }
  }
  @keyframes nav-panel-in { from { opacity: 0; transform: translateY(-1rem); } to { opacity: 1; transform: none; } }
  @keyframes nav-panel-out { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(-1rem); } }
  @keyframes nav-item-in { from { opacity: 0; transform: translateY(.75rem); } to { opacity: 1; transform: none; } }
  @keyframes nav-item-out { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(.5rem); } }
  @media (min-width: 768px) {
    .nav-disclosure > summary { display: none; }
    .nav-panel {
      position: static;
      block-size: auto;
      display: block;
      background: none;
      padding: 0;
      overflow: visible;
    }
    .nav-panel > ul { display: flex; gap: var(--space-lg); }
    .nav-panel > ul a {
      min-block-size: 44px;
      font-family: var(--font-body);
      font-size: var(--fs-0);
      font-weight: 500;
    }
    .nav-foot { display: none; }
  }

  /* language toggle: two letters (M7); since M22 a plain link (shareable, opens in a new tab), left of the hamburger */
  .lang-switch {
    margin-inline-start: auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: 1px solid var(--color-control-border);
    border-radius: var(--radius-pill);
    min-block-size: 44px;
    min-inline-size: 44px;
    padding-inline: var(--space-sm);
    color: var(--color-text);
    text-decoration: none;
    font-size: var(--fs--1);
    font-weight: 600;
    letter-spacing: .04em;
  }
  @media (min-width: 768px) {
    .site-nav { order: 1; margin-inline-start: auto; }
    .lang-switch { order: 2; margin-inline-start: 0; }
  }
  .lang-switch:hover { border-color: var(--color-accent); color: var(--color-accent); }

  /* buttons */
  .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-xs);
    min-block-size: 44px;
    padding: var(--space-xs) var(--space-lg);
    border: 0;
    border-radius: var(--radius-pill);
    background: var(--color-accent);
    color: var(--color-accent-contrast);
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    transition: background var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
  }
  .btn:hover { background: color-mix(in oklab, var(--color-accent), #000 12%); }
  .btn:active { transform: translateY(1px); }
  .btn--ghost {
    background: transparent;
    color: var(--color-accent);
    box-shadow: inset 0 0 0 1px currentColor;
  }
  .btn--ghost:hover { background: color-mix(in srgb, var(--color-accent) 10%, transparent); }
  .btn--small { font-size: var(--fs--1); padding-inline: var(--space-md); }
  .btn--large { font-size: var(--fs-1); min-block-size: 56px; padding: var(--space-sm) var(--space-xl); }  /* M32: the About page's closing action */

  /* hero */
  /* viewport-tall with the copy at the foot: 60svh, then 86svh from 900 px. The height
     holds while the window narrows and steps once, instead of drifting with the width. */
  .hero {
    position: relative;
    min-block-size: 60svh;
    display: flex;
    align-items: flex-end;
    padding-block: var(--space-2xl) var(--space-xl);
    isolation: isolate;
    overflow: clip;
    background: var(--color-ink);
  }
  @media (min-width: 900px) {
    .hero { min-block-size: 86svh; padding-block-end: var(--space-2xl); }
  }
  .hero__image { position: absolute; inset: 0; z-index: -2; width: 100%; height: 100%; object-fit: cover; }
  .hero::before { content: ""; position: absolute; inset: 0; z-index: -1; background: linear-gradient(180deg, color-mix(in oklab, var(--color-ink), transparent 15%), color-mix(in oklab, var(--color-ink), transparent 45%)); }
  .hero .logo-mark { inline-size: clamp(3.5rem, 2.5rem + 5vw, 6rem); color: var(--color-cream); margin-block-end: var(--space-lg); }
  .hero h1 { max-inline-size: 22ch; color: var(--color-cream); }
  .hero__actions { display: flex; flex-wrap: wrap; gap: var(--space-md); margin-block-start: var(--space-xl); }
  .hero__actions .btn--ghost { color: var(--color-cream); }
  /* M22: the focus ring on the two dark grounds: cream ring (15:1 on ink), ink halo keeps it off the picture */
  .hero, .site-footer { --color-focus: var(--color-cream); --color-focus-halo: var(--color-ink); }
  /* M30, generalised in M32: the point of a picture kept in view on every screen (SiteImage.image_focus_x/y, in steps of 5) */
  .focus { object-position: var(--fx, 50%) var(--fy, 50%); }
  .focus--x0 { --fx: 0%; }
  .focus--x5 { --fx: 5%; }
  .focus--x10 { --fx: 10%; }
  .focus--x15 { --fx: 15%; }
  .focus--x20 { --fx: 20%; }
  .focus--x25 { --fx: 25%; }
  .focus--x30 { --fx: 30%; }
  .focus--x35 { --fx: 35%; }
  .focus--x40 { --fx: 40%; }
  .focus--x45 { --fx: 45%; }
  .focus--x50 { --fx: 50%; }
  .focus--x55 { --fx: 55%; }
  .focus--x60 { --fx: 60%; }
  .focus--x65 { --fx: 65%; }
  .focus--x70 { --fx: 70%; }
  .focus--x75 { --fx: 75%; }
  .focus--x80 { --fx: 80%; }
  .focus--x85 { --fx: 85%; }
  .focus--x90 { --fx: 90%; }
  .focus--x95 { --fx: 95%; }
  .focus--x100 { --fx: 100%; }
  .focus--y0 { --fy: 0%; }
  .focus--y5 { --fy: 5%; }
  .focus--y10 { --fy: 10%; }
  .focus--y15 { --fy: 15%; }
  .focus--y20 { --fy: 20%; }
  .focus--y25 { --fy: 25%; }
  .focus--y30 { --fy: 30%; }
  .focus--y35 { --fy: 35%; }
  .focus--y40 { --fy: 40%; }
  .focus--y45 { --fy: 45%; }
  .focus--y50 { --fy: 50%; }
  .focus--y55 { --fy: 55%; }
  .focus--y60 { --fy: 60%; }
  .focus--y65 { --fy: 65%; }
  .focus--y70 { --fy: 70%; }
  .focus--y75 { --fy: 75%; }
  .focus--y80 { --fy: 80%; }
  .focus--y85 { --fy: 85%; }
  .focus--y90 { --fy: 90%; }
  .focus--y95 { --fy: 95%; }
  .focus--y100 { --fy: 100%; }
  /* M18: the admin-managed hero images crossfade (js/hero.js toggles is-active) */
  .hero__images { position: absolute; inset: 0; z-index: -2; }
  .hero__images .hero__image { opacity: 0; transition: opacity 1.5s ease; }
  .hero__images .hero__image.is-active { opacity: 1; }
  @media (prefers-reduced-motion: reduce) {
    .hero__images .hero__image { transition: none; }
  }

  /* M18: the Instagram strip on the home page, photos only */
  .insta-grid { display: grid; gap: var(--space-md); grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); }
  .insta-grid img { inline-size: 100%; aspect-ratio: 1; object-fit: cover; border-radius: var(--radius-lg); display: block; }

  /* M22: the home page's « Ce qui se passe ici » and the two kinds of evening */
  .lede { font-size: var(--fs-1); max-inline-size: 40ch; }
  .kinds { display: grid; gap: var(--space-md); }
  @media (min-width: 640px) { .kinds { grid-template-columns: 1fr 1fr; } }
  .kinds__card { background: var(--color-surface); border: var(--border); border-block-start: 4px solid var(--color-cat-connect); border-radius: var(--radius-lg); padding: var(--space-lg); display: grid; gap: var(--space-xs); align-content: start; }
  .kinds__card--danse { border-block-start-color: var(--color-cat-danse); }
  .kinds__card h3 { font-size: var(--fs-1); }
  .home-more { display: flex; justify-content: flex-end; }

  /* ---------- M32: the About page as an editorial spread ---------- */
  /* Same words, re-set on a twelve-column grid from 900 px: a typographic
     opening, the group photo at the feature width, the mission as a poster,
     the values in three columns, a full-bleed band, the place, two portraits
     and one button. Square corners on every picture here (D15.1). The three
     placements whose frame changes with the screen wear the .focus classes
     (the point kept in view); the values and the portraits are cut at 4:5.
     Full bleed comes from a section with no side padding, never from a viewport width
     (reset.css keeps the scrollbar gutter stable). */
  .about .section { padding-block: 0; }
  .about > .section + .section { margin-block-start: var(--space-section); }
  .about-hero__copy { padding-block-start: var(--space-xl); padding-inline: var(--gutter); display: grid; gap: var(--space-lg); justify-items: start; }
  .about-eyebrow { display: flex; align-items: center; gap: var(--space-sm); font-size: var(--fs--1); font-weight: 600; text-transform: uppercase; letter-spacing: .12em; }
  .about-eyebrow::before { content: ""; inline-size: 2.5rem; block-size: 1px; background: currentColor; }
  .about-more { display: inline-flex; align-items: center; gap: var(--space-md); font-size: var(--fs--1); font-weight: 600; text-transform: uppercase; letter-spacing: .12em; text-decoration: none; color: inherit; margin-block-start: var(--space-md); }
  .about-more:hover .about-more__arrow { transform: translateY(0.25rem); }
  .about-more__arrow { transition: transform .3s ease; }
  .about-hero__media { margin-block-start: var(--space-xl); }
  .about-grid { display: grid; gap: var(--space-lg); }
  .about-title { font-size: var(--fs-display); line-height: 1.02; letter-spacing: -0.02em; }
  .about-intro { font-size: var(--fs-1); max-inline-size: 36rem; display: grid; gap: var(--space-md); }
  .about-intro p { max-inline-size: none; }
  .about-heading { font-size: var(--fs-5); margin-block-end: var(--space-xl); }
  .about-label { font-family: var(--font-body); font-size: var(--fs--1); font-weight: 600; text-transform: uppercase; letter-spacing: .08em; color: var(--color-text-muted); }
  .about-statement { font-family: var(--font-heading); font-weight: 600; font-size: var(--fs-5); line-height: 1.2; letter-spacing: -0.01em; text-wrap: balance; max-inline-size: 56rem; }
  .about-statement p { max-inline-size: none; }
  .about-photo { display: block; inline-size: 100%; object-fit: cover; border-radius: 0; }
  .about-photo--header { aspect-ratio: 4 / 3; }
  .about-photo--wide { aspect-ratio: 3 / 2; }
  .about-photo--place { aspect-ratio: 3 / 2; }
  .about-photo--place-wide { aspect-ratio: 3 / 2; }
  .about-photo--portrait { aspect-ratio: 4 / 5; }
  .about-feature { width: 100%; max-inline-size: var(--container-feature); margin-inline: auto; }
  .about-bleed { width: 100%; }
  .values, .hosts { display: grid; gap: var(--space-2xl) var(--space-lg); }
  .value, .host, .place__text { display: grid; gap: var(--space-md); align-content: start; }
  .value h3, .host h3 { font-size: var(--fs-2); margin-block-start: var(--space-xs); }
  .host__photo--empty { display: grid; place-items: center; background: var(--color-surface); color: var(--color-text-muted); }
  .host__photo--empty .logo-mark { inline-size: 3rem; block-size: auto; }
  .place { gap: var(--space-lg); }
  .about-close { text-align: center; }
  @media (min-width: 900px) {
    .about-grid { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--space-lg); }
    .about-hero--split { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); min-block-size: calc(100svh - var(--header-h)); }
    .about-hero--split .about-hero__copy { justify-self: end; inline-size: 100%; max-inline-size: calc(var(--container) / 2); align-content: center; padding-block: var(--space-2xl); }
    .about-hero__media { position: relative; margin-block-start: 0; }
    .about-hero--split .about-photo--header { position: absolute; inset: 0; block-size: 100%; aspect-ratio: auto; }
    .about-hero:not(.about-hero--split) .about-hero__copy { max-inline-size: var(--container); margin-inline: auto; }
    .about-label { grid-column: 1 / span 2; }
    .about-statement { grid-column: 3 / span 10; }
    .about-feature { padding-inline: var(--gutter); }
    .about-photo--wide { aspect-ratio: 21 / 9; }
    .about-photo--place-wide { aspect-ratio: 16 / 9; }
    .values { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .value:nth-child(2) { margin-block-start: 4rem; }
    .hosts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .place .about-photo--place { grid-column: 1 / span 8; }
    .place__text { grid-column: 9 / span 4; align-self: center; }
    .about-feature + .about-feature, .place + .about-feature { margin-block-start: var(--space-xl); }
    .section .about-feature { margin-block-start: var(--space-xl); }
  }

  /* M18: the contact page's one address */
  .contact__email { font-family: var(--font-heading); font-size: var(--fs-2); }

  /* M18: the one « Légal » page */
  .legal-toc ul { display: flex; flex-wrap: wrap; gap: var(--space-md); }
  .legal-section { scroll-margin-block-start: var(--space-xl); display: grid; gap: var(--space-md); }  /* M22: the bodies are not .prose, so the gap lives here */
  .legal-section h2, .legal-section h3 { margin-block-start: var(--space-lg); }
  .legal-section + .legal-section { margin-block-start: var(--space-2xl); padding-block-start: var(--space-xl); border-block-start: 1px solid color-mix(in oklab, var(--color-ink), transparent 85%); }

  /* event rows (M7): a month-grouped list, never a grid; the whole row is the link */
  .event-month { margin-block-start: var(--space-lg); font-size: var(--fs-1); }
  /* M23: a reading measure for the row. The category chip is aligned to the
     row's right edge, so the row's width is what sets how far it sits from the
     text: 40 rem keeps it near without cramping a long title (the User's call). */
  .event-list { display: grid; max-inline-size: 40rem; }
  .event-row { border-block-end: var(--border); }
  .event-row__link {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    padding-block: var(--space-md);
    color: var(--color-text);
    text-decoration: none;
    border-radius: var(--radius-sm);
    transition: color var(--dur-fast) var(--ease);
  }
  .event-row__link:hover .event-row__title,
  .event-row__link:focus-visible .event-row__title { color: var(--color-accent); }
  .event-row__link:hover { color: var(--color-accent); }
  .event-row__img {
    flex: 0 0 auto;
    inline-size: 7rem;   /* M30: the 16:9 thumbnail rendition (480 by 270) */
    block-size: 3.9375rem;
    object-fit: cover;
    border-radius: var(--radius-md);
    background: var(--color-surface);
  }
  .event-row__img--empty {
    display: grid;
    place-items: center;
    border: var(--border);
    color: var(--color-text-muted);
  }
  .event-row__img--empty .logo-mark { inline-size: 1.75rem; block-size: auto; }
  /* M23: flex: 1 so the text column fills the row whatever the title's length,
     which is what puts every category chip in the same place down the list */
  .event-row__text { flex: 1; display: grid; gap: var(--space-2xs); min-inline-size: 0; }
  .event-row__when { color: var(--color-text); font-weight: 500; font-size: var(--fs--1); }
  /* M23: base.css balances headings, which centres a wrapped title well short
     of the column and leaves the right-aligned chip stranded past it; a row
     title fills its line instead, so the text wraps where the chip sits */
  .event-row__title { font-size: var(--fs-1); color: var(--color-text); text-wrap: pretty; transition: color var(--dur-fast) var(--ease); }
  @media (min-width: 768px) {
    .event-row__img { inline-size: 9rem; block-size: 5.0625rem; }
  }
  /* M22: the « En bref » line and the meta line (price, category, places) */
  .event-row__summary { color: var(--color-text); }
  .event-row__meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2xs) var(--space-sm); color: var(--color-text-muted); font-size: var(--fs--1); }
  .event-row__price { color: var(--color-text); font-weight: 500; }
  .event-row__host { color: var(--color-text); font-weight: 500; }  /* M30: « Par <organisateur> » */
  /* M23: the category chip flush right, the same column down the whole list */
  .event-row__cat { margin-inline-start: auto; }

  /* M26: a series shows once a month; its dates sit under the row as square
     buttons, each its own evening. The event page uses the same button. */
  .event-row__dates,
  .event-series__dates { display: flex; flex-wrap: wrap; gap: var(--space-2xs); padding-block-end: var(--space-md); }
  .event-row__dates { padding-inline-start: 7.6rem; margin-block-start: calc(-1 * var(--space-sm)); }
  .event-series { margin-block-start: var(--space-md); }
  .event-series__label { color: var(--color-text-muted); font-size: var(--fs--1); margin-block-end: var(--space-2xs); }
  .event-date {
    display: grid;
    justify-items: center;
    align-content: center;
    gap: 1px;
    min-inline-size: 3.25rem;
    min-block-size: 3.25rem;
    padding: var(--space-2xs);
    border: 1px solid var(--color-control-border);
    border-radius: var(--radius-sm);
    color: var(--color-text);
    text-decoration: none;
    transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
  }
  .event-date:hover, .event-date:focus-visible { color: var(--color-accent); border-color: var(--color-accent); }
  .event-date__wd, .event-date__mo { font-size: var(--fs--1); color: var(--color-text-muted); line-height: 1.1; }
  .event-date__day { font-size: var(--fs-1); font-weight: 500; line-height: 1.1; }
  .event-date__state { font-size: var(--fs--1); color: var(--color-text-muted); line-height: 1.1; }
  /* M28 rider: the date being read is the marked one, on the event page as in
     the list's rows. The border carries it, so it reads without colour alone. */
  .event-date--now { background: var(--color-surface); font-weight: 500; border-color: var(--color-text); }
  .event-date--now .event-date__wd, .event-date--now .event-date__mo { color: var(--color-text); }
  @media (max-width: 767px) {
    .event-row__dates { padding-inline-start: 0; }
  }
  .chip--soon { color: var(--color-accent); }
  .chip {
    display: inline-block;
    justify-self: start;
    padding: 0 var(--space-sm);
    border-radius: var(--radius-pill);
    border: 1px solid currentColor;
    font-size: var(--fs--1);
    font-weight: 600;
    letter-spacing: .02em;
  }
  .chip--soldout { color: var(--color-accent); }
  .chip--cancelled { color: var(--color-text-muted); text-decoration: line-through; }
  .registration-list__address { color: var(--color-text-muted); font-size: var(--fs--1); }

  /* inline social icons (M7): drawn in currentColor, sized to the text line */
  .icon { inline-size: 1em; block-size: 1em; vertical-align: -.125em; margin-inline-end: .4em; }
  .social-link { white-space: nowrap; }

  /* icon-only social links (M10): one row, each a 44 px tap target */
  .social-row { display: flex; flex-wrap: wrap; gap: var(--space-xs); align-items: center; }
  .social-link--icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 44px;
    min-block-size: 44px;
  }
  .social-link--icon .icon { inline-size: 1.75rem; block-size: 1.75rem; margin-inline-end: 0; vertical-align: middle; }

  .event-meta { display: grid; gap: var(--space-2xs); color: var(--color-text-muted); }
  .event-meta__when { color: var(--color-text); }

  /* forms */
  .field { display: grid; gap: var(--space-2xs); }
  .field label { font-weight: 600; }
  .field :where(input:not([type="checkbox"], [type="radio"]), textarea, select) {
    min-block-size: 44px;
    padding-inline: var(--space-md);
    border: 1px solid var(--color-control-border);  /* M22: 3.22:1, WCAG 1.4.11 */
    border-radius: var(--radius-sm);
    background: #FFFDF8;
    appearance: none;
    width: 100%;
    font-size: max(1rem, var(--fs-0));
  }
  .field :where(input, textarea):focus-visible { border-color: var(--color-accent); }
  .field [aria-invalid="true"] { border-color: var(--color-danger); }
  .field--choice {
    grid-template-columns: auto 1fr;
    align-items: center;
    column-gap: var(--space-sm);
  }
  .field--choice input { inline-size: 1.25rem; block-size: 1.25rem; accent-color: var(--color-accent); }
  .field--choice label { font-weight: 500; }
  .field--choice .field__help, .field--choice .field__error { grid-column: 2; }
  .field__error { color: var(--color-danger); font-size: var(--fs--1); }
  .field__help { color: var(--color-text-muted); font-size: var(--fs--1); }
  /* interest lists (M6): a compact vertical checkbox list, 44 px rows */
  .field--choices { border: 0; padding: 0; margin: 0; min-inline-size: 0; gap: 0; }
  .field--choices legend { font-weight: 600; padding: 0; margin-block-end: var(--space-2xs); }
  .choice {
    display: grid;
    grid-template-columns: auto 1fr;
    column-gap: var(--space-sm);
    align-items: center;
    min-block-size: 44px;
    font-weight: 500;
    cursor: pointer;
  }
  .choice input { inline-size: 1.25rem; block-size: 1.25rem; accent-color: var(--color-accent); }
  .choice small { grid-column: 2; color: var(--color-text-muted); font-size: var(--fs--1); }
  .form__error { color: var(--color-danger); }
  .form-row { display: flex; flex-wrap: wrap; gap: var(--space-sm); align-items: end; }
  .form-row .field { flex: 1 1 16rem; }
  .form-row .field--choices { flex-basis: 100%; }
  .form-stack { display: grid; gap: var(--space-lg); }
  .form-actions { display: flex; flex-wrap: wrap; gap: var(--space-sm); align-items: center; }
  .form-actions:empty { display: none; }
  .form-note { color: var(--color-text-muted); font-size: var(--fs--1); }
  .btn--danger { background: var(--color-danger); }
  .btn--danger:hover { background: color-mix(in oklab, var(--color-danger), #000 12%); }

  /* inline status / alerts (django messages, allauth notes, form-level errors) */
  .messages { margin-block-start: var(--space-lg); display: grid; gap: var(--space-sm); }
  .alert {
    background: var(--color-surface);
    border: var(--border);
    border-inline-start: 4px solid var(--color-success);
    border-radius: var(--radius-sm);
    padding: var(--space-sm) var(--space-md);
    max-inline-size: none;
  }
  .alert--error { border-inline-start-color: var(--color-danger); }
  .alert--error p { max-inline-size: none; }
  .badge {
    display: inline-block;
    margin-inline-start: var(--space-xs);
    padding: 0 var(--space-xs);
    border-radius: var(--radius-pill);
    background: var(--color-surface);
    border: var(--border);
    font-size: var(--fs--1);
    font-weight: 500;
  }

  /* M22: the event page's top: the text column, the poster beside it from 900 px */
  .event-top { display: grid; gap: var(--space-lg); }
  .event-top__text, .event-body { max-inline-size: var(--container-narrow); }
  .event-body { margin-block-start: var(--space-xl); }
  .event-hero { inline-size: auto; max-inline-size: 100%; block-size: auto; max-block-size: 60vh; border-radius: var(--radius-lg); background: var(--color-surface); }
  @media (min-width: 900px) {
    .event-top--poster { grid-template-columns: 3fr 2fr; align-items: start; }
    .event-top--poster .event-hero { justify-self: end; }
  }
  .event-summary { font-size: var(--fs-1); color: var(--color-text-muted); }
  .event-places { color: var(--color-accent); font-weight: 600; }
  /* the registration state as a card (the .alert pattern), success for confirmed, accent for a hold */
  .state { background: var(--color-surface); border: var(--border); border-inline-start: 4px solid var(--color-text-muted); border-radius: var(--radius-sm); padding: var(--space-sm) var(--space-md); font-weight: 500; max-inline-size: none; }
  .state--success { border-inline-start-color: var(--color-success); }
  .state--accent { border-inline-start-color: var(--color-accent); }
  .registration__actions { display: flex; flex-wrap: wrap; gap: var(--space-sm); }
  /* M28 (D7): the contribution call to action, just above the button */
  .registration__contribution { color: var(--color-text-muted); }
  /* the confirmed member's ticket */
  .ticket { background: var(--color-surface); border: var(--border); border-inline-start: 4px solid var(--color-success); border-radius: var(--radius-md); padding: var(--space-lg); display: grid; gap: var(--space-xs); }
  .ticket__title { font-size: var(--fs-1); }
  .ticket__code { font-family: var(--font-heading); font-size: var(--fs-2); }
  /* the phone bar: sticky at the foot of main, hidden by js/event-bar.js while #register is on screen */
  .event-bar { position: sticky; inset-block-end: 0; z-index: var(--z-sticky); display: flex; align-items: center; justify-content: space-between; gap: var(--space-md); padding: var(--space-sm) var(--gutter) max(var(--space-sm), env(safe-area-inset-bottom)); background: var(--color-bg); border-block-start: var(--border); }
  .event-bar__price { font-weight: 600; }
  .event-bar form { display: contents; }
  .event-bar[hidden] { display: none; }
  @media (min-width: 768px) { .event-bar { display: none; } }

  /* account page: three stacked cards (M10) */
  .account-card {
    background: var(--color-surface);
    border: var(--border);
    border-radius: var(--radius-md);
    padding: var(--space-lg);
    display: grid;
    gap: var(--space-md);
  }
  .account-card > h2 { font-size: var(--fs-1); }
  .account-card__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-sm);
  }
  .account-card__head h2 { font-size: var(--fs-1); }
  .account-card__security {
    border-block-start: var(--border);
    padding-block-start: var(--space-md);
  }

  /* account: identity + attendance history */
  .identity { display: grid; gap: var(--space-xs); }
  .identity__row { display: grid; gap: var(--space-2xs); }
  .identity dt { font-weight: 600; }
  .identity dd a { margin-inline-start: var(--space-xs); }
  .attendance-list { display: grid; }
  .attendance-list li {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: var(--space-xs) var(--space-md);
    padding-block: var(--space-sm);
    border-block-end: var(--border);
  }
  .attendance-list time { color: var(--color-text-muted); font-size: var(--fs--1); }
  /* M28 (D8): the thumbnail and the link on a past evening, the event_row shape */
  .attendance-list__item { display: block; }
  .attendance-list__link {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    color: var(--color-text);
    text-decoration: none;
  }
  a.attendance-list__link:hover .attendance-list__title { color: var(--color-accent); }
  .attendance-list__img {
    flex: 0 0 auto;
    inline-size: 5rem;   /* M30: the 16:9 thumbnail rendition */
    block-size: 2.8125rem;
    object-fit: cover;
    border-radius: var(--radius-md);
    background: var(--color-surface);
  }
  .attendance-list__img--empty { display: grid; place-items: center; border: var(--border); color: var(--color-text-muted); }
  .attendance-list__img--empty .logo-mark { inline-size: 1.5rem; block-size: auto; }
  .attendance-list__text { display: flex; flex: 1; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: var(--space-2xs) var(--space-md); min-inline-size: 0; }
  .attendance-list__title { font-weight: 500; transition: color var(--dur-fast) var(--ease); }

  /* registration (M8): the button block on the event page, the list on the account page */
  .event-price { color: var(--color-text); font-weight: 600; }
  .event-policy { font-size: var(--fs--1); }
  .registration { display: grid; gap: var(--space-sm); padding-block: var(--space-md); border-block: var(--border); }
  .registration form { display: contents; }
  .registration-list { display: grid; }
  .registration-list__item { display: grid; gap: var(--space-xs); padding-block: var(--space-md); border-block-end: var(--border); }
  .registration-list__head { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-xs) var(--space-md); }
  .registration-list__head time { color: var(--color-text-muted); font-size: var(--fs--1); }
  .registration-list__status { color: var(--color-text-muted); font-size: var(--fs--1); }

  /* M12: the « add to your calendar » links under a confirmed ticket */
  .calendar-links { font-size: var(--fs--1); }

  /* holding page (parked domain) */
  .holding {
    min-block-size: 100svh;
    display: grid;
    align-content: center;
    justify-items: center;
    text-align: center;
    gap: var(--space-md);
    padding: var(--space-fluid) var(--gutter);
  }
  .holding .logo-mark { inline-size: clamp(3.5rem, 2.5rem + 5vw, 6rem); color: var(--color-accent); }
  .holding__status { font-family: var(--font-heading); font-size: var(--fs-1); }
  .holding p { max-inline-size: 40ch; color: var(--color-text-muted); }

  /* status blocks (confirmation pages) */
  .status-card {
    background: var(--color-surface);
    border: var(--border);
    border-radius: var(--radius-lg);
    padding: var(--space-xl);
    display: grid;
    gap: var(--space-md);
    justify-items: start;
  }
  /* M16: the public category, a text chip in its own colour on the rows and
     the event page; the colour follows the category, the text is the signal */
  .chip--cat { font-weight: 600; }
  .chip--cat-danse { color: var(--color-cat-danse); }
  .chip--cat-connect { color: var(--color-cat-connect); }
  h1 .chip--cat { vertical-align: middle; font-size: var(--fs--1); }
  /* M16: « Toutes · Danse · Connect » above the list; M22: pills with counts */
  .event-filter { display: flex; flex-wrap: wrap; gap: var(--space-xs); }
  .event-filter__item { display: inline-flex; align-items: center; gap: var(--space-2xs); min-block-size: 44px; padding-inline: var(--space-md); border: 1px solid var(--color-control-border); border-radius: var(--radius-pill); color: var(--color-text); text-decoration: none; font-weight: 600; font-size: var(--fs--1); }
  .event-filter__item--on { background: var(--color-accent); border-color: var(--color-accent); color: var(--color-accent-contrast); }
  .event-filter__count { font-weight: 500; opacity: .8; }

  /* M23: the month pill, the list's own month filter, a dropdown */
  .event-months { position: relative; }
  .event-months > summary { cursor: pointer; list-style: none; }
  .event-months > summary::-webkit-details-marker { display: none; }
  .event-months__pill { gap: var(--space-2xs); padding-inline-end: var(--space-sm); }
  .event-months__caret { flex: none; transition: transform var(--dur-fast) var(--ease); }
  .event-months[open] .event-months__caret { transform: rotate(180deg); }
  .event-months__menu { position: absolute; z-index: 20; inset-block-start: calc(100% + var(--space-2xs)); inset-inline-start: 0; min-inline-size: 12rem; max-block-size: 60vh; overflow-y: auto; margin: 0; padding: var(--space-2xs); list-style: none; background: var(--color-surface); border: 1px solid var(--color-control-border); border-radius: var(--radius-md); box-shadow: 0 8px 24px rgb(0 0 0 / .18); }
  .event-months__item { display: flex; min-block-size: 44px; align-items: center; padding-inline: var(--space-sm); border-radius: var(--radius-sm); color: var(--color-text); text-decoration: none; font-size: var(--fs--1); }
  .event-months__item:hover { background: var(--color-control-border); }
  .event-months__item--on { font-weight: 600; background: var(--color-control-border); }

  /* M16: the price picker of a tiered evening (event page and pay page) */
  .tiers { border: 0; padding: 0; margin: 0; min-inline-size: 0; display: grid; gap: var(--space-2xs); }
  .tiers__legend { font-weight: 600; padding: 0; margin-block-end: var(--space-2xs); }
  .tiers__item { display: grid; gap: var(--space-xs); }
  .tiers__option { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: var(--space-sm); min-block-size: 44px; cursor: pointer; }
  .tiers__option input { inline-size: 1.25rem; block-size: 1.25rem; accent-color: var(--color-accent); margin: 0; }
  .tiers__name { font-weight: 500; }
  .tiers__amount { color: var(--color-text); font-weight: 600; text-align: end; }
  .tiers__item--full { color: var(--color-text-muted); }
  .tiers__item--full .tiers__amount { color: var(--color-text-muted); font-weight: 500; }
  .tiers__item--full .tiers__option { cursor: default; }
  .tiers__raise { padding-inline-start: calc(1.25rem + var(--space-sm)); max-inline-size: 18rem; }

  /* ---------- M29: the scroll reveal (D1, D2) ---------- */
  /* js/reveal.js arms only the blocks below the first screen; no script,
     no arming, nothing ever hidden. is-in must come after is-armed here:
     equal specificity, source order decides the settled state. */
  @media (prefers-reduced-motion: no-preference) {
    [data-reveal].is-armed,
    [data-reveal-stagger].is-armed > * { opacity: 0; transform: translateY(16px); }
    [data-reveal].is-in,
    [data-reveal-stagger].is-in > * {
      opacity: 1; transform: none;
      transition: opacity var(--dur-reveal) var(--ease), transform var(--dur-reveal) var(--ease);
    }
    [data-reveal-stagger].is-in > :nth-child(2) { transition-delay: 60ms; }
    [data-reveal-stagger].is-in > :nth-child(3) { transition-delay: 120ms; }
    [data-reveal-stagger].is-in > :nth-child(4) { transition-delay: 180ms; }
    [data-reveal-stagger].is-in > :nth-child(5) { transition-delay: 240ms; }
    [data-reveal-stagger].is-in > :nth-child(n+6) { transition-delay: 300ms; }
  }

  /* ---------- M29: photos zoom slightly under a real pointer (D3) ---------- */
  @media (hover: hover) and (pointer: fine) {
    .insta-grid li { border-radius: var(--radius-lg); overflow: hidden; }
    .insta-grid img { transition: transform var(--dur-slow) var(--ease); }
    .insta-grid li:hover img { transform: scale(1.03); }
    img.event-row__img { transition: transform var(--dur-slow) var(--ease); }
    .event-row__link:hover img.event-row__img { transform: scale(1.03); }
  }
}
