/* ==========================================================================
   Hockey Drop-In — v2 Design System
   --------------------------------------------------------------------------
   Loaded LAST, after bootstrap.min.css and theme.css. This is an additive
   layer: it re-skins Bootstrap's primitives and modernises the app's own
   components so all 102 views improve without touching a single view file.

   Mobile-first. Every size from 320px to 2560px is a first-class target.
   ========================================================================== */

/* ==========================================================================
   1. TOKENS
   ========================================================================== */
:root {
    /* --- Type scale: fluid, no breakpoint jumps --- */
    --v2-font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
               'Helvetica Neue', Arial, sans-serif;
    --v2-mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;

    --v2-text-2xs: clamp(0.6875rem, 0.66rem + 0.13vw, 0.75rem);
    --v2-text-xs:  clamp(0.75rem, 0.72rem + 0.14vw, 0.8125rem);
    --v2-text-sm:  clamp(0.8125rem, 0.79rem + 0.14vw, 0.875rem);
    --v2-text-base:clamp(0.9375rem, 0.91rem + 0.15vw, 1rem);
    --v2-text-md:  clamp(1rem, 0.96rem + 0.2vw, 1.125rem);
    --v2-text-lg:  clamp(1.125rem, 1.05rem + 0.35vw, 1.375rem);
    --v2-text-xl:  clamp(1.375rem, 1.24rem + 0.62vw, 1.75rem);
    --v2-text-2xl: clamp(1.625rem, 1.4rem + 1.05vw, 2.375rem);
    --v2-text-3xl: clamp(2rem, 1.55rem + 2.1vw, 3.5rem);

    /* --- Spacing: 4px base, fluid at the top end --- */
    --v2-space-1: 0.25rem;
    --v2-space-2: 0.5rem;
    --v2-space-3: 0.75rem;
    --v2-space-4: 1rem;
    --v2-space-5: 1.5rem;
    --v2-space-6: 2rem;
    --v2-space-7: 3rem;
    --v2-space-8: 4rem;
    --v2-gutter: clamp(1rem, 0.6rem + 1.8vw, 2rem);
    --v2-section: clamp(2.5rem, 1.6rem + 4vw, 5rem);

    /* --- Radius --- */
    --v2-r-sm: 8px;
    --v2-r: 12px;
    --v2-r-lg: 16px;
    --v2-r-xl: 22px;
    --v2-r-full: 999px;

    /* --- Elevation: soft, layered, never muddy --- */
    --v2-e1: 0 1px 2px rgba(15, 23, 42, .05),
            0 1px 3px rgba(15, 23, 42, .06);
    --v2-e2: 0 2px 4px rgba(15, 23, 42, .04),
            0 6px 12px -2px rgba(15, 23, 42, .08);
    --v2-e3: 0 4px 8px rgba(15, 23, 42, .05),
            0 16px 32px -8px rgba(15, 23, 42, .14);
    --v2-ring: 0 0 0 3px rgba(0, 119, 182, .28);

    /* --- Brand --- */
    --v2-blue-50:  #eff8ff;
    --v2-blue-100: #dbeefe;
    --v2-blue-200: #bfe2fe;
    --v2-blue-300: #93d1fd;
    --v2-blue-400: #60b8fa;
    --v2-blue-500: #3b9ef4;
    --v2-blue-600: #0077b6;   /* primary — hockey blue */
    --v2-blue-700: #0369a1;
    --v2-blue-800: #075985;
    --v2-blue-900: #0c4a6e;

    --v2-pri: var(--v2-blue-600);
    --v2-pri-hover: var(--v2-blue-700);
    --v2-pri-soft: var(--v2-blue-50);
    --v2-pri-ring: rgba(0, 119, 182, .3);

    /* --- Surfaces (light) --- */
    --v2-bg: #f6f8fb;
    --v2-surface: #ffffff;
    --v2-surface-2: #f8fafc;
    --v2-line: #e3e9f0;
    --v2-line-soft: #eef2f7;
    --v2-ink: #0f172a;
    --v2-ink-2: #475569;
    --v2-ink-3: #7c8ba1;

    /* --- Feedback --- */
    --v2-ok: #059669;
    --v2-ok-bg: #ecfdf5;
    --v2-warn: #b45309;
    --v2-warn-bg: #fffbeb;
    --v2-bad: #dc2626;
    --v2-bad-bg: #fef2f2;
    --v2-info: #0369a1;
    --v2-info-bg: #f0f9ff;

    /* --- Motion --- */
    --v2-fast: 120ms cubic-bezier(.4, 0, .2, 1);
    --v2-med: 200ms cubic-bezier(.4, 0, .2, 1);
    --v2-slow: 320ms cubic-bezier(.16, 1, .3, 1);

    /* --- Shell metrics --- */
    --v2-topbar-h: 60px;
    --v2-rail: 264px;
    --v2-rail-collapsed: 68px;
    --v2-tabs-h: 60px;

    /* Bridge to legacy theme.css so the two layers agree */
    --hdi-primary: var(--v2-pri);
    --hdi-radius: var(--v2-r);
    --hdi-border: var(--v2-line);
    --hdi-text: var(--v2-ink);
    --hdi-transition: var(--v2-fast);
    --hdi-topbar-h: var(--v2-topbar-h);
    --hdi-bottom-tabs-h: var(--v2-tabs-h);
    --hdi-sidebar-w: var(--v2-rail);
}

/* --- Dark mode --- */
[data-theme="dark"] {
    --v2-bg: #0a0f1a;
    --v2-surface: #111827;
    --v2-surface-2: #161f31;
    --v2-line: #263449;
    --v2-line-soft: #1d2839;

    --v2-ink: #e8eef7;
    --v2-ink-2: #9fb0c7;
    --v2-ink-3: #6b7f9b;

    --v2-pri: #38bdf8;
    --v2-pri-hover: #7dd3fc;
    --v2-pri-soft: rgba(56, 189, 248, .12);
    --v2-pri-ring: rgba(56, 189, 248, .3);

    --v2-ok: #34d399;  --v2-ok-bg: rgba(52, 211, 153, .12);
    --v2-warn: #fbbf24; --v2-warn-bg: rgba(251, 191, 36, .12);
    --v2-bad: #f87171;  --v2-bad-bg: rgba(248, 113, 113, .12);
    --v2-info: #7dd3fc; --v2-info-bg: rgba(125, 211, 252, .12);

    --v2-e1: 0 1px 2px rgba(0, 0, 0, .4);
    --v2-e2: 0 4px 12px -2px rgba(0, 0, 0, .5);
    --v2-e3: 0 12px 32px -8px rgba(0, 0, 0, .65);
    --v2-ring: 0 0 0 3px rgba(56, 189, 248, .3);

    --hdi-primary: var(--v2-pri);
    --hdi-text: var(--v2-ink);
    --hdi-text-secondary: var(--v2-ink-2);
    --hdi-text-muted: var(--v2-ink-3);
    --hdi-border: var(--v2-line);
    --hdi-border-light: var(--v2-line-soft);
    --hdi-surface: var(--v2-surface);
    --hdi-surface-hover: var(--v2-surface-2);
    --hdi-bg: var(--v2-bg);
}

/* ==========================================================================
   2. BASE
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
    scroll-padding-top: calc(var(--v2-topbar-h) + var(--v2-space-4));
}
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
    }
}

body {
    font-family: var(--v2-font);
    font-size: var(--v2-text-base);
    line-height: 1.6;
    color: var(--v2-ink);
    background: var(--v2-bg);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
    /* `clip` not `hidden`: `hidden` turns the body into a scroll container,
       which makes every position:fixed descendant (the mobile tab bar, the
       drawer, the scrim) anchor to the document instead of the viewport.
       Verified: with `hidden` the tab bar sat at y=1939 instead of y=783. */
    overflow-x: clip;
}

h1, h2, h3, h4, h5, h6 {
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.2;
    color: var(--v2-ink);
    margin: 0 0 var(--v2-space-3);
}
h1 { font-size: var(--v2-text-2xl); }
h2 { font-size: var(--v2-text-xl); }
h3 { font-size: var(--v2-text-lg); }
h4 { font-size: var(--v2-text-md); }
h5, h6 { font-size: var(--v2-text-base); }

p { margin: 0 0 var(--v2-space-4); }
p:last-child { margin-bottom: 0; }

a {
    color: var(--v2-pri);
    text-decoration: none;
    transition: color var(--v2-fast);
}
a:hover { color: var(--v2-pri-hover); }

hr { border-color: var(--v2-line); opacity: 1; }

/* Focus: visible, consistent, keyboard-only */
:focus-visible {
    outline: 2px solid var(--v2-pri);
    outline-offset: 2px;
    border-radius: 4px;
}
:focus:not(:focus-visible) { outline: none; }

/* Icons must never collapse or inherit text colour by accident */
.fas, .far, .fab, .bi, [class^="fa-"], [class*=" fa-"] {
    line-height: 1;
    display: inline-block;
    flex-shrink: 0;
}

/* ==========================================================================
   3. LAYOUT PRIMITIVES
   ========================================================================== */
.container, .container-fluid {
    padding-left: var(--v2-gutter);
    padding-right: var(--v2-gutter);
}
/* Ultra-wide: cap the measure so lines never get uncomfortably long */
@media (min-width: 1800px) {
    .container { max-width: 1600px; }
}

.public-main, .app-main {
    padding: var(--v2-space-5) 0 var(--v2-space-7);
}
.app-main { padding: var(--v2-space-5) 0 var(--v2-space-7); }

/* Section rhythm */
.section-title {
    font-size: var(--v2-text-lg);
    font-weight: 700;
    letter-spacing: -0.02em;
    display: flex;
    align-items: center;
    gap: var(--v2-space-3);
    margin: var(--v2-space-6) 0 var(--v2-space-4);
    color: var(--v2-ink);
}
.section-title .count {
    font-size: var(--v2-text-xs);
    font-weight: 600;
    background: var(--v2-pri-soft);
    color: var(--v2-pri);
    border-radius: var(--v2-r-full);
    padding: 2px 10px;
}

/* ==========================================================================
   4. BOOTSTRAP SKIN — buttons
   ========================================================================== */
.btn {
    --bs-btn-font-size: var(--v2-text-sm);
    --bs-btn-font-weight: 600;
    --bs-btn-padding-x: 1rem;
    --bs-btn-padding-y: 0.5rem;
    --bs-btn-border-radius: var(--v2-r-sm);
    --bs-btn-border-width: 1px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    letter-spacing: -0.01em;
    transition: background-color var(--v2-fast),
                border-color var(--v2-fast),
                color var(--v2-fast),
                box-shadow var(--v2-fast),
                transform var(--v2-fast);
    white-space: nowrap;
    text-decoration: none;
}
.btn:active { transform: translateY(1px); }
.btn:focus-visible { box-shadow: var(--v2-ring); outline: none; }

.btn-sm {
    --bs-btn-padding-x: 0.75rem;
    --bs-btn-padding-y: 0.3125rem;
    --bs-btn-font-size: var(--v2-text-xs);
    --bs-btn-border-radius: var(--v2-r-sm);
}
.btn-lg {
    --bs-btn-padding-x: 1.5rem;
    --bs-btn-padding-y: 0.75rem;
    --bs-btn-font-size: var(--v2-text-md);
    --bs-btn-border-radius: var(--v2-r);
}

.btn-primary {
    --bs-btn-bg: var(--v2-pri);
    --bs-btn-border-color: var(--v2-pri);
    --bs-btn-color: #fff;
    --bs-btn-hover-bg: var(--v2-pri-hover);
    --bs-btn-hover-border-color: var(--v2-pri-hover);
    --bs-btn-hover-color: #fff;
    --bs-btn-active-bg: var(--v2-pri-hover);
    --bs-btn-active-border-color: var(--v2-pri-hover);
    --bs-btn-active-color: #fff;
    --bs-btn-disabled-bg: var(--v2-blue-300);
    --bs-btn-disabled-border-color: var(--v2-blue-300);
    --bs-btn-disabled-color: #fff;
    box-shadow: var(--v2-e1);
}
.btn-primary:hover { box-shadow: var(--v2-e2); }

.btn-outline-primary {
    --bs-btn-color: var(--v2-pri);
    --bs-btn-border-color: var(--v2-pri);
    --bs-btn-bg: transparent;
    --bs-btn-hover-bg: var(--v2-pri);
    --bs-btn-hover-border-color: var(--v2-pri);
    --bs-btn-hover-color: #fff;
    --bs-btn-active-bg: var(--v2-pri);
    --bs-btn-active-border-color: var(--v2-pri);
    --bs-btn-active-color: #fff;
}

.btn-outline-secondary {
    --bs-btn-color: var(--v2-ink-2);
    --bs-btn-border-color: var(--v2-line);
    --bs-btn-bg: var(--v2-surface);
    --bs-btn-hover-bg: var(--v2-surface-2);
    --bs-btn-hover-border-color: var(--v2-ink-3);
    --bs-btn-hover-color: var(--v2-ink);
    --bs-btn-active-bg: var(--v2-surface-2);
    --bs-btn-active-border-color: var(--v2-ink-3);
    --bs-btn-active-color: var(--v2-ink);
}

.btn-outline-danger {
    --bs-btn-color: var(--v2-bad);
    --bs-btn-border-color: var(--v2-bad);
    --bs-btn-border-color: color-mix(in srgb, var(--v2-bad) 35%, transparent);
    --bs-btn-bg: transparent;
    --bs-btn-hover-bg: var(--v2-bad);
    --bs-btn-hover-border-color: var(--v2-bad);
    --bs-btn-hover-color: #fff;
    --bs-btn-active-bg: var(--v2-bad);
    --bs-btn-active-border-color: var(--v2-bad);
    --bs-btn-active-color: #fff;
}

.btn-success {
    --bs-btn-bg: var(--v2-ok);
    --bs-btn-border-color: var(--v2-ok);
    --bs-btn-color: #fff;
    --bs-btn-hover-bg: var(--v2-ok);
    --bs-btn-hover-bg: color-mix(in srgb, var(--v2-ok) 85%, #000);
    --bs-btn-hover-border-color: var(--v2-ok);
    --bs-btn-hover-border-color: color-mix(in srgb, var(--v2-ok) 85%, #000);
    --bs-btn-hover-color: #fff;
}

.btn-link {
    --bs-btn-color: var(--v2-pri);
    --bs-btn-hover-color: var(--v2-pri-hover);
    text-decoration: none;
    font-weight: 600;
}

/* Touch targets: 44px minimum on coarse pointers */
@media (pointer: coarse) {
    .btn { min-height: 44px; }
    .btn-sm { min-height: 38px; }
}

/* ==========================================================================
   5. BOOTSTRAP SKIN — cards
   ========================================================================== */
.card {
    --bs-card-bg: var(--v2-surface);
    --bs-card-border-color: var(--v2-line);
    --bs-card-border-radius: var(--v2-r-lg);
    --bs-card-box-shadow: var(--v2-e1);
    border: 1px solid var(--v2-line);
    border-radius: var(--v2-r-lg);
    box-shadow: var(--v2-e1);
    transition: box-shadow var(--v2-med), border-color var(--v2-med),
                transform var(--v2-med);
}
.card:hover { box-shadow: var(--v2-e2); }

.card-header {
    background: transparent;
    border-bottom: 1px solid var(--v2-line-soft);
    padding: var(--v2-space-4);
    font-weight: 600;
    display: flex;
    align-items: center;
    gap: var(--v2-space-3);
    flex-wrap: wrap;
}
.card-body { padding: var(--v2-space-4); }
.card-footer {
    background: var(--v2-surface-2);
    border-top: 1px solid var(--v2-line-soft);
    padding: var(--v2-space-3) var(--v2-space-4);
}

/* Clickable cards */
a.card, .card-link { text-decoration: none; color: inherit; }
a.card:hover, .card-link:hover {
    transform: translateY(-2px);
    box-shadow: var(--v2-e3);
    border-color: var(--v2-pri-ring);
    color: inherit;
}

/* ==========================================================================
   6. BOOTSTRAP SKIN — forms
   ========================================================================== */
.form-label {
    font-size: var(--v2-text-sm);
    font-weight: 600;
    color: var(--v2-ink-2);
    margin-bottom: var(--v2-space-2);
}

.form-control, .form-select {
    font-size: var(--v2-text-base);
    padding: 0.625rem 0.875rem;
    border: 1px solid var(--v2-line);
    border-radius: var(--v2-r-sm);
    background: var(--v2-surface);
    color: var(--v2-ink);
    transition: border-color var(--v2-fast), box-shadow var(--v2-fast),
                background-color var(--v2-fast);
    min-height: 44px;
}
.form-control:focus, .form-select:focus {
    border-color: var(--v2-pri);
    box-shadow: var(--v2-ring);
    background: var(--v2-surface);
    color: var(--v2-ink);
}
.form-control::placeholder { color: var(--v2-ink-3); }
.form-control:disabled, .form-select:disabled {
    background: var(--v2-surface-2);
    color: var(--v2-ink-3);
}
textarea.form-control { min-height: 120px; resize: vertical; }

.form-check-input {
    width: 1.25rem;
    height: 1.25rem;
    border: 1px solid var(--v2-line);
    border-radius: 5px;
}
.form-check-input:checked {
    background-color: var(--v2-pri);
    border-color: var(--v2-pri);
}
.form-check-input:focus { box-shadow: var(--v2-ring); border-color: var(--v2-pri); }
.form-check-label { font-size: var(--v2-text-sm); cursor: pointer; }

.input-group-text {
    background: var(--v2-surface-2);
    border-color: var(--v2-line);
    color: var(--v2-ink-2);
}

/* ==========================================================================
   7. BOOTSTRAP SKIN — tables
   ========================================================================== */
.table {
    --bs-table-bg: transparent;
    --bs-table-color: var(--v2-ink);
    --bs-table-border-color: var(--v2-line-soft);
    --bs-table-hover-bg: var(--v2-surface-2);
    --bs-table-hover-color: var(--v2-ink);
    --bs-table-striped-bg: var(--v2-surface-2);
    --bs-table-striped-color: var(--v2-ink);
    margin-bottom: 0;
    font-size: var(--v2-text-sm);
}
.table > thead th {
    font-size: var(--v2-text-2xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--v2-ink-3);
    background: var(--v2-surface-2);
    border-bottom: 1px solid var(--v2-line);
    padding: 0.75rem 1rem;
    white-space: nowrap;
}
.table > tbody td { padding: 0.75rem 1rem; vertical-align: middle; }
.table > tbody tr { border-color: var(--v2-line-soft); }
.table > tbody tr:hover { background: var(--v2-surface-2); }

.table-responsive {
    border-radius: var(--v2-r);
    -webkit-overflow-scrolling: touch;
}
.table-responsive::-webkit-scrollbar { height: 8px; }
.table-responsive::-webkit-scrollbar-thumb {
    background: var(--v2-line);
    border-radius: var(--v2-r-full);
}

/* ==========================================================================
   8. BOOTSTRAP SKIN — badges, alerts, pagination, dropdowns
   ========================================================================== */
.badge {
    --bs-badge-font-size: var(--v2-text-2xs);
    --bs-badge-font-weight: 600;
    --bs-badge-padding-x: 0.625em;
    --bs-badge-padding-y: 0.4em;
    border-radius: var(--v2-r-full);
    letter-spacing: 0.01em;
    /* Bootstrap uses inline-block; keep it. inline-flex made the badge a flex
       container that stretched oddly as a flex item. */
    display: inline-block;
    vertical-align: middle;
}
.badge.text-bg-primary { background: var(--v2-pri) !important; }
.badge.bg-primary { background: var(--v2-pri) !important; }
.badge.bg-success, .badge.text-bg-success { background: var(--v2-ok) !important; }
.badge.bg-danger,  .badge.text-bg-danger  { background: var(--v2-bad) !important; }
.badge.bg-warning, .badge.text-bg-warning {
    background: var(--v2-warn) !important; color: #fff !important;
}
.badge.bg-info,    .badge.text-bg-info    { background: var(--v2-info) !important; }
.badge.bg-secondary, .badge.text-bg-secondary {
    background: var(--v2-ink-3) !important;
}

.alert {
    --bs-alert-border-radius: var(--v2-r);
    border: 1px solid transparent;
    padding: var(--v2-space-4);
    font-size: var(--v2-text-sm);
    /* Deliberately NOT display:flex. Alerts routinely contain block
       content (headers, collapsible help, lists) which must stack
       vertically — flex row squeezed the Team Management Guide into
       side-by-side slivers on phones. Inline icons get spacing instead. */
    display: block;
}
.alert > i:first-child,
.alert > svg:first-child,
.alert > .fas:first-child, .alert > .far:first-child {
    margin-right: var(--v2-space-2);
}
.alert-success { background: var(--v2-ok-bg);   border-color: var(--v2-ok);   border-color: color-mix(in srgb, var(--v2-ok) 25%, transparent);   color: var(--v2-ok); }
.alert-danger  { background: var(--v2-bad-bg);  border-color: var(--v2-bad);  border-color: color-mix(in srgb, var(--v2-bad) 25%, transparent);  color: var(--v2-bad); }
.alert-warning { background: var(--v2-warn-bg); border-color: var(--v2-warn); border-color: color-mix(in srgb, var(--v2-warn) 30%, transparent); color: var(--v2-warn); }
.alert-info    { background: var(--v2-info-bg); border-color: var(--v2-info); border-color: color-mix(in srgb, var(--v2-info) 25%, transparent); color: var(--v2-info); }
.alert strong { font-weight: 700; }

.pagination { --bs-pagination-border-radius: var(--v2-r-sm); gap: 2px; }
.page-link {
    color: var(--v2-ink-2);
    border: 1px solid var(--v2-line);
    border-radius: var(--v2-r-sm) !important;
    padding: 0.5rem 0.75rem;
    font-size: var(--v2-text-sm);
    font-weight: 600;
    background: var(--v2-surface);
}
.page-link:hover { background: var(--v2-surface-2); color: var(--v2-ink); }
.page-item.active .page-link {
    background: var(--v2-pri);
    border-color: var(--v2-pri);
    color: #fff;
}

.dropdown-menu {
    --bs-dropdown-bg: var(--v2-surface);
    --bs-dropdown-border-color: var(--v2-line);
    --bs-dropdown-link-color: var(--v2-ink-2);
    --bs-dropdown-link-hover-bg: var(--v2-surface-2);
    --bs-dropdown-link-hover-color: var(--v2-ink);
    --bs-dropdown-border-radius: var(--v2-r);
    --bs-dropdown-link-padding-y: 0.5rem;
    --bs-dropdown-link-padding-x: 0.875rem;
    --bs-dropdown-box-shadow: var(--v2-e3);
    font-size: var(--v2-text-sm);
    padding: var(--v2-space-2);
    border-width: 1px;
}
.dropdown-item { border-radius: var(--v2-r-sm); font-weight: 500; }
.dropdown-item:active { background: var(--v2-pri); color: #fff; }
.dropdown-divider { border-color: var(--v2-line-soft); margin: var(--v2-space-2) 0; }
.dropdown-header { font-size: var(--v2-text-2xs); text-transform: uppercase;
    letter-spacing: .06em; color: var(--v2-ink-3); font-weight: 700; }

.modal-content {
    --bs-modal-bg: var(--v2-surface);
    --bs-modal-border-color: var(--v2-line);
    --bs-modal-border-radius: var(--v2-r-lg);
    --bs-modal-box-shadow: var(--v2-e3);
    border: 1px solid var(--v2-line);
    border-radius: var(--v2-r-lg);
}
.modal-header, .modal-footer { border-color: var(--v2-line-soft); padding: var(--v2-space-4); }
.modal-body { padding: var(--v2-space-4); }
.modal-title { font-size: var(--v2-text-lg); font-weight: 700; }

.toast {
    --bs-toast-bg: var(--v2-surface);
    --bs-toast-border-color: var(--v2-line);
    --bs-toast-header-bg: var(--v2-surface-2);
    --bs-toast-header-color: var(--v2-ink-3);
    --bs-toast-border-radius: var(--v2-r);
    box-shadow: var(--v2-e3);
    font-size: var(--v2-text-sm);
}
.toast-header { border-color: var(--v2-line-soft); font-weight: 600; }

.list-group {
    --bs-list-group-bg: var(--v2-surface);
    --bs-list-group-border-color: var(--v2-line);
    --bs-list-group-border-radius: var(--v2-r);
    font-size: var(--v2-text-sm);
}
.list-group-item {
    background: var(--v2-surface);
    border-color: var(--v2-line-soft);
    padding: var(--v2-space-3) var(--v2-space-4);
}
.list-group-item.active {
    background: var(--v2-pri);
    border-color: var(--v2-pri);
    color: #fff;
}

.breadcrumb {
    --bs-breadcrumb-divider-color: var(--v2-ink-3);
    --bs-breadcrumb-item-active-color: var(--v2-ink-3);
    font-size: var(--v2-text-sm);
    margin-bottom: var(--v2-space-4);
}
.breadcrumb-item + .breadcrumb-item::before { color: var(--v2-ink-3); }

.nav-tabs {
    --bs-nav-tabs-border-color: var(--v2-line);
    --bs-nav-tabs-link-active-color: var(--v2-pri);
    --bs-nav-tabs-link-active-bg: var(--v2-surface);
    --bs-nav-tabs-link-active-border-color: var(--v2-line) var(--v2-line) var(--v2-surface);
    gap: 2px;
}
.nav-tabs .nav-link {
    border: none;
    border-bottom: 2px solid transparent;
    color: var(--v2-ink-2);
    font-weight: 600;
    font-size: var(--v2-text-sm);
    padding: 0.625rem 1rem;
    border-radius: var(--v2-r-sm) var(--v2-r-sm) 0 0;
}
.nav-tabs .nav-link:hover { border-color: transparent transparent var(--v2-line); color: var(--v2-ink); }
.nav-tabs .nav-link.active {
    background: transparent;
    border-bottom-color: var(--v2-pri);
    color: var(--v2-pri);
}

/* ==========================================================================
   9. TEXT UTILITIES (aligned to the new ink ramp)
   ========================================================================== */
.text-muted { color: var(--v2-ink-3) !important; }
.text-secondary { color: var(--v2-ink-2) !important; }
.text-primary { color: var(--v2-pri) !important; }
.text-success { color: var(--v2-ok) !important; }
.text-danger  { color: var(--v2-bad) !important; }
.text-warning { color: var(--v2-warn) !important; }
.text-info    { color: var(--v2-info) !important; }
.text-dark    { color: var(--v2-ink) !important; }
.text-light   { color: var(--v2-surface) !important; }

.bg-light   { background-color: var(--v2-surface-2) !important; }
.bg-white   { background-color: var(--v2-surface) !important; }
.bg-dark    { background-color: var(--v2-ink) !important; }

.border, .border-top, .border-bottom, .border-start, .border-end { border-color: var(--v2-line) !important; }
.shadow-sm { box-shadow: var(--v2-e1) !important; }
.shadow    { box-shadow: var(--v2-e2) !important; }
.shadow-lg { box-shadow: var(--v2-e3) !important; }

.rounded { border-radius: var(--v2-r) !important; }
.rounded-0 { border-radius: 0 !important; }

/* ==========================================================================
   10. APP PRIMITIVES
   ========================================================================== */
.brand-mark {
    width: 34px; height: 34px;
    border-radius: 10px;
    background: linear-gradient(140deg, var(--v2-blue-500), var(--v2-blue-700));
    color: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.9375rem;
    flex-shrink: 0;
    box-shadow: 0 2px 8px -2px var(--v2-pri-ring);
}

/* Stat card */
.stat-card {
    background: var(--v2-surface);
    border: 1px solid var(--v2-line);
    border-radius: var(--v2-r-lg);
    padding: var(--v2-space-4);
    box-shadow: var(--v2-e1);
    height: 100%;
    display: flex;
    flex-direction: column;
    gap: var(--v2-space-1);
    transition: box-shadow var(--v2-med), transform var(--v2-med);
}
.stat-card:hover { box-shadow: var(--v2-e2); }
.stat-card__label {
    font-size: var(--v2-text-2xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--v2-ink-3);
}
.stat-card__value {
    font-size: var(--v2-text-2xl);
    font-weight: 800;
    letter-spacing: -0.03em;
    line-height: 1.05;
    color: var(--v2-ink);
    font-variant-numeric: tabular-nums;
}
.stat-card__value.is-negative { color: var(--v2-bad); }
.stat-card__value.is-positive { color: var(--v2-ok); }
.stat-card__sub { font-size: var(--v2-text-xs); color: var(--v2-ink-3); }

/* Group / event cards */
.group-card, .event-card {
    background: var(--v2-surface);
    border: 1px solid var(--v2-line);
    border-radius: var(--v2-r-lg);
    box-shadow: var(--v2-e1);
    transition: box-shadow var(--v2-med), transform var(--v2-med),
                border-color var(--v2-med);
    overflow: hidden;
    text-decoration: none;
    color: inherit;
    display: block;
}
.group-card:hover, .event-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--v2-e3);
    border-color: var(--v2-pri-ring);
    color: inherit;
}
.group-card__avatar, .event-card__date {
    width: 46px; height: 46px;
    border-radius: var(--v2-r);
    background: linear-gradient(140deg, var(--v2-blue-400), var(--v2-blue-600));
    color: #fff;
    display: flex; align-items: center; justify-content: center;
    font-weight: 700; flex-shrink: 0;
}
.group-card__balance, .event-card__meta {
    font-size: var(--v2-text-sm);
    color: var(--v2-ink-2);
}

/* Pills / filter chips */
.pill {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.5rem 0.875rem;
    border-radius: var(--v2-r-full);
    background: var(--v2-surface);
    border: 1px solid var(--v2-line);
    color: var(--v2-ink-2);
    font-size: var(--v2-text-sm);
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
    transition: all var(--v2-fast);
}
.pill:hover {
    background: var(--v2-surface-2);
    color: var(--v2-ink);
    border-color: var(--v2-ink-3);
}
.pill.is-active {
    background: var(--v2-pri);
    border-color: var(--v2-pri);
    color: #fff;
    box-shadow: var(--v2-e1);
}
.pill-count {
    background: var(--v2-surface-2);
    color: var(--v2-ink-3);
    border-radius: var(--v2-r-full);
    padding: 0 0.5rem;
    font-size: var(--v2-text-2xs);
    font-weight: 700;
}
.pill.is-active .pill-count { background: rgba(255,255,255,.22); color: #fff; }

/* Auth card */
.auth-card {
    background: var(--v2-surface);
    border: 1px solid var(--v2-line);
    border-radius: var(--v2-r-xl);
    box-shadow: var(--v2-e3);
    padding: clamp(1.5rem, 4vw, 2.5rem);
    max-width: 460px;
    margin: 0 auto;
    width: 100%;
}
.auth-card__brand {
    display: flex;
    align-items: center;
    gap: var(--v2-space-3);
    margin-bottom: var(--v2-space-5);
}
.auth-card__title { font-size: var(--v2-text-xl); margin-bottom: var(--v2-space-1); }
.auth-card__subtitle { color: var(--v2-ink-3); font-size: var(--v2-text-sm); margin-bottom: var(--v2-space-5); }
.auth-card__footer {
    text-align: center;
    margin-top: var(--v2-space-5);
    padding-top: var(--v2-space-4);
    border-top: 1px solid var(--v2-line-soft);
    font-size: var(--v2-text-sm);
    color: var(--v2-ink-3);
}

/* Form field */
.form-field { margin-bottom: var(--v2-space-4); }
.form-field__label {
    display: block;
    font-size: var(--v2-text-sm);
    font-weight: 600;
    color: var(--v2-ink-2);
    margin-bottom: var(--v2-space-2);
}
.form-field__input {
    width: 100%;
    font-size: var(--v2-text-base);
    padding: 0.625rem 0.875rem;
    border: 1px solid var(--v2-line);
    border-radius: var(--v2-r-sm);
    background: var(--v2-surface);
    color: var(--v2-ink);
    min-height: 44px;
    transition: border-color var(--v2-fast), box-shadow var(--v2-fast);
}
.form-field__input:focus {
    outline: none;
    border-color: var(--v2-pri);
    box-shadow: var(--v2-ring);
}
.form-field__password-wrap { position: relative; }
.form-field__password-wrap .form-field__input { padding-right: 3rem; }
.form-field__password-toggle {
    position: absolute;
    right: 4px; top: 50%;
    transform: translateY(-50%);
    width: 40px; height: 40px;
    border: 0;
    background: transparent;
    color: var(--v2-ink-3);
    border-radius: var(--v2-r-sm);
    cursor: pointer;
    display: flex; align-items: center; justify-content: center;
}
.form-field__password-toggle:hover { color: var(--v2-ink); background: var(--v2-surface-2); }

/* Empty state */
.empty-state {
    text-align: center;
    padding: var(--v2-space-7) var(--v2-space-4);
    color: var(--v2-ink-3);
}
.empty-state__icon {
    width: 64px; height: 64px;
    border-radius: var(--v2-r-lg);
    background: var(--v2-surface-2);
    color: var(--v2-ink-3);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.5rem;
    margin-bottom: var(--v2-space-4);
}
.empty-state__title {
    font-size: var(--v2-text-md);
    font-weight: 700;
    color: var(--v2-ink);
    margin-bottom: var(--v2-space-2);
}
.empty-state__subtitle { font-size: var(--v2-text-sm); max-width: 42ch; margin: 0 auto var(--v2-space-4); }

/* ==========================================================================
   11. UTILITY BRIDGE
   ========================================================================== */
.spinner-border { color: var(--v2-pri); }
.form-text { font-size: var(--v2-text-xs); color: var(--v2-ink-3); }
.invalid-feedback { font-size: var(--v2-text-xs); }
.was-validated .form-control:invalid,
.form-control.is-invalid { border-color: var(--v2-bad); }
.was-validated .form-control:valid,
.form-control.is-valid { border-color: var(--v2-ok); }

/* ==========================================================================
   12. CARD DENSITY & IN-PAGE HEADINGS
   --------------------------------------------------------------------------
   `.section-title` is used both as a page heading and as a card heading.
   Sized for the page it was wildly wrong inside a card: 3rem of top margin
   and a large type size on every card heading, which is most of why the
   group/event pages feel like a stack of oversized boxes on a phone.
   ========================================================================== */
.card > .card-body > .section-title:first-child,
.card > .card-header > .section-title:first-child,
.card .section-title:first-child {
    margin-top: 0;
}
.card .section-title {
    font-size: var(--v2-text-base);
    font-weight: 700;
    letter-spacing: -0.01em;
    margin: 0 0 var(--v2-space-3);
    gap: var(--v2-space-2);
    color: var(--v2-ink);
}
.card .section-title i { font-size: 0.875rem; color: var(--v2-ink-3); }

/* Tighter cards on phones: less chrome, more content per screen */
@media (max-width: 767.98px) {
    .card > .card-body { padding: var(--v2-space-3); }
    .card > .card-header { padding: var(--v2-space-3); }
    .card + .card, .card.mb-3 { margin-bottom: var(--v2-space-3) !important; }
}

/* ==========================================================================
   13. DEFINITION LISTS
   --------------------------------------------------------------------------
   The app renders facts as <dl class="row"><dt class="col-sm-4">..</dt>
   <dd class="col-sm-8">..</dd>. Below 576px the col-sm-* classes stop
   applying, so every pair collapsed to label-on-one-line, value-on-the-next
   and the "Group information" block turned into 10 near-empty rows.

   Grid auto-placement keeps each dt in column 1 and its dd in column 2, so
   pairs stay side by side at every width.
   ========================================================================== */
@media (max-width: 767.98px) {
    dl.row {
        display: grid;
        grid-template-columns: minmax(0, 40%) minmax(0, 60%);
        gap: var(--v2-space-2) var(--v2-space-3);
        row-gap: var(--v2-space-2);
    }
    dl.row > dt,
    dl.row > dd {
        flex: none;
        width: auto;
        max-width: none;
        margin-bottom: 0;
        padding-left: 0;
        padding-right: 0;
        min-width: 0;
        overflow-wrap: anywhere;
    }
    dl.row > dt {
        font-size: var(--v2-text-xs);
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: 0.04em;
        color: var(--v2-ink-3);
        align-self: baseline;
    }
    dl.row > dd {
        font-size: var(--v2-text-sm);
        color: var(--v2-ink);
        font-weight: 500;
    }
}

/* ==========================================================================
   14. VERTICAL RHYTHM INSIDE GROUP / EVENT PAGES
   ========================================================================== */
/* A run of sibling cards on a phone reads better as one grouped panel than
   as N separate boxes with gaps. Pull them together without losing the
   card separation on wider screens. */
@media (max-width: 767.98px) {
    .row > [class*="col-"] > .card + .card { margin-top: 0; }
    .row.g-3 > [class*="col-"] { margin-bottom: var(--v2-space-3); }
}

/* Group header card: the avatar + title + CTA block was ~180px tall on a
   phone before any content was visible. Lay it out horizontally instead. */
@media (max-width: 575.98px) {
    .group-hero {
        display: flex;
        align-items: center;
        gap: var(--v2-space-3);
        flex-wrap: wrap;
    }
    .group-hero__cta { margin-left: auto; }
}

/* ==========================================================================
   15. GROUP HERO HEADER
   --------------------------------------------------------------------------
   The header row is a flex line of [avatar 64px] [name + meta] [actions].
   At 390px the three do not fit, so the actions wrapped onto their own line
   and pushed the first real content ~180px down. Scale the avatar and title
   down on phones, and drop the header's "Join Group" on mobile so the page
   shows exactly one prominent join CTA (the overview panel) instead of two
   competing ones a scroll apart.
   ========================================================================== */
.group-hero {
    display: flex;
    align-items: center;
    gap: var(--v2-space-3);
    flex-wrap: nowrap;
    min-width: 0;
}
.group-hero__avatar {
    width: 64px; height: 64px;
    background: linear-gradient(140deg, var(--v2-blue-500), var(--v2-blue-700));
    color: #fff;
    font-weight: 700;
    font-size: 1.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--v2-r-lg);
    box-shadow: 0 2px 10px -2px var(--v2-pri-ring);
    flex-shrink: 0;
}
.group-hero__title {
    font-size: var(--v2-text-xl);
    font-weight: 800;
    letter-spacing: -0.025em;
    margin: 0 0 2px;
    line-height: 1.15;
}
.group-hero__actions {
    display: flex;
    gap: var(--v2-space-2);
    flex-wrap: wrap;
    flex-shrink: 0;
}

@media (max-width: 767.98px) {
    .group-hero { gap: var(--v2-space-2); flex-wrap: wrap; }
    .group-hero__avatar { width: 44px; height: 44px; font-size: 1.0625rem; border-radius: var(--v2-r); }
    .group-hero__title { font-size: var(--v2-text-md); }
    /* one CTA on mobile: the overview panel owns it */
    .group-hero__actions { display: none; }
}

/* ==========================================================================
   16. BOOTSTRAP GRID OVERFLOW INSIDE PADDED WRAPPERS
   --------------------------------------------------------------------------
   Bootstrap's `.row` carries a negative inline margin (-.5 * gutter) whose
   only job is to cancel the padding of the container it sits in. When a
   `.row` is nested inside some *other* padded element instead — which is
   what most of the 102 views do, e.g.

       <div class="d-md-none p-3"><div class="row g-3">
           <div class="col-12"><div class="card">…</div></div>
       </div></div>

   the negative margin no longer cancels anything. It pushes the row 2 *
   gutter wider than the wrapper, and `.col-12 { width: 100% }` then resolves
   against that inflated width, so the column (and the card inside it) spills
   past the wrapper and off the right edge of the screen. On a 390px phone
   the group Events tab rendered every event card clipped: the "17
   Registered" badge and the View button were sliced off.

   Fix: zero the row's inline margin when it is a direct child of a padded
   wrapper. The per-column gutter padding that `g-*` installs is untouched, so
   spacing between columns is identical — the row simply stops overflowing.
   ========================================================================== */
.p-1 > .row, .p-2 > .row, .p-3 > .row, .p-4 > .row, .p-5 > .row,
.card-body > .row, .card-header > .row, .card-footer > .row,
.alert > .row, .list-group > .row {
    margin-left: 0;
    margin-right: 0;
}

/* Belt and braces: a row should never be able to push its wrapper wider. */
.row { min-width: 0; }
.row > * { min-width: 0; }

/* Long unbroken strings (emails, URLs, Stripe ids) are the other classic
   cause of horizontal scroll on a phone. */
@media (max-width: 767.98px) {
    .card-body, .table-responsive, .list-group-item, .v2-navlink {
        overflow-wrap: anywhere;
        word-break: break-word;
    }
    /* Long values in a label/value grid get their own line rather than
       pushing the layout sideways. */
    dl.row > dd { overflow-wrap: anywhere; }
}

/* ==========================================================================
   17. CARD HEADER ROWS THAT OVERFLOW ON A PHONE
   --------------------------------------------------------------------------
   Card headers are built as
       <div class="d-flex justify-content-between align-items-start mb-2">
           <div><strong>Tuesday, October 6, 2026</strong></div>
           <span class="badge bg-primary">17 Registered</span>
       </div>
   With a non-wrapping row, a long title and a badge cannot both fit inside a
   ~280px card, and neither child is allowed to shrink far enough. Measured at
   390px: the row's children summed to 616px inside a 280px card, so the
   badge and the action button were sliced off the right edge (the body clips
   horizontal overflow, so it looked like a rendering glitch rather than a
   scrollbar).

   Fix: let these rows wrap, allow the text side to shrink and wrap its words,
   and stop badges from ever growing past their content.
   ========================================================================== */
@media (max-width: 767.98px) {
    .card .d-flex.justify-content-between {
        flex-wrap: wrap;
        row-gap: var(--v2-space-2);
    }
    .card .d-flex.justify-content-between > div:first-child {
        min-width: 0;
        flex: 1 1 auto;
        overflow-wrap: anywhere;
    }
}

.badge { max-width: 100%; }

/* ==========================================================================
   18. EVENT CARD (group > Events, mobile)
   ========================================================================== */
.evt-card__head {
    display: flex;
    flex-direction: column;
    gap: var(--v2-space-2);
    margin-bottom: var(--v2-space-3);
}
.evt-card__title {
    font-size: var(--v2-text-md);
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.25;
    color: var(--v2-ink);
    overflow-wrap: anywhere;
}
.evt-card__meta {
    /* Deliberately NOT a flex container. As flex items these badges blockify
       and resolve to flex-basis:100%, so each one took a full line at 280px.
       Plain block flow keeps them inline, wrapping on their own. */
    display: block;
    font-size: 0;
    line-height: 0;
}
.evt-card__meta > * {
    font-size: var(--v2-text-2xs);
    line-height: 1.5;
    margin: 0 var(--v2-space-1) var(--v2-space-1) 0;
    display: inline-block;
    vertical-align: middle;
}
.evt-card__line {
    font-size: var(--v2-text-sm);
    color: var(--v2-ink-2);
    margin-bottom: var(--v2-space-1);
    overflow-wrap: anywhere;
}
.evt-card__line i { color: var(--v2-ink-3); font-size: 0.8125rem; margin-right: var(--v2-space-2); }
.evt-card__actions {
    /* Plain block flow: one full-width action per line. (A flex row here
       produced a nested inline-flex button whose flex-basis resolved to
       100% of an already-narrow container, slicing the label on 390px.) */
    display: block;
    margin-top: var(--v2-space-3);
}
.evt-card__actions .btn {
    display: block;
    width: 100%;
    margin: 0 0 var(--v2-space-2);
}
.evt-card__actions .btn:last-child { margin-bottom: 0; }

/* Wider screens get the roomier side-by-side header back. */
@media (min-width: 768px) {
    .evt-card__head {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        gap: var(--v2-space-4);
    }
}

/* ==========================================================================
   19. VISUAL IDENTITY OVERHAUL
   --------------------------------------------------------------------------
   The app was clean but generic: flat white cards, stock Bootstrap blue,
   gray text — indistinguishable from any admin template. This section gives
   it an identity: deep ice-navy + electric cyan, gradient heroes, dark
   sidebar, floating mobile tab bar, glowing primary actions. Light mode
   stays light and airy; drama comes from the heroes and the sidebar.
   ========================================================================== */

/* --- Identity tokens (both modes) --- */
:root {
    --v2-navy-950: #060d1a;
    --v2-navy-900: #0a1628;
    --v2-navy-800: #10233d;
    --v2-navy-700: #16304f;
    --v2-cyan-300: #67e8f9;
    --v2-cyan-400: #22d3ee;
    --v2-cyan-500: #06b6d4;
    --v2-grad-brand: linear-gradient(135deg, #0077b6 0%, #023e8a 55%, #03045e 100%);
    --v2-grad-hero: linear-gradient(150deg, #0a1628 0%, #10233d 45%, #16304f 75%, #0d3b5e 100%);
    --v2-grad-btn: linear-gradient(135deg, #0096c7 0%, #0077b6 60%, #023e8a 100%);
    --v2-glow: 0 8px 24px -6px rgba(0, 119, 182, .5);
    --v2-ice: radial-gradient(ellipse 80% 60% at 80% 10%, rgba(103, 232, 249, .14), transparent 60%),
               radial-gradient(ellipse 60% 50% at 10% 90%, rgba(0, 150, 199, .12), transparent 60%);
}

/* --- Primary buttons: gradient + glow --- */
.btn-primary {
    background: var(--v2-grad-btn);
    border: none;
    box-shadow: var(--v2-glow);
    font-weight: 700;
}
.btn-primary:hover {
    filter: brightness(1.08);
    box-shadow: 0 10px 28px -6px rgba(0, 119, 182, .65);
    transform: translateY(-1px);
}
.btn-primary:active { transform: translateY(0); filter: brightness(.97); }

/* --- Brand mark: gradient puck --- */
.brand-mark {
    background: var(--v2-grad-brand);
    box-shadow: 0 4px 12px -2px rgba(0, 119, 182, .5), inset 0 1px 0 rgba(255,255,255,.25);
}

/* --- Avatars: gradient initial chips --- */
.group-card__avatar, .event-card__date, .avatar, .v2-avatar {
    background: linear-gradient(140deg, #0096c7, #023e8a);
    box-shadow: 0 4px 10px -3px rgba(0, 119, 182, .45), inset 0 1px 0 rgba(255,255,255,.2);
}
.group-hero__avatar {
    background: linear-gradient(140deg, var(--v2-cyan-400), #0077b6);
    box-shadow: 0 0 0 3px rgba(103, 232, 249, .35), 0 8px 20px -4px rgba(0, 0, 0, .5);
}

/* ==========================================================================
   GROUP HERO — gradient banner
   ========================================================================== */
.grp-hero {
    background: var(--v2-grad-hero);
    border: none;
    overflow: hidden;
    position: relative;
    box-shadow: 0 16px 40px -12px rgba(6, 13, 26, .55);
}
.grp-hero::before {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--v2-ice);
    pointer-events: none;
}
/* faint oversized puck watermark */
.grp-hero::after {
    content: "\f453";
    font-family: "Font Awesome 6 Free";
    font-weight: 900;
    position: absolute;
    right: -30px;
    top: 50%;
    transform: translateY(-50%) rotate(-12deg);
    font-size: 11rem;
    color: rgba(255, 255, 255, .045);
    pointer-events: none;
    line-height: 1;
}
.grp-hero > .card-body { position: relative; z-index: 1; }
.grp-hero .group-hero__title { color: #fff; }
.grp-hero .text-muted { color: rgba(255, 255, 255, .65) !important; }
.grp-hero a.text-muted { color: rgba(255, 255, 255, .75) !important; }
.grp-hero a.text-muted:hover { color: #fff !important; }
.grp-hero .badge.bg-danger-subtle { background: rgba(248, 113, 113, .2) !important; color: #fca5a5 !important; }
.grp-hero .badge.bg-warning-subtle { background: rgba(251, 191, 36, .2) !important; color: #fcd34d !important; }
.grp-hero .btn-outline-secondary {
    border-color: rgba(255, 255, 255, .3);
    color: #fff;
    background: rgba(255, 255, 255, .08);
}
.grp-hero .btn-outline-secondary:hover { background: rgba(255, 255, 255, .16); border-color: rgba(255,255,255,.5); }

/* ==========================================================================
   EVENT HERO — gradient banner with date
   ========================================================================== */
.evt-hero {
    background: var(--v2-grad-hero);
    border: none;
    overflow: hidden;
    position: relative;
    box-shadow: 0 16px 40px -12px rgba(6, 13, 26, .55);
    color: #fff;
}
.evt-hero::before {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--v2-ice);
    pointer-events: none;
}
.evt-hero > .card-body { position: relative; z-index: 1; }
.evt-hero h1, .evt-hero h2, .evt-hero h3, .evt-hero strong { color: #fff; }
.evt-hero .text-muted { color: rgba(255, 255, 255, .65) !important; }
.evt-hero a { color: var(--v2-cyan-300); }
.evt-hero .badge.bg-secondary { background: rgba(255,255,255,.16) !important; color: #fff !important; }
.evt-hero .badge.bg-success { box-shadow: 0 4px 12px -2px rgba(5, 150, 105, .6); }
.evt-hero .btn-outline-danger {
    border-color: rgba(248, 113, 113, .5);
    color: #fca5a5;
    background: rgba(248, 113, 113, .1);
}
.evt-hero .btn-outline-danger:hover { background: var(--v2-bad); border-color: var(--v2-bad); color: #fff; }

   CARDS — depth and icon chips
   ========================================================================== */
.card { border-width: 1px; }
.card:hover { box-shadow: var(--v2-e2); }

/* Tinted icon chips in card headings (replaces bare gray fa- icons) */
.card .section-title > i:first-child,
.card-body > h2 > i:first-child,
.card-body > h3 > i:first-child {
    background: var(--v2-pri-soft);
    color: var(--v2-pri);
    width: 30px;
    height: 30px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 9px;
    font-size: 0.8125rem;
    margin-right: 2px;
    vertical-align: -6px;
}

/* Pills / tabs: stronger active state */
.pill.is-active {
    background: var(--v2-grad-btn);
    border: none;
    box-shadow: var(--v2-glow);
    color: #fff;
}
.v2-navlink__badge { box-shadow: 0 2px 6px -1px rgba(220, 38, 38, .5); }

/* Stat cards: gradient top edge */
.stat-card { position: relative; overflow: hidden; }
.stat-card::before {
    content: "";
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 3px;
    background: var(--v2-grad-btn);
    opacity: .85;
}
.stat-card__value { font-variant-numeric: tabular-nums; }

/* Tables: sticky header + row hover */
.table > thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--v2-surface-2);
}
.table > tbody tr { transition: background-color var(--v2-fast); }

/* Badges: dot style for status */
.badge.bg-success, .badge.bg-danger, .badge.bg-warning {
    box-shadow: 0 2px 8px -2px rgba(0,0,0,.25);
}

/* Forms: stronger focus */
.form-control:focus, .form-select:focus {
    border-color: var(--v2-cyan-500);
    box-shadow: 0 0 0 3px rgba(6, 182, 212, .22);
}

/* Auth card: elevated with gradient edge */
.auth-card { position: relative; overflow: hidden; }
.auth-card::before {
    content: "";
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 4px;
    background: var(--v2-grad-brand);
}

/* Homepage hero: richer band */
.v2-hero {
    background:
        radial-gradient(ellipse 70% 55% at 85% 15%, rgba(103, 232, 249, .16), transparent 60%),
        radial-gradient(ellipse 55% 45% at 8% 85%, rgba(0, 150, 199, .1), transparent 60%);
}
.v2-hero h1 {
    letter-spacing: -0.04em;
    text-wrap: balance;
}

/* Belt-and-braces page background: some legacy sheets paint their own
   surface on wrappers, so pin the page itself in both modes. */
html[data-theme="dark"] body { background-color: #0a0f1a; }
html:not([data-theme="dark"]) body { background-color: #f6f8fb; }

/* ==========================================================================
   20. MOBILE ACTION ROWS
   --------------------------------------------------------------------------
   Pattern used across admin + group views for row-level actions:
       <div class="d-flex gap-2">
         <a class="btn ... flex-grow-1">…</a>
         <button class="btn ...">…</button>
       </div>
   On a 390px card the growing button resolves its flex-basis against the
   full row width and shoves its siblings (and its own label) off-screen.
   On phones these rows stack vertically with full-width buttons instead —
   the standard mobile action pattern, and it can never overflow.
   Scoped with :has() so input+button rows (search bars) keep their
   horizontal layout.
   ========================================================================== */
@media (max-width: 767.98px) {
    .card-body > .d-flex.gap-2:has(> .btn.flex-grow-1),
    .card > .d-flex.gap-2:has(> .btn.flex-grow-1) {
        flex-direction: column;
        align-items: stretch;
    }
    .card-body > .d-flex.gap-2:has(> .btn.flex-grow-1) > .btn,
    .card > .d-flex.gap-2:has(> .btn.flex-grow-1) > .btn {
        width: 100%;
        margin-left: 0 !important;
        margin-right: 0 !important;
    }
}

/* ==========================================================================
   21. ICONS INSIDE BUTTONS — explicit flex pinning
   --------------------------------------------------------------------------
   On phones, an <i class="fas ..."> inside a .btn repeatedly measured
   314px wide (flex-basis resolving to 100% of the button's content box),
   shoving the label out of the button. No author rule sets that basis —
   it emerges from the inline-flex + nowrap + shrink-0 interaction.
   Pin icons to content size explicitly. The !important is intentional:
   this must beat any present or future flex shorthand on .btn.
   ========================================================================== */
.btn > i[class*="fa-"],
.btn > i.fas, .btn > i.far, .btn > i.fab, .btn > i.bi,
.btn > svg {
    flex: 0 0 auto !important;
    width: auto !important;
    max-width: none !important;
}

/* ==========================================================================
   22. SCROLLABLE TAB BARS (group section + anywhere .pill-group is used)
   --------------------------------------------------------------------------
   The group page has up to 8 tabs (Overview … Email). On a 390px phone they
   summed past 770px wide. The container already scrolled (overflow-x:auto)
   but with no snap, no edge affordance and no guarantee the active tab was
   visible — from the user's perspective the tabs just "spilled over".

   Now: mandatory proximity snap so a pill never rests half-cut, momentum
   scrolling on iOS, dynamic edge fades driven by JS (.at-start/.at-end),
   and the active pill auto-centered on load (see v2-shell.js).
   ========================================================================== */
.pill-group {
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
    position: relative;
}
.pill-group::-webkit-scrollbar { display: none; }
.pill-group > * { scroll-snap-align: start; }

/* Edge fades via mask-image on the container itself (fixed to the element
   box, does not scroll with content, takes no layout space — unlike the
   earlier sticky ::before/::after attempt, which rendered as a solid block
   over the first pill on some phones). JS toggles .can-left/.can-right so
   each fade only shows where content actually continues. */
.pill-group {
    --v2-tabfade: 26px;
    -webkit-mask-image: linear-gradient(to right, #000, #000);
    mask-image: linear-gradient(to right, #000, #000);
}
.pill-group.can-right {
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - var(--v2-tabfade)), transparent);
    mask-image: linear-gradient(to right, #000 calc(100% - var(--v2-tabfade)), transparent);
}
.pill-group.can-left {
    -webkit-mask-image: linear-gradient(to right, transparent, #000 var(--v2-tabfade));
    mask-image: linear-gradient(to right, transparent, #000 var(--v2-tabfade));
}
.pill-group.can-left.can-right {
    -webkit-mask-image: linear-gradient(to right, transparent, #000 var(--v2-tabfade), #000 calc(100% - var(--v2-tabfade)), transparent);
    mask-image: linear-gradient(to right, transparent, #000 var(--v2-tabfade), #000 calc(100% - var(--v2-tabfade)), transparent);
}

/* Keyboard users get a visible target when tabbing through pills. */
.pill-group > .pill:focus-visible {
    outline: 2px solid var(--v2-pri);
    outline-offset: 2px;
}
