:root {
    --brand-red: #E6000A;
    --brand-red-bright: #FA000A;
    --brand-red-dark: #A00000;
    --brand-black: #141414;
    --brand-gold: #B8860B;
    --app-bg: #17181a;

    /* Overwritten with the banner's real rendered height by the inline
       script in includes/footer.php (it wraps to more lines on narrow
       screens) — this value is just the pre-JS fallback. */
    --gambling-banner-height: 48px;

    /* Overwritten with .suggestion-fab's real rendered height by the inline
       script in includes/footer.php (its height varies slightly across
       breakpoints — see the @media rule near .suggestion-fab) — the navbar
       bell (.notif-bell-wrap) stacks directly above it using this var, same
       idiom as --gambling-banner-height. This is just the pre-JS fallback. */
    --suggestion-fab-height: 52px;

    /* Recolor Bootstrap's utility classes (.text-*, .bg-*, .border-*, links)
       that read these root tokens; component classes like .btn-primary keep
       their own local copies and are overridden separately below. */
    --bs-primary: var(--brand-red);
    --bs-primary-rgb: 230, 0, 10;
    --bs-dark: var(--brand-black);
    --bs-dark-rgb: 20, 20, 20;
    --bs-link-color: var(--brand-red-bright);
    --bs-link-color-rgb: 250, 0, 10;
    --bs-link-hover-color: #ff4d55;
    --bs-link-hover-color-rgb: 255, 77, 85;
}

body {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    background-color: var(--app-bg);
}

.navbar-brand {
    font-weight: 600;
}

.navbar.bg-dark {
    border-bottom: 3px solid var(--brand-red);
}

.nav-icon {
    font-size: 1.15em;
    opacity: 1;
    filter: saturate(1.4);
}

/* Challenge cards (render_challenge_card() in includes/challenges.php, used
   by challenges.php and challenges_collectifs.php). A thin colored strip
   across the top (.challenge-card-accent) carries the category color instead
   of a left border, paired with a circular icon chip (.challenge-icon-badge)
   for a less "form-like", more dashboard-like read. */
.challenge-card {
    border: 1px solid var(--bs-border-color);
    border-radius: 12px;
    overflow: hidden;
    transition: transform 0.15s ease, box-shadow 0.15s ease, opacity 0.15s ease;
}

.challenge-card-accent {
    height: 5px;
    width: 100%;
}

.challenge-icon-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 9px;
    font-size: 1rem;
    flex-shrink: 0;
}

.challenge-card-footer {
    border-top: 1px solid var(--bs-border-color);
}

.challenge-card-mine {
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.25);
}

.challenge-card-mine:hover {
    transform: translateY(-3px);
    box-shadow: 0 10px 24px rgba(0, 0, 0, 0.35);
}

/* Toned-down visual for other members' challenge cards on challenges.php
   (see $isOther in render_challenge_card()) — grey accent and reduced
   opacity so the viewer's own challenges read as the primary content;
   hovering restores full opacity to still make them easy to read. */
.challenge-card-other {
    opacity: 0.7;
}

.challenge-card-other:hover {
    opacity: 1;
}

/* members.php's member directory cards are links to my_stats.php?user=<id>
   — a pronounced hover-lift + red glow + avatar zoom so it reads as clearly
   clickable rather than a static profile tile, plus a "Voir les stats" hint
   that fades in (see .member-card-hint below). */
.member-card {
    cursor: pointer;
    border-width: 2px;
    transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease, background-color 0.2s ease;
}

.member-card:hover {
    transform: translateY(-8px) scale(1.03);
    box-shadow: 0 16px 32px rgba(0, 0, 0, 0.45), 0 0 0 2px var(--brand-red);
    border-color: var(--brand-red);
    background-color: rgba(230, 0, 10, 0.06);
}

.member-card-avatar {
    transition: transform 0.2s ease;
}

.member-card:hover .member-card-avatar {
    transform: scale(1.12);
}

.member-card-hint {
    color: var(--brand-red-bright);
    opacity: 0;
    transform: translateY(4px);
    transition: opacity 0.2s ease, transform 0.2s ease;
}

.member-card:hover .member-card-hint {
    opacity: 1;
    transform: translateY(0);
}

/* Every progress bar on the site (challenges.php/challenges_collectifs.php
   cards, members.php's goal bar, stats.php/my_stats.php's goal bars) fills in
   gently from 0 instead of snapping straight to its final width — "to" is
   intentionally omitted so the browser uses the bar's own current width (set
   server-side for static bars, or via bar.style.width right before
   re-applying this class for JS-driven ones — see stats.php/my_stats.php's
   renderRange()) as the implicit end state. */
@keyframes progress-fill {
    from {
        width: 0%;
    }
}

.progress-bar-animated {
    /* Keep this duration in sync with the JS constant in
       render_challenge_progress_animation_script() (includes/challenges.php)
       so challenge cards' % counter and bar finish at the same time. */
    animation: progress-fill 2.4s ease-out;
}

/* "Like" button on stats.php's "Dernières sessions saisies" table
   (session_like.php toggles it). Muted grey by default, blue on hover, solid
   blue once the viewer has liked that row. */
.session-like-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 2px 6px;
    color: var(--bs-secondary-color);
    border: none;
    background: none;
    line-height: 1;
}

.session-like-btn:hover {
    color: #3987e5;
}

.session-like-btn-active {
    color: #3987e5;
}

/* Overlapping "liked by" avatar stack next to the like button (stats.php).
   Each avatar_html() <img>/initial span gets a slight ring so it reads as a
   separate stacked chip rather than a solid blob. */
.session-like-avatars > span:not(:first-child) {
    margin-left: -8px;
}

.session-like-avatars span > img,
.session-like-avatars span.rounded-circle {
    box-shadow: 0 0 0 2px var(--bs-body-bg);
}

/* Floating notification bell (includes/header.php, api/notifications.php) —
   app-wide activity feed (new sessions, challenges, suggestions). Stacked
   directly above the suggestion FAB (.suggestion-fab), same fixed
   bottom-right corner, using --suggestion-fab-height (synced in
   includes/footer.php) to clear its real rendered height + a gap. "dropup"
   on the wrapper (not just the menu's own class) makes Bootstrap open the
   dropdown upward, since opening downward from this low on the screen would
   run off the viewport. */
.notif-bell-wrap {
    position: fixed;
    right: 20px;
    bottom: calc(var(--gambling-banner-height) + var(--suggestion-fab-height) + 32px);
    z-index: 1049;
}

.notif-bell-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 999px;
    background: var(--brand-black);
    color: #fff;
    font-size: 1.2rem;
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
    transition: background-color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}

.notif-bell-btn:hover {
    background: #232323;
    border-color: rgba(255, 255, 255, 0.28);
    transform: translateY(-2px);
}

.notif-bell-badge {
    position: absolute;
    top: -2px;
    right: -2px;
    min-width: 18px;
    height: 18px;
    padding: 0 4px;
    border-radius: 999px;
    border: 2px solid var(--brand-black);
    background: var(--brand-red-bright);
    color: #fff;
    font-size: 0.65rem;
    font-weight: 700;
    line-height: 14px;
    text-align: center;
}

.notif-dropdown {
    width: 340px;
    max-width: 90vw;
    padding: 0;
    overflow: hidden;
}

.notif-dropdown-header {
    padding: 10px 14px;
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--bs-secondary-color);
    border-bottom: 1px solid var(--bs-border-color);
}

.notif-list {
    max-height: 380px;
    overflow-y: auto;
}

.notif-item {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 10px 14px;
    color: var(--bs-body-color);
    text-decoration: none;
    border-bottom: 1px solid var(--bs-border-color);
    transition: background-color 0.15s ease;
}

.notif-item:last-child {
    border-bottom: none;
}

a.notif-item:hover {
    background-color: rgba(255, 255, 255, 0.06);
    color: var(--bs-body-color);
}

/* Unread notification (item.is_unread, api/notifications.php) — red tint +
   bold message + a small dot, so it's obvious at a glance which ones haven't
   been clicked yet. Clearing it is instant client-side (clearUnreadStyling()
   in includes/header.php) the moment any notification is clicked, ahead of
   the mark_seen beacon actually landing. */
.notif-item-unread {
    background-color: rgba(230, 0, 10, 0.07);
}

a.notif-item-unread:hover {
    background-color: rgba(230, 0, 10, 0.12);
}

.notif-item-unread .notif-item-message {
    font-weight: 700;
}

.notif-item-dot {
    flex-shrink: 0;
    align-self: center;
    width: 8px;
    height: 8px;
    border-radius: 999px;
    background-color: var(--brand-red-bright);
    box-shadow: 0 0 0 3px rgba(250, 0, 10, 0.22);
}

.notif-item-avatar {
    position: relative;
    flex-shrink: 0;
    width: 30px;
    height: 30px;
}

.notif-item-avatar img,
.notif-item-avatar-initial,
.notif-item-avatar-generic {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    object-fit: cover;
    color: #fff;
    font-weight: 700;
    font-size: 0.85rem;
}

.notif-item-avatar-initial {
    background-color: var(--brand-red);
}

.notif-item-avatar-generic {
    background-color: rgba(255, 255, 255, 0.1);
    font-size: 1rem;
}

.notif-item-type-badge {
    position: absolute;
    bottom: -3px;
    right: -3px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    border-radius: 999px;
    border: 2px solid var(--brand-black);
    background: var(--bs-body-bg);
    font-size: 0.6rem;
    line-height: 1;
}

.notif-item-message {
    font-size: 0.85rem;
    line-height: 1.35;
}

.notif-item-time {
    font-size: 0.72rem;
    color: var(--bs-secondary-color);
    margin-top: 2px;
}

.navbar-account {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 14px 4px 4px;
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.06);
    color: #fff;
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease;
}

.navbar-account:hover {
    background: rgba(255, 255, 255, 0.14);
    border-color: rgba(255, 255, 255, 0.28);
}

.navbar-account-avatar {
    position: relative;
    display: inline-flex;
}

.navbar-account-badge {
    position: absolute;
    bottom: -3px;
    right: -3px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: 999px;
    border: 2px solid var(--brand-black);
    background: var(--brand-red-bright);
    color: #fff;
    font-size: 0.65rem;
    font-weight: 700;
    line-height: 12px;
    text-align: center;
}

.navbar-account-name {
    font-weight: 600;
    font-size: 0.9rem;
    white-space: nowrap;
}

/* XP/level badge (includes/gamification.php) — navbar (next to the username)
   and members.php (on each member card). Gold to read as an achievement/
   reward, distinct from the brand-red used everywhere else for primary
   actions. */
.level-badge {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    padding: 2px 8px;
    border-radius: 999px;
    background: rgba(184, 134, 11, 0.18);
    border: 1px solid rgba(184, 134, 11, 0.4);
    color: var(--brand-gold);
    font-size: 0.72rem;
    font-weight: 700;
    white-space: nowrap;
}

@media (max-width: 576px) {
    .navbar-account-name {
        display: none;
    }

    .navbar-account .level-badge {
        display: none;
    }

    .navbar-account {
        padding: 4px;
    }
}

/* my_stats.php's profile header — avatar + page title merged with the level/
   XP block into a single card, top accent bar in the same gold family as
   .level-badge to read as one cohesive "profile" unit rather than two
   separate cards stacked on top of each other. */
.profile-header-card {
    overflow: hidden;
}

.profile-header-accent {
    height: 4px;
    width: 100%;
    background: linear-gradient(90deg, var(--brand-gold), var(--brand-red-bright));
}

.profile-xp-block {
    flex: 1 1 260px;
    max-width: 320px;
}

/* "How do I earn XP?" info button (my_stats.php, next to the level badge) —
   opens #xpRulesModal. */
.xp-info-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    padding: 0;
    border: none;
    background: none;
    color: var(--bs-secondary-color);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
}

.xp-info-btn:hover {
    color: var(--brand-gold);
}

/* home.php's feature grid — a lightweight bordered tile (icon + text on one
   row) instead of a full shadowed .card per feature, so 8 of them read as a
   dense, scannable list rather than 8 tall stacked-and-centered cards. */
.home-feature-tile {
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(255, 255, 255, 0.07);
    transition: background-color 0.15s ease, border-color 0.15s ease;
}

.home-feature-tile:hover {
    background: rgba(255, 255, 255, 0.06);
    border-color: rgba(255, 255, 255, 0.14);
}

.card {
    border: none;
}

.btn-primary {
    --bs-btn-bg: var(--brand-red);
    --bs-btn-border-color: var(--brand-red);
    --bs-btn-hover-bg: var(--brand-red-dark);
    --bs-btn-hover-border-color: var(--brand-red-dark);
    --bs-btn-active-bg: var(--brand-red-dark);
    --bs-btn-active-border-color: var(--brand-red-dark);
    --bs-btn-disabled-bg: var(--brand-red);
    --bs-btn-disabled-border-color: var(--brand-red);
    --bs-btn-focus-shadow-rgb: 230, 0, 10;
}

.form-control:focus,
.form-select:focus {
    border-color: var(--brand-red);
    box-shadow: 0 0 0 0.25rem rgba(230, 0, 10, 0.25);
}

.table-scroll {
    max-height: 480px;
    overflow-y: auto;
}

.table-scroll.table-scroll-sm {
    max-height: 260px;
}

.table-scroll.table-scroll-md {
    max-height: 420px;
}

/* stats.php's three-up row ("Stats par semaine" / "Stats par mois" /
   #recentSessions) is crammed into narrower columns than it used to be —
   shrink table type and badges a notch across all three so rows stay
   compact instead of wrapping. */
#weekStatsTable,
#monthStatsTable,
#recentSessions table {
    font-size: 0.82rem;
}

#recentSessions .badge {
    font-size: 0.72rem;
    padding: 0.25em 0.5em;
}

.table-scroll thead th {
    position: sticky;
    top: 0;
    background: var(--bs-body-bg);
    z-index: 1;
}

/* Keeps the last bit of page content (e.g. session.php's table) clear of the
   fixed suggestion FAB and notification bell stacked above it, which
   otherwise float on top of whatever is scrolled to the bottom of the
   viewport. Sized to comfortably clear both (see .suggestion-fab,
   .notif-bell-wrap). */
.app-content {
    padding-bottom: calc(var(--gambling-banner-height) + var(--suggestion-fab-height) + 100px);
}

/* Suggestion board (admin_suggestions.php / render_suggestion_thread_card()
   in includes/suggestions.php) — same accent-bar + icon-badge dashboard
   idiom as challenge cards (.challenge-card above), plus status-colored
   stat tiles standing in for plain filter pills/buttons. */
.suggestion-stat-tile {
    display: flex;
    align-items: center;
    gap: 10px;
    height: 100%;
    padding: 10px 12px;
    border-radius: 12px;
    border: 1px solid var(--bs-border-color);
    background: var(--bs-body-bg);
    transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}

.suggestion-stat-tile:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.25);
}

.suggestion-stat-tile-active {
    border-color: var(--tile-color, var(--brand-red));
    box-shadow: 0 0 0 1px var(--tile-color, var(--brand-red));
}

.suggestion-stat-tile-count {
    display: block;
    font-size: 1.1rem;
    font-weight: 700;
    line-height: 1.2;
    color: var(--bs-body-color);
}

.suggestion-stat-tile-label {
    display: block;
    font-size: 0.72rem;
    color: var(--bs-secondary-color);
}

.suggestion-icon-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 9px;
    font-size: 1.05rem;
    flex-shrink: 0;
}

/* The "rejete" status uses Bootstrap's "dark" keyword, which --bs-dark
   (overridden above to --brand-black) renders as near-black-on-near-black
   subtle/text pairing on this already-dark theme — override just that
   combo so the icon stays legible instead of vanishing into the badge. */
.suggestion-icon-badge.bg-dark-subtle {
    background-color: rgba(255, 255, 255, 0.12);
}

.suggestion-icon-badge.text-dark {
    color: var(--bs-body-color);
}

.suggestion-card {
    border: 1px solid var(--bs-border-color);
    border-radius: 12px;
    overflow: hidden;
}

.suggestion-card-accent {
    height: 5px;
    width: 100%;
}

.suggestion-thread {
    max-height: 420px;
    overflow-y: auto;
    padding-right: 4px;
}

.suggestion-fab {
    position: fixed;
    bottom: calc(var(--gambling-banner-height) + 20px);
    right: 20px;
    z-index: 1050;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 20px;
    border-radius: 999px;
    border: none;
    background-color: var(--brand-red);
    color: #fff;
    font-weight: 500;
    white-space: nowrap;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
}

.suggestion-fab:hover {
    background-color: var(--brand-red-dark);
}

.live-badge {
    font-weight: 700;
    letter-spacing: 0.03em;
}

.live-icon {
    animation: live-pulse 1.4s ease-in-out infinite;
}

@keyframes live-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.25; }
}

.blink-icon {
    display: inline-block;
    animation: live-pulse 1.2s ease-in-out infinite;
}

.live-mini-player {
    position: fixed;
    bottom: 20px;
    left: 20px;
    width: 320px;
    min-width: 240px;
    max-width: min(90vw, 800px);
    z-index: 1045;
    background: var(--brand-black);
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
}

/* Custom top-right resize grip (JS-driven, see includes/header.php) — native
   CSS `resize` can only put its handle bottom-right, not where we want it on
   a box anchored bottom-left on screen. */
.live-mini-player-resize-handle {
    position: absolute;
    top: 0;
    right: 0;
    width: 20px;
    height: 20px;
    z-index: 2;
    cursor: ne-resize;
}

.live-mini-player-resize-handle::before {
    content: '';
    position: absolute;
    top: 5px;
    right: 5px;
    width: 8px;
    height: 8px;
    border-top: 2px solid rgba(255, 255, 255, 0.8);
    border-right: 2px solid rgba(255, 255, 255, 0.8);
}

.live-mini-player-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 4px 8px;
    background: var(--brand-red);
    color: #fff;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.03em;
}

.live-mini-player-video {
    width: 100%;
    aspect-ratio: 16 / 9;
}

.live-mini-player-video iframe {
    width: 100%;
    height: 100%;
    border: 0;
    display: block;
}

.btn-close-mini {
    /* Sits under the resize handle's hit zone (top-right corner) — bump it
       above so clicks land on the button, not the handle, and give it more
       room/margin so it's easier to hit precisely. */
    position: relative;
    z-index: 3;
    background: none;
    border: none;
    color: #fff;
    font-size: 1.1rem;
    line-height: 1;
    padding: 2px 6px;
    margin-right: 6px;
    cursor: pointer;
}

.live-mini-player a {
    color: #c9cbce;
}

/* Moved into the page's <h1> by JS (see includes/header.php) so it reads as
   part of the page title rather than floating on its own — same visual
   design (btn btn-danger btn-sm live-badge) as the old navbar "EN DIRECT"
   badge it replaces, just repositioned. */
.live-mini-player-reopen {
    display: none;
    vertical-align: middle;
    margin-left: 12px;
}

@media (max-width: 480px) {
    .live-mini-player {
        width: calc(100vw - 24px);
        left: 12px;
        bottom: 12px;
    }
}

@media (max-width: 480px) {
    .suggestion-fab {
        padding: 14px;
        border-radius: 50%;
    }

    .suggestion-fab-label {
        display: none;
    }
}

.gambling-warning-banner {
    /* Body is a flex column (see body rule above) so this margin pushes the
       banner to the bottom of the viewport on short pages, while still
       scrolling with the page (not fixed) once content is taller than the
       viewport. */
    margin-top: auto;
    background-color: #ffd400;
    color: #000;
    text-align: center;
    padding: 10px 16px;
    font-size: 0.85rem;
    line-height: 1.4;
}

.gambling-warning-banner strong {
    font-weight: 700;
}
