/* ── COACH PORTAL STYLES ─────────────────────────────────────
   Matches MyBest24 dark design system.
   Scope: /coach/ — never loaded in the main app or landing page.
──────────────────────────────────────────────────────────── */

/* ── VARIABLES ──────────────────────────────────────────────── */
:root {
    --bg:              #090909;
    --bg-card:         #0f0f0f;
    --bg-card-2:       #131313;
    /* Used specifically for section header strips (.coach-section-header,
       .settings-section-header). Intentionally more contrast vs --bg-card
       than --bg-card-2 (which stays subtle for hover/alt states). */
    --bg-card-header:  #1f1f1f;
    --bg-input:        #111;
    --border:          #1c1c1c;
    --border-mid:      #282828;
    --accent:       #46a5ce;
    --accent-glow:  rgba(70,165,206,0.15);
    --accent-dim:   rgba(70,165,206,0.1);
    --text:         #efefef;
    --text-mid:     #888;
    --text-dim:     #5d5d5d;
    --green:        #3cba6c;
    --red:          #e05252;
    --yellow:       #d4a843;
    --font-head:    'Outfit', sans-serif;
    --font-body:    'DM Sans', system-ui, sans-serif;
    --radius:       10px;
    --sidebar-w:    240px;

    /* Admin impersonation — declared once, referenced in three places
       (banner height, body padding-top, sidebar offset) so a future
       breakpoint or extra-row banner only changes one number.
       Color: amber against the dark workspace, picked for unmistakable
       contrast — the existing palette has no warning-weight token. */
    --impersonation-banner-h:  48px;
    --banner-amber:            #d97706;
    --banner-amber-2:          #f59e0b;
    --banner-amber-text:       #1a0f00;
}

/* ── BASE ────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body {
    background: var(--bg);
    color: var(--text);
    font-family: var(--font-body);
    font-size: 0.95rem;
    line-height: 1.6;
    min-height: 100vh;
}
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
img { display: block; max-width: 100%; }
button { cursor: pointer; font-family: inherit; }

/* ── UTILITIES ──────────────────────────────────────────────── */
.hidden { display: none !important; }
.accent { color: var(--accent); }
.text-mid { color: var(--text-mid); }
.text-dim { color: var(--text-dim); }

/* ── LOGO ───────────────────────────────────────────────────── */
.coach-logo {
    font-family: var(--font-head);
    font-weight: 800;
    font-size: 1.3rem;
    color: var(--text);
    letter-spacing: -0.5px;
}

/* ════════════════════════════════════════════════════════════
   AUTH SCREEN
════════════════════════════════════════════════════════════ */
#auth-screen {
    /* Copied from /app/auth.css → #auth-overlay.
       Previously `min-height: 100vh`, which on iOS Safari and mobile
       Chrome counts the address-bar height — so the flex-centered card
       sat below the visual centre whenever the bar was showing. Fixed
       positioning binds to the actual visible viewport instead. */
    position: fixed;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 24px;
}
.auth-card {
    width: 100%;
    max-width: 420px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 16px;
    overflow: hidden;
}
.auth-header {
    padding: 32px 32px 0;
}
.auth-tabs {
    display: flex;
    gap: 0;
    border-bottom: 1px solid var(--border);
    margin-top: 28px;
}
.auth-tab {
    flex: 1;
    background: transparent;
    border: none;
    border-bottom: 2px solid transparent;
    padding: 12px;
    font-family: var(--font-head);
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--text-mid);
    letter-spacing: 0.5px;
    transition: all 0.15s;
}
.auth-tab.active {
    color: var(--accent);
    border-bottom-color: var(--accent);
}
.auth-tab:hover:not(.active) { color: var(--text); }
.auth-body { padding: 28px 32px 32px; }
.auth-tagline {
    font-size: 0.85rem;
    color: var(--text-mid);
    margin-bottom: 24px;
}

/* ── FORM ELEMENTS ──────────────────────────────────────────── */
.form-group { margin-bottom: 14px; }
.form-label {
    display: block;
    font-size: 0.78rem;
    font-weight: 700;
    font-family: var(--font-head);
    letter-spacing: 0.5px;
    color: var(--text-mid);
    margin-bottom: 6px;
    text-transform: uppercase;
}
.form-input {
    width: 100%;
    background: var(--bg-input);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 11px 14px;
    color: var(--text);
    font-family: var(--font-body);
    font-size: 0.95rem;
    outline: none;
    transition: border-color 0.15s;
}
.form-input:focus { border-color: var(--accent); }
.form-input::placeholder { color: var(--text-dim); }
.form-hint {
    font-size: 0.78rem;
    color: var(--text-dim);
    margin-top: 5px;
}
.form-error {
    font-size: 0.82rem;
    color: var(--red);
    margin-top: 12px;
    text-align: center;
}

/* ── BUTTONS ────────────────────────────────────────────────── */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    border: none;
    border-radius: 8px;
    padding: 11px 20px;
    font-family: var(--font-head);
    font-weight: 700;
    font-size: 0.9rem;
    transition: all 0.15s;
    text-decoration: none;
}
.btn-primary { background: var(--accent); color: #fff; }
.btn-primary:hover { filter: brightness(1.1); transform: translateY(-1px); text-decoration: none; }
.btn-primary:disabled { opacity: 0.5; cursor: not-allowed; transform: none; filter: none; }
.btn-ghost {
    background: transparent;
    border: 1px solid var(--border-mid);
    color: var(--text-mid);
}
.btn-ghost:hover { border-color: var(--accent); color: var(--text); }
.btn-danger { background: var(--red); color: #fff; }
.btn-danger:hover { filter: brightness(1.1); }
.btn-full { width: 100%; }
.btn-sm { padding: 7px 14px; font-size: 0.8rem; }

.auth-forgot {
    display: block;
    text-align: right;
    font-size: 0.78rem;
    color: var(--text-dim);
    margin-bottom: 20px;
}
.auth-forgot:hover { color: var(--accent); }

/* ════════════════════════════════════════════════════════════
   APP SHELL (post-login)
════════════════════════════════════════════════════════════ */
#app-shell {
    display: flex;
    min-height: 100vh;
}

/* ── SIDEBAR ────────────────────────────────────────────────── */
.coach-sidebar {
    width: var(--sidebar-w);
    background: var(--bg-card);
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    height: 100dvh;   /* dvh tracks the *visible* viewport so the panel never
                         extends behind the mobile browser's address/tool bar */
    overflow-y: auto; /* and if content ever exceeds it, the panel scrolls
                         instead of stranding items off-screen */
    z-index: 50;
    padding: 24px 0;
    padding-bottom: calc(24px + env(safe-area-inset-bottom));
}
.sidebar-brand {
    padding: 0 20px 24px;
    border-bottom: 1px solid var(--border);
}
/* Brand text on the left, the tappable initials avatar on the right. */
.sidebar-brand-row {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
}
.sidebar-brand .coach-badge {
    font-size: 0.65rem;
    font-family: var(--font-head);
    font-weight: 700;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: var(--accent);
    background: var(--accent-dim);
    border: 1px solid rgba(70,165,206,0.25);
    border-radius: 4px;
    padding: 2px 7px;
    margin-top: 4px;
    display: inline-block;
}
/* Stacked brand: full-width logo with a divider under it → avatar on its own
   line → badge below it. (Was logo+badge on the left, avatar on the right in a
   flex row.) The block button sits content-width on the left; the badge, being
   the next block-flow element, drops onto its own line beneath the avatar. */
.sidebar-brand .coach-logo {
    padding-bottom: 18px;
    margin-bottom: 18px;
    border-bottom: 1px solid var(--border);
}
.sidebar-brand .sidebar-profile-toggle {
    display: block;
    width: fit-content;
}
.sidebar-nav {
    flex: 1;
    padding: 16px 0;
}
.sidebar-nav-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 20px;
    color: var(--text-mid);
    font-size: 0.9rem;
    font-weight: 500;
    cursor: pointer;
    border-left: 3px solid transparent;
    transition: all 0.12s;
    background: transparent;
    border-top: none;
    border-right: none;
    border-bottom: none;
    width: 100%;
    text-align: left;
}
.sidebar-nav-item:hover { color: var(--text); background: rgba(255,255,255,0.03); }
.sidebar-nav-item.active {
    color: var(--accent);
    border-left-color: var(--accent);
    background: var(--accent-dim);
}
.sidebar-nav-icon {
    width: 16px;
    height: 16px;
    opacity: 0.6;
    flex-shrink: 0;
}
.sidebar-nav-item.active .sidebar-nav-icon { opacity: 1; }
.sidebar-footer {
    padding: 16px 20px;
    border-top: 1px solid var(--border);
}

/* ── Profile menu (avatar toggle + dropdown) ────────────────────────────────
   The circular initials avatar (.sidebar-coach-avatar) inherits the
   .client-avatar look — accent circle + white initials; only its size is set
   here. Tapping it reveals the dropdown with name/email + Switch to App /
   Sign Out. */
.sidebar-profile-toggle {
    flex-shrink: 0;
    padding: 0;
    background: none;
    border: 2px solid transparent;
    border-radius: 50%;
    cursor: pointer;
    line-height: 0;
    transition: border-color 0.12s;
}
.sidebar-profile-toggle:hover,
.sidebar-profile-toggle[aria-expanded="true"] {
    border-color: var(--accent);
}
.sidebar-coach-avatar {
    width: 36px;
    height: 36px;
    font-size: 0.8rem;
}
/* Profile dropdown — mirrors the app's account menu: full-width flat rows
   (icon+text) separated by dividers. Lives in NORMAL FLOW as a sibling of
   .sidebar-brand, so revealing it pushes the nav items down rather than
   overlaying them. Full-width because the sidebar has no horizontal padding;
   the brand's border-bottom is the top divider, the rule below separates the
   menu from the nav. */
.sidebar-profile-menu {
    border-bottom: 1px solid var(--border);
    padding: 4px 0;
}
.sidebar-profile-user {
    padding: 10px 20px 8px;
}
.sidebar-profile-divider {
    height: 1px;
    background: var(--border);
}
.sidebar-profile-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 10px 20px;   /* match .sidebar-nav-item height */
    background: none;
    border: none;
    color: var(--text-mid);
    font-size: 0.9rem;
    font-family: inherit;
    text-align: left;
    cursor: pointer;
    transition: background 0.12s, color 0.12s;
}
.sidebar-profile-item:hover {
    background: rgba(255, 255, 255, 0.04);
    color: var(--text);
}
.sidebar-profile-item:last-child:hover {
    color: #ff6b6b;           /* sign-out: subtle red tint on hover, matches app */
}
.sidebar-profile-icon {
    width: 16px;
    text-align: center;
    opacity: 0.7;
    flex-shrink: 0;
}
.sidebar-coach-name {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--text);
    margin-bottom: 1px;
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.sidebar-coach-email {
    font-size: 0.75rem;
    color: var(--text-dim);
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.sidebar-legal-links {
    margin-top: 12px;
    font-size: 0.7rem;
    color: var(--text-dim);
    text-align: center;
}
.sidebar-legal-links a {
    color: var(--text-dim);
    text-decoration: none;
}
.sidebar-legal-links a:hover { text-decoration: underline; }
.sidebar-legal-links span { margin: 0 6px; }

/* ── Mobile hamburger ───────────────────────────────────────────── */
.coach-hamburger {
    display: none;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    width: 36px;
    height: 36px;
    padding: 6px;
    background: none;
    border: none;
    cursor: pointer;
    flex-shrink: 0;
    margin-right: 8px;
}
.coach-hamburger span {
    display: block;
    width: 100%;
    height: 2px;
    background: var(--text, #fff);
    border-radius: 2px;
    transition: opacity 0.15s;
}
.coach-hamburger:hover span { opacity: 0.7; }

/* Overlay darkens content when mobile sidebar is open */
.coach-sidebar-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.55);
    z-index: 49;
    backdrop-filter: blur(1px);
}
.coach-sidebar-overlay.active { display: block; }

/* ── MAIN CONTENT ───────────────────────────────────────────── */
.coach-main {
    margin-left: var(--sidebar-w);
    flex: 1;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    min-width: 0;
    overflow-x: hidden;
}
.coach-topbar {
    background: var(--bg-card);
    border-bottom: 1px solid var(--border);
    padding: 16px 32px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    position: sticky;
    top: 0;
    z-index: 40;
}
.coach-topbar-title {
    font-family: var(--font-head);
    font-size: 1.1rem;
    font-weight: 800;
}
.coach-content {
    padding: 32px;
    flex: 1;
}

/* ── VIEW PANELS (routed by JS) ─────────────────────────────── */
.coach-view { display: none; }
.coach-view.active { display: block; }

/* ════════════════════════════════════════════════════════════
   CLIENT LIST (Dashboard view)
════════════════════════════════════════════════════════════ */
.client-list-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 24px;
    flex-wrap: wrap;
    gap: 12px;
}
.client-count {
    font-size: 0.82rem;
    color: var(--text-dim);
    font-family: var(--font-head);
    font-weight: 700;
    letter-spacing: 0.5px;
}
.client-list {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.client-row {
    display: grid;
    grid-template-columns: 1fr 120px 120px 100px 90px 90px;
    align-items: center;
    gap: 16px;
    padding: 14px 20px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    cursor: pointer;
    transition: border-color 0.12s, background 0.12s;
}
.client-row:hover { border-color: var(--border-mid); background: var(--bg-card-2); }
.client-name {
    font-weight: 600;
    font-size: 0.95rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.client-email {
    font-size: 0.78rem;
    color: var(--text-dim);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ── Client avatar ──────────────────────────────────────────────────────────
   Small accent-blue circle with white initials, used in two places:
   - Dashboard list row (small, alternating opacity for visual rhythm)
   - Per-client detail header (large, full opacity, solo)
   Initials come from coachInitials() in coach-state.js. */

.client-avatar {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--accent);
    color: #fff;
    font-family: var(--font-head);
    font-weight: 700;
    letter-spacing: 0.5px;
    user-select: none;
}
.client-avatar--sm {
    width: 32px;
    height: 32px;
    font-size: 0.78rem;
}
.client-avatar--lg {
    width: 48px;
    height: 48px;
    font-size: 1.05rem;
}

/* Alternate opacity inside the dashboard client list only. The :nth-child
   approach is intentional per spec — pure CSS, no JS bookkeeping. One known
   cosmetic regression: on mobile, when a row is tap-expanded, an
   .client-row-expanded-stats panel is inserted as a sibling, which shifts
   the :nth-child count for rows below it (alternation drifts after the
   first expand). Accepted tradeoff vs. a JS-driven .client-row--alt class
   that would survive the shift. The per-client detail view is unaffected
   because it lives outside .client-list. */
.client-list .client-row:nth-child(odd)  .client-avatar { opacity: 1; }
.client-list .client-row:nth-child(even) .client-avatar { opacity: 0.5; }

/* Subtle accent tint on odd rows reinforces the alternating-pair distinction
   (paired with the avatar opacity rules above). 8% accent is light enough
   not to compete with the row's content, dark enough to read as a band. */
.client-list .client-row:nth-child(odd) {
    background: color-mix(in srgb, var(--accent) 8%, transparent);
}

/* Flex wrappers for avatar + name+email layout, used in both views.
   min-width: 0 lets the inner text columns truncate via the existing
   .client-name / .client-dash-name text-overflow rules — without it,
   flex items default to min-content and ellipsis breaks. */
.client-name-cell,
.client-dash-name-cell {
    display: flex;
    align-items: center;
    gap: 12px;
    min-width: 0;
}
.client-name-stack,
.client-dash-name-stack {
    min-width: 0;
    flex: 1;
}

.client-stat {
    font-size: 0.82rem;
    color: var(--text-mid);
    text-align: right;
}
.client-stat-val {
    font-family: var(--font-head);
    font-weight: 700;
    font-size: 0.9rem;
    color: var(--text);
}
.client-stat-val.good  { color: var(--green); }
.client-stat-val.warn  { color: var(--yellow); }
.client-stat-val.bad   { color: var(--red); }
.client-status-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 0.72rem;
    font-family: var(--font-head);
    font-weight: 700;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    padding: 3px 9px;
    border-radius: 100px;
    border: 1px solid;
}
.badge-active   { color: var(--green);  border-color: rgba(60,186,108,0.35); background: rgba(60,186,108,0.08); }
.badge-pending  { color: var(--yellow); border-color: rgba(212,168,67,0.35); background: rgba(212,168,67,0.08); }
.badge-expiring { color: var(--yellow); border-color: rgba(212,168,67,0.35); background: rgba(212,168,67,0.08); }
.badge-revoked  { color: var(--text-dim); border-color: var(--border); background: transparent; }

/* List header row */
.client-list-cols {
    display: grid;
    grid-template-columns: 1fr 120px 120px 100px 90px 90px;
    gap: 16px;
    padding: 8px 20px;
    margin-bottom: 6px;
}
.client-list-col-label {
    font-size: 0.7rem;
    font-family: var(--font-head);
    font-weight: 700;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: var(--text-dim);
    text-align: right;
}
.client-list-col-label:first-child { text-align: left; }

/* Empty state */
.empty-state {
    text-align: center;
    padding: 80px 24px;
    color: var(--text-mid);
}
.empty-state-icon { font-size: 2.5rem; margin-bottom: 16px; opacity: 0.3; }
.empty-state-title {
    font-family: var(--font-head);
    font-size: 1.2rem;
    font-weight: 700;
    color: var(--text);
    margin-bottom: 8px;
}
.empty-state-desc { font-size: 0.9rem; color: var(--text-mid); margin-bottom: 28px; }

/* ════════════════════════════════════════════════════════════
   INVITE MODAL
════════════════════════════════════════════════════════════ */
.coach-modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.8);
    backdrop-filter: blur(6px);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 40px 20px;
    z-index: 200;
    overflow-y: auto;
}
.coach-modal {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 16px;
    width: 100%;
    max-width: 480px;
    margin: auto;
}
.coach-modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 20px 24px;
    border-bottom: 1px solid var(--border);
}
.coach-modal-title {
    font-family: var(--font-head);
    font-size: 1.1rem;
    font-weight: 800;
}
.coach-modal-close {
    background: transparent;
    border: none;
    color: var(--text-dim);
    font-size: 1.2rem;
    line-height: 1;
    padding: 0;
    transition: color 0.12s;
}
.coach-modal-close:hover { color: var(--text); }
.coach-modal-body { padding: 24px; }
.coach-modal-footer {
    padding: 16px 24px;
    border-top: 1px solid var(--border);
    display: flex;
    justify-content: flex-end;
    gap: 10px;
}

/* Section toggles in invite modal */
.section-toggles {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-top: 8px;
}
.section-toggle {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    cursor: pointer;
    transition: border-color 0.12s;
}
.section-toggle:hover { border-color: var(--border-mid); }
.section-toggle input[type="checkbox"] { accent-color: var(--accent); width: 15px; height: 15px; }
.section-toggle-label { font-size: 0.88rem; color: var(--text); flex: 1; }
.section-toggle-desc  { font-size: 0.75rem; color: var(--text-dim); }

/* ── LOADING SPINNER ────────────────────────────────────────── */
.coach-spinner {
    display: inline-block;
    width: 18px;
    height: 18px;
    border: 2px solid rgba(255,255,255,0.2);
    border-top-color: var(--accent);
    border-radius: 50%;
    animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.coach-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 80px;
    color: var(--text-dim);
    gap: 12px;
    font-size: 0.9rem;
}

/* ── TOASTS ─────────────────────────────────────────────────── */
#coach-toast {
    position: fixed;
    bottom: 24px;
    left: 50%;
    transform: translateX(-50%) translateY(80px);
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 100px;
    padding: 10px 20px;
    font-size: 0.85rem;
    color: var(--text);
    z-index: 999;
    transition: transform 0.3s ease-out, opacity 0.3s;
    opacity: 0;
    pointer-events: none;
    white-space: nowrap;
}
#coach-toast.show {
    transform: translateX(-50%) translateY(0);
    opacity: 1;
}
#coach-toast.toast-success { border-color: rgba(60,186,108,0.4); color: var(--green); }
#coach-toast.toast-error   { border-color: rgba(224,82,82,0.4);  color: var(--red); }

/* ── MOBILE ─────────────────────────────────────────────────── */
@media (max-width: 860px) {
    .coach-sidebar {
        transform: translateX(-100%);
        transition: transform 0.25s ease;
        z-index: 50;        /* above overlay */
    }
    .coach-sidebar.open { transform: translateX(0); }
    .coach-main { margin-left: 0; }
    .coach-content { padding: 20px 16px; }
    .client-topbar { padding: 14px 16px; }
    .client-list-cols { display: none; }

    /* Show hamburger on mobile */
    .coach-hamburger { display: flex; }

    /* Topbar: hamburger | title | actions */
    .coach-topbar {
        padding: 12px 16px;
        gap: 0;
    }

    /* Mobile client row — name | chevron */
    .client-row {
        grid-template-columns: 1fr auto;
        gap: 8px;
        align-items: center;
    }
    .client-stat { display: none; }

    /* Chevron */
    .client-row::after {
        content: '›';
        font-size: 1.3rem;
        color: var(--text-dim);
        transition: transform 0.2s;
        padding-left: 4px;
    }
    .client-row.expanded::after { transform: rotate(90deg); }

    /* Expanded stats panel */
    .client-row-expanded-stats {
        display: grid;
        grid-template-columns: 1fr 1fr 1fr;
        background: var(--bg-card-2);
        border: 1px solid var(--border);
        border-top: none;
        border-radius: 0 0 var(--radius) var(--radius);
        padding: 12px 16px;
        gap: 12px;
        margin-bottom: 4px;
    }
    .client-expanded-stat-label {
        font-size: 0.65rem;
        text-transform: uppercase;
        letter-spacing: 0.8px;
        color: var(--text-dim);
        font-family: var(--font-head);
        font-weight: 700;
        margin-bottom: 3px;
    }
    .client-expanded-stat-val {
        font-size: 0.9rem;
        font-weight: 700;
        color: var(--text);
    }
}

/* end mobile */

/* ════════════════════════════════════════════════════════════
   PER-CLIENT DASHBOARD
════════════════════════════════════════════════════════════ */

.client-dash-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    margin-bottom: 28px;
    flex-wrap: wrap;
    gap: 12px;
}
.client-dash-name {
    font-family: var(--font-head);
    font-size: 1.5rem;
    font-weight: 800;
    margin-bottom: 4px;
}
.client-dash-email { font-size: 0.85rem; color: var(--text-dim); }
.client-dash-updated {
    font-size: 0.75rem;
    color: var(--text-dim);
    font-family: var(--font-head);
    padding-top: 4px;
}

.client-sections {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

/* ── SECTION CARD ───────────────────────────────────────────── */
.client-section {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 24px;
}
.client-section-header {
    display: flex;
    align-items: baseline;
    gap: 10px;
    margin-bottom: 20px;
}
.client-section-title {
    font-family: var(--font-head);
    font-size: 1rem;
    font-weight: 800;
    color: var(--text);
}
.client-section-label {
    font-size: 0.75rem;
    color: var(--text-dim);
    font-family: var(--font-head);
    font-weight: 700;
    letter-spacing: 0.5px;
}
.client-section-subtitle {
    font-family: var(--font-head);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: var(--text-dim);
    margin: 30px 0 10px;
}
.client-section-empty {
    font-size: 0.85rem;
    color: var(--text-dim);
    margin-top: 12px;
}

/* ── LONGITUDINAL: PIE + BARS LAYOUT ─────────────────────────────────────────
   Pie on the left (~140px), bars on the right (flex-grow). Stacks vertically
   on mobile (≤600px) so neither half gets squeezed. The bars container is
   `min-width: 0` to let the inner grid columns truncate gracefully when the
   container shrinks — without it, the 75px+1fr+100px grid would force the
   parent to its content width and break wrapping.
   ─────────────────────────────────────────────────────────────────────── */
.coach-longitudinal-row {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 24px;
    margin-bottom: 12px;
}
.coach-longitudinal-pie {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
}
.coach-longitudinal-bars {
    flex: 1 1 auto;
    min-width: 0;
}

@media (max-width: 600px) {
    .coach-longitudinal-row {
        flex-direction: column;
        gap: 16px;
        align-items: stretch;
    }
    .coach-longitudinal-pie {
        align-self: center;
    }
}

/* ── DONUT CHART ─────────────────────────────────────────────────────────────
   SVG <circle> stack with stroke-dasharray slices. Hole text in the center
   shows total hours + "this week" label. Empty state (no slices) renders
   an outlined ring + em-dash placeholder. Title elements on each slice give
   coaches an exact-hours tooltip on hover.
   ─────────────────────────────────────────────────────────────────────── */
.coach-donut {
    display: block;
}
.coach-donut-total {
    font-family: var(--font-head);
    font-size: 1.4rem;
    font-weight: 700;
    fill: var(--text);
}
.coach-donut-label {
    font-size: 0.62rem;
    fill: var(--text-mid);
    letter-spacing: 0.6px;
    text-transform: uppercase;
}

/* ── BAR CHARTS ─────────────────────────────────────────────── */
.coach-bar-chart {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.coach-bar-row {
    display: grid;
    /* Grid was 90px / 1fr / 70px pre-fix. Tightened the left label column
       from 90px to 75px (still fits "This week" comfortably at 0.82rem) to
       give the right value column +30px (70 → 100) so the new "X / Y unit"
       format ("1795 / 2095 cal") fits without wrapping. The bar track loses
       15px in the middle — minor; tracks were always flexible. */
    grid-template-columns: 75px 1fr 100px;
    align-items: center;
    gap: 10px;
}
.coach-bar-row--sub {
    opacity: 0.7;
    margin-top: -4px;
}
.coach-bar-row--sub .coach-bar-label { font-size: 0.72rem; }
.coach-bar-label {
    font-size: 0.82rem;
    color: var(--text-mid);
    font-family: var(--font-head);
    font-weight: 700;
    text-align: right;
    white-space: nowrap;
}
.coach-bar-track {
    height: 8px;
    background: #1a1a1a;
    border-radius: 4px;
    overflow: hidden;
}
.coach-bar-fill {
    height: 100%;
    background: var(--accent);
    border-radius: 4px;
    width: 0%;
}
.coach-bar-fill.bar-good  { background: var(--green); }
.coach-bar-fill.bar-warn  { background: var(--yellow); }
.coach-bar-fill.bar-bad   { background: var(--red); }

/* ── DAILY 7-DAY BARS (coach-pro v3.2 §4.3) ─────────────────────────────────
   Mirrors the food panel's .report-weekly-bars pattern — vertical 7-column
   chart, today rightmost, accent-ringed. Same visual language as what the
   client sees on their food panel "This Week" tab; coaches see the same
   chart shape on the per-client dashboard. CLAUDE.md invariant #188 governs
   color rules (calorie/protein asymmetry — protein never penalized for over-
   goal). bar-neutral handles goal=0/null/missing days where compliance is
   undefined; never use it as a "default pretty grey" elsewhere.
   ─────────────────────────────────────────────────────────────────────── */

.coach-daily-bars {
    display: flex;
    gap: 6px;
    align-items: flex-end;     /* columns bottom-align so labels share a baseline */
    justify-content: center;   /* center the strip on wide desktop viewports
                                  so columns don't sprawl across 1200+px;
                                  pairs with .coach-daily-col max-width below */
    padding: 8px 0 4px;
    margin-bottom: 12px;
    overflow-x: auto;          /* graceful when 360px viewport squeezes 7 cols */
    -webkit-overflow-scrolling: touch;
}

.coach-daily-col {
    display: flex;
    flex-direction: column;
    align-items: center;
    flex: 1;
    min-width: 32px;           /* keeps bars finger-friendly on narrow phones */
    /* Cap column width on wide desktop — pre-cap, a 1200px-wide content
       area distributed 7 cols × ~160px each, leaving "giant gaps" between
       bars (per smoke-test feedback). 60px caps the column at ~3x mobile's
       natural width; with 22px bar + 6px gap, that's ~32px between bar
       edges on desktop vs ~10px on mobile. justify-content:center on the
       parent then centers the bounded strip instead of left-aligning it. */
    max-width: 60px;
    position: relative;
}

/* Today: 1px accent ring around the track so the eye lands on today
   without reading labels. Same treatment as food panel. */
.coach-daily-col--today .coach-daily-bar-track {
    box-shadow: 0 0 0 1px var(--accent, var(--accent-color));
}

.coach-daily-bar-track {
    width: 22px;
    height: 56px;
    background: color-mix(in srgb, var(--accent, var(--accent-color)) 50%, transparent);
    border-radius: 5px;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;  /* fills grow up from bottom */
    overflow: hidden;
    position: relative;
}

.coach-daily-bar-fill {
    width: 100%;
    border-radius: 5px;
    /* height set inline by JS — Number.isFinite-guarded; never NaN/Infinity */
    transition: height 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}

@media (prefers-reduced-motion: reduce) {
    .coach-daily-bar-fill { transition: none; }
}

/* Color modifier classes for the daily bars. Keep in sync with weekly
   .coach-bar-fill rules above. bar-neutral is only emitted by the daily
   path — weekly never produces a no-goal state. */
.coach-daily-bar-fill.bar-good     { background: var(--green); }
.coach-daily-bar-fill.bar-warn     { background: var(--yellow); }
.coach-daily-bar-fill.bar-bad      { background: var(--red); }
.coach-daily-bar-fill.bar-neutral  { background: var(--text-dim); opacity: 0.5; }

/* Empty-day placeholder — outlined bar shape sized identically to the track
   so the column lines up with non-empty siblings. No fill, no opacity:
   this is "didn't log" not "logged zero." */
.coach-daily-col--empty .coach-daily-bar-placeholder {
    width: 22px;
    height: 56px;
    border-radius: 5px;
    border: 1px solid color-mix(in srgb, var(--accent, var(--accent-color)) 50%, transparent);
}

/* Overage annotation — shown above bar when value > 115% of goal. Color
   inherited (or set inline) to match the bar's danger/warning treatment. */
.coach-daily-bar-overage {
    font-size: 0.58rem;
    font-weight: 600;
    /* Color set per .bar-{good|warn|bad|neutral} modifier below — inherits
       the bar's threshold so e.g. protein >115% reads green (the bar is
       bar-good per CLAUDE.md #188 asymmetry rule), not a contradicting red.
       Default fallback red preserved for any caller that forgets the
       modifier — fail loud, not silent grey. */
    color: var(--red);
    white-space: nowrap;
    line-height: 1;
    margin-bottom: 2px;
}

.coach-daily-bar-overage.bar-good     { color: var(--green); }
.coach-daily-bar-overage.bar-warn     { color: var(--yellow); }
.coach-daily-bar-overage.bar-bad      { color: var(--red); }
.coach-daily-bar-overage.bar-neutral  { color: var(--text-mid); }

/* Per-day under-bar text rows: weekday label, recorded value, target.
   Coach-pro is a data-rich surface — coaches need exact numbers alongside
   the bar's at-a-glance pattern. Hierarchy is via color, not size:
     - Value:  bright (#efefef ~94%, bold) — most important read
     - Day:    medium (#888 ~53%) — column anchor
     - Target: medium (#888 ~53%) — context for the value, slash prefix
                                    semantically separates it
   Font size 0.75rem across all three rows — tested at 100% browser zoom;
   readable without strain. tabular-nums ensures digits align column-to-
   column so a vertical scan reads cleanly across all 7 days. Always
   rendered (em-dash placeholder on empty/no-goal days) to keep the
   strip's vertical alignment consistent. */
.coach-daily-day-label,
.coach-daily-bar-value,
.coach-daily-bar-target {
    font-size: 0.75rem;
    line-height: 1.1;
    text-align: center;
    white-space: nowrap;
    font-feature-settings: "tnum";
    font-variant-numeric: tabular-nums;
}

.coach-daily-bar-value {
    font-size: 0.8rem;
}


.coach-daily-day-label {
    color: var(--text-mid, var(--text-muted));
    margin-top: 6px;
    padding-bottom: 6px;
}

.coach-daily-bar-value {
    color: var(--text);
    font-weight: 600;
    margin-top: 2px;
}

.coach-daily-bar-target {
    color: var(--text-mid, var(--text-muted));
    margin-top: 1px;
}
.coach-bar-val {
    font-family: var(--font-head);
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--text-mid);
    text-align: right;
}

/* ── EXERCISE LOGS ──────────────────────────────────────────── */
.exercise-log-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.exercise-log-row {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-rows: auto auto;
    gap: 2px 12px;
    padding: 10px 12px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 8px;
}
.exercise-log-meta {
    display: flex;
    align-items: center;
    gap: 10px;
    grid-column: 1;
}
.exercise-log-name {
    font-weight: 600;
    font-size: 0.88rem;
    color: var(--text);
}
.exercise-log-date {
    font-size: 0.75rem;
    color: var(--text-dim);
}
.exercise-log-text {
    font-size: 0.82rem;
    color: var(--text-mid);
    grid-column: 1;
}
.exercise-log-stars {
    font-size: 0.8rem;
    color: var(--accent);
    grid-column: 2;
    grid-row: 1 / 3;
    align-self: center;
    letter-spacing: 1px;
}

/* ── Recent Set Logs (coach-pro v3.2 §3, redesigned May 2026) ───────────────
   Date-grouped rollup: one card per date, exercises stacked inside, each
   set rendered as a blue accent pill. Mirrors the visual language of the
   end-user spotlight-more "Today" view (.spotlight-more-set-pill in
   spotlight-more.css) and the coach-panel inline editor — coach sees the
   same pills the client used to log, no new visual vocabulary to learn.
   Different slot from activityLog (.exercise-log-* above) — both blocks
   render back-to-back in the Fitness Compliance section per CLAUDE.md
   invariant #173.
   ─────────────────────────────────────────────────────────────────────── */
.set-log-list {
    display: flex;
    flex-direction: column;
    /* Tighter inter-card gap — pre-tightening this was 12px which doubled
       up vertical real estate when stacked. 6px keeps cards visually
       distinct (border helps) without bleeding space. */
    gap: 6px;
}

/* One <details> per date — collapsed by default except the most recent day,
   which renders with `open` attr from JS so the coach immediately sees the
   latest activity. Native <details>/<summary> gives keyboard-accessible
   expand/collapse without JS event handlers. */
.set-log-day {
    padding: 0;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    overflow: hidden;
}
.set-log-day-header {
    cursor: pointer;
    user-select: none;
    list-style: none;          /* hide native triangle (Firefox) */
    display: flex;
    align-items: center;
    gap: 10px;
    /* Tightened 12px 14px → 8px 12px to reduce per-row height; with 14 days
       in the strip, the savings stack to ~100px vertical. */
    padding: 8px 12px;
    /* Font size tightened 0.88 → 0.82rem — still bold enough to read as
       a header against the dim count meta on the right. */
    font-size: 0.82rem;
    font-weight: 700;
    color: var(--text);
    letter-spacing: 0.2px;
}
/* Chrome/Safari native marker — hide so our chevron is the only indicator. */
.set-log-day-header::-webkit-details-marker { display: none; }

/* CSS-triangle chevron — points right when collapsed, rotates to point down
   when the day is expanded. Lighter weight than a unicode glyph or SVG. */
.set-log-day-chevron {
    display: inline-block;
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 5px 0 5px 7px;
    border-color: transparent transparent transparent var(--text-mid);
    transition: transform 0.2s ease;
    flex-shrink: 0;
}
.set-log-day[open] > .set-log-day-header > .set-log-day-chevron {
    transform: rotate(90deg);
}

/* Push the count meta to the right of the date label. */
.set-log-day-date  { flex: 1; }
.set-log-day-count {
    font-size: 0.75rem;
    color: var(--text-dim);
    font-weight: 500;
}

/* Body wrapper — gives the exercises consistent inset from the header
   regardless of the <details> internal padding. Tightened 14px → 12px
   horizontal and 14px → 10px bottom to shave another ~6px off each
   expanded card. */
.set-log-day-body {
    padding: 0 12px 10px;
}

/* Exercise block within a day — name, then row of pills. */
.set-log-exercise {
    margin-top: 10px;
}
.set-log-exercise:first-of-type {
    margin-top: 0;
}
.set-log-exercise-name {
    font-size: 0.85rem;
    color: var(--text-mid);
    font-weight: 600;
    margin-bottom: 6px;
}

/* Pill row — flex-wraps to multiple lines when 4+ pills don't fit on one. */
.coach-set-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

/* Set pill — color/sizing mirrored from .spotlight-more-set-pill in
   spotlight-more.css line 84 (read-only display, no cursor:pointer or
   hover state since these aren't interactive in the coach view). */
.coach-set-pill {
    display: inline-flex;
    align-items: center;
    background: color-mix(in srgb, var(--accent) 18%, transparent);
    border: 1px solid var(--accent);
    color: var(--accent);
    border-radius: 20px;
    padding: 5px 12px;
    font-size: 0.85rem;
    font-weight: 600;
    white-space: nowrap;
}

/* ── WEIGHT ─────────────────────────────────────────────────── */
.weight-summary {
    display: flex;
    align-items: baseline;
    gap: 16px;
    margin-bottom: 12px;
    flex-wrap: wrap;
}
.weight-current {
    font-family: var(--font-head);
    font-size: 2rem;
    font-weight: 800;
    color: var(--text);
}
.weight-delta {
    font-family: var(--font-head);
    font-size: 0.9rem;
    font-weight: 700;
}
.weight-sparkline { margin-bottom: 4px; }

/* viewBox width is computed in JS to match screen width exactly,
   so the SVG fills its container with ~1:1 px mapping.
   Height is fixed — only the x spacing grows on wider screens.
   vector-effect keeps stroke width crisp at any scale. */
.weight-sparkline-svg {
    display: block;
    width: 100%;
    height: 180px;
    overflow: visible;
}
.weight-labels {
    display: flex;
    justify-content: space-between;
    font-size: 0.7rem;
    color: var(--text-dim);
    font-family: var(--font-head);
}

/* ════════════════════════════════════════════════════════════
   PROGRAM BUILDER
════════════════════════════════════════════════════════════ */

/* ── Header ─────────────────────────────────────────────────── */
.prog-builder-header {
    margin-bottom: 24px;
}
.prog-builder-title-row {
    display: flex;
    align-items: baseline;
    gap: 12px;
    margin-bottom: 4px;
}
.prog-builder-title {
    font-family: var(--font-head);
    font-size: 1.4rem;
    font-weight: 800;
}
.prog-builder-meta {
    font-size: 0.8rem;
    color: var(--text-dim);
    font-family: var(--font-head);
    font-weight: 700;
}
.prog-builder-notes {
    font-size: 0.85rem;
    color: var(--text-mid);
    margin-top: 4px;
}

/* ── Week / Day grid ────────────────────────────────────────── */
.prog-weeks {
    display: flex;
    flex-direction: column;
    gap: 24px;
}
.prog-week-label {
    font-family: var(--font-head);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: var(--text-dim);
    margin-bottom: 10px;
}
.prog-days {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 8px;
    overflow-x: auto;
}

/* ── Day card ───────────────────────────────────────────────── */
.prog-day-card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 14px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-height: 120px;
    min-width: 150px;
}
.prog-day-card--rest {
    opacity: 0.7;
}
.prog-day-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.prog-day-label {
    font-family: var(--font-head);
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--text);
}
.prog-rest-toggle {
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: 0.72rem;
    color: var(--text-dim);
    cursor: pointer;
    user-select: none;
}
.prog-rest-toggle input { accent-color: var(--accent); }
.prog-rest-label {
    font-family: var(--font-head);
    font-size: 1.4rem;
    font-weight: 800;
    color: var(--text-mid);
    text-align: center;
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    letter-spacing: -0.5px;
}

/* ── Exercise list in day card ──────────────────────────────── */
.prog-ex-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
    flex: 1;
}
.prog-ex-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 6px;
}
.prog-ex-info { flex: 1; min-width: 0; }
.prog-ex-name {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.prog-ex-detail {
    font-size: 0.68rem;
    color: var(--text-dim);
    margin-top: 1px;
}
.prog-ex-remove {
    background: transparent;
    border: none;
    cursor: pointer;
    padding: 2px 4px;
    flex-shrink: 0;
    /* Icon is a child <span>, not text — flex centers the 14×14 icon
       inside the button's clickable padding box. color/font-size removed
       since there's no text content anymore; the icon's color is driven
       by background-color on .prog-ex-remove-icon below. */
    display: inline-flex;
    align-items: center;
}

/* Trash icon for the exercise-remove button. Uses mask-image rather than
   background-image (the pattern used by the Back/Assign buttons) because
   we need a two-color hover transition: text-dim → red. With mask-image,
   the visible colour is set by background-color, so a simple
   transitioned color swap on hover works. With background-image we'd be
   stuck with a single tinted PNG plus opacity tricks, which can't match
   --red precisely.
   Atlas geometry (total height + this row's Y) is the single source of truth
   in assets_art_and_animation.json; coach-state.js hydrates it into the CSS
   vars --ui-atlas-h and --ui-y-ui_trash_icon (see app/claude-ui-atlas.md).
   ui_trash_icon is currently row 20 → native y=320, atlas height 720. We
   render at 14×14 (slightly smaller than the atlas's intrinsic 16×16) to fit
   the existing 0.7rem button footprint without enlarging the row, so the mask
   is scaled by 14/16 = 0.875:
       mask-size:     14 × (atlas-h × 0.875)   → 14 × 630 today
       mask-position: 0 × −(trash-y × 0.875)   → 0 −280 today
   The var() fallbacks equal today's values, so this renders correctly even
   if the hydrate fetch fails; when the atlas changes, the vars track it.
   The -webkit-mask-* aliases are required for Safari (still treats
   mask-* as experimental on some versions). */
.prog-ex-remove-icon {
    display: inline-block;
    width: 14px;
    height: 14px;
    background-color: var(--text-dim);
    -webkit-mask-image: url('../app/assets_art/atlas_ui_icons.png');
            mask-image: url('../app/assets_art/atlas_ui_icons.png');
    -webkit-mask-size: 14px calc(var(--ui-atlas-h, 720px) * 0.875);
            mask-size: 14px calc(var(--ui-atlas-h, 720px) * 0.875);
    -webkit-mask-position: 0 calc(var(--ui-y-ui_trash_icon, 320px) * -0.875);
            mask-position: 0 calc(var(--ui-y-ui_trash_icon, 320px) * -0.875);
    -webkit-mask-repeat: no-repeat;
            mask-repeat: no-repeat;
    transition: background-color 0.12s;
}
.prog-ex-remove:hover .prog-ex-remove-icon { background-color: var(--red); }
.prog-add-ex-btn {
    background: transparent;
    border: 1px dashed var(--border-mid);
    border-radius: 6px;
    color: var(--text-dim);
    font-size: 0.75rem;
    font-family: var(--font-head);
    font-weight: 700;
    padding: 6px;
    cursor: pointer;
    transition: border-color 0.12s, color 0.12s;
    text-align: center;
    width: 100%;
}
.prog-add-ex-btn:hover {
    border-color: var(--accent);
    color: var(--accent);
}

/* ── Exercise picker sidebar ────────────────────────────────── */
.prog-picker-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.5);
    z-index: 100;
}
.prog-picker {
    position: fixed;
    top: 0;
    right: 0;
    width: 380px;
    height: 100vh;
    background: var(--bg-card);
    border-left: 1px solid var(--border);
    z-index: 101;
    display: flex;
    flex-direction: column;
}
.prog-picker-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 18px 20px;
    border-bottom: 1px solid var(--border);
}
.prog-picker-title {
    font-family: var(--font-head);
    font-size: 1rem;
    font-weight: 800;
}
.prog-picker-search {
    padding: 14px 16px;
    border-bottom: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.prog-picker-filters {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}
.prog-filter-select {
    flex: 1;
    min-width: 100px;
    background: var(--bg-input);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 6px 8px;
    color: var(--text);
    font-size: 0.75rem;
    font-family: var(--font-body);
    outline: none;
}
.prog-filter-select:focus { border-color: var(--accent); }
.prog-picker-results {
    flex: 1;
    overflow-y: auto;
    padding: 8px 0;
}
.prog-ex-result {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 16px;
    border-bottom: 1px solid var(--border);
    transition: background 0.1s;
}
.prog-ex-result:hover { background: var(--bg-card-2); }
.prog-ex-result-info { flex: 1; min-width: 0; }
.prog-ex-result-name {
    font-size: 0.84rem;
    font-weight: 600;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.prog-ex-result-meta {
    display: flex;
    gap: 6px;
    margin-top: 2px;
}
.prog-ex-result-meta span {
    font-size: 0.68rem;
    color: var(--text-dim);
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 4px;
    padding: 1px 5px;
}

/* ── Program builder extra styles ───────────────────────────── */
.prog-week-header {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 10px;
}
.prog-week-header .prog-week-label { margin-bottom: 0; }

/* Template cards */
.prog-template-card {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 16px 24px;
    border-bottom: 1px solid var(--border);
    transition: background 0.1s;
}
.prog-template-card:last-child { border-bottom: none; }
.prog-template-card:hover { background: var(--bg-card-2); }
.prog-template-info { flex: 1; }
.prog-template-name {
    font-family: var(--font-head);
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--text);
    margin-bottom: 3px;
}
.prog-template-desc {
    font-size: 0.78rem;
    color: var(--text-mid);
    line-height: 1.4;
    margin-bottom: 4px;
}
.prog-template-meta {
    font-size: 0.7rem;
    color: var(--text-dim);
    font-family: var(--font-head);
    font-weight: 700;
    letter-spacing: 0.5px;
}
.prog-ai-card {
    background: var(--accent-dim);
    border-top: 1px solid rgba(70,165,206,0.2);
}
.prog-ai-card:hover { background: rgba(70,165,206,0.12); }
.prog-ai-card .prog-template-name { color: var(--accent); }

/* ── Day focus label ────────────────────────────────────────── */
.prog-day-focus {
    font-size: 0.7rem;
    color: var(--accent);
    font-family: var(--font-head);
    font-weight: 700;
    letter-spacing: 0.5px;
    margin-top: 1px;
}

/* Override .btn-sm padding/font-size for the Back button so its rendered
   height matches .prog-assign-btn (which is sized independently of .btn).
   Without this the Back button is shorter and sits lower than Assign,
   even though both share the same flex row. Match the Assign values
   exactly — padding 10px 18px, font-size 0.88rem — so the two buttons
   align on a common baseline. */
#prog-back-btn.btn-sm { padding: 10px 18px; font-size: 0.88rem; }

/* ── Assign to client button ────────────────────────────────── */
.prog-assign-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--green);
    color: #fff;
    border: none;
    border-radius: 8px;
    padding: 10px 18px;
    font-family: var(--font-head);
    font-weight: 700;
    font-size: 0.88rem;
    cursor: pointer;
    transition: filter 0.15s;
    /* Was margin-top: 24px — that pushed Assign below Back's baseline,
       creating a stair-step. Now that #prog-back-btn matches Assign's
       height, both buttons sit on the same y-axis with no offset. */
    margin-top: 0;
}
.prog-assign-btn:hover { filter: brightness(1.1); }

/* ── Atlas icons for Back / Assign buttons ──────────────────────────────────
   References the UI icon atlas maintained in /app/assets_art/. The /coach/
   portal doesn't ship its own copy of the atlas — single-source-of-truth
   lives in /app/, see app/claude-ui-atlas.md for the full system docs.
   Atlas geometry comes from assets_art_and_animation.json; coach-state.js
   hydrates it into CSS vars (--ui-atlas-h for the total height, --ui-y-<stem>
   per row) so these rules never hardcode the height again. Row offsets used:
       ui_back_icon    → y = 32   (row 2,  back/"Programs" button)
       ui_forward_icon → y = 448  (row 28, Assign button)
   var() fallbacks equal today's values (height 720), so the buttons render
   correctly even before the hydrate fetch lands or if it fails.
   We avoid Unicode arrow glyphs (← / ↗) here because iOS Safari falls
   through to the emoji font and renders them as oversized colored emoji
   that don't match the button typography. */

.prog-back-icon,
.prog-assign-icon {
    display: inline-block;
    width: 16px;
    height: 16px;
    background-image: url('../app/assets_art/atlas_ui_icons.png');
    background-size: 16px var(--ui-atlas-h, 720px);
    background-repeat: no-repeat;
    flex-shrink: 0;
}

/* Back button is .btn-ghost — text-mid (#888) at rest, text (#efefef) on
   hover. Approximate the same value progression for the icon via opacity
   on a brightness(0) invert(1) (force-white) source. */
.prog-back-icon {
    background-position: 0 calc(var(--ui-y-ui_back_icon, 32px) * -1);
    filter: brightness(0) invert(1);
    opacity: 0.65;
    transition: opacity 0.15s;
}
.btn-ghost:hover .prog-back-icon { opacity: 1; }

/* Assign button is white text on green — pure white icon. */
.prog-assign-icon {
    background-position: 0 calc(var(--ui-y-ui_forward_icon, 448px) * -1);
    filter: brightness(0) invert(1);
}

/* ── Days-per-week selector ─────────────────────────────────── */
.prog-days-selector {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
}
.prog-days-selector-label {
    font-size: 0.72rem;
    color: var(--text-dim);
    font-family: var(--font-head);
    font-weight: 700;
    letter-spacing: 0.5px;
    margin-right: 4px;
}
.prog-days-selector-btn {
    width: 28px;
    height: 28px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text-dim);
    font-size: 0.78rem;
    font-family: var(--font-head);
    font-weight: 700;
    cursor: pointer;
    transition: all 0.12s;
    display: flex;
    align-items: center;
    justify-content: center;
}
.prog-days-selector-btn:hover { border-color: var(--accent); color: var(--text); }
.prog-days-selector-btn.active {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}

/* ── Picker drag handle ─────────────────────────────────────── */
.prog-picker-drag-handle {
    position: absolute;
    left: -12px;
    top: 50%;
    transform: translateY(-50%);
    width: 12px;
    height: 48px;
    background: var(--border-mid);
    border-radius: 4px 0 0 4px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: ew-resize;
    color: var(--text-dim);
    font-size: 0.7rem;
    transition: background 0.12s;
}
.prog-picker-drag-handle:hover { background: var(--accent); color: #fff; }

/* ── Exercise result name — show full on hover ──────────────── */
.prog-ex-result-name {
    font-size: 0.84rem;
    font-weight: 600;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: default;
    transition: white-space 0.15s;
}
.prog-ex-result:hover .prog-ex-result-name {
    white-space: normal;
    word-break: break-word;
}

/* ── Exercise picker pagination ─────────────────────────────── */
.prog-picker-pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 12px 16px;
    border-top: 1px solid var(--border);
    background: var(--bg-card);
    position: sticky;
    bottom: 0;
}
.prog-page-btn {
    background: var(--bg-card);
    border: 1px solid var(--border-mid);
    border-radius: 6px;
    color: var(--text);
    width: 32px;
    height: 32px;
    font-size: 0.9rem;
    cursor: pointer;
    transition: all 0.12s;
    display: flex;
    align-items: center;
    justify-content: center;
}
.prog-page-btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.prog-page-btn:disabled { opacity: 0.3; cursor: not-allowed; }

/* ── Focus selector strip (replaces Rest checkbox) ──────────────────── */
.prog-focus-strip {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-bottom: 6px;
}
.prog-focus-btn {
    padding: 3px 8px;
    border-radius: 100px;
    border: 1px solid var(--border);
    background: transparent;
    color: var(--text-dim);
    font-size: 0.65rem;
    font-family: var(--font-head);
    font-weight: 700;
    letter-spacing: 0.3px;
    cursor: pointer;
    transition: all 0.12s;
    white-space: nowrap;
}
.prog-focus-btn:hover {
    border-color: var(--accent);
    color: var(--text);
}
.prog-focus-btn.active {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}
/* Rest Day pill no longer gets a muted override — it inherits the default
   accent-blue active state above so the coach can clearly see when Rest is
   the current selection. The earlier muted treatment was reported as making
   Rest look unselected, undermining the prompt to flip away from it. The
   Off pill never had an override; both Rest and Off now render in accent
   blue when active, matching every other focus pill. See coach-pro.md
   April 27 2026. */

/* ── Google OAuth button ─────────────────────────────────────────────────── */
.btn-google {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    width: 100%;
    padding: 12px;
    background: #1a1a1a;
    color: #efefef;
    border: 1px solid rgba(255,255,255,0.15);
    border-radius: 8px;
    font-family: inherit;
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
    margin-bottom: 4px;
}
.btn-google:hover { background: #252525; border-color: rgba(255,255,255,0.3); }

.auth-divider {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 16px 0;
    color: var(--text-dim);
    font-size: 0.75rem;
}
.auth-divider::before,
.auth-divider::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--border);
}

/* ════════════════════════════════════════════════════════════
   ADMIN IMPERSONATION — banner, admin view, break-glass modal
   See coach-admin-impersonation-prd.md §6 and coach/coach-admin.js.

   Banner geometry uses --impersonation-banner-h declared on :root.
   Three places reference the height: the banner itself, the body's
   padding-top compensation while impersonating, and the offset/height
   of the fixed sidebar so it doesn't vanish behind the amber bar.
════════════════════════════════════════════════════════════ */

/* ── Banner ─────────────────────────────────────────────────── */
.coach-impersonation-banner {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: var(--impersonation-banner-h);
    z-index: 100;                                /* above sidebar (50) and topbar (40) */
    background: linear-gradient(180deg, var(--banner-amber-2), var(--banner-amber));
    color: var(--banner-amber-text);
    border-bottom: 1px solid rgba(0, 0, 0, 0.25);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 0 20px;
    font-family: var(--font-body);
    font-size: 0.85rem;
    line-height: 1.2;
}
.coach-impersonation-banner__lens {
    display: flex;
    align-items: baseline;
    gap: 8px;
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}
.coach-impersonation-banner__label {
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 0.7rem;
    opacity: 0.78;
}
.coach-impersonation-banner__name {
    font-weight: 800;
    font-family: var(--font-head);
    font-size: 0.95rem;
}
.coach-impersonation-banner__email {
    opacity: 0.78;
    overflow: hidden;
    text-overflow: ellipsis;
}
.coach-impersonation-banner__countdown {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    opacity: 0.9;
    flex-shrink: 0;
}
.coach-impersonation-banner__end-btn {
    background: rgba(0, 0, 0, 0.85);
    color: #fff;
    border: 1px solid rgba(0, 0, 0, 0.5);
    border-radius: 6px;
    padding: 6px 14px;
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
    flex-shrink: 0;
    transition: filter 0.12s, transform 0.12s;
}
.coach-impersonation-banner__end-btn:hover { filter: brightness(1.2); transform: translateY(-1px); }
.coach-impersonation-banner__end-btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }

/* Body modifier — applied/removed by coach-admin.js. Shifts the rest
   of the layout down so nothing hides behind the fixed amber bar. */
body.coach-impersonating { padding-top: var(--impersonation-banner-h); }
body.coach-impersonating .coach-sidebar {
    top: var(--impersonation-banner-h);
    height: calc(100vh - var(--impersonation-banner-h));
    height: calc(100dvh - var(--impersonation-banner-h));
}

/* ── Admin view (#view-admin) ───────────────────────────────── */
.admin-section {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 20px 24px;
    margin-bottom: 20px;
}
.admin-section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: 12px;
    gap: 12px;
}
.admin-section-title {
    font-family: var(--font-head);
    font-size: 1rem;
    font-weight: 800;
    margin-bottom: 12px;
}
.admin-section-head .admin-section-title { margin-bottom: 0; }
.admin-section-sub {
    font-size: 0.78rem;
    color: var(--text-dim);
}
.admin-search-input { width: 100%; }
.admin-search-results {
    margin-top: 12px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.admin-search-result {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 12px;
    background: var(--bg-card-2);
    border: 1px solid var(--border);
    border-radius: 8px;
}
.admin-search-result-info { min-width: 0; }
.admin-search-result-name {
    font-weight: 600;
    font-size: 0.9rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.admin-search-result-email {
    font-size: 0.78rem;
    color: var(--text-dim);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.admin-empty {
    color: var(--text-dim);
    font-size: 0.85rem;
    padding: 8px 0;
}

/* Audit log activity list */
.admin-activity {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.admin-activity-row {
    background: var(--bg-card-2);
    border: 1px solid var(--border);
    border-radius: 6px;
}
.admin-activity-row > summary {
    list-style: none;
    cursor: pointer;
    padding: 8px 12px;
    display: grid;
    grid-template-columns: minmax(120px, max-content) auto 1fr auto;
    align-items: center;
    gap: 10px;
    font-size: 0.82rem;
}
.admin-activity-row > summary::-webkit-details-marker { display: none; }
.admin-activity-row[open] > summary { border-bottom: 1px solid var(--border); }
.admin-activity-action {
    font-weight: 600;
    color: var(--accent);
    font-family: var(--font-body);
}
.admin-activity-surface {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-dim);
    background: var(--bg-input);
    padding: 2px 6px;
    border-radius: 4px;
}
.admin-activity-target {
    color: var(--text);
    font-weight: 500;
}
.admin-activity-time {
    color: var(--text-dim);
    font-size: 0.75rem;
    text-align: right;
    font-variant-numeric: tabular-nums;
}
.admin-activity-payload {
    margin: 0;
    padding: 12px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.75rem;
    color: var(--text-mid);
    background: var(--bg-input);
    overflow-x: auto;
    white-space: pre;
}

/* ── Break-glass modal content (uses .coach-modal-* shell) ─── */
.impersonate-target-label {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-dim);
    margin-bottom: 6px;
}
.impersonate-target-display {
    background: var(--bg-input);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 10px 12px;
    font-size: 0.9rem;
}
.impersonate-target-display strong {
    font-weight: 700;
    margin-right: 8px;
}
.impersonate-target-email {
    color: var(--text-dim);
    font-size: 0.8rem;
}
.impersonate-examples {
    margin-top: 10px;
    font-size: 0.78rem;
}
.impersonate-examples-heading {
    color: var(--text-dim);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 0.7rem;
    margin-bottom: 4px;
}
.impersonate-examples ul {
    margin: 0;
    padding-left: 18px;
    color: var(--text-mid);
    line-height: 1.6;
}
.form-help {
    margin-top: 6px;
    font-size: 0.75rem;
    color: var(--text-dim);
    line-height: 1.4;
}

/* ── Mobile (matches existing 860px breakpoint) ─────────────── */
@media (max-width: 860px) {
    .coach-impersonation-banner {
        padding: 0 12px;
        gap: 10px;
        font-size: 0.78rem;
    }
    .coach-impersonation-banner__email { display: none; }   /* keep name + countdown + end-btn on one line */
    .coach-impersonation-banner__name  { font-size: 0.85rem; }
    .coach-impersonation-banner__end-btn { padding: 5px 10px; font-size: 0.75rem; }

    .admin-section { padding: 16px; }
    .admin-activity-row > summary {
        grid-template-columns: 1fr auto;
        row-gap: 4px;
    }
    .admin-activity-surface, .admin-activity-time {
        grid-column: 2;
        justify-self: end;
    }
}


/* ── Referral Share Card (Phase 1 — Coach Partner Program referral mechanics) ── */
/* Renders at the top of the dashboard view; spec: monetize-coach-referral-spec.md v3 */

/* Referral link content inside the My Clients .coach-section card.
   The old standalone .referral-card flex wrapper is gone — the section
   card provides the outer styling now. These classes style the inner
   URL display, hint text, and the 3-button action row. */
.referral-card-url {
    font-family: monospace;
    font-size: 0.95rem;
    color: var(--accent, #46a5ce);
    cursor: pointer;
    word-break: break-all;
    line-height: 1.4;
    user-select: all;
}
.referral-card-url:hover { text-decoration: underline; }
.referral-card-hint {
    font-size: 0.82rem;
    color: var(--text-mid);
    margin-top: 10px;
    line-height: 1.5;
}
/* Action row — 3 buttons inline (Share / Test / + Invite Client).
   Wraps on narrow viewports so buttons don't overflow. */
.referral-card-actions {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 18px;
}
.referral-card-actions .btn {
    white-space: nowrap;
}
.referral-card-empty {
    padding: 14px 20px;
    margin: 0 0 18px;
    background: var(--bg-card, #1a1a1a);
    border: 1px dashed var(--border, rgba(255,255,255,0.08));
    border-radius: 10px;
    font-size: 0.85rem;
    color: var(--text-dim, #888);
    text-align: center;
    line-height: 1.5;
}
@media (max-width: 600px) {
    .referral-card-actions {
        gap: 6px;
    }
    .referral-card-actions .btn {
        flex: 1 1 calc(50% - 6px);   /* roughly 2 per row on tight screens */
    }
}

/* ── Programs Section (May 23 2026) ─────────────────────────────────────── */
/* Renders between Body Weight and Fitness Compliance on the client dashboard. */
/* Per-program: name + progress bar + completion counts + assigned/end dates. */
/* Visual conventions match existing .client-section / .coach-bar-* patterns. */

.coach-program-list {
    display: flex;
    flex-direction: column;
    gap: 18px;
}
.coach-program-row {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.coach-program-row-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
}
.coach-program-name {
    font-family: var(--font-head, inherit);
    font-weight: 700;
    font-size: 0.95rem;
    color: var(--text-main, #fff);
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.coach-program-stats {
    font-size: 0.8rem;
    color: var(--text-dim, #888);
    flex-shrink: 0;
    white-space: nowrap;
}
.coach-program-bar-track {
    /* Inherits .coach-bar-track height/background; just full-width inside the
       program row (no label/value flanking it like in compliance bars). */
    flex: none;
    width: 100%;
}
.coach-program-meta {
    font-size: 0.78rem;
    color: var(--text-dim, #888);
    letter-spacing: 0.2px;
}

@media (max-width: 600px) {
    .coach-program-row-head {
        flex-direction: column;
        align-items: flex-start;
        gap: 2px;
    }
    .coach-program-name {
        font-size: 0.9rem;
    }
}

/* ════════════════════════════════════════════════════════════
   ADMIN — Recent account viewings session rows
   Each row pairs an impersonation start with its matching end,
   replacing the older per-event audit-log row format.
════════════════════════════════════════════════════════════ */

.admin-session-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 14px 20px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    margin-bottom: 8px;
}
.admin-session-name {
    font-weight: 600;
    font-size: 0.95rem;
    color: var(--text);
}
.admin-session-times {
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: 0.82rem;
    color: var(--text-mid);
    text-align: right;
}
.admin-session-time-row {
    white-space: nowrap;
}
.admin-session-time-label {
    color: var(--text-dim);
    font-weight: 600;
    margin-right: 6px;
}
.admin-session-time-active {
    color: var(--green);
    font-weight: 600;
}
@media (max-width: 600px) {
    .admin-session-row {
        flex-direction: column;
        align-items: flex-start;
        gap: 10px;
        padding: 12px 16px;
    }
    .admin-session-times {
        text-align: left;
        width: 100%;
    }
}

/* ════════════════════════════════════════════════════════════
   COACH PANEL — shared section/card pattern
   Used by both Settings (Profile / Payouts / Account cards) and the
   My Clients dashboard (Referral link / Your clients cards). One
   visual language across the panel so every page feels consistent.
   .settings-section is an alias kept for backward compatibility.
════════════════════════════════════════════════════════════ */

.settings-page {
    max-width: 540px;
}
/* Section card — padding lives on the body now, not the card, so the header
   can have its own lighter bg that goes edge-to-edge inside the rounded card.
   overflow:hidden clips the header bg to the card's rounded corners. */
.coach-section,
.settings-section {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
    margin-bottom: 20px;
}
/* Header strip — lighter bg + bottom border give clear visual separation
   from the body. Padding lives here (not on the section) so the bg fills
   the strip edge-to-edge. Uses --bg-card-header (dedicated header tone,
   ~12% lighter than card body) so the separation is clearly perceivable. */
.coach-section-header,
.settings-section-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 16px 28px;
    background: var(--bg-card-header);
    border-bottom: 1px solid var(--border-mid);
}
/* Wraps icon + title together on the LEFT so they read as a group.
   Without this wrapper, justify-content:space-between would push the
   icon and title to opposite ends of the header — see the May 2026
   fix described in the Settings UI changelog. */
.settings-section-header-left,
.coach-section-header-left {
    display: flex;
    align-items: center;
    gap: 12px;
    min-width: 0;
}
/* Emojis must never receive the accent filter — they show true colors
   (same rule as .mood-face-img and emoji-picker icons across the app). */
.settings-section-icon {
    font-size: 1.3rem;
    line-height: 1;
    filter: none !important;
}
.coach-section-title,
.settings-section-title {
    font-family: var(--font-head);
    font-weight: 800;
    font-size: 1.05rem;
    color: var(--text);
    letter-spacing: -0.3px;
}
/* Right-aligned subtle counter next to a section title (e.g. "Your clients
   · 1 CLIENT"). Sits opposite the title in the flex header row. */
.coach-section-count {
    font-size: 0.78rem;
    color: var(--text-dim);
    font-family: var(--font-head);
    font-weight: 700;
    letter-spacing: 0.5px;
    text-transform: uppercase;
}
/* Body — owns the inner padding. The section card itself has no padding
   so the header strip can sit flush against the card edges. */
.coach-section-body,
.settings-section-body {
    padding: 24px 28px;
}
/* Tertiary "soft accent" button — dim accent fill + accent border.
   Sits between btn-primary (filled accent) and btn-secondary (white outline)
   in visual weight. Used on the My Clients dashboard for + Invite Client
   so it reads as a third distinct action alongside Share / Test. */
.btn-accent-soft {
    background: color-mix(in srgb, var(--accent) 18%, transparent);
    color: var(--text);
    border: 1px solid color-mix(in srgb, var(--accent) 55%, transparent);
}
.btn-accent-soft:hover {
    background: color-mix(in srgb, var(--accent) 28%, transparent);
    border-color: var(--accent);
}
@media (max-width: 600px) {
    .coach-section,
    .settings-section {
        margin-bottom: 16px;
    }
    .coach-section-header,
    .settings-section-header {
        padding: 14px 18px;
    }
    .coach-section-body,
    .settings-section-body {
        padding: 20px 18px;
    }
}

/* ════════════════════════════════════════════════════════════
   EARNINGS VIEW
   Used by:
     - /coach/index.html   #view-earnings  (live tab)
     - /coach/earnings-demo.html           (preview / screenshots)
   Single source of truth — no inline duplicate styles.
════════════════════════════════════════════════════════════ */

.earnings-view { max-width: 880px; }

.earnings-kpi-card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 36px 32px 28px;
    margin-bottom: 32px;
    position: relative;
    overflow: hidden;
}
.earnings-kpi-card::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 3px;
    background: var(--accent);
}

/* ── Hero this-month KPI ─────────────────────────────────── */
.earnings-hero {
    text-align: center;
    padding-bottom: 28px;
    margin-bottom: 24px;
    border-bottom: 1px solid var(--border);
}
.earnings-hero-label {
    font-size: 0.72rem;
    font-family: var(--font-head);
    font-weight: 700;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: var(--text-dim);
    margin-bottom: 12px;
}
.earnings-hero-value {
    font-family: var(--font-head);
    font-weight: 800;
    font-size: 4.2rem;
    line-height: 1;
    color: var(--accent);
    letter-spacing: -2px;
}
.earnings-hero-value .currency {
    font-size: 2.8rem;
    vertical-align: top;
    margin-right: 4px;
    letter-spacing: 0;
}
.earnings-hero-sub {
    font-size: 0.82rem;
    color: var(--text-mid);
    margin-top: 10px;
}

/* ── Secondary stats row ─────────────────────────────────── */
.earnings-secondary-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 32px;
    margin-bottom: 24px;
}
.earnings-stat {
    min-width: 0;
}
.earnings-stat-label {
    font-size: 0.7rem;
    font-family: var(--font-head);
    font-weight: 700;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: var(--text-dim);
    margin-bottom: 6px;
}
.earnings-stat-value {
    font-family: var(--font-head);
    font-weight: 700;
    font-size: 1.5rem;
    line-height: 1.1;
    color: var(--text);
}
.earnings-stat-helper {
    font-size: 0.74rem;
    color: var(--text-dim);
    margin-top: 4px;
    line-height: 1.4;
}

.earnings-disclosure {
    font-size: 0.82rem;
    color: var(--text-mid);
    line-height: 1.55;
    padding-top: 18px;
    border-top: 1px solid var(--border);
}
.earnings-disclosure a { color: var(--accent); }

/* ── Payout-setup placeholder card ───────────────────────── */
.earnings-payout-card {
    background: var(--bg-card-2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 18px 22px;
    margin-bottom: 32px;
    display: flex;
    align-items: center;
    gap: 14px;
}
.earnings-payout-icon {
    font-size: 1.4rem;
    line-height: 1;
}
.earnings-payout-text {
    font-size: 0.92rem;
    color: var(--text);
    flex: 1;
    min-width: 0;
}
.earnings-payout-text .muted {
    display: block;
    font-size: 0.78rem;
    color: var(--text-dim);
    margin-top: 2px;
}

/* ── Subscriber list ─────────────────────────────────────── */
.earnings-section-label {
    font-size: 0.72rem;
    font-family: var(--font-head);
    font-weight: 700;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: var(--text-dim);
    margin-bottom: 14px;
}

.earn-list-cols {
    display: grid;
    grid-template-columns: 1fr 90px 90px 100px 100px;
    gap: 16px;
    padding: 8px 20px;
    margin-bottom: 6px;
}
.earn-list-col-label {
    font-size: 0.7rem;
    font-family: var(--font-head);
    font-weight: 700;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: var(--text-dim);
    text-align: right;
}
.earn-list-col-label:first-child { text-align: left; }

.earn-list {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.earn-row {
    display: grid;
    grid-template-columns: 1fr 90px 90px 100px 100px;
    align-items: center;
    gap: 16px;
    padding: 14px 20px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    transition: border-color 0.12s, background 0.12s;
}
.earn-row:nth-child(odd) {
    background: color-mix(in srgb, var(--accent) 8%, transparent);
}
.earn-row:hover {
    border-color: var(--border-mid);
}

.earn-display-name {
    font-weight: 600;
    font-size: 0.95rem;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.earn-cell {
    font-size: 0.85rem;
    color: var(--text-mid);
    text-align: right;
}
.earn-cell.right-val {
    color: var(--text);
    font-family: var(--font-head);
    font-weight: 700;
    font-size: 0.88rem;
}

.earn-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 0.7rem;
    font-family: var(--font-head);
    font-weight: 700;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    padding: 3px 9px;
    border-radius: 100px;
    border: 1px solid;
    justify-self: end;
}
.earn-badge--active   { color: var(--green);    border-color: rgba(60,186,108,0.35); background: rgba(60,186,108,0.08); }
.earn-badge--pastdue  { color: var(--red);      border-color: rgba(224,82,82,0.35);  background: rgba(224,82,82,0.08); }
.earn-badge--canceled { color: var(--text-dim); border-color: var(--border);          background: transparent; }
.earn-badge--test     { color: #f0c074;         border-color: rgba(217,119,6,0.55);  background: rgba(217,119,6,0.18); }

/* Test rows render dimmed so they're visually separate from real revenue.
   Pairs with the amber TEST badge in the status column. */
.earn-row--test {
    opacity: 0.55;
}
.earn-row--test:hover {
    opacity: 0.85;
}

/* ── Affiliate-gate empty state ──────────────────────────── */
.earnings-gate {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 56px 32px;
    text-align: center;
    max-width: 560px;
    margin: 24px auto;
}
.earnings-gate-icon {
    font-size: 2.4rem;
    margin-bottom: 16px;
}
.earnings-gate-title {
    font-family: var(--font-head);
    font-weight: 800;
    font-size: 1.4rem;
    color: var(--text);
    margin-bottom: 12px;
}
.earnings-gate-body {
    font-size: 0.95rem;
    color: var(--text-mid);
    line-height: 1.55;
    margin-bottom: 28px;
}
.earnings-gate-cta {
    display: inline-block;
}

/* ── Demo ribbon (preview page only) ─────────────────────── */
.demo-ribbon {
    font-size: 0.7rem;
    font-family: var(--font-head);
    font-weight: 700;
    letter-spacing: 1px;
    text-transform: uppercase;
    padding: 4px 10px;
    border-radius: 100px;
    border: 1px solid var(--accent);
    color: var(--accent);
    background: var(--accent-dim);
}

/* ── Demo-data banner (live tab, while backend is pending) ─
   Removed once api/coach/earnings-summary.php is wired up.
   Amber on dark — purposefully louder than the accent-blue
   palette so a partner can't miss that these numbers aren't
   theirs.                                                    */
.earnings-demo-banner {
    background: rgba(217,119,6,0.12);
    border: 1px solid rgba(217,119,6,0.45);
    border-radius: var(--radius);
    padding: 12px 16px;
    margin-bottom: 24px;
    font-size: 0.85rem;
    color: #f0c074;
    line-height: 1.5;
}
.earnings-demo-banner strong {
    color: #ffd693;
}

@media (max-width: 720px) {
    .earnings-hero-value      { font-size: 3.2rem; }
    .earnings-hero-value .currency { font-size: 2rem; }
    .earnings-secondary-row   { grid-template-columns: 1fr; gap: 20px; }

    /* Mobile subscriber list — single-row layout (matches desktop).
       Compact columns + smaller fonts + short date format so all five
       cells fit on one line at iPhone-SE 375px width. Long subscriber
       names (e.g. @rickstevens24) truncate with ellipsis. */
    .earn-list-cols {
        grid-template-columns: minmax(0, 1fr) 52px 56px 62px 64px;
        gap: 6px;
        padding: 4px 10px;
        margin-bottom: 4px;
    }
    .earn-list-col-label {
        font-size: 0.58rem;
        letter-spacing: 0.4px;
    }
    .earn-row {
        grid-template-columns: minmax(0, 1fr) 52px 56px 62px 64px;
        grid-template-areas: none;   /* clear desktop areas, use direct columns */
        gap: 6px;
        padding: 12px 10px;
        row-gap: 0;
    }
    .earn-display-name {
        font-size: 0.85rem;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        grid-area: auto;             /* clear desktop grid-area assignment */
    }
    .earn-cell {
        font-size: 0.72rem;
    }
    .earn-row .earn-cell:nth-of-type(1),
    .earn-row .earn-cell:nth-of-type(2),
    .earn-row .earn-cell:nth-of-type(3) {
        grid-area: auto;
        text-align: right;
    }
    .earn-cell.right-val {
        font-size: 0.76rem;
    }
    .earn-badge {
        grid-area: auto;
        padding: 2px 6px;
        font-size: 0.55rem;
        letter-spacing: 0.2px;   /* override desktop's 0.5px so "Past due" fits in one line */
    }
}
