﻿/*#region RESET*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font: inherit;
    vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
    display: block;
}

/* button is deliberately left out of the reset block above (the same way the original
   Eric Meyer reset it's based on leaves out every form control) — so unless a class
   explicitly sets its own border, every <button> in the app falls back to the browser's
   native UA-stylesheet button chrome, which renders as a light gray 3D/"embossed" outset
   border. Reset it here instead; any class that sets its own border (e.g. a deliberate
   1px outline button) still wins, since a class selector is more specific than this bare
   element one. */
button {
    border: none;
}

body {
    line-height: 1;
}

ol, ul {
    list-style: none;
}

blockquote, q {
    quotes: none;
}

    blockquote:before, blockquote:after,
    q:before, q:after {
        content: '';
        content: none;
    }

table {
    border-collapse: collapse;
    border-spacing: 0;
}
/*#endregion*/


:root {
    --main-bg: #1a1a1a;
    --text-color: #f1f1f1;
    --lighter-bg: #262626;
    --lightest-bg: #333333;
    --darker-bg: #0F0F0F;
    --theme-dark: #FF7E00;
    --theme-light: #FFC402;
    --accent-dark: #2F1059;
    --accent-light: #6231A7;
    --accent-green: #3DFF9B;
    --accent-green-dark: #197A48;
    --accent-gray-light: #979797;
    --list-container-padding: 32px;
    --list-container-border-radius: 10px;
    --list-container-border-color: #979797;
    --list-container-margin-top-bottom: 64px;
    --list-container-gap: 8px;
    --container-max-width: 1200px;
    --info-blue: #0031D0;
    --error-red: rgba(255, 63, 95, 1);
    --header-height: 56px;
}

html, body {
    background: var(--main-bg);
    color: var(--text-color);
    font-family: 'Roboto', sans-serif;
    min-height: 100dvh;
    /* Reserves the vertical scrollbar's gutter permanently, so a filter/search change that
       pushes content past (or back under) the viewport height doesn't shift the page's
       available width and cause a visible jump. Safe alongside overflow-x: clip below — unlike
       overflow-y, this doesn't force html/body into their own scroll container, so it doesn't
       touch the position: sticky containing-block issue documented there. No effect in browsers
       without support (pre-18.2 Safari) — content just keeps today's jump behavior, not a
       regression. */
    scrollbar-gutter: stable;
    /* Defense-in-depth against full-bleed elements (e.g. .breadcrumbs-panel) that use the
       100vw-breakout technique — 100vw measures the viewport as if no scrollbar existed, so
       on a page tall enough to get a vertical scrollbar, a 100vw-wide element ends up a few
       pixels wider than the actually-visible area and would otherwise trigger a horizontal
       scrollbar of its own.
       Deliberately `clip`, not `hidden`: per the CSS Overflow spec, setting overflow-x to any
       non-visible value while overflow-y is left as `visible` forces overflow-y to compute to
       `auto` too (a browser can't have one axis clip and the other stay truly visible) — that
       silently turned html/body into their own scroll container and broke `position: sticky`
       for every descendant (e.g. .plays-sticky-bar), because the sticky containing block ended
       up wrong once html/body itself claimed the overflow instead of the real viewport. `clip`
       is exempt from that axis-coupling rule, so it clips horizontal overflow without taking
       over vertical scrolling. Reproduced and confirmed in a standalone test page before this
       fix — do not revert to `hidden` here without re-testing sticky elements. */
    overflow-x: clip;
}

a {
    color: inherit;
    text-decoration: none;
}

/*#region APP SHELL / HEADER*/
.app-shell {
    min-height: 100dvh;
}

.app-header {
    position: fixed;
    top: env(safe-area-inset-top);
    left: 0;
    right: 0;
    z-index: 40;
    display: flex;
    align-items: center;
    gap: 16px;
    height: var(--header-height);
    padding: 0 16px;
    background: var(--darker-bg);
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.menu-btn {
    background: none;
    border: none;
    color: var(--text-color);
    font-size: 22px;
    line-height: 1;
    padding: 8px;
    cursor: pointer;
}

.app-header-logo {
    height: 28px;
    width: auto;
}

.app-header-title {
    font-size: 18px;
    font-weight: 700;
    letter-spacing: 0.02em;
}

.app-header-context {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 6px;
    max-width: 45vw;
    font-size: 13px;
    white-space: nowrap;
    overflow: hidden;
}

.app-header-context-org {
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
}

.app-header-context-sep {
    color: var(--accent-gray-light);
    flex-shrink: 0;
}

.app-header-context-unit {
    color: var(--accent-gray-light);
    overflow: hidden;
    text-overflow: ellipsis;
}

.app-header-context-role {
    color: var(--accent-green);
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Root/Admin indicator, right of the "MyHockeyIQ" title — 9px margin here plus the header's
   own 16px flex gap nets the ~25px gap to the title. */
.app-header-role-badge {
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
    background: var(--theme-dark);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    /* Explicit height + line-height 1 so every pill (Root / Admin / Director) is exactly the
       same box regardless of how its text's line box renders. */
    height: 20px;
    line-height: 1;
    box-sizing: border-box;
    padding: 0 10px;
    border-radius: 999px;
    margin-left: 9px;
}

/* 2.20-005: Director pill — purple, next to the orange Root/Admin pills. */
.app-header-role-badge-director {
    background: var(--accent-dark);
}

@media (max-width: 480px) {
    .app-header-context {
        display: none;
    }
}

.app-header-household-context-icon {
    color: var(--theme-light);
    flex-shrink: 0;
}

.app-header-clear-player-btn {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    background: var(--darker-bg);
    border: none;
    border-radius: 50%;
    color: var(--accent-gray-light);
    font-size: 10px;
    cursor: pointer;
}

.app-header-clear-player-btn:hover {
    color: var(--text-color);
}

.app-content {
    max-width: var(--container-max-width);
    margin-left: auto;
    margin-right: auto;
    padding: 16px;
    padding-top: calc(var(--header-height) + env(safe-area-inset-top) + 16px);
}
/*#endregion*/

/*#region NAV MENU*/
.nav-overlay {
    position: fixed;
    top: calc(var(--header-height) + env(safe-area-inset-top));
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.6);
    z-index: 35;
}

.nav-menu {
    position: fixed;
    top: calc(var(--header-height) + env(safe-area-inset-top));
    left: 0;
    bottom: 0;
    width: min(80%, 300px);
    background: var(--lighter-bg);
    box-shadow: 2px 0 12px rgba(0, 0, 0, 0.4);
    /* Must beat any in-page sticky/overlay content (e.g. .plays-sticky-bar at z-index 30) —
       previously both sat at 30, and since the nav menu renders earlier in the DOM than page
       content, equal z-index ties are broken by paint order and the later-painted page content
       won, drawing over the open nav menu. Stays below .app-header (40) so the menu toggle
       button in the header remains clickable/visible while the drawer is open. */
    z-index: 36;
    padding-top: 8px;
    padding-bottom: env(safe-area-inset-bottom);
    transform: translateX(-100%);
    transition: transform 0.25s ease;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
    scrollbar-color: #202020 transparent;
}

.nav-menu::-webkit-scrollbar {
    width: 2px;
}

.nav-menu::-webkit-scrollbar-track {
    background: transparent;
}

.nav-menu::-webkit-scrollbar-thumb,
.nav-menu::-webkit-scrollbar-thumb:hover {
    background-color: #202020;
    border-radius: 4px;
}

.nav-menu-open {
    transform: translateX(0);
}

.nav-menu-top,
.nav-menu-bottom {
    display: flex;
    flex-direction: column;
    padding: 0 16px;
}

.nav-menu .NavLink {
    height: 50px;
    width: 100%;
    background-color: var(--darker-bg);
    color: var(--text-color);
    display: flex;
    border-radius: 6px;
    align-items: center;
    gap: 14px;
    box-sizing: border-box;
    padding: 0 15px;
    text-decoration: none;
    font-size: 16px;
}

.nav-menu .NavLink:not(:first-child) {
    margin-top: 10px;
}

.nav-menu .NavLink.active {
    color: #fff;
    border: 2px solid var(--theme-dark);
}

.nav-menu .NavLink i {
    width: 20px;
    text-align: center;
    color: var(--theme-dark);
}

/* Admin Console gets the same purple accent as its own pages (see .admin-page in the DASHBOARD
   region) instead of the orange every other nav item uses — a preview, before you even click
   in, that this link leads somewhere different from the rest of the app. */
.nav-menu .NavLink-admin i {
    color: var(--accent-light);
}

.nav-menu .NavLink-admin.active {
    border-color: var(--accent-light);
}

.nav-household-toggle {
    display: flex;
    justify-content: center;
    margin-top: 12px;
}

.nav-menu-divider {
    flex-shrink: 0;
    height: 1px;
    margin: 16px 16px;
    background: rgba(255, 255, 255, 0.16);
}

.nav-badge {
    margin-left: auto;
    background: var(--error-red);
    color: #fff;
    font-size: 12px;
    font-weight: 700;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

/* Pill container distinguishing the user control from OrgContextSwitcher immediately below it
   (same nav-menu-divider-separated sibling, but with no container of its own — sits directly on
   the nav menu's own background). Darker than --lighter-bg (the nav menu's own background) so
   the two read as visually distinct controls at a glance, not just text separated by a rule.
   No overflow:hidden here — .nav-user-dropdown is an absolutely-positioned child that renders
   below this element's own height, and clipping would cut it off entirely. */
.nav-user {
    position: relative;
    margin: 0 16px;
    border-radius: 999px;
    background: var(--darker-bg);
}

.nav-user-trigger {
    display: flex;
    align-items: center;
    gap: 14px;
    width: 100%;
    padding: 14px 24px;
    font-family: inherit;
    background: none;
    border: none;
    color: inherit;
    text-align: left;
    cursor: pointer;
}

.nav-user-avatar {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: var(--darker-bg);
    color: var(--theme-light);
    font-size: 14px;
    font-weight: 700;
}

.nav-user-avatar-image {
    object-fit: cover;
}

.nav-user-info {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.nav-user-name {
    font-size: 15px;
    font-weight: 700;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.nav-user-email {
    font-size: 13px;
    color: var(--accent-gray-light);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.nav-user-caret {
    flex-shrink: 0;
    font-size: 13px;
    color: var(--accent-gray-light);
    transition: transform 0.2s ease;
}

.nav-user-caret-open {
    transform: rotate(180deg);
}

.nav-user-dropdown {
    position: absolute;
    left: 8px;
    right: 8px;
    top: calc(100% + 4px);
    z-index: 2;
    display: flex;
    flex-direction: column;
    background: var(--darker-bg);
    border-radius: var(--list-container-border-radius);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35), 0 10px 28px rgba(0, 0, 0, 0.55);
    overflow: hidden;
}

.nav-user-dropdown button {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    padding: 12px 16px;
    font-size: 15px;
    font-family: inherit;
    background: none;
    border: none;
    color: inherit;
    text-align: left;
    cursor: pointer;
}

.nav-user-dropdown button:hover {
    background: rgba(0, 0, 0, 0.3);
}

.nav-user-dropdown i {
    width: 20px;
    text-align: center;
}

.nav-user-login {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 24px;
    font-size: 16px;
}

.nav-context {
    position: relative;
    margin-bottom: 16px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.nav-context-trigger {
    display: flex;
    align-items: center;
    gap: 14px;
    width: 100%;
    padding: 14px 24px;
    font-family: inherit;
    background: none;
    border: none;
    color: inherit;
    text-align: left;
    cursor: pointer;
}

.nav-context-avatar {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: var(--darker-bg);
    color: var(--theme-light);
    font-size: 14px;
    font-weight: 700;
}

.nav-context-avatar-image {
    object-fit: cover;
}

.nav-context-info {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.nav-context-org {
    font-size: 15px;
    font-weight: 700;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.nav-context-unit {
    font-size: 13px;
    color: var(--accent-gray-light);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.nav-context-caret {
    flex-shrink: 0;
    font-size: 13px;
    color: var(--accent-gray-light);
    transition: transform 0.2s ease;
}

.nav-context-caret-open {
    transform: rotate(180deg);
}

/* Invisible full-page click-catcher — sits behind .nav-context-dropdown (lower z-index) so
   any click outside the dropdown itself (elsewhere in the nav, or the rest of the page)
   closes it instead of reaching whatever's underneath. */
.nav-context-backdrop {
    position: fixed;
    inset: 0;
    z-index: 0;
    background: transparent;
}

.nav-context-dropdown {
    position: absolute;
    left: 8px;
    right: 8px;
    top: calc(100% + 4px);
    z-index: 1;
    display: flex;
    flex-direction: column;
    gap: 10px;
    background: var(--darker-bg);
    border-radius: var(--list-container-border-radius);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35), 0 10px 28px rgba(0, 0, 0, 0.55);
    padding: 14px 16px;
}

.nav-context-picker-label {
    font-size: 12px;
    font-weight: 600;
    color: var(--accent-gray-light);
    margin-bottom: -4px;
}

.nav-context-picker {
    width: 100%;
    background: var(--lighter-bg);
    color: var(--text-color);
    border: none;
    border-radius: var(--list-container-border-radius);
    padding: 10px 12px;
    font-size: 14px;
    font-family: inherit;
}

.nav-context-picker-multi {
    padding: 4px;
    max-height: 140px;
    overflow-y: auto;
}

.nav-context-picker-multi option {
    padding: 6px 8px;
    border-radius: 4px;
}
/*#endregion*/

/*#region DASHBOARD*/
.dashboard-title {
    font-size: 22px;
    font-weight: 700;
    margin-bottom: 16px;
}

/* Marks every Admin Console page (added to the same root div as .dashboard/.dashboard
   profile-page) with a purple accent instead of the app's usual orange theme, so it's obvious
   at a glance that you're inside admin-only functionality. --accent-dark/--accent-light were
   already defined but otherwise unused — reused here rather than introducing new vars. */
.admin-page {
    border-top: 4px solid var(--accent-light);
    padding-top: 20px;
}

.admin-page .dashboard-title {
    color: var(--accent-light);
}

.dashboard-title + .dashboard-guardian-name {
    margin-top: -10px;
}

.dashboard-guardian-name {
    font-size: 14px;
    font-weight: 600;
    color: #6D28D9;
    margin: 0 0 2px;
}

.dashboard-other-guardians {
    font-size: 12px;
    color: var(--accent-gray-light);
    margin: 0 0 16px;
}

.dashboard-loading {
    display: flex;
    justify-content: center;
    padding: 48px 0;
}

.dashboard-loading i {
    font-size: 32px;
    color: var(--theme-dark);
}

.dashboard-section {
    margin-bottom: 24px;
}

.section-title {
    font-size: 15px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--accent-gray-light);
    margin-bottom: 10px;
}

.section-subtitle {
    font-size: 13px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--accent-gray-light);
    margin: 20px 0 10px;
}

.empty-state {
    color: var(--accent-gray-light);
    font-size: 14px;
    background: var(--lighter-bg);
    border-radius: var(--list-container-border-radius);
    padding: 16px;
}

.activity-list li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    background: var(--lighter-bg);
    border-radius: var(--list-container-border-radius);
    padding: 12px 16px;
    margin-bottom: 8px;
    font-size: 14px;
}

.activity-date {
    flex-shrink: 0;
    font-size: 12px;
    color: var(--accent-gray-light);
}

.activity-link {
    color: inherit;
    text-decoration: none;
}

.activity-link:hover {
    text-decoration: underline;
}

.journey-section {
    margin-bottom: 28px;
}

.journey-section-header {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    margin-bottom: 12px;
}

.journey-section-icon {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--lighter-bg);
    color: var(--theme-dark);
    font-size: 18px;
}

.journey-section-title {
    font-size: 16px;
    font-weight: 700;
    margin: 0;
}

.journey-section-subtitle {
    font-size: 13px;
    color: var(--accent-gray-light);
    margin: 2px 0 0;
}

.journey-section-empty {
    color: var(--accent-gray-light);
    font-size: 14px;
    background: var(--lighter-bg);
    border-radius: var(--list-container-border-radius);
    padding: 16px;
    font-weight: 400;
    margin: 0;
}

.journey-team-list {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
}

.journey-team-card {
    display: flex;
    flex-direction: column;
    gap: 4px;
    background: var(--lighter-bg);
    border-radius: var(--list-container-border-radius);
    padding: 14px 16px;
    min-width: 180px;
}

.journey-team-card.is-clickable {
    cursor: pointer;
}

.journey-team-card.is-past {
    opacity: 0.55;
    cursor: default;
}

.journey-team-org {
    font-size: 15px;
    font-weight: 700;
    color: var(--theme-dark);
}

.journey-team-name,
.journey-team-joined {
    font-size: 13px;
    color: var(--accent-gray-light);
}

.section-title-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 10px;
}

.section-title-group {
    display: flex;
    align-items: center;
    gap: 10px;
}

.favorites-total {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 13px;
    font-weight: 600;
    color: var(--accent-gray-light);
}

.favorites-total-icon {
    color: var(--theme-dark);
    font-size: 13px;
}

.section-title-row .section-title {
    margin-bottom: 0;
}

.dashboard-section-view-all {
    font-size: 13px;
    color: var(--theme-dark);
}

.dashboard-favorites-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.dashboard-favorite-item {
    display: flex;
    align-items: center;
    gap: 12px;
    background: var(--lighter-bg);
    border-radius: var(--list-container-border-radius);
    padding: 8px 12px;
}

.dashboard-favorite-image {
    width: 36px;
    height: 36px;
    border-radius: 6px;
    object-fit: cover;
    flex-shrink: 0;
}

.dashboard-favorite-image-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.25);
    color: #f5c518;
}

.dashboard-favorite-title {
    font-size: 14px;
}

.settings-link {
    display: flex;
    align-items: center;
    gap: 12px;
    background: var(--lighter-bg);
    border-radius: var(--list-container-border-radius);
    padding: 16px;
    font-size: 15px;
    font-weight: 500;
}

.settings-link i:first-child {
    color: var(--theme-dark);
    font-size: 18px;
}

.settings-link i:last-child {
    margin-left: auto;
    color: var(--accent-gray-light);
    font-size: 14px;
}

.app-version {
    display: block;
    text-align: center;
    color: var(--accent-gray-light);
    font-size: 12px;
    margin: 24px 0 8px;
}

.app-version:hover {
    text-decoration: underline;
}
/*#endregion*/

/*#region RELEASE NOTES*/
.release-notes-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.release-notes-list-item {
    display: flex;
    flex-direction: column;
    gap: 2px;
    background: var(--lighter-bg);
    border-radius: var(--list-container-border-radius);
    padding: 14px 16px;
}

.release-notes-version {
    font-size: 13px;
    font-weight: 700;
    color: var(--theme-light);
}

.release-notes-title {
    font-size: 15px;
    font-weight: 600;
}

.release-notes-date {
    font-size: 12px;
    color: var(--accent-gray-light);
}

.release-notes-back {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    color: var(--accent-gray-light);
    margin-bottom: 16px;
}

.release-notes-content h2 {
    font-size: 16px;
    font-weight: 700;
    margin: 20px 0 10px;
}

.release-notes-content h2:first-child {
    margin-top: 0;
}

.release-notes-content ul {
    padding-left: 20px;
}

.release-notes-content li {
    list-style: disc;
    font-size: 14px;
    line-height: 1.5;
    margin-bottom: 8px;
    color: var(--text-color);
}

.release-notes-content li strong {
    font-weight: 700;
}
/*#endregion*/

/*#region PLAYS*/
/* Docks the search/filter/tags bar (and the bulk-select "add to" bar, when present) under
   the fixed app header while the tile grid scrolls underneath. Opaque background matches the
   page so scrolled-past tiles don't show through; the bottom border only becomes visible once
   real content is stuck beneath it. */
.plays-sticky-bar {
    position: sticky;
    top: calc(var(--header-height) + env(safe-area-inset-top));
    z-index: 30;
    background: var(--main-bg);
    padding-top: 16px;
    margin-top: -16px;
    margin-bottom: 16px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.plays-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 16px;
}

.media-usage-label {
    font-size: 13px;
    color: var(--accent-gray-light);
    margin: -8px 0 16px;
}

.media-usage-used {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}

.media-usage-used.media-usage-over {
    color: var(--error-red);
}

.plays-new-btn {
    display: flex;
    align-items: center;
    gap: 6px;
    background: #6D28D9;
    color: #fff;
    border-radius: 999px;
    padding: 8px 16px;
    font-size: 14px;
    font-weight: 600;
}

/* Shown instead of .plays-new-btn when the caller's Personal org is read-only (no active
   Personal subscription) — same pill shape and outline-only treatment as
   .content-visibility-toggle's own muted state, so it reads as a secondary/disabled
   action rather than the normal creation button. Links to the subscription settings page. */
.plays-new-btn-locked {
    background: none;
    border: 2px solid var(--accent-gray-light);
    color: var(--accent-gray-light);
}

.practice-plan-header-actions {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.practice-plan-more-wrap {
    position: relative;
}

.practice-plan-more-trigger {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 999px;
    border: 2px solid var(--accent-gray-light);
    background: none;
    color: var(--accent-gray-light);
    font-size: 15px;
    cursor: pointer;
}

.practice-plan-more-trigger:hover {
    color: var(--text-color);
    border-color: var(--text-color);
}

/* Invisible full-viewport click-catcher, same technique as the modal backdrops elsewhere —
   closes the menu on any outside click without a JS click-outside directive. */
.practice-plan-more-backdrop {
    position: fixed;
    inset: 0;
    z-index: 4;
}

.practice-plan-more-menu {
    position: absolute;
    right: 0;
    top: calc(100% + 6px);
    z-index: 5;
    min-width: 160px;
    display: flex;
    flex-direction: column;
    background: var(--darker-bg);
    border-radius: var(--list-container-border-radius);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35), 0 10px 28px rgba(0, 0, 0, 0.55);
    overflow: hidden;
}

.practice-plan-more-menu button {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 10px 14px;
    font-size: 14px;
    font-family: inherit;
    background: none;
    border: none;
    color: inherit;
    text-align: left;
    cursor: pointer;
}

.practice-plan-more-menu button:hover {
    background: rgba(0, 0, 0, 0.3);
}

.practice-plan-more-menu i {
    width: 16px;
    text-align: center;
}

.practice-plan-more-menu button.practice-plan-more-menu-danger {
    color: var(--error-red);
}

/* Draft/Published is a status the creator toggles, not a navigational action like the
   pill buttons next to it — an outlined/filled pair reads as a state switch rather than
   "go do something else", distinct from .plays-new-btn's solid purple. Feedback-exclusive —
   Play/PracticePlan use .content-visibility-toggle below (a separate, differently-named
   Private/Public rule) since Feedback's own Draft/Published workflow is unchanged. */
.practice-plan-publish-toggle {
    display: flex;
    align-items: center;
    gap: 6px;
    border-radius: 999px;
    padding: 8px 16px;
    font-size: 14px;
    font-weight: 600;
    border: 2px solid var(--accent-gray-light);
    background: none;
    color: var(--accent-gray-light);
}

.practice-plan-publish-toggle.published {
    border-color: var(--accent-green);
    color: var(--accent-green);
}

/* Private/Public toggle for Play/PracticePlan (post-refactor) — same shape as
   .practice-plan-publish-toggle above but a distinct class since Feedback's own
   Draft/Published toggle was deliberately left using the old naming. Shared by the
   Practice Plan header toggle and the Play Share tab's PublishPanel toggle. */
.content-visibility-toggle {
    display: flex;
    align-items: center;
    gap: 6px;
    border-radius: 999px;
    padding: 8px 16px;
    font-size: 14px;
    font-weight: 600;
    border: 2px solid var(--accent-gray-light);
    background: none;
    color: var(--accent-gray-light);
}

.content-visibility-toggle.public {
    border-color: var(--accent-green);
    color: var(--accent-green);
}

.plays-filter-bar {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-bottom: 16px;
}

.plays-picker-banner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    background: var(--lighter-bg);
    border: 1px solid var(--theme-dark);
    border-radius: var(--list-container-border-radius);
    padding: 10px 14px;
    margin-bottom: 16px;
    font-size: 14px;
}

.plays-picker-banner-done {
    flex-shrink: 0;
    background: var(--theme-dark);
    color: #fff;
    font-size: 13px;
    font-weight: 600;
    padding: 6px 14px;
    border-radius: 999px;
}

.filter-checkbox-row {
    display: flex;
    flex-wrap: wrap;
    gap: 12px 20px;
}

.filter-checkbox {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 14px;
    color: var(--accent-gray-light);
    cursor: pointer;
}

.filter-checkbox input {
    accent-color: var(--theme-dark);
    width: 16px;
    height: 16px;
    cursor: pointer;
}

/* Matches the legacy HMS Plays filter look: a dark card housing a row of pill-shaped
   checkbox chips, built only from white + the orange theme color (no other palette colors).
   Unchecked = transparent fill, orange border/text, empty orange-bordered box. Checked =
   solid orange fill, white text, white box with an orange checkmark. The real <input> stays
   in the DOM (hidden, not display:none) for accessibility/keyboard support; visual state is
   driven by the .plays-filter-chip-checked class toggled in the Razor markup, same convention
   already used by .tag-chip-selected. */
.plays-legacy-filter-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    background: var(--lighter-bg);
    border-radius: var(--list-container-border-radius);
    padding: 12px 16px;
}

/* Sits alongside .plays-legacy-filter-bar's checkbox chips — reuses the same ToggleSwitch
   component as the whiteboard's Editor/Animation control and the nav's household toggle,
   rather than another checkbox chip, since these two filters are each a genuine two-state
   view switch (All/Favorites, Active/Archived) rather than an additive multi-select. Same card
   treatment as .plays-legacy-filter-bar (background + rounded corners) so the pair reads as
   its own grouped control rather than floating loose against the page background. */
.plays-toggle-filter-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    background: var(--lighter-bg);
    border-radius: var(--list-container-border-radius);
    padding: 12px 16px;
}

/* One step lighter than .plays-toggle-filter-bar's own background — each toggle gets a
   visibly bounded pill of its own, rather than relying on gap alone to separate them. */
.plays-toggle-item {
    background: var(--lightest-bg);
    border-radius: 999px;
    padding: 6px 14px;
}

/* Hidden by default (desktop) — the collapse toggle and the collapsed-height clamp below
   both only apply on a phone viewport, so this feature is mobile-only end to end even though
   the three panels' _collapsed booleans default to true regardless of device. */
.plays-filter-panel-toggle {
    display: none;
}

/* Only ever shown while its panel is collapsed (see the media query below) — a short name
   for what's hidden underneath, since the collapsed content itself is display:none, not just
   clipped. */
.plays-filter-panel-label {
    display: none;
}

/* Same phone-viewport condition as viewport.js's isPhoneViewport() / the whiteboard header's
   own collapse toggle — narrow width (portrait phones) or short height on a touch device
   (landscape phones). */
@media (max-width: 639px), ((max-height: 480px) and (pointer: coarse)) {
    .plays-filter-panel {
        position: relative;
    }

    .plays-filter-panel-toggle {
        display: flex;
        align-items: center;
        justify-content: center;
        position: absolute;
        top: 6px;
        right: 8px;
        width: 22px;
        height: 22px;
        background: none;
        border: none;
        color: var(--accent-gray-light);
        font-size: 13px;
        cursor: pointer;
    }

    /* .tag-chip-list has no card look of its own (it's reused bare elsewhere — MyLockerPage,
       the whiteboard's TagsPanel) — this wrapper gives the Plays sticky bar's tags section the
       same card treatment as its two sibling panels, but only on mobile; desktop keeps the
       existing bare tag-chip-list look untouched. Declared before .plays-filter-panel-collapsed
       below so that rule's own padding-top/bottom (equal specificity, same element) wins the
       cascade when collapsed, rather than this rule's padding shorthand clobbering it. */
    .plays-tags-panel {
        background: var(--lighter-bg);
        border-radius: var(--list-container-border-radius);
        padding: 12px 16px;
    }

    /* Expanded-only — .plays-filter-panel-collapsed's own height:30px/overflow:hidden already
       handles the collapsed case. With enough tags, the chip list can grow taller than the
       remaining viewport under the sticky bar; since the panel itself is position:sticky, a
       tag row that overflows below the viewport edge is otherwise unreachable — the page can't
       scroll it back into view the way it would a non-sticky element. Capping the chip list's
       own height and letting IT scroll internally keeps every tag reachable regardless of count. */
    .plays-tags-panel:not(.plays-filter-panel-collapsed) .tag-chip-list {
        max-height: 33vh;
        overflow-y: auto;
    }

    /* box-sizing: border-box so the 30px is the panel's true total height, padding included —
       content-box math would push the real height past 30px once padding is added back.
       min-height: 0 overrides the flex column's default content-based floor (a column flex
       item won't shrink below its content's intrinsic size otherwise — the classic flexbox
       min-height:auto trap — which would otherwise win over the explicit height here).
       display:flex + align-items:center vertically centers the one visible child (the label)
       regardless of whether the panel is normally a flex row (.plays-legacy-filter-bar,
       .plays-toggle-filter-bar) or a plain block (.plays-tags-panel) — safe to force here since
       every other child is display:none while collapsed. */
    .plays-filter-panel-collapsed {
        box-sizing: border-box;
        height: 30px;
        min-height: 0;
        padding-top: 4px;
        padding-bottom: 4px;
        overflow: hidden;
        display: flex;
        align-items: center;
    }

    /* The actual filter/toggle/tag content — fully hidden (not just clipped) while collapsed,
       leaving only the toggle button (position:absolute, out of flow, unaffected) and the
       label below in view. */
    .plays-filter-panel-collapsed > *:not(.plays-filter-panel-toggle):not(.plays-filter-panel-label) {
        display: none;
    }

    /* Vertically centers the chevron within the collapsed 30px bar — the expanded state keeps
       its own top:6px corner pinning above (only overridden here, scoped to collapsed). */
    .plays-filter-panel-collapsed .plays-filter-panel-toggle {
        top: 50%;
        transform: translateY(-50%);
    }

    .plays-filter-panel-collapsed .plays-filter-panel-label {
        display: block;
        align-self: center;
        font-size: 12px;
        font-weight: 600;
        color: var(--accent-gray-light);
        text-transform: uppercase;
        letter-spacing: 0.04em;
        line-height: 12px;
    }
}

.plays-filter-chip {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 14px;
    border-radius: 6px;
    border: 2px solid var(--theme-dark);
    background: transparent;
    color: var(--theme-dark);
    font-size: 14px;
    font-weight: 700;
    cursor: pointer;
    user-select: none;
}

.plays-filter-chip input[type="checkbox"] {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.plays-filter-chip-box {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
    border: 2px solid var(--theme-dark);
    border-radius: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.plays-filter-chip-box i {
    font-size: 10px;
    color: var(--theme-dark);
    visibility: hidden;
}

.plays-filter-chip-checked {
    background: var(--theme-dark);
    color: #fff;
}

.plays-filter-chip-checked .plays-filter-chip-box {
    background: #fff;
    border-color: #fff;
}

.plays-filter-chip-checked .plays-filter-chip-box i {
    visibility: visible;
}

/*#region TOGGLE SWITCH (reusable)*/
.toggle-switch {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    user-select: none;
}

.toggle-switch input[type="checkbox"] {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.toggle-switch-track {
    position: relative;
    flex-shrink: 0;
    width: 44px;
    height: 24px;
    background: var(--lighter-bg);
    border-radius: 999px;
    transition: background-color 0.2s ease;
}

.toggle-switch-thumb {
    position: absolute;
    top: 2px;
    left: 2px;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: #fff;
    transition: transform 0.2s ease;
}

.toggle-switch input:checked + .toggle-switch-track {
    background: var(--theme-dark);
}

.toggle-switch input:checked + .toggle-switch-track .toggle-switch-thumb {
    transform: translateX(20px);
}

.toggle-switch input:focus-visible + .toggle-switch-track {
    outline: 2px solid var(--theme-dark);
    outline-offset: 2px;
}

.toggle-switch-disabled {
    opacity: 0.5;
    cursor: default;
}

.toggle-switch-label {
    font-size: 13px;
    font-weight: 600;
    color: var(--accent-gray-light);
    white-space: nowrap;
    transition: color 0.2s ease;
}

.toggle-switch-label.active {
    color: var(--text-color);
}
/*#endregion*/

.settings-sms-toggle {
    margin-top: 16px;
}

.settings-sms-disclosure {
    margin: 4px 0 0;
    line-height: 1.5;
}

.pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 16px;
    margin-top: 20px;
}

.pagination-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    background: var(--lighter-bg);
    border: none;
    border-radius: 50%;
    color: var(--text-color);
    font-size: 14px;
    cursor: pointer;
}

.pagination-btn:disabled {
    opacity: 0.4;
    cursor: default;
}

.pagination-status {
    font-size: 13px;
    color: var(--accent-gray-light);
}

.plays-bulk-actions {
    display: flex;
    align-items: center;
    gap: 12px;
    background: var(--lighter-bg);
    border-radius: var(--list-container-border-radius);
    padding: 10px 14px;
    margin-bottom: 16px;
}

.plays-bulk-actions-count {
    font-size: 13px;
    color: var(--accent-gray-light);
    margin-right: auto;
}

.plays-bulk-actions-btn {
    background: #6D28D9;
    color: #fff;
    border-radius: 999px;
    padding: 8px 16px;
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
}

/*#region ADD TO PLAYBOOK MODAL*/
.add-to-playbook-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 50;
}

.add-to-playbook-modal {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: min(90vw, 380px);
    max-height: 80vh;
    overflow-y: auto;
    background: var(--lighter-bg);
    border-radius: var(--list-container-border-radius);
    padding: 20px;
    z-index: 51;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.add-to-playbook-title {
    font-size: 16px;
    font-weight: 700;
    margin: 0;
}

.add-to-playbook-create-btn {
    justify-content: center;
    width: 100%;
}

.add-to-playbook-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.add-to-playbook-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    width: 100%;
    background: var(--darker-bg);
    border: none;
    border-radius: var(--list-container-border-radius);
    padding: 10px 12px;
    cursor: pointer;
    /* Buttons don't reliably inherit body's --text-color in every browser (some UA
       stylesheets force a system button-text color) — without this, the plan/playbook
       title span rendered dark-on-dark against --darker-bg. */
    color: inherit;
}

.add-to-playbook-item-title {
    font-size: 14px;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/*#endregion*/

.plays-list {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 24px;
    margin-bottom: 100px;
}

.infinite-scroll-sentinel {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 48px;
    margin-top: 12px;
    color: var(--accent-gray-light);
    font-size: 18px;
}

@media (min-width: 640px) {
    .plays-list {
        grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    }
}

/* Plays-only: 20px wider tile column than the shared .plays-list default above (which
   Practice Plans/Moments/Media Library also use and shouldn't be affected). */
@media (min-width: 640px) {
    .plays-tile-list {
        grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    }
}

/* Plays-only: below 640px, .plays-list's own base rule forces a fixed 2-column grid regardless
   of available width. That's fine for the narrower shared tile (220px), but this list's 240px
   tiles no longer fit two across on a phone-width screen without squeezing — drop to 1 column
   there. Matches this file's existing 480px phone breakpoint (see .app-header-context above). */
@media (max-width: 480px) {
    .plays-tile-list {
        grid-template-columns: 1fr;
    }
}

.play-card {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

.play-card-image-wrap {
    position: relative;
    /* Rounds itself instead of depending on .play-card-wrap's clip — needed now that Play
       tiles (.plays-tile-list) turn that clip off so the favorite-group popover isn't cut off.
       Redundant-but-harmless everywhere else, where the parent still clips too. */
    overflow: hidden;
    border-radius: var(--list-container-border-radius) var(--list-container-border-radius) 0 0;
}

.play-card-image {
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    display: block;
    border-radius: 0;
}

.play-card-global-badge {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 126, 0, 0.9);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.05em;
}

/* Play tiles' visibility-scope badge (GLOBAL/MY PLAY/ORG LEVEL) — same full-width banner look
   as the old image-overlay bars, just relocated to the top of the card's body/info section
   instead of overlaid on the image, so it needs no clipping against a rounded image corner at
   all. display:block + text-align:center reproduces that bar (.play-card-info is a column flex
   container, so it stretches full width by default); margin-bottom is the "distance between the
   overlay and the content below it" gap the rest of .play-card-info's own 2px flex gap is too
   tight to provide on its own. */
.play-card-badge {
    display: block;
    text-align: center;
    background: rgba(139, 46, 220, 0.9);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.05em;
    padding: 4px 10px;
    margin-bottom: 8px;
}

.play-card-badge-global {
    background: rgba(255, 126, 0, 0.9);
}

/* Practice Plan list tile overlays — same bottom-bar treatment as the Play badges above.
   Assigned takes priority over Shared when both are somehow true (shouldn't normally
   co-occur given the Draft/Published access handoff, but Assigned is the "further along"
   status so it wins the single visible slot). */
.practice-plan-assigned-badge {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(61, 255, 155, 0.9);
    color: #0F0F0F;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.05em;
}

.practice-plan-shared-badge {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 49, 208, 0.9);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.05em;
}

.practice-plan-archived-badge {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(178, 27, 27, 0.9);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.05em;
}

.practice-plan-archive-actions {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 10px;
    background: var(--lighter-bg);
    border-top: 1px solid var(--darker-bg);
}

/* Today/Upcoming/Completed, derived from ScheduledDate — anchored to the TOP of the image
   (unlike the Global/Shared badges above, which own the bottom bar) so it can coexist with
   either of those rather than fight them for the same slot. */
.practice-plan-schedule-badge {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.05em;
}

/* Fully opaque (not translucent): this badge sits directly on the placeholder image's white
   background, and at 90% alpha the entire badge — not just its rounded corners — visibly
   lightened toward that white rather than showing its true color. Full opacity also shrinks the
   remaining rounded-corner anti-aliasing fringe against that white edge down to the ~1 device
   pixel floor that's inherent to rendering any curve next to a high-contrast background. */
/* UPCOMING */
.practice-plan-schedule-badge-upcoming {
    background: rgb(255, 126, 0);
}

/* TODAY */
.practice-plan-schedule-badge-today {
    background: rgb(25, 122, 72);
}

/* COMPLETED */
.practice-plan-schedule-badge-completed {
    background: rgb(98, 49, 167);
}

/* Always rendered (even with no ScheduledDate, when it's left empty) so this reserves the same
   vertical space either way — title/subtitle/meta below all land at the same spot on every tile
   in the grid, scheduled or not. min-height (not just line-height) is required here: a truly
   empty block with no text content collapses to 0 height in every browser regardless of
   line-height, since line-height only affects line boxes that already contain content. */
.practice-plan-scheduled-date {
    display: block;
    min-height: 20px;
    line-height: 20px;
    font-size: 16px;
    font-weight: 600;
    color: #8B5CF6;
    margin-bottom: 6px;
}

.practice-plan-visibility-label {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.05em;
    color: var(--accent-gray-light);
    margin-top: 4px;
}

.practice-plan-visibility-label.public {
    color: var(--accent-green);
}

.play-card-image-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    aspect-ratio: 16 / 9;
    background: var(--darker-bg);
    color: var(--accent-gray-light);
    font-size: 32px;
}

/* Practice plan tiles/cover use images/PPImagePlaceholder.jpg (white background, "IQ" mark +
   tagline) as their placeholder. Its own 556x312 aspect ratio is close to but not exactly the
   16:9 box these render in, and it carries its own light background and readable dark text —
   so unlike a bare icon mark, this needs no forced dark fill or inset padding behind it.
   object-fit:cover (not contain) fills the box exactly, cropping a negligible sliver of the
   placeholder's own white margin rather than leaving a hairline letterbox gap along one edge —
   contain's gap was invisible along a flat edge but showed as a white wedge where it crossed
   the tile's rounded corners. */
.play-card-image-placeholder-logo,
.practice-plan-cover-placeholder-logo {
    object-fit: cover;
    background: #fff;
}

.play-card-info {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    padding: 10px 12px 12px;
}

.play-card-org {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
    margin-bottom: 6px;
}

.play-card-org-logo {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    object-fit: cover;
    flex-shrink: 0;
}

.play-card-org-logo-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--darker-bg);
    color: var(--accent-gray-light);
    font-size: 21px;
}

.play-card-org-name {
    font-size: 18px;
    font-weight: 600;
    color: var(--accent-gray-light);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.play-card-title {
    font-size: 14px;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.play-card-subtitle {
    font-size: 12px;
    color: var(--accent-gray-light);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.play-card-tags {
    display: flex;
    flex-wrap: nowrap;
    gap: 4px;
    overflow: hidden;
    min-height: 22px;
    margin-top: 4px;
}

.play-card-tag-pill {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    background: #6D28D9;
    color: #fff;
    font-size: 11px;
    font-weight: 600;
    padding: 3px 10px;
    border-radius: 999px;
    white-space: nowrap;
}

.playbook-card-meta {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
    margin-top: 4px;
    min-width: 0;
}

.playbook-card-count-pill {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    background: var(--theme-dark);
    color: #fff;
    font-size: 11px;
    font-weight: 600;
    padding: 3px 10px;
    border-radius: 999px;
    white-space: nowrap;
}

.play-card-wrap {
    position: relative;
    /* Grid items default to min-width:auto, so a long nowrap title's intrinsic text width
       can force its column wider than its 1fr share — this is what actually lets the
       ellipsis truncation take effect instead of blowing out the grid track. */
    min-width: 0;
    /* Stacks .play-card and (Plays-only) .play-card-actions as flex children instead of
       relying on .play-card's height:100%. Needed because this li is itself a CSS Grid item:
       align-items:stretch (grid's default) gives it a definite height, and resolving
       .play-card's height:100% against that definite height — AFTER .play-card-actions has
       already been laid out below it in normal flow — pushed .play-card-actions outside this
       box entirely (its own getBoundingClientRect exceeded the wrap's), eating the grid gap
       and spilling into the next row. Flexbox sizes both children into the wrap's intrinsic
       height up front, so nothing overflows. Harmless for other pages reusing this class
       (Practice Plans/Moments), which only ever have one in-flow child here.
    */
    display: flex;
    flex-direction: column;
    /* The visible card box (background/border/rounded corners) lives here, not on .play-card,
       so that .play-card-actions renders as a genuine bottom row of the same tile instead of
       a separate panel sitting below the card's own border. All the absolutely-positioned
       overlays (.play-card-select, .favorite-toggle, .play-card-confirm) already position
       against this element (position:relative), so they still land correctly. */
    background: var(--lighter-bg);
    border-radius: var(--list-container-border-radius);
    overflow: hidden;
    border: 2px solid var(--darker-bg);
    box-sizing: border-box;
    /* overflow:hidden's own border-radius clip kept leaking a hairline of whatever's underneath
       (image/badge) at the top corners, even after giving those descendants their own matching
       border-radius — each element's rounded corner is rasterized independently, and two
       separately-computed arcs don't always agree on the exact same device pixels. clip-path
       applies a single unified mask to this element's entire painted subtree instead, so there's
       only one rounded-corner computation for the browser to get right, not several that have to
       coincide exactly. */
    clip-path: inset(0 round var(--list-container-border-radius));
}

/* Play tiles only: the favorite-group picker popover opens from a button inside this card and
   is taller than the card itself, so the base rule's clip-path/overflow:hidden above was cutting
   it off. Image corners now round themselves (see .play-card-image-wrap below) instead of
   relying on this element's clip, since that clip no longer exists here. */
.plays-tile-list .play-card-wrap {
    overflow: visible;
    clip-path: none;
}

.play-card-selected {
    border-color: var(--theme-dark);
}

/* Strategy plays get a background just a few shades bluer than --lighter-bg (#262626) —
   subtle enough to not read as a distinct color, but enough to tell tiles apart at a glance
   when scanning a mixed list. */
.play-card-strategy {
    background: #24243a;
}

/* .play-card-actions paints its own background (rather than showing the wrap's through),
   so the strategy tint needs to be repeated here too or the bottom action row stays the
   untinted default color while the rest of the tile changes. */
.play-card-strategy .play-card-actions {
    background: #24243a;
}

.play-card-delete {
    position: absolute;
    top: 6px;
    right: 6px;
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.45);
    color: var(--error-red);
    border-radius: 50%;
    font-size: 14px;
}

/* Plays-only bottom row (in normal flow, not an image overlay like .play-card-delete's base
   rule above still is for MediaLibrary/Moments tiles) — delete on the left, favorite on the
   right. This is what makes the Plays tile taller than the shared .play-card default: this
   row adds real layout height instead of floating over the image. */
.play-card-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 6px 10px;
    background: var(--lighter-bg);
}

.play-card-actions .play-card-delete {
    position: static;
    width: 32px;
    height: 32px;
    background: transparent;
}

/* Groups Adopt + Favorite together as the right-hand slot of .play-card-actions'
   space-between layout, so Delete stays the sole left-hand slot. */
.play-card-actions-right {
    display: flex;
    align-items: center;
    gap: 6px;
}

.play-card-adopt {
    position: static;
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    color: var(--accent-gray-light);
    border-radius: 50%;
    font-size: 14px;
}

.play-card-adopt:hover {
    color: var(--theme-light);
}

.play-card-select {
    position: absolute;
    top: 6px;
    left: 6px;
    z-index: 1;
    width: 30px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.45);
    border-radius: 6px;
}

.play-card-select input[type="checkbox"] {
    width: 18px;
    height: 18px;
    margin: 0;
    accent-color: var(--theme-dark);
    cursor: pointer;
}

/* Play tiles' Public/Private status — same color convention as the whiteboard's own Publish
   panel (gray for private, green once public), just packaged as a corner pill overlay instead
   of an inline label since Practice Plan tiles' plain-text version has no tile of its own to
   sit in on Play tiles' redesigned layout. */
.play-card-visibility-badge {
    position: absolute;
    top: 6px;
    right: 6px;
    z-index: 1;
    background: #000;
    color: var(--accent-gray-light);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.05em;
    padding: 4px 10px;
    border-radius: 999px;
}

.play-card-visibility-badge.public {
    color: var(--accent-green);
}

/* 2.20-002: the badge doubles as a Private/Public toggle for anyone allowed to publish the
   play. Reset the button chrome so it's pixel-identical to the static badge, then add only
   the affordances. */
.play-card-visibility-toggle {
    border: 0;
    font: inherit;
    font-size: 11px;
    font-weight: 700;
    cursor: pointer;
    transition: opacity 0.15s ease;
}

.play-card-visibility-toggle:hover:not(:disabled) {
    opacity: 0.8;
}

.play-card-visibility-toggle:focus-visible {
    outline: 2px solid var(--theme-dark);
    outline-offset: 2px;
}

.play-card-visibility-toggle:disabled {
    cursor: wait;
    opacity: 0.6;
}

.favorite-toggle {
    position: absolute;
    bottom: 6px;
    right: 6px;
    z-index: 1;
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.45);
    color: #fff;
    border-radius: 50%;
    cursor: pointer;
    font-size: 14px;
}

.favorite-toggle.favorited {
    color: #f5c518;
}

.favorite-toggle-inline {
    position: static;
    flex-shrink: 0;
    background: transparent;
    color: var(--accent-gray-light);
}

/* Play tiles' (and My Locker's, same markup pattern) favorite button sits in .play-card-actions'
   in-flow bottom row rather than as an image overlay, but should still read as the same
   black-circle badge Practice Plan tiles use — .favorite-toggle-inline's own transparent/flat
   rule above (needed for its other, non-tile usages) had silently dropped that circle here.
   Restoring the circle look (not transparent/gray) and sizing it to match its Delete/Adopt
   row-mates rather than the wider default overlay size. */
.play-card-actions-right .favorite-toggle-inline {
    background: rgba(0, 0, 0, 0.45);
    color: #fff;
    width: 32px;
    height: 32px;
}

.play-card-actions-right .favorite-toggle-inline.favorited {
    color: #f5c518;
}

.favorite-group-swatch {
    width: 16px;
    height: 16px;
    border-radius: 50%;
    flex-shrink: 0;
    border: 1px solid rgba(255, 255, 255, 0.25);
}

.favorite-group-create-form {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.favorite-groups-panel {
    display: flex;
    flex-direction: column;
    gap: 12px;
    background: var(--lighter-bg);
    border-radius: var(--list-container-border-radius);
    padding: 16px;
    margin-bottom: 16px;
}

.favorite-groups-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.favorite-groups-title {
    font-size: 15px;
    font-weight: 700;
    margin: 0;
}

.favorite-groups-add-btn {
    width: auto;
}

.favorite-groups-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.favorite-groups-row {
    display: flex;
    align-items: center;
    gap: 10px;
}

.favorite-groups-name {
    flex: 1;
    font-size: 14px;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.favorite-groups-name-input {
    flex: 1;
}

.favorite-groups-count {
    font-size: 12px;
    color: var(--accent-gray-light);
    flex-shrink: 0;
}

.favorite-groups-icon-btn {
    flex-shrink: 0;
    background: transparent;
    border: none;
    color: var(--accent-gray-light);
    cursor: pointer;
    padding: 6px;
}

.favorite-groups-icon-btn:hover {
    color: var(--text-color);
}

.favorites-group-filter {
    min-width: 160px;
}

.play-card-confirm {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0 12px;
    background: var(--lighter-bg);
    border-radius: var(--list-container-border-radius);
    font-size: 14px;
}

.play-card-confirm span {
    flex: 1;
    min-width: 0;
}

.play-card-confirm-yes,
.play-card-confirm-no {
    padding: 8px 12px;
    border-radius: 6px;
    font-size: 13px;
    font-weight: 600;
    flex-shrink: 0;
}

.play-card-confirm-yes {
    background: var(--error-red);
    color: #fff;
}

.play-card-confirm-no {
    background: var(--darker-bg);
    color: var(--accent-gray-light);
}

/* Overrides .play-card-confirm's single horizontal row (text + buttons side by side) — same
   fix as .media-tile-confirm/.admin-user-card-confirm below: a Play tile is too narrow for the
   message and two buttons on one line, so it wraps/crunches. Stack text on top, actions below. */
.play-card-confirm-stacked {
    flex-direction: column;
    justify-content: center;
    gap: 10px;
    padding: 12px;
    text-align: center;
}

.play-card-confirm-stacked span {
    flex: none;
}

.play-card-confirm-actions {
    display: flex;
    gap: 10px;
    width: 100%;
}

.play-card-confirm-actions .play-card-confirm-yes,
.play-card-confirm-actions .play-card-confirm-no {
    flex: 1;
}
/*#endregion*/

/*#region MEDIA LIBRARY*/
.media-type-tabs {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    margin-bottom: 16px;
}

.media-type-tab {
    background: var(--lighter-bg);
    border: none;
    color: var(--accent-gray-light);
    font-size: 13px;
    font-weight: 600;
    padding: 8px 16px;
    border-radius: 999px;
    cursor: pointer;
}

.media-type-tab.active {
    background: var(--theme-dark);
    color: #fff;
}

.media-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 24px;
    margin-bottom: 100px;
}

@media (min-width: 640px) {
    .media-grid {
        grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    }
}

.media-tile-wrap {
    position: relative;
    min-width: 0;
}

.media-tile {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    width: 100%;
    background: var(--lighter-bg);
    border: 2px solid var(--darker-bg);
    border-radius: var(--list-container-border-radius);
    overflow: hidden;
    cursor: pointer;
    padding: 0;
    text-align: left;
}

.media-tile-icon-wrap {
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 16 / 9;
    background: var(--darker-bg);
    color: var(--accent-gray-light);
    font-size: 40px;
    overflow: hidden;
}

.media-tile-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.media-tile-info {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 10px 12px;
    min-width: 0;
}

.media-tile-name {
    font-size: 14px;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.media-tile-meta {
    font-size: 12px;
    color: var(--accent-gray-light);
}

.media-picker-modal {
    width: min(90vw, 560px);
}

.media-picker-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 12px;
    margin-bottom: 0;
}

@media (min-width: 480px) {
    .media-picker-grid {
        grid-template-columns: repeat(3, 1fr);
    }
}

.media-preview-overlay {
    position: fixed;
    inset: 0;
    z-index: 60;
    background: rgba(0, 0, 0, 0.85);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
}

.media-preview-panel {
    max-width: 100%;
    max-height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}

.media-preview-image,
.media-preview-video {
    max-width: 100%;
    max-height: 90vh;
    border-radius: var(--list-container-border-radius);
}

.media-preview-document {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    background: var(--lighter-bg);
    padding: 32px;
    border-radius: var(--list-container-border-radius);
    color: var(--text-color);
    font-size: 16px;
    font-weight: 600;
    text-align: center;
}

.media-preview-document-icon {
    font-size: 48px;
    color: var(--accent-gray-light);
}

/* Scoped smaller than the default .plays-new-btn pill — that base size (14px text, icon
   inherits it) reads fine as a standalone header action but felt oversized inside this
   compact preview panel. It was ALSO previously catching .media-preview-document i's 48px
   icon rule above by accident (a plain descendant selector matched both the big file-type
   icon and this button's icon) — now both icons have their own scoped class. */
.media-preview-download-btn {
    font-size: 13px;
    padding: 8px 14px;
}

.media-preview-download-btn i {
    font-size: 13px;
}

/* Overrides .play-card-confirm's single horizontal row (text + buttons side by side) — same
   fix as .admin-user-card-confirm, same reason: that layout assumes a wide play tile, and
   media tiles squish it into a crunched single line. Stack text on top, actions below. */
.media-tile-confirm {
    flex-direction: column;
    justify-content: center;
    gap: 10px;
    padding: 12px;
    text-align: center;
}

.media-tile-confirm span {
    flex: none;
}

.media-tile-confirm-actions {
    display: flex;
    gap: 10px;
    width: 100%;
}

.media-tile-confirm-actions .play-card-confirm-yes,
.media-tile-confirm-actions .play-card-confirm-no {
    flex: 1;
}

/* MediaUploadModal reuses AvatarCropper's backdrop/modal/pick-label/actions/cancel classes
   directly rather than duplicating that chrome — it just isn't driven by AvatarCropper's own
   FrameWidth/FrameHeight parameters (no cropping happens here), so the pieces that normally
   come from those inline styles get their own fixed-size overrides below. */
.media-upload-modal {
    width: min(90vw, 420px);
}

.media-upload-pick-label {
    /* The base .avatar-cropper-pick-label rule sets width:100% under the default content-box
       model — adding padding here without also switching to border-box pushed the label's
       rendered width past the modal's own edges by 2x this padding plus its border. */
    box-sizing: border-box;
    height: auto;
    padding: 24px;
}

.media-upload-preview-image {
    max-width: 100%;
    max-height: 200px;
    border-radius: var(--list-container-border-radius);
    margin: 8px 0;
    object-fit: contain;
}

.media-upload-file-meta {
    font-size: 13px;
    color: var(--accent-gray-light);
    margin: 8px 0;
}

.media-upload-description {
    height: 80px;
    resize: vertical;
}
/*#endregion*/

/*#region AUTH*/
.auth-page {
    max-width: 360px;
    margin: 0 auto;
    padding-top: 16px;
    display: flex;
    flex-direction: column;
}

.auth-logo {
    height: 40px;
    width: auto;
    align-self: center;
    margin-bottom: 16px;
}

.auth-title {
    font-size: 22px;
    font-weight: 700;
    text-align: center;
    margin-bottom: 24px;
}

.auth-subtext {
    font-size: 14px;
    color: var(--accent-gray-light);
    margin-bottom: 16px;
}

.auth-label {
    display: block;
    font-size: 13px;
    font-weight: 500;
    color: var(--accent-gray-light);
    margin-bottom: 6px;
    margin-top: 16px;
}

.auth-label:first-of-type {
    margin-top: 0;
}

/* Border is transparent at rest (not just "none") so the 1px box stays the same size when
   :focus turns it orange — no layout jump. Background is a tone lighter than --lighter-bg so
   the field still reads as its own box even with no visible border, since it's used inside
   --lighter-bg cards/modals as often as directly on the darker page background. */
.auth-input {
    width: 100%;
    background: var(--lightest-bg);
    border: 1px solid transparent;
    border-radius: var(--list-container-border-radius);
    padding: 12px 14px;
    font-size: 15px;
    color: var(--text-color);
    font-family: inherit;
    box-sizing: border-box;
}

.auth-input:focus {
    outline: none;
    border-color: var(--theme-dark);
}

.auth-error {
    display: block;
    color: var(--error-red);
    font-size: 13px;
    margin-top: 6px;
}

.auth-hint {
    color: var(--accent-gray-light);
    font-size: 12px;
    margin: 6px 0 0;
}

.auth-checkbox {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 16px;
    font-size: 14px;
}

.auth-submit {
    width: 100%;
    background: var(--theme-dark);
    color: var(--darker-bg);
    border: none;
    border-radius: var(--list-container-border-radius);
    padding: 14px;
    font-size: 15px;
    font-weight: 700;
    font-family: inherit;
    cursor: pointer;
    margin-top: 24px;
}

.auth-submit:disabled {
    opacity: 0.6;
    cursor: default;
}

a.auth-submit {
    display: block;
    box-sizing: border-box;
    text-align: center;
    text-decoration: none;
}

.auth-link-button {
    display: block;
    width: 100%;
    background: none;
    border: none;
    color: var(--accent-gray-light);
    font-size: 14px;
    font-family: inherit;
    padding: 12px 0 0;
    cursor: pointer;
    text-align: center;
}

.auth-footer {
    text-align: center;
    font-size: 14px;
    color: var(--accent-gray-light);
    margin-top: 32px;
}

.auth-footer a {
    color: var(--theme-light);
    font-weight: 500;
}
/*#endregion*/

/*#region TOAST*/
.toast-container {
    position: fixed;
    top: 25px;
    left: 50%;
    transform: translateX(-50%);
    width: calc(100% - 32px);
    max-width: 500px;
    z-index: 50;
    display: flex;
    flex-direction: column;
    gap: 8px;
    pointer-events: none;
}

.toast {
    display: flex;
    align-items: center;
    gap: 10px;
    background: var(--theme-dark);
    color: #fff;
    border-radius: 4px;
    padding: 14px 16px;
    font-size: 14px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
}

.toast-icon {
    flex-shrink: 0;
    font-size: 16px;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
}

.toast-text {
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
}

.toast-success {
    background: var(--accent-green-dark);
}

.toast-error {
    background: var(--error-red);
}
/*#endregion*/

/*#region PWA INSTALL PROMPT*/
.pwa-install-prompt {
    position: fixed;
    left: 50%;
    bottom: 16px;
    transform: translateX(-50%);
    z-index: 55;
    display: flex;
    align-items: center;
    gap: 14px;
    width: calc(100% - 32px);
    max-width: 480px;
    background: var(--lighter-bg);
    border: 1px solid var(--list-container-border-color);
    border-radius: var(--list-container-border-radius);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
    padding: 14px 16px;
    box-sizing: border-box;
    animation: pwa-install-prompt-slide-up 0.25s ease-out;
}

@keyframes pwa-install-prompt-slide-up {
    from {
        transform: translate(-50%, 20px);
        opacity: 0;
    }
    to {
        transform: translate(-50%, 0);
        opacity: 1;
    }
}

.pwa-install-prompt-icon {
    flex-shrink: 0;
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 8px;
    background: var(--darker-bg);
    color: var(--theme-dark);
    font-size: 16px;
}

.pwa-install-prompt-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    flex: 1;
}

.pwa-install-prompt-title {
    font-size: 14px;
    font-weight: 700;
}

.pwa-install-prompt-subtitle {
    font-size: 12px;
    color: var(--accent-gray-light);
}

.pwa-install-prompt-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
}

.pwa-install-prompt-install-btn:disabled {
    opacity: 0.6;
    cursor: default;
}

.pwa-install-prompt-close-btn {
    background: none;
    border: none;
    color: var(--accent-gray-light);
    font-size: 16px;
    cursor: pointer;
    padding: 4px;
}

.pwa-install-prompt-close-btn:hover {
    color: var(--text-color);
}
/*#endregion*/

/*#region WHITEBOARD*/
.whiteboard-error-screen {
    position: fixed;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 14px;
    padding: 24px;
    text-align: center;
    background: var(--main-bg);
}

.whiteboard-error-screen i {
    font-size: 34px;
    color: var(--error-red);
}

.whiteboard-error-screen p {
    max-width: 320px;
    color: var(--accent-gray-light);
}

.whiteboard-error-actions {
    display: flex;
    gap: 10px;
}

.whiteboard-error-retry,
.whiteboard-error-back {
    padding: 10px 18px;
    border-radius: var(--list-container-border-radius);
    font-size: 14px;
    font-weight: 600;
}

.whiteboard-error-retry {
    background: var(--theme-dark);
    color: #fff;
}

.whiteboard-error-back {
    background: var(--lighter-bg);
    color: var(--accent-gray-light);
}

.whiteboard-loading-placeholder {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--main-bg);
    color: var(--theme-dark);
}

.whiteboard-canvas-area {
    position: fixed;
    inset: 0;
}

.whiteboard-canvas-area.with-strip {
    top: calc(56px + env(safe-area-inset-top));
    transition: top 0.2s ease;
}

.whiteboard-canvas-area.with-sidebar {
    left: 150px;
}

.whiteboard-canvas-area.with-sidebar.sidebar-collapsed {
    left: 36px;
}

/* UnityWhiteboardHost is a single persistent instance (mounted once outside <Router>, see
   App.razor) — when no Play/Moment page has currently claimed it, it stays fully hidden instead
   of covering whatever page IS showing underneath it. */
.whiteboard-canvas-area.unity-host-inactive {
    display: none;
}

.unity-host {
    position: relative;
    width: 100%;
    height: 100%;
    background: #fff;
    overflow: hidden;
}

.unity-host-loading {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 10;
    background: var(--main-bg);
}

.unity-host-loading i {
    font-size: 40px;
    color: var(--theme-dark);
}

#unity-container {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}

.unity-canvas-frame {
    position: relative;
    aspect-ratio: 16 / 9;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

#unity-canvas {
    outline: none;
    background: #231F20;
}

#unity-loading-bar {
    display: none;
}

#unity-warning {
    position: absolute;
    top: 8px;
    left: 50%;
    transform: translateX(-50%);
    max-width: 90%;
    z-index: 5;
}

.whiteboard-strip {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 56px;
    z-index: 20;
    background: var(--darker-bg);
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 12px;
    padding-top: env(safe-area-inset-top);
    box-sizing: content-box;
    overflow-x: auto;
    transition: transform 0.2s ease;
}

.whiteboard-header-collapse-toggle {
    display: none;
    position: fixed;
    top: calc(56px + env(safe-area-inset-top));
    left: 50%;
    transform: translateX(-50%);
    z-index: 21;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 16px;
    background: var(--darker-bg);
    color: var(--text-color);
    border: none;
    border-radius: 0 0 10px 10px;
    font-size: 11px;
    cursor: pointer;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
    transition: top 0.2s ease;
}

.whiteboard-header-collapse-toggle.is-collapsed {
    top: env(safe-area-inset-top);
}

/* Phone-only: the header strip already gets tight on a phone-width screen, so trading it away
   temporarily for a bigger rink is worth the tap — on a tablet/desktop there's room to spare,
   so the toggle stays hidden and any collapsed state left over from a narrower session has no
   visual effect (the strip/canvas/sidebar overrides below are scoped the same way). The first
   condition (max-width: 639px, the same phone-width cutover used elsewhere in the whiteboard
   UI — see the modal tab icons) catches phones in PORTRAIT. It never fires in LANDSCAPE, where
   a phone's width is typically 700-900px — vertical room is exactly what's scarce there, so the
   second condition catches any short, touch-driven viewport instead. pointer:coarse keeps a
   desktop browser window that's merely been resized short from tripping it. */
@media (max-width: 639px), ((max-height: 480px) and (pointer: coarse)) {
    .whiteboard-header-collapse-toggle {
        display: flex;
    }

    .whiteboard-strip.is-collapsed {
        transform: translateY(-100%);
        pointer-events: none;
    }

    .whiteboard-canvas-area.with-strip.header-collapsed {
        top: env(safe-area-inset-top);
    }

    .whiteboard-sidebar.with-strip.header-collapsed {
        top: env(safe-area-inset-top);
    }
}

/* Extra breathing room next to the animation toggle specifically in this header — the base
   .practice-plan-slot-assigned-players rule stays untouched so the content slot tile's own
   layout (driven by its parent's block flow, not a flex gap) is unaffected. */
.whiteboard-strip .practice-plan-slot-assigned-players {
    margin-left: 8px;
}

.whiteboard-strip-tags {
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: 10px;
    color: var(--theme-dark);
    margin-left: 22px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.whiteboard-strip-tags i {
    font-size: 10px;
}


.whiteboard-playback-controls .strip-btn:hover {
    background: rgba(255, 255, 255, 0.1);
}

.strip-btn {
    background: var(--lighter-bg);
    border: none;
    color: var(--text-color);
    font-size: 13px;
    font-weight: 600;
    padding: 8px 12px;
    border-radius: var(--list-container-border-radius);
    cursor: pointer;
    white-space: nowrap;
}

.strip-btn.active {
    background: var(--theme-dark);
    color: #fff;
}

.strip-select {
    background: var(--lighter-bg);
    border: none;
    color: var(--text-color);
    font-size: 13px;
    padding: 8px 10px;
    border-radius: var(--list-container-border-radius);
    flex-shrink: 0;
}

.strip-save {
    margin-left: auto;
    background: var(--theme-dark);
    color: #fff;
}

.moment-tool-group {
    display: flex;
    align-items: center;
    gap: 8px;
}

.moment-tool-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    flex-shrink: 0;
    border-radius: 50%;
    background: var(--lighter-bg);
    color: var(--text-color);
    border: none;
    font-size: 15px;
    cursor: pointer;
}

.moment-tool-btn.active {
    background: var(--theme-dark);
    color: #fff;
}

.moment-palette {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-shrink: 0;
}

.moment-palette-swatch {
    width: 24px;
    height: 24px;
    flex-shrink: 0;
    border-radius: 50%;
    border: 2px solid transparent;
    cursor: pointer;
    padding: 0;
}

.moment-palette-swatch.selected {
    border-color: var(--text-color);
    box-shadow: 0 0 0 2px var(--darker-bg);
}

.whiteboard-fab {
    position: fixed;
    bottom: 16px;
    right: 16px;
    z-index: 20;
    width: 52px;
    height: 52px;
    border-radius: 50%;
    background: var(--theme-dark);
    color: #fff;
    border: none;
    font-size: 18px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
    cursor: pointer;
}

.whiteboard-exit-btn {
    position: fixed;
    bottom: 16px;
    left: 16px;
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 52px;
    height: 52px;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    border: none;
    font-size: 18px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
    cursor: pointer;
}


.whiteboard-sidebar {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 84px;
    width: 150px;
    /* Above .whiteboard-strip's z-index:20 — the sidebar establishes its own stacking context
       (position + z-index), which traps any position:fixed descendant's z-index (e.g. the
       commentary playback fullscreen overlay) inside it. If the sidebar itself ranked below the
       header, that trapped overlay would render behind the header no matter how high its own
       z-index was set. They never actually overlap on screen: whenever the header is visible,
       .with-strip pushes the sidebar's top below it. */
    z-index: 21;
    background: var(--lighter-bg);
    border-right: 1px solid rgba(255, 255, 255, 0.08);
    overflow-y: auto;
    overflow-x: hidden;
    transition: width 0.2s ease, top 0.2s ease;
}

.whiteboard-sidebar.with-strip {
    top: calc(56px + env(safe-area-inset-top));
}

.whiteboard-sidebar.collapsed {
    width: 36px;
}

.whiteboard-sidebar-toggle {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    background: none;
    border: none;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    color: var(--text-color);
    font-size: 13px;
    font-weight: 600;
    padding: 10px 12px;
    cursor: pointer;
    white-space: nowrap;
}

.whiteboard-sidebar.collapsed .whiteboard-sidebar-toggle {
    justify-content: center;
    padding: 10px 0;
}

.whiteboard-sidebar-toggle:hover {
    background: rgba(255, 255, 255, 0.06);
}

.whiteboard-sidebar-body {
    padding: 12px;
}

.whiteboard-sidebar-body select.strip-select {
    width: 100%;
}

.whiteboard-modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 30;
}

.whiteboard-modal {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    max-height: 70vh;
    background: var(--lighter-bg);
    border-radius: 16px 16px 0 0;
    z-index: 31;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    padding-bottom: env(safe-area-inset-bottom);
}

.whiteboard-modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    border-bottom: 1px solid var(--list-container-border-color);
    padding: 8px 8px 8px 16px;
    flex-shrink: 0;
}

.whiteboard-modal-tabs {
    display: flex;
    gap: 4px;
    /* 5 full-text tabs (Metadata/Animation/Tags/Publish/Commentary) can outgrow the header at
       tablet-ish widths, above the 639px icon-swap breakpoint — scrolls instead of overlapping
       the close button or wrapping awkwardly. */
    overflow-x: auto;
    scrollbar-width: none;
    /* Takes all remaining header width so .whiteboard-modal-header-actions (Adopt + Close)
       stays pinned flush-right instead of floating mid-header the way a 3-child
       justify-content:space-between would. min-width:0 is required alongside flex:1 for the
       overflow-x:auto above to actually have room to kick in instead of forcing the header wider. */
    flex: 1 1 auto;
    min-width: 0;
}

.whiteboard-modal-tabs::-webkit-scrollbar {
    display: none;
}

.modal-tab {
    background: none;
    border: none;
    color: var(--accent-gray-light);
    font-size: 14px;
    font-weight: 600;
    flex-shrink: 0;
    padding: 10px 12px;
    border-radius: var(--list-container-border-radius);
    cursor: pointer;
}

.modal-tab.active {
    color: #fff;
    background: var(--darker-bg);
}

.modal-tab-icon {
    display: none;
}

/* Below the same 640px cutover used for the Plays list grid — tab labels give way to icons
   so four tabs fit a phone-width header without wrapping or squeezing unreadably small. */
@media (max-width: 639px) {
    .modal-tab-icon {
        display: inline-block;
        font-size: 16px;
    }

    .modal-tab-label {
        display: none;
    }

    .modal-tab {
        padding: 10px;
    }
}

.whiteboard-modal-header-actions {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
}

.modal-close {
    background: none;
    border: none;
    color: var(--text-color);
    font-size: 18px;
    padding: 8px;
    cursor: pointer;
}

.modal-adopt-btn {
    background: none;
    border: none;
    color: var(--accent-gray-light);
    font-size: 16px;
    padding: 8px;
    cursor: pointer;
}

.modal-adopt-btn:hover {
    color: var(--theme-light);
}

.whiteboard-modal-body {
    padding: 16px;
    overflow-y: auto;
}

.whiteboard-modal-textarea {
    min-height: 90px;
    resize: vertical;
    font-family: inherit;
}

.rich-text-editor {
    width: 100%;
    box-sizing: border-box;
}

.rich-text-toolbar {
    display: flex;
    gap: 4px;
    padding: 6px;
    background: var(--lightest-bg);
    border: 1px solid transparent;
    border-bottom: none;
    border-radius: var(--list-container-border-radius) var(--list-container-border-radius) 0 0;
}

.rich-text-btn {
    width: 30px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 6px;
    color: var(--text-color);
    cursor: pointer;
    font-size: 0.9rem;
}

.rich-text-btn:hover {
    background: var(--list-container-border-color);
}

.rich-text-btn.active {
    background: var(--theme-dark);
    color: #fff;
}

.rich-text-select {
    height: 30px;
    background: var(--lightest-bg);
    border: 1px solid transparent;
    border-radius: 6px;
    color: var(--text-color);
    font-family: inherit;
    font-size: 0.85rem;
    padding: 0 4px;
    /* Hints the browser to render the native dropdown popup (and its default option colors)
       in light mode, since --text-color is light in this app's dark theme but <option> popups
       mostly ignore custom color/background CSS and fall back to the platform default anyway. */
    color-scheme: light;
}

.rich-text-select:focus {
    outline: none;
    border-color: var(--theme-dark);
}

/* <option> reliably supports only color/background-color across browsers — everything else
   in the popup is native chrome. Pinned to concrete values (not theme variables) so the text
   stays legible against the light popup background regardless of the app's dark theme. */
.rich-text-select option {
    color: #1a1a1a;
    background-color: #ffffff;
}

.rich-text-color {
    width: 30px;
    height: 30px;
    padding: 2px;
    background: var(--lightest-bg);
    border: 1px solid transparent;
    border-radius: 6px;
    cursor: pointer;
}

.rich-text-color:focus {
    outline: none;
    border-color: var(--theme-dark);
}

.rich-text-link-bar {
    display: flex;
    gap: 4px;
    padding: 6px;
    background: var(--lightest-bg);
    border: 1px solid transparent;
    border-top: none;
    border-bottom: none;
}

/* Already sits on --darker-bg, one tone below the toolbar's --lightest-bg, so it reads as its
   own (recessed) box without needing the same lighter-background bump the rest of this family
   gets — only the border needs to go transparent. */
.rich-text-link-input {
    flex: 1;
    min-width: 0;
    height: 30px;
    background: var(--darker-bg);
    border: 1px solid transparent;
    border-radius: 6px;
    color: var(--text-color);
    font-family: inherit;
    font-size: 0.85rem;
    padding: 0 8px;
}

.rich-text-link-input:focus {
    outline: none;
    border-color: var(--theme-dark);
}

.rich-text-link-confirm,
.rich-text-link-cancel {
    width: 30px;
    height: 30px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 1px solid var(--list-container-border-color);
    border-radius: 6px;
    cursor: pointer;
    font-size: 0.9rem;
}

.rich-text-link-confirm {
    color: var(--accent-green);
}

.rich-text-link-cancel {
    color: var(--error-red);
}

.rich-text-link-confirm:hover,
.rich-text-link-cancel:hover {
    background: var(--list-container-border-color);
}

.rich-text-content {
    min-height: 90px;
    max-height: 240px;
    overflow-y: auto;
    background: var(--lightest-bg);
    border: 1px solid transparent;
    border-radius: 0 0 var(--list-container-border-radius) var(--list-container-border-radius);
    padding: 12px 14px;
    color: var(--text-color);
    font-family: inherit;
}

.rich-text-content:focus {
    outline: none;
    border-color: var(--theme-dark);
}

/* Horizontal divider between the play metadata modal's tab header and body — half as visible
   as the app's default border color, at the user's request. */
.play-metadata-modal .whiteboard-modal-header {
    border-bottom-color: rgba(151, 151, 151, 0.5);
}

.rich-text-content p {
    margin: 0 0 8px;
}

/* The app-wide CSS reset (ol, ul { list-style: none; }) kills bullet/number rendering
   everywhere — restore it here so the toolbar's bulleted/numbered list commands are actually
   visible, not just structurally present in the HTML (same issue as the b/i/u rules below). */
.rich-text-content ul,
.rich-text-content ol {
    margin: 0 0 8px;
    padding-left: 24px;
}

.rich-text-content ul {
    list-style: disc;
}

.rich-text-content ol {
    list-style: decimal;
}

/* The app-wide CSS reset (html, body, ... b, u, i, ... { font-weight: inherit; font-style:
   inherit; ... }) neutralizes <b>/<i>/<u>'s native rendering everywhere — restore it here so
   the toolbar's Bold/Italic/Underline commands are actually visible, not just structurally
   present in the HTML. */
.rich-text-content b,
.rich-text-content strong {
    font-weight: bold;
}

.rich-text-content i,
.rich-text-content em {
    font-style: italic;
}

.rich-text-content u {
    text-decoration: underline;
}

/* The app-wide `a { color: inherit; text-decoration: none; }` rule makes links indistinguishable
   from surrounding text — restore real link styling here, same reasoning as b/i/u above. */
.rich-text-content a {
    color: var(--theme-dark);
    text-decoration: underline;
}

/* No toolbar → the content box is the whole editor, round every corner. */
.rich-text-editor:has(.rich-text-toolbar) .rich-text-content {
    border-radius: 0 0 var(--list-container-border-radius) var(--list-container-border-radius);
}

.rich-text-editor:not(:has(.rich-text-toolbar)) .rich-text-content {
    border-radius: var(--list-container-border-radius);
    /* Same "no toolbar" signal as the border-radius rule above — the toolbar is only rendered
       when ReadOnly is false (RichTextEditor.razor), so its absence means this is a read-only
       viewer (Feedback's player-facing detail view is the main case) rather than the coach's
       own editor. The bounded 240px scrollable box is reasonable while actively composing, but
       a read-only viewer has no toolbar/focus affordance hinting "scroll for more" — longer
       feedback just read as cut off. Auto-size instead, matching the read-only
       .whiteboard-readonly-description pattern already used for Play descriptions. */
    max-height: none;
    overflow-y: visible;
}

/* Read-only Play details (PlayMetadataModal, !CanEdit) — plain text, deliberately with none of
   auth-input's or rich-text-content's editable-looking border/focus ring, so it doesn't read
   as an editable field to a viewer who can't actually edit it. */
.whiteboard-readonly-title {
    margin: 0 0 16px;
    font-size: 20px;
    font-weight: 600;
    color: var(--text-color);
}

/* A flat black overlay (not a new hardcoded hex) so this stays a step darker than the modal's
   own --lighter-bg background no matter what that variable is set to. */
.whiteboard-readonly-description {
    background: rgba(0, 0, 0, 0.15);
    border-radius: var(--list-container-border-radius);
    padding: 16px;
    color: var(--text-color);
    font-size: 15px;
    line-height: 1.5;
}

.whiteboard-readonly-description p {
    margin: 0 0 8px;
}

.whiteboard-readonly-description ul,
.whiteboard-readonly-description ol {
    margin: 0 0 8px;
    padding-left: 24px;
}

.whiteboard-readonly-description ul {
    list-style: disc;
}

.whiteboard-readonly-description ol {
    list-style: decimal;
}

.whiteboard-readonly-description b,
.whiteboard-readonly-description strong {
    font-weight: bold;
}

.whiteboard-readonly-description i,
.whiteboard-readonly-description em {
    font-style: italic;
}

.whiteboard-readonly-description u {
    text-decoration: underline;
}

.whiteboard-readonly-description a {
    color: var(--theme-dark);
    text-decoration: underline;
}

.whiteboard-readonly-strategy {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 16px;
    font-size: 14px;
}

.whiteboard-readonly-strategy-yes {
    color: var(--accent-green);
}

.whiteboard-readonly-strategy-no {
    color: var(--error-red);
}

.whiteboard-modal-save {
    margin: 16px auto 0;
    width: 100%;
    max-width: 250px;
    background: var(--theme-dark);
    color: #fff;
    border: none;
    border-radius: var(--list-container-border-radius);
    padding: 12px;
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
}

.whiteboard-modal-save:disabled {
    opacity: 0.6;
    cursor: default;
}

/* Same specificity as the base rule above, so this must stay physically AFTER it in the
   file — CSS resolves equal-specificity ties by source order, not by which one is inside a
   media query, and a copy of this rule placed earlier in the stylesheet was silently losing
   to the base rule's unconditional max-width regardless of viewport width. */
@media (max-width: 639px) {
    .whiteboard-modal-save {
        max-width: none;
    }
}

.whiteboard-anim-controls {
    display: flex;
    gap: 8px;
    margin-bottom: 16px;
}

.whiteboard-anim-controls .strip-btn {
    flex: 1;
    text-align: center;
}

.whiteboard-checkbox-label {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 16px;
    font-size: 14px;
}

.whiteboard-anim-panel {
    position: fixed;
    top: 80px;
    right: 16px;
    width: 260px;
    background: var(--lighter-bg);
    border-radius: var(--list-container-border-radius);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
    z-index: 25;
    overflow: hidden;
}

/* Opposite corner from the animation panel — the two aren't expected to be open at the
   same time, but keeping distinct defaults avoids them ever landing on top of each other. */
.whiteboard-commentary-panel {
    right: auto;
    left: 16px;
}

.whiteboard-anim-panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 8px 8px 12px;
    background: var(--darker-bg);
    cursor: grab;
    touch-action: none;
    user-select: none;
}

.whiteboard-anim-panel-header.dragging {
    cursor: grabbing;
}

.whiteboard-anim-panel-title {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    font-weight: 600;
    color: var(--accent-gray-light);
}

.whiteboard-anim-panel-close {
    background: none;
    border: none;
    color: var(--text-color);
    font-size: 16px;
    padding: 4px;
    cursor: pointer;
}

.whiteboard-anim-panel-body {
    padding: 12px;
}

.whiteboard-anim-panel-body .whiteboard-anim-controls {
    margin-bottom: 12px;
}

.whiteboard-anim-panel-body .whiteboard-checkbox-label {
    margin-top: 12px;
}

.whiteboard-team-toggle {
    display: flex;
    gap: 4px;
    margin-bottom: 12px;
}

.whiteboard-team-toggle .strip-btn {
    flex: 1;
    text-align: center;
    font-size: 15px;
}

.whiteboard-team-toggle .team-btn-x.active {
    background: #2F6FED;
    color: #fff;
}

.whiteboard-team-toggle .team-btn-o.active {
    background: var(--error-red);
    color: #fff;
}

.whiteboard-team-toggle .team-btn-c.active {
    background: #D9A400;
    color: #1a1a1a;
}

.whiteboard-anim-panel-restore-link {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    background: none;
    border: 1px solid var(--error-red);
    color: var(--error-red);
    font-size: 13px;
    font-weight: 600;
    padding: 8px 12px;
    border-radius: var(--list-container-border-radius);
    cursor: pointer;
    margin-bottom: 12px;
}

.whiteboard-anim-divider {
    border: none;
    border-top: 1px solid rgba(255, 255, 255, 0.1);
    margin: 16px 0;
}

.commentary-replace-notice {
    font-size: 12px;
    color: var(--accent-gray-light);
    margin-bottom: 8px;
}

.commentary-recording-indicator {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 14px;
    margin-bottom: 16px;
}

.commentary-rec-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--error-red);
    animation: commentary-pulse 1.2s ease-in-out infinite;
}

@keyframes commentary-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.3; }
}

.commentary-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-top: 16px;
}

.commentary-item {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
}

.commentary-item-play {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    min-width: 0;
    background: var(--darker-bg);
    border-radius: var(--list-container-border-radius);
    padding: 10px 12px;
    text-align: center;
}

.commentary-item-play i {
    font-size: 22px;
    color: var(--theme-dark);
    flex-shrink: 0;
}

.commentary-item-info {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.commentary-item-label {
    font-size: 14px;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.commentary-item-date {
    font-size: 12px;
    color: var(--accent-gray-light);
}

.commentary-delete {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    background: rgba(0, 0, 0, 0.6);
    color: var(--error-red);
    border: none;
    border-radius: 6px;
    height: 36px;
    flex-shrink: 0;
    cursor: pointer;
}

.commentary-fullscreen-overlay {
    position: fixed;
    inset: 0;
    z-index: 60;
    background: #000;
    display: flex;
    align-items: center;
    justify-content: center;
}

.commentary-fullscreen-video {
    max-width: 100%;
    max-height: 100%;
}

.commentary-fullscreen-close {
    position: fixed;
    top: calc(12px + env(safe-area-inset-top));
    right: 12px;
    z-index: 61;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.6);
    color: #fff;
    border: none;
    border-radius: 50%;
    font-size: 18px;
    cursor: pointer;
}

.whiteboard-confirm-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.6);
    z-index: 70;
}

.whiteboard-confirm-modal {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: min(90%, 360px);
    background: var(--lighter-bg);
    border-radius: var(--list-container-border-radius);
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
    z-index: 71;
    padding: 20px;
}

.whiteboard-confirm-title {
    font-size: 18px;
    font-weight: 700;
    margin-bottom: 8px;
}

.whiteboard-confirm-body {
    font-size: 14px;
    color: var(--accent-gray-light);
    margin-bottom: 20px;
}

.whiteboard-confirm-actions {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

/* .whiteboard-modal-save carries its own max-width:250px/centered-margin for its other uses
   (the Description tab, Publish tab) — overridden here so all three confirm-modal buttons
   actually match the same full-width sizing. */
.whiteboard-confirm-actions .whiteboard-modal-save {
    max-width: none;
    margin: 0;
}

.whiteboard-confirm-user-list {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 6px;
    max-height: 200px;
    overflow-y: auto;
    margin-bottom: 20px;
}

.whiteboard-confirm-user-list-item {
    background: var(--darker-bg);
    border-radius: var(--list-container-border-radius);
    padding: 8px 12px;
    font-size: 14px;
}

.whiteboard-confirm-disregard,
.whiteboard-confirm-cancel {
    width: 100%;
    padding: 10px 12px;
    border: none;
    border-radius: var(--list-container-border-radius);
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
}

.whiteboard-confirm-disregard {
    background: rgba(220, 53, 69, 0.15);
    color: var(--error-red);
}

.whiteboard-confirm-cancel {
    background: var(--darker-bg);
    color: var(--accent-gray-light);
}
/*#endregion*/

/*#region TAGS PANEL*/
/* Two panels: the tag groups on one side, the add-a-tag form on the other. Stacked (groups
   above add-form) on mobile, side-by-side above the same 640px cutover the rest of the app's
   mobile/desktop CSS already uses (see the modal tab icon/label swap below). */
.tags-panel-columns {
    display: flex;
    flex-direction: column;
    gap: 24px;
}

@media (min-width: 640px) {
    .tags-panel-columns {
        flex-direction: row;
        align-items: flex-start;
    }

    .tags-panel-groups {
        flex: 1 1 60%;
        min-width: 0;
    }

    .tags-panel-add {
        flex: 1 1 40%;
        min-width: 0;
        /* A little breathing room from the groups panel above it on mobile isn't needed once
           they're side by side and already separated by the column gap. */
        position: sticky;
        top: 0;
    }
}

.tags-section {
    margin-top: 16px;
}

.tags-section:first-child {
    margin-top: 0;
}

.tags-section-title {
    font-size: 13px;
    font-weight: 500;
    color: var(--accent-gray-light);
    margin-bottom: 8px;
}

.tag-chip-list {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.tag-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: transparent;
    border: 1px solid var(--list-container-border-color);
    border-radius: 999px;
    padding: 6px 14px;
    font-size: 14px;
    cursor: pointer;
}

/* Same "border + text now, solid + white text once selected" mechanic for all three, just a
   different color per scope — orange/purple/green matches the same trio already used for the
   practice-plan schedule badges (upcoming/completed/today), so the scope color reads the same
   way across the app instead of introducing a fourth, unrelated palette. */
.tag-chip-global {
    border-color: var(--theme-dark);
    color: var(--theme-dark);
}

.tag-chip-global.tag-chip-selected {
    background: var(--theme-dark);
    border-color: var(--theme-dark);
    color: #fff;
}

/* Lighter than --accent-light (#6231A7, reserved for admin-only surfaces) — this is the same
   lighter violet already used for .practice-plan-scheduled-date, so it reads as "purple" without
   being confused for the admin accent color. */
.tag-chip-org {
    border-color: #8B5CF6;
    color: #8B5CF6;
}

.tag-chip-org.tag-chip-selected {
    background: #8B5CF6;
    border-color: #8B5CF6;
    color: #fff;
}

.tag-chip-private {
    border-color: var(--accent-green-dark);
    color: var(--accent-green-dark);
}

.tag-chip-private.tag-chip-selected {
    background: var(--accent-green-dark);
    border-color: var(--accent-green-dark);
    color: #fff;
}

.tag-chip-readonly {
    cursor: default;
}

.tag-chip-delete {
    font-size: 11px;
    opacity: 0.7;
}

.tag-chip-delete:hover {
    opacity: 1;
}

.tags-panel-add .auth-input {
    margin: 0 0 12px;
}

.tag-add-scope-fixed {
    font-size: 13px;
    color: var(--accent-gray-light);
    margin: 0 0 12px;
}

.tag-add-btn {
    flex-shrink: 0;
    background: var(--theme-dark);
    color: #fff;
    border: none;
    border-radius: var(--list-container-border-radius);
    padding: 0 18px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
}

.tag-add-btn:disabled {
    opacity: 0.6;
    cursor: default;
}

.tag-add-btn-full {
    width: 100%;
    height: 44px;
}
/*#endregion*/

/*#region PUBLISH PANEL*/
.publish-subpanel {
    margin-top: 20px;
}

.publish-subpanel:first-child {
    margin-top: 0;
}

.publish-subpanel-title {
    font-size: 15px;
    font-weight: 700;
    margin-bottom: 10px;
}

.coach-seasons-title {
    margin-top: 24px;
}

.coach-new-season-btn {
    margin-top: 12px;
}

.practice-plan-share-hint {
    font-size: 12px;
    color: var(--accent-gray-light);
    margin: -6px 0 10px;
}

.content-visibility-hint {
    font-size: 12px;
    color: var(--accent-gray-light);
    margin: 20px 0 10px;
}

.practice-plan-share-roster-entry {
    display: flex;
    flex-direction: column;
    line-height: 1.3;
}

.practice-plan-share-roster-email {
    font-size: 12px;
    color: var(--accent-gray-light);
}

/* Save/Close as an equal-width pair, same treatment as .avatar-cropper-actions — overrides
   .whiteboard-modal-save's own centered/max-width-250px default so it doesn't out-size Close. */
.practice-plan-share-actions {
    display: flex;
    gap: 10px;
    margin-top: 16px;
}

.practice-plan-share-actions .whiteboard-modal-save,
.practice-plan-share-actions .avatar-cropper-cancel {
    flex: 1;
    width: auto;
    max-width: none;
    margin: 0;
}

.publish-roster {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin-top: 10px;
    max-height: 180px;
    overflow-y: auto;
    background: var(--darker-bg);
    border-radius: var(--list-container-border-radius);
    padding: 8px 12px;
}

.publish-roster-row .filter-checkbox {
    padding: 4px 0;
}
/*#endregion*/

/*#region USER PROFILE*/
@media (min-width: 640px) {
    .profile-page {
        max-width: 500px;
        margin-left: auto;
        margin-right: auto;
    }
}

.profile-avatar-section {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    margin-bottom: 24px;
}

.profile-avatar {
    width: 96px;
    height: 96px;
    border-radius: 50%;
    object-fit: cover;
}

.profile-avatar-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--darker-bg);
    color: var(--theme-light);
    font-size: 32px;
    font-weight: 700;
}

.profile-avatar-change {
    background: none;
    border: 1px solid var(--list-container-border-color);
    border-radius: var(--list-container-border-radius);
    color: var(--text-color);
    font-size: 13px;
    font-weight: 600;
    padding: 8px 16px;
    cursor: pointer;
}

.practice-plan-cover-section {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    margin-bottom: 24px;
}

.practice-plan-cover-image {
    width: 100%;
    max-width: 480px;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    border-radius: var(--list-container-border-radius);
}

.practice-plan-cover-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--darker-bg);
    color: var(--accent-gray-light);
    font-size: 32px;
}

.practice-plan-cover-actions {
    display: flex;
    gap: 8px;
}

.playbook-form-plays-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 8px;
}

.playbook-form-plays-header .tags-section-title {
    margin-bottom: 0;
}

.practice-plan-meta-row {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    margin-top: 20px;
    margin-bottom: 4px;
}

.practice-plan-meta-row > div {
    flex: 1 1 200px;
    min-width: 160px;
}

.practice-plan-add-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.practice-plan-notes-input {
    width: 100%;
}

.practice-plan-slot-text-input {
    width: 100%;
    resize: vertical;
    font-family: inherit;
}

.practice-plan-duration-input {
    width: 70px;
    flex-shrink: 0;
}

.practice-plan-slot-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.practice-plan-slot-item {
    display: flex;
    align-items: center;
    gap: 12px;
    background: var(--lighter-bg);
    border-radius: var(--list-container-border-radius);
    padding: 10px 12px;
    /* Transparent by default (not just "no border") so applying the over-budget red border
       below doesn't change the item's box size and shift the rest of the list. */
    border: 2px solid transparent;
}

.practice-plan-slot-item-over-budget {
    border-color: var(--error-red);
}

.practice-plan-slot-time-warning {
    position: absolute;
    left: 6px;
    bottom: 6px;
    background: var(--error-red);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
    padding: 5px 8px;
    border-radius: 5px;
    white-space: nowrap;
}

.practice-plan-slot-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    /* Fixed 356x200 (16:9) so every slot's preview is identically sized regardless of content
       type or the row's own height — object-fit:cover on the img crops to fit rather than
       distorting the source image's real proportions. */
    width: 356px;
    height: 200px;
    flex-shrink: 0;
    border-radius: 8px;
    background: var(--darker-bg);
    color: var(--accent-gray-light);
    font-size: 15px;
    overflow: hidden;
    position: relative;
}

.practice-plan-slot-assigned-badge {
    position: absolute;
    right: 6px;
    bottom: 6px;
    background: var(--theme-dark);
    color: #1a1a1a;
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
    padding: 5px 8px;
    border-radius: 5px;
    white-space: nowrap;
}

.practice-plan-slot-icon-link {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    color: inherit;
    /* Also used on a <button> (replace-media) alongside its original <a> (open-in-whiteboard)
       use — resets the button-specific chrome an anchor never had in the first place. */
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
}

.practice-plan-slot-icon-link:hover img {
    opacity: 0.85;
}

.practice-plan-slot-icon img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.practice-plan-slot-info {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
    flex: 1;
}

.practice-plan-slot-title {
    font-size: 14px;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.practice-plan-slot-assigned-players {
    display: flex;
    align-items: center;
    gap: 5px;
    min-height: 16px;
    margin: 6px 0;
    font-size: 12px;
    /* Lighter than --accent-light on purpose — that admin-theme purple reads as muted/dark
       against the tile's --lighter-bg background, this needs to pop instead. */
    color: #B18AFF;
}

.practice-plan-slot-assigned-players-text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

.feedback-assigned-players {
    margin-bottom: 16px;
}

.practice-plan-slot-fields {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.practice-plan-slot-fields label {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: var(--accent-gray-light);
    white-space: nowrap;
}

.practice-plan-slot-actions {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
}

.practice-plan-slot-move-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    background: var(--darker-bg);
    color: var(--text-color);
    border: none;
    border-radius: 50%;
    cursor: pointer;
}

.practice-plan-slot-move-btn:disabled {
    opacity: 0.35;
    cursor: default;
}

.practice-plan-slot-delete-btn {
    color: var(--error-red);
}

/*#region PRACTICE PLAN PLAYER (linear "Play all" viewer)*/
.practice-plan-player {
    display: flex;
    flex-direction: column;
    min-height: 100dvh;
    padding: 16px;
    padding-bottom: calc(16px + env(safe-area-inset-bottom));
    box-sizing: border-box;
}

.practice-plan-player-header {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 16px;
    padding: 8px 56px;
    text-align: center;
}

.practice-plan-player-progress {
    font-size: 14px;
    font-weight: 600;
}

.practice-plan-player-body {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 40px;
    min-height: 0;
}

.practice-plan-player-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
    text-align: center;
}

.practice-plan-player-text {
    font-size: 20px;
    line-height: 1.5;
    max-width: 560px;
    white-space: pre-wrap;
}

.practice-plan-player-media-image {
    max-height: 500px;
    max-width: 100%;
    width: auto;
}

.practice-plan-player-media-image-btn {
    display: inline-block;
    padding: 0;
    border: none;
    background: none;
    cursor: pointer;
    line-height: 0;
}

.practice-plan-player-image-modal-img {
    display: block;
    border-radius: var(--list-container-border-radius);
}

/* Unlike the shared .media-preview-image (always capped at 90vh), this modal's image can be
   shown at native size when that's larger than 90% of the viewport — which means it can
   exceed the panel's own max-height:100%. Scroll instead of clipping in that case. */
.practice-plan-player-image-modal-panel {
    max-height: 100vh;
    overflow: auto;
}

.practice-plan-player-notes {
    font-size: 14px;
    color: var(--accent-gray-light);
    max-width: 480px;
}

.practice-plan-player-media-caption {
    font-size: 16px;
    max-width: 480px;
    margin-top: 4px;
}

.practice-plan-player-nav-btn {
    position: fixed;
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.45);
    color: #fff;
    border: none;
    font-size: 18px;
    cursor: pointer;
    /* 22, not the 20 every other whiteboard floating control uses — on WhiteboardPage (Play all
       stepping through a Play slot), .whiteboard-sidebar sits at z-index 21 and spans the full
       left edge, which would otherwise paint over the Previous button sitting at the same
       vertically-centered left position. PracticePlanPlayerPage has no such sidebar, so this is
       a no-op there. */
    z-index: 22;
}

.practice-plan-player-nav-btn:disabled {
    opacity: 0.25;
    cursor: default;
}

.practice-plan-player-nav-btn-prev {
    left: calc(12px + env(safe-area-inset-left));
}

.practice-plan-player-nav-btn-next {
    right: calc(12px + env(safe-area-inset-right));
}
/*#endregion*/

.profile-theme-input {
    width: 44px;
    height: 44px;
    padding: 2px;
    background: var(--lightest-bg);
    border: 1px solid transparent;
    border-radius: var(--list-container-border-radius);
    cursor: pointer;
}

.profile-theme-input:focus {
    outline: none;
    border-color: var(--theme-dark);
}
/*#endregion*/

/*#region AVATAR CROPPER*/
.avatar-cropper-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 50;
}

.avatar-cropper-modal {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background: var(--lighter-bg);
    border-radius: var(--list-container-border-radius);
    padding: 20px;
    z-index: 51;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
}

.avatar-cropper-title {
    font-size: 16px;
    font-weight: 700;
    margin: 0;
    align-self: flex-start;
}

/* Actual size comes from an inline style driven by AvatarCropper's FrameWidth/FrameHeight
   parameters — this just supplies the box's fixed visual chrome. */
.avatar-cropper-pick-label {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    width: 100%;
    height: 100%;
    border: 2px dashed var(--list-container-border-color);
    border-radius: var(--list-container-border-radius);
    color: var(--accent-gray-light);
    font-size: 14px;
    cursor: pointer;
}

.avatar-cropper-pick-label i {
    font-size: 32px;
}

/* Actual size comes from an inline style driven by AvatarCropper's FrameWidth/FrameHeight
   parameters — this just supplies the circular mask default (avatars/org logos). */
.avatar-cropper-frame {
    border-radius: 50%;
    overflow: hidden;
    touch-action: none;
    cursor: grab;
}

/* Widescreen covers (e.g. a playbook's) crop to a rounded rectangle instead — a circular mask
   only makes sense at a 1:1 aspect. */
.avatar-cropper-frame-rect {
    border-radius: var(--list-container-border-radius);
}

.avatar-cropper-frame canvas {
    display: block;
}

.avatar-cropper-zoom {
    width: 100%;
    accent-color: var(--theme-dark);
}

.avatar-cropper-actions {
    display: flex;
    gap: 10px;
    width: 100%;
}

.avatar-cropper-actions .whiteboard-modal-save {
    margin-top: 0;
}

.avatar-cropper-cancel {
    flex: 1;
    background: none;
    border: 1px solid var(--list-container-border-color);
    border-radius: var(--list-container-border-radius);
    color: var(--text-color);
    font-size: 15px;
    font-weight: 600;
    padding: 12px;
    cursor: pointer;
}

/* The "Remove current image" action ChangeImageModal (avatar/logo/cover) adds to
   MediaItemPickerModal via ShowRemoveOption — every other picker consumer never sets that flag,
   so this never shows up there. */
.change-image-remove {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    background: none;
    border: none;
    color: var(--accent-gray-light);
    font-size: 13px;
    font-weight: 600;
    padding: 4px;
    cursor: pointer;
}

.change-image-remove:hover {
    color: var(--text-color);
}
/*#endregion*/

/*#region ADMIN CONSOLE*/
.console-tabs-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
    margin: 16px 0;
}

.console-tabs {
    display: flex;
    gap: 4px;
    overflow-x: auto;
    scrollbar-width: none;
    margin-bottom: 20px;
}

.console-tabs::-webkit-scrollbar {
    display: none;
}

.console-tab {
    background: none;
    border: none;
    color: var(--accent-gray-light);
    font-size: 14px;
    font-weight: 600;
    flex-shrink: 0;
    padding: 10px 16px;
    border-radius: var(--list-container-border-radius);
    cursor: pointer;
}

.console-tab.active {
    color: #fff;
    background: var(--accent-dark);
}

.admin-user-overview-summary {
    color: var(--accent-gray-light);
    font-size: 12px;
    font-weight: 400;
    margin-top: 6px;
}

.console-tabs + .dashboard-section,
.console-tabs + .profile-avatar-section,
.console-tabs + .dashboard-loading,
.console-tabs + .empty-state,
.console-tabs + .plays-list {
    margin-top: 16px;
}

.admin-org-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.admin-org-list-item {
    display: flex;
    align-items: center;
    gap: 12px;
    background: var(--lighter-bg);
    border-radius: var(--list-container-border-radius);
    padding: 14px 16px;
}

.admin-org-list-item:hover {
    background: rgba(0, 0, 0, 0.3);
}

.admin-org-owner-avatar {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    object-fit: cover;
    flex-shrink: 0;
}

.admin-org-owner-avatar-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--darker-bg);
    color: var(--accent-gray-light);
    font-size: 14px;
}

.admin-org-info {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.admin-org-name-row {
    display: flex;
    align-items: center;
    gap: 8px;
}

.admin-org-name {
    font-size: 15px;
    font-weight: 600;
}

.admin-org-type {
    font-size: 12px;
    color: var(--accent-gray-light);
}

.admin-org-owner {
    font-size: 13px;
    color: var(--accent-gray-light);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.admin-org-created {
    font-size: 12px;
    color: var(--accent-gray-light);
}

.admin-org-list-item i {
    color: var(--accent-gray-light);
}

.admin-marketing-identity-preview {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 10px;
}

.admin-marketing-identity-swatch {
    width: 20px;
    height: 20px;
    border-radius: 50%;
    flex-shrink: 0;
    border: 2px solid var(--darker-bg);
}

.admin-units-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 12px;
}

.admin-unit-form {
    background: var(--lighter-bg);
    border-radius: var(--list-container-border-radius);
    padding: 16px;
    margin-bottom: 16px;
}

.admin-season-picker {
    margin-bottom: 16px;
}

.admin-invite-email-status {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    margin-top: 8px;
    margin-bottom: 12px;
    color: var(--accent-gray-light);
}

.admin-invite-email-status-new {
    color: var(--theme-dark);
}

.admin-unit-form-actions {
    display: flex;
    gap: 10px;
    margin-top: 16px;
}

.admin-unit-form-actions .whiteboard-modal-save {
    margin: 0;
    max-width: none;
    width: auto;
    flex: 1;
}

.admin-unit-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.admin-unit-list-item {
    display: flex;
    align-items: center;
    gap: 12px;
    background: var(--lighter-bg);
    border-radius: var(--list-container-border-radius);
    padding: 12px 16px;
    flex-wrap: wrap;
}

.admin-unit-name {
    font-size: 14px;
    font-weight: 600;
    flex: 1;
    min-width: 0;
}

.admin-unit-name-link {
    color: inherit;
    text-decoration: none;
}

.admin-unit-name-link:hover {
    text-decoration: underline;
}

.admin-unit-type {
    font-size: 12px;
    color: var(--accent-gray-light);
    background: var(--darker-bg);
    padding: 4px 10px;
    border-radius: 999px;
    flex-shrink: 0;
}

.admin-household-member-name-group {
    display: flex;
    align-items: center;
    gap: 25px;
    flex: 1;
    min-width: 0;
}

.admin-household-member-name {
    font-size: 14px;
    font-weight: 600;
    color: inherit;
    text-decoration: none;
}

.admin-household-member-name:hover {
    text-decoration: underline;
}

.admin-household-member-email {
    font-size: 12px;
    color: var(--accent-gray-light);
}

.admin-unit-status {
    font-size: 12px;
    font-weight: 600;
    color: var(--theme-dark);
    flex-shrink: 0;
}

.admin-unit-status.admin-unit-inactive {
    color: var(--accent-gray-light);
}

.admin-unit-edit-name {
    flex: 1;
    min-width: 120px;
}

/* Full-bleed panel: breaks out of .app-content's own max-width/centering so the background
   spans the whole viewport, while .breadcrumbs-panel-inner keeps the actual crumb text
   aligned to the same 1200px column as the page content below it. Uses the calc(50% - 50vw)
   form of the breakout (not position:relative + left:50% + margin-left:-50vw) — that older
   form measures its "50%" against the containing block and its "-50vw" against the raw
   viewport, two different reference frames that drift apart by half a scrollbar's width and
   creep the panel sideways; a single calc() per side avoids that. html/body's own
   overflow-x:hidden (see base rules above) is the backstop for the part no CSS trick can fix
   outright: 100vw itself is measured as if no scrollbar existed, so on a page tall enough to
   scroll vertically this is still a hair wider than the visible area.
   The margin-top cancels only the fixed 16px portion of .app-content's own top padding — NOT
   the header-height or env(safe-area-inset-top) portions, which have to stay untouched so the
   panel's top edge lands exactly at the header's bottom edge, not underneath the header itself
   (canceling header-height too pulls the panel's top up to the header's own TOP, and since the
   panel itself is shorter than the header, the whole thing ends up hidden behind it). Rendered
   via the Breadcrumbs.razor component, always the first child of a page's outer wrapper. */
.breadcrumbs-panel {
    width: 100vw;
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
    margin-top: -16px;
    background: var(--lighter-bg);
}

.breadcrumbs-panel-inner {
    max-width: var(--container-max-width);
    margin: 0 auto;
    padding: 12px 16px;
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    font-size: 13px;
    color: #fff;
}

.breadcrumbs-panel-inner a {
    color: #fff;
    opacity: 0.7;
}

.breadcrumbs-panel-inner a:hover {
    opacity: 1;
}

.breadcrumbs-panel-inner i {
    font-size: 10px;
    opacity: 0.6;
}

.breadcrumbs-panel + .dashboard-title {
    margin-top: 16px;
}

.admin-back-button {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    color: var(--accent-gray-light);
    margin-top: 16px;
    margin-bottom: 16px;
}

.admin-org-details {
    width: 100%;
    border-collapse: collapse;
}

.admin-org-details tr:not(:last-child) th,
.admin-org-details tr:not(:last-child) td {
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.admin-org-details th,
.admin-org-details td {
    text-align: left;
    padding: 10px 16px 10px 0;
    vertical-align: middle;
}

.admin-org-details th {
    color: var(--accent-gray-light);
    font-size: 13px;
    font-weight: 400;
    white-space: nowrap;
    width: 1%;
}

.admin-org-details td {
    font-size: 14px;
    font-weight: 600;
    width: 100%;
}

.admin-org-owner-current {
    font-size: 14px;
    font-weight: 600;
    margin-right: 10px;
}

.admin-org-owner-unassigned {
    color: var(--accent-gray-light);
    font-weight: 500;
}

.admin-owner-action-btn,
.admin-owner-cancel-btn {
    background: none;
    border: none;
    color: var(--accent-light);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    padding: 0;
    margin-right: 12px;
}

.admin-owner-action-btn:hover,
.admin-owner-cancel-btn:hover {
    text-decoration: underline;
}

.admin-owner-cancel-btn {
    color: var(--accent-gray-light);
    display: block;
    margin-top: 8px;
}

.admin-owner-action-btn-danger {
    color: var(--error-red);
}

.admin-org-archived-badge {
    display: inline-block;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--error-red);
    background: rgba(255, 63, 95, 0.12);
    border-radius: 4px;
    padding: 2px 8px;
    vertical-align: middle;
    margin-left: 8px;
}

.subscription-card {
    background: var(--lighter-bg);
    border-radius: var(--list-container-border-radius);
    padding: 16px;
    margin-bottom: 16px;
    border: 1px solid transparent;
}

.subscription-card-current {
    border-color: var(--accent-green);
}

.subscription-card-title {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 16px;
    font-weight: 700;
    margin-bottom: 12px;
}

.subscription-current-badge {
    display: inline-block;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--accent-green);
    background: rgba(61, 255, 155, 0.12);
    border-radius: 4px;
    padding: 2px 8px;
    vertical-align: middle;
}

.admin-unit-list-item-current {
    border: 1px solid var(--accent-green);
}

.admin-org-archive-bar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 4px 12px;
    background: var(--lighter-bg);
    border-radius: var(--list-container-border-radius);
    padding: 12px 16px;
    margin: 16px 0;
    font-size: 13px;
    color: var(--accent-gray-light);
}

.admin-org-archived-toggle {
    margin: 16px 0;
}

.admin-user-filter-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    margin: 16px 0;
}

.admin-user-filter-bar .auth-input {
    width: auto;
    flex: 1 1 220px;
}

.admin-user-role-select {
    flex: 0 1 160px;
}

.admin-user-filter-bar .filter-checkbox {
    flex-shrink: 0;
}

.admin-user-card {
    align-items: center;
    text-align: center;
    padding: 20px 12px 16px;
}

.admin-user-card-avatar {
    width: 64px;
    height: 64px;
    border-radius: 50%;
    object-fit: cover;
    margin-bottom: 10px;
}

.admin-user-card-avatar-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--darker-bg);
    color: var(--accent-gray-light);
    font-size: 24px;
}

.admin-user-card-info {
    align-items: center;
    padding: 0;
    width: 100%;
}

.admin-user-card-info .play-card-title,
.admin-user-card-info .play-card-desc {
    max-width: 100%;
}

.admin-user-card-stats {
    display: flex;
    gap: 12px;
    margin-top: 6px;
    font-size: 12px;
    color: var(--accent-gray-light);
}

.admin-user-card-stats i {
    margin-right: 4px;
}

.admin-user-role-badge {
    display: inline-block;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--theme-dark);
    background: rgba(255, 126, 0, 0.12);
    border-radius: 4px;
    padding: 2px 8px;
    margin-top: 8px;
}

.admin-user-restore-btn {
    color: var(--accent-green);
}

/* Overrides .play-card-confirm's single horizontal row (text + buttons side by side) — that
   layout assumes a wide play tile; the narrower, centered user tile squishes it. Stack text
   on top, actions below, instead. */
.admin-user-card-confirm {
    flex-direction: column;
    justify-content: center;
    gap: 10px;
    padding: 12px;
    text-align: center;
}

.admin-user-card-confirm span {
    flex: none;
}

.admin-user-card-confirm-actions {
    display: flex;
    gap: 10px;
}
/*#endregion*/

/*#region USER PICKER*/
.user-picker {
    position: relative;
    width: 100%;
}

.user-picker-input {
    width: 100%;
    background: var(--lightest-bg);
    border: 1px solid transparent;
    border-radius: var(--list-container-border-radius);
    padding: 12px 14px;
    font-size: 15px;
    color: var(--text-color);
    font-family: inherit;
    box-sizing: border-box;
}

.user-picker-input:focus {
    outline: none;
    border-color: var(--theme-dark);
}

.user-picker-results {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    z-index: 20;
    max-height: 260px;
    overflow-y: auto;
    background: var(--lighter-bg);
    border: 1px solid var(--list-container-border-color);
    border-radius: var(--list-container-border-radius);
}

.user-picker-status {
    padding: 12px 14px;
    font-size: 13px;
    color: var(--accent-gray-light);
}

.user-picker-result {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    background: none;
    border: none;
    padding: 10px 14px;
    cursor: pointer;
    text-align: left;
    font-family: inherit;
    color: var(--text-color);
}

.user-picker-result:hover {
    background: rgba(0, 0, 0, 0.3);
}

.user-picker-avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    object-fit: cover;
    flex-shrink: 0;
}

.user-picker-avatar-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--darker-bg);
    color: var(--accent-gray-light);
    font-size: 13px;
}

.user-picker-info {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.user-picker-name {
    font-size: 14px;
    font-weight: 600;
}

.user-picker-email {
    font-size: 12px;
    color: var(--accent-gray-light);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.user-picker-selected {
    display: flex;
    align-items: center;
    gap: 10px;
    background: var(--lighter-bg);
    border: 1px solid var(--list-container-border-color);
    border-radius: var(--list-container-border-radius);
    padding: 10px 14px;
}

.user-picker-clear {
    background: none;
    border: none;
    color: var(--accent-gray-light);
    cursor: pointer;
    font-size: 14px;
    padding: 4px;
}

.user-picker-clear:hover {
    color: var(--text-color);
}
/*#endregion*/

/*#region NOTIFICATIONS*/
.notification-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.notification-item {
    display: flex;
    align-items: center;
    gap: 12px;
    background: var(--lighter-bg);
    border-radius: var(--list-container-border-radius);
    padding: 12px 16px;
    flex-wrap: wrap;
}

.notification-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: var(--darker-bg);
    color: var(--theme-dark);
    font-size: 15px;
    flex-shrink: 0;
}

.notification-info {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1;
    min-width: 0;
}

.notification-title {
    font-size: 14px;
    font-weight: 600;
}

.notification-detail {
    font-size: 12px;
    color: var(--accent-gray-light);
}

.notification-accept-btn {
    margin: 0;
    max-width: none;
    width: auto;
    padding: 8px 16px;
    flex-shrink: 0;
}

.notification-dismiss-btn {
    background: none;
    border: none;
    color: var(--accent-gray-light);
    font-size: 16px;
    cursor: pointer;
    padding: 4px;
    flex-shrink: 0;
}

.notification-dismiss-btn:hover {
    color: var(--text-color);
}
/*#endregion*/

/*#region QUICK PLAY BANNER*/
.quick-play-btn {
    background: #6D28D9;
    border-radius: 999px;
}

.quick-play-banner {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
    background: var(--lighter-bg);
    border-radius: var(--list-container-border-radius);
    box-shadow: 0 0 27px 5px rgba(0, 0, 0, 0.23);
    padding: 16px 24px;
    margin-bottom: 24px;
}

.quick-play-content {
    display: flex;
    align-items: center;
    gap: 16px;
}

.quick-play-image {
    height: 56px;
    width: auto;
}

.quick-play-title {
    font-size: 22px;
    font-weight: 700;
    color: var(--text-color);
}

.quick-play-actions {
    display: flex;
    align-items: center;
    gap: 16px;
}

@media (min-width: 640px) {
    .quick-play-banner {
        flex-direction: row;
        justify-content: space-between;
    }
}
/*#endregion*/

/*#region Households */
.household-section-title {
    font-size: 15px;
    font-weight: 700;
    margin: 24px 0 12px;
}

.household-member-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-bottom: 24px;
}

.household-member-row {
    display: flex;
    align-items: center;
    gap: 12px;
    background: var(--lighter-bg);
    border-radius: var(--list-container-border-radius);
    padding: 12px 16px;
}

.household-member-name {
    font-weight: 600;
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.household-member-role {
    color: var(--accent-gray-light);
    font-size: 13px;
}

.household-member-remove {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: none;
    border: 1px solid var(--error-red);
    color: var(--error-red);
    border-radius: 999px;
    padding: 6px 12px;
    font-size: 12px;
    cursor: pointer;
}

.household-member-remove:disabled {
    opacity: 0.5;
    cursor: default;
}

.household-add-player-tabs {
    display: flex;
    gap: 8px;
    margin-bottom: 16px;
}

.household-add-player-tab {
    flex: 1;
    background: var(--lighter-bg);
    color: var(--accent-gray-light);
    border: none;
    border-radius: var(--list-container-border-radius);
    padding: 10px;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}

.household-add-player-tab.active {
    background: var(--theme-dark);
    color: #fff;
}

/*#endregion*/

/*#region Dashboard player tiles (guardian view) */
.dashboard-player-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 12px;
}

.dashboard-player-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    background: var(--lighter-bg);
    border-radius: var(--list-container-border-radius);
    padding: 20px 12px;
    text-align: center;
    cursor: pointer;
}

.dashboard-player-tile-avatar {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: var(--darker-bg);
    color: var(--accent-gray-light);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 22px;
}

.dashboard-player-tile-name {
    font-weight: 600;
    font-size: 14px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
}

.dashboard-player-tile-journey-btn {
    display: flex;
    align-items: center;
    gap: 6px;
    background: var(--darker-bg);
    color: var(--theme-dark);
    border: none;
    border-radius: 999px;
    padding: 6px 12px;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
}
/*#endregion*/
