/*
  RestoCare, app-specific layer.

  The chrome, buttons, cards, tables, forms, search, chips, badges, metrics,
  modal, toast and the work-order board all come from the CANONICAL Resto OS
  design system, served from documents/assets and linked BEFORE this file in
  this fixed order:
      rg-theme.css        brand tokens (color, type, radius, light/dark)
      rg-components.css   app chrome (shell, controls, forms, feedback)
      resto-os-applied.css the locked Apple direction + kanban + slide-over

  This file therefore defines ONLY the things the kit does not have, all rebased
  on the kit's CSS variables so nothing goes off-palette. It must never redefine
  a kit token (--radius, --radius-sm, --ease, the palette) or fork a colour. The
  single interactive accent is navy (var(--navy) / var(--accent)); there is no
  second accent.

  App-specific bits kept here: the nav list wrapper, the page-head right side,
  a compatibility shim that maps the app's old .badge/.b-* and .kpi to the kit
  look, the filters/toolbar, the activity timeline, attachments, the PM calendar,
  the notification bell, the work-order chat, the permission matrix, the camera
  overlay, the login/setup pages, Tom Select skinning, and the mobile bottom bar.
*/

em, i { font-family: var(--serif, "Spectral", Georgia, serif); font-style: italic; }

/* ---------------- List pager ----------------
   Prev / page-count / next, centered under a paginated list. Disabled controls
   read as quiet, non-interactive. */
.pager { display: flex; align-items: center; justify-content: center; gap: 14px; margin-top: 16px; }
.pager-info { font-size: 13px; color: var(--ink-strong); font-weight: 600; font-variant-numeric: tabular-nums; }
.pager .is-disabled { opacity: 0.45; pointer-events: none; cursor: default; }

/* The hidden attribute must always win, even over flex/inline-flex display rules. */
[hidden] { display: none !important; }

/* Utility text helpers used across templates. */
.muted, td .muted { color: var(--ink-dim); }
td .strong, .strong { font-weight: 600; color: var(--ink-strong); }
.hint { color: var(--ink-dim); font-size: 12px; margin: 4px 0 0; }
.tabular { font-variant-numeric: tabular-nums; }
/* The " FC" suffix on a CDF cost amount is only needed on the mobile reflow,
   where there is no column header. On desktop the CDF column header says it. */
.cdf-unit { display: none; }
.mobile-only { display: none; }
.txt-short { display: none; }
/* The mobile "More" tab button and the More sheet exist only on the phone
   bottom bar; the desktop sidebar never shows them. */
.mob-more-btn { display: none; }
.more-sheet { display: none; }

/* ---------------- Sidebar nav list + user logout ----------------
   The kit styles .app-sidebar, .app-brand, .nav-item and .sidebar-user. We only
   need the nav list wrapper to grow and the logout icon button to read on the
   glass rail. */
.sidebar-nav { display: flex; flex-direction: column; gap: 2px; padding: 6px 0; }
.sidebar-user .who { flex: 1; min-width: 0; }
.sidebar-user .nav-item.btn-icon { width: 34px; height: 34px; padding: 0; flex: none; }

/* Brand lockup: the real RestoCare logo SVG, displayed as an img so the
   sidebar always shows the exact brand asset. Four variants cover the two
   theme modes (light/dark) and the two sidebar states (expanded/collapsed).
   The selection is done in CSS using data-theme and .nav-collapsed on <html>.
   On mobile the brand row is hidden entirely (only the bottom tab bar shows). */
.app-brand { justify-content: space-between; }
.app-brand .brand-link { display: flex; align-items: center; min-width: 0; text-decoration: none; }
.app-brand .brand-link:hover { text-decoration: none; }
/* All four logo variants start hidden; only the right one is shown. */
.bl { display: none; }
/* Expanded sidebar, light mode: full horizontal logo */
html:not(.nav-collapsed)[data-theme="light"] .bl.bl-full.bl-light { display: block; height: 27px; width: auto; }
/* Expanded sidebar, dark mode: reversed full logo */
html:not(.nav-collapsed)[data-theme="dark"]  .bl.bl-full.bl-dark  { display: block; height: 27px; width: auto; }
/* Collapsed sidebar, light mode: symbol mark only */
html.nav-collapsed[data-theme="light"] .bl.bl-sym.bl-light { display: block; height: 28px; width: 28px; }
/* Collapsed sidebar, dark mode: reversed symbol mark */
html.nav-collapsed[data-theme="dark"]  .bl.bl-sym.bl-dark  { display: block; height: 28px; width: 28px; }
/* Collapse toggle: a quiet icon button on the brand row. */
.sidebar-toggle {
  flex: none; display: grid; place-items: center; width: 30px; height: 30px;
  border: none; background: transparent; color: var(--sidebar-ink-dim);
  border-radius: 8px; cursor: pointer; padding: 0;
  transition: background .18s var(--ease), color .18s var(--ease);
}
.sidebar-toggle:hover { background: var(--sidebar-hover-bg); color: var(--sidebar-ink-strong); }
.sidebar-toggle .ico { width: 18px; height: 18px; transition: transform .42s cubic-bezier(.32,.72,0,1); }

/* ---- Collapsed rail: icons only. State lives on <html>.nav-collapsed so it is
   applied before paint (no flash); the kit animates the rail width + label fade.
   Labels release their width (so icons centre) while opacity eases them out. */
html.nav-collapsed .app-shell { grid-template-columns: var(--sidebar-w-collapsed) 1fr; }
html.nav-collapsed .app-sidebar { padding-left: 8px; padding-right: 8px; }
html.nav-collapsed .app-brand { flex-direction: column; gap: 10px; justify-content: center; }
html.nav-collapsed .brand-link { justify-content: center; }
html.nav-collapsed .nav-item .txt,
html.nav-collapsed .nav-item .txt-short,
html.nav-collapsed .sidebar-user .who {
  opacity: 0; width: 0; overflow: hidden; pointer-events: none;
}
html.nav-collapsed .nav-item { justify-content: center; gap: 0; padding-left: 0; padding-right: 0; }
html.nav-collapsed .nav-item .count { display: none; }
/* Collapsed rail is only 72px, so the avatar + logout cannot sit side by side
   (they overflow and the logout gets clipped against the edge). Stack them
   vertically and centre, so the footer reads cleanly in the narrow rail. */
html.nav-collapsed .sidebar-user {
  flex-direction: column; align-items: center; justify-content: center;
  gap: 8px; padding-left: 0; padding-right: 0;
}
html.nav-collapsed .sidebar-user .nav-item.btn-icon { margin-left: 0 !important; }
html.nav-collapsed .sidebar-toggle .ico { transform: rotate(180deg); }

/* ---------------- Page head right side ----------------
   The kit defines .page-head and .page-head .sub; the right side (primary action
   rightmost, page controls left of it) is app glue. */
.page-head .rhs { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: flex-end; }
.page-head .rhs:empty { display: none; }

/* ---------------- Card headers with bare text ----------------
   The kit styles .card-head h3, but this app puts the title as plain text (often
   beside an action button) directly in .card-head. Give the head itself the
   heading treatment so those read like the kit h3; buttons inside reset their
   own font weight/size, so they are unaffected. */
.card-head { font-size: 17px; font-weight: 700; letter-spacing: -0.01em; color: var(--ink-strong); justify-content: space-between; }
.card-head .btn { font-size: 14px; font-weight: 600; letter-spacing: 0; }
.card-head .btn-sm { font-size: 13px; }

/* ---------------- Breadcrumb (in-content, deep pages) ---------------- */
.breadcrumb { font-size: 13px; color: var(--ink-dim); margin-bottom: 14px; }
.breadcrumb a { color: var(--ink-dim); }
.breadcrumb a:hover { color: var(--accent-ink); }

/* ---------------- Flash banner ---------------- */
.flash {
  display: flex; align-items: center; gap: 9px;
  padding: 12px 16px; border-radius: var(--radius-md);
  margin-bottom: 18px; font-size: 14px; font-weight: 600;
  background: color-mix(in srgb, var(--green) 8%, transparent);
  color: var(--green);
  border: 1px solid color-mix(in srgb, var(--green) 40%, transparent);
}
.flash::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: var(--green); flex: none;
}
/* Error / blocked actions: same banner, red instead of green. */
.flash.flash-error {
  background: color-mix(in srgb, var(--red) 8%, transparent);
  color: var(--red);
  border-color: color-mix(in srgb, var(--red) 40%, transparent);
}
.flash.flash-error::before { background: var(--red); }

/* ---------------- KPI / metric grids (map to the kit metric look) ----------------
   Templates use .kpi-grid/.kpi and .metric-row/.metric. We render them as flat
   hairline metric cards identical to the kit's .rg-metric. */
.kpi-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 14px; margin-bottom: 22px; }
/* Clickable KPI (e.g. pending requests -> inbox). */
a.kpi { text-decoration: none; transition: border-color .15s var(--ease), box-shadow .15s var(--ease); }
a.kpi:hover { border-color: var(--accent-line); box-shadow: 0 1px 3px rgba(0,0,0,0.06); text-decoration: none; }
.metric-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-bottom: 18px; }
.kpi, .metric {
  background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--radius); padding: 18px 20px;
}
.kpi .label, .metric .label {
  color: var(--ink-dim); font-size: 12px; font-weight: 600;
  letter-spacing: 0.02em; margin-bottom: 11px;
}
.kpi .value, .metric .value {
  font-size: 32px; font-weight: 900; letter-spacing: -0.02em; line-height: 1;
  color: var(--ink-strong); font-variant-numeric: tabular-nums;
}
.kpi .value.warn, .metric .value.warn { color: var(--amber); }
.kpi .value.bad, .metric .value.bad { color: var(--red); }

.dash-cols { display: grid; grid-template-columns: 1.3fr 1fr; gap: 18px; }

/* ---------------- Table wrapper as a flat kit card ----------------
   Templates wrap ledgers in .table-wrap. Render it like a kit card so the row
   ledger sits in flat hairline chrome (table.data itself comes from the kit). */
.table-wrap {
  background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--radius); overflow: hidden;
}
/* Status / threshold row tint inside a ledger. */
table.data tr.row-low { background: var(--sev-crit-tint); }
table.data tr.row-low:hover { background: var(--sev-crit-tint); }
/* Totals row. */
table.data tfoot td { border-top: 1px solid var(--ink); font-weight: 700; padding-top: 14px; }

/* ---------------- Badges (compatibility shim -> kit .rg-badge look) ----------------
   Templates and _macros emit .badge .b-* with a leading .d dot. We render them
   as the kit's outlined pill badge. Navy is the only accent, so .b-blue (used for
   non-status states like assigned / in_progress / medium) reads as a neutral ink
   badge, not a second accent colour. */
.badge {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11.5px; font-weight: 600; line-height: 1;
  padding: 4px 10px; border-radius: 999px;
  border: 1px solid var(--hairline-2); color: var(--ink-dim);
  background: transparent; white-space: nowrap;
}
.badge .d { width: 7px; height: 7px; border-radius: 50%; flex: none; background: var(--ink-faint); }
.b-green { color: var(--green); border-color: color-mix(in srgb, var(--green) 45%, transparent); }
.b-amber { color: var(--amber); border-color: color-mix(in srgb, var(--amber) 45%, transparent); }
.b-red   { color: var(--red);   border-color: color-mix(in srgb, var(--red) 45%, transparent); }
.b-blue, .b-neutral { color: var(--ink-dim); border-color: var(--hairline-2); }
.b-green .d { background: var(--green); }
.b-amber .d { background: var(--amber); }
.b-red .d   { background: var(--red); }
.b-blue .d  { background: var(--accent); }
.b-neutral .d { background: var(--ink-faint); }

/* ---------------- Toolbar + filters ----------------
   Search lives in the content toolbar (never the topbar corner). The kit styles
   buttons/inputs; this is just the row layout + native select skin to match the
   kit .select. */
.toolbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }
/* All filters sit on one aligned row: the search box grows to fill, the selects
   keep their natural width beside it. They share one height so they line up. */
.filters { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; width: 100%; }

/* Native search box + selects, skinned to the kit input/search (kit only styles
   .input/.select classes, these use bare elements, so map them here). */
.filters .search-box, .filters select {
  font-family: inherit; font-size: 14px; color: var(--ink-strong);
  background: var(--surface); border: 1px solid var(--hairline-2);
  border-radius: var(--radius-md); height: var(--ctrl-h, 44px); padding: 0 14px;
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.filters .search-box { flex: 1 1 240px; min-width: 200px; max-width: 380px; border-radius: 999px; padding-left: 16px; }
.filters .search-box::placeholder { color: var(--ink-faint); }
.filters select { flex: 0 0 auto; }
/* TomSelect (.searchable) renders a wrapper div instead of the native select and
   defaults to full width, which would push the other filters onto a second line.
   Pin it to its content so every filter stays on one aligned row at one height. */
.filters .ts-wrapper { flex: 0 0 auto; width: auto; min-width: 170px; }
.filters .ts-wrapper.full { width: auto; }
.filters .ts-wrapper .ts-control { min-height: var(--ctrl-h, 44px); border-radius: var(--radius-md); }
.filters select {
  -webkit-appearance: none; appearance: none; padding-right: 34px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%235a6b7a' stroke-width='2.5'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center;
}
.filters .search-box:hover, .filters select:hover { border-color: var(--accent-line); }
.filters .search-box:focus, .filters select:focus {
  outline: none; border-color: var(--accent); box-shadow: var(--focus-ring);
}

/* Sortable column headers: the whole header is a quiet link with an arrow on the
   active column. */
th.th-sort { padding: 0; }
th.th-sort a { display: flex; align-items: center; gap: 5px; padding: 11px 16px; color: inherit; text-decoration: none; white-space: nowrap; }
th.th-sort.num a { justify-content: flex-end; }
th.th-sort a:hover { color: var(--accent-ink); }
th.th-sort .sort-ind { font-size: 9px; line-height: 1; color: var(--accent-ink); }
th.th-sorted a { color: var(--ink-strong); }

/* Mobile-only sort control (column-header sorting is hidden when the table
   reflows into cards). */
.sort-mobile { display: none; align-items: center; gap: 6px; }
.sort-mobile-label { font-size: 11px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-faint); }
.sort-mobile select {
  font-family: inherit; font-size: 14px; color: var(--ink-strong);
  background: var(--surface); border: 1px solid var(--hairline-2);
  border-radius: var(--radius-md); height: 38px; padding: 0 12px;
}

/* ---------------- Native form controls inside .field ----------------
   The kit styles .input/.select/.textarea classes. The app's forms use bare
   <input>/<select>/<textarea> inside .field, so skin those elements to the kit
   control look. (.field layout itself comes from the kit.) */
.field input, .field select, .field textarea {
  width: 100%; max-width: 100%; font-family: inherit; font-size: 14px;
  color: var(--ink-strong); background: var(--surface);
  border: 1px solid var(--hairline-2); border-radius: var(--radius-md);
  height: var(--ctrl-h, 44px); padding: 0 13px;
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.field textarea { height: auto; min-height: 90px; padding: 11px 13px; line-height: 1.5; resize: vertical; }
.field input::placeholder, .field textarea::placeholder { color: var(--ink-faint); }
.field input:hover, .field select:hover, .field textarea:hover { border-color: var(--accent-line); }
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-color: var(--accent); box-shadow: var(--focus-ring); }
.field select {
  -webkit-appearance: none; appearance: none; padding-right: 36px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%235a6b7a' stroke-width='2.5'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 13px center;
}
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px 20px; }
.field.full { grid-column: 1 / -1; }
.form-actions { display: flex; gap: 10px; margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--hairline); }
.subform { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
.subform .field { flex: 1; min-width: 120px; margin-bottom: 0; }
.subform .field.narrow { flex: 0 0 90px; }

/* ---------------- Detail layout ---------------- */
.detail-grid { display: grid; grid-template-columns: 1.4fr 1fr; gap: 18px; align-items: start; }
.kv { display: grid; grid-template-columns: 150px 1fr; gap: 11px 16px; font-size: 14px; margin: 0; }
.kv dt { color: var(--ink-dim); font-weight: 500; }
.kv dd { margin: 0; font-weight: 600; color: var(--ink-strong); }

/* Collapsible card: the head becomes a toggle button, the body shows when .open. */
.card.collapsible > .card-toggle { display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%; background: none; border: 0; cursor: pointer; font: inherit; color: inherit; text-align: left; }
.card.collapsible:not(.open) > .card-body { display: none; }
.card.collapsible > .card-toggle .chev { flex: none; opacity: .55; transition: transform .2s var(--ease); }
.card.collapsible.open > .card-toggle .chev { transform: rotate(180deg); }

/* ---------------- Spend-by-site mini bars ---------------- */
.bar-row { display: grid; grid-template-columns: 130px 1fr 70px; align-items: center; gap: 12px; margin-bottom: 11px; }
.bar-row .site-name { font-size: 13px; font-weight: 500; }
.bar-track { background: var(--surface-2); border-radius: 100px; height: 8px; overflow: hidden; }
.bar-fill { background: var(--accent); height: 100%; border-radius: 100px; }
.bar-row .amt { text-align: right; font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; }

/* ---------------- Reports grid + charts ---------------- */
.report-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.report-grid .card.span-2 { grid-column: 1 / -1; }
.chart-box { position: relative; height: 260px; }

/* ---------------- Error page ---------------- */
.error-wrap { padding: 80px 28px; text-align: center; }
.error-wrap .code { font-size: 60px; font-weight: 900; color: var(--ink-strong); letter-spacing: -0.03em; }
.error-wrap p { color: var(--ink-dim); margin: 8px 0 22px; }

/* ---------------- Activity timeline ---------------- */
.timeline { list-style: none; margin: 0; padding: 0; position: relative; }
.timeline::before { content: ""; position: absolute; left: 7px; top: 4px; bottom: 4px; width: 2px; background: var(--hairline-2); }
.tl-item { position: relative; padding: 0 0 16px 26px; }
.tl-item:last-child { padding-bottom: 0; }
.tl-dot { position: absolute; left: 1px; top: 3px; width: 14px; height: 14px; border-radius: 50%; background: var(--surface); border: 2px solid var(--accent); }
.tl-item.comment .tl-dot { border-color: var(--ice); background: var(--ice); }
.tl-head { font-size: 12.5px; color: var(--ink-dim); }
.tl-head .who { font-weight: 600; color: var(--ink-strong); }
.tl-action { font-weight: 600; font-size: 13.5px; margin-top: 1px; color: var(--ink-strong); }
.tl-detail { color: var(--ink-dim); font-size: 13px; margin-top: 1px; }
.tl-body { margin-top: 5px; background: var(--surface-2); border: 1px solid var(--hairline); border-radius: var(--radius-md); padding: 9px 11px; font-size: 13.5px; white-space: pre-wrap; }

/* ---------------- Attachments ---------------- */
.att-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 12px; margin-top: 4px; }
.att-item { border: 1px solid var(--hairline); border-radius: var(--radius-md); overflow: hidden; background: var(--surface-2); display: flex; flex-direction: column; }
.att-thumb { height: 96px; background: var(--surface-2); display: flex; align-items: center; justify-content: center; overflow: hidden; }
.att-thumb img { width: 100%; height: 100%; object-fit: cover; }
.att-thumb.pdf { color: var(--red); font-weight: 700; font-size: 13px; gap: 6px; }
.att-thumb.pdf svg { width: 26px; height: 26px; }
.att-meta { padding: 8px 9px; font-size: 11.5px; }
.att-meta .name { font-weight: 600; color: var(--ink-strong); word-break: break-word; }
.att-meta .by { color: var(--ink-dim); margin-top: 2px; }
.att-item .att-del { border: none; background: transparent; color: var(--red); font-size: 11.5px; font-weight: 600; cursor: pointer; padding: 6px 9px; text-align: left; border-top: 1px solid var(--hairline); }
.att-item .att-del:hover { background: var(--sev-crit-tint); }

/* ---------------- Photo field (in-app camera + picker) ---------------- */
.photo-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.photo-actions .btn svg { width: 16px; height: 16px; }
.photo-thumbs { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 10px; }
.photo-thumbs:empty { margin-top: 0; }
.pf-thumb { position: relative; width: 76px; height: 76px; border: 1px solid var(--hairline); border-radius: var(--radius-md); overflow: hidden; background: var(--surface-2); }
.pf-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pf-thumb-file { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 700; color: var(--red); }
.pf-thumb-rm { position: absolute; top: 3px; right: 3px; width: 20px; height: 20px; border: none; border-radius: 50%; background: rgba(14, 42, 60, 0.78); color: #fff; font-size: 15px; line-height: 1; cursor: pointer; display: flex; align-items: center; justify-content: center; }
.pf-thumb-rm:hover { background: var(--red); }

/* Full-screen in-app camera */
.cam-overlay { position: fixed; inset: 0; z-index: 1000; background: var(--navy-deep, #0A1F2D); display: flex; flex-direction: column; }
.cam-stage { flex: 1; display: flex; align-items: center; justify-content: center; overflow: hidden; padding: env(safe-area-inset-top) 0 0; }
.cam-stage video { max-width: 100%; max-height: 100%; }
.cam-strip { display: flex; gap: 8px; padding: 10px 14px; overflow-x: auto; background: var(--navy-darkest, #07161F); min-height: 0; }
.cam-strip img { height: 48px; width: 48px; object-fit: cover; border-radius: 6px; flex: none; }
.cam-bar { display: flex; align-items: center; justify-content: space-between; padding: 16px 20px calc(20px + env(safe-area-inset-bottom)); background: var(--navy-darkest, #07161F); }
.cam-bar button { font-family: inherit; font-size: 14px; font-weight: 600; cursor: pointer; border-radius: var(--radius-md); }
.cam-cancel, .cam-done { background: transparent; color: #fff; border: 1px solid rgba(255, 255, 255, 0.3); padding: 9px 15px; min-width: 84px; }
.cam-done { background: var(--ice); color: var(--navy-deep, #0A1F2D); border-color: var(--ice); }
.cam-shutter { width: 64px; height: 64px; border-radius: 50%; background: #fff; border: 4px solid rgba(255, 255, 255, 0.45); box-shadow: 0 0 0 2px var(--navy-deep, #0A1F2D) inset; }
.cam-shutter:active { transform: scale(0.94); }

/* ---------------- Undo toast (after accept / decline / cancel) ----------------
   Gmail-style: a dark pill pinned bottom-centre with an Undo action, auto-hides. */
.undo-toast {
  position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%);
  z-index: 95; display: flex; align-items: center; gap: 16px;
  background: var(--navy-deep, #0A1F2D); color: #fff;
  padding: 12px 14px 12px 18px; border-radius: 12px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.28);
  font-size: 14px; max-width: calc(100vw - 32px);
  animation: undo-rise .28s var(--ease) both;
}
.undo-toast.hide { opacity: 0; transform: translate(-50%, 8px); transition: opacity .3s var(--ease), transform .3s var(--ease); }
.undo-toast .undo-msg { font-weight: 500; }
.undo-toast .undo-btn {
  background: transparent; border: none; color: var(--ice, #7FA9C9);
  font-family: inherit; font-size: 14px; font-weight: 700; cursor: pointer;
  padding: 4px 6px; border-radius: 7px;
}
.undo-toast .undo-btn:hover { background: rgba(255,255,255,0.10); }
.undo-toast .undo-x {
  background: transparent; border: none; color: rgba(255,255,255,0.6);
  font-size: 18px; line-height: 1; cursor: pointer; padding: 2px 4px;
}
.undo-toast .undo-x:hover { color: #fff; }
@keyframes undo-rise { from { opacity: 0; transform: translate(-50%, 10px); } to { opacity: 1; transform: translate(-50%, 0); } }
@media (prefers-reduced-motion: reduce) { .undo-toast { animation: none; } }

/* ---------------- Request (intake) banner ---------------- */
.req-banner {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 16px; border-radius: var(--radius-md); margin-bottom: 18px;
  font-size: 14px; font-weight: 500; color: var(--accent-ink);
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
}
.req-banner svg { flex: none; }

/* ---------------- Work orders board view (by urgency) ----------------
   Opt-in column view toggled from the toolbar; the row ledger stays default. */
.wo-board { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; align-items: start; }
.wo-col { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius); overflow: hidden; }
.wo-col-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 11px 13px; border-bottom: 1px solid var(--hairline); background: var(--surface-2); }
.wo-col-head .count { font-size: 11px; font-weight: 700; color: var(--ink-dim); background: var(--surface); border: 1px solid var(--hairline-2); border-radius: 999px; padding: 1px 8px; font-variant-numeric: tabular-nums; }
.wo-col-body { padding: 10px; display: flex; flex-direction: column; gap: 8px; min-height: 44px; }
.wo-card { display: block; text-decoration: none; border: 1px solid var(--hairline-2); border-radius: var(--radius-md); padding: 10px 11px; background: var(--surface); transition: border-color .15s var(--ease), box-shadow .15s var(--ease); }
.wo-card:hover { border-color: var(--accent-line); box-shadow: 0 1px 3px rgba(0,0,0,0.07); text-decoration: none; }
.wo-card .t { font-weight: 600; color: var(--ink-strong); font-size: 14px; line-height: 1.3; }
.wo-card .meta { font-size: 12px; color: var(--ink-dim); margin-top: 3px; }
.wo-col-empty { color: var(--ink-faint); font-size: 12px; padding: 6px 2px; }
@media (max-width: 980px) { .wo-board { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .wo-board { grid-template-columns: 1fr; } }

/* ---------------- PM calendar ---------------- */
.cal-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; flex-wrap: wrap; }
.cal-title { font-size: 17px; font-weight: 700; letter-spacing: -0.01em; color: var(--ink-strong); }
.cal-legend { display: flex; gap: 14px; flex-wrap: wrap; font-size: 12px; color: var(--ink-dim); }
.cal-legend .swatch { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: 5px; vertical-align: middle; }
/* display:table is REQUIRED here: the kit (rg-components.css) also defines a
   .cal-grid (its date-picker is display:grid). This PM calendar is a real
   <table>, so we must re-assert table layout or the kit's grid turns the
   thead/tbody into broken grid cells. */
.cal-grid { display: table; width: 100%; border-collapse: collapse; table-layout: fixed; border: 1px solid var(--hairline); border-radius: var(--radius); overflow: hidden; background: var(--surface); }
.cal-grid thead, .cal-grid tbody, .cal-grid tr { display: table-row-group; }
.cal-grid thead { display: table-header-group; }
.cal-grid tr { display: table-row; }
.cal-grid th, .cal-grid td { display: table-cell; }
.cal-grid .cal-dow { padding: 9px 10px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-dim); background: var(--surface-2); border-bottom: 1px solid var(--hairline); text-align: left; }
.cal-cell { height: 96px; border-right: 1px solid var(--hairline); border-bottom: 1px solid var(--hairline); padding: 7px 8px; vertical-align: top; }
.cal-cell:nth-child(7n) { border-right: none; }
.cal-cell.empty { background: var(--surface-2); }
.cal-cell .daynum { font-size: 12.5px; font-weight: 600; color: var(--ink-dim); }
.cal-cell.is-today { background: var(--accent-soft); }
.cal-cell.is-today .daynum { color: var(--accent-ink); }
.cal-event { display: block; font-size: 11.5px; font-weight: 600; border-radius: 5px; padding: 3px 6px; margin-top: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cal-event.ev-overdue { background: var(--sev-crit-tint); color: var(--red); }
.cal-event.ev-soon { background: var(--sev-warn-tint); color: var(--amber); }
.cal-event.ev-ok { background: var(--surface-2); color: var(--ink-dim); }

/* ---------------- Notification bell ---------------- */
.bell { position: relative; display: inline-flex; }
.bell-btn { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: 999px; border: 1px solid var(--hairline-2); background: var(--surface); color: var(--ink-dim); cursor: pointer; transition: border-color .18s var(--ease), background .18s var(--ease), color .18s var(--ease); }
.bell-btn:hover { border-color: var(--accent-line); background: var(--surface-2); color: var(--ink-strong); }
.bell-btn svg { width: 18px; height: 18px; }
.bell-badge { position: absolute; top: -4px; right: -4px; min-width: 17px; height: 17px; padding: 0 4px; border-radius: 100px; background: var(--red); color: #fff; font-size: 10px; font-weight: 700; line-height: 17px; text-align: center; box-shadow: 0 0 0 2px var(--surface); }
.bell-panel { position: absolute; top: calc(100% + 10px); right: 0; width: 360px; max-width: calc(100vw - 32px); background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius); box-shadow: var(--shadow); z-index: 80; overflow: hidden; }
.bell-head { display: flex; align-items: center; justify-content: space-between; padding: 12px 14px; border-bottom: 1px solid var(--hairline); }
.bell-head-title { font-size: 13px; font-weight: 700; color: var(--ink-strong); }
.bell-markall { border: none; background: transparent; color: var(--accent-ink); font-size: 12px; font-weight: 600; cursor: pointer; padding: 2px 4px; }
.bell-markall:hover { text-decoration: underline; }
.bell-list { max-height: 420px; overflow-y: auto; }
.bell-empty { padding: 26px 16px; text-align: center; color: var(--ink-dim); font-size: 13px; }
.bell-row { display: flex; align-items: flex-start; gap: 10px; padding: 12px 14px; border-bottom: 1px solid var(--hairline); color: var(--ink); cursor: pointer; transition: background .14s var(--ease); }
.bell-row:last-child { border-bottom: none; }
.bell-row:hover { background: var(--surface-2); text-decoration: none; }
.bell-row.unread { background: var(--accent-soft); }
.bell-row.unread:hover { background: var(--accent-soft); }
.bell-row.unread .bell-row-event::before { content: ""; display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); margin-right: 6px; vertical-align: middle; }
.bell-row-main { flex: 1; min-width: 0; }
.bell-row-event { font-size: 12.5px; font-weight: 700; color: var(--ink-strong); }
.bell-row-body { font-size: 13px; color: var(--ink-dim); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bell-row-time { font-size: 11px; color: var(--ink-faint); flex: none; padding-top: 1px; }

/* ---------------- Work-order chat ---------------- */
.chat-stream { display: flex; flex-direction: column; gap: 10px; height: 440px; max-height: 440px; overflow-y: auto; padding: 4px 2px 8px; }
.chat-empty { color: var(--ink-dim); font-size: 13.5px; padding: 18px 4px; text-align: center; }
.chat-msg { display: flex; }
.chat-msg.me { justify-content: flex-end; }
.chat-msg.them { justify-content: flex-start; }
.chat-bubble { max-width: 78%; border: 1px solid var(--hairline); border-radius: 14px; padding: 8px 12px; background: var(--surface-2); }
.chat-msg.me .chat-bubble { background: var(--accent-soft); border-color: var(--accent-line); }
.chat-meta { display: flex; align-items: baseline; gap: 8px; font-size: 11.5px; margin-bottom: 3px; }
.chat-author { font-weight: 700; color: var(--ink-strong); }
.chat-time { color: var(--ink-faint); font-size: 11px; }
.chat-text { font-size: 14px; color: var(--ink-strong); white-space: pre-wrap; word-break: break-word; line-height: 1.45; }
.chat-form { display: flex; gap: 8px; align-items: flex-end; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--hairline); }
.chat-input { flex: 1; resize: none; min-height: 42px; max-height: 120px; border: 1px solid var(--hairline-2); border-radius: var(--radius-md); padding: 10px 12px; font-family: inherit; font-size: 14px; line-height: 1.4; color: var(--ink-strong); background: var(--surface); }
.chat-input:focus { outline: none; border-color: var(--accent); box-shadow: var(--focus-ring); }
.chat-send { flex: none; align-self: stretch; }

/* ---------------- Permission matrix ---------------- */
.perm-block { margin-top: 22px; padding-top: 20px; border-top: 1px solid var(--hairline); }
.perm-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; margin-bottom: 14px; flex-wrap: wrap; }
.perm-title { font-size: 15px; font-weight: 700; color: var(--ink-strong); letter-spacing: -0.01em; }
.perm-matrix { width: 100%; max-width: 520px; border-collapse: collapse; }
.perm-matrix th { text-align: left; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-faint); padding: 6px 10px; border-bottom: 1px solid var(--hairline-2); }
.perm-matrix td { padding: 8px 10px; border-bottom: 1px solid var(--hairline); vertical-align: middle; }
.perm-matrix tr:last-child td { border-bottom: none; }
.perm-matrix .perm-area { font-weight: 600; color: var(--ink-strong); font-size: 13.5px; }
.perm-select { border: 1px solid var(--hairline-2); border-radius: var(--radius-md); padding: 0 12px; height: 38px; font-size: 13px; font-family: inherit; background: var(--surface); color: var(--ink-strong); min-width: 150px; }
.perm-select:focus { outline: none; border-color: var(--accent); box-shadow: var(--focus-ring); }
.scope-opt { display: flex; gap: 9px; align-items: center; cursor: pointer; font-size: 14px; font-weight: 600; color: var(--ink-strong); }
.scope-opt input, .field input[type="checkbox"], label input[type="checkbox"] { accent-color: var(--navy); }
[data-theme="dark"] .scope-opt input, [data-theme="dark"] label input[type="checkbox"] { accent-color: var(--ice); }

/* ---------------- Login / setup ---------------- */
.login-wrap { min-height: 100vh; display: flex; align-items: center; justify-content: center; background: var(--navy); padding: 20px; }
.login-card { background: var(--surface); border-radius: var(--radius); width: 100%; max-width: 380px; padding: 34px 32px; box-shadow: 0 12px 40px rgba(0, 0, 0, 0.25); }
.login-logo { display: block; height: 56px; width: auto; margin-bottom: 14px; }
/* Theme-aware logo swap on the login/setup card (the card surface flips with the
   theme). Light card shows the navy logo, dark card shows the white one. */
[data-theme="light"] .login-logo.logo-dark { display: none; }
[data-theme="dark"] .login-logo.logo-light { display: none; }
.login-card .sub { color: var(--ink-dim); font-size: 13px; margin-bottom: 24px; }
.login-card .field { margin-bottom: 14px; }
.login-card .field label { font-size: 13px; font-weight: 600; color: var(--ink-strong); margin-bottom: 7px; display: block; }
.login-card .field input {
  width: 100%; font-family: inherit; font-size: 14px; color: var(--ink-strong);
  background: var(--surface); border: 1px solid var(--hairline-2);
  border-radius: var(--radius-md); height: var(--ctrl-h, 44px); padding: 0 13px;
}
.login-card .field input:focus { outline: none; border-color: var(--accent); box-shadow: var(--focus-ring); }
.login-card .btn-primary { width: 100%; justify-content: center; margin-top: 6px; }
.login-error { background: var(--sev-crit-tint); color: var(--red); padding: 9px 13px; border-radius: var(--radius-md); font-size: 13px; margin-bottom: 16px; font-weight: 500; border: 1px solid var(--sev-crit-line); }

/* Auth-page theme toggle, pinned top-right over the navy backdrop. */
.auth-toggle { position: fixed; top: 18px; right: 18px; z-index: 5; width: 40px; height: 40px; background: rgba(255, 255, 255, 0.08); border: 1px solid rgba(255, 255, 255, 0.22); color: rgba(255, 255, 255, 0.9); }
.auth-toggle:hover { background: rgba(255, 255, 255, 0.16); border-color: rgba(255, 255, 255, 0.4); color: #ffffff; }

/* ---------------- Searchable selects (Tom Select), skinned to the kit .select ---------------- */
.ts-wrapper { min-width: 0; width: 100%; box-sizing: border-box; }
.ts-wrapper.single .ts-control, .ts-control {
  border: 1px solid var(--hairline-2); border-radius: var(--radius-md);
  padding: 0 13px; min-height: var(--ctrl-h, 44px); font-size: 14px;
  font-family: inherit; background: var(--surface); color: var(--ink-strong);
  box-shadow: none; align-items: center;
}
.ts-wrapper.single.input-active .ts-control, .ts-wrapper.focus .ts-control { border-color: var(--accent); box-shadow: var(--focus-ring); }
.ts-control input, .ts-control .item { font-size: 14px; color: var(--ink-strong); }
.ts-control input::placeholder { color: var(--ink-faint); }
.ts-wrapper.single .ts-control { flex-wrap: nowrap; }
.ts-wrapper.single .ts-control > input { flex: 1 1 auto; min-width: 0; }
/* Hide the selected value ONLY while the dropdown is open (you are searching),
   not merely while the control is focused. Otherwise the chosen value stays
   hidden right after you pick it (control still focused) until you click away,
   which reads as "the value did not populate". With dropdown-active the value
   shows the instant the menu closes on selection. */
.ts-wrapper.single.dropdown-active .ts-control > input { flex: 1 1 auto; }
.ts-wrapper.single.dropdown-active .ts-control > .item { display: none; }
.ts-wrapper.single:not(.dropdown-active) .ts-control > input { width: 0 !important; flex: 0 0 auto; min-width: 0; padding: 0; }
.ts-wrapper.single:not(.has-items) .ts-control > input { width: 100% !important; flex: 1 1 auto; }
.ts-dropdown { border: 1px solid var(--hairline-2); border-radius: var(--radius-md); box-shadow: var(--shadow); font-size: 14px; margin-top: 5px; overflow: hidden; background: var(--surface); }
.ts-dropdown .option { padding: 9px 12px; color: var(--ink-strong); }
.ts-dropdown .option:hover { background: var(--surface-2); }
.ts-dropdown .active { background: var(--accent-soft); color: var(--accent-ink); }
.ts-dropdown .no-results { padding: 9px 12px; color: var(--ink-dim); }
.ts-wrapper.multi .ts-control > .item { background: var(--accent-soft); color: var(--accent-ink); border: 1px solid var(--accent-line); border-radius: 999px; padding: 2px 9px; }

/* ---------------- Home launcher + settings tile hub ----------------
   A grid of tiles, one per section the user can open. Used by the post-login
   home page and the settings hub. Each tile is a quiet hairline card with an
   icon medallion, a name + subtitle, an optional live-count chip, and a chevron
   that slides on hover. Navy accent only, no off-palette colour. */
.home-hero { margin-bottom: 26px; }
.home-hero-mark { margin-bottom: 16px; }
.home-logo { display: block; height: 44px; width: auto; }
[data-theme="light"] .home-logo.logo-dark { display: none; }
[data-theme="dark"] .home-logo.logo-light { display: none; }
.home-greeting { font-size: clamp(26px, 3.2vw, 34px); font-weight: 800; letter-spacing: -0.02em; line-height: 1.05; color: var(--ink-strong); margin: 0; }
.home-sub { color: var(--ink-dim); font-size: 14.5px; margin: 7px 0 0; max-width: 60ch; }

.launcher { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 16px; }
.launcher-compact { grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); max-width: 880px; }

.tile {
  position: relative; display: flex; align-items: center; gap: 15px;
  padding: 18px 18px; text-decoration: none;
  background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--radius); min-height: 92px;
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease), transform .18s var(--ease);
}
.tile:hover {
  text-decoration: none; border-color: var(--accent-line);
  box-shadow: var(--shadow-sm); transform: translateY(-2px);
}
.tile-ico {
  flex: none; width: 48px; height: 48px; border-radius: 13px;
  display: grid; place-items: center;
  background: var(--accent-soft); color: var(--accent-ink);
  border: 1px solid var(--accent-line);
  transition: background .18s var(--ease), color .18s var(--ease);
}
.tile-ico svg { width: 24px; height: 24px; }
.tile:hover .tile-ico { background: var(--navy); color: #fff; border-color: var(--navy); }
[data-theme="dark"] .tile:hover .tile-ico { background: var(--ice); color: var(--navy-deep); border-color: var(--ice); }
.tile-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.tile-name {
  font-size: 16px; font-weight: 700; letter-spacing: -0.01em; color: var(--ink-strong);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tile-sub {
  font-size: 12.5px; color: var(--ink-dim); line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.tile-count {
  flex: none; align-self: flex-start; font-size: 11px; font-weight: 700;
  line-height: 1; padding: 4px 9px; border-radius: 999px;
  color: var(--accent-ink); background: var(--accent-soft);
  border: 1px solid var(--accent-line); white-space: nowrap;
}
.tile-count-warn { color: var(--amber); background: var(--sev-warn-tint); border-color: var(--sev-warn-line); }
.tile-count-bad { color: var(--red); background: var(--sev-crit-tint); border-color: var(--sev-crit-line); }
.tile-go { flex: none; color: var(--ink-faint); transition: transform .2s var(--ease), color .18s var(--ease); }
.tile-go svg { width: 18px; height: 18px; display: block; }
.tile:hover .tile-go { color: var(--accent-ink); transform: translateX(3px); }
@media (prefers-reduced-motion: reduce) {
  .tile, .tile-go, .tile-ico { transition: none; }
  .tile:hover { transform: none; }
  .tile:hover .tile-go { transform: none; }
}

/* ---------------- On/off toggle (.rg-switch) ----------------
   A tidy on-brand switch: navy track + white knob when checked, neutral when
   off. The real checkbox is visually hidden but still posts its value, so the
   form behaviour is unchanged. Used for the site "Operational" control. */
.rg-switch { display: inline-flex; align-items: center; gap: 11px; cursor: pointer; user-select: none; }
.rg-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.rg-switch-track {
  position: relative; flex: none; width: 42px; height: 24px; border-radius: 999px;
  background: var(--surface-2); border: 1px solid var(--hairline-2);
  transition: background .18s var(--ease), border-color .18s var(--ease);
}
.rg-switch-knob {
  position: absolute; top: 2px; left: 2px; width: 18px; height: 18px;
  border-radius: 50%; background: var(--surface);
  box-shadow: 0 1px 2px rgba(14,42,60,0.35);
  transition: transform .2s var(--ease), background .18s var(--ease);
}
.rg-switch input:checked + .rg-switch-track { background: var(--navy); border-color: var(--navy); }
[data-theme="dark"] .rg-switch input:checked + .rg-switch-track { background: var(--ice); border-color: var(--ice); }
.rg-switch input:checked + .rg-switch-track .rg-switch-knob { transform: translateX(18px); background: #fff; }
[data-theme="dark"] .rg-switch input:checked + .rg-switch-track .rg-switch-knob { background: var(--navy-deep); }
.rg-switch input:focus-visible + .rg-switch-track { outline: none; box-shadow: var(--focus-ring); }
.rg-switch-label { font-size: 14px; font-weight: 600; color: var(--ink-strong); }
@media (prefers-reduced-motion: reduce) { .rg-switch-track, .rg-switch-knob { transition: none; } }

/* ---------------- Decline action hover (request triage) ----------------
   The Decline control gets a very light red tint on hover (a faint wash of the
   brand red), with readable text, instead of the default grey ghost hover.
   Scoped to the .btn-decline toggle in the convert panel only. */
.btn-ghost.btn-decline:hover,
button.btn-decline:hover {
  background: var(--sev-crit-tint);
  color: var(--red);
  border-color: var(--sev-crit-line);
}

/* ---------------- Trash icon button (delete a cost line) ----------------
   A compact square icon button: quieter and smaller than a text "Delete", and
   reads as red-destructive on hover. Used for per-line cost deletion. */
.btn-trash {
  display: inline-grid; place-items: center; width: 32px; height: 32px; padding: 0;
  border: 1px solid var(--hairline-2); background: var(--surface); color: var(--ink-dim);
  border-radius: 9px; cursor: pointer;
  transition: background .15s var(--ease), color .15s var(--ease), border-color .15s var(--ease);
}
.btn-trash svg { width: 16px; height: 16px; display: block; }
.btn-trash:hover { background: var(--sev-crit-tint); color: var(--red); border-color: var(--sev-crit-line); }
.btn-trash:focus-visible { outline: none; box-shadow: var(--focus-ring); }

/* Cost ledger (desktop): the delete column hugs the right edge as a narrow,
   right-aligned action cell so the trash sits at the end of each row. */
table.cost-table td.cell-action { width: 1%; white-space: nowrap; text-align: right; }
table.cost-table td.cell-action form { display: inline-flex; justify-content: flex-end; }

/* ---------------- Access-model legend (staff page) ----------------
   Three role steps connected by arrows, showing the request-to-work-order flow.
   Collapsible like the activity card. */
.role-flow { display: flex; align-items: stretch; gap: 12px; flex-wrap: wrap; }
.role-step {
  flex: 1 1 200px; min-width: 0; background: var(--surface-2);
  border: 1px solid var(--hairline); border-radius: var(--radius-md); padding: 13px 14px;
}
.role-step-tag {
  display: inline-block; font-size: 11px; font-weight: 700; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--accent-ink);
  background: var(--accent-soft); border: 1px solid var(--accent-line);
  border-radius: 999px; padding: 3px 10px; margin-bottom: 8px;
}
.role-step p { margin: 0; font-size: 13px; line-height: 1.5; color: var(--ink-dim); }
.role-arrow { flex: none; display: flex; align-items: center; color: var(--ink-faint); }
.role-arrow svg { width: 20px; height: 20px; }

/* ---------------- Tablet ---------------- */
@media (max-width: 1000px) {
  .kpi-grid { grid-template-columns: repeat(3, 1fr); }
  .dash-cols, .detail-grid, .form-grid, .report-grid { grid-template-columns: 1fr; }
  .metric-row { grid-template-columns: repeat(3, 1fr); }
}

/* The role-flow arrows turn vertical when the steps stack. */
@media (max-width: 760px) {
  .role-flow { flex-direction: column; }
  .role-arrow { transform: rotate(90deg); align-self: center; }
}

/* ---------------- Mobile (bottom tab bar + card tables) ----------------
   Breakpoint matches the kit's own sidebar-to-drawer breakpoint (860px) so the
   bottom tab bar takes over exactly where the kit would otherwise hide the
   sidebar as an (un-openable, in this app) left drawer. Below this width the
   sidebar is a fixed bottom bar, tables reflow into cards, and forms stack. */
@media (max-width: 860px) {
  /* The glass sidebar becomes a fixed bottom tab bar.
     The kit's mobile rule hides the sidebar as a left drawer
     (transform: translateX(-100%)); we repurpose it as a bottom bar, so we must
     reset that transform or the bar slides off-screen to the left. */
  .app-shell { grid-template-columns: 1fr; }
  /* A collapsed-sidebar state saved on desktop must not leak into mobile: the
     bottom bar is full-width, so neutralize the desktop collapse grid here
     (same selector as the global rule, but later + in-media, so it wins). */
  html.nav-collapsed .app-shell { grid-template-columns: 1fr; }
  .app-sidebar {
    position: fixed; left: 0; right: 0; bottom: 0; top: auto;
    transform: none !important;
    width: 100%; height: auto; flex-direction: row; align-items: center;
    border-right: none; border-top: 1px solid var(--sidebar-hairline);
    padding: 6px 4px env(safe-area-inset-bottom); z-index: 50; gap: 0;
  }
  .app-brand, .sidebar-user, .sidebar-spacer { display: none; }
  /* Exactly 5 tabs (Home, Dashboard, Work orders, Assets, More) spread evenly
     across the bar: no horizontal scroll, comfortable tap targets. */
  .sidebar-nav {
    flex: 1; flex-direction: row; padding: 0; gap: 0;
    justify-content: space-around;
  }
  /* The secondary destinations live in the More sheet, not the bottom bar. */
  .nav-item.mob-in-more { display: none; }
  /* The More tab button shows as the 5th tab. */
  .mob-more-btn {
    display: flex; background: none; border: none; cursor: pointer;
    font-family: inherit; color: inherit;
  }
  .nav-item {
    flex: 1 1 0; min-width: 0; flex-direction: column; gap: 3px;
    align-items: center; justify-content: center; margin: 0; padding: 7px 4px; min-height: 52px;
  }
  .nav-item .txt { display: none; }
  .nav-item .txt-short {
    display: block; width: 100%; font-size: 10.5px; font-weight: 600;
    letter-spacing: -0.01em; line-height: 1.1; text-align: center;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .nav-item .ico { width: 22px; height: 22px; }
  /* The pending-requests badge moves into the More sheet now, but keep the
     bottom-tab count hidden so it never overlaps a 5-up tab. */
  .nav-item .count { display: none; }

  .app-content { padding-bottom: calc(66px + env(safe-area-inset-bottom)); }
  .mobile-only { display: inline-flex; }

  /* ---- More sheet: a bottom sheet listing secondary destinations ---- */
  .more-sheet { display: block; position: fixed; inset: 0; z-index: 60; }
  .more-scrim {
    position: absolute; inset: 0; background: rgba(7,22,31,0.45);
    opacity: 0; transition: opacity .24s var(--ease);
  }
  .more-sheet.open .more-scrim { opacity: 1; }
  .more-panel {
    position: absolute; left: 0; right: 0; bottom: 0;
    background: var(--surface); border-top-left-radius: 18px; border-top-right-radius: 18px;
    border-top: 1px solid var(--hairline);
    box-shadow: 0 -16px 40px rgba(7,22,31,0.28);
    padding: 8px 14px calc(16px + 66px + env(safe-area-inset-bottom));
    transform: translateY(100%); transition: transform .26s cubic-bezier(.32,.72,0,1);
    max-height: 80vh; overflow-y: auto;
  }
  .more-sheet.open .more-panel { transform: translateY(0); }
  .more-head { display: flex; align-items: center; justify-content: space-between; padding: 10px 4px 12px; }
  .more-title { font-size: 16px; font-weight: 700; color: var(--ink-strong); letter-spacing: -0.01em; }
  .more-close {
    width: 36px; height: 36px; display: grid; place-items: center; flex: none;
    border: 1px solid var(--hairline-2); background: var(--surface); color: var(--ink-dim);
    border-radius: 999px; cursor: pointer;
  }
  .more-close:active { background: var(--surface-2); }
  .more-list { display: flex; flex-direction: column; gap: 2px; }
  .more-link {
    display: flex; align-items: center; gap: 14px; padding: 14px 12px;
    border-radius: var(--radius-md); color: var(--ink-strong); font-size: 15.5px; font-weight: 600;
    text-decoration: none;
  }
  .more-link .ico { width: 22px; height: 22px; flex: none; color: var(--ink-dim); }
  .more-link:active { background: var(--surface-2); text-decoration: none; }
  .more-link.active { background: var(--accent-soft); color: var(--accent-ink); }
  .more-link.active .ico { color: var(--accent-ink); }
  .more-link .more-count {
    margin-left: auto; font-size: 11px; font-weight: 700; line-height: 1;
    padding: 3px 8px; border-radius: 999px; background: var(--red); color: #fff;
  }
  .more-link-logout { margin-top: 6px; border-top: 1px solid var(--hairline); border-radius: 0; color: var(--ink-dim); }
  @media (prefers-reduced-motion: reduce) {
    .more-scrim, .more-panel { transition: none; }
  }

  .kpi-grid { grid-template-columns: repeat(2, 1fr); gap: 10px; }
  .kpi .value, .metric .value { font-size: 24px; }
  .metric-row { grid-template-columns: 1fr; }
  .report-grid { grid-template-columns: 1fr; }
  .chart-box { height: 240px; }

  /* Page head: stack title above actions on mobile so the h1 never scrunches
     beside the primary button. Both sides go full width when stacked. */
  .page-head { flex-direction: column; align-items: flex-start; gap: 8px; }
  .toolbar { flex-direction: column; align-items: stretch; }
  /* Filters pack into a wrapping row instead of a tall single column. The search
     box keeps its own line (room to type); the compact dropdowns flow two per
     row, and a lone trailing one grows to fill the width. Composite controls
     (the Sort pair), checkboxes and action buttons each take a full line. */
  .filters { width: 100%; flex-direction: row; flex-wrap: wrap; align-items: stretch; gap: 8px; }
  .filters .search-box { flex: 1 1 100%; width: 100%; min-width: 0; max-width: none; }
  .filters > select,
  .filters .ts-wrapper { flex: 1 1 calc(50% - 4px); width: auto; min-width: 0; }
  .filters .ts-wrapper .ts-control { width: 100%; }
  .filters .sort-mobile,
  .filters > label,
  .filters > .btn { flex: 1 1 100%; width: 100%; }
  .filters > .btn { justify-content: center; }
  /* The thin hairline divider in the PM toolbar is desktop-only chrome. */
  .filters > span { display: none; }
  /* Page-action area: buttons (including form-wrapped ones) go full width and
     wrap instead of overflowing. Badges (priority/status) keep their natural
     size and sit on their own wrapped row. */
  .page-head .rhs { width: 100%; gap: 8px; }
  .page-head .rhs > .btn,
  .page-head .rhs > a.btn,
  .page-head .rhs > form { flex: 1 1 140px; justify-content: center; min-width: 0; }
  .page-head .rhs > form { display: flex; }
  .page-head .rhs > form > .btn { flex: 1; width: 100%; justify-content: center; }
  .page-head .rhs > .btn, .page-head .rhs > form > .btn,
  .page-head .rhs > a.btn { white-space: normal; }
  /* Badges in the page head (work order detail) stay compact, not stretched. */
  .page-head .rhs > .badge { flex: 0 0 auto; }

  .sort-mobile { display: flex; width: 100%; }
  .sort-mobile select { flex: 1; }

  /* 16px inputs so iOS does not auto-zoom on focus. */
  .field input, .field select, .field textarea,
  .filters select, .filters .search-box,
  .ts-control, .ts-control input, .ts-control .item, .ts-dropdown,
  .perm-select, .chat-input, .login-card .field input { font-size: 16px; }

  /* Data tables reflow into labeled cards (nothing hidden). */
  .table-wrap { overflow: visible; }
  table.data thead { display: none; }
  table.data, table.data tbody, table.data tr, table.data td { display: block; width: 100%; }
  table.data tr { padding: 13px 15px; border-bottom: 1px solid var(--hairline); }
  table.data tr:last-child { border-bottom: none; }
  table.data td { padding: 5px 0; border: none; display: flex; justify-content: space-between; align-items: center; gap: 16px; text-align: right; font-size: 13.5px; }
  table.data td::before { content: attr(data-label); text-align: left; flex: none; color: var(--ink-faint); font-weight: 600; font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; }
  table.data td:empty { display: none; }
  table.data td.cell-primary { display: block; text-align: left; padding: 0 0 7px; font-size: 15px; font-weight: 600; }
  table.data td.cell-primary::before { display: none; }
  table.data td.cell-action { display: block; text-align: left; padding-top: 11px; }
  table.data td.cell-action::before { display: none; }
  table.data td.cell-action form { justify-content: space-between; }
  /* Totals row in a reflowed cost/parts table: render as one clean labeled row
     (the desktop top-border on each cell becomes a stray rule in card mode). */
  table.data tfoot { display: block; border-top: 2px solid var(--ink); margin-top: 4px; }
  table.data tfoot tr { padding: 11px 15px 2px; }
  table.data tfoot td { border-top: none; padding: 4px 0; }
  table.data tfoot td:empty { display: none; }

  /* ---- Cost ledger on mobile ----
     A money list reads badly as the generic label/value cards: the dual CDF/USD
     columns double up and the total row repeats its own label. Override the
     reflow to a clean line per cost: what it is for on the left, the USD amount
     on the right, the original CDF as a muted "Paid ... FC" sub-line, and the
     Delete action (edit mode) on its own sub-row. */
  /* A 3-column grid gives deterministic placement (flex + wrap let the trash
     wrap to its own line at the sub-pixel edge): label | amount | trash. The
     CDF sub-line spans the full width on its own grid row, muted. */
  table.cost-table tr {
    display: grid; grid-template-columns: 1fr auto auto;
    align-items: baseline; column-gap: 12px; row-gap: 3px; padding: 12px 15px;
  }
  /* width:auto is essential: the generic reflow sets every cell to width:100%. */
  table.cost-table td { display: block; width: auto; padding: 0; border: none; text-align: left; font-size: 14px; }
  table.cost-table td::before { display: none !important; }
  /* Explicit row placement: amount + trash stay on row 1 next to the label, and
     the CDF sub-line is pinned to row 2. (Auto-placement would otherwise push the
     amount below the full-width CDF cell, since CDF precedes it in the markup.) */
  table.cost-table td.cell-primary { grid-column: 1; grid-row: 1; min-width: 0; font-size: 14.5px; font-weight: 600; }
  table.cost-table td.col-usd { grid-column: 2; grid-row: 1; text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
  table.cost-table td.col-usd:empty { display: none; }
  table.cost-table td.cell-action { grid-column: 3; grid-row: 1; }
  table.cost-table td.col-cdf { grid-column: 1 / -1; grid-row: 2; color: var(--ink-dim); font-size: 12.5px; }
  table.cost-table td.col-cdf:empty { display: none; }
  table.cost-table td.col-cdf::before { content: "Paid "; display: inline !important; }
  table.cost-table .cdf-unit { display: inline; }
  table.cost-table tfoot { border-top: none; margin-top: 0; }
  table.cost-table tfoot tr { padding: 13px 15px; border-top: 2px solid var(--ink); }
  table.cost-table tfoot td { padding: 0; }
  table.cost-table tfoot td.strong { grid-column: 1; grid-row: 1; font-size: 14px; font-weight: 700; }
  table.cost-table tfoot td.col-usd { font-size: 17px; font-weight: 800; }

  .bar-row { grid-template-columns: 110px 1fr 64px; }

  /* Calendar scrolls horizontally so cells stay tappable. */
  .cal-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .cal-grid { min-width: 620px; }

  .bell-panel { position: fixed; top: 60px; left: 0; right: 0; width: 100%; max-width: 100%; border-radius: 0; border-left: none; border-right: none; }
  .bell-list { max-height: calc(100vh - 60px - 52px - 66px); }
  .chat-bubble { max-width: 88%; }
  .chat-stream { height: 340px; max-height: 340px; }
  .perm-select { width: 100%; min-width: 0; }
  .perm-matrix { max-width: none; }

  /* ---- Home launcher + settings hub: 2-up app-style tiles on phone ----
     Tiles stack their content vertically (icon, then name + subtitle) so two
     fit per row comfortably without cramping. The chevron is dropped (the whole
     tile is the tap target) and the count chip sits inline by the name. */
  .launcher, .launcher-compact { grid-template-columns: 1fr 1fr; gap: 11px; max-width: none; }
  .tile { flex-direction: column; align-items: flex-start; gap: 10px; padding: 15px 14px; min-height: 0; }
  .tile-ico { width: 42px; height: 42px; border-radius: 12px; }
  .tile-ico svg { width: 22px; height: 22px; }
  .tile-body { gap: 2px; width: 100%; }
  .tile-name { font-size: 14.5px; }
  .tile-sub { font-size: 11.5px; }
  .tile-count { margin-top: 2px; }
  .tile-go { display: none; }
  /* Disable the lift on touch so tiles never feel jumpy. */
  .tile:hover { transform: none; box-shadow: none; border-color: var(--hairline); }

  /* Home hero: tighter on phone, smaller logo. */
  .home-hero { margin-bottom: 18px; }
  .home-logo { height: 34px; }
  .home-greeting { font-size: 24px; }
  .home-sub { font-size: 13.5px; }

  /* Detail key-value pairs stack so long values never collide with the label. */
  .kv { grid-template-columns: 1fr; gap: 3px 0; }
  .kv dt { font-size: 12px; }
  .kv dd { margin-bottom: 8px; }
  .kv dd:last-child { margin-bottom: 0; }

  /* Inline add-cost / add-part subforms stack full width in edit mode. Some
     fields carry an inline flex-basis (e.g. flex:0 0 140px) for the desktop row;
     in a stacked column that basis becomes a fixed HEIGHT and leaves a tall gap,
     so we reset it to auto here (the inline style needs !important to beat). */
  .subform { flex-direction: column; align-items: stretch; }
  .subform .field, .subform .field.narrow { flex: 1 1 auto !important; width: 100%; min-width: 0; }
  .subform .btn { width: 100%; justify-content: center; }

  /* Form action rows: full-width stacked buttons, comfortable tap targets. */
  .form-actions { flex-direction: column; align-items: stretch; }
  .form-actions .btn { width: 100%; justify-content: center; }

  /* Photo capture/choose row wraps cleanly. */
  .photo-actions { width: 100%; }
  .photo-actions .btn { flex: 1 1 auto; justify-content: center; }

  /* Card headers with an inline action (e.g. Sites/Users) wrap instead of
     squeezing the button. */
  .card-head { flex-wrap: wrap; gap: 8px; row-gap: 10px; }
  .card-head .btn { width: auto; }

  /* Long words / refs / emails wrap rather than forcing horizontal overflow. */
  .tl-detail, .chat-text, .att-meta .name, .kv dd { overflow-wrap: anywhere; }

  /* Role-flow legend already stacks at 760px; keep its steps full width here. */
  .role-step { flex-basis: auto; }
}

/* ---- Very narrow phones (<=360px): keep the launcher readable ----
   At 360px a 2-up grid with our padding is fine, but drop to one column if the
   tile name would wrap awkwardly on the smallest devices. */
@media (max-width: 360px) {
  .home-greeting { font-size: 22px; }
  .tile { padding: 14px 13px; }
}

/* ====================================================================
   Accessibility layer
   Loads after the brand kit, so these rules win where they touch the
   same properties. Nothing here changes layout or the palette, it only
   makes existing controls reachable and legible for keyboard and
   screen-reader users.
   ==================================================================== */

/* Amber badge contrast override (RestoCare only).
   The kit's light-theme --amber (#a9762e) measures about 3.95:1 on white,
   under the WCAG AA 4.5:1 minimum for the small badge text. Darken it just
   enough to clear AA. Light theme only: the dark-theme amber is untouched,
   and the kit files themselves are not edited. */
:root, [data-theme="light"] { --amber: #8a5e1f; }

/* Visible keyboard focus indicator.
   :focus-visible only fires for keyboard / programmatic focus, so a mouse
   click never shows the ring. We give a clear outline to the interactive
   elements that did not already carry one. Elements with their own
   :focus-visible treatment (inputs, .rg-switch, .btn-trash) keep theirs. */
a:focus-visible,
button:focus-visible,
[role="button"]:focus-visible,
.nav-item:focus-visible,
.mob-tab:focus-visible,
.crumbs a:focus-visible,
.bell-btn:focus-visible,
.rg-toggle:focus-visible,
.sidebar-toggle:focus-visible,
.more-link:focus-visible,
th.th-sort a:focus-visible,
.pager a:focus-visible,
.tile:focus-visible,
.att-del:focus-visible {
  outline: 2px solid var(--accent-ink);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* Keyboard-operable table rows.
   List rows use a row-level onclick for the mouse. To make the same target
   reachable by keyboard we put a real link on the row's primary text and
   stretch it across the row with an ::after overlay, so Tab focuses it and
   Enter follows it. Other interactive cells (action buttons, links) are
   lifted above the overlay so they stay clickable. */
.data tr { position: relative; }
.data a.row-link { color: inherit; text-decoration: none; }
.data a.row-link::after { content: ""; position: absolute; inset: 0; z-index: 0; }
.data td.cell-action,
.data td.cell-action a,
.data td.cell-action button,
.data td.cell-action form { position: relative; z-index: 1; }
