/* HDProtek Live Operations — base stylesheet.
   Same design language as HDProtek Presentation and Content Operation (slate
   navy sidebar, HDProtek blue accent, Inter), but laid out mobile-first: the
   primary user is a field operator on a phone, in a van, one-handed. */

* { margin: 0; padding: 0; box-sizing: border-box; }

:root {
    --bg: #f8fafc;
    --card: #ffffff;
    --border: #e2e8f0;
    --text: #0f172a;
    --muted: #64748b;
    --accent: #149ed8;           /* HDProtek blue (sampled from the logo) */
    --accent-hover: #0f7fb0;
    --sidebar-bg: #0f172a;       /* Content Operation slate navy */
    --sidebar-text: #cbd5e1;
    --sidebar-active: #1e40af;
    --danger: #dc2626;
    --danger-bg: #fee2e2;
    --success: #16a34a;
    --success-bg: #dcfce7;
    --warn: #f59e0b;
    --warn-bg: #fef3c7;
    --info: #0284c7;
    --info-bg: #e0f2fe;

    --nav-h: 56px;               /* mobile top bar */
    --tabbar-h: 60px;            /* mobile bottom tab bar */
    --radius: 10px;
}

.hidden { display: none !important; }

html, body { height: 100%; }
body {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    background: var(--bg);
    color: var(--text);
    font-size: 15px;
    line-height: 1.55;
    -webkit-text-size-adjust: 100%;
}
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ============================================================
   Layout — mobile first: top bar + content + bottom tab bar.
   The sidebar appears only from 900px up.

   An app shell, not a scrolling document: the layout is exactly one viewport
   tall, and the *content* scrolls between a fixed top bar and a fixed tab bar.

   Two iOS-in-standalone lessons are baked into this rule, both learned the
   hard way on a phone:

   1. The tab bar must not be `position: fixed; bottom: 0`. When the document
      does not scroll, iOS lines a fixed element up against a different box
      than when it does — so the bar sat correctly on a long page and floated a
      home-indicator's height above the bottom on a short one ("My Events").
   2. The shell must not be measured in viewport units. `height: 100svh` came
      out shorter than the screen once installed to the Home Screen: the whole
      app bunched up at the top with a dead strip underneath.

   So: no units, no fixed children. `inset: 0` pins the shell to all four edges
   of whatever iOS considers the viewport, and the tab bar is simply the last
   flex item in it.
   ============================================================ */
.layout {
    position: fixed; inset: 0;
    display: flex; flex-direction: column;
    overflow: hidden;
}

.sidebar { display: none; }

.topbar {
    position: relative; z-index: 30; flex-shrink: 0;
    /* The notch inset is ADDED to the bar, never eaten out of it. With
       border-box, `height: 56px` + `padding-top: 47px` leaves a 9px content
       strip: on a notched phone the logo and the log-out button spill out of it
       and the whole bar reads as shifted. The side insets matter in landscape,
       where the notch eats into one edge. */
    height: calc(var(--nav-h) + env(safe-area-inset-top));
    background: var(--sidebar-bg);
    color: #fff;
    display: flex; align-items: center; gap: 12px;
    padding: env(safe-area-inset-top) max(14px, env(safe-area-inset-right))
             0 max(14px, env(safe-area-inset-left));
}
.topbar .brand {
    display: flex; align-items: center; gap: 9px; font-weight: 700; font-size: 15px;
    min-width: 0;                        /* let the label ellipsis instead of pushing Log out off-screen */
}
.topbar .brand img { height: 30px; width: auto; flex-shrink: 0; }
.topbar .brand span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.topbar .spacer { flex: 1; }
.topbar .topbar-action {
    color: #cbd5e1; font-size: 13px; font-weight: 600; white-space: nowrap; flex-shrink: 0;
    padding: 6px 10px; border-radius: 8px; background: rgba(255,255,255,.08);
}
.topbar .topbar-action:hover { text-decoration: none; background: rgba(255,255,255,.16); color: #fff; }

/* The one scrolling element on a phone. min-height:0 is what lets a flex child
   actually shrink and scroll instead of stretching its parent. */
.content {
    flex: 1; min-height: 0; min-width: 0;
    display: flex; flex-direction: column;
    overflow-y: auto; overflow-x: hidden; -webkit-overflow-scrolling: touch;
    overscroll-behavior-y: contain;
}
/* Side padding respects the notch in landscape, where the inset eats one edge. */
.content-header {
    padding: 16px max(16px, env(safe-area-inset-right)) 0 max(16px, env(safe-area-inset-left));
    display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; flex-wrap: wrap;
}
.content-header > div:first-child { min-width: 0; flex: 1 1 220px; }
.content-header h1 { font-size: 20px; font-weight: 700; line-height: 1.3; word-break: break-word; }
.content-header .subtitle { color: var(--muted); font-size: 13.5px; margin-top: 2px; word-break: break-word; }
.header-actions {
    display: flex; gap: 8px; flex-wrap: wrap; align-items: center;
    max-width: 100%;
}
.content-body {
    /* No tab-bar allowance any more: the bar is a sibling in the shell, not an
       overlay, so nothing of it covers the last row of content. */
    padding: 16px max(16px, env(safe-area-inset-right)) 28px max(16px, env(safe-area-inset-left));
    flex: 1;
    min-width: 0;
}

/* Bottom tab bar — thumb-reachable, the primary navigation on a phone.
   Part of the shell (see .layout): a flex item, deliberately not fixed. */
.tabbar {
    flex-shrink: 0; z-index: 40;
    height: calc(var(--tabbar-h) + env(safe-area-inset-bottom));
    padding: 0 env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
    background: #fff;
    border-top: 1px solid var(--border);
    display: flex;
}
.tabbar a {
    flex: 1 1 0; min-width: 0;           /* five tabs must share a 360px phone, not overflow it */
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
    color: var(--muted); font-size: 11px; font-weight: 600;
    text-decoration: none; text-align: center;
    padding: 0 2px;
}
.tabbar a > span:last-child {
    max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tabbar a .tab-icon { font-size: 20px; line-height: 1; }
.tabbar a.active { color: var(--accent); }
.tabbar a:hover { text-decoration: none; }
.tabbar a.tab-center { font-weight: 600; }
.tabbar a.tab-center .tab-icon { font-size: 21px; }

/* ============================================================
   Desktop — sidebar layout (the centre works on a real screen)
   ============================================================ */
@media (min-width: 900px) {
    /* Desktop keeps the same one-screen shell, sideways. `inset: 0` carries
       over from the mobile rule; only the direction changes. */
    .layout { flex-direction: row; }
    .topbar, .tabbar { display: none; }

    .sidebar {
        display: flex; flex-direction: column;
        width: 240px; flex-shrink: 0; height: 100%; overflow: hidden;
        background: var(--sidebar-bg); color: var(--sidebar-text);
    }
    /* Mark over wordmark, centred. The mark alone left the panel looking
       unfinished; the old version was simply too tall. This keeps both, at a
       size that costs one line rather than a menu item's worth of height. */
    .sidebar-header {
        padding: 16px 16px 14px; border-bottom: 1px solid #1e293b;
        text-align: center;
    }
    .brand-logo { width: 46px; height: auto; display: block; margin: 0 auto 7px; }
    .brand-title { font-size: 14.5px; font-weight: 700; color: #fff; line-height: 1.15; }
    .brand-tagline {
        font-size: 9.5px; color: #64748b; letter-spacing: .7px;
        text-transform: uppercase; margin-top: 2px;
    }
    .sidebar-nav { flex: 1; padding: 12px 8px; overflow-y: auto; }
    .sidebar-footer { padding: 8px 8px 8px; border-top: 1px solid #1e293b; }
    .nav-group-toggle {
        display: flex; align-items: center; gap: 8px; width: 100%;
        padding: 12px 14px 6px; background: transparent; border: none;
        color: #64748b; font-size: 11px; font-weight: 700; letter-spacing: .6px;
        text-transform: uppercase; cursor: pointer; text-align: left;
        font-family: inherit; margin-top: 4px;
    }
    .nav-group-toggle:hover { color: #fff; }
    .nav-group-arrow {
        display: inline-block; font-size: 10px; width: 12px; text-align: center;
        transition: transform 0.15s;
    }
    .nav-group-toggle[aria-expanded="false"] .nav-group-arrow { transform: rotate(-90deg); }
    .nav-group-content.collapsed { display: none; }
    .nav-item {
        display: flex; align-items: center; gap: 10px;
        padding: 9px 14px; border-radius: 8px;
        color: var(--sidebar-text); font-size: 14px; font-weight: 500; margin-bottom: 2px;
    }
    .nav-item:hover { background: #1e293b; color: #fff; text-decoration: none; }
    .nav-item.active { background: var(--sidebar-active); color: #fff; }
    .nav-icon { font-size: 16px; width: 20px; text-align: center; }
    .nav-badge {
        margin-left: auto; background: var(--danger); color: #fff;
        font-size: 11px; font-weight: 700; padding: 1px 7px; border-radius: 99px;
    }
    .user-row {
        display: flex; align-items: center; gap: 10px;
        padding: 8px 6px 6px 14px;
    }
    .user-info { flex: 1; min-width: 0; color: #94a3b8; font-size: 12px; }
    .user-name {
        color: #fff; font-weight: 600; font-size: 13px;
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    }
    .user-role { color: #64748b; text-transform: uppercase; font-size: 10px; letter-spacing: 1px; margin-top: 2px; }
    .logout-btn {
        flex-shrink: 0; display: inline-flex; align-items: center; gap: 5px;
        padding: 6px 10px; border: 1px solid #334155; border-radius: 7px;
        color: #fca5a5; font-size: 12px; font-weight: 600; text-decoration: none;
        transition: background 0.15s, border-color 0.15s, color 0.15s;
    }
    .logout-btn .logout-icon { font-size: 13px; line-height: 1; }
    .logout-btn:hover { background: #7f1d1d; border-color: #7f1d1d; color: #fff; text-decoration: none; }
    .app-version {
        text-align: left; padding: 2px 6px 0 14px;
        font-size: 10.5px; letter-spacing: 0.4px; line-height: 1.4;
        color: #64748b; font-family: ui-monospace, "SF Mono", monospace;
    }

    /* One line on a real screen: chips, then the date navigator, then the
       filters. Nothing is pushed to the far edge — the reset button belongs
       next to the date it resets, not at the end of the bar. */
    .day-bar { flex-wrap: nowrap; }
    .view-switch, .vsw { flex: 0 0 auto; }
    .nav-row { flex: 0 1 auto; }
    .nav-row .date-input { width: 165px; flex: 0 0 auto; }
    .filter-row { flex: 1 1 auto; }
    .filter-row select { flex: 0 1 210px; }

    .content { overflow-y: auto; }
    .content-header {
        padding: 20px 28px 0;
        position: sticky; top: 0; background: var(--bg); z-index: 5;
    }
    .content-header h1 { font-size: 23px; }
    .content-body { padding: 18px 28px 40px; }
}

/* Date / view control bar — shared by the event list and the calendar.

   Three groups, not eight loose controls: the range chips, the date navigator
   (◀ input ▶) and the filters. Grouping is what makes it survive a narrow
   screen — each group wraps as a whole row. Loose children wrapped one at a
   time, which left the arrows floating away from the date they move and the
   reset button stranded on the far right. */
.day-bar { display: flex; gap: 8px; align-items: center; margin-bottom: 12px; flex-wrap: wrap; }

.view-switch { display: flex; gap: 6px; flex: 1 1 100%; }
.vsw {
    flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    padding: 8px 12px; border-radius: 9px; font-size: 13px; font-weight: 650;
    background: #fff; border: 1px solid var(--border); color: var(--text);
    min-height: 44px; white-space: nowrap;
}
.vsw:hover { text-decoration: none; background: var(--bg); }
.vsw.active { background: var(--sidebar-bg); border-color: var(--sidebar-bg); color: #fff; }

.nav-row { display: flex; align-items: center; gap: 8px; flex: 1 1 100%; }
.nav-row .date-input { flex: 1 1 auto; min-width: 0; }
.nav-arrow { flex: 0 0 auto; width: 46px; padding: 0 ; justify-content: center; }

.filter-row { display: flex; align-items: center; gap: 8px; flex: 1 1 100%; flex-wrap: wrap; }
.filter-row select { flex: 1 1 150px; min-width: 0; }
.filter-row .reset-btn { flex: 0 0 auto; }
.range-line {
    display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
    font-size: 13px; font-weight: 600; margin: -4px 0 14px 2px;
}
.range-icon { opacity: .8; }
.range-count {
    font-size: 11.5px; font-weight: 700; color: var(--muted);
    background: #f1f5f9; border-radius: 99px; padding: 1px 8px;
}

/* Inclusive from/to bar — reports, incidents, crew/vehicle cards.
   Preset chips + one airline-style dual-date control. Native date inputs
   stay in the form for no-JS; JS hides them and opens a single calendar
   panel. That is presentation only — it does not change the PWA. */
.range-bar {
    display: flex; flex-direction: column; align-items: flex-start; gap: 8px;
    margin-bottom: 16px; padding: 10px 12px;
    background: var(--card); border: 1px solid var(--border);
    border-radius: var(--radius);
    position: relative;
}
.range-presets { display: flex; flex-wrap: wrap; gap: 6px; width: 100%; }
.range-chip {
    display: inline-flex; align-items: center; justify-content: center;
    padding: 8px 12px; min-height: 44px; border-radius: 9px;
    border: 1px solid var(--border); background: #fff;
    font-size: 13px; font-weight: 650; color: var(--text); white-space: nowrap;
}
.range-chip:hover { text-decoration: none; background: var(--bg); }
.range-chip.active {
    background: var(--sidebar-bg); border-color: var(--sidebar-bg); color: #fff;
}
.range-toggle {
    display: none; width: 100%; max-width: 340px; min-width: 0; min-height: 44px;
    align-items: center; justify-content: space-between; gap: 8px;
    padding: 8px 12px; border: 1px solid var(--border); border-radius: 9px;
    background: #fff; font: inherit; font-size: 14px; font-weight: 650;
    color: var(--text); text-align: left; cursor: pointer;
}
.range-bar.is-enhanced .range-toggle { display: flex; }
.range-bar.is-enhanced .range-native { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0,0,0,0); }
.range-toggle:hover { background: var(--bg); }
.range-bar.is-open .range-toggle {
    border-color: var(--accent); box-shadow: 0 0 0 3px rgba(20,158,216,.14);
}
.range-toggle-dates { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.range-toggle-caret { color: var(--muted); flex-shrink: 0; }
.range-native { display: flex; align-items: flex-end; gap: 8px; flex-wrap: wrap; width: 100%; max-width: 420px; }
.range-field { display: flex; flex-direction: column; gap: 4px; margin: 0; flex: 1 1 140px; min-width: 0; }
.range-field-label {
    font-size: 11px; font-weight: 700; color: var(--muted);
    text-transform: uppercase; letter-spacing: .4px;
}
.range-field input[type=date] { min-height: 44px; }
.range-span {
    font-size: 12.5px; font-weight: 700; color: var(--muted);
    background: #f1f5f9; border-radius: 99px; padding: 6px 10px;
    white-space: nowrap; align-self: center;
}
.range-panel {
    display: none; position: absolute; z-index: 45; left: 12px; top: calc(100% + 6px);
    width: 300px; max-width: calc(100% - 24px);
    background: #fff; border: 1px solid var(--border); border-radius: 12px;
    box-shadow: 0 14px 36px rgba(15, 23, 42, .16); padding: 12px;
}
.range-bar.is-open .range-panel { display: block; }
.range-panel-hint { font-size: 12.5px; color: var(--muted); font-weight: 600; margin: 0 0 10px; }
.range-months { display: block; }
.range-month-head {
    display: flex; align-items: center; justify-content: space-between;
    font-size: 13.5px; font-weight: 700; margin-bottom: 8px;
}
.range-month-nav {
    width: 36px; height: 36px; border: 1px solid var(--border); border-radius: 8px;
    background: #fff; cursor: pointer; font-size: 16px;
}
.range-month-nav:hover { background: var(--bg); }
.range-dow, .range-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.range-dow span {
    text-align: center; font-size: 10.5px; font-weight: 700; color: var(--muted);
    text-transform: uppercase; padding: 4px 0;
}
.range-day {
    min-height: 40px; border: 0; border-radius: 8px; background: transparent;
    font: inherit; font-size: 13px; font-weight: 600; color: var(--text); cursor: pointer;
}
.range-day:hover { background: #e0f2fe; }
.range-day.is-muted { color: #cbd5e1; }
.range-day.is-in { background: #e0f2fe; }
.range-day.is-start, .range-day.is-end { background: var(--sidebar-bg); color: #fff; }
.range-day.is-today:not(.is-start):not(.is-end) { box-shadow: inset 0 0 0 1.5px var(--accent); }

.push-banner {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    margin: 0 0 14px; padding: 12px 14px;
    background: var(--info-bg); border: 1px solid #bae6fd; border-radius: var(--radius);
}
.push-banner p { margin: 0; font-size: 13.5px; color: #075985; flex: 1 1 200px; }
.push-banner strong { display: block; font-size: 14px; color: var(--text); margin-bottom: 2px; }
.push-banner .btn { min-height: 40px; }

@media (max-width: 720px) {
    .range-presets { display: grid; grid-template-columns: 1fr 1fr 1fr; }
    .range-chip { width: 100%; padding: 8px 6px; font-size: 12.5px; }
    .range-toggle { max-width: none; }
    .range-panel { width: min(300px, calc(100% - 24px)); }
}

/* Searchable single-select. Native <select> stays in the form (no-JS fallback);
   this is the presentation layer, same contract as .ms-field. */
.combo { position: relative; min-width: 0; }
.combo-native {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; padding: 0;
}
.combo-btn {
    width: 100%; display: flex; align-items: center; justify-content: space-between;
    gap: 8px; min-height: 44px; padding: 8px 12px;
    border: 1px solid var(--border); border-radius: 9px; background: #fff;
    font: inherit; font-size: 14.5px; font-weight: 600; color: var(--text);
    text-align: left; cursor: pointer;
}
.combo-btn:hover { background: var(--bg); }
.combo.is-open .combo-btn {
    border-color: var(--accent); box-shadow: 0 0 0 3px rgba(20,158,216,.14);
}
.combo.is-invalid .combo-btn {
    border-color: var(--danger); box-shadow: 0 0 0 3px rgba(220,38,38,.14);
}
.combo-btn-label {
    min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.combo-caret { color: var(--muted); flex-shrink: 0; font-size: 12px; }
.combo-panel {
    position: absolute; z-index: 40; left: 0; right: 0; top: calc(100% + 4px);
    background: #fff; border: 1px solid var(--border); border-radius: 10px;
    box-shadow: 0 10px 28px rgba(15, 23, 42, .12); overflow: hidden;
}
.combo-search {
    width: 100%; border: 0; border-bottom: 1px solid var(--border);
    border-radius: 0; min-height: 44px; font-size: 16px;
}
.combo-list {
    list-style: none; margin: 0; padding: 6px; max-height: 280px;
    overflow-y: auto; -webkit-overflow-scrolling: touch;
}
.combo-option {
    display: block; width: 100%; text-align: left;
    padding: 9px 10px; border: 0; border-radius: 7px;
    background: transparent; font: inherit; font-size: 14px; color: var(--text);
    cursor: pointer;
}
.combo-option:hover, .combo-option.is-active { background: #f1f5f9; }
.combo-option.is-selected { font-weight: 700; color: var(--accent); }
.combo-empty { padding: 12px 14px; font-size: 13px; }
.filter-row .combo { flex: 1 1 150px; min-width: 0; }
.filter-bar .combo { flex: 1 1 180px; min-width: 0; max-width: 280px; }
@media (max-width: 600px) {
    .filter-bar .combo { max-width: 100%; flex: 1 1 100%; }
}

/* ============================================================
   Cards, KPIs, tables, forms
   ============================================================ */
.card {
    background: var(--card); border: 1px solid var(--border);
    border-radius: var(--radius); padding: 16px 18px; margin-bottom: 14px;
    min-width: 0; max-width: 100%;
}

/* Card title with a leading icon — the Content Operation / Budget & Reporting
   convention. The emoji is not decoration: on a dense screen it is what the eye
   lands on first, so a section is recognised before it is read. */
.card-title {
    font-size: 15px; font-weight: 700; margin-bottom: 12px;
    display: flex; align-items: center; gap: 2px; flex-wrap: wrap;
}
.card-title .ci { margin-right: 7px; font-size: 16px; line-height: 1; }

/* Header row inside a card: title + subtitle on the left, actions on the right,
   separated from the body by a rule. */
.card-header {
    display: flex; justify-content: space-between; align-items: flex-start;
    gap: 12px; margin-bottom: 14px; padding-bottom: 14px;
    border-bottom: 1px solid var(--border); flex-wrap: wrap;
}
.card-header .card-title { margin-bottom: 0; }
.card-subtitle { font-size: 12.5px; color: var(--muted); margin-top: 4px; }
.card-header-actions { display: flex; gap: 8px; flex-wrap: wrap; }

.section-header-muted {
    font-size: 11px; text-transform: uppercase; letter-spacing: .6px;
    color: var(--muted); margin: 18px 0 8px; font-weight: 700;
}

.kpi-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 12px; margin-bottom: 18px; }
.kpi {
    background: var(--card); border: 1px solid var(--border);
    border-left: 4px solid var(--accent);
    border-radius: var(--radius); padding: 14px 16px;
}
.kpi.danger  { border-left-color: var(--danger); }
.kpi.warn    { border-left-color: var(--warn); }
.kpi.success { border-left-color: var(--success); }
.kpi-icon { font-size: 22px; line-height: 1; margin-bottom: 6px; display: block; }
.kpi-label { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .5px; font-weight: 700; }
.kpi-value {
    font-size: 28px; font-weight: 700; line-height: 1.2; margin-top: 4px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-variant-numeric: tabular-nums;
}
.kpi.danger  .kpi-value { color: var(--danger); }
.kpi.warn    .kpi-value { color: #d97706; }
.kpi.success .kpi-value { color: var(--success); }
.kpi-hint { font-size: 12.5px; color: var(--muted); margin-top: 2px; }

/* Status dot — a colored circle before a label. Reads faster than a badge when
   the row already carries text, and keeps tables from turning into pill soup. */
.dot {
    display: inline-block; width: 8px; height: 8px; border-radius: 50%;
    margin-right: 6px; vertical-align: middle; flex-shrink: 0;
}
.dot-success { background: var(--success); }
.dot-warn    { background: var(--warn); }
.dot-danger  { background: var(--danger); }
.dot-muted   { background: #cbd5e1; }

/* Read-only value rendered like an input, so a detail view lines up with the
   form it mirrors. */
.field-display {
    display: block; padding: 9px 12px; border: 1px solid var(--border); border-radius: 8px;
    background: var(--bg); font-size: 14px; min-height: 38px; line-height: 1.4; color: var(--text);
}
.field-display-multiline { min-height: 62px; white-space: pre-wrap; }

.empty {
    text-align: center; padding: 40px 20px; color: var(--muted);
    background: var(--card); border: 1px dashed var(--border); border-radius: var(--radius);
}
.empty .empty-icon { font-size: 34px; display: block; margin-bottom: 10px; opacity: .6; }

.badge {
    display: inline-flex; align-items: center; gap: 4px;
    font-size: 11.5px; font-weight: 700; padding: 2px 9px; border-radius: 99px;
    letter-spacing: .2px; white-space: nowrap;
}
.badge.ok,      .badge-success  { background: var(--success-bg); color: #166534; }
.badge.fail,    .badge-danger   { background: var(--danger-bg);  color: #991b1b; }
.badge.pending, .badge-warning  { background: var(--warn-bg);    color: #92400e; }
.badge.info,    .badge-info     { background: var(--info-bg);    color: #075985; }
.badge.muted,   .badge-neutral  { background: #f1f5f9;           color: var(--muted); }
/* Role colours, matching Content Operation's convention */
.badge-admin   { background: #dbeafe; color: #1e40af; }
.badge-central { background: #e0e7ff; color: #3730a3; }
.badge-field   { background: #f3f4f6; color: #4b5563; }

table { width: 100%; border-collapse: collapse; font-size: 14px; }
th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--border); vertical-align: middle; }
th {
    background: var(--bg); font-size: 12px; font-weight: 650;
    text-transform: uppercase; letter-spacing: .4px; color: var(--muted);
    position: sticky; top: 0;
    /* A heading never wraps. The explicit widths below are hints; a wrapped
       heading is not — "Reached air" over two lines reads as two columns, and
       the eye loses which figures belong to it. With nowrap the column takes
       the width its own name needs and .table-wrap scrolls if the screen is
       too narrow, which is the honest trade. */
    white-space: nowrap;
}
tbody tr:hover { background: #f8fafc; }
/* Icon in a column heading — same reasoning as .ci in a card title: the column
   is recognised before it is read. Muted so it never competes with the data. */
.th-i { margin-right: 6px; opacity: .75; font-size: 12.5px; }
/* The heading of a number column sits over its digits. Cells carrying .num are
   right-aligned; without this the heading stayed at the left edge and the two
   never lined up — the wider the column, the further apart they drifted. Rule:
   if the cells in a column are .num, its <th> is .th-num. */
.th-num { text-align: right; }
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); width: 100%; max-width: 100%; min-width: 0; }

.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 7px;
    font: inherit; font-size: 14px; font-weight: 600; cursor: pointer;
    padding: 10px 16px; border-radius: 9px;
    border: 1px solid var(--border); background: #fff; color: var(--text);
    min-height: 44px;                    /* touch target */
    text-decoration: none;
}
.btn:hover { background: var(--bg); text-decoration: none; }
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn.primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.btn.danger { background: var(--danger); border-color: var(--danger); color: #fff; }
.btn.block { width: 100%; }
.btn.small { min-height: 34px; padding: 6px 12px; font-size: 13px; }
.btn:disabled { opacity: .5; cursor: not-allowed; }

.form-group { margin-bottom: 14px; min-width: 0; }
label {
    display: flex; align-items: center; gap: 6px;
    font-size: 12.5px; font-weight: 650; color: var(--muted); margin-bottom: 6px;
}
/* Icon inside a form label — same idea as .ci in a card title: the field is
   recognised before it is read, which matters on a long planning form. */
label .li { font-size: 14px; line-height: 1; flex-shrink: 0; }
/* The same glyph in a definition list (the incident summary), where there is
   no flex gap to space it off the word. */
.kv dt .li { font-size: 13px; margin-right: 5px; opacity: .85; }
input[type=text], input[type=password], input[type=email], input[type=number],
input[type=search], input[type=date], input[type=time], input[type=datetime-local],
select, textarea {
    width: 100%; font: inherit; font-size: 16px;   /* 16px: stops iOS zooming on focus */
    padding: 11px 12px; border: 1px solid var(--border); border-radius: 9px;
    background: #fff; color: var(--text); min-height: 44px;
    min-width: 0; max-width: 100%;
}
input[type=search] { -webkit-appearance: none; appearance: none; }
textarea { min-height: 88px; resize: vertical; line-height: 1.5; }
input:focus, select:focus, textarea:focus {
    outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(20,158,216,.14);
}
.form-hint { font-size: 12.5px; color: var(--muted); margin-top: 5px; }
.form-error { color: var(--danger); font-size: 13px; margin-top: 5px; }

.alert { padding: 11px 14px; border-radius: 9px; font-size: 14px; margin-bottom: 14px; border-left: 4px solid; }
.alert-error   { background: var(--danger-bg);  border-color: var(--danger);  color: #991b1b; }
.alert-success { background: var(--success-bg); border-color: var(--success); color: #166534; }
.alert-warn    { background: var(--warn-bg);    border-color: var(--warn);    color: #92400e; }
.alert-info    { background: var(--info-bg);    border-color: var(--info);    color: #075985; }

/* ============================================================
   Auth pages
   ============================================================ */
.auth-page {
    /* svh, not vh: on a phone 100vh is the height *without* the browser chrome,
       so the card sits partly under it until you scroll. */
    min-height: 100vh; min-height: 100svh;
    display: flex; align-items: center; justify-content: center;
    background: var(--sidebar-bg);
    padding: max(24px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right))
             max(24px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
}
.auth-card {
    width: 100%; max-width: 380px; background: #fff;
    border-radius: 14px; padding: 30px 26px;
    box-shadow: 0 20px 40px rgba(2, 6, 23, .35);
}
.auth-brand { text-align: center; margin-bottom: 26px; }
.auth-brand img { width: 84px; height: auto; margin-bottom: 10px; }
.auth-brand .title { font-size: 19px; font-weight: 700; }
.auth-brand .tagline {
    font-size: 11px; color: var(--muted); margin-top: 3px;
    text-transform: uppercase; letter-spacing: .7px;
}
.auth-h1 { font-size: 19px; font-weight: 700; text-align: center; margin-bottom: 4px; }
.auth-sub { font-size: 13px; color: var(--muted); text-align: center; margin-bottom: 18px; line-height: 1.55; }
.auth-icon { font-size: 34px; text-align: center; margin-bottom: 8px; }
.auth-alt { text-align: center; font-size: 13px; color: var(--muted); margin-top: 16px; }
.auth-alt a { font-weight: 600; }
.auth-alt .sep { margin: 0 6px; }
/* Honeypot: off-screen rather than display:none — some bots skip hidden fields. */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.muted { color: var(--muted); }
.mono { font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; }
.num {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    text-align: right; font-variant-numeric: tabular-nums;
}
.text-success { color: var(--success); }
.text-danger  { color: var(--danger); }
/* Filled button variants, matching HDProtek Presentation: an action reads as a
   button at a glance instead of as a bare glyph. */
.btn-secondary { background: #e2e8f0; border-color: #e2e8f0; color: var(--text); }
.btn-secondary:hover { background: #cbd5e1; border-color: #cbd5e1; }
.btn-danger { background: var(--danger); border-color: var(--danger); color: #fff; }
.btn-danger:hover { background: #b91c1c; border-color: #b91c1c; }
.btn-sm { min-height: 34px; padding: 6px 12px; font-size: 13px; }
.nowrap { white-space: nowrap; }
.text-right { text-align: right; }
.stack > * + * { margin-top: 10px; }

/* Page-title icon. A screen names itself with the same glyph as its entry in
   the sidebar, so landing on a page confirms which one you opened without
   reading the heading — and on a phone, where the sidebar is not there at all,
   it is the only thing that does. Sized in em so it tracks the heading between
   the phone and desktop sizes. */
.content-header h1 .pi { margin-right: 9px; font-size: .95em; line-height: 1; }

/* Legend under a grid: what the colours in the column above mean. Small, quiet,
   and directly beneath the thing it explains — a key nobody scrolls to is not
   a key. */
.chip-legend {
    display: flex; gap: 14px; flex-wrap: wrap; align-items: center;
    font-size: 12px; color: var(--muted); margin-top: 10px;
}
.chip-legend .badge { font-size: 11px; }

/* Crew picker extras — the position dropdown that rides inside a chip, and the
   "not on the list?" row at the bottom of the panel. Defined here rather than in
   the two event templates that carry the rest of the .ms-* rules, because these
   two are the parts most likely to be got wrong twice. */
.ms-chip .ms-pos {
    width: auto; min-width: 118px; min-height: 28px; padding: 2px 6px;
    font-size: 12px; font-weight: 600; border-radius: 7px;
    border: 1px solid #bae6fd; background: #fff; color: #075985;
    max-width: 100%;
}
.ms-chip:has(.ms-pos) { padding-left: 10px; gap: 8px; }
.ms-add {
    display: flex; gap: 7px; flex-wrap: wrap; align-items: center;
    margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--border);
}
.ms-add .ms-add-name { flex: 1 1 170px; font-size: 14px; min-height: 38px; padding: 7px 10px; }
.ms-add .ms-add-kind { width: auto; min-width: 128px; font-size: 13px; min-height: 38px; padding: 7px 8px; }

/* Crew on an event: one row per person, position first because that is what the
   eye is looking for when it asks "did we have a sound engineer". */
.crew-line {
    display: flex; align-items: center; gap: 10px; padding: 8px 11px;
    border: 1px solid var(--border); border-radius: 9px; color: inherit;
    min-width: 0; max-width: 100%;
}
.crew-line:hover { background: var(--bg); text-decoration: none; }
.crew-pos {
    min-width: 118px; font-size: 11.5px; font-weight: 700; color: var(--muted);
    text-transform: uppercase; letter-spacing: .3px;
}
.crew-name { flex: 1; min-width: 0; font-size: 14px; font-weight: 600; word-break: break-word; }

/* Mobile viewport adjustments to prevent horizontal sliding */
@media (max-width: 600px) {
    .content-header {
        padding: 14px max(14px, env(safe-area-inset-right)) 0 max(14px, env(safe-area-inset-left));
        gap: 10px;
    }
    .content-body {
        padding: 14px max(14px, env(safe-area-inset-right)) 24px max(14px, env(safe-area-inset-left));
    }
    .header-actions {
        width: 100%;
        justify-content: flex-start;
    }
    .header-actions .btn {
        flex: 1 1 auto;
        min-height: 38px;
        padding: 6px 12px;
        font-size: 13px;
    }
    .card {
        padding: 14px 12px;
    }
}

.grid-2 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 14px; }
@media (max-width: 640px) { .grid-2 { grid-template-columns: minmax(0, 1fr); gap: 0; } }

.grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
@media (max-width: 768px) { .grid-3 { grid-template-columns: minmax(0, 1fr); gap: 0; } }
