/* The portal's look.
 *
 * The palette is the testing report's :root, unchanged, so the portal, the
 * report and the app read as one product. Desktop first since P3.2
 * (CLIENT_READY_PLAN.md, 2026-10-08): the portal is for a laptop or desktop
 * (ShootC, 2026-09-24). 1366x768 and 1920x1080 are the design viewports; at
 * 1200px and up the full shell shows, between 800 and 1200 the sidebar
 * collapses to its icons, and under 800 it becomes a top bar with a menu
 * button, because a technician checking "My inspections" next to a van still
 * needs the download link to work.
 *
 * Inter is shipped with the portal (fonts/, the same file the site serves)
 * rather than fetched from anywhere: the CSP allows nothing third-party, and
 * that stays so.
 */

@font-face {
  font-family: "Inter";
  src: url(fonts/inter-latin-wght-normal.woff2) format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  --navy: #0f172a;
  --navy2: #1e293b;
  --navy3: #334155;
  --accent: #C8102E;
  --accent2: #a50d26;
  --ink: #1e293b;
  --ink2: #64748b;
  --ink3: #475569;   /* grey that still reads on --pale (4.5:1 and more) */
  --line: #e2e8f0;
  --line2: #cbd5e1;
  --pale: #f1f5f9;
  --bg: #f8fafc;
  --ok: #16a34a;
  --warn: #d97706;
  --bad: #dc2626;
  --on-dark: #f1f5f9;
  --on-dark2: #a3b0c2;
  --mono: "Cascadia Mono", ui-monospace, Consolas, monospace;
  --font: "Inter", "Segoe UI", system-ui, -apple-system, Roboto, Arial, sans-serif;

  /* the spacing scale */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px; --s6: 32px; --s7: 48px;
  /* the type scale */
  --t12: 12px; --t13: 13px; --t14: 14px; --t16: 16px; --t20: 20px; --t28: 28px;

  --side: 240px;
  --side-narrow: 64px;
  --content: 1440px;
  --gutter: var(--s6);
  --radius: 10px;
  --radius-sm: 7px;
  --shadow: 0 1px 2px rgb(15 23 42 / .05), 0 8px 24px rgb(15 23 42 / .06);
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: var(--t14)/1.5 var(--font);
  font-feature-settings: "cv11", "ss01", "tnum" 0;
  -webkit-font-smoothing: antialiased;
}

/* Text for a screen reader only: a header over the ... column, and the like. */
.vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* Keyboard users land on the content, not on the nav, with one press. */
.skip {
  position: absolute; left: -999px; top: 8px; z-index: 50;
  background: var(--navy); color: #fff; padding: 8px 12px; border-radius: 6px;
}
.skip:focus { left: 8px; }

/* ---- the shell ---------------------------------------------------------- */

body.shell {
  display: grid;
  grid-template-columns: var(--side) minmax(0, 1fr);
  min-height: 100vh;
}

.side {
  background: var(--navy);
  color: var(--on-dark);
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh;
  overflow-y: auto;
}
.sidehead {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--s4) var(--s4) var(--s3);
}
.sidebody { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }

/* The same lockup the exe and the testing report use: the real flame badge
   out of the app (hyperpyre_mark.png), then the wordmark as TEXT with a red H
   and P. The image URL is relative, so it resolves against wherever this
   stylesheet is served from and does not need to know the base path. */
.brand {
  display: inline-flex; align-items: center; gap: 9px;
  text-decoration: none; color: var(--navy);
  font-size: 1.15rem; font-weight: 800; letter-spacing: .005em; white-space: nowrap;
}
.brand b { color: var(--accent); font-weight: 800; }
.brand .mark {
  height: 1.25em; width: 1.25em; flex: 0 0 auto; border-radius: 24%;
  background: url(hyperpyre-mark.png) center / contain no-repeat;
}
.side .brand, .brand.light { color: #fff; }

.navbtn { display: none; }

/* The customer's mark, under HyperPyre's own. Capped hard in height so a tall
   logo cannot push the sidebar about. */
.co { padding: 0 var(--s4) var(--s4); border-bottom: 1px solid rgb(255 255 255 / .1); margin-bottom: var(--s3); }
.side .cologo {
  max-height: 40px; max-width: 100%; object-fit: contain; display: block;
  background: #fff; border-radius: 6px; padding: 4px 6px; margin: 0 0 6px;
}
.coname { display: block; font-weight: 600; font-size: var(--t13); color: var(--on-dark); overflow-wrap: anywhere; }

.nav { display: flex; flex-direction: column; gap: var(--s1); padding: 0 var(--s2); }
.nav .group { display: flex; flex-direction: column; gap: 2px; }
.nav .group + .group { margin-top: var(--s3); padding-top: var(--s3); border-top: 1px solid rgb(255 255 255 / .1); }
.nav a, .me a, .signout {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; border-radius: var(--radius-sm);
  color: var(--on-dark2); text-decoration: none; font-size: var(--t14); font-weight: 500;
  border-left: 3px solid transparent;
}
.nav a:hover, .me a:hover, .signout:hover { color: #fff; background: rgb(255 255 255 / .06); }
.nav a.on, .me a.on { color: #fff; background: rgb(255 255 255 / .08); border-left-color: var(--accent); }
.ico { flex: 0 0 auto; }

.offices { padding: var(--s4) var(--s2) 0; display: flex; flex-direction: column; gap: 2px; }
.sidelabel {
  font-size: 11px; letter-spacing: .12em; text-transform: uppercase; font-weight: 700;
  color: var(--on-dark2); padding: 0 10px 4px;
}
.offices a {
  display: block; padding: 5px 10px; border-radius: var(--radius-sm);
  color: var(--on-dark2); text-decoration: none; font-size: var(--t13);
}
.offices a:hover { color: #fff; background: rgb(255 255 255 / .06); }
.offices a.on { color: #fff; font-weight: 600; }

.me {
  margin-top: auto; padding: var(--s3) var(--s2) var(--s4);
  border-top: 1px solid rgb(255 255 255 / .1); display: flex; flex-direction: column; gap: 2px;
}
.who { padding: 4px 10px 8px; color: #fff; font-size: var(--t14); }
.who small { display: block; color: var(--on-dark2); font-size: var(--t12); margin-top: 2px; }
.signout { width: 100%; background: none; border: 0; border-left: 3px solid transparent; font: inherit; cursor: pointer; text-align: left; }
.inline { display: inline; margin: 0; }
.me form { display: block; }

/* ---- the content area --------------------------------------------------- */

.content {
  max-width: var(--content);
  width: 100%;
  margin: 0;
  padding: var(--s5) var(--gutter) var(--s7);
  min-width: 0;
}

.phead {
  display: flex; align-items: flex-end; justify-content: space-between; gap: var(--s4);
  margin: 0 0 var(--s5);
}
.ptitle { min-width: 0; }
.pact { display: flex; gap: var(--s2); align-items: center; flex: 0 0 auto; }

.eyebrow {
  font-size: 11px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--accent); font-weight: 700; margin: 0;
}
h1 { margin: 2px 0 0; font-size: var(--t28); line-height: 1.2; color: var(--navy); font-weight: 700; letter-spacing: -.01em; overflow-wrap: anywhere; }
h2 { font-size: var(--t16); color: var(--navy); margin: 0 0 var(--s3); font-weight: 700; }
h3 { font-size: var(--t14); color: var(--navy); margin: 0 0 var(--s2); font-weight: 700; }

/* ---- messages ----------------------------------------------------------- */

.said, .problem {
  margin: 0 0 var(--s4); padding: 10px 14px; border-radius: var(--radius-sm);
  border: 1px solid var(--line2); background: #fff; font-size: var(--t14);
}
.said { border-color: #bbf7d0; background: #f0fdf4; color: #14532d; }
.problem { border-color: #fecaca; background: #fef2f2; color: #7f1d1d; }
.ok { color: #14532d; }
.warn { color: var(--warn); }
.bad { color: var(--bad); }
.dim { color: var(--ink2); }
.mono { font-family: var(--mono); font-size: .92em; }
.meta { color: var(--ink2); font-size: var(--t13); }
.note {
  margin: 0 0 var(--s4); padding: 10px 14px; background: #fffbeb;
  border: 1px solid #fde68a; border-radius: var(--radius-sm);
}

/* Where the subscription stands, and the "only admin" warning: a slim bar
   above the page header, never a modal and never a blocker. At worst the
   account is read-only, and the technician's job still has to be openable. */
.account {
  margin: 0 0 var(--s4); padding: 8px 14px; border-radius: var(--radius-sm);
  font-size: var(--t13); border: 1px solid var(--line2); background: #fff;
}
.account.info { border-color: #bfdbfe; background: #eff6ff; color: #1e3a8a; }
.account.warn { border-color: #fde68a; background: #fffbeb; color: #92400e; }
.account.stop { border-color: #fecaca; background: #fef2f2; color: #7f1d1d; }
.account a { color: inherit; }

/* ---- cards and forms ---------------------------------------------------- */

.card {
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius);
  padding: var(--s5); margin: 0 0 var(--s4);
}
.card.narrow { max-width: 560px; }
.card.collect { border-color: var(--line2); }

/* Two or three cards side by side on a page that has them, on a wide screen. */
.cols { display: grid; gap: var(--s4); grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); align-items: start; }
.cols .card { margin: 0; max-width: none; }
/* The inspection's timeline (P3.6): the five steps of HOW_IT_FITS_TOGETHER,
   done / the one to do next / not yet, read from the trail. */
.timeline { list-style: none; margin: 0 0 var(--s5); padding: 0; display: grid; grid-template-columns: repeat(5, 1fr); gap: 2px; counter-reset: step; }
.timeline li { position: relative; padding: 10px 12px 10px 36px; background: #fff; border: 1px solid var(--line); font-size: var(--t13); min-height: 52px; }
.timeline li:first-child { border-radius: var(--radius) 0 0 var(--radius); }
.timeline li:last-child { border-radius: 0 var(--radius) var(--radius) 0; }
.timeline li::before {
  counter-increment: step; content: counter(step); position: absolute; left: 10px; top: 11px;
  width: 18px; height: 18px; border-radius: 50%; font-size: 11px; line-height: 18px; text-align: center;
  font-weight: 700; background: var(--pale); color: var(--ink3);
}
.timeline li.done::before { content: "\2713"; background: var(--navy); color: #fff; }
.timeline li.now { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.timeline li.now::before { background: var(--accent); color: #fff; }
.timeline li b { display: block; color: var(--ink); }
.timeline li.todo b, .timeline li.past b { color: var(--ink3); }
.timeline li small { display: block; color: var(--ink2); font-size: var(--t12); margin-top: 2px; }
@media (max-width: 900px) { .timeline { grid-template-columns: 1fr; } .timeline li, .timeline li:first-child, .timeline li:last-child { border-radius: 0; } }
.plain { list-style: none; margin: 0; padding: 0; }
.plain li { padding: 6px 0; border-top: 1px solid var(--line); font-size: var(--t14); }
.plain li:first-child { border-top: 0; }

fieldset { border: 1px solid var(--line); border-radius: var(--radius); padding: var(--s3) var(--s4); margin: 0 0 var(--s4); }
legend { padding: 0 6px; font-weight: 600; color: var(--navy); font-size: var(--t14); }

label { display: block; margin: 0 0 var(--s3); font-size: var(--t13); color: var(--ink2); }
input, select, textarea {
  display: block; width: 100%; margin-top: 4px; padding: 9px 10px;
  font: inherit; color: var(--ink); background: #fff;
  border: 1px solid var(--line2); border-radius: var(--radius-sm);
}
input[type="file"] { padding: 8px; background: var(--pale); }
input:focus, select:focus, textarea:focus, button:focus-visible, a:focus-visible {
  outline: 2px solid var(--navy); outline-offset: 1px;
}

.row { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; margin: 0 0 var(--s3); }
.row label { margin: 0; flex: 1 1 200px; }
.row.tight { margin: 0; gap: 6px; align-items: center; }
.row.tight input { width: auto; min-width: 150px; margin: 0; }
.actions { display: flex; flex-wrap: wrap; gap: var(--s3); align-items: center; margin: var(--s4) 0 0; }

.btn {
  display: inline-flex; align-items: center; gap: 8px; padding: 9px 16px; border: 0; border-radius: var(--radius-sm);
  background: var(--accent); color: #fff; font: inherit; font-weight: 600; line-height: 1.4;
  text-decoration: none; cursor: pointer; white-space: nowrap;
}
.btn:hover { background: var(--accent2); }
.btn:disabled { background: var(--line2); cursor: default; }
.btn.small { padding: 6px 11px; font-size: var(--t13); }
.btn.ghost { background: #fff; color: var(--navy); border: 1px solid var(--line2); }
.btn.ghost:hover { background: var(--pale); }
.btn.danger { background: #fff; color: var(--bad); border: 1px solid #fecaca; }
.btn.danger:hover { background: #fef2f2; }

.linky {
  background: none; border: 0; padding: 0; font: inherit;
  color: var(--ink2); text-decoration: underline; cursor: pointer;
}
.linky:hover { color: var(--navy); }

hr { border: 0; border-top: 1px solid var(--line); margin: var(--s4) 0; }

/* ---- filtering ---------------------------------------------------------- */

.tabs {
  display: flex; flex-wrap: wrap; gap: 4px;
  border-bottom: 1px solid var(--line); margin: 0 0 var(--s3);
}
.tab {
  padding: 8px 12px; text-decoration: none; color: var(--ink2);
  border-bottom: 2px solid transparent; font-size: var(--t14); white-space: nowrap; margin-bottom: -1px;
}
.tab:hover { color: var(--navy); }
.tab.on { color: var(--navy); border-bottom-color: var(--accent); font-weight: 600; }
.tally {
  display: inline-block; margin-left: 6px; padding: 1px 7px; border-radius: 999px;
  background: var(--pale); color: var(--ink3); font-size: var(--t12); font-weight: 600;
}
.tally.bad { background: #fee2e2; color: #991b1b; }
.tally.none { background: transparent; color: var(--line2); }

.filters {
  display: flex; flex-wrap: wrap; gap: var(--s2); align-items: center;
  margin: 0 0 var(--s4); padding: var(--s3); background: #fff;
  border: 1px solid var(--line); border-radius: var(--radius);
}
.filters input, .filters select { width: auto; margin: 0; padding: 7px 10px; font-size: var(--t14); }
.filters input[type="search"] { min-width: 240px; flex: 1 1 240px; }
.filters .linky { margin-left: 4px; }

/* The job code. Big, monospaced and spaced out, because it gets read down a
   phone to somebody standing at a panel. */
.codebox { margin: 0 0 6px; }
.codelabel {
  font-size: 11px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink2); font-weight: 700;
}
.code {
  font-family: var(--mono); font-size: 1.7rem; font-weight: 700;
  letter-spacing: .14em; color: var(--navy); margin: 2px 0 8px;
}
/* The two-step QR code: always black on white with its quiet zone, which is
   what a phone camera reads. */
.qr { margin: 4px 0 12px; line-height: 0; }
.qr svg { max-width: 100%; height: auto; border: 1px solid var(--line); border-radius: 6px; }
.qrkey summary { cursor: pointer; color: var(--navy); font-size: var(--t14); }
/* A two-step setup key is 32 characters: smaller, and allowed to wrap. */
#totpkey { font-size: 1.15rem; letter-spacing: .08em; overflow-wrap: anywhere; }
/* Recovery codes, to be written down or printed. */
.codes { font-size: 1.05rem; line-height: 1.7; background: var(--pale); padding: 10px 14px; margin: 0 0 12px; }

.count { margin: 0 0 var(--s2); }
/* Controls inside a table cell stay the size of their content, or a select
   stretches the column and the table stops reading as a table. */
.grid td .row.tight select,
.grid td .row.tight input { width: auto; min-width: 104px; max-width: 160px; }
.grid td .row.tight { gap: 5px; margin-top: 4px; }

label.tick { display: flex; gap: 9px; align-items: center; color: var(--ink); font-size: var(--t14); }

/* A tick to be on the job, a dot to lead it. */
.crew { display: grid; gap: 2px; margin: 0 0 10px; }
.crewrow {
  display: flex; gap: 14px; align-items: center; justify-content: space-between;
  padding: 5px 8px; border-radius: 7px;
}
.crewrow:hover { background: var(--pale); }
.crewrow label.tick { margin: 0; }
.crewrow label.tick.lead { color: var(--ink2); font-size: var(--t13); flex: 0 0 auto; }
fieldset.inner { margin: 0 0 12px; background: #fff; }
label.tick input { width: auto; margin: 0; }
.late { color: var(--bad); }
.soon { color: #b45309; }   /* amber that reads on white (4.5:1); --warn is for backgrounds */

/* ---- tables ------------------------------------------------------------- */

.grid {
  width: 100%; border-collapse: separate; border-spacing: 0; background: #fff;
  margin: 0 0 var(--s4); border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden;
}
.grid th, .grid td {
  text-align: left; padding: 10px 14px; border-bottom: 1px solid var(--line);
  vertical-align: top;
}
.grid tbody tr:last-child td { border-bottom: 0; }
.grid tbody tr:hover td { background: #fcfdfe; }
.grid thead th {
  position: sticky; top: 0; z-index: 1;
  font-size: var(--t12); letter-spacing: .06em; text-transform: uppercase; font-weight: 700;
  color: var(--ink3); background: var(--pale); border-bottom: 1px solid var(--line2);
  white-space: nowrap;
}
.grid thead th.sorted { color: var(--navy); }
.grid th .sort { color: inherit; text-decoration: none; display: inline-flex; gap: 4px; align-items: center; }
.grid th .sort:hover { color: var(--navy); }
.grid th .mark { font-size: 9px; }
.grid td small { display: block; color: var(--ink2); font-size: var(--t13); }
.grid .num, .grid th.num { text-align: right; font-variant-numeric: tabular-nums; }
.grid .num .sort { justify-content: flex-end; }
.grid .date, .grid th.date { white-space: nowrap; font-variant-numeric: tabular-nums; }
.grid.tight th, .grid.tight td { padding: 6px 10px; font-size: var(--t13); }
.grid a { color: var(--navy); }
/* A link in a cell is a target at least 24px tall (WCAG 2.5.8), without the
   row growing much: a name and the small link under it stack. */
.grid td a:not(.btn) { display: inline-block; padding: 3.5px 0; }
/* A suspended person's row stands down - by colour, not opacity, so it still
   reads (and the menu stays as it is: Restore lives there). */
.grid tr.off td:not(.menucell), .grid tr.off td:not(.menucell) b { color: var(--ink3); }
.grid tr.off td:not(.menucell) small { color: var(--ink2); }

/* Above and below a table: the count and the pages. */
.pager {
  display: flex; flex-wrap: wrap; gap: var(--s3); align-items: center;
  margin: 0 0 var(--s4); font-size: var(--t13);
}
.pager .perpage { margin-left: auto; color: var(--ink2); }
.pager .perpage a { color: var(--ink2); margin-left: 4px; }
.pager .perpage b { color: var(--navy); margin-left: 4px; }
.actions.pager { margin-top: 0; }

.facts { display: grid; grid-template-columns: max-content 1fr; gap: 6px 16px; margin: 0 0 var(--s4); }
.facts dt { color: var(--ink2); font-size: var(--t12); text-transform: uppercase; letter-spacing: .06em; padding-top: 2px; }
.facts dd { margin: 0; }

/* An empty list: one sentence and the thing to do. */
.empty {
  background: #fff; border: 1px dashed var(--line2); border-radius: var(--radius);
  padding: var(--s5); margin: 0 0 var(--s4); color: var(--ink2);
}
.empty p { margin: 0; }
.empty .actions { margin-top: var(--s3); }

/* The Overview's tiles: one number each, the whole tile a link into the list
   it counts. By office when there is more than one. */
.tiles { display: grid; gap: var(--s4); grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); margin: 0 0 var(--s5); }
.tile {
  display: block; background: #fff; border: 1px solid var(--line); border-radius: var(--radius);
  padding: var(--s4) var(--s5); text-decoration: none; color: var(--ink);
}
.tile:hover { border-color: var(--line2); box-shadow: var(--shadow); }
.tile .n { display: block; font-size: var(--t28); font-weight: 700; color: var(--navy); line-height: 1.1; font-variant-numeric: tabular-nums; }
.tile .n.bad { color: var(--bad); }
.tile .n.zero { color: var(--line2); }
.tile .l { display: block; margin-top: 4px; font-size: var(--t13); color: var(--ink2); font-weight: 600; }
.tile .s { display: block; font-size: var(--t12); color: var(--ink2); }
/* Five tiles in one row where they fit (the operator console, P3.5). */
.tiles.five { grid-template-columns: repeat(auto-fit, minmax(176px, 1fr)); }
.byoffice { margin: 0 0 var(--s5); }
.byoffice h2 { margin-bottom: var(--s2); }

/* The "how an inspection flows" strip: three lines, dismissable. */
.strip {
  display: flex; gap: var(--s4); align-items: flex-start; flex-wrap: wrap;
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius);
  padding: var(--s4) var(--s5); margin: 0 0 var(--s5);
}
.strip ol { margin: 0; padding-left: 20px; flex: 1 1 420px; }
.strip ol li { margin: 0 0 4px; }
.strip ol li:last-child { margin: 0; }
.strip form { flex: 0 0 auto; }

/* The ⋯ on a row: everything that can be done to it, out of sight until asked
   for. It opens a window in the middle of the screen (ShootC, 2026-09-24: the
   old drop-down had to be scrolled and closed from the same ⋯). */
.menucell { width: 1%; text-align: right; white-space: nowrap; }
.menubtn {
  display: inline-block; cursor: pointer; padding: 2px 10px; border: 1px solid var(--line2);
  border-radius: 6px; color: var(--ink2); font-weight: 700; letter-spacing: 1px; background: #fff;
  font: inherit; line-height: 1.5;
}
.menubtn:hover { background: var(--pale); color: var(--navy); }

/* A window: one job at a time, Save or Close. The browser's own <dialog>, so
   Esc closes it and the page behind cannot be clicked by accident. */
dialog.win {
  width: min(520px, calc(100vw - 32px)); max-height: calc(100vh - 48px); padding: 0;
  border: 1px solid var(--line2); border-radius: var(--radius); background: #fff; color: var(--ink);
  box-shadow: 0 18px 50px rgba(15, 23, 42, .25); text-align: left; white-space: normal;
}
dialog.win::backdrop { background: rgba(15, 23, 42, .38); }
.winhead {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 14px 18px; border-bottom: 1px solid var(--line);
}
.winhead h2 { margin: 0; font-size: var(--t16); }
.winx { background: none; border: 0; font-size: 1.5rem; line-height: 1; cursor: pointer; color: var(--ink2); padding: 0 4px; }
.winx:hover { color: var(--navy); }
.winbody { padding: 14px 18px 16px; }
.winbody label { margin: 0 0 10px; }
.winbody input:not([type="checkbox"]):not([type="radio"]), .winbody select, .winbody textarea { width: 100%; }
.winbody .meta { margin: 0 0 10px; }
.winfoot { display: flex; gap: 8px; justify-content: flex-end; margin-top: 14px; }
/* The ⋯ window's list of what can be done. */
.actions-list { display: flex; flex-direction: column; gap: 6px; }
.actions-list button {
  text-align: left; padding: 9px 12px; border: 1px solid var(--line); border-radius: 8px;
  background: #fff; cursor: pointer; font: inherit; color: var(--navy);
}
.actions-list button:hover { background: var(--pale); }
.actions-list button.danger { color: var(--accent); }
.actions-list small { display: block; color: var(--ink2); font-size: var(--t13); }
/* A button that opens a window, sitting where the open form used to. */
.opens { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 0 0 var(--s4); }
.opens .filters { margin: 0; padding: 0; border: 0; background: none; }
.former summary { cursor: pointer; }
.former table { margin-top: 10px; }

.legend { margin: 0 0 var(--s4); font-size: var(--t14); }
.legend summary { cursor: pointer; color: var(--ink2); }
.legend dl { display: grid; grid-template-columns: max-content 1fr; gap: 3px 14px; margin: 10px 0 0; }
.legend dt { font-family: var(--mono); color: var(--navy); }
.legend dd { margin: 0; color: var(--ink2); }

.preview { margin-top: 12px; padding: 12px; background: var(--pale); border-radius: var(--radius); }
.preview .grid { margin: 0; }

.chip {
  display: inline-block; padding: 2px 9px; border-radius: 999px;
  font-size: var(--t12); font-weight: 600; letter-spacing: .02em; white-space: nowrap;
}
.chip.grey  { background: var(--pale);  color: var(--ink3); }
.chip.blue  { background: #e0e7ff;      color: #3730a3; }
.chip.amber { background: #fef3c7;      color: #92400e; }
.chip.green { background: #dcfce7;      color: #14532d; }

ol { padding-left: 20px; }
ol li { margin: 0 0 6px; }

.logobox { display: flex; gap: 14px; align-items: center; margin: 0 0 12px; }
.logoprev {
  max-height: 60px; max-width: 220px; object-fit: contain;
  border: 1px solid var(--line); border-radius: 8px; padding: 6px; background: #fff;
}
.logometa { font-size: var(--t13); color: var(--ink2); }
.logonone {
  margin: 0 0 12px; padding: 12px; border: 1px dashed var(--line2);
  border-radius: 8px; color: var(--ink2); font-size: var(--t13);
}
.problemtext { color: var(--bad); }
.tagline { font-style: italic; }

/* ---- the front door (sign in, the code, an invitation, setup) ------------- */

body.auth {
  display: grid; grid-template-columns: minmax(300px, 2fr) minmax(0, 3fr); min-height: 100vh;
  background: #fff;
}
.authside {
  background: var(--navy); color: var(--on-dark);
  padding: var(--s7) var(--s6); display: flex; flex-direction: column; gap: var(--s4);
}
.authname { margin: var(--s7) 0 0; font-size: var(--t28); font-weight: 700; color: #fff; letter-spacing: -.01em; }
.authline { margin: 0; color: var(--on-dark2); font-size: var(--t16); max-width: 32em; line-height: 1.55; }
.authmain {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: var(--s7) var(--s6); gap: var(--s5);
}
.authcard { width: min(440px, 100%); }
.authcard h1 { margin-bottom: var(--s4); }
.authcard .card { padding: 0; border: 0; margin: 0; }
.authcard .card.narrow { max-width: none; }
.authcard .cologo { max-height: 60px; max-width: 240px; object-fit: contain; display: block; margin: 0 0 var(--s4); }
.authcard .btn { width: 100%; justify-content: center; padding: 11px 16px; }
.authfoot { color: var(--ink2); font-size: var(--t13); }
.authfoot a { color: var(--ink2); }

/* Signed out and not a sign-in page: a 404, an error. */
body.bare .content { max-width: 720px; margin: 0 auto; padding-top: var(--s7); }
body.bare .brand { margin-bottom: var(--s5); }
body.bare .cologo { max-height: 40px; display: block; margin: 0 0 var(--s4); }

/* ---- narrower screens --------------------------------------------------- */

/* 800-1200: the sidebar keeps its icons only. */
@media (max-width: 1199px) {
  body.shell { grid-template-columns: var(--side-narrow) minmax(0, 1fr); }
  .side .brand .word, .co, .offices, .who, .sidelabel { display: none; }
  .sidehead { justify-content: center; padding: var(--s4) 0 var(--s3); }
  .nav, .me { padding-left: var(--s2); padding-right: var(--s2); }
  .nav a, .me a, .signout { font-size: 0; justify-content: center; padding: 10px 0; gap: 0; }
  .nav a .ico, .me a .ico, .signout .ico { width: 22px; height: 22px; }
  .content { padding-left: var(--s5); padding-right: var(--s5); }
}

/* Under 800: a top bar with a menu button; the nav opens under it. */
@media (max-width: 799px) {
  body.shell { display: block; }
  .side { position: static; height: auto; overflow: visible; }
  .sidehead { justify-content: space-between; padding: var(--s3) var(--s4); }
  .side .brand .word { display: inline; }
  .navbtn {
    display: inline-flex; align-items: center; justify-content: center;
    background: none; border: 1px solid rgb(255 255 255 / .25); color: #fff;
    border-radius: 6px; padding: 5px 7px; cursor: pointer;
  }
  .sidebody { display: none; padding-bottom: var(--s3); }
  body.menu-open .sidebody { display: flex; }
  .co, .offices, .who, .sidelabel { display: block; }
  .co { padding-top: var(--s2); }
  .nav a, .me a, .signout { font-size: var(--t14); justify-content: flex-start; padding: 9px 10px; gap: 10px; }
  .nav a .ico, .me a .ico, .signout .ico { width: 20px; height: 20px; }
  .me { margin-top: var(--s3); }
  .content { padding: var(--s4) var(--s4) var(--s7); }
  .phead { flex-direction: column; align-items: flex-start; }
  h1 { font-size: var(--t20); }
  .facts { grid-template-columns: 1fr; gap: 2px; }
  .facts dd { margin: 0 0 8px; }

  body.auth { grid-template-columns: 1fr; }
  .authside { padding: var(--s5) var(--s4); }
  .authname { margin-top: var(--s3); font-size: var(--t20); }
  .authmain { padding: var(--s5) var(--s4); }
}

/* On a phone the columns that are only context stand down and the rows
   become cards, so "My inspections" still reads next to a van. */
@media (max-width: 640px) {
  .grid, .grid tbody, .grid tr, .grid td { display: block; width: 100%; }
  .grid thead { display: none; }
  .grid { border: 0; background: none; overflow: visible; }
  .grid tr {
    border: 1px solid var(--line); border-radius: var(--radius); background: #fff;
    margin: 0 0 10px; padding: 4px 0;
  }
  .grid td { border: 0; padding: 5px 12px; }
  .grid .num, .grid .date { text-align: left; }

  /* The head row is gone, so each value carries its own label. */
  .grid td[data-label]::before {
    content: attr(data-label);
    display: inline-block;
    min-width: 86px;
    color: var(--ink2);
    font-size: var(--t12);
    letter-spacing: .08em;
    text-transform: uppercase;
  }

  .row.tight input { width: 100%; min-width: 0; }
  .filters { gap: 6px; }
  .filters input, .filters select, .filters button { width: 100%; }
  .filters input[type="search"] { min-width: 0; }
  .tabs { gap: 0; }
  .tab { padding: 8px 10px; font-size: var(--t13); }
  .btn { padding: 12px 16px; }          /* a thumb, not a mouse */
  .menucell { width: auto; text-align: left; }
  .tiles { grid-template-columns: 1fr 1fr; }
}

/* ---- print ---------------------------------------------------------------- */
/* (View report is its own sandboxed page with the report's own print styles;
   this is only for a list somebody prints from the portal.) */
@media print {
  .side, .skip, .pact, .filters, .pager, .tabs { display: none !important; }
  body.shell { display: block; }
  .content { max-width: none; padding: 0; }
  .grid { border: 0; }
  .grid thead th { position: static; }
}

/* ---- the calendar (P3.9) ---------------------------------------------------- */
.calnav { display: flex; align-items: center; gap: var(--s2); margin: var(--s3) 0; }
.calnav .callabel { margin: 0 0 0 var(--s3); font-size: var(--t20); }
.calwrap { display: grid; gap: var(--s4); grid-template-columns: 1fr; align-items: start; margin: var(--s3) 0; }
.calwrap.with-techs { grid-template-columns: 1fr 200px; }
.cal { width: 100%; border-collapse: separate; border-spacing: 0; table-layout: fixed; background: #fff; border: 1px solid var(--line); border-radius: var(--radius); }
.cal th { background: var(--pale); color: var(--ink2); font-size: var(--t12); text-transform: uppercase; letter-spacing: .06em; padding: 6px 8px; text-align: left; border-bottom: 1px solid var(--line); }
.cal td { vertical-align: top; border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); padding: 4px 6px 6px; }
.cal tr td:last-child { border-right: 0; }
.cal tbody tr:last-child td { border-bottom: 0; }
.cal.month td { height: 112px; }
.cal.week td { height: 60vh; min-height: 240px; }
.cal td.other { background: #fafbfc; }
.cal td.other .dnum span { color: var(--ink3); }
.cal td.today { background: #fffbeb; }
.cal td.today .dnum span { color: var(--accent); font-weight: 700; }
.cal td.over { outline: 2px solid var(--accent); outline-offset: -2px; background: #fff5f5; }
.dnum { display: flex; justify-content: space-between; align-items: center; font-size: var(--t13); color: var(--ink); margin-bottom: 4px; }
.dnum .plus { color: var(--ink2); text-decoration: none; font-weight: 700; padding: 0 6px; border-radius: 4px; line-height: 1.4; }
.dnum .plus:hover { background: var(--pale); color: var(--navy); }
.cal.week .dnum { font-weight: 600; }
.part .plabel { font-size: 10px; text-transform: uppercase; letter-spacing: .06em; color: var(--ink2); margin: 6px 0 2px; }
.ev { display: block; width: 100%; text-align: left; font: inherit; font-size: var(--t12); line-height: 1.25; border: 1px solid var(--line2); border-left-width: 4px; border-radius: 5px; background: #fff; color: var(--ink); padding: 3px 6px; margin: 0 0 3px; cursor: pointer; position: relative; }
.ev:hover { box-shadow: var(--shadow); }
.ev .site { display: block; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ev .addr, .ev .svc, .ev .crew { display: block; color: var(--ink2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cal.month .ev .svc, .cal.board .ev .svc { display: inline; }
.cal.month .ev .crew, .cal.board .ev .crew { display: inline; margin-left: 4px; }
.ev .crew .lead { text-decoration: underline; }
.ev .crew.none { color: var(--warn); }
.ev .win-tag { float: right; font-size: 10px; font-weight: 700; color: var(--ink2); margin-left: 4px; }
.ev.s-draft { border-left-color: var(--line2); }
.ev.s-assigned { border-left-color: var(--navy); }
.ev.s-picked_up { border-left-color: var(--warn); }
.ev.s-complete { border-left-color: var(--ok); }
.ev.late { outline: 1px solid var(--bad); outline-offset: -1px; }
.ev.dragging { opacity: .5; }
.ev.busy { opacity: .6; cursor: wait; }
.ev.over { outline: 2px solid var(--accent); outline-offset: -2px; }
.ev .mark { display: inline-block; font-size: 10px; border-radius: 3px; padding: 0 4px; margin-top: 2px; }
.ev .dblmark { background: #fef3c7; color: #92400e; }
.ev .aftermark { background: #fee2e2; color: #991b1b; }
.ev.ghost { border-style: dashed; border-left-width: 1px; background: transparent; color: var(--ink2); text-decoration: none; }
.ev.ghost:hover { color: var(--navy); border-color: var(--navy); box-shadow: none; }
.more { font: inherit; font-size: var(--t12); background: none; border: 0; color: var(--navy); cursor: pointer; padding: 2px 0; }
.legend .ev { display: inline-block; width: auto; margin: 0 6px 0 0; cursor: default; padding: 1px 6px; }
.legend .ev:hover { box-shadow: none; }
.techlist { background: #fff; border: 1px solid var(--line); border-radius: var(--radius); padding: var(--s3); }
.techlist ul { list-style: none; margin: 0; padding: 0; }
.techlist li { padding: 6px 8px; border: 1px solid var(--line); border-radius: 5px; margin: 0 0 4px; cursor: grab; font-size: var(--t13); background: var(--pale); }
.techlist li.dragging { opacity: .5; }
.cal.board th[scope="row"] { background: #fff; width: 150px; font-size: var(--t13); text-transform: none; letter-spacing: 0; color: var(--ink); font-weight: 600; border-right: 1px solid var(--line); }
.cal.board th[scope="row"] small { display: block; color: var(--ink2); font-weight: 400; font-size: var(--t12); }
.cal.board td { height: 64px; }
.cal.board tr.unassigned th, .cal.board tr.unassigned td { background: #fffbeb; }
.crewlist { list-style: none; margin: 0 0 var(--s3); padding: 0; }
.crewlist li { display: flex; gap: var(--s3); align-items: center; padding: 4px 0; border-bottom: 1px solid var(--line); }
.crewlist .crewacts { margin-left: auto; display: flex; gap: var(--s3); }
label.inline { display: inline-flex; gap: 6px; align-items: center; margin: 0 var(--s2) 0 0; }
label.inline input, label.inline select { width: auto; margin: 0; }
.daylist .ev { cursor: default; }
@media (max-width: 1100px) { .calwrap.with-techs { grid-template-columns: 1fr; } }
@media print {
  .side, .pact, .filters, .tabs, .calnav .btn, .techlist, .legend, .dnum .plus, .account, .strip, .navbtn { display: none !important; }
  .content { padding: 0; max-width: none; }
  .cal.week td { height: auto; min-height: 120px; }
  .ev { box-shadow: none; }
}
