/*
 * Accueil (homepage) — hero/about, spotlight (incl. the blog/calendar
 * spotlight cards — these are Accueil's own markup even though they show
 * blog/calendar content), contact, comité sections.
 * Split out of theme.css 2026-08-04 (v10.29, 4th attempt) — see
 * VERSIONS.md.
 */

/* ---- Accueil page ---- */
.gsl-home-wrap { margin: -1rem 0 0; padding: 0; }
.gsl-home-section {
    width: 100vw;
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
    padding: 5rem 0;
    overflow: hidden;
}
.gsl-home-section--hero { padding: 0; }
/* Alternating dark/lighter tone down the page, 3 real sections in order:
   hero+intro (dark, page bg) -> spotlight (lighter) -> contact/map + comité
   (dark, one merged section since v10.42). Two deliberate tones, not 4 one-off colors, so the
   alternation reads as a clear system rather than coincidental drift.
   .gsl-home-section--story is dead/orphaned (the histoire section moved
   off this page in v2.1) — kept unstyled here, not part of the pattern. */
.gsl-home-section--find { background: #0e1518; }  /* Nous trouver + Le comité, one section (v10.42) — the dark tone of the old contact section keeps the alternation after the lighter spotlight */
.gsl-home-inner { max-width: 1200px; margin: 0 auto; padding: 0 2rem; }
.gsl-home-section__head { text-align: center; margin-bottom: 3rem; }
.gsl-home-section__head h2 { font-size: clamp(1.5rem,3vw,2.2rem); font-family:"Cardo",Georgia,serif; color: var(--gsl-text); margin: 0 0 0.5rem; }
.gsl-home-section__head p { opacity: 0.5; font-size: 0.95rem; margin: 0; }
/* Hero banner */
.gsl-home-banner { position: relative; width: 100%; min-height: 520px; display: flex; align-items: flex-end; justify-content: flex-start; background-size: cover; background-position: center 35%; overflow: hidden; }
/* Hero slider is the bg — pull the banner section up to overlay it */
.gsl-home-wrap .gsl-home-section--hero {
    margin-top: calc(-1 * var(--gsl-banner-h)) !important;
    margin-block-start: calc(-1 * var(--gsl-banner-h)) !important;
    position: relative;
    z-index: 1;
    pointer-events: none; /* transparent area passes clicks through to hero arrows/dots */
}
.gsl-home-wrap .gsl-home-banner {
    background-image: none !important;
    background: transparent !important;
    min-height: var(--gsl-banner-h) !important;
    overflow: visible !important;
    align-items: center !important;
}
.gsl-home-wrap .gsl-home-banner__overlay {
    display: block !important;
    background: linear-gradient(to right, rgba(0,0,0,0.62) 0%, rgba(0,0,0,0.25) 65%, transparent 100%) !important;
    position: absolute;
    /* Scoped to the sharp image's own footprint (matches
       .gsl-hero-slide__sharp), not the full banner width — so the
       gradient still reads relative to the photo the same way it did
       before the 1.7 margin-reduction, instead of stretching across the
       blurred margins too. */
    top: 0; bottom: 0;
    left: calc((100% - var(--gsl-banner-photo-w)) / 2);
    width: var(--gsl-banner-photo-w);
    pointer-events: none;
}
.gsl-home-wrap .gsl-home-banner__content { pointer-events: auto; }
.gsl-home-banner__overlay { display: none; }
.gsl-home-banner__content { position: relative; z-index: 1; padding: 3rem 4rem 3rem 7rem; color: #fff; max-width: 680px; }
/* 1.7: keep the text anchored to the SHARP image's own left edge (now
   inset from the banner's outer edge by the blurred margin,
   (100% - --gsl-banner-photo-w) / 2), not the banner's outer edge —
   otherwise the text visually floats over blurred empty space instead
   of over the photo, like it did before this exploration. Must ZERO the
   base rule's own padding-left (7rem, line above) first — otherwise this
   margin stacks ON TOP of that padding instead of replacing it, pushing
   the text well past the photo's actual left edge instead of right after
   it. */
.gsl-home-wrap .gsl-home-banner__content {
    padding-left: 1.5rem;
    margin-left: calc((100% - var(--gsl-banner-photo-w)) / 2);
    max-width: calc(var(--gsl-banner-photo-w) - 3rem);
}
.gsl-home-banner__eyebrow { font-size: 0.78rem; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; opacity: 0.6; margin: 0 0 0.8rem; font-family: "Inter", sans-serif; }
.gsl-home-banner__title { font-size: clamp(2rem,5vw,3.6rem); font-family: "Cardo",Georgia,serif; line-height: 1.1; margin: 0 0 1rem; }
.gsl-home-banner__sub { font-size: 1rem; opacity: 0.75; line-height: 1.6; margin: 0 0 2rem; }
/* Filled accent-button convention, site-wide: solid gold background, dark
   text by default, text flips to white on hover (not a rust/gold-toned
   hover, which read as low-contrast) — kept consistent with the matching
   .gsl-home-spotlight-item__link buttons below. Not the same thing as the
   separate grey/light button system used by cave-table/blog controls
   (.gsl-dt-search__btn, .gsl-dt-admin-link, etc.) — those are intentionally
   a different, lighter visual language and untouched here. color needs
   !important: the global `a { color: #b8956a !important; }` reset (top of
   this file) otherwise wins and the button text renders gold instead of
   dark, since a plain unqualified color here has lower specificity than
   that rule despite coming later in the file. */
.gsl-home-banner__cta { display: inline-block; padding: 0.7rem 1.8rem; background: var(--gsl-accent); color: #0e1518 !important; font-weight: 700; font-size: 0.88rem; letter-spacing: 0.04em; border-radius: 3px; text-decoration: none; transition: color 0.2s; }
.gsl-home-banner__cta:hover { color: #fff !important; outline: none !important; box-shadow: none !important; }
/* Activity cards — 4 cols wide, 2x2 medium, 1 col narrow */
.gsl-home-cards { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.75rem; margin-top: 3rem; margin-bottom: 3rem; }
.gsl-home-card { background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.09); border-radius: 6px; overflow: hidden; display: flex; flex-direction: column; }
.gsl-home-card__img { width: 100%; height: 276px; object-fit: cover; display: block; background: rgba(255,255,255,0.04); flex-shrink: 0; }
.gsl-home-card__body { padding: 1.2rem 1.4rem 1.4rem; border-top: 3px solid var(--gsl-accent); display: flex; flex-direction: column; justify-content: flex-start; flex: 1; }
.gsl-home-card__title { font-size: 1rem; font-weight: 700; color: var(--gsl-text); margin: 0 0 0.5rem; }
.gsl-home-card__desc { font-size: 0.86rem; opacity: 0.65; line-height: 1.65; margin: 0; }
/* About paragraph strip */
.gsl-home-about { padding-top: 3.5rem; }
.gsl-home-about .gsl-home-story__body { gap: 5rem; }
/* Spotlight section */
.gsl-home-section--spotlight { background: #181e22; }
.gsl-home-spotlight__body { display: grid; grid-template-columns: 1fr 1fr; gap: 3rem; align-items: start; }
/* v6.0 second pass: true 2x2 grid (was 2 flex columns) — one dedicated
   category slot per cell (general/camp/desob) plus the calendar, so the
   grid reads as 4 co-equal cards rather than a lopsided 3-vs-1 column
   split. Explicit named areas keep the visual layout (general | desob /
   camp | calendar) obvious from the CSS itself, not just DOM order. */
.gsl-home-spotlight__body--grid {
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 1fr 1fr;
    grid-template-areas: "tl tr" "bl br";
    gap: 1.8rem 3rem;
    /* Overrides the base class's align-items:start (both classes live on
       the same element) — grid rows only equalize to their tallest cell's
       natural height if items are told to stretch to fill it; "start"
       was letting each card keep its own intrinsic height instead, so a
       short card and a tall card in the same row ended up different
       heights with misaligned bottom links. */
    align-items: stretch;
}
.gsl-home-spotlight__cell { display: flex; }
.gsl-home-spotlight__cell--tl { grid-area: tl; }
.gsl-home-spotlight__cell--tr { grid-area: tr; }
.gsl-home-spotlight__cell--bl { grid-area: bl; }
.gsl-home-spotlight__cell--br { grid-area: br; }
.gsl-home-spotlight__cell .gsl-home-spotlight-item { flex: 1; display: flex; flex-direction: column; }
.gsl-home-spotlight__cell .gsl-home-spotlight-item .gsl-home-spotlight-item__body { flex: 1; display: flex; flex-direction: column; }
.gsl-home-spotlight__cell .gsl-home-spotlight-item .gsl-home-spotlight-item__desc { flex: 1; }
/* Pins the bottom link to the same vertical position regardless of how
   much text/content sits above it, within an already-equal-height card
   (see align-items:stretch above) — auto margin eats all remaining flex
   space instead of the desc/list growing to fill it unevenly. */
.gsl-home-spotlight__cell .gsl-home-spotlight-item .gsl-home-spotlight-item__link { margin-top: auto; }
.gsl-home-spotlight-item { background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.07); border-radius: 6px; overflow: hidden; display: block; text-decoration: none !important; }
/* v6.0: last-3-blog-posts cards. Photo box uses object-fit:contain against
   a flat fill (never crops — same technique as .gsl-liens-card__photo in
   liens.php) rather than object-fit:cover, since these ~500 photos are
   arbitrary/uncurated (unlike liens.php's handful of dev-produced images)
   and cropping them unpredictably would sometimes look bad with no way to
   tell which ones ahead of time. Fixed height so every card in the column
   is the same shape whether or not a given post actually has a photo
   (only 3% don't) — see the placeholder rule just below. */
.gsl-home-spotlight-item__photo { display: block; position: relative; height: 190px; overflow: hidden; background: rgba(255,255,255,0.04); background-size: cover; background-position: center; }
/* Fade-away fill, computed per-image, no per-photo judgment call: a
   blurred/darkened full-bleed copy of the exact same photo (set inline as
   the anchor's own background-image, see accueil.php) sits behind the
   sharp object-fit:contain image, so the box is never letterboxed with a
   flat color no matter the photo's aspect ratio. Lives on a ::before
   pseudo-element rather than filter:blur() on .__photo itself, which
   would blur the foreground <img> too since it isn't a separate stacking
   context. (CLAUDE.md's Liens-cards notes rejected this exact technique
   there — but that was for a handful of static photos Anna hand-produces
   herself against a matched flat color; here it's ~500 arbitrary,
   automatically-rotating blog photos of unknown tone, where a fixed flat
   color can't adapt and a per-photo blur costs nothing extra.) */
.gsl-home-spotlight-item__photo::before {
    content: "";
    position: absolute;
    /* Overscan the box before computing background-size:cover (not a
       transform:scale() on top of an already-cover-cropped layer — that
       compounded the crop, so a wide/panoramic source photo showed only a
       narrow, off-center slice of itself behind the blur, exaggerating
       whatever brightness gradient that slice happened to contain instead
       of reading as "the same photo, softened"). A generous negative inset
       re-triggers cover-sizing against the larger box, growing outward
       from center symmetrically, so the visible portion stays a faithful
       (if further-zoomed) crop of the actual photo. Also large enough that
       the blur's own soft/rounded edge — a Gaussian blur always rounds a
       hard rectangular edge, which read as a "circle" vignette before —
       lands outside the card's overflow:hidden clip entirely. */
    inset: -40px;
    background-image: inherit;
    background-size: cover;
    background-position: center;
    filter: blur(18px) brightness(0.55);
    z-index: 0;
}
.gsl-home-spotlight-item__photo img { display: block; position: relative; z-index: 1; width: 100%; height: 100%; object-fit: contain; }
.gsl-home-spotlight-item__photo-placeholder { position: relative; z-index: 1; }
.gsl-home-spotlight-item__photo-placeholder { display: flex; align-items: center; justify-content: center; height: 100%; font-family: "Cardo", Georgia, serif; font-size: 1.3rem; letter-spacing: 0.08em; color: var(--gsl-accent); opacity: 0.35; }
/* Body padding trimmed (was 1.2rem 1.4rem 1.4rem) — Anna asked to shrink
   just the text-body half of the spotlight cards, not the photo box
   above it (kept at its existing height, untouched). Paired with the
   shorter excerpt word count (accueil.php) and the calendar card's own
   shorter --gsl-spotlight-event-row-h below, so both halves of the
   bottom row shrink together and stay visually matched. */
.gsl-home-spotlight-item__body { padding: 0.9rem 1.4rem 1rem; border-top: 3px solid var(--gsl-accent); }
/* Lighter brown-gold than the site's base --gsl-accent (#6D533C, a muted
   brown) — this label sits directly under the photo box on a dark card,
   and a lighter tone reads better there than the darker site-wide accent.
   Covers both uses: the per-card kicker/date line on the 3 blog cards and
   "Prochains événements" on the calendar card, since both share this
   class. */
.gsl-home-spotlight-item__label { font-size: 0.72rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: #c9a876; opacity: 0.9; margin: 0 0 0.4rem; }
.gsl-home-spotlight-item__title { font-size: 1.05rem; font-weight: 700; margin: 0 0 0.5rem; font-family: "Cardo", Georgia, serif; }
.gsl-home-spotlight-item__title a { color: var(--gsl-text) !important; text-decoration: none; }
.gsl-home-spotlight-item__title a:hover { color: var(--gsl-accent) !important; }
.gsl-home-spotlight-item__desc { font-size: 0.88rem; opacity: 0.65; line-height: 1.45; margin: 0 0 0.6rem; }
/* Filled button treatment, all 4 cards alike (v6.0 fourth pass) — was a
   plain text link, then a bordered/outline button; matches the filled-
   accent look of .gsl-home-banner__cta instead (solid background, dark
   text) since that read as nicer than the outline version. Same site-wide
   convention as .gsl-home-banner__cta: dark text by default, white on
   hover — see that rule's comment for why (not the opacity-fade tried
   first here, which read as a muddy rust tone on hover instead of a
   clean state change). */
.gsl-home-spotlight-item__link {
    display: block;
    text-align: center;
    font-size: 0.83rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    background: var(--gsl-accent);
    color: #0e1518 !important;
    text-decoration: none !important;
    padding: 0.6rem 1rem;
    border-radius: 4px;
    transition: color 0.2s ease;
}
.gsl-home-spotlight-item__link:hover { color: #fff !important; text-decoration: none !important; }
/* Spotlight: upcoming-events card (bottom-right cell) — v6.0 third pass:
   restyled to reuse the exact same .gsl-home-spotlight-item shape as the 3
   blog cards (photo box + accent-border body + bottom link), instead of
   its own bespoke layout, so all 4 cards in the grid read as one
   consistent set. The event list itself replaces where a blog card's
   excerpt would go. */
/* Capped height + internal scroll (not left to grow freely): the query
   pulls up to 5 events, and an uncapped list made the calendar card's
   height vary day-to-day with however many happened to be upcoming —
   since align-items:stretch matches every card in the same grid row to
   its tallest neighbor, a busy day stretched the camp card too, and a
   quiet day let the whole bottom row shrink. ~3 events' worth of height,
   matching a blog card's own natural excerpt-area height, then scrolls
   rather than clipping silently — a 4th/5th event should still be
   reachable, not invisible. */
/* Row height is fixed and exact (--gsl-spotlight-event-row-h) rather than
   estimated: each .gsl-home-spotlight-event is forced to exactly one line
   (no wrapping — title truncates with an ellipsis instead), so the list's
   max-height below can be a precise whole-number multiple of one row's
   real height. That's what actually prevents a partial row/tag from ever
   peeking out at the cutoff, regardless of viewport size or how long a
   given event's title happens to be — a plain fixed pixel max-height
   (the previous approach) couldn't guarantee that, since row height varied
   with whatever content happened to wrap that day. */
.gsl-home-spotlight-events__mask {
    /* Was 3.2rem — tightened alongside the blog cards' own shorter body
       (see .gsl-home-spotlight-item__body/__desc above) so the calendar
       card's 3-row list shrinks to match, still exactly 3 rows visible
       (the *3 multiplier below is unchanged). */
    --gsl-spotlight-event-row-h: 2.3rem;
    margin: 0 0 0.6rem;
}
/* flex-shrink:0 + min-height:0 go directly on the list, since IT is the
   flex item of .gsl-home-spotlight-item__body's flex column (the mask
   wrapper around it isn't itself a flex item of anything) — without
   them the list's default min-height:auto let it grow to fit all 5
   events instead of clipping to 3 rows + scrolling, same bug class as
   the wrapper fix earlier, just needed on the actual flex item this time. */
.gsl-home-spotlight-events__list {
    list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column;
    flex-shrink: 0;
    min-height: 0;
    max-height: calc(var(--gsl-spotlight-event-row-h) * 3);
    overflow-y: scroll;
    overscroll-behavior: contain;
    /* Thin black scrollbar as the scroll-affordance. Didn't render in
       Chrome/macOS in testing here (that combination sticks to overlay
       scrollbars regardless of these rules), but scrollbar-width/
       ::-webkit-scrollbar are still real, standard properties other
       browsers/OS scrollbar-preference combinations do honor — left in
       as a straightforward, low-intrusion styling rather than fighting
       it with a fake always-drawn bar. */
    scrollbar-width: thin;
    scrollbar-color: rgba(0,0,0,0.45) rgba(255,255,255,0.05);
}
.gsl-home-spotlight-events__list::-webkit-scrollbar { width: 4px; }
.gsl-home-spotlight-events__list::-webkit-scrollbar-track { background: rgba(255,255,255,0.05); }
.gsl-home-spotlight-events__list::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.45); border-radius: 2px; }
.gsl-home-spotlight-event {
    height: var(--gsl-spotlight-event-row-h);
    /* flex-shrink:0 is the actual fix for the "all 5 events show, no
       scroll" bug: as a flex item of .gsl-home-spotlight-events__list
       (itself display:flex;flex-direction:column), this row's default
       flex-shrink:1 let the browser squeeze all 5 rows shorter than
       their set height so they'd all fit inside the list's capped
       153.6px box instead of overflowing it — the box was genuinely
       clipped at the right height the whole time (confirmed via
       devtools Computed panel), the rows themselves were just shrinking
       to avoid ever needing to scroll. */
    flex-shrink: 0;
    box-sizing: border-box;
    padding: 0.3rem 0;
    display: flex; align-items: center; gap: 0.7rem;
    border-bottom: 1px solid rgba(255,255,255,0.06);
    overflow: hidden;
}
.gsl-home-spotlight-event:last-child { border-bottom: none; }
.gsl-home-spotlight-event__date { font-size: 0.78rem; font-variant-numeric: tabular-nums; opacity: 0.45; white-space: nowrap; min-width: 3.5rem; flex-shrink: 0; }
.gsl-home-spotlight-event__info { display: flex; flex-wrap: nowrap; align-items: baseline; gap: 0.4rem; flex: 1; min-width: 0; }
.gsl-home-spotlight-event__title { font-size: 0.9rem; font-weight: 500; color: var(--gsl-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.gsl-home-spotlight-event__time { font-size: 0.75rem; opacity: 0.4; white-space: nowrap; flex-shrink: 0; }
/* Empty state — content-blind, same treatment every time there are zero
   events, no attempt to evaluate "how empty." Reuses .gsl-home-spotlight-
   item__desc's own styling, just italicized to read as a status message
   rather than a real excerpt. */
.gsl-home-spotlight-item__desc--empty { font-style: italic; opacity: 0.45; }
.gsl-home-about__text { font-size: 1.05rem; line-height: 1.85; opacity: 0.82; }
.gsl-home-about__stats { display: flex; flex-direction: column; gap: 1.2rem; }
.gsl-home-stat { border-left: 3px solid var(--gsl-accent); padding: 0.4rem 0 0.4rem 1.2rem; }
.gsl-home-stat__val { font-size: 2rem; font-weight: 700; color: var(--gsl-text); font-family:"Cardo",Georgia,serif; line-height: 1; }
.gsl-home-stat__label { font-size: 0.78rem; opacity: 0.5; text-transform: uppercase; letter-spacing: 0.06em; margin-top: 0.2rem; }
/* Histoire */
.gsl-home-story__body { display: grid; grid-template-columns: 2fr 1fr; gap: 5rem; align-items: start; }
.gsl-home-story__text { font-size: 1rem; line-height: 1.9; opacity: 0.8; }
.gsl-home-story__text p { margin: 0 0 1.2rem; }
.gsl-home-milestones { border-left: 1px solid rgba(122,179,200,0.25); padding-left: 1.5rem; }
.gsl-home-milestone { margin-bottom: 1.6rem; position: relative; }
.gsl-home-milestone::before { content:""; position:absolute; left:-1.75rem; top:0.35rem; width:8px; height:8px; border-radius:50%; background: var(--gsl-accent); }
.gsl-home-milestone__year { font-size: 0.78rem; font-weight: 700; color: var(--gsl-accent); letter-spacing: 0.06em; margin-bottom: 0.2rem; }
.gsl-home-milestone__desc { font-size: 0.88rem; opacity: 0.7; line-height: 1.6; margin: 0; }
/* Contact / Nous trouver */
.gsl-home-map { border-radius: 6px; overflow: hidden; border: 1px solid rgba(255,255,255,0.1); }
.gsl-home-map iframe { display: block; width: 100%; height: 400px; border: none; }
.gsl-home-contact__details { display: flex; flex-direction: column; gap: 1.8rem; padding-top: 0.5rem; }
.gsl-home-contact__row h4 { font-size: 0.72rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--gsl-accent); opacity: 0.8; margin: 0 0 0.4rem; }
.gsl-home-contact__row p, .gsl-home-contact__row a { font-size: 0.95rem; opacity: 0.75; margin: 0; line-height: 1.7; color: var(--gsl-text); text-decoration: none; display: block; }
.gsl-home-contact__row a:hover { color: var(--gsl-accent); }
/* Board / Comité */
/* Nous trouver + Le comité share ONE 6-column grid (v10.42): column lines at 1/2 and 2/3
   exist for both rows — the top row is map 2/3 (cols 1-4) + details 1/3 (cols 5-6), the
   committee row is two 50-50 cells (3 cols each); both section headers span all 6.
   Zero column-gap so the fractions are exact; the old 4rem gutter between map and details
   is padding-left on the details cell. The committee row is two 50-50 cells; a photo card
   fills its cell with the blurred back-fill around the photo kept at its original 266px. */
.gsl-home-find-grid { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); align-items: start; }
.gsl-home-find-grid > .gsl-home-section__head { grid-column: 1 / -1; }
.gsl-home-find__head--board { margin-top: 6rem; scroll-margin-top: 5rem; }  /* 6rem: the two old 5rem section paddings, minus the background step that no longer separates them */
.gsl-home-find__map { grid-column: 1 / span 4; }
.gsl-home-find__details { grid-column: 5 / span 2; padding-left: 4rem; }
.gsl-home-find__card { grid-column: span 3; box-sizing: border-box; width: min(100%, 266px); justify-self: start; margin-right: 0.75rem; }  /* border-box: 266px is the card's TOTAL width, padding included (as when it stretched to a 266px grid track) */
.gsl-home-find__card + .gsl-home-find__card { justify-self: end; margin-right: 0; margin-left: 0.75rem; }
/* Photo cards fill their whole half (back-fill, see .gsl-home-board-card--photo); the 0.75rem margins leave a 1.5rem gutter, the old board-grid gap. A card WITHOUT a photo is just the 266px avatar box above. */
.gsl-home-find__card.gsl-home-board-card--photo { width: auto; justify-self: stretch; }
.gsl-home-board-card { background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.07); border-radius: 6px; padding: 1.8rem 1.2rem; text-align: center; }
.gsl-home-board-card__avatar { width: 56px; height: 56px; border-radius: 50%; background: rgba(122,179,200,0.15); color: var(--gsl-accent); display: flex; align-items: center; justify-content: center; font-size: 1.3rem; font-weight: 700; margin: 0 auto 1rem; }
.gsl-home-board-card__name { font-weight: 600; font-size: 1rem; margin: 0 0 0.3rem; color: var(--gsl-text); }
.gsl-home-board-card__role { font-size: 0.78rem; opacity: 0.45; font-style: italic; margin: 0; }
/* Board card with a real photo (v10.42): the card fills its whole grid cell and uses the
   site's usual back-fill — a blurred, darkened full-bleed copy of the same photo behind a
   sharp copy kept at its ORIGINAL size (the 266px-wide card it had when 4 sat in a row,
   cover-cropped from the top, never stretched), centered. Same technique as the spotlight
   cards (.gsl-home-spotlight-item__photo::before) and the hero slider. The photo reaches both
   layers through --photo (set inline in accueil.php) because the sharp layer also carries the
   dark gradient scrim for the white name/role, and `inherit` can't be combined with it.
   ::before = blurred backdrop, ::after = sharp photo + scrim, text on top. */
.gsl-home-board-card--photo {
    position: relative;
    min-height: 260px;
    background: none;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    overflow: hidden;
    border: none;
    padding: 1.2rem 1.2rem 1.4rem;
}
.gsl-home-board-card--photo::before {
    content: "";
    position: absolute;
    inset: -40px;  /* overscan so the blur's soft edge lands outside the overflow:hidden clip */
    background: var(--photo) center / cover;
    filter: blur(18px) brightness(0.55);
    z-index: 0;
}
.gsl-home-board-card--photo::after {
    content: "";
    position: absolute;
    top: 0; bottom: 0; left: 50%;
    width: min(100%, 266px);
    transform: translateX(-50%);
    background: linear-gradient(to top, rgba(0,0,0,0.75) 0%, rgba(0,0,0,0.25) 45%, transparent 70%), var(--photo) center 15% / cover;
    z-index: 1;
}
.gsl-home-board-card--photo .gsl-home-board-card__name,
.gsl-home-board-card--photo .gsl-home-board-card__role {
    position: relative;
    z-index: 2;
    color: #ffffff;
}
.gsl-home-board-card--photo .gsl-home-board-card__role { opacity: 0.75; }
/* 4 cards → 2x2 when viewport too narrow for single row */
@media (max-width: 1000px) {
    .gsl-home-cards { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 900px) {
    .gsl-home-story__body, .gsl-home-spotlight__body { grid-template-columns: 1fr; gap: 2.5rem; }
    /* Nous trouver + comité: 2 columns — map and details stack full width, the two board cards stay side by side */
    .gsl-home-find-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .gsl-home-find__map, .gsl-home-find__details { grid-column: 1 / -1; }
    .gsl-home-find__map { margin-bottom: 2.5rem; }
    .gsl-home-find__details { padding-left: 0; }
    .gsl-home-find__card { grid-column: span 1; }
    /* Stack the 2x2 grid into a single reading-order column: general post,
       desob, camp, then calendar. */
    .gsl-home-spotlight__body--grid {
        grid-template-areas: "tl" "tr" "bl" "br";
        gap: 1.8rem;
    }
}
@media (max-width: 820px) {
    .gsl-home-banner__content { padding: 2rem; }
    .gsl-home-section { padding: 3rem 0; }
    .gsl-home-find__head--board { margin-top: 4rem; scroll-margin-top: 3rem; }
    .gsl-home-card__img { height: 220px; }
}
/* Comité cards: one per row on phones, full width as before */
@media (max-width: 600px) {
    .gsl-home-find-grid { grid-template-columns: minmax(0, 1fr); }
    .gsl-home-find__card { grid-column: 1; width: 100%; margin-right: 0; }
    .gsl-home-find__card + .gsl-home-find__card { margin-top: 1.5rem; margin-left: 0; }
}
/* 2x2 → 1 col on very narrow */
@media (max-width: 480px) {
    .gsl-home-cards { grid-template-columns: 1fr; }
    .gsl-home-stat__val { font-size: 1.5rem; }
}
