/* GSL Admin v2 — application styles. All colours come from tokens.css. */

* { box-sizing: border-box; }
[hidden] { display: none !important; }

html, body {
    margin: 0;
    padding: 0;
    font-family: var(--font);
    font-size: 13px;
    line-height: 1.5;
    background: var(--bg);
    color: var(--text);
    -webkit-font-smoothing: antialiased;
}

a { color: var(--brand); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ── App shell ─────────────────────────────────────────────── */

.shell { display: flex; min-height: 100vh; }

.sidebar {
    width: var(--sidebar-w);
    flex-shrink: 0;
    background: var(--sidebar-bg);
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
    border-right: 1px solid var(--border);
}

.sidebar-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 16px;
    color: var(--sidebar-text-active);
    font-weight: 600;
    font-size: 14px;
    letter-spacing: 0.2px;
}

.sidebar-brand .logo {
    width: 30px; height: 30px;
    border-radius: 8px;
    background: var(--brand);
    display: grid;
    place-items: center;
    color: #fff;
    font-size: 13px;
    font-weight: 800;
}

.sidebar-nav { flex: 1; padding: 8px; overflow-y: auto; }

.nav-section {
    margin: 14px 10px 6px;
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.7px;
    color: var(--text-3);
}

.nav-link {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    margin-bottom: 2px;
    border-radius: var(--radius-sm);
    color: var(--sidebar-text);
    font-weight: 500;
    font-size: 13px;
}

.nav-link:hover { background: var(--sidebar-hover); color: var(--text); text-decoration: none; }
.nav-link.active {
    background: var(--sidebar-active);
    color: var(--sidebar-text-active);
    font-weight: 600;
}
.nav-link svg { width: 17px; height: 17px; flex-shrink: 0; opacity: 0.85; }
.nav-link.active svg { color: var(--brand); opacity: 1; }

.nav-link.disabled { opacity: 0.38; cursor: default; pointer-events: none; }
.nav-link .soon {
    margin-left: auto;
    font-size: 9.5px;
    font-weight: 700;
    padding: 1px 6px;
    border-radius: 99px;
    background: var(--sidebar-hover);
    letter-spacing: 0.4px;
}

.sidebar-footer { padding: 10px; border-top: 1px solid var(--border); }

/* ── Main column ───────────────────────────────────────────── */

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.topbar {
    height: var(--topbar-h);
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 0 18px;
    margin: 14px 24px 0;
    background: var(--surface);
    border-radius: var(--radius);
    box-shadow: var(--shadow-1);
    position: sticky;
    top: 14px;
    z-index: 50;
}

.topbar h1 { font-size: 13px; font-weight: 500; color: var(--text-2); margin: 0; }
.topbar .spacer { flex: 1; }

.content { padding: 20px 24px 32px; max-width: 1360px; width: 100%; margin: 0 auto; }

.page-head { margin-bottom: 18px; }
.page-head h2 { margin: 0; font-size: 18px; font-weight: 700; letter-spacing: -0.01em; }
.page-head p { margin: 4px 0 0; color: var(--text-3); font-size: 12.5px; }

/* ── Components ────────────────────────────────────────────── */

.card {
    background: var(--surface);
    border: none;
    border-radius: var(--radius);
    box-shadow: var(--shadow-1);
}

.card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px;
    border-bottom: 1px solid var(--border);
}

.card-head h3 { margin: 0; font-size: 13.5px; font-weight: 600; white-space: nowrap; }
.card-head .small { text-align: right; }
.card-body { padding: 16px; }
.card-body.flush { padding: 0; }

/* Stat tiles */
.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 10px;
    margin-bottom: 16px;
}

.stat {
    background: var(--surface);
    border: none;
    border-radius: var(--radius);
    box-shadow: var(--shadow-1);
    padding: 12px 16px;
}

.stat .label { font-size: 11px; font-weight: 500; color: var(--text-2); display: flex; align-items: center; gap: 7px; }
.stat .value { font-size: 20px; font-weight: 600; margin-top: 4px; line-height: 1.1; }
.stat .dot { width: 8px; height: 8px; border-radius: 99px; }

/* Tables */
.table { width: 100%; border-collapse: collapse; }
.table th {
    text-align: left;
    font-size: 10.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    color: var(--text-2);
    padding: 9px 16px;
    border-bottom: 1px solid var(--border);
    background: var(--surface-2);
}
.table td {
    padding: 9px 16px;
    border-bottom: 1px solid var(--border);
    vertical-align: middle;
}
.table tr:last-child td { border-bottom: none; }
.table tbody tr:hover { background: var(--surface-2); }
.table .sub { color: var(--text-3); font-size: 12px; margin-top: 1px; }
.table .num { font-variant-numeric: tabular-nums; }

.empty {
    padding: 28px 14px;
    text-align: center;
    color: var(--text-3);
}

/* Badges */
.badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 11px;
    font-weight: 500;
    padding: 2px 8px;
    border-radius: 99px;
    white-space: nowrap;
}
.badge.green  { background: var(--green-soft);  color: var(--green-text); }
.badge.amber  { background: var(--amber-soft);  color: var(--amber-text); }
.badge.red    { background: var(--red-soft);    color: var(--red-text); }
.badge.blue   { background: var(--blue-soft);   color: var(--blue-text); }
.badge.violet { background: var(--violet-soft); color: var(--violet-text); }
.badge.teal   { background: var(--teal-soft);   color: var(--teal-text); }
.badge.pink   { background: var(--pink-soft);   color: var(--pink-text); }
.badge.slate  { background: var(--slate-soft);  color: var(--slate-text); }
.badge.grey   { background: var(--grey-soft);   color: var(--grey-text); }

/* Dot variant — calmer status display for dense tables */
.badge.dot { background: transparent; padding: 0; font-weight: 500; }
.badge.dot::before { content: ''; width: 7px; height: 7px; border-radius: 99px; flex-shrink: 0; }
.badge.dot.green::before  { background: var(--green); }
.badge.dot.amber::before  { background: var(--amber); }
.badge.dot.red::before    { background: var(--red); }
.badge.dot.blue::before   { background: var(--blue); }
.badge.dot.violet::before { background: var(--violet); }
.badge.dot.teal::before   { background: var(--teal); }
.badge.dot.pink::before   { background: var(--pink); }
.badge.dot.slate::before  { background: var(--slate); }
.badge.dot.grey::before   { background: var(--text-3); }
.badge.dot.green  { color: var(--green-text); }
.badge.dot.amber  { color: var(--amber-text); }
.badge.dot.red    { color: var(--red-text); }
.badge.dot.blue   { color: var(--blue-text); }
.badge.dot.violet { color: var(--violet-text); }
.badge.dot.teal   { color: var(--teal-text); }
.badge.dot.pink   { color: var(--pink-text); }
.badge.dot.slate  { color: var(--text-2); }
.badge.dot.grey   { color: var(--text-2); }

/* Buttons */
.btn {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-family: var(--font);
    font-size: 12.5px;
    font-weight: 600;
    padding: 7px 14px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border-strong);
    background: var(--surface);
    color: var(--text-2);
    cursor: pointer;
    transition: background 0.12s, border-color 0.12s, box-shadow 0.12s;
}
.btn:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
.btn.primary {
    background: var(--brand); border-color: var(--brand); color: #fff;
    box-shadow: 0 2px 4px 0 rgba(211, 47, 47, 0.35);
}
.btn.primary:hover { background: var(--brand-strong); box-shadow: none; }
.btn.icon { padding: 5px; }
.btn svg { width: 16px; height: 16px; }
.btn.block { width: 100%; justify-content: center; }

/* Bootstrap-named aliases. Pages migrated to Sneat markup write btn-primary /
   btn-outline-* / btn-sm; map those onto the app's own button language so both
   idioms render identically. (Without these, btn-primary fell through to the
   bare outline style with a stray focus ring — see the WiFi page.) */
.btn.btn-primary {
    background: var(--brand); border-color: var(--brand); color: #fff;
    box-shadow: 0 2px 4px 0 rgba(211, 47, 47, 0.35);
}
.btn.btn-primary:hover { background: var(--brand-strong); color: #fff; box-shadow: none; }
.btn.btn-outline-primary { color: var(--brand); border-color: var(--brand); }
.btn.btn-outline-primary:hover { background: var(--brand-soft); color: var(--brand); }
.btn.btn-outline-danger { color: var(--red-text); border-color: var(--red-text); }
.btn.btn-outline-danger:hover { background: var(--red-soft); color: var(--red-text); }
/* btn-outline-secondary is the base .btn look already — no override needed. */
.btn.btn-sm { padding: 4px 10px; font-size: 12px; }
.btn:disabled { opacity: 0.55; cursor: not-allowed; }

/* Forms */
.field { margin-bottom: 12px; }
.field label { display: block; font-size: 12px; font-weight: 500; color: var(--text-2); margin-bottom: 4px; }
.input {
    width: 100%;
    font-family: var(--font);
    font-size: 13px;
    padding: 7px 10px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border-strong);
    background: var(--surface);
    color: var(--text);
}
/* One height for every single-line control.
   Sizing used to be padding-only, and a <select>, a number spinner and a plain
   text box each have their own intrinsic height — so a row of them came out
   visibly uneven (see the booking edit form: Event name against Event type).
   Fixing the height makes them agree regardless of control type.
   Narrower contexts override this with a more specific selector — e.g.
   .shift-detail-bar .input at 28px — and still win. */
select.input,
input.input { height: 38px; }
/* Textareas keep sizing to their rows attribute. */
textarea.input { height: auto; min-height: 38px; }
.input:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }

/* Flash messages */
.flash { padding: 11px 14px; border-radius: var(--radius-sm); font-weight: 500; margin-bottom: 14px; }
.flash.success { background: var(--green-soft); color: var(--green-text); }
.flash.error { background: var(--red-soft); color: var(--red-text); }

/* User chip / theme toggle */
.user-chip {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 6px 8px;
    border-radius: var(--radius-sm);
    color: var(--text);
}
.avatar {
    width: 28px; height: 28px;
    border-radius: 99px;
    background: var(--surface-3);
    color: var(--text-2);
    display: grid;
    place-items: center;
    font-size: 11.5px;
    font-weight: 600;
}

.theme-toggle {
    border: 1px solid var(--border-strong);
    background: var(--surface);
    color: var(--text-2);
    border-radius: var(--radius-sm);
    width: 34px; height: 34px;
    display: grid;
    place-items: center;
    cursor: pointer;
}
.theme-toggle:hover { background: var(--surface-2); }
.theme-toggle svg { width: 16px; height: 16px; }
[data-theme="light"] .icon-sun { display: none; }
[data-theme="dark"] .icon-moon { display: none; }

/* Two-column dashboard area */
.grid-2 {
    display: grid;
    grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
    gap: 12px;
    align-items: start;
}
.grid-2 > * { min-width: 0; }
.grid-2 .card { min-width: 0; }
@media (max-width: 1000px) { .grid-2 { grid-template-columns: 1fr; } }

/* Login page */
.login-wrap {
    min-height: 100vh;
    display: grid;
    place-items: center;
    background: var(--bg);
    padding: 20px;
}
.login-card {
    width: 100%;
    max-width: 380px;
    background: var(--surface);
    border: none;
    box-shadow: var(--shadow-2);
    border-radius: 14px;
    box-shadow: var(--shadow-2);
    padding: 32px;
}
.login-card .logo-row { display: flex; align-items: center; gap: 11px; margin-bottom: 24px; }
.login-card h1 { font-size: 17px; margin: 0; }
.login-card .divider {
    display: flex; align-items: center; gap: 10px;
    color: var(--text-3); font-size: 12px; margin: 18px 0;
}
.login-card .divider::before, .login-card .divider::after {
    content: ''; flex: 1; height: 1px; background: var(--border);
}

/* Utility */
.muted { color: var(--text-2); }
.small { font-size: 12px; }
strong { font-weight: 600; }
.field-hint { font-size: 11.5px; color: var(--text-3); margin-top: 3px; }
.form-actions { position: sticky; bottom: 0; padding: 10px 0; background: var(--bg); display: flex; gap: 10px; z-index: 10; }
.mt-0 { margin-top: 0; }

/* ── Bookings ──────────────────────────────────────────────── */

.toolbar {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    margin-bottom: 16px;
}
.toolbar .search { max-width: 340px; margin-left: auto; }

.chips { display: flex; gap: 6px; flex-wrap: wrap; }
.chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    font-weight: 500;
    padding: 4px 10px;
    border-radius: 99px;
    border: 1px solid var(--border-strong);
    background: var(--surface);
    color: var(--text-2);
}
.chip:hover { background: var(--surface-2); text-decoration: none; }
.chip.active { background: var(--brand-soft); border-color: var(--brand); color: var(--brand); }
.chip .count { opacity: 0.65; font-weight: 600; }

.pager { display: flex; align-items: center; gap: 10px; margin-top: 14px; }
.pager .spacer { flex: 1; }

/* Key-value lists (detail panels) */
.kv { display: grid; grid-template-columns: 100px 1fr; gap: 6px 12px; margin: 0; }
.kv dt { color: var(--text-3); font-size: 12px; font-weight: 500; }
.kv dd { margin: 0; min-width: 0; overflow-wrap: break-word; }

/* Discussion notes */
.note { padding: 8px 0; border-bottom: 1px solid var(--border); }
.note:first-child { padding-top: 0; }
.note-head { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.note-body { white-space: pre-wrap; }

/* Form rows */
.field-row { display: flex; gap: 12px; }
.field-row .field { flex: 1; min-width: 0; }

/* Tables with inputs (edit page) */
#sessions-table td, #equipment-table td { padding: 8px 10px; }
#sessions-table .input, #equipment-table .input { min-width: 0; }

/* ── Calendar ──────────────────────────────────────────────── */

.cal { display: flex; flex-direction: column; }
.cal-head {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
}
.cal-head div {
    padding: 7px 10px;
    font-size: 10.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.6px;
    color: var(--text-3);
}
.cal-week {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    border-bottom: 1px solid var(--border);
}
.cal-week:last-child { border-bottom: none; }
.cal-day {
    min-height: max(96px, calc((100vh - 305px) / var(--weeks, 5)));
    padding: 6px;
    border-right: 1px solid var(--border);
    overflow: hidden;
}
.cal-day.weekend:not(.dim) { background: var(--weekend-tint); }
.cal-day.today { box-shadow: inset 0 0 0 1.5px var(--brand); }
.cal-day:last-child { border-right: none; }
.cal-day.dim { background: var(--surface-2); }
.cal-day.dim .cal-daynum { color: var(--text-3); }
.cal-daynum { font-size: 11.5px; font-weight: 500; color: var(--text-2); margin-bottom: 4px; }
.cal-day.today .cal-daynum {
    display: inline-grid; place-items: center;
    width: 22px; height: 22px;
    background: var(--brand); color: #fff; border-radius: 99px;
}
.cal-event {
    display: block;
    font-size: 11px;
    font-weight: 500;
    padding: 2px 6px;
    border-radius: 5px;
    margin-bottom: 3px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.cal-event:hover { text-decoration: none; filter: brightness(1.1); }
.cal-event .t { opacity: 0.75; font-weight: 500; margin-right: 3px; }
.cal-event.green  { background: var(--green-soft);  color: var(--green-text); }
.cal-event.amber  { background: var(--amber-soft);  color: var(--amber-text); }
.cal-event.blue   { background: var(--blue-soft);   color: var(--blue-text); }
.cal-event.violet { background: var(--violet-soft); color: var(--violet-text); }
.cal-event.teal   { background: var(--teal-soft);   color: var(--teal-text); }
.cal-event.pink   { background: var(--pink-soft);   color: var(--pink-text); }
.cal-event.slate  { background: var(--slate-soft);  color: var(--slate-text); }
.cal-more { display: block; font-size: 11px; color: var(--text-3); padding-left: 6px; text-decoration: none; }
.cal-more:hover { color: var(--text); text-decoration: underline; }

/* ── Shifts ────────────────────────────────────────────────── */

.staff-picker { display: flex; flex-wrap: wrap; gap: 6px; }
.staff-check {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    font-weight: 500;
    padding: 5px 10px;
    border-radius: 99px;
    border: 1px solid var(--border-strong);
    background: var(--surface);
    cursor: pointer;
    user-select: none;
}
.staff-check:has(input:checked) { background: var(--brand-soft); border-color: var(--brand); color: var(--brand); }

.shift-detail {
    padding: 12px 16px;
    background: var(--surface-2);
}
.shift-detail-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.shift-detail-bar + .shift-people { margin-top: 8px; }
.shift-person {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 5px 0;
    border-bottom: 1px solid var(--border);
}
.shift-person:last-of-type { border-bottom: none; }
.shift-person-name { font-weight: 500; min-width: 140px; }
.shift-person form { display: contents; }
.shift-person .btn, .shift-detail-bar .btn { height: 26px; padding-top: 0; padding-bottom: 0; font-size: 12px; }
.shift-detail-bar .input { height: 28px; padding-top: 0; padding-bottom: 0; font-size: 12.5px; }

.shift-toggle {
    border: none;
    background: transparent;
    color: var(--text-3);
    width: 26px;
    height: 26px;
    border-radius: var(--radius-sm);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    flex-shrink: 0;
}
.shift-toggle:hover { background: var(--surface-3); color: var(--text); }
.shift-toggle svg { width: 15px; height: 15px; transition: transform 0.15s; }
.shift-toggle.open svg { transform: rotate(180deg); }

/* ── SMS inbox ─────────────────────────────────────────────── */

.sms-layout {
    display: grid;
    grid-template-columns: 340px 1fr;
    gap: 16px;
    align-items: stretch;
    height: calc(100vh - var(--topbar-h) - 175px);
    min-height: 420px;
}
.sms-list { overflow-y: auto; }
.sms-convo {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 14px;
    border-bottom: 1px solid var(--border);
    color: var(--text);
}
.sms-convo:hover { background: var(--surface-2); text-decoration: none; }
.sms-convo.active { background: var(--brand-soft); }
.sms-thread { display: flex; flex-direction: column; min-height: 0; }
.sms-messages { flex: 1; overflow-y: auto; padding: 16px; display: flex; flex-direction: column; gap: 8px; }
.bubble-row { display: flex; }
.bubble-row.outbound { justify-content: flex-end; }
.bubble {
    max-width: min(70%, 520px);
    padding: 8px 12px;
    border-radius: 14px;
    background: var(--surface-3);
}
.bubble-body { white-space: pre-wrap; overflow-wrap: anywhere; }
.bubble-row.outbound .bubble { background: var(--brand); color: #fff; border-bottom-right-radius: 4px; }
.bubble-row.inbound .bubble { border-bottom-left-radius: 4px; }
.bubble-meta { font-size: 10.5px; opacity: 0.65; margin-top: 3px; }
/* Comms page only. This used to be an unscoped .sms-compose, so its 12px padding
   and top border leaked onto the booking view's composer — indenting the text box
   relative to the template picker above it and drawing a stray rule between them.
   The booking and mobile composers set their own spacing. */
.sms-layout .sms-compose {
    display: flex;
    gap: 8px;
    padding: 12px;
    border-top: 1px solid var(--border);
}
@media (max-width: 900px) { .sms-layout { grid-template-columns: 1fr; height: auto; } }

.input.mono, textarea.mono { font-family: var(--mono); font-size: 12.5px; }
code { font-family: var(--mono); font-size: 12px; background: var(--surface-3); padding: 1px 5px; border-radius: 4px; }

/* ── Attention strip (dashboard) ───────────────────────────── */

.attn-strip {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin-bottom: 14px;
}
.attn-label { font-size: 12px; color: var(--text-3); margin-right: 2px; }
.attn-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    font-weight: 500;
    padding: 3px 10px;
    border-radius: 99px;
}
.attn-chip:hover { text-decoration: none; filter: brightness(1.05); }
.attn-chip.amber { background: var(--amber-soft); color: var(--amber-text); }
.attn-chip.red   { background: var(--red-soft);   color: var(--red-text); }
.attn-chip.blue  { background: var(--blue-soft);  color: var(--blue-text); }
.attn-chip.violet { background: var(--violet-soft); color: var(--violet-text); }
.attn-chip.slate  { background: var(--slate-soft);  color: var(--slate-text); }
.attn-chip.teal   { background: var(--teal-soft);   color: var(--teal-text); }
.pipeline { font-size: 12px; color: var(--text-3); }
.pipeline a { color: var(--text-3); }
.pipeline a:hover { color: var(--text); text-decoration: none; }
.pipeline strong { color: var(--text); font-weight: 600; }

/* ── Dashboard KPI tiles ───────────────────────────────────── */
.kpi-grid {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 12px;
    margin-bottom: 16px;
}
@media (max-width: 1080px) { .kpi-grid { grid-template-columns: repeat(2, 1fr); } }
.kpi {
    display: block;
    background: var(--surface);
    border: none;
    border-radius: var(--radius);
    box-shadow: var(--shadow-1);
    padding: 14px 16px;
    color: inherit;
}
a.kpi:hover { box-shadow: var(--shadow-2); text-decoration: none; }
.kpi-head {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 12px;
    font-weight: 500;
    color: var(--text-2);
    margin-bottom: 12px;
}
.kpi-head svg { width: 15px; height: 15px; color: var(--text-3); flex-shrink: 0; }
.kpi-value { font-size: 25px; font-weight: 600; line-height: 1; }
.kpi-sub { font-size: 11px; color: var(--text-3); margin-top: 6px; }
.kpi-sub.amber { color: var(--amber-text); }
.kpi-sub.red   { color: var(--red-text); }
.kpi-sub.green { color: var(--green-text); }
.kpi-sub.blue  { color: var(--blue-text); }

/* ── Agenda (dashboard schedule, date-rail) ────────────────── */

/* Cap the agenda so a busy fortnight doesn't push the rest of the dashboard
   (quotes to chase / ready to invoice / shifts to action) below the fold. */
.agenda { padding: 2px 0 6px; max-height: 545px; overflow-y: auto; }
.agenda-group {
    display: flex;
    gap: 14px;
    padding: 7px 14px;
    border-bottom: 1px solid var(--border);
}
.agenda-group:last-child { border-bottom: none; }
.agenda-rail { width: 38px; text-align: center; flex-shrink: 0; padding-top: 1px; }
.agenda-rail .dow {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-3);
}
.agenda-rail .dom { font-size: 17px; font-weight: 500; color: var(--text-2); line-height: 1.15; }
.agenda-rail .mon {
    font-size: 9.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-3);
    line-height: 1.3;
}
.agenda-rail.soon .mon { color: var(--amber-text); }
.agenda-rail.soon .dow { color: var(--amber-text); }
.agenda-rail.soon .dom { color: var(--amber-text); }
.agenda-items { flex: 1; min-width: 0; }
.agenda-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 3px 6px;
    margin: 0 -6px;
    border-radius: var(--radius-sm);
    color: var(--text);
}
.agenda-row:hover { background: var(--surface-2); text-decoration: none; }
.agenda-time {
    width: 118px;              /* fits "11:00am – 11:30pm" — 106px overflowed into the event name */
    flex-shrink: 0;
    font-size: 12px;
    color: var(--text-2);
    white-space: nowrap;
    overflow: hidden;          /* backstop so an odd-length range can never overlap */
    text-overflow: ellipsis;
}
.agenda-event {
    flex: 1;
    min-width: 0;
    font-size: 13px;
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.agenda-event .org { font-weight: 400; color: var(--text-3); }
.agenda-venue {
    flex-shrink: 0;
    font-size: 12px;
    color: var(--text-3);
    white-space: nowrap;
}
.agenda-tech {
    width: 70px;
    flex-shrink: 0;
    text-align: right;
    font-size: 12px;
    color: var(--text-2);
    white-space: nowrap;
}
.agenda-tech.open { color: var(--amber-text); font-weight: 500; }
@media (max-width: 800px) {
    .agenda-venue, .agenda-tech { display: none; }
}

/* Shifts agenda extras */
.shift-offers { flex-shrink: 0; white-space: nowrap; min-width: 150px; text-align: right; }
.shift-detail-slot:not(:empty) { margin: 2px 0 6px; }
.shift-detail-slot .shift-detail { border-radius: var(--radius-sm); border: 1px solid var(--border); }
.staff-check.on-leave { opacity: 0.7; }
.leave-mark {
    font-size: 9.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    padding: 1px 6px;
    border-radius: 99px;
    background: var(--amber-soft);
    color: var(--amber-text);
}
@media (max-width: 1000px) { .shift-offers { display: none; } }

.nav-badge {
    margin-left: auto;
    font-size: 10.5px;
    font-weight: 600;
    min-width: 18px;
    text-align: center;
    padding: 1px 6px;
    border-radius: 99px;
    background: var(--brand);
    color: #fff;
}

.user-row {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    padding: 10px 14px;
    border-bottom: 1px solid var(--border);
    flex-wrap: wrap;
}
.user-row:last-child { border-bottom: none; }

/* "happening" gets a leading pulsing dot */
.badge.live::before {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 99px;
    background: currentColor;
    animation: live-pulse 1.6s ease-in-out infinite;
}
@keyframes live-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.35; }
}

/* ── Booking timeline ──────────────────────────────────────── */

.tl-scale, .tl-row { display: flex; align-items: center; gap: 10px; }
.tl-label {
    width: 96px;
    flex-shrink: 0;
    font-size: 11.5px;
    color: var(--text-3);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.tl-hours { display: flex; flex: 1; }
.tl-tick { flex: 1; font-size: 10px; color: var(--text-3); text-align: left; }
.tl-day {
    font-size: 11px;
    font-weight: 600;
    color: var(--text-2);
    margin: 10px 0 4px;
    text-transform: uppercase;
    letter-spacing: 0.4px;
}
.tl-row { margin-bottom: 4px; }
.tl-track {
    position: relative;
    flex: 1;
    height: 22px;
    background: var(--surface-2);
    border-radius: 5px;
    background-image: repeating-linear-gradient(to right, var(--border) 0 1px, transparent 1px calc(100% / 19));
}
.tl-bar {
    position: absolute;
    top: 3px;
    bottom: 3px;
    border-radius: 4px;
    display: flex;
    align-items: center;
    padding: 0 6px;
    overflow: hidden;
}
.tl-bar span { font-size: 10.5px; font-weight: 500; color: #fff; white-space: nowrap; }
.tl-bar.unsynced { background: transparent !important; border: 1.5px dashed var(--border-strong); }
.tl-bar.unsynced span { color: var(--text-2); }

.staffed-yes { color: var(--green-text); font-weight: 600; }
.staffed-part { color: var(--amber-text); font-weight: 500; font-size: 12px; font-variant-numeric: tabular-nums; }
.staffed-no { color: var(--red-text); font-weight: 600; }

/* Page-head action cluster — uniform control heights */
.page-actions { display: flex; gap: 8px; align-items: center; flex-shrink: 0; }
.page-actions form { display: contents; }
.page-actions .btn,
.page-actions .input {
    height: 32px;
    padding-top: 0;
    padding-bottom: 0;
    display: inline-flex;
    align-items: center;
    width: auto;
}

/* Sessions tech cell — identical height in every state */
.tech-cell { display: flex; align-items: center; gap: 6px; min-height: 28px; }
.tech-cell form { display: contents; }
.tech-cell .input {
    height: 28px;
    padding-top: 0;
    padding-bottom: 0;
    font-size: 12.5px;
    width: 140px;
}
.tech-cell select[name="service_ids"] { width: 118px; }
.tech-cell .btn.icon {
    width: 28px;
    height: 28px;
    padding: 0;
    justify-content: center;
    flex-shrink: 0;
}

/* Unstaffed sessions on the calendar — hollow, like the timeline */
.cal-event.unstaffed {
    background: transparent;
    border: 1.5px dashed currentColor;
    padding: 0.5px 4.5px;
}

/* ── Crew breakdown (shifts page) ──────────────────────────── */

.crew-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 180px;
    gap: 24px;
    align-items: center;
}
.crew-table th, .crew-table td { padding-left: 6px; padding-right: 6px; }
.crew-dot {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 3px;
}
.crew-pie-wrap { display: flex; justify-content: center; }
.crew-pie {
    width: 160px;
    height: 160px;
    border-radius: 50%;
    border: 1px solid var(--border);
}
@media (max-width: 800px) {
    .crew-layout { grid-template-columns: 1fr; }
}

/* ── Week calendar ─────────────────────────────────────────── */

.wk { display: flex; flex-direction: column; }
.wk-head {
    display: grid;
    grid-template-columns: 52px repeat(7, 1fr);
    border-bottom: 1px solid var(--border);
    background: var(--surface-2);
}
.wk-day-head {
    padding: 8px 10px;
    display: flex;
    align-items: baseline;
    gap: 6px;
    border-left: 1px solid var(--border);
}
.wk-day-head .dow { font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-3); }
.wk-day-head .dom { font-size: 16px; font-weight: 600; color: var(--text-2); }
.wk-day-head.today .dow, .wk-day-head.today .dom { color: var(--brand); }
.wk-body {
    display: grid;
    grid-template-columns: 52px repeat(7, 1fr);
    height: max(560px, calc(100vh - 320px));
}
.wk-axis { position: relative; }
.wk-body .wk-axis { display: flex; flex-direction: column; }
.wk-hour {
    flex: 1;
    font-size: 10px;
    color: var(--text-3);
    text-align: right;
    padding-right: 8px;
    transform: translateY(-6px);
}
.wk-hour:first-child { transform: none; }
.wk-col {
    position: relative;
    border-left: 1px solid var(--border);
    background-image: repeating-linear-gradient(
        to bottom,
        transparent 0 calc(100% / var(--hours) - 1px),
        var(--border) calc(100% / var(--hours) - 1px) calc(100% / var(--hours))
    );
}
.wk-col.today { background-color: var(--brand-soft); }
.wk-event {
    position: absolute;
    border-radius: 5px;
    padding: 3px 7px;
    overflow: hidden;
    font-size: 11px;
    line-height: 1.35;
    display: flex;
    flex-direction: column;
    min-height: 18px;
}
.wk-event:hover { text-decoration: none; filter: brightness(1.04); z-index: 5; }
.wk-event-name { font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wk-event-meta { font-size: 10px; opacity: 0.75; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wk-event.green  { background: var(--green-soft);  color: var(--green-text);  border-left: 3px solid var(--green); }
.wk-event.amber  { background: var(--amber-soft);  color: var(--amber-text);  border-left: 3px solid var(--amber); }
.wk-event.blue   { background: var(--blue-soft);   color: var(--blue-text);   border-left: 3px solid var(--blue); }
.wk-event.violet { background: var(--violet-soft); color: var(--violet-text); border-left: 3px solid var(--violet); }
.wk-event.pink   { background: var(--pink-soft);   color: var(--pink-text);   border-left: 3px solid var(--pink); }
.wk-event.teal   { background: var(--teal-soft);   color: var(--teal-text);   border-left: 3px solid var(--teal); }
.wk-event.slate  { background: var(--slate-soft);  color: var(--slate-text);  border-left: 3px solid var(--slate); }
.wk-event.red    { background: var(--red-soft);    color: var(--red-text);    border-left: 3px solid var(--red); }
.wk-event.unstaffed { background: transparent; border: 1.5px dashed currentColor; border-left-width: 3px; border-left-style: solid; }

/* Dashboard agenda: venue/tech as true aligned columns */
.agenda-venue { width: 100px; }
.agenda-tech { width: 76px; }

/* Recent bookings list */
.recent-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 9px 14px;
    border-bottom: 1px solid var(--border);
    color: var(--text);
}
.recent-row:last-child { border-bottom: none; }
.recent-row:hover { background: var(--surface-2); text-decoration: none; }
.recent-name {
    font-weight: 500;
    font-size: 13px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.recent-row .sub {
    font-size: 12px;
    color: var(--text-3);
    margin-top: 1px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.recent-status { font-weight: 500; }
.recent-status.green  { color: var(--green-text); }
.recent-status.amber  { color: var(--amber-text); }
.recent-status.blue   { color: var(--blue-text); }
.recent-status.violet { color: var(--violet-text); }
.recent-status.pink   { color: var(--pink-text); }
.recent-status.teal   { color: var(--teal-text); }
.recent-status.red    { color: var(--red-text); }
.recent-status.slate  { color: var(--text-2); }
.recent-total { font-size: 13px; flex-shrink: 0; }

/* ── Dashboard work queues — one calm card, five columns ───── */

.queues-card { margin-top: 12px; }
.queues-inner {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
}
.queue-col { min-width: 0; padding: 4px 0 8px; }
.queue-col + .queue-col { border-left: 1px solid var(--border); }
.queue-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    padding: 10px 14px 6px;
    font-size: 10.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-3);
}
.queue-head a { font-size: 11px; font-weight: 500; text-transform: none; letter-spacing: 0; }
.queue-empty { padding: 14px; font-size: 12.5px; color: var(--text-3); }
.queue-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 6px 14px;
    color: var(--text);
}
.queue-row:hover { background: var(--surface-2); text-decoration: none; }
.queue-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.queue-name {
    font-weight: 500;
    font-size: 13px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.queue-sub {
    font-size: 11.5px;
    color: var(--text-3);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-height: 15px;
}
.queue-side {
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 1px;
    min-width: 64px;
}
.queue-key { font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; }
.queue-key.amber { color: var(--amber-text); }
@media (max-width: 1500px) {
    /* 5 across gets tight before the mobile breakpoint — drop to 2 wide first.
       An odd column count leaves the last one alone on its row, which the
       nth-child rules below already border correctly. */
    .queues-inner { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .queue-col:nth-child(odd) { border-left: none; }
    .queue-col:nth-child(n+3) { border-top: 1px solid var(--border); }
}
@media (max-width: 1100px) {
    .queues-inner { grid-template-columns: 1fr; }
    .queue-col + .queue-col { border-left: none; border-top: 1px solid var(--border); }
}

.sms-who { padding: 10px 12px 8px; border-bottom: 1px solid var(--border); }


/* Split button with dropdown menu */
.split-btn { position: relative; display: inline-flex; }
.split-btn .btn:first-child { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.split-chevron {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
    margin-left: -1px;
    width: 28px;
}
.split-chevron svg { width: 14px; height: 14px; }
/* Legacy actions dropdown. Renamed off .menu/.menu-item because those collide
   with Sneat's sidebar classes and leaked onto the side menu on every page. */
.gsl-actions-menu {
    position: absolute;
    top: calc(100% + 4px);
    right: 0;
    min-width: 170px;
    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-2);
    padding: 4px;
    z-index: 100;
}
.gsl-actions-menu-item {
    display: block;
    width: 100%;
    text-align: left;
    border: none;
    background: transparent;
    font-family: var(--font);
    font-size: 13px;
    font-weight: 500;
    padding: 7px 10px;
    border-radius: 5px;
    cursor: pointer;
}
.gsl-actions-menu-item:hover { background: var(--surface-2); }

/* Modal */
.modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(10, 14, 22, 0.55);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 200;
    padding: 20px;
}
/* Scoped under .modal-overlay so the bare .modal class stays free for
   Bootstrap modals (Sneat) — an unscoped .modal broke them. */
.modal-overlay .modal {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-2);
    padding: 18px;
    width: 100%;
    max-width: 420px;
}

/* Artwork preview modal — wide enough to judge a print design or watch a
   background clip, and dark behind so the artwork is what you look at. */
.modal-overlay.preview-overlay { backdrop-filter: blur(3px); background: rgba(8, 10, 14, 0.72); }
.modal-overlay .modal.preview-modal { max-width: min(1000px, 94vw); }
.preview-modal img, .preview-modal video {
    display: block;
    margin: 0 auto;
    max-width: 100%;
    max-height: 72vh;
    border-radius: 8px;
}
.preview-modal img { background: #fff; }
.preview-modal video { background: #000; }
.preview-modal iframe { width: 100%; height: 72vh; border: 0; border-radius: 8px; background: #fff; }

/* Upload progress modal. The blur is scoped to this one — a file going up is
   the only case where the page behind is genuinely out of bounds until it
   finishes or you cancel. */
.modal-overlay.upload-overlay { backdrop-filter: blur(3px); }
.up-bar {
    height: 8px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 99px;
    overflow: hidden;
}
.up-fill {
    height: 100%;
    width: 0;
    background: var(--red);
    transition: width .12s linear;
}

.btn.disabled, .btn[disabled] {
    opacity: 0.45;
    cursor: not-allowed;
    pointer-events: auto;
}
.btn.disabled:hover, .btn[disabled]:hover { background: var(--surface); }

.booking-sms-thread {
    max-height: 320px;
    overflow-y: auto;
    padding: 4px 2px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

/* ── AAR charts & photos ───────────────────────────────────── */

.aar-chart-col { display: flex; flex-direction: column; }
.aar-bars {
    display: flex;
    align-items: flex-end;
    gap: 8px;
    padding: 10px 14px 0;
    flex: 1;
    min-height: 200px;
}
.aar-bar-col {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    height: 100%;
}
.aar-bar-n { font-size: 10.5px; color: var(--text-2); font-variant-numeric: tabular-nums; margin-bottom: 3px; min-height: 14px; }
.aar-bar {
    width: 100%;
    max-width: 52px;
    background: var(--blue);
    border-radius: 3px 3px 0 0;
    opacity: 0.8;
}
.aar-bar.zero { background: var(--border-strong); opacity: 1; border-radius: 1px; }
.aar-bar-col .aar-bar-label {
    width: 100%;
    text-align: center;
    font-size: 10px;
    color: var(--text-3);
    text-transform: uppercase;
    letter-spacing: 0.4px;
    border-top: 1px solid var(--border);
    padding: 5px 0 8px;
    margin-top: 0;
}

.tech-row { display: flex; align-items: center; gap: 8px; padding: 3px 0; }
.tech-name {
    width: 110px;
    flex-shrink: 0;
    font-size: 12px;
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.tech-track { flex: 1; height: 10px; background: var(--surface-2); border-radius: 99px; overflow: hidden; }
.tech-fill { height: 100%; background: var(--teal); opacity: 0.8; border-radius: 99px; }
.tech-meta { width: 64px; flex-shrink: 0; text-align: right; font-size: 11.5px; color: var(--text-2); }

.aar-photos {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
    gap: 8px;
}
.aar-photos img {
    width: 100%;
    height: 92px;
    object-fit: cover;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
}

.rating { font-weight: 600; font-variant-numeric: tabular-nums; }
.rating.good { color: var(--green-text); }
.rating.ok   { color: var(--amber-text); }
.rating.bad  { color: var(--red-text); }

/* ── shift time comparison (AAR detail) ────────────────────── */

.tspans { padding-bottom: 2px; }
.tspan-row { display: flex; align-items: center; gap: 8px; padding: 3px 0; }
.tspan-label {
    width: 44px;
    flex-shrink: 0;
    font-size: 10.5px;
    color: var(--text-3);
    text-transform: uppercase;
    letter-spacing: 0.4px;
}
.tspan-track {
    flex: 1;
    height: 14px;
    background: var(--surface-2);
    border-radius: 3px;
    position: relative;
    overflow: hidden;
}
.tspan-bar { position: absolute; top: 2px; bottom: 2px; border-radius: 2px; opacity: 0.85; }
.tspan-bar.sched { background: var(--border-strong); }
.tspan-bar.tech  { background: var(--blue); }
.tspan-bar.sling { background: var(--teal); }
.tspan-time {
    width: 148px;
    flex-shrink: 0;
    text-align: right;
    font-size: 11px;
    color: var(--text-2);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.tspan-axis {
    display: flex;
    justify-content: space-between;
    font-size: 10px;
    color: var(--text-3);
    margin: 2px 156px 0 52px;
    border-top: 1px solid var(--border);
    padding-top: 3px;
}

/* ── incident graphics ─────────────────────────────────────── */

.banner {
    padding: 9px 14px;
    border-radius: var(--radius-sm);
    font-size: 12.5px;
    margin-bottom: 12px;
    border: 1px solid var(--border);
}
.banner.red { background: var(--red-soft); color: var(--red-text); border-color: transparent; }

.sev-scale { display: flex; gap: 3px; }
.sev-seg { flex: 1; height: 8px; border-radius: 2px; background: var(--surface-2); }
.sev-seg.on.green { background: var(--green); }
.sev-seg.on.amber { background: var(--amber); }
.sev-seg.on.red   { background: var(--red); }
.sev-labels { display: flex; margin-top: 3px; }
.sev-labels span { flex: 1; text-align: center; font-size: 10px; color: var(--text-3); text-transform: capitalize; }
.sev-labels span.on { color: var(--text-1); font-weight: 600; }

.steps { display: grid; }
.step { display: flex; gap: 10px; position: relative; padding-bottom: 14px; }
.step:last-child { padding-bottom: 0; }
.step-dot {
    width: 10px; height: 10px;
    border-radius: 50%;
    background: var(--surface-2);
    border: 1.5px solid var(--border-strong);
    margin-top: 3px;
    flex-shrink: 0;
    z-index: 1;
}
.step.done .step-dot { background: var(--green); border-color: var(--green); }
.step-line { position: absolute; left: 4.5px; top: 14px; bottom: 2px; width: 1px; background: var(--border); }
.step-label { font-size: 12.5px; font-weight: 600; }
.step:not(.done) .step-label { color: var(--text-3); font-weight: 500; }

.stack-bar {
    width: 100%;
    max-width: 52px;
    display: flex;
    flex-direction: column;
    border-radius: 3px 3px 0 0;
    overflow: hidden;
}
.stack-seg.red   { background: var(--red); opacity: 0.85; }
.stack-seg.amber { background: var(--amber); opacity: 0.85; }

.legend-dot {
    display: inline-block;
    width: 8px; height: 8px;
    border-radius: 2px;
    margin-right: 2px;
    vertical-align: baseline;
}
.legend-dot.red   { background: var(--red); opacity: 0.85; }
.legend-dot.amber { background: var(--amber); opacity: 0.85; }

/* ── Quote / Invoice card sections ─────────────────────────── */
.qi-label {
    font-size: 10.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-3);
    margin: 0 0 7px;
}
.qi-divider { border: none; border-top: 1px solid var(--border); margin: 16px 0 12px; }

/* GSL logo in the sidebar brand */
.sidebar-brand .brand-logo { height: 26px; width: auto; display: block; }

/* Sortable table headers */
.sort-th { color: var(--text-3); text-decoration: none; cursor: pointer; white-space: nowrap; }
.sort-th:hover { color: var(--text); text-decoration: none; }
.sort-th.active { color: var(--brand); }

/* SMS compose: textarea + emoji picker */
.sms-compose { display: flex; gap: 8px; align-items: flex-end; }
.sms-input-wrap { flex: 1; position: relative; display: flex; }
.sms-input {
    flex: 1; resize: none; max-height: 120px; min-height: 38px;
    line-height: 1.4; padding-right: 36px; font-family: inherit;
}
.emoji-btn {
    position: absolute; right: 7px; bottom: 7px;
    background: none; border: none; cursor: pointer;
    line-height: 0; padding: 0; color: var(--text-3);
}
.emoji-btn svg { width: 19px; height: 19px; display: block; }
.emoji-btn:hover { color: var(--brand); }
.emoji-popup {
    position: absolute; bottom: calc(100% + 6px); right: 0; z-index: 120;
    background: var(--surface); border: 1px solid var(--border);
    border-radius: 8px; box-shadow: var(--shadow-2); padding: 8px;
    display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px;
    width: 296px; max-height: 220px; overflow-y: auto;
}
.emoji-item {
    background: none; border: none; cursor: pointer;
    font-size: 19px; line-height: 1; padding: 4px; border-radius: 6px;
}
.emoji-item:hover { background: var(--surface-2); }

/* ── GSL subtle cross-grid background (from the booking site) ──── */
.gsl-pattern {
    background-color: #0c0c0c;
    background-image: url("data:image/svg+xml,%3Csvg width='30' height='30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M15 11.5v7M11.5 15h7' stroke='%23ffffff' stroke-opacity='0.05' stroke-width='1' fill='none'/%3E%3C/svg%3E");
}

/* ── Login — branded GSL, passkey-first ───────────────────────── */
.login-wrap.gsl-pattern { background-color: #0c0c0c; }
.login-card {
    background: rgba(20, 20, 22, 0.94);
    border-color: #2c2c30;
    color: #ededee;
    backdrop-filter: blur(2px);
}
.login-card .logo-row { flex-direction: column; align-items: center; text-align: center; gap: 10px; }
.login-card h1 { color: #fff; }
.login-card label { color: #b0b0b6; font-size: 12px; }
.login-card .input { font-size: 16px; background: #242426; border-color: #3a3a3e; color: #fff; }
.login-card .input::placeholder { color: #6c6c72; }
.login-card .divider { color: #74747b; }
.login-card .divider::before, .login-card .divider::after { background: #2e2e31; }
.login-card .btn { font-size: 14px; }
.passkey-primary { padding: 13px; font-size: 15px; font-weight: 600; gap: 8px; }
.brand-logo-login { height: 42px; width: auto; display: block; }

/* Theme-swapped sidebar logo (white mark on dark, dark mark on light) */
.sidebar-brand .brand-logo--light { display: none; }
[data-theme="light"] .sidebar-brand .brand-logo--dark { display: none; }
[data-theme="light"] .sidebar-brand .brand-logo--light { display: block; }
.sidebar-footer { border-top-color: var(--border) !important; }

/* ── Login: slow subtle shimmer wave ──────────────────────── */
.login-wrap.gsl-pattern { position: relative; overflow: hidden; }
.login-wrap.gsl-pattern::before,
.login-wrap.gsl-pattern::after {
    content: ''; position: absolute; pointer-events: none; z-index: 0;
    width: 85vw; height: 85vw; max-width: 900px; max-height: 900px;
    border-radius: 50%; filter: blur(50px);
}
.login-wrap.gsl-pattern::before {
    background: radial-gradient(circle, rgba(211, 47, 47, 0.13), transparent 62%);
    top: -22%; left: -16%;
    animation: gsl-wave-a 19s ease-in-out infinite;
}
.login-wrap.gsl-pattern::after {
    background: radial-gradient(circle, rgba(255, 255, 255, 0.05), transparent 62%);
    bottom: -26%; right: -16%;
    animation: gsl-wave-b 25s ease-in-out infinite;
}
@keyframes gsl-wave-a {
    0%, 100% { transform: translate(0, 0) scale(1);        opacity: 0.45; }
    50%      { transform: translate(13%, 11%) scale(1.25); opacity: 1; }
}
@keyframes gsl-wave-b {
    0%, 100% { transform: translate(0, 0) scale(1);         opacity: 0.3; }
    50%      { transform: translate(-11%, -13%) scale(1.3); opacity: 0.75; }
}
.login-wrap.gsl-pattern .login-card { position: relative; z-index: 1; }
@media (prefers-reduced-motion: reduce) {
    .login-wrap.gsl-pattern::before, .login-wrap.gsl-pattern::after { animation: none; opacity: 0.5; }
}

/* ── Settings page ─────────────────────────────────────────── */
.settings-layout { display: grid; grid-template-columns: 168px 1fr; gap: 22px; align-items: start; }
.settings-nav { display: flex; flex-direction: column; gap: 2px; position: sticky; top: 16px; }
.settings-nav-item {
    padding: 8px 12px; border-radius: var(--radius-sm);
    color: var(--text-2); font-size: 13px; font-weight: 500;
}
.settings-nav-item:hover { background: var(--surface-2); text-decoration: none; color: var(--text); }
.settings-nav-item.active { background: var(--brand-soft); color: var(--brand); box-shadow: inset 2px 0 0 var(--brand); }
.settings-main { min-width: 0; }
.settings-form { max-width: 720px; }
.settings-users { display: grid; gap: 14px; }
.settings-users .add-user-card { max-width: 560px; }
/* ── Venue edit ─────────────────────────────────────────────
   This page is mostly large free-text fields — a venue's technical specs run
   to thousands of characters — so it uses the full content width rather than
   the narrow form column. Small fields get a fixed basis so they don't stretch
   with it, and the two stubby cards sit side by side instead of stacking. */
.venue-form .field-row .field-narrow { flex: 0 0 140px; }
.venue-form .field-row .field-short { flex: 0 0 170px; }
.venue-cap-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 10px 20px; }
/* Auto-fit rather than a fixed two columns, so adding a card doesn't leave the
   last one stranded on a half-width row. */
.venue-2col { display: grid; grid-template-columns: repeat(auto-fit, minmax(310px, 1fr)); gap: 16px; align-items: start; }
.venue-2col > .card { margin-bottom: 0; }
.venue-upload { max-width: 620px; }
/* A retired document is still listed here — the office is the only place it
   remains reachable — but it reads as inactive rather than current. */
.venue-doc-retired > td { opacity: .55; }
.venue-doc-retired a { text-decoration: line-through; }
@media (max-width: 1000px) {
    .venue-2col { grid-template-columns: 1fr; }
    .venue-form .field-row { flex-wrap: wrap; }
    .venue-form .field-row .field-narrow, .venue-form .field-row .field-short { flex: 1 1 140px; }
}

.settings-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 13px 16px; }
.settings-grid .field { grid-column: 1 / -1; margin: 0; }
.settings-grid .field-narrow { grid-column: span 1; }
.settings-grid .field label { text-transform: none; }
@media (max-width: 760px) {
    .settings-layout { grid-template-columns: 1fr; }
    .settings-nav { flex-direction: row; flex-wrap: wrap; position: static; }
    .settings-grid { grid-template-columns: 1fr; }
}

/* Notification/template reference cards */
.tmpl { padding: 10px 0; border-bottom: 1px solid var(--border); }
.tmpl:last-child { border-bottom: none; }
.tmpl-name { font-weight: 600; font-size: 13px; margin-bottom: 2px; }
.tmpl-when { font-size: 11.5px; color: var(--text-3); }
.tmpl-body { font-size: 12.5px; color: var(--text-2); margin-top: 3px; }

/* ── Add-equipment picker (booking view) ───────────────────── */
.equip-add { padding: 12px 14px; border-top: 1px solid var(--border); }
.equip-add-row { display: flex; gap: 8px; align-items: flex-end; flex-wrap: wrap; }
.equip-search-wrap { position: relative; flex: 1; min-width: 180px; }
.equip-search-wrap .input { width: 100%; }
.equip-field { display: flex; flex-direction: column; gap: 3px; flex-shrink: 0; }
.equip-field span { font-size: 10px; color: var(--text-3); font-weight: 600; text-transform: uppercase; letter-spacing: 0.3px; padding-left: 2px; }
.equip-field .input { width: 62px; }
.equip-field #equip-days { width: 78px; }
.equip-add-row .btn { flex-shrink: 0; }
.equip-results {
    position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 30;
    background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
    box-shadow: 0 6px 20px rgba(0,0,0,0.14); max-height: 260px; overflow-y: auto;
}
.equip-result { padding: 9px 12px; cursor: pointer; font-size: 13.5px; border-bottom: 1px solid var(--border); }
.equip-result:last-child { border-bottom: none; }
.equip-result:hover { background: var(--surface-2); }
.equip-result.muted { color: var(--text-3); cursor: default; }
#equip-selected { margin-top: 6px; }

/* ── Top-bar notification bell + dropdown ──────────────────── */
.notif { position: relative; }
.notif-btn {
    position: relative; display: grid; place-items: center;
    width: 36px; height: 36px; border-radius: 9px;
    background: none; border: 1px solid transparent; cursor: pointer; color: var(--text-2);
}
.notif-btn:hover { background: var(--surface-2); color: var(--text); }
.notif-btn svg { width: 19px; height: 19px; }
.notif-dot {
    position: absolute; top: 6px; right: 7px; min-width: 16px; height: 16px;
    padding: 0 4px; border-radius: 99px; background: var(--red); color: #fff;
    font-size: 10px; font-weight: 700; line-height: 16px; text-align: center;
    border: 2px solid var(--surface);
}
.notif-panel {
    position: absolute; top: calc(100% + 8px); right: 0; z-index: 60;
    width: 340px; max-width: 86vw;
    background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
    box-shadow: 0 10px 34px rgba(0,0,0,0.22); overflow: hidden;
}
.notif-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: 11px 14px; border-bottom: 1px solid var(--border);
    font-weight: 600; font-size: 13.5px;
}
.notif-enable {
    display: flex; align-items: center; gap: 8px; width: 100%;
    background: var(--brand-soft); color: var(--brand); border: none; cursor: pointer;
    font-size: 12.5px; font-weight: 600; padding: 10px 14px; text-align: left;
    border-bottom: 1px solid var(--border);
}
.notif-enable svg { width: 16px; height: 16px; flex-shrink: 0; }
.notif-enable:hover { filter: brightness(0.96); }
.notif-enable.disabled { opacity: 0.6; cursor: default; }
.notif-enable[data-on="1"] { background: var(--green-soft); color: var(--green-text); }
.notif-list { max-height: 380px; overflow-y: auto; }
.notif-item {
    display: block; padding: 11px 14px; border-bottom: 1px solid var(--border); color: inherit;
}
.notif-item:last-child { border-bottom: none; }
.notif-item:hover { background: var(--surface-2); text-decoration: none; }
.notif-item .ni-top { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; }
.notif-item .ni-name { font-size: 13px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.notif-item.unread .ni-name { font-weight: 700; }
.notif-item .ni-time { font-size: 11px; color: var(--text-3); white-space: nowrap; flex-shrink: 0; }
.notif-item .ni-preview { font-size: 12px; color: var(--text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 2px; }
.notif-item .ni-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--brand); margin-right: 5px; vertical-align: middle; }
.notif-empty { padding: 22px 14px; text-align: center; color: var(--text-3); font-size: 12.5px; }

/* ── Busy overlay spinner ───────────────────────────────────── */
.busy-modal { text-align: center; min-width: 210px; }
.spinner {
    width: 30px; height: 30px; margin: 0 auto;
    border: 3px solid var(--border-strong);
    border-top-color: var(--brand);
    border-radius: 50%;
    animation: app-spin 0.7s linear infinite;
}
@keyframes app-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spinner { animation-duration: 1.6s; } }
#app-alert-body ul { margin: 8px 0 0; padding-left: 18px; }
#app-alert-body li { margin-bottom: 3px; }

/* ── Bookings filter dropdown + happening highlight ─────────── */
.booking-filter { width: auto; min-width: 160px; font-size: 13px; font-weight: 500; padding-right: 28px; }
.show-completed { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--text-2); cursor: pointer; white-space: nowrap; }
.show-completed input { width: 15px; height: 15px; cursor: pointer; }
.table tr.row-happening td { background: var(--green-soft); }
.table tr.row-happening:hover td { background: var(--green-soft); filter: brightness(0.98); }
.table tr.row-happening td:first-child { box-shadow: inset 3px 0 0 var(--green); }

/* SMS template picker (booking comms) */
/* Matches the message box below it: same width, same 38px height, same left
   edge. It was shrink-to-fit at 30px, so it sat short and narrow above a
   full-width input. */
.sms-template-select {
    width: 100%;
    height: 38px;
    font-size: 13px;
    font-weight: 500;
    padding: 0 28px 0 10px;
}

/* Client-side sortable table headers (Finance) */
.th-sort { cursor: pointer; user-select: none; white-space: nowrap; }
.th-sort:hover { color: var(--text); }
.th-sort::after { content: ''; opacity: 0.3; margin-left: 5px; font-size: 10px; }
.th-sort.sorted-asc::after { content: '↑'; opacity: 1; }
.th-sort.sorted-desc::after { content: '↓'; opacity: 1; }

/* ── Reports ─────────────────────────────────────────────────── */
.report-head { display: flex; align-items: flex-start; gap: 16px; }
.report-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.date-range-form { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.date-range-form label { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-2); }
.date-range-form .input { width: auto; padding: 5px 8px; }

.report-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 14px; }
.report-card { background: var(--surface); border: none; box-shadow: var(--shadow-1); border-radius: var(--radius); padding: 16px; display: flex; flex-direction: column; gap: 14px; }
.report-card-top { display: flex; gap: 12px; align-items: flex-start; }
.report-card h3 { margin: 0; font-size: 14px; font-weight: 600; }
.report-card p { margin: 3px 0 0; font-size: 12px; color: var(--text-3); }
.report-ic { width: 40px; height: 40px; border-radius: 10px; display: grid; place-items: center; flex-shrink: 0; }
.report-ic svg { width: 20px; height: 20px; }
.report-ic.red { background: var(--red-soft); color: var(--red-text); }
.report-ic.green { background: var(--green-soft); color: var(--green-text); }
.report-ic.blue { background: var(--blue-soft); color: var(--blue-text); }
.report-ic.amber { background: var(--amber-soft); color: var(--amber-text); }
.report-ic.pink { background: var(--pink-soft); color: var(--pink-text); }
.report-ic.teal { background: var(--teal-soft); color: var(--teal-text); }
.btn.block { width: 100%; justify-content: center; }
.btn.block.disabled { opacity: 0.5; pointer-events: none; }

.custom-report-form { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; }
.custom-report-form .field { margin: 0; }
.custom-report-form .input { width: auto; }
/* Match the height of the dropdown, date inputs and the button */
.custom-report-form .input, .custom-report-form .btn { height: 38px; }

.report-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
@media (max-width: 900px) { .report-2col { grid-template-columns: 1fr; } }

/* Horizontal CSS bars (charts) */
.bar-row { display: flex; align-items: center; gap: 10px; padding: 3px 0; font-size: 12px; }
.bar-label { width: 90px; flex-shrink: 0; color: var(--text-2); white-space: nowrap; }
.bar-track { flex: 1; height: 16px; background: var(--surface-3); border-radius: 4px; overflow: hidden; }
.bar-fill { display: block; height: 100%; background: var(--brand); border-radius: 4px; }
.bar-fill.blue { background: var(--blue); } .bar-fill.green { background: var(--green); }
.bar-val { width: 150px; flex-shrink: 0; text-align: right; color: var(--text-2); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* P&L boxes */
.pl-boxes { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
@media (max-width: 760px) { .pl-boxes { grid-template-columns: 1fr; } }
.pl-box { padding: 14px; border-radius: var(--radius-sm); }
.pl-box.green { background: var(--green-soft); } .pl-box.red { background: var(--red-soft); } .pl-box.amber { background: var(--amber-soft); }
.pl-box .label { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.4px; opacity: 0.85; }
.pl-box .amt { font-size: 20px; font-weight: 700; margin-top: 3px; }
.pl-box .pl-sub { display: flex; justify-content: space-between; font-size: 11.5px; margin-top: 5px; opacity: 0.85; }

/* Shift flag tiles */
.flag-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px; }
.flag { background: var(--surface); border: 1px solid var(--border); border-left-width: 3px; border-radius: var(--radius-sm); padding: 8px 12px; }
.flag .label { font-size: 11px; color: var(--text-2); } .flag .n { font-size: 18px; font-weight: 700; }
.flag.red { border-left-color: var(--red); } .flag.amber { border-left-color: var(--amber); }
.flag.blue { border-left-color: var(--blue); } .flag.slate { border-left-color: var(--slate); }

/* Segmented rating bar */
.seg-bar { display: flex; height: 18px; border-radius: 5px; overflow: hidden; background: var(--surface-3); margin: 4px 0 10px; }
.seg { height: 100%; }
.seg.green { background: var(--green); } .seg.blue { background: var(--blue); } .seg.slate { background: var(--slate); }
.seg.amber { background: var(--amber); } .seg.red { background: var(--red); } .seg.teal { background: var(--teal); }
.seg-legend { display: flex; flex-wrap: wrap; gap: 6px; }

.compliance { padding: 4px 0 10px; }
.compliance-head { display: flex; justify-content: space-between; font-size: 12.5px; font-weight: 500; margin-bottom: 4px; }

/* Print → clean PDF via the browser */
@media print {
    .sidebar, .topbar, .no-print, .report-actions { display: none !important; }
    .main, .content { margin: 0 !important; padding: 0 !important; max-width: none !important; }
    .card, .report-card, .stat, .flag, .pl-box { break-inside: avoid; }
    body, .shell { background: #fff !important; }
}

/* Subtle [CurrentRMS] source tag inside item names */
.rms-tag { color: var(--text-3); font-weight: 400; font-size: 0.9em; }

/* Equipment report — category table (75%) + pie (25%), Top-5 drill-down */
.report-cat-row { display: grid; grid-template-columns: 3fr 1fr; gap: 16px; align-items: stretch; }
@media (max-width: 900px) { .report-cat-row { grid-template-columns: 1fr; } }
/* Match the category table height to the pie box, spreading its rows to fill */
.report-cat-row > .card:first-child { display: flex; flex-direction: column; }
.report-cat-row > .card:first-child .card-body { flex: 1; }
.report-cat-row > .card:first-child table { height: 100%; }
.pie { width: 150px; height: 150px; border-radius: 50%; margin: 6px auto 14px; position: relative; }
.pie::after { content: ''; position: absolute; inset: 30%; background: var(--surface); border-radius: 50%; }
.pie-legend { display: grid; gap: 5px; text-align: left; }
.pie-leg { display: flex; align-items: center; gap: 7px; font-size: 12px; }
.pie-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pie-amt { margin-left: auto; color: var(--text-2); font-variant-numeric: tabular-nums; padding-left: 8px; }
.pie-dot { width: 9px; height: 9px; border-radius: 2px; flex-shrink: 0; display: inline-block; margin-right: 6px; vertical-align: middle; }
.clickable-row, .clickable-cat { cursor: pointer; }
.clickable-row:hover td, .clickable-cat:hover td { background: var(--surface-2); }
.table tfoot td { border-top: 2px solid var(--border); }
.pie-leg.zero .pie-name, .pie-leg.zero .pie-amt { color: var(--text-3); }

/* Equipment drill-down modal — cap height and scroll the list */
#eq-item-modal .modal { max-height: 85vh; display: flex; flex-direction: column; }
#eq-item-body { overflow-y: auto; flex: 1; min-height: 0; }

/* Add-to-Home-Screen / Dock hint (Safari iOS + macOS) */
.a2hs-banner { position: fixed; left: 50%; transform: translateX(-50%); bottom: calc(16px + env(safe-area-inset-bottom, 0px)); z-index: 300; display: flex; align-items: center; gap: 12px; max-width: 440px; width: calc(100% - 28px); background: var(--surface); border: 1px solid var(--border-strong); border-radius: 12px; box-shadow: var(--shadow-2); padding: 11px 14px; }
.a2hs-banner.a2hs-above-tabs { bottom: calc(72px + env(safe-area-inset-bottom, 0px)); }
.a2hs-logo { width: 34px; height: 34px; border-radius: 8px; background: var(--brand); color: #fff; font-weight: 800; font-size: 11.5px; display: grid; place-items: center; flex-shrink: 0; }
.a2hs-text { display: flex; flex-direction: column; gap: 2px; font-size: 12.5px; line-height: 1.35; min-width: 0; }
.a2hs-text strong { font-size: 13px; }
.a2hs-text span { color: var(--text-2); }
.a2hs-close { margin-left: auto; align-self: flex-start; background: none; border: none; color: var(--text-3); font-size: 20px; line-height: 1; cursor: pointer; padding: 0 2px; flex-shrink: 0; }
.a2hs-close:hover { color: var(--text); }
@media print { .a2hs-banner { display: none !important; } }

/* ── Narrow-viewport fallback for desktop-only pages ─────────
   Pages without a mobile version (/settings, /enquiries, /shift-status, …)
   still render this desktop layout on phones. Below 700px the fixed sidebar
   becomes a horizontally scrollable strip of nav links across the top and
   the main column takes the full width. A usability floor, not a redesign. */
@media (max-width: 700px) {
    .shell { flex-direction: column; }
    .sidebar {
        position: static;
        width: 100%;
        height: auto;
        flex-direction: row;
        align-items: center;
        border-right: none;
        border-bottom: 1px solid var(--border);
    }
    .sidebar-brand { display: none; }
    .sidebar-nav {
        display: flex;
        align-items: center;
        gap: 2px;
        padding: 8px;
        overflow-x: auto;
        overflow-y: hidden;
        -webkit-overflow-scrolling: touch;
    }
    .sidebar-nav .nav-section { display: none; }
    .sidebar-nav .nav-link, .sidebar-footer .nav-link {
        flex-shrink: 0;
        white-space: nowrap;
        margin-bottom: 0;
        min-height: 40px;
    }
    .nav-link.active { box-shadow: inset 0 -2px 0 var(--brand); }
    .sidebar-footer {
        flex-shrink: 0;
        border-top: none;
        border-left: 1px solid var(--border);
        padding: 8px;
    }
    .topbar { padding: 0 14px; }
    .content { padding: 14px 12px 28px; }
    /* Wide content (tables, calendar grids) scrolls inside its card instead of
       crushing to unreadable slivers — 7-column grids can't stack meaningfully. */
    .card { overflow-x: auto; }
    .card table { min-width: 560px; }
    .cal, .wk { min-width: 560px; }
}

/* ── Settings → Notifications matrix ──────────────────────── */
.notif-masters { display: flex; flex-wrap: wrap; gap: 18px; margin-top: 4px; }
.notif-master { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600; }
.notif-master input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--brand); }

.notif-table { width: 100%; }
.notif-table th, .notif-table td { vertical-align: middle; }
.notif-table th.notif-ch, .notif-table td.notif-ch { width: 78px; text-align: center; }
.notif-table th.notif-who, .notif-table td.notif-who { width: 96px; white-space: nowrap; }
.notif-table td.notif-ch input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--brand); }
.notif-ch-off { opacity: .45; }
.notif-name { font-weight: 600; }
.notif-what { font-size: 12.5px; color: var(--text-3); margin-top: 2px; }
.notif-when { font-size: 12px; color: var(--text-3); opacity: .8; margin-top: 2px; }
.notif-na { color: var(--text-3); opacity: .5; }
.notif-always { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-3); }

@media (max-width: 720px) {
    .notif-table td.notif-who, .notif-table th.notif-who { display: none; }
    .notif-table th.notif-ch, .notif-table td.notif-ch { width: 54px; }
    .notif-what { display: none; }
}

/* ── Topbar global search (Sneat-style) ────────────────────── */
.topbar-search { display: flex; align-items: center; gap: 9px; flex: 0 1 340px; color: var(--text-3); }
.topbar-search svg { width: 17px; height: 17px; flex-shrink: 0; }
.topbar-search input {
    width: 100%; border: none; background: transparent; color: var(--text);
    font-family: var(--font); font-size: 13.5px; padding: 8px 0; outline: none;
}
.topbar-search input::placeholder { color: var(--text-3); }

/* ── Sidebar logo — dark-mode swap without a second asset ────
   gsl-logo-dark.png is pure black line-art + red waveform. invert(1)
   flips black to white; hue-rotate(180deg) then rotates the now-cyan
   waveform back to red (invert of pure red IS cyan, and cyan sits at
   180° from red on the hue wheel — the rotate undoes exactly that).
   Black/white/transparent have no hue, so the rotate doesn't touch them. */
[data-theme="dark"] .app-brand-logo img { filter: invert(1) hue-rotate(180deg); }

/* ── Equipment table ────────────────────────────────────────
   Denser than the app-wide 13px table text: item names are long and sit beside
   small numeric inputs, so 13px read oversized against the 10.5px headers.
   Sized as a row (name, qty, rate, total) so nothing mismatches. */
.eq-table td { font-size: 12px; }
/* Stays compact against the 38px default — this table is dense, and a rate box
   the size of a form field would add 7px to every row of a long kit list. */
.eq-table td .input { font-size: 12px; height: 30px; }

/* ── Dashboard week grid ────────────────────────────────────
   Seven fixed columns, Mon–Sun. Columns are ~95px on this layout, so a cell
   only carries start time + shortened venue; full detail is in the popup.
   minmax(0,1fr) so long venue names can't force the grid wider. */
.wkgrid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; }
.wkday {
    border: 1px solid var(--border); border-radius: 8px; background: var(--surface);
    padding: 7px 6px 8px; min-height: 104px; display: flex; flex-direction: column;
}
.wkday.has-items { cursor: pointer; }
.wkday.has-items:hover { border-color: var(--border-strong); background: var(--surface-2); }
.wkday.has-items:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
.wkday.is-past { opacity: 0.55; }
.wkday.is-today { border-color: var(--brand); }
.wkday-head { display: flex; align-items: baseline; gap: 5px; margin-bottom: 6px; }
.wkday-dow { font-size: 10px; text-transform: uppercase; letter-spacing: .06em; color: var(--text-3); }
.wkday-dom { font-size: 15px; font-weight: 600; color: var(--text-2); line-height: 1; }
.wkday.is-today .wkday-dom, .wkday.is-today .wkday-dow { color: var(--brand); }
.wkday-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.wkday-none { color: var(--text-3); font-size: 12px; }
.wkchip {
    display: flex; align-items: center; gap: 4px; min-width: 0;
    font-size: 11px; line-height: 1.35; color: var(--text-2);
}
.wkchip-dot { flex: 0 0 5px; width: 5px; height: 5px; border-radius: 99px; background: var(--text-3); }
.wkchip-time { font-variant-numeric: tabular-nums; color: var(--text); white-space: nowrap; }
.wkchip-venue { color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wkday-more { font-size: 10.5px; color: var(--text-3); margin-top: 1px; }

/* Day popup rows */
.wkpop-row {
    display: flex; align-items: flex-start; gap: 12px; padding: 9px 4px;
    border-bottom: 1px solid var(--border); text-decoration: none; color: inherit;
}
.wkpop-row:last-child { border-bottom: none; }
.wkpop-row:hover { background: var(--surface-2); }
.wkpop-time { font-size: 12px; font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--text-2); flex: 0 0 auto; min-width: 96px; }
.wkpop-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.wkpop-event { font-size: 13px; font-weight: 500; }
.wkpop-org { font-size: 11.5px; color: var(--text-3); }
.wkpop-meta { font-size: 11.5px; color: var(--text-3); }
.wkpop-dot { display: inline-block; width: 6px; height: 6px; border-radius: 99px; margin-right: 4px; vertical-align: middle; }
.wkpop-open { color: var(--amber-text); }
.wkpop-ref { font-size: 11px; color: var(--text-3); font-family: var(--mono); white-space: nowrap; flex: 0 0 auto; }

@media (max-width: 900px) {
    .wkgrid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* Two equal columns — for cards that should share the row evenly, unlike
   .grid-2's deliberate 1.6fr / 1fr split. */
.grid-half { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
@media (max-width: 900px) { .grid-half { grid-template-columns: 1fr; } }

/* Week stepper in the Schedule card head */
.wknav { display: flex; align-items: center; gap: 8px; }
.wknav .btn { padding: 3px 9px; font-size: 12px; }
.wknav .btn.icon { padding: 3px 8px; line-height: 1.2; font-size: 15px; }
.wknav .btn.disabled { opacity: .45; pointer-events: none; }

/* Dashboard vertical rhythm. Schedule and the row beneath it are separate
   top-level blocks now (Schedule went full width), so without this they butt
   together — the other sections space themselves with margin-bottom. */
.dash-section { margin-bottom: 16px; }

/* ── Modal: blurred neutral backdrop, no motion ─────────────
   Bootstrap ships --bs-backdrop-bg: #22303e (a blue slate) at 50% opacity, which
   read as a blue wash over the page. Neutral dark + a real blur instead. Opacity
   is forced to 1 so the blur isn't fighting a half-transparent layer — the tint
   comes from the rgba background. */
.modal-backdrop, .modal-backdrop.show {
    background-color: rgba(8, 8, 8, 0.5);
    opacity: 1;
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
}
/* No slide-in — the dialog appears where it lands. */
.modal.fade .modal-dialog { transform: none; transition: none; }
.modal.fade { transition: none; }

/* Row-style links must never underline: the whole row is the hit target, so
   underlining every word on hover looks like broken text rather than a link.
   The global a:hover rule would otherwise apply. */
.wkpop-row:hover, .queue-row:hover, .agenda-row:hover, .wkpop-row:focus, .queue-row:focus {
    text-decoration: none;
}

/* Kit expander in the Equipment table.
   Was the character "▸" at 15px — a *small* triangle glyph, so almost all of
   that box is whitespace and the visible mark came out around 6px. Now a real
   SVG chevron inside a 34px tap target.

   Sized to match the sidebar's collapsible-group chevron. Sneat draws that one
   as a 0.45em square with 2px borders rotated 45° (.menu-toggle::after), which
   at the 15px body size is ~9.5px of visible mark. This path spans 14 of 24
   viewBox units vertically, so 14px + a 3-unit stroke lands on ~9.9px — the
   same weight and the same footprint.
   Rotation is instant (no transition) — the app has no motion. */
.eq-toggle {
    background: none; border: none; cursor: pointer; color: var(--text-2);
    line-height: 1; padding: 0;
    width: 34px; height: 34px; margin: -8px 2px -8px -8px;
    display: inline-flex; align-items: center; justify-content: center;
    vertical-align: middle; flex-shrink: 0; border-radius: 6px;
}
.eq-toggle svg { width: 14px; height: 14px; display: block; }
.eq-toggle[aria-expanded="true"] svg { transform: rotate(90deg); }
.eq-toggle:hover, .eq-toggle:focus-visible { background: var(--surface-3); color: var(--text); }
/* Keep "· 2 components" whole — it was breaking mid-phrase onto its own line. */
.eq-sub { font-size: 11.5px; color: var(--text-3); white-space: nowrap; }

/* ── Client access card: button layout ──────────────────────
   Primary action full width on top, the two secondary actions sharing the row
   beneath. The buttons sit inside <form>s, so both the form and the button have
   to be stretched — a plain inline-flex .btn would otherwise shrink to its text
   and leave the row ragged, which is what this replaced. */
.portal-actions { display: grid; gap: 8px; }
.portal-actions > form { display: block; }
.portal-actions > form > .btn,
.portal-actions > .btn { width: 100%; }
/* auto-fit so the row still fills the card when there is only one button in it
   (no contact email on the booking hides "Send internet access"). */
.portal-actions-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
    gap: 8px;
}
.portal-actions-row > form { display: block; }
.portal-actions-row > form > .btn,
.portal-actions-row > .btn { width: 100%; }
/* Centred labels and a 32px tap target, consistent across all three. */
.portal-actions .btn {
    justify-content: center;
    text-align: center;
    min-height: 32px;
}

/* ── Signature proof in the Quote / Invoice card ─────────────
   Sits inside the Signature <dd> so it aligns with the value column rather
   than the card edge. */
.sig-proof { margin-top: 6px; }
.sig-proof img {
    display: block;
    max-width: 190px; max-height: 64px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: #fff;
    padding: 3px;
}
.sig-meta {
    display: flex; flex-wrap: wrap; gap: 2px 14px;
    margin-top: 4px;
    font-size: 11.5px; color: var(--text-3);
}

/* ── Discussion note replies ─────────────────────────────────
   One level of nesting: a left rule marks the thread, the same way a quoted
   reply reads in an email client. */
.note-head { flex-wrap: wrap; }
.note-reply-btn {
    margin-left: auto;
    background: none; border: none; padding: 2px 4px;
    font-family: var(--font); font-size: 12px; font-weight: 600;
    color: var(--text-3); cursor: pointer; border-radius: 4px;
}
.note-reply-btn:hover, .note-reply-btn:focus-visible { color: var(--brand); }
.note-replies {
    margin: 8px 0 0 2px;
    padding-left: 12px;
    border-left: 2px solid var(--border);
}
.note-reply { padding: 6px 0; }
.note-reply + .note-reply { border-top: 1px solid var(--border); }
.note-reply-form { margin-top: 10px; }
.note-reply-form textarea { margin-bottom: 8px; }
.note-reply-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.note-reply-actions label { display: flex; align-items: center; gap: 6px; margin: 0; }

/* ── Staff briefing card ─────────────────────────────────────
   A <details> styled as a card so it collapses with no JS. The summary is the
   card head, so the whole strip is the click target. */
.brief-card { padding: 0; }
.brief-summary {
    cursor: pointer;
    list-style: none;
    user-select: none;
    align-items: center;
}
.brief-summary::-webkit-details-marker { display: none; }
/* Disclosure chevron, matching the equipment expander. */
.brief-summary::after {
    content: '';
    margin-left: auto;
    width: 9px; height: 9px;
    border-right: 2px solid var(--text-3);
    border-bottom: 2px solid var(--text-3);
    transform: rotate(45deg);
    flex-shrink: 0;
}
.brief-card[open] > .brief-summary::after { transform: rotate(-135deg); }
.brief-summary:hover::after { border-color: var(--brand); }
.brief-summary h3 { margin-right: 10px; }
.brief-text {
    min-height: 240px;
    resize: vertical;
    line-height: 1.55;
    font-family: var(--font);
}
.brief-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
.brief-foot { margin: 10px 0 0; }

/* ── Purchases ──────────────────────────────────────────────
   One card per request: the facts, then whatever action it's waiting on. */
.purchase-meta { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px 18px; }
.purchase-meta > div > div { font-size: 14.5px; margin-top: 1px; }
.purchase-actions { display: flex; align-items: flex-end; gap: 10px; flex-wrap: wrap; margin-top: 14px;
    padding-top: 14px; border-top: 1px solid var(--border); }
.purchase-oncharge { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--border); }
.purchase-oncharge .purchase-actions { margin-top: 0; padding-top: 0; border-top: 0; }
.purchase-send { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 12px; }
.purchase-send-form { display: inline; }
.btn-link { background: none; border: 0; padding: 0; color: var(--text-3); text-decoration: underline; }
.purchase-tick { display: flex; align-items: center; margin-right: 2px; }
.purchase-tick input { width: 17px; height: 17px; cursor: pointer; }
.purchase-card.is-dimmed { opacity: .45; }
/* Selection bar: only appears once something is ticked. */
.purchase-bar { position: sticky; bottom: 0; z-index: 20; margin-top: 16px;
    background: var(--surface); border: 1px solid var(--border-strong);
    border-radius: 12px; box-shadow: var(--shadow-2); }
.purchase-bar[hidden] { display: none; }
.purchase-bar-inner { display: flex; align-items: center; gap: 14px; padding: 12px 16px; }
.purchase-bar-inner > div:first-child { flex: 1; min-width: 0; }

/* ── Xero contact picker ────────────────────────────────────
   Type-ahead on the venue billing contact. The menu is absolutely positioned,
   so its field is the positioning context. */
.xc-field { position: relative; }
.xc-menu { position: absolute; z-index: 40; left: 0; right: 0; top: 100%; margin-top: 4px;
    max-height: 280px; overflow-y: auto; background: var(--surface);
    border: 1px solid var(--border-strong); border-radius: 10px; box-shadow: var(--shadow-2); }
.xc-menu[hidden] { display: none; }
.xc-opt { padding: 9px 12px; cursor: pointer; font-size: 14px; }
.xc-opt + .xc-opt { border-top: 1px solid var(--border); }
.xc-opt.on, .xc-opt:hover { background: var(--brand-soft); }
.xc-name { display: block; font-weight: 500; }
.xc-mail { display: block; font-size: 12px; color: var(--text-3); margin-top: 1px; }
/* A name that isn't in Xero is allowed but flagged — it will create a contact. */
.input.xc-warn { border-color: var(--amber); }
.xc-note { color: var(--amber-text); margin: 6px 0 0; }
.xc-note[hidden] { display: none; }

/* ── On-charge preview ──────────────────────────────────────
   The two real Xero PDFs side by side, with the email below them. */
.preview-2col { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 16px; align-items: start; }
.doc-frame { display: block; width: 100%; height: 620px; border: 0; }
.email-frame { display: block; width: 100%; height: 560px; border: 1px solid var(--border); border-radius: 8px; background: #fff; }
.preview-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 24px; }

/* ── Receipts ───────────────────────────────────────────────
   A thumbnail for image receipts, a PDF chip otherwise, and the upload beside. */
.receipt-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 12px;
    padding-top: 12px; border-top: 1px solid var(--border); }
.receipt-thumb { flex: none; width: 52px; height: 52px; border-radius: 8px; overflow: hidden;
    border: 1px solid var(--border); background: var(--surface-2);
    display: flex; align-items: center; justify-content: center; text-decoration: none; }
.receipt-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.receipt-pdf { font-size: 11px; font-weight: 700; letter-spacing: .04em; color: var(--text-3); }
.receipt-upload { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-left: auto; }
.receipt-upload .input { width: auto; max-width: 230px; }
.receipt-upload .input[type="number"] { max-width: 110px; }
.input.small, .btn.small { padding: 7px 10px; font-size: 13px; }

/* ── Money inputs ───────────────────────────────────────────
   A $ sitting inside the field. Absolutely positioned rather than a separate
   box, so it can't be mistaken for something typed and doesn't get submitted. */
.money-input { position: relative; }
.money-input > span { position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
    color: var(--text-3); font-size: 14px; line-height: 1; pointer-events: none; }
.money-input > .input { padding-left: 25px; }
.money-input > .input.small { padding-left: 22px; }

/* ── On-charge editor ───────────────────────────────────────
   Three columns on a wide screen: the amount and its controls, the client-facing
   note, then Save. The amount block is fixed-width so its chips always sit on one
   line — they were wrapping into three rows in a 260px column. */
.oc-form { display: grid; grid-template-columns: 300px minmax(240px, 1fr) auto; gap: 16px;
    align-items: start; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--border); }
.oc-form label { display: block; font-size: 12px; font-weight: 600; letter-spacing: .02em;
    text-transform: uppercase; color: var(--text-3); margin-bottom: 6px; }
.oc-entry { display: flex; gap: 8px; align-items: stretch; }
.oc-entry .money-input { flex: 1; min-width: 0; }

/* Two-state basis selector. Segmented, because it is one question with two
   answers — not two separate actions. */
.oc-basis { flex: none; display: inline-flex; padding: 3px; gap: 2px;
    background: var(--surface-3); border-radius: 9px; }
.oc-opt { padding: 0 11px; border: 0; border-radius: 7px; background: none; cursor: pointer;
    font-family: inherit; font-size: 12.5px; font-weight: 500; color: var(--text-3); white-space: nowrap; }
.oc-opt.is-on { background: var(--surface); color: var(--text); box-shadow: 0 1px 2px rgba(0,0,0,.10); }
.oc-opt:hover:not(.is-on) { color: var(--text-2); }

.oc-chips { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; margin-top: 8px; }
/* Both figures, always, so the basis toggle can never be misread. */
.oc-readout { font-size: 12.5px; color: var(--text-2); margin-top: 7px; min-height: 17px; }
.oc-save { align-self: end; }
@media (max-width: 900px) {
    .oc-form { grid-template-columns: 1fr; }
    .oc-save { align-self: start; justify-self: start; }
}

/* ── Amount helper chips ────────────────────────────────────

   GST and markup arithmetic on the on-charge amount, so it isn't done in
   someone's head against a GST-inclusive receipt. */
.amt-tools { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; margin-top: 7px; }
.chip { padding: 4px 9px; border: 1px solid var(--border-strong); border-radius: 99px;
    background: var(--surface); color: var(--text-2); font-size: 12px; font-weight: 500;
    cursor: pointer; font-family: inherit; line-height: 1.5; }
.chip:hover { background: var(--surface-3); color: var(--text); }
.chip:active { background: var(--border); }
.amt-note { font-size: 12px; color: var(--text-3); margin-top: 5px; min-height: 16px; }

/* ── Dashboard: shifts to action ────────────────────────────
   Two columns because they are two different jobs — reassigning someone who
   pulled out, versus staffing an empty shift. Merged into one list you can't
   tell at a glance how much of each you have. */
.shift-split { display: grid; grid-template-columns: 1fr 1fr; gap: 0 18px; }
.shift-split > .shift-col + .shift-col { border-left: 1px solid var(--border); padding-left: 18px; }
.shift-col { min-width: 0; }
.shift-col-head { display: flex; align-items: center; gap: 7px; font-size: 11px; font-weight: 600;
    letter-spacing: .05em; text-transform: uppercase; color: var(--text-3); margin-bottom: 4px; }
.shift-n { min-width: 17px; height: 17px; padding: 0 5px; border-radius: 99px; font-size: 11px;
    font-weight: 600; display: inline-flex; align-items: center; justify-content: center; }
.shift-n.red { background: var(--red-soft); color: var(--red-text); }
.shift-n.amber { background: var(--amber-soft); color: var(--amber-text); }
.shift-col .queue-row { padding-left: 0; padding-right: 0; }
@media (max-width: 700px) {
    .shift-split { grid-template-columns: 1fr; }
    .shift-split > .shift-col + .shift-col { border-left: 0; padding-left: 0;
        border-top: 1px solid var(--border); padding-top: 10px; margin-top: 6px; }
}

/* ── Venue photo crop ───────────────────────────────────────
   The frame is the public card's real shape (h-48 in a 3-column grid ≈ 2:1),
   and .crop-frame img uses the SAME rules the public card uses, so what is
   framed here is what visitors get. Nothing is written to the file — the crop
   is a focus point plus a zoom, stored on the venue. */
.crop-wrap { display: grid; grid-template-columns: minmax(280px, 460px) minmax(220px, 1fr); gap: 20px; align-items: start; }
.crop-stage { min-width: 0; }
.crop-frame {
    position: relative; width: 100%; aspect-ratio: 2 / 1; overflow: hidden;
    border-radius: 12px; background: var(--surface-3);
    border: 1px solid var(--border-strong);
    cursor: grab; touch-action: none; user-select: none;
}
.crop-frame.is-dragging { cursor: grabbing; }
.crop-frame img { width: 100%; height: 100%; object-fit: cover; display: block; pointer-events: none; }
.crop-empty { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    color: var(--text-3); font-size: 13px; }
/* Rule-of-thirds guides, so the outline reads as a crop tool rather than a box. */
.crop-frame::after {
    content: ''; position: absolute; inset: 0; pointer-events: none;
    background:
        linear-gradient(to right, transparent 33.33%, rgba(255,255,255,.35) 33.33%, rgba(255,255,255,.35) calc(33.33% + 1px), transparent calc(33.33% + 1px),
                        transparent 66.66%, rgba(255,255,255,.35) 66.66%, rgba(255,255,255,.35) calc(66.66% + 1px), transparent calc(66.66% + 1px)),
        linear-gradient(to bottom, transparent 33.33%, rgba(255,255,255,.35) 33.33%, rgba(255,255,255,.35) calc(33.33% + 1px), transparent calc(33.33% + 1px),
                        transparent 66.66%, rgba(255,255,255,.35) 66.66%, rgba(255,255,255,.35) calc(66.66% + 1px), transparent calc(66.66% + 1px));
    opacity: 0; transition: opacity .12s ease;
}
.crop-frame:hover::after, .crop-frame.is-dragging::after { opacity: 1; }

.crop-controls { min-width: 0; }
.crop-controls label { display: block; font-size: 12px; font-weight: 600; letter-spacing: .02em;
    text-transform: uppercase; color: var(--text-3); margin-bottom: 6px; }
.crop-slider { width: 100%; margin: 0 0 12px; }
.crop-readout { font-size: 12.5px; color: var(--text-2); margin-bottom: 12px; min-height: 17px; }
.photo-upload { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.photo-upload .input { width: auto; max-width: 340px; }
@media (max-width: 820px) { .crop-wrap { grid-template-columns: 1fr; } }

/* ── Venue form save bar ────────────────────────────────────
   Sticky: this form runs to several screens once a venue has real specs on
   file, and Save sat below all of it. The bottom margin matters — without it
   the next card butts straight against the bar. */
.venue-save-bar { position: sticky; bottom: 12px; z-index: 30; margin: 20px 0 28px;
    background: var(--surface); border: 1px solid var(--border-strong);
    border-radius: 12px; box-shadow: var(--shadow-2); }
.venue-save-inner { display: flex; align-items: center; gap: 10px; padding: 12px 14px; }
.venue-save-inner .btn { flex: none; }
/* Pushed right by its own margin, so it works whatever the source order and
   whether or not it is hidden. */
.venue-dirty { margin-left: auto; font-size: 13px; color: var(--amber-text); font-weight: 500; }
.venue-dirty[hidden] { display: none; }

/* Cards after the form save on their own, so they get a labelled break rather
   than running on from the form as if Save covered them. */
.venue-extras { display: flex; align-items: center; gap: 12px; margin: 0 0 12px; }
.venue-extras span { font-size: 11.5px; font-weight: 600; letter-spacing: .05em;
    text-transform: uppercase; color: var(--text-3); white-space: nowrap; }
.venue-extras::after { content: ''; flex: 1; height: 1px; background: var(--border); }

/* ── Nested sidebar groups + action pills (menu restructure 2026-08-04) ──
   Second-level groups (Reports inside Operations) indent one step and keep the
   same Sneat caret the top-level toggles draw via .menu-toggle::after. */
.menu-sub .menu-sub { padding-left: 16px; }
.menu-sub .menu-sub .menu-link { font-size: 0.94em; }
/* Action-count pills. Absolutely positioned at one constant right offset so
   every pill sits in a single vertical column — toggle links reserve space for
   the Sneat caret (its ::after is absolute at padding-x + 0.3rem) while plain
   links don't, which is what made flow-positioned pills zig-zag. */
#layout-menu .menu-link { position: relative; }
#layout-menu .menu-pill {
    position: absolute; inset-inline-end: 2.4rem; top: 50%;
    transform: translateY(-50%); margin: 0;
    font-size: 10.5px; min-width: 18px; text-align: center;
}
/* Bootstrap's .badge sets display, which beats the [hidden] UA default. */
#layout-menu .menu-pill[hidden] { display: none !important; }
/* A group's pill exists to surface what's hidden inside it — once the group is
   open the child pills are visible, so the header total would double-count. */
#layout-menu .menu-item.open > .menu-toggle .menu-pill { display: none; }

/* Overdue chase ladder — the plan for one case, done above the line and
   projected below it. Rows stay legible when the labels wrap on mobile. */
.ladder { display: grid; gap: 2px; margin: 0 0 6px; }
.ladder-row { display: grid; grid-template-columns: 16px 1fr auto; gap: 8px; align-items: baseline; padding: 5px 0; border-bottom: 1px solid var(--border); }
.ladder-row:last-child { border-bottom: 0; }
.ladder-mark { color: var(--text-3); font-size: 12px; text-align: center; }
.ladder-body { min-width: 0; display: flex; flex-wrap: wrap; gap: 4px 8px; align-items: baseline; }
.ladder-label { font-size: 13px; }
.ladder-when { white-space: nowrap; color: var(--text-3); }
.ladder-row.is-done .ladder-label { color: var(--text-3); }
.ladder-row.is-done .ladder-mark { color: var(--green-text); }
.ladder-row.is-next .ladder-label { font-weight: 600; }
.ladder-row.is-next .ladder-mark { color: var(--amber-text); }
