/* ────────────────────────────────────────────────────────────────
   Us Tonight — shared design tokens
   Canonical source for colour, type, radius and shadow values.
   Page-level <style> blocks may still hold page-specific layout,
   but should reference these tokens rather than redefining them.
   Contrast ratios below are computed (WCAG relative-luminance
   formula), not eyeballed — see the design audit for the numbers.
   ──────────────────────────────────────────────────────────────── */

:root {
    /* Brand — canonical values from the Aug 2026 redesign (documents/Mobile app
       redesign request/Design System.dc.html). Follow these strictly on any
       page you touch; old names below are aliases so untouched pages don't break. */
    --rose: #e83e8c;
    --rose-dark: #c2185b;      /* use for solid-fill buttons w/ light text — 5.17:1 vs 3.36:1 for --rose */
    --rose-glow: rgba(232, 62, 140, .35);
    --rose-light: #ffd9ea;     /* links, active chip text on dark surfaces */
    --pink: #e83e8c;           /* alias — some pages use --pink, same colour */
    --pink-dark: #c2185b;

    /* Secondary accents (not every page needs all of these) */
    --gold: #f4c542;
    --gold-glow: rgba(244, 197, 66, .35);
    --violet: #a78bfa;                  /* icons, borders, bars, large type */
    --violet-light: #bda6ff;            /* violet TEXT — 8.14:1 on --card (AAA) */
    --violet-dark: #7c3aed;
    --green: #34d399;
    --red: #f87171;                     /* status fills, borders, icons */
    --red-light: #ff9a9a;               /* destructive TEXT — 8.37:1 on --card (AAA) */
    --amber: #facc15;

    /* Surfaces — deepest to raised */
    --ink: #0a0812;         /* app ground */
    --ink-2: #0d0b16;       /* nav bar, wheel hub */
    --plum: #171128;        /* bottom sheets */
    --card: #1e1834;        /* flat cards */
    --card-2: #241c3f;      /* raised cards — anything awaiting a decision */
    --line: rgba(255, 255, 255, .09);
    --line-2: rgba(255, 255, 255, .16);

    /* Surface aliases — old names kept so pages not yet redesigned still render */
    --navy: var(--ink);
    --navy-mid: var(--ink-2);
    --navy-card: var(--card);
    --navy-border: var(--line);

    /* Text */
    --text: #f4f1fa;
    /* Both secondary tones clear WCAG AAA (7:1) on every surface token,
       including the lightest, --card-2 (#241c3f). Measured, not estimated:
       --muted 8.40:1, --dim 7.30:1 there; higher on every darker surface.

       DESIGN.md specifies .62 for --muted and calls --dim a "4.59:1 floor".
       Both were short: at .62 secondary text measured 6.31-6.55:1 on cards,
       which passes AA but fails AAA for text under 18.66px — and nearly all
       of this app's secondary text is 11-13px. The two tones are raised
       together so the step between them survives. Do not lower either
       without re-measuring against --card-2, the worst case. */
    --muted: rgba(244, 241, 250, .74);  /* 8.40:1 on --card-2 — secondary body */
    --dim: rgba(244, 241, 250, .68);    /* 7.30:1 on --card-2 — tertiary floor */
    --text-muted: var(--muted);         /* alias */
    --text-dim: var(--dim);             /* alias */

    /* Type scale — replaces the ad-hoc .58rem/.62rem/.67rem/.7rem/.72rem/.73rem/...
       sprawl found across pages. Use these steps; don't hand-pick new ones. */
    --fs-2xs: .68rem;   /* ~11px — timestamps, tiny badges */
    --fs-xs: .75rem;    /* 12px  — meta, captions */
    --fs-sm: .85rem;    /* 13.6px — secondary body */
    --fs-base: 1rem;    /* 16px  — body text */
    --fs-md: 1.2rem;    /* 19px  — card titles */
    --fs-lg: 1.5rem;    /* 24px  — section headings */
    --fs-xl: 2rem;      /* 32px  — page/hero numbers */

    /* Radius scale — replaces 8/10/12/14/16/18/20px sprawl */
    --r-sm: 10px;    /* chips, small buttons */
    --r-md: 16px;    /* cards */
    --r-lg: 22px;    /* modals, hero cards */
    --r-pill: 999px;

    /* Shadow scale */
    --shadow-sm: 0 2px 8px rgba(0, 0, 0, .25);
    --shadow-md: 0 8px 24px rgba(0, 0, 0, .35);
    --shadow-rose: 0 8px 32px rgba(232, 62, 140, .4);
    --sh-sm: var(--shadow-sm);
    --sh-md: var(--shadow-md);
    --sh-rose: 0 10px 30px rgba(232, 62, 140, .32);

    --font-display: 'Playfair Display', serif;
    --font-body: 'DM Sans', sans-serif;
    --display: var(--font-display);
    --body: var(--font-body);
}

/* ────────────────────────────────────────────────────────────────
   Bootstrap overrides — DESIGN.md §9 step 3.
   Bootstrap 5.3 ships light defaults on :root and re-asserts them on
   its own components (.card, .modal-content, .list-group-item, .table
   …), where they beat anything merely inherited from body. Rebinding
   the variables themselves fixes every component at once rather than
   page-by-page. Buttons take the pill radius per DESIGN.md §4.
   ──────────────────────────────────────────────────────────────── */
:root {
    --bs-body-bg: var(--ink);
    --bs-body-color: var(--text);
    --bs-body-font-family: var(--body);
    --bs-border-color: var(--line);
    --bs-border-radius: var(--r-md);
    --bs-border-radius-sm: var(--r-sm);
    --bs-border-radius-lg: var(--r-lg);
    --bs-emphasis-color: var(--text);
    --bs-secondary-color: var(--muted);
    --bs-heading-color: var(--text);
    --bs-link-color: var(--rose-light);
    --bs-link-hover-color: #fff;
}

.btn { border-radius: var(--r-pill); }

/* Screen-reader-only utility — used for real <h1>s that duplicate an
   already-visible styled title, so the page gains document structure
   without a visual change. */
.visually-hidden {
    position: absolute !important;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ────────────────────────────────────────────────────────────────
   Shared component layer (DESIGN.md §9 step 2) — the handful of
   classes that cover roughly every screen. Pages may still add a
   page-scoped delta on top (spacing, a modifier) but should not
   redeclare these base properties — reference this layer instead.
   ──────────────────────────────────────────────────────────────── */

/* Every page sets a dark background on <body>, but never on <html>
   itself. Whenever the area above the body's own top edge is exposed —
   iOS rubber-band overscroll, or dragging past the top during the
   pull-to-refresh gesture — the browser paints <html>'s own (default
   white) background there instead of the app's dark ground. Loaded on
   every page via this shared stylesheet, so this fixes it everywhere
   at once rather than page-by-page. */
html {
    background: var(--ink);
    /* iOS rotates portrait -> landscape -> portrait and leaves the page
       scaled up. Locking the text-size adjustment stops Safari resizing
       text on rotation, which is what triggers the stuck zoom.
       100%, never `none`: `none` disables the adjustment machinery and
       reintroduces the bug on some iOS versions. */
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    /* Disables the native double-tap-to-zoom gesture (this is a native
       app-like interface, not a document meant to be zoomed into) without
       touching pinch-zoom or normal scrolling — unlike user-scalable=no
       on the viewport meta tag, which kills pinch-zoom entirely and is an
       accessibility anti-pattern. */
    touch-action: manipulation;
}

body {
    /* html's touch-action does not inherit to fixed-position descendants,
       so the nav and bottom sheets still double-tap-zoomed. */
    touch-action: manipulation;
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

.kicker {
    font: 700 10px var(--body);
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--text);
}

.card {
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    padding: 16px;
    /* Bootstrap's own `.card` rule sets `color: var(--bs-body-color)`
       (#212529). A matching rule always beats an inherited value, so
       without this any card text that doesn't set its own colour
       rendered near-black on the dark card — 1.10:1, effectively
       invisible. Seen on the dashboard partner name and proposal title. */
    color: var(--text);
}

.pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 13px;
    border-radius: var(--r-pill);
    font: 500 12.5px var(--body);
    border: 1px solid var(--line-2);
    color: var(--muted);
    background: transparent;
    cursor: pointer;
    transition: all .15s ease;
}

.pill.pill-on, .pill-on {
    background: rgba(232, 62, 140, .13);
    border-color: rgba(232, 62, 140, .36);
    color: var(--rose-light);
    font-weight: 700;
}

.btn-p {
    width: 100%;
    box-sizing: border-box;
    border: none;
    border-radius: var(--r-pill);
    padding: 16px;
    background: linear-gradient(100deg, var(--rose-dark), var(--rose));
    color: #fff;
    font: 700 15px var(--body);
    box-shadow: var(--sh-rose);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    transition: transform .18s cubic-bezier(.2, .8, .3, 1), filter .18s;
}

.btn-p:active { transform: scale(.975); }
.btn-p:hover:not(:disabled) { filter: brightness(1.08); }
.btn-p:disabled {
    background: rgba(255, 255, 255, .08);
    color: rgba(255, 255, 255, .35);
    box-shadow: none;
    cursor: not-allowed;
}

.btn-s {
    width: 100%;
    box-sizing: border-box;
    border: 1px solid var(--line-2);
    background: transparent;
    border-radius: var(--r-pill);
    padding: 15px;
    color: var(--muted);
    font: 500 14.5px var(--body);
    cursor: pointer;
}
.btn-s:hover { background: rgba(255, 255, 255, .06); color: var(--text); }

.lrow {
    display: flex;
    align-items: center;
    gap: 13px;
    padding: 13px 0;
    border-bottom: 1px solid var(--line);
}
.lrow:last-child { border-bottom: none; }

.ico-tile {
    width: 36px;
    height: 36px;
    border-radius: var(--r-sm);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    font-size: 16px;
}

/* Browser autofill (saved logins/addresses) forces its own background —
   override it everywhere so fields stay on the dark theme instead of
   flashing white/square. The huge transition-delay stops Chrome/Safari
   applying their colour before this rule wins. */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
    -webkit-text-fill-color: var(--text) !important;
    -webkit-box-shadow: 0 0 0 1000px rgba(255,255,255,.05) inset !important;
    caret-color: var(--text);
    transition: background-color 5000s ease-in-out 0s;
}

/* ────────────────────────────────────────────────────────────────
   Bottom navigation — canonical component.
   Previously each of the 8 nav-bearing pages redeclared this in its
   own <style> block, and they had drifted apart: four different
   background colours, three blur radii, icon sizes from 1.15rem to
   1.25rem and labels from .56rem to .62rem. Prototype source:
   `.nav` / `.nav-i` / `.nav-on` in Screens.dc.html.
   Pages must NOT redeclare these — add a page-scoped modifier if a
   page genuinely needs a delta.
   ──────────────────────────────────────────────────────────────── */

:root {
    /* Total height the fixed nav occupies, including the home-indicator
       reserve. Pages use this for their own padding-bottom so content
       can never end up underneath the bar. */
    --nav-h: calc(54px + max(26px, env(safe-area-inset-bottom, 0px) + 10px));
}

.bottom-nav {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 300;
    display: flex;
    /* 26px bottom reserve per DESIGN.md §4; on notch devices the home
       indicator inset replaces it rather than stacking on top of it. */
    padding: 10px 6px max(26px, calc(env(safe-area-inset-bottom, 0px) + 10px));
    background: rgba(13, 11, 22, .88);
    -webkit-backdrop-filter: blur(18px);
    backdrop-filter: blur(18px);
    border-top: 1px solid var(--line);
}

.nav-item {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 5px;
    /* WCAG 2.2 §2.5.5 (AAA) target size */
    min-height: 44px;
    padding: 4px;
    border: none;
    background: none;
    text-decoration: none;
    font-family: var(--body);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

.nav-item .nav-icon {
    font-size: 19px;
    line-height: 1;
    /* --dim renders at ~4.0:1 against the nav's translucent ink ground,
       which fails WCAG 1.4.3 for text this small (9.5px). --muted is
       7.0:1 here, so inactive items clear AAA. */
    color: var(--muted);
    transition: color .2s;
}

.nav-item .nav-label {
    font: 500 9.5px var(--body);
    letter-spacing: .05em;
    color: var(--muted);
    transition: color .2s;
}

.nav-item.active .nav-icon,
.nav-item.active .nav-label {
    /* --rose is 5.11:1 on the nav ground and DESIGN.md reserves it for
       "gradients, icons, borders and 24px+ display type". At 9.5px this
       is small text, so it uses --rose-light (15.2:1, AAA) — the token
       the design system designates for active chip text on dark. */
    color: var(--rose-light);
}
.nav-item.active .nav-label { font-weight: 700; }

.nav-item:focus-visible {
    outline: 2px solid var(--rose-light);
    outline-offset: -3px;
    border-radius: var(--r-sm);
}

/* ────────────────────────────────────────────────────────────────
   Keyboard focus — WCAG 2.2 §2.4.7 / §2.4.11.
   Before this the app had no :focus-visible rule anywhere, and a lot
   of controls set `outline: none` in their base rule, which suppresses
   the user-agent ring outright. Ring spec is the prototype's:
   `.btn:focus-visible{outline:2px solid var(--rose-light);outline-offset:3px}`
   (Design System.dc.html). Text inputs that already draw their own
   rose border + 3px halo on :focus keep that treatment — this only
   fills in what had no visible indicator at all.
   ──────────────────────────────────────────────────────────────── */
a:focus-visible,
button:focus-visible,
select:focus-visible,
summary:focus-visible,
[role="button"]:focus-visible,
[tabindex]:not([tabindex="-1"]):focus-visible,
input[type="checkbox"]:focus-visible,
input[type="radio"]:focus-visible,
input[type="range"]:focus-visible,
input[type="file"]:focus-visible {
    outline: 2px solid var(--rose-light);
    outline-offset: 3px;
}

/* Range sliders set `outline:none` in several page style blocks and
   define no focus treatment, so keyboard focus was invisible on them. */
input[type="range"]:focus-visible {
    outline-offset: 6px;
    border-radius: var(--r-pill);
}

/* Never let a tap remove the ring for the keyboard user that follows. */
:focus:not(:focus-visible) { outline: none; }

/* ────────────────────────────────────────────────────────────────
   SweetAlert2 — app theme.
   SweetAlert ships a light popup and only 23 of the app's 85
   Swal.fire() calls passed `background`/`color`, so the rest opened
   as a white panel on the dark ground. Those that did pass colours
   disagreed with each other (#1e1834 / #201c38 / var(--card)) and
   set confirmButtonColor to --rose, which is 3.36:1 under white
   text and fails WCAG 1.4.3 — solid fills must use --rose-dark.
   Theming it once here covers every call site, so new dialogs are
   correct by default and don't need per-call colour options.
   !important is required because SweetAlert writes the background
   and button colours as inline styles when those options are passed.
   ──────────────────────────────────────────────────────────────── */

.swal2-container { background: rgba(5, 4, 9, .72) !important; }

.swal2-popup {
    background: var(--card) !important;
    color: var(--text) !important;
    border: 1px solid var(--line) !important;
    border-radius: var(--r-lg) !important;
    font-family: var(--body) !important;
}

.swal2-title {
    font-family: var(--display) !important;
    font-weight: 600 !important;
    color: var(--text) !important;
}

.swal2-html-container,
.swal2-content { color: var(--muted) !important; }

.swal2-actions { gap: 9px; }

.swal2-styled.swal2-confirm {
    background: linear-gradient(100deg, var(--rose-dark), var(--rose)) !important;
    border-radius: var(--r-pill) !important;
    color: #fff !important;
    font: 700 14px var(--body) !important;
    box-shadow: none !important;
}

.swal2-styled.swal2-cancel,
.swal2-styled.swal2-deny {
    background: transparent !important;
    border: 1px solid var(--line-2) !important;
    border-radius: var(--r-pill) !important;
    color: var(--muted) !important;
    font: 500 14px var(--body) !important;
}

.swal2-styled:focus-visible {
    outline: 2px solid var(--rose-light) !important;
    outline-offset: 3px;
}

.swal2-input,
.swal2-select,
.swal2-textarea,
.swal2-file {
    background: rgba(255, 255, 255, .05) !important;
    border: 1px solid var(--line-2) !important;
    border-radius: var(--r-sm) !important;
    color: var(--text) !important;
    font-family: var(--body) !important;
    box-shadow: none !important;
}

.swal2-input::placeholder,
.swal2-textarea::placeholder { color: var(--dim); }

.swal2-input:focus,
.swal2-select:focus,
.swal2-textarea:focus {
    border-color: var(--rose) !important;
    box-shadow: 0 0 0 3px rgba(232, 62, 140, .14) !important;
}

.swal2-validation-message {
    background: rgba(248, 113, 113, .12) !important;
    color: var(--red) !important;
}

.swal2-close { color: var(--dim) !important; }
.swal2-close:hover { color: var(--text) !important; }

.swal2-icon.swal2-success .swal2-success-ring { border-color: rgba(52, 211, 153, .3) !important; }
.swal2-icon.swal2-success [class^='swal2-success-line'] { background-color: var(--green) !important; }
.swal2-icon.swal2-error { border-color: var(--red) !important; color: var(--red) !important; }
.swal2-icon.swal2-error [class^='swal2-x-mark-line'] { background-color: var(--red) !important; }
.swal2-icon.swal2-warning { border-color: var(--gold) !important; color: var(--gold) !important; }
.swal2-icon.swal2-info,
.swal2-icon.swal2-question { border-color: var(--rose) !important; color: var(--rose) !important; }

/* ────────────────────────────────────────────────────────────────
   Target size — WCAG 2.2 §2.5.8 (AA, 24x24 CSS px).
   Range inputs are the worst offenders: the visible track is 4px
   tall, so the whole control was a 4px-high hit area. content-box
   sizing plus vertical padding grows the hit area to 24px while the
   painted bar stays 4px, because background-clip keeps the paint
   inside the content box.
   ──────────────────────────────────────────────────────────────── */
input[type="range"] {
    box-sizing: content-box;
    padding-top: 10px;
    padding-bottom: 10px;
    background-clip: content-box;
}

/* ────────────────────────────────────────────────────────────────
   Reduced motion — DESIGN.md §6 ("Respect prefers-reduced-motion"),
   WCAG 2.2 §2.3.3 (AAA) and §2.2.2. Nothing in the app honoured the
   setting before this. Transitions collapse to near-instant rather
   than 0s so state changes still complete their transitionend
   handlers; the wheel spin and confetti are additionally short-
   circuited in JS, since neither is a CSS animation.
   ──────────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }

    /* Press feedback is a scale; without motion it becomes a fade. */
    .tapscale:active,
    .btn-p:active { transform: none; }
}

/* ────────────────────────────────────────────────────────────────
   Tab row — canonical component.
   Prototype source: `.tabs` / `.tab` / `.tab-on` in Screens.dc.html,
   used on Our Space, Ideas and Community. The app had two different
   treatments: Community drew an underline row, Our Space drew a
   solid --rose-dark fill. The solid fill also broke "one rose action
   per screen" — the active tab competed with the actual CTA. The
   prototype's active state is a rose *tint*.
   ──────────────────────────────────────────────────────────────── */
.tab-row {
    display: flex;
    gap: 8px;
}

.tab-row .tab-btn {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    padding: 9px 6px;
    border-radius: var(--r-pill);
    border: 1px solid var(--line);
    background: transparent;
    color: var(--muted);
    font: 700 12px var(--body);
    cursor: pointer;
    transition: background .2s, border-color .2s, color .2s;
}

.tab-row .tab-btn:hover { background: rgba(255, 255, 255, .06); color: var(--text); }

.tab-row .tab-btn.active {
    background: rgba(232, 62, 140, .14);
    border-color: rgba(232, 62, 140, .36);
    color: var(--rose-light);
}


/* ────────────────────────────────────────────────────────────────
   Account menu drawer — canonical component.
   Previously duplicated in dashboard.php, wheel.php and memories.php
   and absent from every other page, which left Profile, Settings,
   Edit interests and Sign out unreachable from Our Space, Ideas,
   Leaderboard, Community, Our Story, Couple DNA and Your Year.
   Markup and behaviour live in components/drawer.php — include that
   partial rather than copying this.
   ──────────────────────────────────────────────────────────────── */
.drawer-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, .55);
    z-index: 600;
    opacity: 0;
    pointer-events: none;
    transition: opacity .25s;
}

.drawer-overlay.open {
    opacity: 1;
    pointer-events: all;
}

.drawer {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: 280px;
    max-width: 85vw;
    background: var(--plum);
    border-left: 1px solid var(--line);
    z-index: 601;
    transform: translateX(100%);
    transition: transform .3s cubic-bezier(.25, .8, .25, 1);
    display: flex;
    flex-direction: column;
}

.drawer-overlay.open .drawer {
    transform: translateX(0);
}

.drawer-header {
    padding: calc(1.4rem + env(safe-area-inset-top, 0px)) 1.25rem 1rem;
    border-bottom: 1px solid var(--line);
}

.drawer-avatar {
    width: 52px;
    height: 52px;
    border-radius: var(--r-pill);
    background: linear-gradient(140deg, var(--rose), var(--violet));
    display: flex;
    align-items: center;
    justify-content: center;
    font: 700 16px var(--body);
    color: #fff;
    margin-bottom: 10px;
    overflow: hidden;
}

.drawer-name {
    font: 700 15px var(--body);
}

.drawer-username {
    font: 400 12.5px var(--body);
    color: var(--muted);
    margin-top: 2px;
}

.drawer-nav {
    flex: 1;
    padding: 6px 0;
    overflow-y: auto;
}

.drawer-item {
    display: flex;
    align-items: center;
    gap: 13px;
    padding: 13px 20px;
    text-decoration: none;
    color: var(--text);
    font: 500 14px var(--body);
    cursor: pointer;
    border: none;
    background: none;
    width: 100%;
    text-align: left;
}

.drawer-item:hover {
    background: rgba(255, 255, 255, .05);
}

.drawer-item .di-icon {
    width: 34px;
    height: 34px;
    border-radius: var(--r-sm);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 15px;
    flex-shrink: 0;
    background: rgba(255, 255, 255, .06);
    color: var(--muted);
}

.drawer-item.danger {
    /* --red is 6.14:1 on --card and this is 14px text, so it needs the
       lighter variant to clear AAA. The icon keeps --red. */
    color: var(--red-light);
}

.drawer-item.danger .di-icon {
    background: rgba(248, 113, 113, .12);
    color: var(--red);
}

.drawer-divider {
    border: none;
    border-top: 1px solid var(--line);
    margin: 6px 0;
}

.drawer-close {
    position: absolute;
    top: calc(.9rem + env(safe-area-inset-top, 0px));
    right: 1rem;
    background: none;
    border: none;
    color: var(--muted);
    font-size: 20px;
    cursor: pointer;
    padding: 4px;
}

.drawer-close:hover {
    color: var(--text);
}

/* The drawer's trigger, shown in each page's top bar. */
.avatar-btn {
    width: 36px;
    height: 36px;
    border-radius: var(--r-pill);
    background: linear-gradient(140deg, var(--rose), var(--violet));
    border: none;
    display: flex;
    align-items: center;
    justify-content: center;
    font: 700 12px var(--body);
    color: #fff;
    cursor: pointer;
    flex-shrink: 0;
    overflow: hidden;
    padding: 0;
    transition: box-shadow .2s;
}

.avatar-btn:hover { box-shadow: 0 0 0 3px rgba(232, 62, 140, .35); }
.avatar-btn img { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; display: block; }

/* ────────────────────────────────────────────────────────────────
   OneSignal's own UI — suppressed.

   The slidedown ("Subscribe to our notifications for the latest news
   and updates") and the bell launcher are configured in the OneSignal
   *dashboard*, and the v16 SDK fetches that config from their servers
   at init. Passing promptOptions.slidedown.prompts[].autoPrompt = false
   in init() does not reliably beat it, so the prompt kept appearing on
   every page — including the sign-in screen — as a white banner in a
   light theme that belongs to no part of this app.

   We ask with our own ustModal() (assets/js/app.js) and call
   Notifications.requestPermission() ourselves, so none of their UI is
   ever wanted. Hidden rather than removed from the DOM: their SDK still
   holds references to these nodes, and deleting them throws inside it.

   Switch "Auto Prompt" off in the OneSignal dashboard too — this rule
   is the belt, that is the braces. If you ever DO want their slidedown,
   delete this block first or you will be debugging an invisible prompt.
   ──────────────────────────────────────────────────────────────── */
#onesignal-slidedown-container,
.onesignal-slidedown-container,
#onesignal-popover-container,
.onesignal-popover-container,
#onesignal-bell-launcher,
.onesignal-bell-launcher {
    display: none !important;
    visibility: hidden !important;
    pointer-events: none !important;
}
