 :root {
    --olympus-primary-color: #F0BC42; /*#ff5e3a;*/
    --olympus-secondary-color: #8E1F2F; /*#3f4257;*/
    --olympus-placeholder-form-color: #888da8;
    --olympus-white-color: #fff;
    --olympus-heading-color: #515365;
    --olympus-icon-color: #9a9fbf;
    --olympus-body-bg: #edf2f6;
    --olympus-body-font-color: #888da8;
    --olympus-body-bg-white: #ffffff;
    --olympus-grey: #515365;
    --olympus-grey-light: #888da8;
    --olympus-grey-lighter: #9a9fbf;
    --olympus-purple: #7c5ac2;
    --olympus-purple-dark: #6236b2;
    --olympus-blue: #38a9ff;
    --olympus-breez: #08ddc1;
    --olympus-breez-light: #2aebcb;
    --olympus-orange: #ff763a;
    --olympus-yellow: #ffdc1b;
    --olympus-smoke: #e6ecf5;
    --olympus-green: #1ed760;
    --olympus-smoke-light: #fafbfd;
    --olympus-blue-light: #00b7ff;
    --olympus-violet: #7442ce;
    --olympus-c-facebook: #2f5b9d;
    --olympus-c-twitter: #38bff1;
    --olympus-c-dribbble: #f74881;
    --olympus-c-rss: #fab819;
    --olympus-c-spotify: #1ed760;
    --olympus-c-google: #ea4235;
    --olympus-border-color: #e6ecf5;
    --olympus-headings-font-weight-h1-h4: 300;
}
/*
ul {
    list-style: none;
    padding: 0;
}

a {
    transition: all .15s ease;
    text-decoration: none;
}
*/
 

select,
input,
.form-control {
    background-color: transparent;
}

/*
select, input {
    display: block;
    width: 100%;
    padding: 1.1rem 1.1rem;
    font-size: .875rem;
    line-height: 1.25;
    color: var(--olympus-body-font-color);
    background-color: transparent;
    background-image: none;
    background-clip: padding-box;
    border: 1px solid var(--olympus-border-color);
    border-radius: 0.25rem;
    transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
}

 

.h1, .h2, .h3, .h4, .h5, .h6 {
    color: var(--olympus-heading-color);
}*/

.nav-tabs .nav-item {
    position: relative;
}

.form-group {
    position: relative;
    margin-bottom: 1.4rem;
}

  

a > svg {
    transition: all .15s ease;
}

svg {
    transition: all .3s ease;
    vertical-align: -.125em;
}

button.btn {
    padding: .5rem 1rem;
}

 
 
/*
.h1, .h2, .h3, .h4, h1, h2, h3, h4 {
    font-weight: 300;
}*/

img {
    vertical-align: unset;
    max-width: 100%;
    height: auto;
    display: inline-block;
}

  

/*------------- #Styles for svg-icons --------------*/

[class^="olymp-"], [class*=" -icon"] {
    height: 26px;
    width: 26px;
    display: inline-block;
}

 
  
   
  
 
  
 
  
 
   
 
   
 
 
    
 
 
    
  
 
 /*
 
.preloader {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

 */
 

 

/*------------- #FORMS --------------*/
/*
label.control-label {
    color: var(--olympus-placeholder-form-color);
}

 

label {
    margin-bottom: .5em;
}*/
 

 

 /*

.form-select, input, .form-control {
    color: var(--olympus-heading-color);
    line-height: inherit;
    font-size: .875rem;
}
 */
  
   
 
  
 
 
 
  
/*
.checkbox {
    margin-bottom: 1rem;
}

.checkbox label {
    cursor: pointer;
    padding-left: 0;
    margin-bottom: 0;
}

 
 

.checkbox input[type=checkbox] {
    opacity: 0;
    position: absolute;
    margin: 0;
    z-index: -1;
    width: 0;
    height: 0;
    overflow: hidden;
    left: 0;
    pointer-events: none;
}*/
 


/*------------- #CARDS: renfort contraste (thème par défaut : bordure
rgba(0,0,0,.125) sans ombre sur fond --olympus-body-bg très clair, les
blocs se distinguent mal les uns des autres/du fond) --------------*/
.card {
    border-color: rgba(81, 83, 101, .12);
    border-radius: 16px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, .06);
}

/* Le thème (bootstrap.min.css) code les rayons internes en dur
(calc(.25rem - 1px)) plutôt qu'en variable CSS - sans ce correctif, les
coins de l'image/header/footer restent visiblement moins arrondis que le
.card qui les contient. */
.card-img-top,
.card-header:first-child {
    border-top-left-radius: 15px;
    border-top-right-radius: 15px;
}

.card-img-bottom,
.card-footer:last-child {
    border-bottom-left-radius: 15px;
    border-bottom-right-radius: 15px;
}

/*------------- #POST-COMPOSER: élément le plus important du site (page
d'accueil) - renfort au-delà du .card générique (voir plus haut) pour que
le formulaire de publication se distingue nettement --------------*/
.post-composer {
    border-color: rgba(81, 83, 101, .08);
    border-radius: 20px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, .08);
}

.post-composer-textarea {
    border: none;
    font-size: .95rem;
    font-weight: 400;
    padding: .5rem 0;
    resize: none;
    /* FIX (user-requested: "un vrai textarea ... donne de l'air", "min-height:
       80px"): the field is a real <textarea> (PostType::content is
       TextareaType, so line breaks already work) with a working JS
       auto-grow (ui.js's bindTextareaAutoresize(), on its "input" event) -
       but that only grows the box as text is TYPED, so an empty field still
       looked like a cramped single-line input. A flat 80px minimum makes it
       read as a real multi-line composer from the very first render, before
       a single character is typed; further growth as they type is still
       handled by the existing JS. */
    min-height: 80px;
}

.post-composer .btn-sm {
    font-weight: 500;
    font-size: .8125rem;
}

/* The avatar/textarea row is a flex item that can be squeezed by a long
unbroken word in the content field - min-width:0 lets it shrink instead
of forcing the row wider than the card. */
.post-composer .flex-grow-1 {
    min-width: 0;
}

/* FIX (user-reported: "le bouton violet est tronqué ... sort de la carte"):
 * same root cause as the rule right above, on the icon-buttons row instead
 * of the avatar/textarea one - a flex item's default min-width is `auto`
 * ("at least as wide as my content"), so this <ul> (Emoji/Photo/Vidéo/
 * Événement/Discussion) refused to shrink below its unscrolled content
 * width, forcing the row wider than the card and pushing the "Publier"
 * button (flex-shrink-0, in the same row, justify-content-between) out of
 * it. min-width: 0 lets it actually shrink and scroll internally
 * (overflow-x-auto, already set on the element) instead.
 * gap: 12px per spec (Bootstrap's own gap-* utilities only step 8px/16px). */
.post-composer-actions {
    min-width: 0;
    gap: 12px;
}

/* FIX (user-requested: "mode icônes seules ... petits boutons carrés ou
 * circulaires épurés (width: 40px; height: 40px)"): fixed-size, icon-only
 * button shared by Emoji/Photo/Vidéo/Événement/Discussion once their text
 * label was dropped - .btn-light's own hover is already "un fond gris très
 * clair", so nothing extra was needed for that part of the request. */
.post-composer-icon-btn {
    width: 40px;
    height: 40px;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

/* FIX (user-requested, explicit 600px breakpoint - narrower than
 * Bootstrap's own 576px "sm"): below it, the icon row and the "Publier"
 * button no longer share one cramped horizontal row - they stack, and the
 * button stretches to a full-width, comfortable tap target. The icons
 * stay left-aligned (align-items: stretch on the column does nothing to
 * .post-composer-actions's own internal alignment, which is unchanged).
 * Above 600px, this simply restores the row's own default (row,
 * space-between, center) - nothing to override there. */
@media (max-width: 599.98px) {
    .post-composer-actions-row {
        flex-direction: column;
        align-items: stretch;
        gap: 12px;
    }

    .post-composer-submit {
        width: 100%;
    }
}

/* FIX (user-reported: "le bouton discussion est censé faire quoi ? je
vois rien"): "Discussion" only calls .focus() on this field (see
bindContentFocus() in ui.js) - box-shadow:none here made that focus
invisible, so nothing appeared to happen on click. A subtle ring restores
visible feedback (and standard focus-visibility for anyone tabbing into
the field, lost when box-shadow was removed). */
.post-composer-textarea:focus {
    box-shadow: 0 0 0 3px rgba(240, 188, 66, .18);
}

/*------------- #REACTION-BAR: rendu plus discret/moderne (icône +
nombre nu, sans pastille colorée) - voir _bar.html.twig --------------*/
.reaction-btn {
    opacity: .85;
    transition: opacity .15s ease;
}

.reaction-btn:hover {
    opacity: 1;
}

.reaction-icon {
    font-size: 1.05rem;
    line-height: 1;
}

/*------------- #REGISTRATION-LOGIN-FORM --------------*/
.registration-login-form {
    border: 1px solid var(--olympus-border-color);
    border-radius: 0 5px 5px 0;
    background-color: var(--olympus-white-color);
    overflow: hidden;
    position: relative;
    padding-left: 71px;
    margin-bottom: 20px;
    min-height: 700px;
}

.registration-login-form .nav-tabs {
    float: left;
    display: block;
    height: 100%;
    border: none;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
}

.registration-login-form .nav-item {
    margin-bottom: 0;
    height: 50%;
    display: table;
}

.registration-login-form .nav-item:last-child .nav-link {
    border-bottom: 0;
}

.registration-login-form .nav-link {
    border-radius: 0;
    border: none;
    border-bottom: 1px solid var(--olympus-border-color);
    border-right: 1px solid var(--olympus-border-color);
    padding: 25px;
    color: #c0c4d8;
    fill: #c0c4d8;
    background-color: var(--olympus-smoke-light);
    height: 100%;
    display: table-cell;
    vertical-align: middle;
}

.registration-login-form .nav-link.active {
    fill: var(--olympus-primary-color);
    background-color: var(--olympus-white-color);
    border-color: var(--olympus-border-color);
}

.registration-login-form .nav-link svg {
    width: 21px;
    height: 21px;
}

.registration-login-form .tab-content {
    overflow: hidden;
}

.registration-login-form .content {
    padding: 35px 25px;
}

.registration-login-form .title {
    padding: 25px;
    border-bottom: 1px solid var(--olympus-border-color);
    margin-bottom: 0;
}


/*
 * Availability update card - feed/_content/availability/updated.html.twig.
 * Day tabs of the "a mis a jour ses disponibilites" feed card: flat tabs on
 * the tinted strip (Bootstrap's own .nav-tabs borders are reset), the active
 * day lifted onto the body background with an accent underline. The strip
 * scrolls sideways instead of wrapping when a member declared many days.
 * Selectors start at .availability-update to win over Bootstrap's
 * .nav-tabs rules whatever the stylesheet order.
 */
.availability-update .nav-tabs {
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
}

.availability-update .nav-tabs .nav-link {
    min-width: 4rem;
    border: 0;
    border-radius: 0;
    white-space: nowrap;
    box-shadow: inset 0 -2px 0 transparent;
}

.availability-update .nav-tabs .nav-link.active {
    background-color: var(--bs-body-bg);
    box-shadow: inset 0 -2px 0 var(--bs-primary);
}


/*
 * Follow card - feed/_content/profile/followed.html.twig.
 * The "X suit un utilisateur / un groupe / une page" card: a cover banner,
 * a round avatar overlapping it with a small "follow" badge, then name, city
 * and badges. The whole card is one link, hence the small lift on hover
 * (disabled for users who ask for reduced motion). The cover URL is dynamic
 * and set inline by the template; without a cover, a gradient stands in.
 */
.follow-card {
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.follow-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--bs-box-shadow) !important; /* beats .shadow-sm, which is !important */
}

.follow-card__cover {
    position: relative;
    height: 84px;
    background-size: cover;
    background-position: center;
}

.follow-card__cover--empty {
    background-image: linear-gradient(135deg, var(--bs-primary), var(--bs-info));
}

/* Soft dark fade at the bottom of the cover so the avatar ring stands out on any picture. */
.follow-card__cover::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(0, 0, 0, 0) 40%, rgba(0, 0, 0, 0.3) 100%);
}

.follow-card__avatar-wrap {
    position: relative;
    display: inline-block;
    margin-top: -42px;
}

.follow-card__avatar {
    display: block;
    width: 84px;
    height: 84px;
    object-fit: cover;
    border: 4px solid var(--bs-body-bg);
    box-shadow: var(--bs-box-shadow-sm);
}

/* Initial shown when the followed entity has no picture (page, deleted target). */
.follow-card__initial {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 2rem;
    font-weight: 700;
    color: #fff;
    background-image: linear-gradient(135deg, var(--bs-primary), var(--bs-info));
}

.follow-card__badge {
    position: absolute;
    right: -2px;
    bottom: 2px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    font-size: 0.85rem;
    color: #fff;
    background-color: var(--bs-primary);
    border: 3px solid var(--bs-body-bg);
    border-radius: 50%;
}

@media (prefers-reduced-motion: reduce) {
    .follow-card {
        transition: none;
    }

    .follow-card:hover {
        transform: none;
    }
}


/*
 * Member avatar of the home sidebar widgets ("Disponibles ce soir", "Membres
 * compatibles"). A fixed 56px square with object-fit: the members' pictures are
 * often not square, and the theme's own `img { height: auto }` rule overrides the
 * height attribute, which stretched round avatars into ovals.
 */
.widget-member-avatar {
    width: 56px;
    height: 56px;
    object-fit: cover;
}
/*
 * "Membres compatibles" widget card (widget/profile/compatible/_content.html.twig)
 * - user-requested: more breathing room in the card. Raises the card's
 *   padding by overriding the two variables Bootstrap reads for
 *   .card-header/.card-body/.card-footer, so both get more space from one
 *   change.
 *
 * (The "Voir le profil" button that used to squeeze the pseudo/distance text
 * next to it - and the flex-wrap/min-width fix built for it - is gone: the
 * avatar and pseudo are the links now, like every other sidebar widget.)
 */
.widget-compatible-members-card {
    --bs-card-spacer-y: 1.25rem;
    --bs-card-spacer-x: 1.25rem;
}
/*
 * "Mes disponibilités" summary (widget/social_network/availability/
 * _content.html.twig) - user-requested redesign: replaces the day-picker
 * (a fixed 7-circle row plus a below-the-fold pane per day) with a compact
 * row of badges, one per day that actually has a declared availability, and
 * a single centred empty state when none of the 7 days has anything.
 *
 * The violet is a flat, literal colour (not a Bootstrap CSS variable): the
 * request asked for this exact look regardless of whichever colour
 * experiment (theme-test*.css) happens to be active, so it must not
 * silently change if --bs-primary is retuned there.
 *
 * Each badge is a real <button> (clickable: user-requested - "on ne peut
 * plus cliquer dessus"), so the browser's own button chrome (border,
 * inherited-then-reset font) is cleared first.
 */
.availability-day-badge {
    background-color: rgba(126, 34, 206, 0.1);
    color: #581c87;
    font-weight: 600;
    font-size: .8125rem;
    font-family: inherit;
    padding: .4rem .7rem;
    border: 0;
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease;
}

.availability-day-badge:hover {
    background-color: rgba(126, 34, 206, 0.2);
}

/* Selected day: dark violet fill, white text (user-requested). */
.availability-day-badge--selected,
.availability-day-badge--selected:hover {
    background-color: #581c87;
    color: #fff;
}

/* Detail sentence of the selected day ("Disponible en soirée...") - discreet,
 * literal grey for the same reason as the badges' violet above. */
.availability-day-detail {
    color: #6b7280;
}

/* Centred, discreet empty state - same literal grey whatever the theme. */
.availability-empty-state {
    min-height: 4rem;
    color: #9ca3af;
}

/* Feed "a mis à jour ses disponibilités" card - the day tabs (Auj. 27,
 * Mer 30...) had never had any CSS of their own at all, so they rendered
 * as plain, unstyled Bootstrap .nav-tabs (user-reported: "ont perdu leur
 * CSS"). Same literal violet as .availability-day-badge above (the
 * "Mes disponibilités" sidebar widget), user-requested. These are real
 * Bootstrap tabs (data-bs-toggle="tab"), so the selected state is styled
 * off Bootstrap's own .active class - already toggled by tab.js on every
 * click - rather than introducing a second, unwired "selected" class that
 * could fall out of sync with which pane is actually showing. */
.availability-update__tabs {
    border-bottom: 0 !important;
    gap: .4rem;
    padding: .75rem .75rem 0;
}

/* FIX (user-reported): "le texte s'écrit en noir sur fond gris sombre" -
 * this tab strip sits on .bg-body-tertiary, which is a DARK grey in dark
 * mode; a semi-transparent background (rgba(126,34,206,0.1), the same
 * pattern as .availability-day-badge above) blends with whatever is
 * behind it, so on that dark strip it rendered as a barely-lighter dark
 * violet-grey instead of the intended light lavender - and the dark
 * violet text on top of THAT was the "black on dark grey" the user saw.
 * A solid (non-transparent) background renders identically regardless of
 * what is behind it, which is what the light-violet/dark-violet-text
 * combination actually needs to hold up in both themes. */
.availability-update__tab {
    background-color: #F3E8FF;
    border: 0 !important;
    border-radius: var(--bs-border-radius);
    transition: background-color .15s ease, color .15s ease;
}

/* The two inner <span>s carry Bootstrap's own .text-primary utility
 * (!important, whatever --bs-primary currently resolves to) - overridden
 * here to the same literal violet as the badge text, both states. */
.availability-update__tab span {
    color: #581c87 !important;
}

.availability-update__tab:hover {
    background-color: #E9D5FF;
}

/* User-requested: detach the slot pills ("Matin"...) from the date badges
 * above them - the removed "Disponibilité" title used to provide this gap
 * as a side effect of its own margin. */
.availability-update__slots {
    margin-top: 12px;
}

/* !important: Bootstrap's own .nav-tabs .nav-link.active (3 combined
 * classes) otherwise outweighs this 2-class selector and wins regardless
 * of source order, silently keeping its own (near-white) active-tab
 * background - which, combined with this file's white active-tab TEXT
 * right below, is exactly the "texte blanc invisible" the user reported. */
.availability-update__tab.active,
.availability-update__tab.active:hover {
    background-color: #581c87 !important;
}

.availability-update__tab.active span {
    color: #fff !important;
}

/*
 * Right side of the desktop navbar (icons + avatar) - user-requested:
 * "conteneur Flexbox avec align-items: center; gap: 16px" pour aligner les
 * icônes de notification et l'avatar, et des pastilles rouges qui restent
 * de petits cercles parfaits sans déborder sur l'icône voisine.
 *
 * The parent <ul class="navbar-nav ... align-items-center"> already has
 * align-items:center (Bootstrap's own class) and already spans the whole
 * nav (Accueil/Recherche/DM/Événements/"Plus" too, not just this trailing
 * cluster) - giving IT a `gap` would space out those unrelated items too.
 * header-icon-item instead gives each of these 6 specific <li> a
 * consistent left margin (replacing their previous, inconsistent `ms-2` =
 * 8px), which reads exactly as a `gap` for this cluster alone.
 *
 * FIX (user-reported): 16px still let the "visibilité" icon's red
 * notification dot touch/overlap the bell icon immediately to its left -
 * bumped to 20px.
 */
.header-icon-item {
    margin-left: 1.25rem;
}

/* FIX (user-reported): "les éléments se chevauchent sur deux lignes" -
 * Bootstrap's own .navbar (and .navbar > .container-fluid, which inherits
 * it) sets flex-wrap: wrap by default, so once the header's total content
 * width (logo + nav links + icon cluster) exceeds the row's width, it
 * wraps onto a second line instead of shrinking. The wider Kinkasa
 * wordmark+wreath logo pushed this over the edge.
 *
 * FIX (user-reported follow-up, mobile): originally scoped to lg+ only,
 * assuming mobile's own row (toggler + logo + the 4-icon toolbar) always
 * fit on one line. It doesn't, below ~310px - and wrapping there is
 * actively harmful, not just untidy: the vendor theme hard-codes
 * `header { height: 56px }` AND `header.fixed-top + main { padding-top:
 * calc(1.5rem + 56px) }` (assets/css/style-iFhbbwn.css) - i.e. it
 * assumes a single-line, fixed-height header everywhere else on the
 * page. A wrapped second line pushes the toolbar's real content past
 * that hard-coded 56px (measured: toolbar bottom ~73px against a
 * 56px-tall header box, header itself is `overflow: visible` so nothing
 * clips it) - the overflow paints on the page's own lighter background
 * *underneath* the header instead of on its violet one (hence the icons
 * suddenly looking faded/washed out - a real symptom, not a rendering
 * artifact), while `main`'s padding-top stays fixed at the old 56px, so
 * that same overflow also visually collides with the very top of the
 * page content. Removing the lg+ scope - nowrap unconditionally - keeps
 * the header exactly as tall as the rest of the page already assumes it
 * is, at every width; the row's own items simply sit tighter together
 * instead, which is a far smaller visual cost than an overflowing
 * header. */
.header-static .navbar,
.header-static .navbar > .container-fluid {
    flex-wrap: nowrap;
}

/* FIX (user-reported): "quand on clique sur le camembert le nom du site
 * est encore poussé sur la droite" - not actually about the click at
 * all (measured at several widths: 375/360/340/320px all rendered
 * fine, 300px reproduced it every time, with or without opening the
 * collapse). Root cause: Bootstrap's own .navbar sets `justify-content:
 * space-between` unconditionally (assets/css/style-iFhbbwn.css) - with
 * nowrap now unconditional too (above), wrapping should never happen at
 * all, but this stays as a second line of defence: if the row is ever
 * tight enough to wrap regardless (nowrap can still overflow rather
 * than wrap in some edge case), flex-start keeps [toggler, logo]
 * adjacent at the left rather than stretched to the row's two edges,
 * exactly like a 3-item row would already correctly do. */
@media (max-width: 991.98px) {
    .header-static .navbar > .container-fluid {
        justify-content: flex-start;
    }
}

.header-static .navbar {
    min-height: 64px;
}

/* The nav links (Accueil, Recherche...) and the icon cluster used to be
 * one single <ul>, entirely pushed to the right of the logo by ms-auto -
 * there was no "centered links, icons on the right" distinction at all.
 * Split into two <ul>s (header.html.twig) under one flex row so they
 * space apart instead of bunching together against the icons. */
.header-nav-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
}

/* flex-shrink:0 on both <ul>s: without it, the browser's default
 * flex-shrink:1 let the links <ul> get squeezed once flex-wrap:nowrap
 * (above) forced everything onto one line - the squeeze then showed up
 * as each nav-link's own label text wrapping onto a second line below its
 * icon, a different-looking but equally real instance of the same
 * "wraps instead of fitting" bug. white-space:nowrap on the link itself
 * is the other half of the same fix. */
.header-nav-row > .navbar-nav {
    flex-shrink: 0;
}

.header-nav-row .nav-link {
    white-space: nowrap;
}

/* User-reported: opening the mobile menu squeezed the logo and header
 * icons violently to the right - #navbarCollapse was expanding as a
 * regular flex item inside the header's own row instead of taking over
 * the screen. Turned into a real fixed full-screen panel below lg, which
 * fully covers the original header behind it (z-index:100) instead of
 * sharing space with it. Also applied to .collapsing (the transition
 * state) so the slide-open animation doesn't visibly jump-cut into place
 * only once .show lands.
 *
 * FIX (user-reported follow-up, same bug still visible on real devices):
 * Bootstrap's Collapse plugin animates height by setting `element.style.
 * height` directly as an INLINE style during `.collapsing` (a plain,
 * non-!important inline style, computed from the panel's natural content
 * height, e.g. "420px") - an inline style always wins over an external
 * rule regardless of the external selector's specificity, `#id` or not,
 * UNLESS that external rule is itself `!important` (the one case where
 * !important beats a plain inline style). Without it, the panel was
 * briefly - or, on some devices/timings, persistently - stuck at its
 * pre-animation pixel height instead of the full screen, which is
 * exactly the "squeezed" look reported: the header row above stayed
 * visible because the panel covering it was far shorter than 100%. */
@media (max-width: 991.98px) {
    #navbarCollapse.show,
    #navbarCollapse.collapsing {
        position: fixed !important;
        top: 0 !important;
        left: 0 !important;
        width: 100% !important;
        height: 100% !important;
        z-index: 100 !important;
        background: #6D28D9;
        overflow-y: auto;
        display: block !important;
    }
}

/* The panel's own top row (header.html.twig) - close button pinned
 * left, site name TRULY centered (not "pushed to the right" against
 * the opposite edge, user-reported: the closed header's burger+logo
 * sit close together, and the open panel's X+name jumping to opposite
 * corners read as inconsistent with that). A plain flex space-between
 * centers the title only when the two children have equal width, which
 * they never do here - position:absolute + left:50%/translateX(-50%)
 * centers the title in the row regardless of the close button's own
 * width, while the button stays a normal flow item pinned at the
 * start. */
.mobile-nav-panel-header {
    display: flex;
    align-items: center;
    padding: 16px;
    position: relative;
}

/* Plain white Lucide-style X (inline SVG in the template) - no grey
 * square/border behind it, just the stroked icon on the panel's own
 * violet background. */
.mobile-nav-panel-close {
    background: transparent;
    border: 0;
    padding: 0;
    color: #fff;
    line-height: 0;
}

.mobile-nav-panel-title {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    color: #fff;
    font-weight: 700;
    letter-spacing: 0.03em;
}

/* Detaches the (unchanged) links list from the new panel header row
 * above it - scoped to the mobile panel only, the desktop row (a normal
 * inline navbar) must keep its own vertical centering untouched. */
@media (max-width: 991.98px) {
    #navbarCollapse .header-nav-row {
        margin-top: 24px;
    }
}

/*
 * .badge-notif (assets/css/style.css) is a plain 8x8px dot with no text -
 * this project puts a real notification COUNT inside it, which can't stay
 * a "petit cercle parfait" at a fixed 8x8px (a 2-digit number would either
 * overflow it or distort it into an oval). Restyled as a small pill that
 * stays a true circle for one digit and grows just enough (padding) for
 * two, nudged closer to its icon (top/right -4px instead of the default
 * top:0/right:-3px sized for a plain dot) so it never spills onto the next
 * icon, 1rem (16px) away thanks to header-icon-item above.
 */
.header-static .badge-notif {
    top: -4px;
    right: -4px;
    left: auto;
    bottom: auto;
    width: auto;
    height: 16px;
    min-width: 16px;
    padding: 0 3px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 10px;
    line-height: 1;
    font-weight: 600;
    color: #fff;
    border-radius: 50rem;
}

/*
 * "Mode Discret" (user-requested toggle, header.html.twig button +
 * public/frontend/js/core/discreet-mode.js): blurs every image on the page
 * and swaps the primary colour for a neutral corporate blue, so a screen
 * glimpsed by someone else reads as an ordinary work app. State lives on
 * <html data-discreet-mode="on|off">, same mechanism as the site's own
 * light/dark theme toggle.
 *
 * Scope note: targets real <img> elements (avatars, post/gallery photos -
 * the literal ask), not the handful of widgets that show a picture via a
 * CSS background-image (e.g. the event card's cover strip) - a deliberately
 * light-touch utility, not an exhaustive rework of every component.
 */
html[data-discreet-mode="on"] img {
    filter: blur(15px);
}

/* Bootstrap redeclares its own colour on several components directly
 * (e.g. .btn-primary's own --bs-btn-* variables), not only on :root, so each
 * needs its own override here - same reasoning as every --bs-* override
 * elsewhere in this file. */
html[data-discreet-mode="on"] {
    --bs-primary: #2c3e66;
    --bs-primary-rgb: 44, 62, 102;
    --bs-primary-text-emphasis: #1b2740;
    --bs-primary-bg-subtle: #dbe1ec;
    --bs-primary-border-subtle: #aebbd4;
    --bs-link-color: #2c3e66;
    --bs-link-color-rgb: 44, 62, 102;
    --bs-link-hover-color: #1b2740;
    --bs-link-hover-color-rgb: 27, 39, 64;
}

html[data-discreet-mode="on"] .btn-primary {
    --bs-btn-color: #fff;
    --bs-btn-bg: #2c3e66;
    --bs-btn-border-color: #2c3e66;
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: #1b2740;
    --bs-btn-hover-border-color: #1b2740;
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: #1b2740;
    --bs-btn-active-border-color: #1b2740;
    --bs-btn-focus-shadow-rgb: 44, 62, 102;
}

html[data-discreet-mode="on"] .btn-outline-primary {
    --bs-btn-color: #2c3e66;
    --bs-btn-border-color: #2c3e66;
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: #2c3e66;
    --bs-btn-hover-border-color: #2c3e66;
    --bs-btn-active-bg: #1b2740;
    --bs-btn-active-border-color: #1b2740;
}

/* The header toggle button itself: filled once the mode is on, so its own
 * state is visible at a glance (JS toggles this class, discreet-mode.js). */
.header-static [data-discreet-mode-toggle].active {
    background-color: #2c3e66 !important;
    color: #fff;
}

/*
 * Event card (event/event/partial/_event_item.html.twig) - user-requested:
 * "uniformiser strictement le design des cartes pour qu'elles aient toutes
 * exactement les mêmes dimensions, indépendamment des variations de données
 * en BDD". None of .event-image-wrapper/.event-img/.event-date/.event-city/
 * .event-address had ANY CSS rule anywhere before this - pure hook classes
 * relying on browser/Bootstrap defaults, which is exactly why cards could
 * end up any height depending on title length or a missing image.
 *
 * The card's OVERALL height across a row is already handled correctly by
 * Bootstrap itself (.card.h-100 inside a .row, which stretches every column
 * to the tallest one) - what was missing is that the INSIDE of the card
 * never had a fixed rhythm, so even same-height cards could show their
 * date/city/club block starting at different Y positions. Fixed here:
 * the image zone (180px, object-fit: cover so a non-16:9 flyer is cropped,
 * never distorted) and the title zone (clamped to exactly 2 lines).
 */
.event-image-wrapper {
    position: relative;
    height: 180px;
    overflow: hidden;
}

.event-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Elegant placeholder (user-requested) instead of a generic stock photo
 * when the event has no flyer: a violet gradient with a themed icon,
 * consistent with the site's own established brand palette. */
.event-img-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, #581c87, #7e22ce);
    color: rgba(255, 255, 255, .85);
    font-size: 2.75rem;
}

/* Event detail page banner (user-requested "effet club privé sélect")
 * when the event has neither a cover nor a flyer image: a deep-violet-to-
 * magenta gradient with a faint diagonal hairline pattern and a centered,
 * low-opacity moon-and-stars icon, instead of the old blurred stock photo. */
.event-cover-placeholder {
    background:
        repeating-linear-gradient(
            45deg,
            rgba(255, 255, 255, .035) 0,
            rgba(255, 255, 255, .035) 1px,
            transparent 1px,
            transparent 26px
        ),
        linear-gradient(135deg, #12071f 0%, #3b0f5c 45%, #7e1d6b 75%, #a8306f 100%);
    background-size: cover;
    background-position: center;
    min-height: 320px;
}

.event-cover-placeholder-icon {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 5.5rem;
    color: rgba(255, 255, 255, .16);
    z-index: 0;
    pointer-events: none;
}

/* Clamped to 2 lines: a short title and a long one reserve the exact same
 * height, so everything below (date/city/club/badge) lines up across cards
 * regardless of title length. Both the standard and the older WebKit-prefixed
 * properties are set - every evergreen browser supports one of the two. */
.event-card-title {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    min-height: 2.9rem;
}

/* City/club rows: fixed 16x16 icons (user-requested), whatever the
 * surrounding text size would otherwise have scaled them to. */
.event-meta-icon {
    font-size: 16px;
    width: 16px;
    flex-shrink: 0;
    text-align: center;
}

/* "La communauté en direct" widget - each of the 4 stat blocks in the
 * flex row above (justify-content-around, user-requested) gets a minimum
 * width so short labels ("12 discussions cette semaine") don't collapse
 * narrower than long ones, keeping the row visually even; wide enough
 * that only 2 fit per line on narrow viewports, matching the old
 * row-cols-2 breakpoint intent it replaces. */
.community-stat {
    min-width: 7rem;
}

/* "À venir" sidebar widget (user-reported: "le bleu du calendrier et le
 * noir de l'épingle" ne correspondaient pas à la charte) - the date row
 * used to be a literal 📅 emoji (a fixed-colour multi-tone glyph, not
 * affected by `color` at all, hence "bleu" regardless of the surrounding
 * .text-secondary), now a Bootstrap Icon like the pin next to it so both
 * can share one violet (widget_next-events.js). Same 16px as
 * .event-meta-icon above (same "taille discrète" convention), same
 * literal violet as the availability badges' text (#581c87). */
.next-event-meta-icon {
    font-size: 16px;
    width: 16px;
    display: inline-block;
    text-align: center;
    color: #581c87;
}

/* Header wordmark (user-requested, final brand identity: "Lakinkeria") -
 * bold caps text plus a small rounded suffix badge, replacing the earlier
 * SVG-based logo. Gold reads clearly against this header's own background
 * in both modes (a violet gradient in light mode, theme-test-2.css; near-
 * black in dark mode, --bs-mode: #0f0f10) - a literal color, not a
 * theme-test.css variable, so it does not depend on that toggle file. */
/* Laurel-wreath emblem before the wordmark (user-requested) - sized to
 * roughly match .site-name-mark's own text height, so the icon and the
 * wordmark read as one lockup rather than the icon dwarfing or
 * disappearing next to the text. */
.site-wreath-icon {
    height: 28px;
    width: auto;
}

.site-name-mark {
    font-weight: 900;
    letter-spacing: 0.05em;
    font-size: 1.35rem;
    line-height: 1;
    color: #F5D76E;
}

/* FIX (user-reported mobile regression): below `lg`, the logo shares its
 * row with the toggler button and the 4-icon mobile toolbar - this wider
 * wordmark+wreath (replacing the old compact text-only logo) no longer
 * left enough room, so the row wrapped onto a second line. Shrinking here
 * (the suffix badge is hidden outright below lg, in the template) is
 * enough to fit without touching the toggler/toolbar icons themselves. */
@media (max-width: 991.98px) {
    .site-wreath-icon {
        height: 22px;
    }

    .site-name-mark {
        font-size: 1.05rem;
    }
}

/* FIX (user-reported, still not enough margin even after the reductions
 * above and the mobile toolbar's own icon shrink): at 320px specifically
 * (the narrowest common phone width, and the one actually tested against -
 * DevTools "Adaptatif 320 x 817"), logo + toggler + toolbar were still a
 * few pixels too wide combined, wrapping the toolbar onto its own line.
 * The wreath is decorative (it already reads as an abstract rosette, not
 * a literal wreath, at this size - see the header's own FIX comment) and
 * the least essential part of the lockup, so it is what gives way at the
 * very narrowest width rather than shrinking the toolbar icons further. */
@media (max-width: 359.98px) {
    .site-wreath-icon {
        display: none;
    }
}

.site-suffix-badge {
    background-color: #3B0764;
    color: #fff;
    font-size: 0.7rem;
    font-weight: 600;
    line-height: 1;
    padding: 0.3rem 0.55rem;
    border-radius: 999px;
    white-space: nowrap;
}

/* Chat sidebar trigger (user-requested: moved off the floating button,
 * bottom-right, into the "Mon espace" header - mobile row + the same
 * offcanvas's own header on desktop, _chat_trigger_button.html.twig).
 * Discreet but visible: filled violet pill, rounds fully via border-
 * radius, subtle hover lift - not the site's --bs-primary (which can be
 * retuned by the theme-test*.css colour experiment), a literal colour so
 * this reads the same regardless of that toggle. */
.chat-sidebar-trigger {
    background-color: #8B2BE2;
    color: #fff;
    font-size: 0.85rem;
    font-weight: 600;
    padding: 0.4rem 0.85rem;
    border: 0;
    border-radius: 999px;
    transition: background-color .15s ease, transform .15s ease;
}

.chat-sidebar-trigger:hover,
.chat-sidebar-trigger:focus {
    background-color: #7a1fc9;
    color: #fff;
    transform: translateY(-1px);
}

.chat-sidebar-trigger .chat_count {
    /* Overrides .badge's own dark text - .bg-danger already sets a
     * readable white, kept explicit here since it sits on the trigger's
     * own violet, not the header's. */
    color: #fff;
}

/* Icon-only mobile variant (user-requested: "Chat en ligne" was too
 * wide on the mobile "Mon espace" bar) - a perfect circle, same
 * footprint as the options button next to it. */
.chat-sidebar-trigger--icon-only {
    width: 45px;
    height: 45px;
    padding: 0;
    border-radius: 50%;
    font-size: 1.1rem;
}

/* Floating desktop variant (user-requested revert: the in-sidebar
 * placement sat awkwardly above the profile card) - fixed bottom-right,
 * above regular content but below modals/offcanvas (z-index: 50).
 * Overrides --icon-only's 45px with the requested 48px - declared after
 * it so the cascade picks this rule when both classes are present. */
.chat-sidebar-trigger--floating {
    position: fixed;
    bottom: 24px;
    right: 24px;
    width: 48px;
    height: 48px;
    z-index: 50;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
}

/* Defensive fix found while investigating a mobile layout report: a
 * BROKEN avatar image (a missing file, a failed upload) falls back to
 * rendering its alt text at natural size, ignoring width/height - which
 * then spills out of the circle instead of staying clipped to it. Scoped
 * to this one composer avatar rather than the shared .avatar class site-
 * wide: some other .avatar usages (chat online/away/offline status dot,
 * assets/css/style.css .status-online:before etc.) deliberately let a
 * small badge poke 2px outside their own box - a blanket overflow:hidden
 * on .avatar itself would clip that. */
.post-composer-avatar {
    overflow: hidden;
}

/* FIX (user-reported): at 320px, the mobile header row (logo + toggler +
 * this 4-item toolbar) still didn't quite fit on one line even after the
 * logo itself was already shrunk below lg - the toolbar wrapped onto its
 * own line under the logo/toggler. The avatar (.avatar-sm, a fixed 40px)
 * was the single widest item; a consistent, slightly smaller 32px box for
 * all four items frees just enough width. overflow:hidden keeps the
 * avatar image (object-fit: cover) cropped to the smaller circle. */
.header-mobile-toolbar-icon {
    width: 32px;
    height: 32px;
    overflow: hidden;
}

/* User-requested: "inverse l'ordre du logo et du menu burger [...] ajoute
 * un léger espace (gap: 12px) entre le bouton du menu burger et le texte
 * du logo" - the toggler now renders first in the DOM (header.html.twig),
 * immediately left of the logo; this replaces its old me-2 (8px, spaced
 * from the toolbar it used to sit next to) with the requested 12px,
 * scoped to this button alone rather than a container-wide gap (which
 * would also space the already-separate logo/icon-cluster pair via
 * ms-auto). Harmless at lg+ since the button itself is d-lg-none there. */
.header-mobile-toggler-gap {
    margin-right: 12px;
}
