:root {
  --brand-500: #0b5a99;
  --brand-600: #00447c;
  --brand-50: #e6eff7;
  --green-600: #387c2b;
  --ink-900: #0f2335;
  --ink-700: #33475a;
  --ink-500: #5f7184;
  --ink-300: #c3cdd7;
  --line: #e0e6ed;
  --surface: #ffffff;
  --canvas: #f2f5f8;

  --ok: #387c2b;      --ok-bg: #e7f2e3;
  --due: #b45309;     --due-bg: #fdf1dc;
  --overdue: #c62828; --overdue-bg: #fde8e8;
  --info: #0b5a99;    --info-bg: #e3eef8;
  --muted: #5a6b7c;   --muted-bg: #edf1f5;

  /* surfaces & roles that change between themes */
  --accent-fill: #00447c;        /* filled buttons, counters (white text on it) */
  --accent-fill-hover: #003561;
  --danger-fill: #c62828;
  --danger-fill-hover: #a61f1f;
  --on-fill: #ffffff;
  --header-bg: rgba(255, 255, 255, .92);
  --raised: #ffffff;             /* menus, dialogs, inputs, pressed segments */
  --row-hover: #f8fafc;
  --table-head: #f8fafc;
  --photo-bg: #dde7ef;
  --due-fill: #e08a00;
  --inverse-bg: #0f2335;         /* toast, offline banner, skip link */
  --inverse-fg: #ffffff;
  --footer-bg: #00375f;
  --footer-fg: #cfdbe6;
  --footer-strong: #ffffff;
  --info-border: #c9d9e8;
  --ai-bg: #f5f9fc;
  --ai-border: #b5cade;
  --overlay: rgba(15, 35, 53, .45);
  --shadow-lg: 0 20px 60px rgba(15, 35, 53, .25);
  --shadow-menu: 0 12px 32px rgba(15, 35, 53, .14);
  --shadow-press: 0 1px 3px rgba(15, 35, 53, .12);
  --shadow-lift: 0 2px 4px rgba(16, 67, 104, .06), 0 12px 28px rgba(16, 67, 104, .12);
  --scroll-thumb: rgba(15, 35, 53, .2);        /* scrollbars: thin rounded thumb, no track */
  --scroll-thumb-hover: rgba(15, 35, 53, .38);

  --radius: 14px;
  --radius-sm: 8px;
  --shadow: 0 1px 2px rgba(16, 67, 104, .06), 0 4px 16px rgba(16, 67, 104, .06);
  --header-h: 68px;
  --ease-out: cubic-bezier(.2, .8, .2, 1);
  font-family: Inter, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  color-scheme: light;
}

/* Dark palette: follows the device unless the person picked Light or Dark (data-theme on <html>). */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --brand-500: #7fb3e0;
    --brand-600: #a6cbec;
    --brand-50: #12283b;
    --green-600: #7cc06c;
    --ink-900: #e6edf3;
    --ink-700: #b9c7d4;
    --ink-500: #8a9bab;
    --ink-300: #364656;
    --line: #22303f;
    --surface: #111c28;
    --canvas: #0a121b;
    --ok: #7cc06c;      --ok-bg: #16301a;
    --due: #f2a93b;     --due-bg: #36280f;
    --overdue: #ff7a7a; --overdue-bg: #3d1a1d;
    --info: #7fb3e0;    --info-bg: #12283b;
    --muted: #a1adbf;   --muted-bg: #222d3c;
    --accent-fill: #0b5a99;
    --accent-fill-hover: #1668ab;
    --danger-fill: #c33a3a;
    --danger-fill-hover: #d24b4b;
    --on-fill: #ffffff;
    --header-bg: rgba(17, 28, 40, .9);
    --raised: #172433;
    --row-hover: #142130;
    --table-head: #132030;
    --photo-bg: #172433;
    --due-fill: #f2a93b;
    --inverse-bg: #e6edf3;
    --inverse-fg: #0a121b;
    --footer-bg: #061019;
    --footer-fg: #a3b3c2;
    --footer-strong: #e6edf3;
    --info-border: #234561;
    --ai-bg: #10202f;
    --ai-border: #2a4a66;
    --overlay: rgba(0, 0, 0, .6);
    --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 4px 16px rgba(0, 0, 0, .25);
    --shadow-lg: 0 20px 60px rgba(0, 0, 0, .55);
    --shadow-menu: 0 12px 32px rgba(0, 0, 0, .45);
    --shadow-press: 0 1px 3px rgba(0, 0, 0, .5);
    --shadow-lift: 0 2px 4px rgba(0, 0, 0, .4), 0 12px 28px rgba(0, 0, 0, .4);
    --scroll-thumb: rgba(230, 237, 243, .18);
    --scroll-thumb-hover: rgba(230, 237, 243, .34);
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --brand-500: #7fb3e0;
  --brand-600: #a6cbec;
  --brand-50: #12283b;
  --green-600: #7cc06c;
  --ink-900: #e6edf3;
  --ink-700: #b9c7d4;
  --ink-500: #8a9bab;
  --ink-300: #364656;
  --line: #22303f;
  --surface: #111c28;
  --canvas: #0a121b;
  --ok: #7cc06c;      --ok-bg: #16301a;
  --due: #f2a93b;     --due-bg: #36280f;
  --overdue: #ff7a7a; --overdue-bg: #3d1a1d;
  --info: #7fb3e0;    --info-bg: #12283b;
  --muted: #a1adbf;   --muted-bg: #222d3c;
  --accent-fill: #0b5a99;
  --accent-fill-hover: #1668ab;
  --danger-fill: #c33a3a;
  --danger-fill-hover: #d24b4b;
  --on-fill: #ffffff;
  --header-bg: rgba(17, 28, 40, .9);
  --raised: #172433;
  --row-hover: #142130;
  --table-head: #132030;
  --photo-bg: #172433;
  --due-fill: #f2a93b;
  --inverse-bg: #e6edf3;
  --inverse-fg: #0a121b;
  --footer-bg: #061019;
  --footer-fg: #a3b3c2;
  --footer-strong: #e6edf3;
  --info-border: #234561;
  --ai-bg: #10202f;
  --ai-border: #2a4a66;
  --overlay: rgba(0, 0, 0, .6);
  --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 4px 16px rgba(0, 0, 0, .25);
  --shadow-lg: 0 20px 60px rgba(0, 0, 0, .55);
  --shadow-menu: 0 12px 32px rgba(0, 0, 0, .45);
  --shadow-press: 0 1px 3px rgba(0, 0, 0, .5);
  --shadow-lift: 0 2px 4px rgba(0, 0, 0, .4), 0 12px 28px rgba(0, 0, 0, .4);
  --scroll-thumb: rgba(230, 237, 243, .18);
  --scroll-thumb-hover: rgba(230, 237, 243, .34);
  color-scheme: dark;
}

*, *::before, *::after { box-sizing: border-box; }

/* App-style scrollbars everywhere (page, dialogs, menus, panels, wide tables): a thin rounded thumb on no track, no
   arrow buttons, a little stronger on hover. The thumb is inset by a transparent border so it reads as 6px wide.
   Chromium and Safari use the ::-webkit-scrollbar rules; setting scrollbar-width/-color would make Chromium ignore
   them, so the standard properties are only applied where ::-webkit-scrollbar isn't supported (Firefox). */
::-webkit-scrollbar { width: 10px; height: 10px; background: transparent; }
::-webkit-scrollbar-track, ::-webkit-scrollbar-corner { background: transparent; }
::-webkit-scrollbar-button { display: none; width: 0; height: 0; }
::-webkit-scrollbar-thumb { background: var(--scroll-thumb); background-clip: padding-box; border: 2px solid transparent; border-radius: 999px; min-height: 32px; min-width: 32px; }
::-webkit-scrollbar-thumb:hover { background-color: var(--scroll-thumb-hover); }
::-webkit-scrollbar-thumb:active { background-color: var(--scroll-thumb-hover); }
/* The page scrollbar runs beside the content only: its track starts below the sticky header (and the staging strip),
   and the gutter beside the header is painted to match it so the header reads full width. */
html { --page-top: calc(env(safe-area-inset-top, 0px) + var(--env-banner-h, 0px) + var(--header-h) + 1px); }
body::-webkit-scrollbar { background: linear-gradient(to bottom, var(--due-bg) calc(env(safe-area-inset-top, 0px) + var(--env-banner-h, 0px)),
  var(--surface) 0 calc(var(--page-top) - 1px), var(--line) 0 var(--page-top), transparent 0); }
body::-webkit-scrollbar-track:vertical { margin-top: var(--page-top); }
@supports not selector(::-webkit-scrollbar) {
  html { scrollbar-color: var(--scroll-thumb) transparent; }
  * { scrollbar-width: thin; }
}
html { height: 100%; scroll-behavior: smooth; scroll-padding-top: calc(var(--header-h) + var(--env-banner-h, 0px) + 16px); }
/* Header, content, footer as one column that fills the window: short pages fit without scrolling and the footer sits at the bottom. */
body { margin: 0; min-height: 100%; display: flex; flex-direction: column; padding-bottom: env(safe-area-inset-bottom); background: var(--canvas); color: var(--ink-900); font-size: 15px; line-height: 1.5; -webkit-font-smoothing: antialiased; -webkit-tap-highlight-color: transparent; }
h1, h2, p { margin: 0; }
a { color: var(--brand-500); }
/* Text links: light dashed underline that firms up on hover. */
a { text-decoration-line: underline; text-decoration-style: dashed; text-decoration-thickness: 1px; text-underline-offset: 3px; text-decoration-color: color-mix(in srgb, currentColor 45%, transparent); transition: text-decoration-color .15s; }
a:hover { text-decoration-color: currentColor; }
img { max-width: 100%; display: block; }
[hidden] { display: none !important; }

.container { width: 100%; max-width: 1200px; margin: 0 auto; padding: 0 16px; }
@media (min-width: 720px) { .container { padding: 0 24px; } }

.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.skip-link { position: absolute; left: 16px; top: -48px; background: var(--inverse-bg); color: var(--inverse-fg); padding: 8px 12px; border-radius: var(--radius-sm); z-index: 100; }
.skip-link:focus { top: 12px; }
:focus-visible { outline: 3px solid color-mix(in srgb, var(--brand-500) 55%, transparent); outline-offset: 2px; }
.mono { font-variant-numeric: tabular-nums; letter-spacing: .02em; }

/* ---------- header ---------- */
.site-header { position: sticky; top: env(safe-area-inset-top, 0px); z-index: 20; background: var(--header-bg); backdrop-filter: saturate(1.4) blur(10px); border-bottom: 1px solid var(--line); }
/* Non-production deployments (TITLE_TAG): a thin strip pinned above the header on every screen. */
.env-banner { padding: 3px 16px; text-align: center; font-size: 12px; font-weight: 600; letter-spacing: .04em; line-height: 16px;
  color: var(--due); background: var(--due-bg); border-bottom: 1px solid color-mix(in srgb, var(--due) 25%, transparent); }
:root:has(.env-banner:not([hidden])) { --env-banner-h: 23px; }
.header-inner { display: flex; align-items: center; justify-content: space-between; height: var(--header-h); gap: 24px; }
.brand { flex: none; display: flex; align-items: center; gap: 10px; color: var(--ink-900); text-decoration: none; }
.brand-mark { width: 44px; height: 44px; border-radius: 50%; }
.brand-text { font-size: 17px; letter-spacing: -.01em; }
.brand-text strong { font-weight: 700; }

.primary-nav { display: flex; align-items: center; gap: 4px; }
.primary-nav > a { color: var(--ink-700); text-decoration: none; font-weight: 500; padding: 8px 12px; border-radius: var(--radius-sm); }
.primary-nav > a:hover { background: var(--canvas); color: var(--ink-900); }
.primary-nav > a[aria-current="page"] { color: var(--brand-600); background: var(--brand-50); }
.header-app { display: flex; align-items: center; gap: 12px; flex: 1; justify-content: flex-end; min-width: 0; }
.aircraft-picker .dd-trigger { font-size: 14px; font-weight: 600; border-color: var(--line); padding: 7px 10px 7px 12px; max-width: 260px; }
.account { position: relative; margin-left: 12px; padding-left: 16px; border-left: 1px solid var(--line); }
.account-btn { display: flex; align-items: center; gap: 8px; font: inherit; background: none; border: 0; padding: 4px 6px; border-radius: var(--radius-sm); cursor: pointer; color: var(--ink-900); }
.account-btn:hover { background: var(--canvas); }
.account-name { font-weight: 500; font-size: 14px; }
.chev { width: 16px; height: 16px; fill: none; stroke: var(--ink-500); stroke-width: 2; }
.menu { position: absolute; right: 0; top: calc(100% + 8px); min-width: 230px; background: var(--raised); border: 1px solid var(--line); border-radius: 12px; box-shadow: var(--shadow-menu); padding: 6px; z-index: 30; }
.menu button { display: block; width: 100%; text-align: left; font: inherit; font-size: 14px; background: none; border: 0; padding: 10px 12px; border-radius: 8px; cursor: pointer; color: var(--ink-900); }
.menu button:hover, .menu button:focus-visible { background: var(--canvas); }


/* Phones and small tablets: pages move to the bottom tab bar; the header keeps the aircraft picker and account menu. */
@media (max-width: 860px) {
  .brand-text, .primary-nav > a, .account-name, .chev { display: none; }
  .account { margin-left: 0; padding-left: 0; border-left: 0; }
  .aircraft-picker .dd-trigger { max-width: 52vw; }
}

/* ---------- buttons, badges ---------- */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; font: inherit; font-weight: 600; font-size: 14px; border-radius: var(--radius-sm); border: 1px solid transparent; padding: 9px 16px; cursor: pointer; text-decoration: none; white-space: nowrap; transition: background .15s, border-color .15s, color .15s, transform .12s var(--ease-out); }
.btn-sm { padding: 6px 12px; font-size: 13px; }
.btn-primary { background: var(--accent-fill); color: var(--on-fill); }
.btn-primary:hover { background: var(--accent-fill-hover); }
.btn-secondary { background: var(--raised); color: var(--ink-900); border-color: var(--ink-300); }
.btn-secondary:hover { border-color: var(--ink-500); }
.btn-ghost { background: transparent; color: var(--ink-700); border-color: var(--line); }
.btn-ghost:hover { background: var(--canvas); }
.btn-danger { background: var(--danger-fill); color: var(--on-fill); }
.btn-danger:hover { background: var(--danger-fill-hover); }

.badge { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; padding: 3px 10px; border-radius: 999px; white-space: nowrap; }
.badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.badge-ok { color: var(--ok); background: var(--ok-bg); }
.badge-due { color: var(--due); background: var(--due-bg); }
.badge-overdue { color: var(--overdue); background: var(--overdue-bg); }
.badge-info { color: var(--info); background: var(--info-bg); }
.badge-muted { color: var(--muted); background: var(--muted-bg); }

.icon-btn { display: inline-grid; place-items: center; width: 34px; height: 34px; border-radius: var(--radius-sm); color: var(--ink-500); background: none; border: 0; cursor: pointer; font-size: 22px; line-height: 1; transition: background .15s, color .15s, transform .12s var(--ease-out); }
.icon-btn:hover { background: var(--canvas); color: var(--ink-900); }
.icon-btn svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

.avatar { display: inline-grid; place-items: center; width: 32px; height: 32px; border-radius: 50%; background: var(--brand-50); color: var(--brand-600); font-size: 12px; font-weight: 700; flex: none; }
.avatar-lg { width: 40px; height: 40px; font-size: 14px; }

/* ---------- layout & cards ---------- */
main { flex: 1 0 auto; display: grid; gap: 20px; align-content: start; }
/* .container sets the side gutters; the space under the header is set here, the same on every page. */
main.container { padding-top: 32px; padding-bottom: 48px; }
.card { background: var(--surface); border-radius: var(--radius); box-shadow: var(--shadow); border: 1px solid var(--line); }

/* aircraft summary */
.aircraft { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); overflow: hidden; }
.aircraft-photo { position: relative; background: var(--photo-bg); min-height: 240px; }
.aircraft-photo img { width: 100%; height: 100%; object-fit: cover; }
.photo-badge { position: absolute; top: 14px; left: 14px; box-shadow: var(--shadow); }
.aircraft-body { padding: 24px 28px; display: grid; gap: 20px; align-content: start; }
.aircraft-head { display: flex; justify-content: space-between; align-items: center; gap: 16px; flex-wrap: wrap; }
.aircraft-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.eyebrow { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-500); }
h1 { font-size: 26px; font-weight: 700; letter-spacing: -.02em; line-height: 1.2; margin-top: 2px; }
.specs { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 14px 24px; margin: 0; }
.specs dt { font-size: 12px; color: var(--ink-500); }
.specs dd { margin: 2px 0 0; font-weight: 600; overflow-wrap: anywhere; }

.kpis { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.kpi { display: grid; gap: 2px; padding: 12px 14px; border-radius: var(--radius-sm); border: 1px solid var(--line); text-decoration: none; color: inherit; border-left-width: 4px; height: 100%; transition: background .15s, transform .2s var(--ease-out), box-shadow .2s var(--ease-out); }
.kpi:hover { background: var(--canvas); }
.kpi-label { font-size: 12px; color: var(--ink-500); font-weight: 500; }
.kpi-value { font-size: 18px; font-weight: 700; letter-spacing: -.01em; }
.kpi-note { font-size: 12px; color: var(--ink-500); }
.kpi-ok { border-left-color: var(--ok); }
.kpi-warn { border-left-color: var(--due); }
.kpi-danger { border-left-color: var(--overdue); }
.kpi-danger .kpi-value { color: var(--overdue); }
.kpi-neutral { border-left-color: var(--brand-500); }

@media (max-width: 900px) {
  .aircraft { grid-template-columns: 1fr; }
  .aircraft-photo { min-height: 0; aspect-ratio: 16 / 8; }
}
@media (max-width: 560px) {
  .aircraft-body { padding: 20px 16px; }
  .kpis { gap: 8px; }
  .kpi { padding: 10px; border-left-width: 3px; }
  .kpi-value { font-size: 15px; }
  .kpi-note { display: none; }
  .aircraft-actions, .aircraft-actions .btn { width: 100%; }
  .aircraft-actions .btn { flex: 1; }
}

/* section nav */

/* panels */
.panel { padding: 22px 0 8px; min-width: 0; }
.panel-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; padding: 0 24px 16px; flex-wrap: wrap; }
.panel-head h2 { font-size: 18px; font-weight: 700; letter-spacing: -.01em; }
.panel-sub { color: var(--ink-500); font-size: 14px; margin-top: 2px; }
.panel-sub strong { color: var(--ink-900); }
.panel-foot { display: flex; justify-content: center; padding: 12px 24px 16px; }
.empty { padding: 24px; text-align: center; color: var(--ink-500); }

.segmented { display: inline-flex; padding: 3px; background: var(--canvas); border-radius: 10px; border: 1px solid var(--line); }
.segmented button { font: inherit; font-size: 13px; font-weight: 500; border: 0; background: none; padding: 6px 12px; border-radius: 7px; cursor: pointer; color: var(--ink-700); }
.segmented button[aria-pressed="true"] { background: var(--raised); color: var(--ink-900); box-shadow: var(--shadow-press); }

.split { display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px; }

/* ---------- tables ---------- */
/* position: relative keeps screen-reader-only labels inside the scroller, so a wide table never widens the page. */
.table-wrap { overflow-x: auto; position: relative; }
.table { width: 100%; border-collapse: collapse; font-size: 14px; }
.table th, .table td { text-align: left; padding: 12px 12px; border-top: 1px solid var(--line); vertical-align: middle; }
.table th:first-child, .table td:first-child { padding-left: 24px; }
.table th:last-child, .table td:last-child { padding-right: 24px; }
.table thead th { border-top: 0; font-size: 12px; font-weight: 600; color: var(--ink-500); text-transform: uppercase; letter-spacing: .04em; padding-top: 8px; padding-bottom: 8px; background: var(--table-head); }
/* Long labels wrap to a second line only when the table would otherwise be wider than its card. */
.table thead .sort { display: inline; text-align: inherit; }
.table thead .sort::after { margin-left: 4px; white-space: nowrap; }
.table tbody th { font-weight: 600; }
.table tbody tr:hover { background: var(--row-hover); }
.table .num { text-align: right; font-variant-numeric: tabular-nums; }
.sort { font: inherit; color: inherit; text-transform: inherit; letter-spacing: inherit; background: none; border: 0; padding: 0; cursor: pointer; display: inline-flex; align-items: center; gap: 4px; }
.sort::after { content: "↕"; font-size: 11px; opacity: .45; }
th[aria-sort="ascending"] .sort::after { content: "↑"; opacity: 1; }
th[aria-sort="descending"] .sort::after { content: "↓"; opacity: 1; }
.sort:hover { color: var(--ink-900); }
.row-actions { text-align: right; white-space: nowrap; }

.remaining { display: block; font-weight: 600; white-space: nowrap; }
.interval { display: block; font-size: 12px; color: var(--ink-500); }
.row-overdue .remaining { color: var(--overdue); }
.row-due .remaining { color: var(--due); }

.col-status { min-width: 180px; }
.meter-row { display: flex; align-items: center; gap: 10px; }
.meter { flex: 1; max-width: 140px; height: 8px; border-radius: 999px; background: var(--muted-bg); overflow: hidden; }
.meter span { display: block; height: 100%; border-radius: inherit; }
.meter-ok span { background: var(--ok); }
.meter-due span { background: var(--due-fill); }
.meter-overdue span { background: var(--overdue); }
.meter-pct { font-size: 12px; color: var(--ink-500); width: 36px; font-variant-numeric: tabular-nums; }

.message { max-width: 320px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-700); }
.invoice-link { display: inline-flex; align-items: center; gap: 6px; text-decoration: none; font-weight: 600; }
.invoice-link svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.invoice-link:hover span { text-decoration: underline; }
.amount { font-weight: 600; }
.paid-note { font-size: 13px; color: var(--ink-500); }

/* stacked-card tables on small screens */
@media (max-width: 720px) {
  .table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .table, .table tbody, .table tr, .table th, .table td { display: block; }
  .table tbody tr { border-top: 1px solid var(--line); padding: 14px 16px; display: grid; grid-template-columns: 1fr 1fr; gap: 10px 16px; }
  .table tbody tr:hover { background: none; }
  .table th, .table td, .table th:first-child, .table td:first-child, .table th:last-child, .table td:last-child { border: 0; padding: 0; text-align: left; }
  .table tbody th { grid-column: 1 / -1; font-size: 15px; }
  .table .num { text-align: left; }  /* stacked cards: every label/value pair aligns the same way */
  .table td[data-label]::before { content: attr(data-label); display: block; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-500); margin-bottom: 2px; }
  .table .col-status, .table .message, .table .row-actions { grid-column: 1 / -1; }
  .col-status { min-width: 0; }
  .meter { max-width: none; }
  .message { max-width: none; white-space: normal; }
  .row-actions { text-align: left; display: flex; gap: 4px; }
  .row-actions { flex-wrap: wrap; }
  .row-actions .btn { flex: 1 1 140px; }
  .panel { padding-top: 16px; }
  .panel-head { padding: 0 16px 16px; }
}
/* narrow phones: two columns get cramped, so card details stack in one */
@media (max-width: 380px) {
  .table tbody tr { grid-template-columns: 1fr; }
}

/* ---------- people ---------- */
.people { list-style: none; margin: 0; padding: 0; }
.people li { display: flex; align-items: center; gap: 12px; padding: 14px 24px; border-top: 1px solid var(--line); flex-wrap: wrap; }
.person { display: grid; flex: 1; min-width: 160px; }
.person span { font-size: 13px; color: var(--ink-500); }
.person-email { font-size: 14px; overflow-wrap: anywhere; }

/* ---------- history timeline ---------- */
.timeline { list-style: none; margin: 0; padding: 4px 24px 0 24px; }
.timeline li { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 12px; align-content: start; padding: 0 0 18px 22px; border-left: 2px solid var(--line); margin-left: 5px; }
.timeline li:last-child { border-left-color: transparent; padding-bottom: 14px; }
.timeline li::before { content: ""; position: absolute; left: -7px; top: 3px; width: 12px; height: 12px; border-radius: 50%; background: var(--surface); border: 3px solid var(--brand-500); }
.timeline li.tl-invoice::before { border-color: var(--green-600); }
.timeline li.tl-request::before { border-color: var(--due-fill); }
.timeline li > :not(.tl-when) { grid-column: 1; }
.timeline li > .tl-type { grid-column: 1 / -1; }
/* Level with the item's title and byline, not its category label. */
.tl-when { grid-column: 2; grid-row: 2 / span 2; align-self: center; display: grid; justify-items: end; align-content: center; font-size: 12px; color: var(--ink-500); line-height: 1.4; text-align: right; white-space: nowrap; }
.tl-type { font-size: 12px; color: var(--ink-500); line-height: 1.4; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
.timeline p { font-weight: 600; margin: 2px 0; }
.tl-by { font-size: 13px; color: var(--ink-500); }
@media (max-width: 720px) { .people li { padding: 14px 16px; } .timeline { padding: 4px 16px 0; } }

/* ---------- footer ---------- */
.site-footer { flex-shrink: 0; background: var(--footer-bg); color: var(--footer-fg); }
.footer-inner { display: flex; flex-wrap: wrap; gap: 8px 32px; justify-content: center; padding-top: 32px; padding-bottom: 32px; font-size: 14px; }
.site-footer strong { color: var(--footer-strong); letter-spacing: .04em; text-transform: uppercase; }
.site-footer address { font-style: normal; }
.site-footer a { color: var(--footer-strong); }
/* Phones: stack name, address and phone, centered, so nothing gets clipped. */
@media (max-width: 560px) { .footer-inner { flex-direction: column; align-items: center; gap: 6px; text-align: center; } }

/* ---------- dialogs & toast ---------- */
.dialog { border: 0; border-radius: var(--radius); padding: 0; width: min(520px, calc(100vw - 32px)); box-shadow: var(--shadow-lg); background: var(--surface); color: var(--ink-900); }
.dialog-sm { width: min(380px, calc(100vw - 32px)); }
.dialog::backdrop { background: var(--overlay); }
.dialog form { padding: 20px 24px 24px; display: grid; gap: 16px; }
.dialog-head { display: flex; justify-content: space-between; align-items: center; }
.dialog-head h2 { font-size: 18px; }
.dialog-foot { display: flex; justify-content: flex-end; gap: 8px; margin-top: 4px; }
.field { display: grid; gap: 6px; font-size: 14px; font-weight: 500; }
.field em { font-style: normal; color: var(--ink-500); font-weight: 400; }
.field input, .field textarea { font: inherit; font-weight: 400; padding: 9px 12px; border: 1px solid var(--ink-300); border-radius: var(--radius-sm); width: 100%; background: var(--raised); color: var(--ink-900); }
.field input:focus, .field textarea:focus { border-color: var(--brand-500); outline: 3px solid var(--brand-50); }
/* Password managers and browser autofill shouldn't tint fields: the inset shadow paints over the UA's
   (often !important) autofill background, and the text keeps our ink color in both themes. */
input:not([type="checkbox"]):not([type="radio"]):autofill,
textarea:autofill { box-shadow: inset 0 0 0 1000px var(--raised); -webkit-text-fill-color: var(--ink-900); caret-color: var(--ink-900); }
input:not([type="checkbox"]):not([type="radio"]):-webkit-autofill,
textarea:-webkit-autofill { box-shadow: inset 0 0 0 1000px var(--raised); -webkit-text-fill-color: var(--ink-900); caret-color: var(--ink-900); }

.toast { position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%); background: var(--inverse-bg); color: var(--inverse-fg); padding: 12px 18px; border-radius: 10px; box-shadow: var(--shadow); font-size: 14px; z-index: 50; max-width: calc(100vw - 32px); }

@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } * { transition: none !important; } }

/* ---------- app additions ---------- */
body:not(.is-staff) .staff-only { display: none !important; }
body.no-add-aircraft [data-action="add-aircraft"] { display: none !important; }
.muted { color: var(--ink-500); }
.btn-block { width: 100%; }
.btn-left { margin-right: auto; }
.btn[disabled] { opacity: .6; cursor: progress; }
.link-btn { font: inherit; color: var(--brand-500); background: none; border: 0; padding: 0; cursor: pointer; text-align: left; }
.link-btn:hover { text-decoration: underline; }
.row-link { color: var(--ink-900); font-weight: 600; }
.icon-btn { position: relative; }
.icon-btn .count { position: absolute; top: 2px; right: 0; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 999px; background: var(--accent-fill); color: var(--on-fill); font-size: 10px; font-weight: 700; line-height: 16px; }
.alert { margin: 0; padding: 10px 12px; border-radius: var(--radius-sm); background: var(--overdue-bg); color: var(--overdue); font-size: 14px; white-space: pre-line; }
.spec-edit { align-self: end; }
.panel-tools { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.photo-upload { position: absolute; right: 14px; bottom: 14px; }
.app-main[hidden], #aircraft-view[hidden] { display: none; }
#aircraft-view { display: grid; gap: 20px; }

/* banners */
.banner { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 16px; border-radius: var(--radius); font-size: 14px; flex-wrap: wrap; }
.banner-actions { display: flex; align-items: center; gap: 4px; }
.banner-install, .banner-push { background: var(--brand-50); border: 1px solid var(--info-border); color: var(--ink-900); }
/* Lives inside the sticky header, so the two stay together instead of covering each other. */
.banner-offline { border-radius: 0; justify-content: center; background: var(--inverse-bg); color: var(--inverse-fg); padding: 8px 16px; }

/* login */
.login { display: grid; place-items: center; align-content: center; padding: 32px 16px; }
.login-card { width: 100%; max-width: 420px; padding: 32px 28px; display: grid; gap: 16px; text-align: center; }
.login-card img { margin: 0 auto; }
.login-card h1 { font-size: 22px; }
.login-card .stack { text-align: left; }
.login-install { width: 100%; max-width: 420px; margin-top: 16px; padding: 16px 20px; display: flex; align-items: center; gap: 14px; text-align: left; }
.login-install img { flex: none; border-radius: 11px; box-shadow: 0 1px 3px rgb(0 0 0 / 0.15); }
.login-install-text { flex: 1; min-width: 0; }
.login-install h2 { font-size: 16px; margin: 0; }
.login-install p { font-size: 13px; margin: 2px 0 0; }
.login-install .btn { flex: none; }
.stack { display: grid; gap: 14px; }
.fine { font-size: 13px; color: var(--ink-500); margin: 4px 0 0; }
.empty-state { padding: 40px 24px; text-align: center; display: grid; gap: 12px; justify-items: center; }
.empty-state h1 { font-size: 22px; }

/* dialog content */
.dialog-wide { width: min(640px, calc(100vw - 32px)); }
.dialog form { max-height: calc(100vh - 48px); max-height: calc(100dvh - 48px); overflow: auto; }
.dialog-body { display: grid; gap: 14px; }
.dialog-intro { margin: 0; }
.dialog-section { font-size: 13px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-500); margin: 6px 0 0; }
.field small { font-weight: 400; color: var(--ink-500); font-size: 12px; }
.field .dd { width: 100%; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; align-items: start; }
@media (max-width: 480px) { .field-row { grid-template-columns: 1fr; } }
/* first line is box-height; the 1px drop centers the box on the text's optical middle (between cap and x-height) */
.check { display: flex; gap: 12px; align-items: flex-start; font-size: 14px; line-height: 22px; cursor: pointer; }
.check input {
  appearance: none; -webkit-appearance: none; flex: none; width: 22px; height: 22px; margin: 1px 0 0; border-radius: 6px; cursor: pointer;
  border: 1.5px solid var(--ink-300); background: var(--raised) center / 13px 13px no-repeat; transition: background-color .15s, border-color .15s;
}
.check input:hover { border-color: var(--ink-500); }
/* white check, drawn smaller than the box so it has room around it */
.check input:checked {
  border-color: var(--accent-fill); background-color: var(--accent-fill);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 8.5l3 3 6-7'/%3E%3C/svg%3E");
}
.check input:focus-visible { outline: 3px solid color-mix(in srgb, var(--brand-500) 55%, transparent); outline-offset: 2px; }
/* radio buttons share the checkbox look, round, with a dot that grows in when picked */
.check input[type="radio"] {
  border-radius: 50%; background: var(--accent-fill); box-shadow: inset 0 0 0 11px var(--raised);
  transition: border-color .15s, box-shadow .2s var(--ease-out), transform .12s var(--ease-out);
}
.check input[type="radio"]:checked { border-color: var(--accent-fill); background-image: none; box-shadow: inset 0 0 0 4.5px var(--raised); }
.check input:active { transform: scale(.88); transition-duration: .06s; }
@media (prefers-reduced-motion: reduce) { .check input:active { transform: none; } }
.check small { display: block; color: var(--ink-500); line-height: 1.45; margin-top: 1px; }
/* Staff Role dropdown under the "North Star staff" checkbox, lined up with its label; slides in when checked. */
.staff-role-field { margin: -4px 0 4px 34px; max-width: 340px; animation: field-in .2s ease-out; }
@keyframes field-in { from { opacity: 0; transform: translateY(-6px); } }
@media (prefers-reduced-motion: reduce) { .staff-role-field { animation: none; } }
.btn-row { display: flex; gap: 8px; flex-wrap: wrap; }
.device-on { margin: 0; align-self: center; line-height: 1.2; color: var(--ok); font-weight: 600; font-size: 14px; }
.version-ok { margin-left: 8px; white-space: nowrap; }
.install-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 12px; border: 1px solid var(--line); border-radius: var(--radius-sm); font-size: 14px; }
.steps { margin: 0; padding-left: 20px; display: grid; gap: 8px; }
.detail-meta { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; margin: 0; padding: 12px 14px; background: var(--canvas); border-radius: var(--radius-sm); }
.detail-meta dt { font-size: 12px; color: var(--ink-500); }
.detail-meta dd { margin: 2px 0 0; font-weight: 600; font-size: 14px; }
.detail-message { margin: 0; white-space: pre-wrap; line-height: 1.6; }
.attachments { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.attachments li, .attachments a { display: flex; align-items: center; gap: 10px; font-size: 14px; }
.attachments img { width: 56px; height: 56px; object-fit: cover; border-radius: 6px; border: 1px solid var(--line); }
.attachments svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; flex: none; }
.attachments small { color: var(--ink-500); margin-left: 4px; }
.ai-box { padding: 12px 14px; border-radius: var(--radius-sm); border: 1px dashed var(--ai-border); background: var(--ai-bg); display: grid; gap: 6px; font-size: 14px; }
.ai-box p { margin: 0; }
.ai-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--brand-600); }
.toast { bottom: calc(24px + env(safe-area-inset-bottom)); }
.theme-picker { justify-self: start; }

/* ---------- pages ---------- */
/* Title on the left, the page's Add button at the top right, level with the title (phones too).
   The title never wraps: when the two don't fit side by side, the button shrinks instead (see data-fit below). */
.page-head { display: flex; flex-wrap: wrap; align-items: center; column-gap: 16px; padding: 0 2px; }
.page-head > div:first-child { display: contents; }
.page-head .eyebrow, .page-head .panel-sub { flex-basis: 100%; }
.page-head h1 { font-size: 28px; line-height: 1.15; letter-spacing: -.02em; text-wrap: balance; margin-top: 4px; flex: 1 0 min-content; order: 1; }
.page-head .panel-sub { margin-top: 6px; order: 3; }
/* negative margins keep the taller button from pushing the title away from its eyebrow */
.page-actions { order: 2; display: flex; gap: 8px; margin-block: -10px; }
.page-head:has(.page-actions) h1 { white-space: nowrap; flex-basis: auto; }
/* Add buttons shrink in steps when space runs out (fitPageHeads sets data-fit):
   1 drops the qualifier ("Add Request"), 2 leaves "Add", 3 is a "+" icon button. */
.btn-plus { display: none; width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; }
.page-head:is([data-fit="1"], [data-fit="2"]) .btn-extra, .page-head[data-fit="2"] .btn-target { display: none; }
.page-head[data-fit="3"] .btn-text { display: none; }
.page-head[data-fit="3"] .btn-plus { display: block; }
.page-head[data-fit="3"] .page-actions .btn { width: 44px; height: 44px; padding: 0; border-radius: 10px; }
.page-head.is-stacked .page-actions { margin-block: 8px 0; }
@media (max-width: 420px) {
  .page-head { column-gap: 10px; }
  .page-actions .btn { padding-left: 12px; padding-right: 12px; }
}
.page-actions:empty { display: none; }
[data-route="overview"] .full-only, body:not([data-route="overview"]) .compact-only { display: none !important; }
/* tools that only hold overview links leave no empty row (and extra space) under the intro on list pages */
body:not([data-route="overview"]) .panel-tools:not(:has(> :not(.compact-only))) { display: none; }
[data-route="maintenance"] #maintenance-title, [data-route="requests"] #requests-title, [data-route="invoices"] #invoices-title { display: none; }
[data-route="overview"] .table .sort { pointer-events: none; }
[data-route="overview"] .table .sort::after { display: none; }
.view-all { font-size: 14px; font-weight: 600; text-decoration: none; padding: 6px 2px; white-space: nowrap; }
.view-all::after { content: " →"; }
.view-all:hover { text-decoration: underline; }
.primary-nav > a[aria-current="page"] { color: var(--brand-600); background: var(--brand-50); }

/* contact */
.contact-page { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 20px; align-items: start; }
.contact-page .contact-card:last-child { grid-column: 1 / -1; }
.contact-list { margin: 0; padding: 0 24px 16px; display: grid; gap: 18px; }
.contact-list dt { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-500); }
.contact-list dd { margin: 4px 0 0; display: flex; flex-wrap: wrap; gap: 4px 14px; align-items: baseline; }
.contact-list address { font-style: normal; flex-basis: 100%; }
.contact-big { font-size: 24px; font-weight: 700; letter-spacing: -.01em; text-decoration: none; color: var(--ink-900); font-variant-numeric: tabular-nums; user-select: all; }
.contact-cta { padding: 0 24px 20px; }
@media (max-width: 720px) {
  .contact-page { grid-template-columns: 1fr; }
  .contact-list, .contact-cta { padding-left: 16px; padding-right: 16px; }
  .page-head h1 { font-size: 24px; }
}

/* bottom tab bar (phones) */
.tabbar { display: none; }
@media (max-width: 860px) {
  .tabbar:not([hidden]) {
    display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
    background: var(--header-bg); backdrop-filter: saturate(1.4) blur(10px); border-top: 1px solid var(--line);
    padding: 6px 4px calc(6px + env(safe-area-inset-bottom, 0px));
  }
  .tabbar a { display: grid; justify-items: center; gap: 2px; padding: 4px 0; font-size: 11px; font-weight: 500; color: var(--ink-500); text-decoration: none; border-radius: var(--radius-sm); }
  .tabbar svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
  .tabbar a[aria-current="page"] { color: var(--brand-600); }
  .tabbar a[aria-current="page"] svg { stroke-width: 2.2; }
  /* labels never run into each other: a little smaller on narrow phones, icons only when there's no room at all */
  .tabbar a span { max-width: 100%; padding: 0 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  body:has(.tabbar:not([hidden])) { padding-bottom: calc(68px + env(safe-area-inset-bottom, 0px)); }
  body:has(.tabbar:not([hidden])) .toast { bottom: calc(80px + env(safe-area-inset-bottom, 0px)); }
}
@media (max-width: 359px) {
  /* tabs size to their labels here, so the long one ("Maintenance") gets the room it needs */
  .tabbar:not([hidden]) { display: flex; justify-content: space-between; padding-inline: 4px; }
  .tabbar a { flex: 1 1 auto; }
  .tabbar a span { font-size: 10px; padding: 0 1px; overflow: visible; }
}
@media (max-width: 299px) {
  .tabbar a { padding: 10px 0; }
  .tabbar a span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .tabbar svg { width: 24px; height: 24px; }
}
.primary-nav > a, .account-name { white-space: nowrap; }
@media (max-width: 1240px) {
  .primary-nav > a { padding: 8px 9px; }
  .account-name { display: none; }
  .account { margin-left: 6px; padding-left: 10px; }
}
@media (max-width: 1040px) { .brand-text { display: none; } }

/* ---------- dashboard ---------- */
.dashboard { display: grid; gap: 20px; }
.dashboard[hidden] { display: none; }
.dash-kpis { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.dash-kpis .kpi { background: var(--surface); }
.dash-grid { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); gap: 20px; align-items: start; }
.section-title { font-size: 18px; font-weight: 700; letter-spacing: -.01em; margin: 4px 2px 12px; }
.text-overdue { color: var(--overdue); }
.menu a { display: block; font-size: 14px; padding: 10px 12px; border-radius: 8px; color: var(--ink-900); text-decoration: none; }
.menu a:hover, .menu a:focus-visible { background: var(--canvas); }

.attention { list-style: none; margin: 0; padding: 0; }
.attention-item { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "kind badge" "title badge" "detail badge"; align-items: center; column-gap: 12px;
  width: 100%; text-align: left; font: inherit; color: inherit; background: none; border: 0; border-top: 1px solid var(--line); padding: 12px 24px 12px 21px; cursor: pointer; border-left: 3px solid transparent; }
.attention-item:hover { background: var(--row-hover); }
.attention-item.tone-overdue { border-left-color: var(--overdue); }
.attention-item.tone-due { border-left-color: var(--due-fill); }
.attention-item.tone-info { border-left-color: var(--brand-500); }
.attention-kind { grid-area: kind; font-size: 12px; color: var(--ink-500); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
.attention-item strong { grid-area: title; font-weight: 600; }
.attention-detail { grid-area: detail; font-size: 13px; color: var(--ink-500); }
.attention-item .badge { grid-area: badge; }
.attention-empty { display: flex; align-items: center; gap: 10px; padding: 18px 24px 22px; border-top: 1px solid var(--line); color: var(--ok); font-weight: 600; }
.attention-empty svg, .can-list svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; flex: none; }

.account-card { display: grid; gap: 16px; padding: 0 24px 22px; }
.account-id { display: flex; align-items: center; gap: 12px; }
.account-id .person span { overflow-wrap: anywhere; }
.access { margin: 0; display: grid; gap: 14px; }
.access dt { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-500); }
.access dd { margin: 4px 0 0; font-size: 14px; }
.can-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.can-list li { display: flex; gap: 8px; align-items: flex-start; }
.can-list svg { color: var(--ok); margin-top: 1px; }

.fleet { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 16px; }
.fleet-card { display: grid; grid-template-columns: minmax(0, 1fr); align-content: start; width: 100%; height: 100%; text-align: left; font: inherit; color: inherit; cursor: pointer; padding: 0; overflow: hidden;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); transition: transform .2s var(--ease-out), box-shadow .2s var(--ease-out); }
.fleet-card img { width: 100%; aspect-ratio: 16 / 7; object-fit: cover; background: var(--photo-bg); }
.fleet-body { display: grid; gap: 8px; padding: 14px 16px; align-content: start; min-width: 0; }
.fleet-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-start; gap: 6px 8px; }
/* when the name and role tag can't share a line, the tag drops under the name instead of running off the card */
.fleet-head strong { font-size: 16px; flex: 1 1 140px; }
.fleet-head .tag { flex: none; }
.fleet-stats { display: grid; gap: 6px; font-size: 14px; }
/* each value starts on its label's line; anything under it stacks below */
.fleet-stats > span { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; min-height: 26px; }
.fleet-stats > span > :last-child { text-align: right; font-variant-numeric: tabular-nums; }
.fleet-label { flex: none; }
.fleet-value { display: grid; justify-items: end; min-width: 0; }
.fleet-value > span { font-size: 13px; color: var(--ink-500); }
.fleet-value > span.text-overdue { color: var(--overdue); }
.fleet-label { color: var(--ink-700); }
/* narrow cards: every label sits above its value, and a badge gets its own line under that (like the stacked table cards) */
.fleet-body { container-type: inline-size; }
@container (max-width: 230px) {
  .fleet-stats { gap: 12px; }
  .fleet-stats > span { flex-direction: column; align-items: flex-start; gap: 2px; min-height: 0; }
  .fleet-stats > span > :last-child { text-align: left; }
  .fleet-stats .fleet-label { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-500); }
  .fleet-value { justify-items: start; }
}

@media (max-width: 900px) {
  .dash-grid { grid-template-columns: 1fr; }
  .dash-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 720px) {
  .attention-item { padding-left: 13px; padding-right: 16px; }
  .account-card { padding: 0 16px 18px; }
  .attention-empty { padding: 16px; }
  .fleet { grid-template-columns: 1fr; }
}
@media (max-width: 560px) { .dash-kpis .kpi-note { display: block; } }

/* role tags are labels, not statuses: no status dot */
.tag { display: inline-flex; align-items: center; font-size: 12px; font-weight: 600; padding: 2px 8px; border-radius: 6px; background: var(--brand-50); color: var(--brand-600); white-space: nowrap; }
.access-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.access-list li { display: flex; justify-content: space-between; gap: 8px; align-items: center; }

/* empty states look the same in every list */
.timeline li.empty, .people li.empty { display: block; border: 0; margin: 0; padding: 24px; text-align: center; color: var(--ink-500); }
.timeline li.empty::before { display: none; }

/* ---------- aircraft area: back link, picker, sub-tabs ---------- */
.aircraft-bar { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 10px 16px; }
.back-link { font-size: 14px; font-weight: 600; text-decoration: none; white-space: nowrap; }
.back-link::before { content: "← "; }
.back-link:hover { text-decoration: underline; }
.aircraft-bar .aircraft-picker { justify-self: start; }
.aircraft-bar .aircraft-picker .dd-trigger { font-size: 16px; font-weight: 700; max-width: min(420px, 100%); }
.subnav { grid-column: 1 / -1; display: flex; gap: 4px; overflow-x: auto; scrollbar-width: none; border-bottom: 1px solid var(--line); }
.subnav::-webkit-scrollbar { display: none; }
.subnav a { flex: none; padding: 10px 14px; font-size: 14px; font-weight: 600; color: var(--ink-500); text-decoration: none; border-bottom: 3px solid transparent; margin-bottom: -1px; }
.subnav a:hover { color: var(--ink-900); }
.subnav a[aria-current="page"] { color: var(--brand-600); border-bottom-color: var(--green-600); }
/* The aircraft name shows in the picker; the page sections carry their own titles. */
body:not([data-route="overview"]) #maintenance-title, body:not([data-route="overview"]) #requests-title, body:not([data-route="overview"]) #invoices-title { display: none; }

/* ---------- dashboard: compact aircraft list ---------- */
.fleet-mini { list-style: none; margin: 0; padding: 0; }
.fleet-row { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: 12px; width: 100%; text-align: left; font: inherit; color: inherit;
  background: none; border: 0; border-top: 1px solid var(--line); padding: 12px 24px; cursor: pointer; }
.fleet-row:hover { background: var(--row-hover); }
.fleet-row-name { display: grid; min-width: 0; }
.fleet-row-name strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fleet-row-name span { font-size: 13px; color: var(--ink-500); }
.fleet-row-bal { font-weight: 600; font-variant-numeric: tabular-nums; min-width: 72px; text-align: right; }
.fleet-mini .empty, .fleet .empty-state { list-style: none; }

/* aircraft list page */
.page-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
#list-head .page-actions { align-items: flex-end; }
.search input { font: inherit; font-size: 14px; padding: 8px 12px; border: 1px solid var(--ink-300); border-radius: var(--radius-sm); background: var(--raised); color: var(--ink-900); width: min(280px, 100%); }
.search input:focus { border-color: var(--brand-500); outline: 3px solid var(--brand-50); }

/* ---------- profile ---------- */
.profile-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; align-items: start; }
/* Each column stacks on its own so a tall card never leaves a gap beside it. */
.profile-col { display: grid; gap: 20px; align-content: start; min-width: 0; }
.profile-body { display: grid; gap: 14px; padding: 0 24px 22px; }
.inline-form { display: flex; gap: 8px; align-items: flex-end; flex-wrap: wrap; }
.inline-form .field { flex: 1 1 220px; }

/* ---------- offline: waiting changes ---------- */
.sync-panel { border: 1px solid var(--info-border); background: var(--brand-50); border-radius: var(--radius); padding: 12px 16px; display: grid; gap: 8px; font-size: 14px; }
.sync-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; }
.sync-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.sync-list li { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; padding: 8px 10px; border-radius: var(--radius-sm); background: var(--surface); }
.sync-list li > span:first-child { display: grid; }
.sync-list .is-failed { box-shadow: inset 3px 0 0 var(--overdue); }
.sync-error { color: var(--overdue); font-size: 13px; }

@media (max-width: 900px) {
  .profile-grid { grid-template-columns: 1fr; }
  /* One column: drop the column wrappers and keep the original reading order. */
  .profile-col { display: contents; }
  .profile-profile { order: 1; } .profile-access { order: 2; } .profile-notifications { order: 3; } .profile-appearance { order: 4; } .profile-app { order: 5; }
}
@media (max-width: 720px) {
  .fleet-row { padding: 12px 16px; grid-template-columns: minmax(0, 1fr) auto; }
  .fleet-row-bal { grid-column: 2; min-width: 0; }
  .profile-body { padding: 0 16px 18px; }
  .aircraft-bar { grid-template-columns: 1fr; }
  .aircraft-bar .aircraft-picker .dd, .aircraft-bar .aircraft-picker .dd-trigger { max-width: 100%; width: 100%; }
}

@media (max-width: 720px) { main.container { padding-top: 12px; } }

/* Design-preview strip: part of the page, scrolls away (never covers the sticky header). */
.banner-preview { justify-content: center; border-radius: 0; background: #1f5aa6; color: #ffffff; padding: 8px 16px; }

/* ---------- list pages: aircraft column ---------- */
.table:not(.show-aircraft) .col-aircraft { display: none; }
.table td.col-aircraft { font-weight: 600; }
.table td.col-aircraft span { white-space: nowrap; }

/* ---------- list pages: search field, with sort and filter icon buttons that open their panels ---------- */
.filter-card { padding: 14px; display: grid; }
.find-row { display: flex; gap: 8px; align-items: center; }
.find-search { position: relative; flex: 1; min-width: 0; }
.find-search input { font: inherit; width: 100%; min-width: 0; height: 44px; padding: 0 12px 0 40px; border: 1px solid var(--ink-300); border-radius: 10px; background: var(--raised); color: var(--ink-900); }
.find-search input:focus { border-color: var(--brand-500); outline: 3px solid var(--brand-50); }
.find-icon { position: absolute; left: 13px; top: 50%; width: 18px; height: 18px; transform: translateY(-50%); fill: none; stroke: var(--ink-500); stroke-width: 2; stroke-linecap: round; pointer-events: none; }
.find-btn {
  position: relative; flex: none; display: grid; place-items: center; width: 44px; height: 44px; padding: 0; border-radius: 10px;
  border: 1px solid var(--ink-300); background: var(--raised); color: var(--ink-700); cursor: pointer;
  transition: background .15s, border-color .15s, color .15s, transform .12s var(--ease-out), box-shadow .15s;
}
.find-btn svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; transition: transform .25s var(--ease-out); }
.find-btn:hover { border-color: var(--ink-500); color: var(--ink-900); box-shadow: var(--shadow-press); }
.find-btn:active { transform: scale(.92); transition-duration: .06s; }
.find-btn[aria-expanded="true"] { background: var(--brand-50); border-color: var(--brand-500); color: var(--brand-600); }
/* a non-default sort or any filter keeps the button tinted, with a dot or a count */
.find-btn.is-active { color: var(--brand-600); border-color: var(--brand-500); }
.find-btn .count, .find-dot {
  position: absolute; top: -6px; right: -6px; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px;
  background: var(--accent-fill); color: var(--on-fill); font-size: 11px; font-weight: 700; line-height: 18px; text-align: center;
  box-shadow: 0 0 0 2px var(--surface); animation: badge-pop .28s var(--ease-out);
}
.find-dot { min-width: 10px; width: 10px; height: 10px; padding: 0; top: -3px; right: -3px; }
.find-btn .count[hidden], .find-dot[hidden] { display: none; }
@keyframes badge-pop { from { transform: scale(0); } 60% { transform: scale(1.2); } }

/* very small phones: search is an icon button too, and its field opens in a panel below the row */
.find-row:not(.is-compact) .find-search-toggle { display: none; }
.find-row.is-compact .find-btn { flex: 1 1 0; width: auto; }
.find-panel .find-search { display: block; }
/* the clipped panel reaches 3px past the row so the field lines up with the buttons and its focus ring still shows */
.find-panel:has(> .find-panel-body > .find-search) .find-panel-body { margin-inline: -3px; padding: 0 3px 3px; }

/* panels slide open below the search row; only one is open at a time */
.find-panel { display: grid; grid-template-rows: 0fr; opacity: 0; transition: grid-template-rows .28s var(--ease-out), opacity .2s; }
.find-panel.is-open { grid-template-rows: 1fr; opacity: 1; }
.find-panel-body { min-height: 0; overflow: hidden; }
/* the space above a panel is part of it, so a closed panel takes no room */
.find-panel-body::before { content: ""; display: block; height: 14px; }
.find-panel-body { transform: translateY(-6px); transition: transform .28s var(--ease-out); }
.find-panel.is-open .find-panel-body { transform: none; }
.find-label { font-size: 13px; font-weight: 600; color: var(--ink-500); margin: 0 0 8px; }
.filter-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 12px; align-content: start; }
.filter-grid::before { grid-column: 1 / -1; height: 2px; }
.filter-card .field { gap: 4px; font-size: 13px; color: var(--ink-500); font-weight: 600; }
.filter-card .field[hidden] { display: none; }
.filter-grid .dd { width: 100%; }
.filter-card .dd-trigger { min-width: 0; }
.filter-foot { display: flex; justify-content: space-between; align-items: center; gap: 12px; font-size: 14px; margin-top: 12px; padding: 0 2px; }
.filter-foot:not(:has(> :not([hidden]))) { display: none; }

/* sort choices: app-styled pills, the picked one filled with a check */
.chips { display: flex; flex-wrap: wrap; gap: 8px; padding: 2px; }
.chip { position: relative; display: inline-flex; align-items: center; gap: 6px; padding: 8px 14px; border-radius: 999px; border: 1px solid var(--ink-300); background: var(--raised); color: var(--ink-700); font-size: 14px; font-weight: 500; cursor: pointer; transition: background .15s, border-color .15s, color .15s, transform .12s var(--ease-out), padding .2s var(--ease-out); -webkit-user-select: none; user-select: none; }
.chip input { position: absolute; opacity: 0; pointer-events: none; }
.chip:hover { border-color: var(--ink-500); color: var(--ink-900); }
.chip:active { transform: scale(.95); transition-duration: .06s; }
.chip::before { content: ""; width: 0; height: 14px; margin-right: -6px; background: currentColor; transition: width .2s var(--ease-out), margin .2s var(--ease-out);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 8.5l3 3 6-7'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 8.5l3 3 6-7'/%3E%3C/svg%3E") center / contain no-repeat; }
.chip:has(input:checked) { background: var(--accent-fill); border-color: var(--accent-fill); color: var(--on-fill); }
.chip:has(input:checked)::before { width: 14px; margin-right: 0; }
.chip:has(input:focus-visible) { outline: 3px solid color-mix(in srgb, var(--brand-500) 55%, transparent); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
  .find-panel, .find-panel-body, .find-btn svg, .chip, .chip::before { transition: none; }
  .find-btn .count, .find-dot { animation: none; }
  .find-btn:active, .chip:active { transform: none; }
}

/* ---------- people: phone above email ---------- */
.person-contact { display: grid; justify-items: end; gap: 2px; text-align: right; }
.person-phone { font-weight: 600; text-decoration: none; color: var(--ink-900); font-variant-numeric: tabular-nums; user-select: all; }
.person-phone:hover { text-decoration: underline; }
.menu-mobile-only { display: none !important; }
@media (max-width: 860px) { .menu .menu-mobile-only { display: block !important; } }
@media (max-width: 720px) {
  .person-contact { justify-items: start; text-align: left; flex-basis: 100%; padding-left: 52px; }
  .table tbody th { order: -1; }
  .filter-card { padding: 12px; }
  .filter-grid { grid-template-columns: 1fr 1fr; }
}

/* ---------- six-slot code input ---------- */
.otp { position: relative; display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 8px; }
/* the real input sits over the slots, invisible, so typing, paste and SMS/email auto-fill all work */
.otp input { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; font-size: 16px; border: 0; padding: 0; cursor: text; z-index: 1; }
.otp-cell { height: 52px; display: grid; place-items: center; border: 1px solid var(--ink-300); border-radius: var(--radius-sm); background: var(--raised);
  font-size: 24px; font-weight: 700; color: var(--ink-900); font-variant-numeric: tabular-nums; transition: border-color .15s, box-shadow .15s; }
.otp-cell:not(.filled)::after { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--ink-300); }
.otp-cell.active { border-color: var(--brand-500); box-shadow: 0 0 0 3px var(--brand-50); }
.otp-cell.active:not(.filled)::after { width: 2px; height: 26px; border-radius: 1px; background: var(--brand-500); animation: otp-caret 1s steps(1) infinite; }
@keyframes otp-caret { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .otp-cell.active:not(.filled)::after { animation: none; } }
.field > label[for] { font-size: 14px; font-weight: 500; }

/* ---------- profile editor ---------- */
img.avatar { object-fit: cover; padding: 0; background: var(--brand-50); }
.avatar-xl { width: 72px; height: 72px; font-size: 24px; }
.photo-row { display: flex; gap: 16px; align-items: center; flex-wrap: wrap; }
.photo-actions { display: grid; gap: 6px; }
.email-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--radius-sm); }
.email-row > div { display: grid; min-width: 0; }
.email-row strong { overflow-wrap: anywhere; }

/* summary cards that open a page */
a.kpi { position: relative; cursor: pointer; }
.kpi-go { font-size: 12px; font-weight: 600; color: var(--brand-500); margin-top: 2px; }

/* ---------- People ---------- */
.panel-actions { display: inline-flex; align-items: center; gap: 12px; }
.pending-note { font-style: normal; color: var(--due); font-weight: 600; }
.directory-card { padding: 0; overflow: hidden; }
.directory { list-style: none; margin: 0; padding: 0; }
/* One grid for the header and every row, so names, aircraft, contacts and statuses line up row to row. */
.directory-head, .dir-row { display: grid; grid-template-columns: 44px minmax(150px, 1.1fr) minmax(190px, 1.3fr) minmax(170px, 1fr) 128px 92px; gap: 16px; align-items: center; padding: 14px 24px; }
.directory-head { padding-top: 12px; padding-bottom: 12px; font-size: 12px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-500); background: var(--canvas); }
.dir-row { border-top: 1px solid var(--line); }
.dir-row.is-disabled > :not(.dir-open) { opacity: .6; }
.dir-name { display: grid; gap: 2px; min-width: 0; padding: 0; border: 0; background: none; font: inherit; color: inherit; text-align: left; cursor: pointer; }
.dir-name strong { display: flex; align-items: center; gap: 8px; overflow-wrap: anywhere; }
.dir-name:hover strong { text-decoration: underline; }
.dir-name > span { font-size: 13px; color: var(--ink-500); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dir-aircraft { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; font-size: 14px; min-width: 0; }
.dir-aircraft li { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.dir-ac { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dir-row .person-contact { justify-items: start; text-align: left; min-width: 0; }
.dir-open { justify-self: end; }
.directory .empty { display: block; padding: 32px 24px; text-align: center; color: var(--ink-500); border-top: 1px solid var(--line); }
@media (max-width: 1000px) {
  .directory-head { display: none; }
  .dir-row { grid-template-columns: 44px minmax(0, 1fr) auto; grid-template-areas: "av name open" ". status status" ". ac ac" ". contact contact"; row-gap: 10px; padding: 16px; }
  .dir-row > .avatar { grid-area: av; }
  .dir-name { grid-area: name; }
  .dir-open { grid-area: open; }
  .dir-aircraft { grid-area: ac; }
  .dir-row .person-contact { grid-area: contact; padding-left: 0; flex-basis: auto; }
  .dir-status { grid-area: status; justify-self: start; }
}

.person-card { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; padding-bottom: 16px; border-bottom: 1px solid var(--line); }
.person-card .person { gap: 2px; }
.person-card-status { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 4px; }
.person-section h3, .person-section-title { font-size: 15px; margin: 4px 0 8px; }
.person-section .fine { margin: 0 0 8px; }
.grant-list { list-style: none; margin: 0; padding: 0; border: 1px solid var(--line); border-radius: var(--radius-sm); }
.grant-list li { display: grid; grid-template-columns: minmax(0, 1fr) 150px 36px; align-items: center; gap: 12px; padding: 8px 8px 8px 14px; border-top: 1px solid var(--line); min-height: 52px; }
.grant-list li:first-child { border-top: 0; }
.grant-list li.empty { display: block; color: var(--ink-500); min-height: 0; padding: 14px; }
.grant-list .dd { width: 100%; }
.grant-list .tag { justify-self: start; }
.access-ac { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.access-add { display: grid; grid-template-columns: minmax(0, 1fr) 150px auto; gap: 12px; align-items: end; margin-top: 12px; }
.access-add:empty { display: none; }
.access-add .dd { width: 100%; }
.person-actions { display: flex; gap: 8px; flex-wrap: wrap; }
@media (max-width: 520px) {
  .grant-list li { grid-template-columns: minmax(0, 1fr) 120px 36px; padding-left: 12px; }
  .access-add { grid-template-columns: 1fr 1fr; }
  .access-add .btn { grid-column: 1 / -1; }
}
.person-open, .dir-open { min-width: 80px; justify-content: center; }

/* Roles & permissions: controls the signed-in person can't use on this page */
.no-perm { display: none !important; }

/* On-page assignment in an aircraft's People card: one grid so every row lines up. */
#people-list .crew-row { display: grid; grid-template-columns: 44px minmax(0, 1.2fr) 150px minmax(0, 1fr) 36px; align-items: center; gap: 14px; flex-wrap: nowrap; }
.crew-role .dd { width: 100%; }
.crew-role .tag { justify-self: start; }
#people-list .crew-row .person-contact { justify-items: end; text-align: right; padding-left: 0; flex-basis: auto; }
.crew-spacer { width: 36px; }
@media (max-width: 720px) {
  #people-list .crew-row { grid-template-columns: 44px minmax(0, 1fr) 36px; grid-template-areas: "av name x" ". role role" ". contact contact"; row-gap: 8px; }
  #people-list .crew-row > .avatar { grid-area: av; }
  #people-list .crew-row > .dir-name { grid-area: name; }
  #people-list .crew-row > .crew-role { grid-area: role; }
  #people-list .crew-row > .person-contact { grid-area: contact; justify-items: start; text-align: left; }
  #people-list .crew-row > .icon-btn, #people-list .crew-row > .crew-spacer { grid-area: x; }
}

/* Add bands at the foot of the overview cards (Maintenance, Service Requests, Invoices, and Assign on People).
   The tinted band runs edge to edge and follows the card's rounded bottom corners. Collapsed it's one Add
   button; tapping it folds the button away and unfolds the form (height + fade + slight drop), Cancel reverses. */
.panel-add, #people-list .crew-assign { display: block; padding: 0; background: var(--canvas); border-top: 1px solid var(--line); border-radius: 0 0 calc(var(--radius) - 1px) calc(var(--radius) - 1px); }
#people-list .crew-assign.muted { padding: 14px 24px; }
[data-route="overview"] .panel:has(> .panel-add:not(.no-perm)), .panel:has(> .people > .crew-assign:last-child) { padding-bottom: 0; }
.panel-add-toggle, .panel-add-body { display: grid; transition: grid-template-rows .28s var(--ease-out), opacity .22s var(--ease-out); }
.panel-add-toggle > div, .panel-add-body > div { min-height: 0; overflow: hidden; }
.panel-add-toggle { grid-template-rows: 1fr; }
.panel-add-body { grid-template-rows: 0fr; opacity: 0; }
.is-open > .panel-add-toggle { grid-template-rows: 0fr; opacity: 0; }
.is-open > .panel-add-body { grid-template-rows: 1fr; opacity: 1; }
.is-settled > .panel-add-body > div { overflow: visible; }
.panel-add-content { padding: 16px 24px 18px; transform: translateY(-8px); transition: transform .28s var(--ease-out); }
.is-open .panel-add-content { transform: none; }
.is-settled .panel-add-content { transform: none; transition: none; } /* no transform once open, so popovers anchor normally */
.add-toggle { display: flex; align-items: center; gap: 8px; width: 100%; padding: 14px 24px; font: inherit; font-size: 14px; font-weight: 600; color: var(--brand-500); background: none; border: 0; border-radius: 0 0 calc(var(--radius) - 1px) calc(var(--radius) - 1px); cursor: pointer; text-align: left; transition: background .15s, transform .12s var(--ease-out); }
.add-toggle svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; transition: transform .2s var(--ease-out); }
@media (hover: hover) { .add-toggle:hover { background: color-mix(in srgb, var(--brand-500) 8%, transparent); } .add-toggle:hover svg { transform: rotate(90deg); } }
.add-toggle:active { transform: scale(.99); background: color-mix(in srgb, var(--brand-500) 12%, transparent); }
.add-toggle:focus-visible { outline: 2px solid var(--brand-500); outline-offset: -2px; }
.panel-add-content:not(:has(.crew-assign-fields)) { display: flex; align-items: flex-end; gap: 12px; }
.crew-assign-fields { display: grid; grid-template-columns: minmax(0, 1fr) 150px auto; align-items: end; gap: 12px; }
.panel-add-fields { flex: 1; min-width: 0; display: grid; gap: 12px; align-items: end; }
#maintenance-add .panel-add-fields { grid-template-columns: minmax(0, 1.6fr) repeat(3, minmax(0, 1fr)); }
#requests-add .panel-add-fields { grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr); }
#invoices-add .panel-add-fields { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.panel-add .field > span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.panel-add .dd, .crew-assign .dd { width: 100%; }
.panel-add-actions { display: flex; gap: 8px; }
@media (max-width: 1100px) {
  .panel-add-content:not(:has(.crew-assign-fields)) { flex-direction: column; align-items: stretch; }
  .panel-add-actions { justify-content: flex-end; }
  #maintenance-add .panel-add-fields { grid-template-columns: 1fr 1fr; }
  #maintenance-add .panel-add-fields > :first-child { grid-column: 1 / -1; }
  #maintenance-add .panel-add-fields > :nth-child(3) { grid-column: 1 / -1; order: 1; } /* Last completed under hours + tach */
}
@media (max-width: 720px) {
  .panel-add-content { padding: 14px 16px 16px; }
  .add-toggle { padding: 14px 16px; }
  #people-list .crew-assign.muted { padding: 14px 16px; }
  .crew-assign-fields { grid-template-columns: 1fr 1fr; }
  .crew-assign-fields .panel-add-actions { grid-column: 1 / -1; }
  #requests-add .panel-add-fields, #invoices-add .panel-add-fields { grid-template-columns: 1fr 1fr; }
  #requests-add .panel-add-fields > *, #invoices-add .panel-add-fields > :first-child { grid-column: 1 / -1; }
  .panel-add-actions .btn { flex: 1; }
}
@media (prefers-reduced-motion: reduce) { .panel-add-content { transform: none; } }

/* Roles & permissions table */
.matrix-card { margin-top: 24px; }
.matrix { width: 100%; border-collapse: collapse; font-size: 14px; min-width: 820px; }
.matrix th, .matrix td { padding: 10px 12px; border-top: 1px solid var(--line); text-align: center; vertical-align: middle; }
.matrix thead th { font-size: 12px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-500); background: var(--canvas); border-top: 0; white-space: nowrap; }
.matrix thead th small { display: block; text-transform: none; letter-spacing: 0; color: var(--brand-600); font-weight: 600; }
.matrix th[scope="row"], .matrix thead th:first-child { text-align: left; font-weight: 500; color: var(--ink-900); padding-left: 24px; }
.matrix thead th:first-child { color: var(--ink-500); font-weight: 600; }
.matrix th[scope="row"] { position: sticky; left: 0; background: var(--surface); }
.matrix .matrix-section th { text-align: left; padding: 14px 24px 6px; font-size: 13px; font-weight: 700; color: var(--brand-600); background: var(--surface); }
/* The label stays in view while the table scrolls sideways on phones. */
.matrix .matrix-section th > span { position: sticky; left: 24px; }
.matrix .is-mine { background: var(--brand-50); }
.matrix thead .matrix-groups th, .matrix thead .matrix-groups td { padding-top: 12px; padding-bottom: 0; background: var(--canvas); border-top: 0; font-size: 11px; color: var(--ink-500); }
.matrix thead .matrix-groups + tr th { border-top: 0; }
.matrix .matrix-staff-start { border-left: 1px solid var(--line); }
.matrix thead :is(th, td):first-child { position: sticky; left: 0; z-index: 3; }
/* Header rows stay under the app header while their table scrolls past it (sticky-head.js). */
.table-wrap.has-sticky-head.is-fit { overflow: visible; }
/* --row-top: how far below the first header row this row sits (set by sticky-head.js), so stacked header rows pin together. */
.has-sticky-head.is-fit thead :is(th, td) { position: sticky; top: calc(var(--sticky-head-top, 0px) + var(--row-top, 0px)); z-index: 2; }
.has-sticky-head:not(.is-fit) thead :is(th, td) { position: relative; z-index: 2; transform: translateY(var(--head-shift, 0px)); }
.has-sticky-head thead th { transition: box-shadow .15s ease; }
.has-sticky-head.is-stuck thead tr:last-child :is(th, td) { box-shadow: inset 0 -1px 0 var(--line), 0 6px 8px -6px rgb(0 0 0 / .18); }
.has-sticky-head .matrix thead :is(th, td):first-child { position: sticky; z-index: 3; }
.matrix th[scope="row"] { z-index: 1; }
.matrix-yes svg { width: 18px; height: 18px; fill: none; stroke: var(--ok); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; vertical-align: middle; }
.matrix-no { color: var(--ink-300); }
/* block-level flex so no text strut adds space under the box; the cell centers it */
.matrix-check, .matrix-yes { display: flex; justify-content: center; margin: 0; }
.matrix-check input { margin: 0; }
@media (max-width: 720px) { #people-list .crew-row > .dir-name > span { white-space: normal; } }

/* ---------- native-feel touch feedback ---------- */
/* Tappable cards lift with a softer shadow on hover and sink when pressed, like app cards.
   Hover only applies on devices with a real pointer, so it never sticks after a tap on a phone. */
@media (hover: hover) {
  .fleet-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lift); }
  a.kpi:hover { transform: translateY(-2px); box-shadow: var(--shadow-lift); background: var(--surface); }
}
.fleet-card:active, a.kpi:active { transform: scale(.98); box-shadow: var(--shadow-press); transition-duration: .08s; }
.btn:active:not(:disabled), .icon-btn:active { transform: scale(.97); transition-duration: .06s; }
.attention-item, .fleet-row { transition: background .15s; }
.attention-item:active, .fleet-row:active { background: var(--canvas); }
.tabbar svg { transition: transform .12s var(--ease-out); }
.tabbar a:active svg { transform: scale(.86); transition-duration: .06s; }

/* ---------- drop zones (js/dropzone.js) ---------- */
/* Every file input is a dashed zone to drag files onto or tap to browse. The native input covers the
   zone invisibly, so a click or tap opens the picker and form validation still points at it. */
.dz { display: grid; gap: 8px; min-width: 0; }
.dz-target {
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  padding: 22px 16px; text-align: center; font-size: 14px; font-weight: 400; color: var(--ink-700);
  background: var(--raised); border: 1.5px dashed var(--ink-300); border-radius: var(--radius-sm); cursor: pointer;
  transition: border-color .15s, background .15s, box-shadow .2s var(--ease-out), transform .2s var(--ease-out);
}
.dz-icon { width: 36px; height: 36px; padding: 7px; border-radius: 50%; background: var(--brand-50); fill: none; stroke: var(--brand-500); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; transition: transform .25s var(--ease-out); }
.dz-browse { color: var(--brand-500); font-weight: 600; }
.dz-touch { display: none; font-weight: 600; color: var(--brand-500); }
@media (pointer: coarse) { .dz-mouse { display: none; } .dz-touch { display: inline; } }
.field .dz-native, .dz-native { position: absolute; inset: 0; width: 100%; height: 100%; padding: 0; margin: 0; border: 0; opacity: 0; cursor: pointer; font-size: 0; }
@media (hover: hover) {
  .dz-target:hover { border-color: var(--brand-500); background: var(--brand-50); }
  .dz-target:hover .dz-icon { transform: translateY(-2px); }
}
.dz-target:has(.dz-native:focus-visible) { border-color: var(--brand-500); outline: 3px solid var(--brand-50); outline-offset: 0; }
.dz-target:active { transform: scale(.98); background: var(--canvas); transition-duration: .06s; }
/* Files dragged anywhere on the page: zones light up; over a zone it lifts and the icon jumps. */
.is-dragging-files .dz-target { border-color: var(--brand-500); }
.dz.is-over .dz-target { border-style: solid; border-color: var(--brand-500); background: var(--brand-50); transform: scale(1.02); box-shadow: var(--shadow-lift); }
.dz.is-over .dz-icon { transform: translateY(-4px) scale(1.08); }
.dz.is-over .dz-target * { pointer-events: none; }
.dz.is-disabled .dz-target { opacity: .55; cursor: not-allowed; }
.dz-note { margin: 0; font-size: 13px; color: var(--overdue); }
.dz-note:empty { display: none; }
.dz-files { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.dz-files:empty { display: none; }
.dz-file { display: flex; align-items: center; gap: 10px; padding: 6px 6px 6px 8px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); font-size: 14px; font-weight: 400; animation: dz-in .22s var(--ease-out); }
.dz-thumb { display: grid; place-items: center; flex: none; width: 40px; height: 40px; border-radius: 6px; background: var(--brand-50); overflow: hidden; }
.dz-thumb img { width: 100%; height: 100%; object-fit: cover; }
.dz-thumb svg { width: 20px; height: 20px; fill: none; stroke: var(--brand-500); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.dz-name { display: grid; flex: 1; min-width: 0; }
.dz-name span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-900); }
.dz-name small { color: var(--ink-500); font-size: 12px; }
.dz-remove { display: grid; place-items: center; flex: none; width: 32px; height: 32px; border: 0; border-radius: 50%; background: none; color: var(--ink-500); cursor: pointer; transition: background .15s, color .15s, transform .12s var(--ease-out); }
.dz-remove svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
@media (hover: hover) { .dz-remove:hover { background: var(--overdue-bg); color: var(--overdue); } }
.dz-remove:active { transform: scale(.88); transition-duration: .06s; }
@keyframes dz-in { from { opacity: 0; transform: translateY(-4px); } }
/* One-line zone (profile photo): sits in a button row and uploads as soon as a photo lands. */
.dz-compact .dz-target { flex-direction: row; gap: 8px; padding: 6px 14px 6px 8px; font-size: 14px; font-weight: 500; }
.dz-compact .dz-icon { width: 26px; height: 26px; padding: 5px; }
.dz-compact.is-over .dz-target { transform: scale(1.04); }
@media (prefers-reduced-motion: reduce) {
  .dz-target, .dz-target:active, .dz.is-over .dz-target, .dz-icon, .dz-file { transform: none !important; animation: none; }
}

/* ---------- dropdowns (js/select.js) ---------- */
/* An app-styled button opens a rounded, animated list. The native <select> stays underneath for forms;
   on touch screens it covers the button invisibly so a tap opens the phone's own picker. */
.dd { position: relative; display: inline-grid; max-width: 100%; min-width: 0; vertical-align: middle; }
.dd-native { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; pointer-events: none; font-size: 16px; appearance: none; border: 0; }
@media (pointer: coarse) { .dd-native { pointer-events: auto; cursor: pointer; } }
.dd-trigger {
  display: flex; align-items: center; gap: 8px; min-width: 0; width: 100%; text-align: left; cursor: pointer;
  font: inherit; font-size: 14px; font-weight: 500; color: var(--ink-900); padding: 9px 10px 9px 12px;
  background: var(--raised); border: 1px solid var(--ink-300); border-radius: var(--radius-sm);
  transition: border-color .15s, background .15s, box-shadow .15s, transform .2s var(--ease-out);
}
.dd-value { display: grid; flex: 1; min-width: 0; }
.dd-value > span { grid-area: 1 / 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dd-sizer { visibility: hidden; }
.dd-chevron { flex: none; width: 16px; height: 16px; fill: none; stroke: var(--ink-500); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; transition: transform .2s var(--ease-out); }
@media (hover: hover) { .dd-trigger:hover:not(:disabled) { border-color: var(--ink-500); } }
.dd-trigger:focus-visible, .dd.is-open .dd-trigger { border-color: var(--brand-500); outline: 3px solid var(--brand-50); outline-offset: 0; }
.dd-trigger:active:not(:disabled), .dd:has(.dd-native:active) .dd-trigger { transform: scale(.98); background: var(--canvas); transition-duration: .06s; }
.dd:has(.dd-native:focus-visible) .dd-trigger { border-color: var(--brand-500); outline: 3px solid var(--brand-50); outline-offset: 0; }
.dd.is-open .dd-chevron { transform: rotate(180deg); }
.dd-trigger:disabled { opacity: .55; cursor: not-allowed; }

.dd-list {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 40; inset: auto; margin: 0;
  padding: 6px; overflow: auto; overscroll-behavior: contain; max-height: 320px; width: max-content;
  background: var(--raised); color: var(--ink-900); border: 1px solid var(--line); border-radius: 12px; box-shadow: var(--shadow-menu);
  font-size: 14px; transform-origin: top center;
}
.dd-list:not([popover]) { top: calc(100% + 6px); left: 0; }
.dd-list[popover] { position: fixed; }
.dd-list.is-up { transform-origin: bottom center; }
@keyframes dd-in { from { opacity: 0; transform: translateY(-6px) scale(.97); } }
@keyframes dd-in-up { from { opacity: 0; transform: translateY(6px) scale(.97); } }
@keyframes dd-out { to { opacity: 0; transform: scale(.97); } }
.dd-list.is-open { animation: dd-in .18s var(--ease-out); }
.dd-list.is-open.is-up { animation-name: dd-in-up; }
.dd-list.is-closing { animation: dd-out .12s ease-in forwards; }
.dd-list [role=option] {
  display: grid; grid-template-columns: 18px minmax(0, 1fr); align-items: center; gap: 8px; padding: 9px 12px 9px 8px; border-radius: 8px;
  cursor: pointer; white-space: nowrap; transition: background .12s, transform .12s var(--ease-out);
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none;
}
.dd-list [role=option] > span { overflow: hidden; text-overflow: ellipsis; }
.dd-list [role=option].is-active { background: var(--canvas); }
.dd-list [role=option]:active { transform: scale(.98); background: var(--line); transition-duration: .06s; }
.dd-list [role=option][aria-selected="true"] { font-weight: 600; color: var(--brand-600); }
.dd-list [role=option][aria-disabled="true"] { opacity: .5; cursor: default; }
.dd-check { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; visibility: hidden; }
[aria-selected="true"] > .dd-check { visibility: visible; }
@media (prefers-reduced-motion: reduce) {
  .dd-list.is-open, .dd-list.is-closing { animation: none; }
  .dd-trigger:active:not(:disabled), .dd-list [role=option]:active { transform: none; }
}

/* ---------- date fields (js/datepicker.js): same button and popover as the dropdowns, with a calendar ---------- */
.dp .dp-icon { transform: none !important; }
.dp.is-empty .dd-current { color: var(--ink-500); }
.dp-cal { width: 296px; max-height: none; padding: 12px; overflow: visible; }
.dp-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
.dp-title {
  display: inline-flex; align-items: center; gap: 4px; font: inherit; font-size: 15px; font-weight: 700; color: var(--ink-900);
  background: none; border: 0; border-radius: 8px; padding: 6px 10px; cursor: pointer; transition: background .15s, transform .12s var(--ease-out);
}
/* a small chevron says the title opens the month / year view */
.dp-title:not(:disabled)::after { content: ""; width: 7px; height: 7px; border: solid var(--ink-500); border-width: 0 2px 2px 0; transform: translateY(-2px) rotate(45deg); margin-left: 4px; }
@media (hover: hover) { .dp-title:hover:not(:disabled) { background: var(--canvas); } }
.dp-title:active:not(:disabled) { transform: scale(.96); background: var(--line); transition-duration: .06s; }
.dp-title:disabled { cursor: default; }
.dp-title:focus-visible { outline: 3px solid color-mix(in srgb, var(--brand-500) 55%, transparent); outline-offset: 0; }
.dp-tiles { display: grid; grid-template-rows: repeat(4, 1fr); gap: 6px; height: 232px; padding: 4px 0; }
.dp-tiles [role=row] { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.dp-tile {
  border: 0; border-radius: 10px; background: none; color: var(--ink-900); font: inherit; font-size: 14px; font-weight: 500; font-variant-numeric: tabular-nums;
  cursor: pointer; transition: background .12s, color .12s, transform .12s var(--ease-out);
}
@media (hover: hover) { .dp-tile:hover:not(:disabled) { background: var(--canvas); } }
.dp-tile:active:not(:disabled) { transform: scale(.94); background: var(--line); transition-duration: .06s; }
.dp-tile.is-today { color: var(--brand-600); font-weight: 700; box-shadow: inset 0 0 0 1.5px var(--brand-500); }
.dp-tile[aria-pressed="true"] { background: var(--accent-fill); color: var(--on-fill); font-weight: 700; box-shadow: none; }
@media (hover: hover) { .dp-tile[aria-pressed="true"]:hover { background: var(--accent-fill-hover); } }
.dp-tile:disabled { opacity: .3; cursor: default; }
.dp-tile:focus-visible { outline: 3px solid color-mix(in srgb, var(--brand-500) 55%, transparent); outline-offset: 0; }
@keyframes dp-zoom { from { opacity: 0; transform: scale(.94); } }
.dp-body.is-zooming { animation: dp-zoom .2s var(--ease-out); }
.dp-nav { display: grid; place-items: center; width: 34px; height: 34px; border: 0; border-radius: 50%; background: none; color: var(--ink-700); cursor: pointer; transition: background .15s, transform .12s var(--ease-out); }
.dp-nav svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
@media (hover: hover) { .dp-nav:hover:not(:disabled) { background: var(--canvas); } }
.dp-nav:active:not(:disabled) { transform: scale(.9); background: var(--line); transition-duration: .06s; }
.dp-nav:disabled { opacity: .35; cursor: default; }
.dp-grid { width: 100%; border-collapse: collapse; table-layout: fixed; }
.dp-grid th { font-size: 12px; font-weight: 600; color: var(--ink-500); padding: 4px 0 6px; text-align: center; }
.dp-grid td { padding: 1px; text-align: center; }
.dp-day {
  width: 36px; height: 36px; border: 0; border-radius: 50%; background: none; color: var(--ink-900); font: inherit; font-size: 14px; font-variant-numeric: tabular-nums;
  cursor: pointer; transition: background .12s, color .12s, transform .12s var(--ease-out);
}
@media (hover: hover) { .dp-day:hover:not(:disabled) { background: var(--canvas); } }
.dp-day:active:not(:disabled) { transform: scale(.9); background: var(--line); transition-duration: .06s; }
.dp-day.is-outside { color: var(--ink-500); opacity: .55; }
.dp-day.is-today { color: var(--brand-600); font-weight: 700; box-shadow: inset 0 0 0 1.5px var(--brand-500); }
.dp-day[aria-pressed="true"] { background: var(--accent-fill); color: var(--on-fill); font-weight: 700; opacity: 1; box-shadow: none; }
@media (hover: hover) { .dp-day[aria-pressed="true"]:hover { background: var(--accent-fill-hover); } }
.dp-day:disabled { opacity: .3; cursor: default; text-decoration: line-through; }
.dp-day:focus-visible, .dp-nav:focus-visible { outline: 3px solid color-mix(in srgb, var(--brand-500) 55%, transparent); outline-offset: 0; }
.dp-foot { display: flex; justify-content: flex-end; border-top: 1px solid var(--line); margin-top: 8px; padding-top: 8px; }
.dp-foot .link-btn { font-size: 14px; font-weight: 600; padding: 4px 6px; }
@media (prefers-reduced-motion: reduce) {
  .dp-day:active:not(:disabled), .dp-nav:active:not(:disabled), .dp-tile:active:not(:disabled), .dp-title:active:not(:disabled) { transform: none; }
  .dp-body.is-zooming { animation: none; }
}

/* Long-pressing controls and cards shouldn't select their text or pop the link/image callout. */
.btn, .icon-btn, .dd-trigger, .account-btn, .primary-nav, .tabbar, .menu, .segmented, .sort, .view-all, .link-btn, .find-btn,
.fleet-card, a.kpi, .attention-item, .fleet-row, .dir-name, .subnav, .back-link, .check {
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none;
}
/* Like a native app, none of the interface selects as text, only what people typed: form fields, and the
   messages and notes they wrote when shown back (.detail-message). Phone numbers and emails keep their
   one-tap select-all (user-select: all) for copying. Dialogs and popovers are named too: in the top layer
   they don't pick it up from body. */
body, dialog, [popover] { -webkit-user-select: none; user-select: none; }
input, textarea, [contenteditable], .detail-message { -webkit-user-select: text; user-select: text; }

/* Page transitions: a page fades and rises in when it's shown. No fill mode, so no transform is
   left on the section afterwards (that would re-anchor fixed-position children). */
@keyframes page-in { from { opacity: 0; transform: translateY(8px); } }
#main [data-routes]:not([hidden]) { animation: page-in .24s var(--ease-out); }

/* Loading placeholders: shimmering bars in a list or table until its first data arrives.
   Every renderer fills these lists (with an "empty" row when there's nothing), so :empty only matches before the first load. */
@keyframes skeleton-pulse { 50% { opacity: .45; } }
#dash-greeting:empty::before, #dash-kpis:empty::before, #dash-attention:empty::before, #dash-fleet:empty::before,
#fleet-list:empty::before, #fleet-list:empty::after, #directory:empty::before, #profile:empty::before,
.panel:has(tbody:empty):has(> .empty[hidden]) .table-wrap::after {
  content: ""; display: block; animation: skeleton-pulse 1.4s ease-in-out infinite;
  --bar: var(--line);
  background: repeating-linear-gradient(to bottom, var(--bar) 0 12px, transparent 12px 30px) 0 0 / 100% 100% no-repeat;
}
#dash-greeting:empty::before { width: min(260px, 70%); height: 30px; background: var(--bar); border-radius: 8px; }
#dash-kpis:empty::before { grid-column: 1 / -1; height: 74px; background: var(--bar); border-radius: var(--radius-sm); }
#dash-attention:empty::before, #dash-fleet:empty::before, #directory:empty::before { height: 102px; margin: 18px 24px 22px; }
.panel:has(tbody:empty):has(> .empty[hidden]) .table-wrap::after { height: 72px; margin: 16px 24px 20px; }
#profile:empty::before { height: 192px; margin: 4px 0; }
#fleet-list:empty::before, #fleet-list:empty::after { height: 230px; border-radius: var(--radius); background: var(--bar); }

/* Pull-to-refresh indicator (js/pull-refresh.js); the browser's own pull-to-reload is turned off. */
html.has-ptr, html.has-ptr body { overscroll-behavior-y: contain; }
.ptr { position: fixed; left: 50%; top: calc(var(--header-h) + var(--env-banner-h, 0px) + env(safe-area-inset-top, 0px) - 30px); z-index: 15; width: 36px; height: 36px; border-radius: 50%;
  display: grid; place-items: center; background: var(--raised); color: var(--ink-500); box-shadow: var(--shadow-menu); opacity: 0; transform: translate(-50%, 0); pointer-events: none; }
.ptr.settling { transition: transform .25s var(--ease-out), opacity .25s; }
.ptr svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; transform: rotate(var(--ptr-turn, 0deg)); }
.ptr.ready, .ptr.spinning { color: var(--brand-600); }
@keyframes ptr-spin { to { transform: rotate(360deg); } }
.ptr.spinning svg { animation: ptr-spin .7s linear infinite; }

/* Dialogs slide down and fade in on larger screens and slide up as a bottom sheet on phones. Closing plays
   the reverse (.is-closing, set by app.js) before the dialog actually closes. */
@keyframes dialog-in { from { opacity: 0; transform: translateY(-24px); } }
@keyframes dialog-out { to { opacity: 0; transform: translateY(-24px); } }
@keyframes sheet-up { from { transform: translateY(100%); } }
@keyframes sheet-down { to { transform: translateY(100%); } }
@keyframes backdrop-in { from { opacity: 0; } }
@keyframes backdrop-out { to { opacity: 0; } }
@keyframes fade-in { from { opacity: 0; } }
@keyframes fade-out { to { opacity: 0; } }
.dialog[open] { animation: dialog-in .26s var(--ease-out); }
.dialog[open]::backdrop { animation: backdrop-in .26s ease-out; }
.dialog[open].is-closing { animation: dialog-out .18s ease-in forwards; pointer-events: none; }
.dialog[open].is-closing::backdrop { animation: backdrop-out .18s ease-in forwards; }
/* While a dialog is open (closing included) the page behind it doesn't scroll. If the page had a scrollbar its
   space is kept (.keep-gutter, set by app.js) so nothing shifts sideways, and scrolling inside the dialog stops
   at its ends instead of carrying on to the page (iOS included). */
html:has(.dialog[open]) { overflow: hidden; }
html.keep-gutter:has(.dialog[open]) { scrollbar-gutter: stable; }
.dialog form { overscroll-behavior: contain; }
@media (max-width: 640px) {
  .dialog, .dialog-sm, .dialog-wide { width: 100%; max-width: 100%; margin: auto 0 0; border-radius: 18px 18px 0 0; padding-bottom: env(safe-area-inset-bottom, 0px); }
  .dialog[open] { animation: sheet-up .32s var(--ease-out); }
  .dialog[open].is-closing { animation: sheet-down .24s cubic-bezier(.4, 0, 1, 1) forwards; }
  .dialog[open].is-closing::backdrop { animation-duration: .24s; }
  .dialog::before { content: ""; display: block; width: 36px; height: 5px; border-radius: 3px; background: var(--ink-300); margin: 8px auto 0; }
  .dialog form { max-height: calc(100vh - 64px); max-height: calc(100dvh - 64px); padding-top: 12px; }
}

@media (prefers-reduced-motion: reduce) {
  .fleet-card:hover, a.kpi:hover, .fleet-card:active, a.kpi:active, .btn:active, .icon-btn:active, .tabbar a:active svg { transform: none; }
  #main [data-routes]:not([hidden]) { animation: none; }
  /* Dialogs and their backdrop just fade, without moving. */
  .dialog[open], .dialog[open]::backdrop { animation: fade-in .15s ease-out; }
  .dialog[open].is-closing, .dialog[open].is-closing::backdrop { animation: fade-out .12s ease-in forwards; }
  .ptr.spinning svg { animation-duration: 1.6s; }
}

/* ---------- rotate your device (phones in portrait, on wide tables) ---------- */
.rotate-prompt {
  position: fixed; left: 12px; right: 12px; bottom: calc(12px + env(safe-area-inset-bottom, 0px)); z-index: 40;
  display: grid; grid-template-columns: 40px 1fr; align-items: center; gap: 8px 12px;
  padding: 14px 14px 14px 14px; border-radius: 16px; background: var(--raised); border: 1px solid var(--line); box-shadow: var(--shadow-lg);
  animation: rotate-in .32s var(--ease-out);
}
.rotate-prompt[hidden] { display: none; }
.rotate-prompt.is-leaving { animation: rotate-out .2s ease-in forwards; }
body:has(.tabbar:not([hidden])) .rotate-prompt { bottom: calc(76px + env(safe-area-inset-bottom, 0px)); }
/* icon beside the heading, the message under both at the card's full width */
.rotate-prompt > div { display: contents; }
.rotate-head { display: flex; align-items: flex-start; gap: 4px; }
.rotate-prompt h2 { flex: 1; font-size: 16px; line-height: 20px; font-weight: 700; color: var(--brand-600); margin: 0; }
.rotate-prompt p { grid-column: 1 / -1; font-size: 14px; line-height: 1.4; color: var(--ink-700); margin: 0; }
/* close button centered on the heading's first line (34px button, 20px line) */
.rotate-prompt .icon-btn { flex: none; margin: -7px -6px -7px 0; }
.rotate-icon { width: 40px; height: 40px; fill: none; stroke: var(--ink-900); stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; overflow: visible; }
.rotate-icon circle { fill: var(--ink-900); stroke: none; }
.rotate-arrows { stroke: var(--brand-600); transform-box: view-box; transform-origin: 24px 24px; animation: rotate-arrows 2.8s var(--ease-out) infinite; }
.rotate-phone { transform-box: view-box; transform-origin: 24px 24px; animation: rotate-phone 2.8s var(--ease-out) infinite; }
/* Upright, turn a quarter counterclockwise into landscape (the way people rotate a phone), hold, then fade back upright and repeat. */
@keyframes rotate-phone {
  0%, 18% { transform: rotate(0); opacity: 1; }
  48%, 80% { transform: rotate(-90deg); opacity: 1; }
  90% { transform: rotate(-90deg); opacity: 0; }
  91% { transform: rotate(0); opacity: 0; }
  100% { transform: rotate(0); opacity: 1; }
}
@keyframes rotate-arrows {
  0%, 12% { opacity: .35; transform: rotate(20deg); }
  42%, 80% { opacity: 1; transform: rotate(0); }
  100% { opacity: .35; transform: rotate(20deg); }
}
@keyframes rotate-in { from { opacity: 0; transform: translateY(24px) scale(.98); } }
@keyframes rotate-out { to { opacity: 0; transform: translateY(24px) scale(.98); } }
@media (prefers-reduced-motion: reduce) {
  .rotate-prompt, .rotate-prompt.is-leaving, .rotate-arrows { animation: none; }
  /* Show the end state: the phone already sideways. */
  .rotate-phone { animation: none; transform: rotate(-90deg); }
}

/* ---------- update available (a new deploy while the app is open) ---------- */
.update-card {
  position: fixed; right: 24px; bottom: calc(24px + env(safe-area-inset-bottom, 0px)); z-index: 45; width: min(400px, calc(100vw - 24px));
  display: grid; grid-template-columns: 40px 1fr; align-items: center; gap: 12px;
  padding: 14px; border-radius: 16px; background: var(--raised); border: 1px solid var(--line); box-shadow: var(--shadow-lg);
  animation: update-in .32s var(--ease-out);
}
.update-card[hidden] { display: none; }
.update-card.is-leaving { animation: update-out .2s ease-in forwards; }
.update-card h2 { font-size: 16px; line-height: 20px; font-weight: 700; color: var(--brand-600); margin: 0; }
.update-card p { font-size: 14px; line-height: 1.4; color: var(--ink-700); margin: 2px 0 0; }
.update-icon { width: 40px; height: 40px; border-radius: 12px; display: grid; place-items: center; background: var(--brand-50); color: var(--brand-600); }
.update-icon svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; animation: update-spin 1.1s var(--ease-out) .25s; }
.update-actions { grid-column: 1 / -1; display: flex; justify-content: flex-end; gap: 8px; }
.update-actions .btn { min-width: 96px; }
/* the toast and the rotate prompt share the bottom of the screen: keep the toast clear, and let the update go first */
body:has(.update-card:not([hidden])) .toast { bottom: calc(150px + env(safe-area-inset-bottom, 0px)); }
body:has(.update-card:not([hidden])) .rotate-prompt { display: none; }
@media (max-width: 860px) {
  .update-card { left: 12px; right: 12px; bottom: calc(12px + env(safe-area-inset-bottom, 0px)); width: auto; }
  .update-actions .btn { flex: 1; }
  body:has(.tabbar:not([hidden])) .update-card { bottom: calc(76px + env(safe-area-inset-bottom, 0px)); }
  body:has(.tabbar:not([hidden])) .update-card:not([hidden]) ~ .toast { bottom: calc(210px + env(safe-area-inset-bottom, 0px)); }
}
@keyframes update-in { from { opacity: 0; transform: translateY(24px) scale(.98); } }
@keyframes update-out { to { opacity: 0; transform: translateY(16px) scale(.98); } }
@keyframes update-spin { from { transform: rotate(-200deg); } }
@media (prefers-reduced-motion: reduce) { .update-card, .update-card.is-leaving, .update-icon svg { animation: none; } }
