/*
 * APRG — user customizations
 *
 * This file is safe to edit. It is loaded last so anything here overrides
 * theme.css without having to mark rules !important.
 *
 * Palette sampled from the club logo (cropped-favicon.png):
 * navy #0b1768 (primary / accent-color in aprg.yaml), sky blue #0089cd
 * (secondary, used sparingly below for hover states).
 */

:root {
  --brand-navy: #0b1768;
  --brand-sky: #0089cd;
}

/* Tighter top-level nav row. Six items ("Accueil", "Le Club", "Actualités",
   "Nos événements", "Espace adhérents", "Contact") plus the header search
   icon were wrapping to two lines on common desktop widths — theme.css's
   `.dropmenu > ul` has `flex-wrap: wrap` (no horizontal scroll fallback),
   so once the row is too narrow the links themselves wrap rather than the
   header growing messily. Scoped to the TOP-LEVEL row only
   (`> ul > li > a`) — the Records dropdown panel keeps its own sizing from
   theme.css's more specific `.dropmenu li > ul a`, unaffected by this. */
.dropmenu > ul {
  gap: 0.3rem;
}
.dropmenu > ul > li > a {
  padding: 0.5rem 0.6rem;
  font-size: 0.85rem;
}

/* Now that the row above fits on one line, the space `.desktop-menu`'s
   `flex: 1 1 auto` (theme.css) used to stretch into was hidden by wrapping —
   visible now as a gap between the logo and "Accueil", since that same rule
   right-aligns the nav (`justify-content: flex-end`) within a box now wider
   than its content. Size the box to its content instead: the nav then sits
   right after the logo, and `.navbar-section.actions`'s own `margin-left:
   auto` (theme.css) is what pushes the search/user icons to the far right —
   it was already doing that job redundantly underneath `desktop-menu`'s
   stretch, so removing the stretch here changes nothing on the right side. */
.desktop-menu {
  flex: 0 1 auto;
}

/* Back to one row (a separate utility row above pushed the header to
   ~130px tall) — logo, menu, and the search/user icons are all direct
   `.navbar-section` children of this same flex row again, and stay aligned
   against the LOGO's middle rather than the menu text's: `.navbar-brand img`
   has a clean, fixed 56px height (below), so `align-items: center` on THIS
   row centers every section's box against that same unambiguous 56px
   reference — no font line-box metrics involved, unlike centering an icon
   glyph against a text baseline (Pico's own button resets kept fighting
   that specific comparison — see git history on this file for the road
   here). `space-between` splits the free space into two even gaps
   (logo↔menu, menu↔icons) rather than funneling it all into one — see the
   `.desktop-menu`/`.navbar-section.actions` rules above and below. */
#header .navbar {
  justify-content: space-between;
}
.navbar-section.actions {
  margin-left: 0;
}

a:hover,
a:focus {
  color: var(--brand-sky);
}

/* theme.css sets .navbar-brand img/svg to 44px — bump it for our logo.
   #header has no fixed height (min-height: 72px), so this doesn't clip. */
.navbar-brand img {
  height: 56px;
}

img.center {
  display: block;
  margin: 0 auto;
}

/* theme.css sets `white-space: nowrap` on all td/th so compact data tables
   (records, results) stay tight. But in a row that also holds a product
   photo, an unwrappable long description hogs the row's width and leaves
   nothing for the image column. Scope the fix to rows with an <img> so
   text-only tables keep their nowrap behavior. */
tr:has(img) td {
  white-space: normal;
}

/* Menu icons (menu_icon: in a page's header), at any nesting depth — not
   just top-level, submenu items carry them too. Color already inherits from
   the link (monochrome, follows hover/active states for free) — just tone
   them down so they read as a quiet hint next to the label, not a competing
   solid-color badge. */
.dropmenu li a > i,
.overlay-menu li a > i {
  font-size: 0.85em;
  opacity: 0.7;
}
/* theme.css's top-level `.dropmenu a` is `inline-flex` with `gap: 0.375rem`,
   which is where the top bar's icon/label spacing actually comes from — but
   `.dropmenu li > ul a` (dropdown panel items, i.e. submenus) later resets
   display to `block` for its vertical-stack layout, silently dropping that
   flex gap. Put it back, same value, so submenu icons space exactly like
   the top bar's instead of relying only on the literal space in the macro. */
.dropmenu li > ul a {
  display: flex;
  align-items: center;
  gap: 0.375rem;
}
/* Desktop spaces icon from label via flex `gap` already; the mobile overlay
   menu is a plain block link (no flex), so the icon needs its own margin. */
.overlay-menu li a > i {
  margin-right: 0.5rem;
}

/* Divider between groups of items in a dropdown submenu (e.g. "Le Club" ->
   activities vs. records). Added via `menu_separator_before: true` on the
   page that should follow it. */
.dropmenu li.menu-divider,
.overlay-menu li.menu-divider {
  height: 1px;
  margin: 0.25rem 0.625rem;
  padding: 0;
  background: var(--q2-border-strong, rgba(0, 0, 0, 0.1));
}

/* Installation help is useful in a browser, but redundant once the PWA is
   already running as an installed app. `display-mode` is the browser's
   authoritative signal and works without JavaScript (so there is no flash). */
@media (display-mode: standalone) {
  .dropmenu li.hide-in-standalone,
  .overlay .overlay-menu li.hide-in-standalone {
    display: none;
  }
}

/* Mirror of `.hide-in-standalone` above, for the opposite case: a nav entry
 * (the "Mes notifications" fallback in navigation.html.twig) that should
 * only exist once installed. The selectors deliberately match the specificity
 * of theme.css's menu rules; a bare class loses against `.dropmenu li` and
 * `.overlay .overlay-menu li`, which both force `display: block`. */
.dropmenu li.show-in-standalone,
.overlay .overlay-menu li.show-in-standalone {
  display: none;
}

@media (display-mode: standalone) {
  .dropmenu li.show-in-standalone,
  .overlay .overlay-menu li.show-in-standalone {
    display: block;
  }
}

/* Search box injected by site.js above the "dates d'ouverture des
   inscriptions" table. Same input styling as the rest of the site
   (theme.css's input[type="search"] rule) — just constrained and spaced
   so it doesn't stretch full-width above the table. */
.races-filter {
  display: block;
  max-width: 26rem;
  margin: 0 0 1rem;
}

/* Edge shadows hinting horizontal scroll on wide tables, injected by
   site.js next to (not inside) .table-scroll. */
.table-scroll-shadow {
  position: absolute;
  width: 28px;
  pointer-events: none;
  z-index: 2;
  opacity: 0;
  transition: opacity 0.15s ease;
}

/* Département/distance filter bar injected by site.js above the "trouver
   une course" sections. Framed as a distinct panel so it reads as a tool
   separate from the result tables below it, not just another row of text. */
.race-finder-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
  margin: 0 0 1.5rem;
  padding: 0.85rem 1rem;
  border: 1px solid var(--q2-border-strong, rgba(0, 0, 0, 0.15));
  border-radius: 0.5rem;
  background: rgba(11, 23, 104, 0.04);
}
.race-finder-filters select {
  padding: 0.4rem 0.6rem;
}
.race-finder-search {
  flex: 1 1 100%;
}
/* Toggle chips (enfants + distances classiques): plain outline until
   pressed, then filled with the brand color — same on/off signal as a
   checkbox but reads better in a row of short labels. */
.race-finder-chip {
  padding: 0.35rem 0.75rem;
  border: 1px solid var(--q2-border-strong, rgba(0, 0, 0, 0.2));
  border-radius: 999px;
  background: transparent;
  color: inherit;
  cursor: pointer;
}
.race-finder-chip[aria-pressed='true'] {
  background: var(--brand-navy);
  border-color: var(--brand-navy);
  color: #fff;
}
.race-finder-range {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}
.race-finder-range-input {
  width: 4.5rem;
  padding: 0.35rem 0.5rem;
}
.race-finder-date-input {
  padding: 0.3rem 0.4rem;
}
.race-finder-count {
  opacity: 0.7;
  font-size: 0.875rem;
}

/* Form fields marked `readonly` (nom/email prefilled from the logged-in
   account on boutique/demande-plan-personnalise/feedback forms — see
   prefill_user_fields in those pages' headers) render with no visual
   distinction from an editable field by default, which reads as "I can type
   here". Deliberately still `readonly` and not `disabled`: a disabled field
   is never sent in the form POST, so nom/email would arrive empty
   server-side. Style it to look like `disabled` instead, without the
   submission breakage. */
input[readonly] {
  background: var(--q2-bg-muted, rgba(0, 0, 0, 0.04));
  color: var(--q2-text-muted, rgba(0, 0, 0, 0.6));
  cursor: not-allowed;
}

/* Utility used sparingly for form labels that must exist for accessibility
   (screen readers, label-for association) but are redundant on screen next
   to an already-obvious placeholder/icon. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Search box in the header's `.navbar-section.actions` (plugin `search`,
   see docs/recherche-site.md). Compact: sits next to the login status, not
   meant to compete with it for width.

   Collapsed icon opens a small panel BELOW it (like .login-status-panel
   below), not an inline field next to it — tried inline first, but it
   fought the row's flex sizing (Pico's width:100% on the submit button,
   see the fix below) and its own vertical alignment against the nav text.
   Dropping the field out of the row entirely sidesteps both: the row's
   layout/height never changes when the field opens. */
.header-search {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  /* No explicit height needed: this container's `height: auto` used to
     resolve to 50.4px (34.4px button + Pico's 16px phantom margin-bottom on
     the button — see .header-search-toggle's own comment below for the real
     cause) even though its only visible child was 34.4px. Fixing the
     button's margin fixed this container's auto height too — a flex
     container's auto cross-size accounts for its items' margin boxes, not
     just their border boxes. */
}
/* Selector includes [type="submit"] deliberately, not just the class: Pico's
   own `[type=submit],button{...}` rule (blades.min.css) is (0,1,1) —
   attribute + element — which beats a plain class selector (0,1,0) outright,
   regardless of custom.css loading after it. `.header-search-toggle` alone
   was NOT enough (a first attempt at this fix only added `width: auto` to
   the plain-class rule and still lost). `.header-search-toggle[type="submit"]`
   is (0,2,0), which wins unconditionally. */
.header-search-toggle[type="submit"] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* THE actual cause of the vertical misalignment (found empirically via
     devtools 2026-08-28: offsetTop was -8px, margin box centering math
     traced back to this exact rule). Pico: `[type=button],[type=reset],
     [type=submit]{margin-bottom:var(--pico-spacing)}` (16px) — invisible
     but very real: `align-items: center` on the parent centers a flex
     item's MARGIN box, not just its visible border box, so 16px of
     margin-bottom with 0 margin-top shifts the visible button upward by
     half that gap. It's also where the untraceable "height: 50.4px" on
     `.header-search` came from: 34.4px button + 16px margin-bottom = 50.4.
     `[type="submit"]` in the selector above already beats this Pico rule's
     own `[type=submit]` branch on specificity (0,2,0) vs (0,1,0), so this
     override needed to be added here, not chased as a separate rule. */
  margin: 0;
  flex: none;
  /* Pico's `[type=submit],button{...}` rule also sets width: 100% via a
     SEPARATE selector list matching this same rule (see comment above). */
  width: auto;
  /* Explicit height rather than trusting padding + line-height to land on
     the same total as `.dropmenu > ul > li > a` (0.5rem padding + 1.35
     line-height at 0.85rem font-size ≈ 2.15rem) — a font-metrics mismatch
     between this icon and the nav's Latin text kept reading as "not quite
     centered" even once padding/font-size/line-height all matched on paper.
     A fixed height both elements can be compared against directly is more
     reliable than trying to reverse-engineer Pico's exact box model. */
  height: 2.15rem;
  padding: 0 0.5rem;
  font-size: 0.85rem;
  border: 1px solid var(--q2-border-strong, rgba(0, 0, 0, 0.15));
  border-radius: var(--q2-radius, 6px);
  background: transparent;
  color: inherit;
  cursor: pointer;
}
.header-search-toggle:hover {
  border-color: var(--brand-sky);
  color: var(--brand-sky);
}
.header-search-form {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.5rem;
}
.header-search-suggestions {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}
.header-search-suggestions li {
  display: flex;
  align-items: center;
  gap: 0.25rem;
}
.header-search-suggestions a {
  display: flex;
  flex-direction: column;
  gap: 0.05rem;
  flex: 1 1 auto;
  min-width: 0;
  padding: 0.4rem 0.5rem;
  border-radius: var(--q2-radius-sm, 4px);
  color: inherit;
  text-decoration: none;
}
.header-search-suggestions a:hover,
.header-search-suggestions li.active a {
  background: var(--q2-bg-muted, rgba(0, 0, 0, 0.05));
}
.header-search-suggestion-external {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.4rem 0.5rem;
  font-size: 0.85em;
  opacity: 0.55;
}
.header-search-suggestion-external:hover {
  opacity: 1;
}
.header-search-suggestions .header-search-suggestion-group {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  opacity: 0.6;
}
.header-search-suggestions .header-search-suggestion-more {
  font-style: italic;
  opacity: 0.85;
}
.header-search-form input[type='search'] {
  padding: 0.35rem 0.6rem;
  font-size: 0.9rem;
  /* Widened from 12rem: the dropdown panel (.header-search.js-collapsed
     .header-search-form below) sizes itself off this input's width — event
     names and "athlète — épreuve (discipline)" suggestion labels need more
     room than a header-sized field to avoid wrapping onto multiple lines
     inside a compact dropdown. */
  width: 24rem;
  /* Same Pico spacing rule as the buttons above, different selector list:
     `input:not([type=checkbox],[type=radio]),select,textarea
     {margin-bottom:var(--pico-spacing)}` — same 16px phantom margin-bottom,
     same effect (align-items: center on .header-search-form centers the
     margin box, so the visible input sits above dead center). This
     selector's specificity (0,2,1) already beats Pico's (0,1,1) here, no
     extra [type=] trick needed unlike the buttons. */
  margin: 0;
}
/* Suppresses the browser's OWN native search-input decorations (WebKit in
   particular renders a small magnifying-glass icon inside `type="search"`
   fields) — it was rendering on top of the placeholder text ("ec" of
   "Rechercher"), not next to it, since nothing here reserved space for it.
   We already have our own loupe on the toggle button; a second, native one
   drawn INSIDE the field is redundant and, without deliberate padding to
   clear it, actively overlaps the text. Simpler to turn it off than to
   guess at its width across browsers. Scoped globally (not just the header
   panel) since every `type="search"` field on the site inherits the same
   native rendering — the "trouver une course" filter box included. */
input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-results-button,
input[type="search"]::-webkit-search-results-decoration {
  -webkit-appearance: none;
  display: none;
}
/* [type="search"] repeated three times deliberately: Pico's own icon rule
   is `input:not([type=checkbox],[type=radio],[type=range],[type=file])
   [type=search]{...}` (blades.min.css) — its `:not(...)` contributes
   specificity same as a class/attribute, giving (0,2,1) total, which beats
   a plain `input[type="search"]` (0,1,1) outright. Repeated three times for
   (0,3,1), to exceed Pico's (0,2,1) outright rather than only tie it — a
   tie would resolve via source order (custom.css loads after blades.min.css,
   so it should still win), but enough "should win" turned out wrong earlier
   in this file's history today that this skips relying on that a second
   time for the same class of bug. */
input[type="search"][type="search"][type="search"] {
  -webkit-appearance: textfield;
  /* Pico's OWN search icon (not a browser-native decoration, a genuine CSS
     rule, see above) — it reserves space via `padding-inline-start` and
     paints the icon via `background-image`. Wherever a padding override
     here sets a smaller value (`.header-search-form input[type='search']`
     does, for the compact dropdown panel), the reserved space shrinks but
     the icon still paints at Pico's original position — text and icon end
     up overlapping rather than the icon just moving. We already have our
     own loupe on the toggle button; drop Pico's redundant one instead of
     trying to keep padding and icon position in sync everywhere a search
     input's padding is customized. */
  background-image: none;
}

.header-search.js-collapsed {
  position: relative;
}
.header-search.js-collapsed .header-search-form {
  display: none;
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  padding: 0.6rem 0.85rem;
  background: var(--q2-bg-elev);
  border-radius: var(--q2-radius-md, 8px);
  box-shadow: var(--q2-shadow-dropdown);
  z-index: 40;
}
.header-search.js-collapsed.open .header-search-form {
  display: flex;
}

/* Logged-in status ("Prénom Nom, Déconnexion"), same collapse-on-click
   pattern as .header-search above and for the same reason — see the
   comment on base.html.twig's login-status-compact block. Without JS
   (no .js-collapsed) the panel stays inline, unpositioned, always visible:
   identical to the plain `<span class="login-status-wrapper">` this
   replaced. */
.login-status-compact {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  /* No explicit height needed here either — same reason as .header-search
     above. */
}
/* [type="button"] in the selector, not just the class, for the same reason
   as .header-search-toggle[type="submit"] above: Pico's own
   `[type=button],button{...font-size:1rem;line-height:...;padding:...}`
   rule (blades.min.css) matches this button via its `[type=button]` branch,
   (0,1,0) — tied with a plain class selector, which the header-search-toggle
   case showed isn't safe to assume resolves via source order. Bumped to
   (0,2,0), an unconditional win. */
.login-status-toggle[type="button"] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Same fix, same root cause as .header-search-toggle above — Pico's
     `[type=button],...{margin-bottom:var(--pico-spacing)}` matches this
     button via its own `[type=button]` branch. */
  margin: 0;
  flex: none;
  /* Same explicit height as .header-search-toggle above, same reason — see
     that rule's comment. */
  height: 2.15rem;
  padding: 0 0.5rem;
  font-size: 0.85rem;
  border: 1px solid var(--q2-border-strong, rgba(0, 0, 0, 0.15));
  border-radius: var(--q2-radius, 6px);
  background: transparent;
  color: inherit;
  cursor: pointer;
}
.login-status-toggle:hover {
  border-color: var(--brand-sky);
  color: var(--brand-sky);
}
.login-status-panel {
  white-space: nowrap;
}
/* Name + link list styled like the main nav's dropdown panels
   (.dropmenu li > ul / .dropmenu a in theme.css) rather than the plain
   <br>-separated stack this replaced — same hover background, same radius,
   same list layout, just under this menu's own class names since it isn't
   part of `.dropmenu` itself (no page tree, no hover/focus-within JS-less
   fallback to inherit). */
.user-menu-header {
  display: block;
  padding: 0.3rem 0.875rem 0.5rem;
  margin-bottom: 0.3rem;
  border-bottom: 1px solid var(--q2-border-ring);
}
.login-status-panel .user-menu-list {
  /* Selector scoped with the panel ancestor (not just `.user-menu-list`)
     purely to win specificity: Pico's `nav ul:first-of-type{margin-left:
     calc(var(--pico-nav-element-spacing-horizontal) * -1)}` / `nav
     ul:last-of-type{margin-right:...}` (blades.min.css, real selectors, not
     :where()-wrapped) is (0,1,2) — nav + ul + a pseudo-class — which beats a
     plain `.user-menu-list{margin:0}` (0,1,0) outright regardless of load
     order. `.user-menu-list` here IS both first- and last-of-type among its
     siblings (the only <ul> under .login-status), so that -0.5rem (8px)
     margin was applied on both sides, widening the list itself past the
     panel's own padding — the hover background then overflowed with it,
     reaching the panel's edge. */
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  /* Pico's `nav ol,nav ul{align-items:center}` (blades.min.css) still wins
     on this property otherwise — I only override display/flex-direction
     above, and align-items is cascaded independently per-property. On a
     column flex container that centers each <li> horizontally by its own
     content width instead of stretching them, which is what actually made
     the two links look unaligned (each centered at a different width, not
     literally justify-content'd apart). Same fix as .dropmenu li > ul above. */
  align-items: stretch;
  gap: 2px;
}
.user-menu-list li {
  /* Pico's `nav li{display:inline-block;padding:var(--pico-nav-element-spacing-vertical)
     var(--pico-nav-element-spacing-horizontal)}` — that's 1rem (16px) of
     vertical padding per <li> inside any <nav>, which is what read as "too
     much space between the two [links]": far more than the 2px `gap` above
     actually asks for. Same reset as .dropmenu li > ul > li in theme.css. */
  display: block;
  margin: 0;
  padding: 0;
  width: 100%;
}
.user-menu-list a {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  /* Pico's `nav li :where(a,[role=link]){margin:calc(var(--pico-nav-link-spacing-vertical)
     * -1) calc(var(--pico-nav-link-spacing-horizontal) * -1);...}` (blades.min.css)
     — a -0.5rem margin on all four sides. It's wrapped in :where() (zero
     specificity) but still wins over nothing: this rule never declared its
     own `margin` before, so there was no competing value to out-specificity
     it against. That negative margin pulled each link (and its hover
     background) 8px past its own box on every side — past the <li> vertically
     (reading as "too cramped", the two rows overlapping) and past the panel's
     own padding horizontally (the hover background spilling outside the
     menu). Padding bumped to match .dropmenu a in theme.css exactly, same
     reasoning as the rest of this block: same visual template as the site's
     other menus. */
  margin: 0;
  padding: 0.5rem 0.9375rem;
  border-radius: var(--q2-radius-sm, 6px);
  color: var(--q2-text-strong);
  font-weight: 500;
  font-size: 0.9375rem;
  line-height: 1.4;
  text-decoration: none;
  transition: background 0.15s ease, color 0.15s ease;
}
.user-menu-list a:hover {
  background: var(--q2-bg-muted);
  color: var(--q2-text-strong);
  text-decoration: none;
}

.login-status-compact.js-collapsed {
  position: relative;
}
.login-status-compact.js-collapsed .login-status-panel {
  display: none;
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 220px;
  padding: 0.5rem 0.375rem 0.375rem;
  background: var(--q2-bg-elev);
  border-radius: var(--q2-radius-md, 8px);
  box-shadow: var(--q2-shadow-dropdown);
  z-index: 40;
}
.login-status-compact.js-collapsed.open .login-status-panel {
  display: block;
}

/* Same search box, mobile overlay menu (`.mobile-container .overlay`). No
   icon-to-expand collapse here — the overlay is already full-width and
   single-column, so a plain full-width field at the top (before the nav
   tree) reads better than a second interaction to get to it. */
.mobile-search-form {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  margin-bottom: 1.5rem;
}
.mobile-search-form input[type='search'] {
  flex: 1 1 auto;
  /* Same Pico margin-bottom fix as .header-search-form's input — see that
     rule's comment. */
  margin: 0;
}
.mobile-search-form button[type="submit"] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  /* Same Pico width: 100% override as .header-search-toggle above, same
     rule, same reason — selector bumped to (0,2,1) for the same reason: a
     plain `.mobile-search-form button` (0,1,1) only ties Pico's rule, and
     the .header-search-toggle case showed a tie/near-tie isn't safe to
     assume resolves the way source order suggests without checking. */
  width: auto;
  padding: 0.5rem 0.7rem;
  border: 1px solid var(--q2-border-strong, rgba(0, 0, 0, 0.15));
  border-radius: var(--q2-radius, 6px);
  background: transparent;
  color: inherit;
  cursor: pointer;
}

/* Feedback form appended by default.html.twig under pages that declare a
   `form:` header (see user/pages/05.espace-adherents/{02,03,04}...). */
.page-feedback-form {
  margin-top: 2.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--q2-border-strong, rgba(0, 0, 0, 0.1));
}
.page-feedback-form .form-wrapper {
  max-width: 32rem;
}

/* Logos partenaires ("Nos partenaires", page d'accueil) — tailles et formats
   très hétérogènes à la source (logo FFA très large, HyperU rectangulaire,
   mairie carrée) : `align-items: center` + une hauteur commune sur les
   images plutôt qu'une largeur, pour un rendu visuellement homogène malgré
   des proportions natives différentes. `space-between` étale les logos sur
   toute la largeur avec un espacement identique entre eux. */
/* Pas de conteneur dédié : Grav/Parsedown ne réinterprète pas la syntaxe
   Markdown des images à l'intérieur d'un bloc HTML brut (testé : les trois
   `![...]()` restent du texte littéral dans un <div>...</div>). Trois images
   consécutives sans ligne vide entre elles forment un seul <p> — c'est ce
   paragraphe-là qu'on cible. */
p:has(> img.partner-logo) {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1.5rem;
  margin: 1.5rem 0;
}
.partner-logo {
  height: 8rem;
  width: auto;
  max-width: 100%;
  object-fit: contain;
}

/* [badge]/[badge style="..."] shortcode (user/plugins/shortcode-core's
   starter example, shortcode-core.yaml) renders bare markup with no styling
   of its own — these are the classes it emits. */
.badge {
  display: inline-block;
  padding: 0.15em 0.65em;
  border-radius: 999px;
  font-size: 0.8em;
  font-weight: 600;
  line-height: 1.5;
  color: #fff;
  background: var(--brand-navy);
  white-space: nowrap;
}
.badge-success {
  background: #2e7d32;
}
.badge-warning {
  background: #b26a00;
}
.badge-danger {
  background: #c62828;
}

/* [ui-accordion-item image="..." count="..."] header — see
   templates/partials/ui-accordion.html.twig (theme override of
   shortcode-ui's own template) for the markup this styles. */
.accordion-wrapper label.accordion-header-event {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.5rem 15px;
}
.accordion-event-thumb {
  flex: 0 0 auto;
  width: auto;
  height: auto;
  max-width: 100px;
  max-height: 100px;
  border-radius: 4px;
}
.accordion-event-title {
  flex: 1 1 auto;
}
.accordion-event-count {
  flex: 0 0 auto;
}
/* ui-accordion.css pins the hover chevron at a fixed `top: 7px`, sized for
   its own single-line label — recenter it now the header can be as tall as
   the 100px thumbnail. One extra class over the plugin's own selector
   (.accordion-wrapper label:hover:after) so this wins regardless of
   stylesheet load order, no !important needed. */
.accordion-wrapper .accordion-header-event:hover:after,
.accordion-wrapper input:checked + .accordion-header-event:hover:after {
  top: 50%;
  transform: translateY(-50%);
}

/* Device-by-device PWA installation guide. */
.app-install-guide {
  --install-blue: #2766c7;
  --install-soft: #f4f7fb;
  max-width: 52rem;
  margin-inline: auto;
}
.app-install-intro {
  max-width: 44rem;
  margin: 0 0 1.5rem;
  font-size: 1.15rem;
  line-height: 1.65;
}
.app-install-platforms {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.75rem;
  margin: 0 0 1.5rem;
}
.app-install-platforms a {
  display: flex;
  min-height: 6.5rem;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 1rem;
  border: 1px solid var(--q2-border-strong, #d8dee8);
  border-radius: 0.85rem;
  background: #fff;
  color: var(--brand-navy, #17233b);
  font-weight: 700;
  text-align: center;
  text-decoration: none;
  transition: border-color 0.15s, box-shadow 0.15s, transform 0.15s;
}
.app-install-platforms a:hover {
  border-color: var(--install-blue);
  box-shadow: 0 0.4rem 1.2rem rgba(23, 35, 59, 0.1);
  transform: translateY(-2px);
}
.app-install-platforms i { font-size: 2rem; color: var(--install-blue); }
.app-install-callout {
  display: flex;
  align-items: flex-start;
  gap: 0.9rem;
  margin: 1rem 0 1.5rem;
  padding: 1rem 1.15rem;
  border-left: 4px solid var(--install-blue);
  border-radius: 0.5rem;
  background: var(--install-soft);
}
.app-install-callout > i { flex: none; margin-top: 0.15rem; color: var(--install-blue); font-size: 1.35rem; }
.app-install-callout p { margin: 0; }
.app-install-callout--important {
  border-left-color: #d88600;
  background: #fff7e6;
}
.app-install-callout--important > i { color: #b56d00; }
.app-install-callout--important strong { display: block; margin-bottom: 0.2rem; }
.app-install-section {
  scroll-margin-top: 6rem;
  margin-top: 3rem;
  padding-top: 0.25rem;
}
.app-install-heading { display: flex; align-items: center; gap: 1rem; margin-bottom: 1.25rem; }
.app-install-heading h2,
.app-install-finish h2 { margin: 0; }
.app-install-eyebrow {
  margin: 0 0 0.15rem;
  color: #607086;
  font-size: 0.75rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.app-install-platform-icon,
.app-install-finish-icon {
  display: inline-flex;
  width: 3.5rem;
  height: 3.5rem;
  flex: none;
  align-items: center;
  justify-content: center;
  border-radius: 1rem;
  color: #fff;
  font-size: 1.75rem;
}
.app-install-platform-icon--android { background: #27884b; }
.app-install-platform-icon--apple { background: #222; }
.app-install-platform-icon--pc { background: var(--install-blue); }
.app-install-steps { margin: 0; padding: 0; list-style: none; counter-reset: install-step; }
.app-install-steps li {
  position: relative;
  display: grid;
  grid-template-columns: 3.25rem 1fr;
  gap: 1rem;
  min-height: 4.25rem;
  padding: 0 0 1.35rem;
  counter-increment: install-step;
}
.app-install-steps li:not(:last-child)::after {
  content: "";
  position: absolute;
  top: 3.05rem;
  bottom: 0.1rem;
  left: 1.58rem;
  width: 2px;
  background: #dce3ed;
}
.app-install-step-icon {
  position: relative;
  display: inline-flex;
  width: 3.25rem;
  height: 3.25rem;
  align-items: center;
  justify-content: center;
  border: 2px solid #dce3ed;
  border-radius: 50%;
  background: #fff;
  color: var(--install-blue);
  font-size: 1.15rem;
}
.app-install-step-icon::after {
  content: counter(install-step);
  position: absolute;
  right: -0.35rem;
  bottom: -0.25rem;
  display: inline-flex;
  width: 1.25rem;
  height: 1.25rem;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--brand-navy, #17233b);
  color: #fff;
  font-size: 0.7rem;
  font-weight: 800;
}
.app-install-steps strong { display: block; padding-top: 0.2rem; font-size: 1.05rem; }
.app-install-steps p { margin: 0.2rem 0 0; color: #56657a; }
.app-install-alternative { padding: 0.85rem 1rem; border-radius: 0.5rem; background: var(--install-soft); }
.app-install-alternative i { margin-right: 0.35rem; color: var(--install-blue); }
.app-install-finish {
  display: flex;
  align-items: flex-start;
  gap: 1.25rem;
  scroll-margin-top: 6rem;
  margin-top: 3.5rem;
  padding: 1.5rem;
  border-radius: 1rem;
  background: var(--brand-navy, #17233b);
  color: #fff;
}
.app-install-finish-icon { background: #f2a900; color: #17233b; }
.app-install-finish .app-install-eyebrow { color: #b9c9df; }
.app-install-finish p:not(.app-install-eyebrow) { color: #e5ebf4; }
.app-install-finish a.button { display: inline-flex; align-items: center; gap: 0.5rem; margin-top: 0.35rem; text-decoration: none; }

@media (max-width: 36rem) {
  .app-install-platforms { gap: 0.45rem; }
  .app-install-platforms a { min-height: 5.5rem; padding: 0.7rem 0.35rem; font-size: 0.88rem; }
  .app-install-platforms i { font-size: 1.65rem; }
  .app-install-finish { flex-direction: column; }
}

/* Show/hide toggle on password fields (login, register, reset, profile —
   templates/forms/fields/password/password.html.twig). .password-field-wrapper
   is the field's own .form-input-wrapper, flagged by that override; vendor's
   form-input-addon-wrapper (used for prepend/append elsewhere) carries no
   CSS of its own to inherit, so this is self-contained. */
.password-field-wrapper {
  position: relative;
}
.password-field-wrapper input[type="password"],
.password-field-wrapper input[type="text"] {
  padding-right: 2.25rem;
  /* Same Pico phantom margin-bottom as .header-search-form input and
     .search-page-form input[type='search'] above: `input:not([type=checkbox],
     [type=radio]),select,textarea{margin-bottom:var(--pico-spacing)}` (16px)
     made .password-field-wrapper (the input's only in-flow child) taller
     than the visible input box, so .password-toggle's `top: 50%` centered
     on that extra height instead of the input itself — the icon sat low,
     against the field's bottom border rather than mid-height. */
  margin: 0;
}
/* [type="button"] in the selector, not just the class: same Pico
   width:100%/margin-bottom fight as .header-search-toggle above. */
.password-toggle[type="button"] {
  position: absolute;
  top: 50%;
  right: 0.35rem;
  transform: translateY(-50%);
  height: 1.9rem;
  width: 1.9rem;
  margin: 0;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: transparent;
  color: inherit;
  opacity: 0.6;
  cursor: pointer;
}
.password-toggle:hover {
  opacity: 1;
}
/* Edge/legacy IE add their own native reveal ("eye") and clear icons inside
   password fields, landing right on top of ours (::-ms-reveal is Microsoft-
   only; other engines ignore this rule, so it's harmless elsewhere). */
.password-field-wrapper input[type="password"]::-ms-reveal,
.password-field-wrapper input[type="password"]::-ms-clear {
  display: none;
}
