/* The `hidden` attribute is how every page in this app shows and hides
   its banners, and an author `display:` rule silently beats the user-agent
   stylesheet's [hidden] { display: none }. .mismatch-banner sets
   display:flex, so device.html's banner rendered as a permanently visible
   empty accent-coloured bar above the content - including right after
   `mismatchBannerEl.hidden = true`. Specificity is not the issue and
   reordering would not fix it, because the UA rule is in a different
   origin; !important is the correct tool here.

   Global on purpose: any element given both `hidden` and a `display:`
   rule has the same problem, and there are a dozen display:flex rules in
   this file. */
[hidden] {
  display: none !important;
}

:root {
  /* Dark palette - the default when neither an explicit choice
     (data-theme, set by js/theme.js) nor prefers-color-scheme says
     otherwise. */
  --bg: #0d1119;
  --surface: #161d2e;
  --surface-raised: #1d2637;
  --border: #2a3448;
  --text: #e6e9f0;
  --text-muted: #8b94a8;
  --accent: #4f8cff;
  --accent-dim: #2a4d8f;
  --accent-soft: rgba(79, 140, 255, 0.12);
  --danger: #ef5757;
  --warning: #e0a72e;
  --success: #3fbf7f;
  --on-accent: #ffffff;
  --accent-hover: #3f7bef;
  --accent-glow: rgba(79, 140, 255, 0.25);
  --info: #4f8cff;
  --success-soft: rgba(63, 191, 127, 0.12);
  /* Each theme's own background and accent, the same in every theme: the
     Theme picker's swatches show every theme whichever is showing. A test pins
     them to the real --bg and --accent of their theme. */
  --swatch-dark-bg: #0d1119;
  --swatch-dark-accent: #4f8cff;
  --swatch-light-bg: #f4f5f9;
  --swatch-light-accent: #2f6fed;
  --swatch-teal-bg: #0f1419;
  --swatch-teal-accent: #2dd4bf;
  --swatch-orange-cream-bg: #fff7ed;
  --swatch-orange-cream-accent: #c2410c;
  /* Two-series chart colours (owner.html). Checked with the dataviz
     palette validator against each theme's surface: colour-blind
     separation and lightness band pass in both. */
  --chart-1: #4f8cff;
  --chart-2: #c97a2a;
  --radius: 10px;
  --sidebar-width: 232px;
  /* Layout scale. The page fills the screen next to the sidebar; only pages
     that are mostly reading (forms, settings) keep a width cap, and that one
     is centred, not left-stranded. Raised at the 1920 and 2560 breakpoints at
     the end of this file. */
  --page-reading-max: 1520px;
  --page-pad-x: 40px;
  --rail-width: 320px;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

/* OS-level light preference, only when the user hasn't explicitly picked
   a theme (data-theme="dark" wins over this - see js/theme.js). */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --bg: #f4f5f9;
    --surface: #ffffff;
    --surface-raised: #f9fafc;
    --border: #dde1ea;
    --text: #1b2130;
    --text-muted: #666f85;
    --accent: #2f6fed;
    --accent-dim: #cddbfb;
    --accent-soft: rgba(47, 111, 237, 0.1);
    --danger: #d43f3f;
    --warning: #b5790a;
    --success: #1f9d5f;
    --on-accent: #ffffff;
    --accent-hover: #3f7bef;
    --accent-glow: rgba(79, 140, 255, 0.25);
    --info: #2f6fed;
    --success-soft: rgba(63, 191, 127, 0.12);
    /* Each theme's own background and accent, the same in every theme: the
       Theme picker's swatches show every theme whichever is showing. A test pins
       them to the real --bg and --accent of their theme. */
    --swatch-dark-bg: #0d1119;
    --swatch-dark-accent: #4f8cff;
    --swatch-light-bg: #f4f5f9;
    --swatch-light-accent: #2f6fed;
    --swatch-teal-bg: #0f1419;
    --swatch-teal-accent: #2dd4bf;
    --swatch-orange-cream-bg: #fff7ed;
    --swatch-orange-cream-accent: #c2410c;
    --chart-1: #2f6fed;
    --chart-2: #c46f1c;
  }
}

/* Explicit choice (the toggle in the sidebar) - wins regardless of OS
   preference, in either direction. */
:root[data-theme="light"] {
  --bg: #f4f5f9;
  --surface: #ffffff;
  --surface-raised: #f9fafc;
  --border: #dde1ea;
  --text: #1b2130;
  --text-muted: #666f85;
  --accent: #2f6fed;
  --accent-dim: #cddbfb;
  --accent-soft: rgba(47, 111, 237, 0.1);
  --danger: #d43f3f;
  --warning: #b5790a;
  --success: #1f9d5f;
  --on-accent: #ffffff;
  --accent-hover: #3f7bef;
  --accent-glow: rgba(79, 140, 255, 0.25);
  --info: #2f6fed;
  --success-soft: rgba(63, 191, 127, 0.12);
  /* Each theme's own background and accent, the same in every theme: the
     Theme picker's swatches show every theme whichever is showing. A test pins
     them to the real --bg and --accent of their theme. */
  --swatch-dark-bg: #0d1119;
  --swatch-dark-accent: #4f8cff;
  --swatch-light-bg: #f4f5f9;
  --swatch-light-accent: #2f6fed;
  --swatch-teal-bg: #0f1419;
  --swatch-teal-accent: #2dd4bf;
  --swatch-orange-cream-bg: #fff7ed;
  --swatch-orange-cream-accent: #c2410c;
  --chart-1: #2f6fed;
  --chart-2: #c46f1c;
}

/* Teal: a third, dark theme (the owner's chosen colour scheme). Chosen
   with the sidebar theme switch (js/common.js) and applied by js/theme.js as
   data-theme="teal". It sits after the light-preference media query and has
   the same specificity, so it wins over that query when the OS prefers light.
   It must redefine EVERY token the other themes do
   (frontend/test_theme_teal.js enforces this and pins the values). */
:root[data-theme="teal"] {
  color-scheme: dark;
  --bg: #0f1419;
  --surface: #172029;
  --surface-raised: #1d2833;
  --border: #2a3642;
  --text: #e4eaf0;
  --text-muted: #93a1ae;
  --accent: #2dd4bf;
  --accent-dim: #1a9e91;
  --accent-soft: #123330;
  --danger: #f26d6d;
  --warning: #f5a524;
  --success: #86d66a;
  --on-accent: #0f1419;
  --accent-hover: #5eead4;
  --accent-glow: rgba(45, 212, 191, 0.25);
  --info: #60a5fa;
  --success-soft: rgba(134, 214, 106, 0.12);
  /* Each theme's own background and accent, the same in every theme: the
     Theme picker's swatches show every theme whichever is showing. A test pins
     them to the real --bg and --accent of their theme. */
  --swatch-dark-bg: #0d1119;
  --swatch-dark-accent: #4f8cff;
  --swatch-light-bg: #f4f5f9;
  --swatch-light-accent: #2f6fed;
  --swatch-teal-bg: #0f1419;
  --swatch-teal-accent: #2dd4bf;
  --swatch-orange-cream-bg: #fff7ed;
  --swatch-orange-cream-accent: #c2410c;
  --chart-1: #2dd4bf;
  --chart-2: #e08a3a;
}

/* Orange Cream: a second light theme, cream and orange (owner's request,
   2026-09-30). Same rules as Teal: it follows the light-preference media query
   and every other theme, so it wins when chosen, and it must redefine every
   token (frontend/test_theme_teal.js pins the values and checks contrast). */
:root[data-theme="orange-cream"] {
  color-scheme: light;
  --bg: #fff7ed;
  --surface: #ffffff;
  --surface-raised: #fffbf5;
  --border: #f1d9c0;
  --text: #2b1d10;
  --text-muted: #76583f;
  --accent: #c2410c;
  --accent-dim: #ea580c;
  --accent-soft: #fff1e6;
  --danger: #c62828;
  --warning: #8a5a00;
  --success: #1b7f45;
  --on-accent: #ffffff;
  --accent-hover: #9a3412;
  --accent-glow: rgba(234, 88, 12, 0.25);
  --info: #1d4ed8;
  --success-soft: rgba(27, 127, 69, 0.12);
  --swatch-dark-bg: #0d1119;
  --swatch-dark-accent: #4f8cff;
  --swatch-light-bg: #f4f5f9;
  --swatch-light-accent: #2f6fed;
  --swatch-teal-bg: #0f1419;
  --swatch-teal-accent: #2dd4bf;
  --swatch-orange-cream-bg: #fff7ed;
  --swatch-orange-cream-accent: #c2410c;
  --chart-1: #ea580c;
  --chart-2: #0f766e;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  min-height: 100vh;
}

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

.muted {
  color: var(--text-muted);
}

/* --- brand: the ITAI mark ----------------------------------------------
   The spark "i" mark, in two lockups (js/common.js, BRAND_LOCKUP). Everything
   is drawn in theme tokens, so each theme (dark, light, teal, orange-cream)
   gets its own accent. --brand-light is the cream "i" on the tile; it is the
   same in every theme because the tile behind it is always a saturated accent. */
:root {
  --brand-light: #fbf7ef;
}
.brand-tile {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  display: block;
  /* An SVG clips to its box, and the box sits on a fractional pixel when it is
     sized in em: that shaved the rounded bottom and right corners off the
     tile. Nothing is drawn outside the viewBox, so never clip. */
  overflow: visible;
}
.brand-bg {
  fill: var(--accent);
}
.brand-fg {
  fill: var(--brand-light);
}
/* ==== BEGIN BRAND WORDMARK (shared: tools/brand_assets.py copies this block, byte for byte, to website/brand.css) ==== */
.brand-lockup {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--text);
  font-weight: 500;
  line-height: 1;
}
/* Option B. Plain text ITAI in one run, so every letter shares one baseline
   and cap line. The last I is a plain inline span in the accent (never an
   inline-block, which could sit a pixel off). The spark above it is an
   in-flow empty span after the I that takes no room: a zero-size margin box
   (negative margins equal to its padding), lifted by vertical-align to one cap height plus a
   gap above the baseline, and pulled back from the end of the I to the middle of its stem.
   --brand-cap is the font's own cap height (the cap unit; 0.7em where the
   browser lacks it). Tune by eye: --brand-spark (width as a share of the cap
   height), --brand-spark-gap, --brand-i-half (how far back from the end of the I's
   box the spark's centre sits: 0.145em, half the advance of an I, measured
   at 0.29em in Segoe UI; near that in the other common sans fonts). js/common.js
   centerBrandSparks replaces --brand-i-half once the page has drawn with the
   distance to the middle of the I's INK, so the spark is centred on the stem
   in any font or zoom. */
.brand-lockup-wordmark {
  --brand-cap: 0.7em;
  --brand-spark: calc(var(--brand-cap) * 0.54);  /* owner: bigger again (0.34, then 0.46), 2026-10-02 */
  --brand-spark-layout: calc(var(--brand-cap) * 0.46);
  --brand-spark-gap: calc(var(--brand-cap) * 0.16);
  --brand-i-half: 0.145em;
  display: inline;
}
@supports (width: 1cap) {
  .brand-lockup-wordmark {
    --brand-cap: 1cap;
  }
}
.brand-cap-i {
  color: var(--accent);
}
.brand-spark {
  display: inline-block;
  width: 0;
  height: 0;
  padding: calc(var(--brand-spark) / 2);
  margin: calc(var(--brand-spark) / -2);
  margin-left: calc(var(--brand-spark) / -2 - var(--brand-i-half));
  margin-right: calc(var(--brand-spark) / -2 + var(--brand-i-half));
  /* The line box is sized by where the zero-size box sits, so that is still
     worked out from the 0.46 spark (--brand-spark-layout): the sidebar row and
     the sign-in heading keep the height they had before the spark grew (the
     bigger one nudged them 0.7px taller). top lifts the drawn spark the
     rest of the way to its centre; relative positioning moves no layout. */
  vertical-align: calc(var(--brand-cap) + var(--brand-spark-gap) + var(--brand-spark-layout) / 2);
  position: relative;
  top: calc((var(--brand-spark-layout) - var(--brand-spark)) / 2);
  background: var(--accent);
  clip-path: polygon(50% 0, 61% 39%, 100% 50%, 61% 61%, 50% 100%, 39% 61%, 0 50%, 39% 39%);
}
/* ==== END BRAND WORDMARK ==== */
/* Option D. */
.brand-lockup-tile-text .brand-tile {
  width: 1.5em;
  height: 1.5em;
}
.brand-text {
  font-weight: 500;
  letter-spacing: 0.02em;
}

/* --- app shell / sidebar ------------------------------------------------ */

.app-shell {
  display: flex;
  align-items: stretch;
  min-height: 100vh;
}

#nav-root {
  display: contents;
}

.sidebar {
  display: flex;
  flex-direction: column;
  width: var(--sidebar-width);
  flex: 0 0 var(--sidebar-width);
  background: var(--surface);
  border-right: 1px solid var(--border);
  padding: 20px 14px;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}

.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 8px 24px;
}

.sidebar-brand .brand-lockup {
  font-size: 1.6rem;
}

.sidebar-nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
}

.nav-link {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border-radius: 8px;
  color: var(--text-muted);
  font-size: 0.9rem;
  font-weight: 500;
}
.nav-link:hover {
  color: var(--text);
  background: var(--surface-raised);
  text-decoration: none;
}
.nav-link.active {
  color: var(--text);
  background: var(--accent-soft);
}
.nav-link.active .nav-icon {
  color: var(--accent);
}

.nav-icon {
  display: inline-flex;
  color: var(--text-muted);
  flex-shrink: 0;
}
.nav-icon svg {
  width: 18px;
  height: 18px;
  display: block;
}

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

.page {
  flex: 1;
  min-width: 0;
  /* The default page is a reading page: a sensible width, centred in the
     space beside the sidebar. .page-wide (lists, tables, grids) is fluid. */
  max-width: 1180px;
  margin-inline: auto;
  padding: 32px var(--page-pad-x) 64px;
}

.page-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 24px;
  gap: 12px;
  flex-wrap: wrap;
}

.page-header h1 {
  margin: 0;
  font-size: 1.5rem;
}

.back-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--text-muted);
  font-size: 0.85rem;
  margin-bottom: 16px;
}
.back-link:hover {
  color: var(--text);
  text-decoration: none;
}

@media (max-width: 720px) {
  .app-shell {
    flex-direction: column;
  }
  .sidebar {
    position: static;
    width: 100%;
    height: auto;
    flex-direction: row;
    align-items: center;
    border-right: none;
    border-bottom: 1px solid var(--border);
  }
  .sidebar-brand {
    padding: 6px 8px;
  }
  /* The nav wraps onto more rows on a phone. flex: auto, because the
     desktop rule's flex-basis (the sidebar width) becomes a fixed HEIGHT
     once the shell is a column, clipping the wrapped rows. */
  .sidebar {
    flex-wrap: wrap;
    flex: 0 0 auto;
  }
  .sidebar-footer {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
  }
  .sidebar-footer .btn-block {
    width: auto;
  }
  .sidebar-nav {
    flex-direction: row;
    flex-wrap: wrap;
  }
  .sidebar-footer {
    margin-top: 0;
    padding-top: 0;
    border-top: none;
  }
  .page {
    padding: 24px 20px 48px;
  }
}

/* --- buttons --------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 9px 16px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--surface-raised);
  color: var(--text);
  font-size: 0.9rem;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, transform 0.1s ease;
}
.btn:hover {
  border-color: var(--accent);
}
.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
  font-weight: 600;
  box-shadow: 0 4px 14px var(--accent-glow);
}
.btn-primary:hover {
  background: var(--accent-hover);
}

.btn-ghost {
  background: transparent;
}

/* Irreversible actions (data.html's deletion request), and Log out in the
   sidebar, which must read as different from its neighbours. */
.btn-danger {
  background: transparent;
  border-color: var(--danger);
  color: var(--danger);
  font-weight: 600;
}

.btn-block {
  width: 100%;
}
/* A second full-width button under the first. */
.btn-block.btn-stack {
  margin-top: 8px;
}
/* Pushes a button to the far end of a flex row. */
.btn.push-right {
  margin-left: auto;
}

/* --- forms ------------------------------------------------------------ */

label {
  display: block;
  font-size: 0.85rem;
  color: var(--text-muted);
  margin-bottom: 6px;
}

input,
textarea,
select {
  width: 100%;
  padding: 10px 12px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
  font-size: 0.95rem;
  font-family: inherit;
}
input:focus,
textarea:focus,
select:focus {
  outline: none;
  border-color: var(--accent);
}

.field {
  margin-bottom: 16px;
}

/* --- tab bar (device list active/retired) --------------------------- */

.tab-bar {
  display: flex;
  gap: 4px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--border);
}
.tab-btn {
  padding: 8px 16px;
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  color: var(--text-muted);
  font-size: 0.9rem;
  font-family: inherit;
  cursor: pointer;
}
.tab-btn:hover {
  color: var(--text);
}
.tab-btn.active {
  color: var(--text);
  border-bottom-color: var(--accent);
}

/* --- filter bar (device list search/status) ------------------------- */

.filter-bar {
  display: flex;
  gap: 12px;
  margin-bottom: 20px;
}
.filter-bar input[type="search"] {
  flex: 1;
}
.filter-bar select {
  width: auto;
  min-width: 160px;
}

/* Organization filter above the device list (dashboard.html). Hidden
   when the user can see only one organization. */
.org-filter {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 16px;
}
.org-filter label {
  margin-bottom: 0;
}
.org-filter select {
  width: auto;
  min-width: 200px;
  max-width: 100%;
}

/* --- privilege selector -------------------------------------------- */

.privilege-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 10px;
}

.privilege-card {
  text-align: left;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px 14px;
  cursor: pointer;
  color: var(--text);
  font-family: inherit;
}
.privilege-card:hover {
  border-color: var(--accent);
}
.privilege-card:disabled {
  cursor: not-allowed;
  opacity: 0.55;
}
.privilege-card:disabled:hover {
  border-color: var(--border);
}
.privilege-card.selected {
  border-color: var(--accent);
  background: var(--surface-raised);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.privilege-card-title {
  font-weight: 600;
  font-size: 0.9rem;
  margin-bottom: 4px;
}
.privilege-card-desc {
  color: var(--text-muted);
  font-size: 0.78rem;
}
.privilege-card-danger.selected {
  border-color: var(--danger);
  box-shadow: inset 0 0 0 1px var(--danger);
}
.privilege-card-danger .privilege-card-title {
  color: var(--danger);
}

/* --- login page --------------------------------------------------------- */

.login-shell {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

.login-card {
  position: relative;
  width: 100%;
  max-width: 360px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 32px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.35);
}

/* The signed-out pages' Theme button, alone, top-right of the card. */
.login-theme {
  position: absolute;
  top: 12px;
  right: 12px;
}

.login-brand {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 20px;
  /* Room for the Theme button at the card's top-right corner. */
  padding-right: 48px;
}

.login-card h1 {
  margin: 0;
  font-size: 1.3rem;
}
.login-card h1.login-brand-h1 {
  font-size: 2rem;
  font-weight: 500;
  line-height: 1;
}

.login-card p.muted {
  margin-top: 0;
  margin-bottom: 24px;
}
/* The line under a signed-out form ("Back to sign in", "Already have an
   account?") and the small link right under a submit button. Classes, not
   style="": the Content-Security-Policy allows no inline styles. */
.login-card p.muted.login-foot {
  margin: 16px 0 0;
}
.login-card p.muted.login-sub-link {
  margin: 12px 0 0;
}

/* --- cards / grid ------------------------------------------------------- */

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(17.5rem, 100%), 1fr));
  gap: 16px;
}

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px;
  display: block;
  color: var(--text);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
  transition: border-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}
.card:hover {
  border-color: var(--accent);
  text-decoration: none;
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
}

.card-title-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
  gap: 8px;
}

.card-title-row h3 {
  margin: 0;
  font-size: 1.05rem;
  overflow-wrap: anywhere;
}

/* --- badges --------------------------------------------------------------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
  white-space: nowrap;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  color: var(--text-muted);
}
.badge::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}

/* A list's paging footer: the "showing N-M" line and its control. */
.list-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 12px;
  flex-wrap: wrap;
}

/* The findings grid holds three cells in two columns, so the last one
   spans rather than leaving a ragged gap beside it. */
.findings-span {
  grid-column: 1 / -1;
}

.list-footer-actions {
  display: flex;
  gap: 8px;
}

/* Attribution, not a risk level: the "ITAI" marker on a notice row says who
   wrote the row, and colouring it like a risk badge would read as one. */
.badge[data-source="itai"] {
  color: var(--text-muted);
  border-color: var(--text-muted);
}

.badge[data-status="idle"],
.badge[data-status="approved"],
.badge[data-status="resolved_by_itai"],
.badge[data-status="tech_resolved_manually"],
.badge[data-status="self_resolved"] {
  color: var(--success);
  border-color: var(--success);
}

/* A verification check ITAI did not use: neutral, never success green. */
.badge[data-status="not_used"] {
  color: var(--text-muted);
  border-color: var(--text-muted);
}

.badge[data-status="running"] {
  color: var(--info);
  border-color: var(--info);
}

/* Waiting for a free diagnosis slot: about to run, so the running blue. */
.badge[data-status="waiting"] {
  color: var(--info);
  border-color: var(--info);
}

.badge[data-status="awaiting_review"] {
  color: var(--warning);
  border-color: var(--warning);
}

.badge[data-status="offline"],
.badge[data-status="unreachable"] {
  color: var(--danger);
  border-color: var(--danger);
}

/* A duplicate merged into another ticket: closed, neutral. */
.badge[data-status="merged"] {
  color: var(--text-muted);
  border-color: var(--text-muted);
}

/* Escalated waits on a technician; it is not an error. Amber, like
   awaiting review. So is a diagnosis a technician stopped. */
.badge[data-status="escalated"],
.badge[data-status="stopped"] {
  color: var(--warning);
  border-color: var(--warning);
}

.badge[data-risk="low"] {
  color: var(--success);
  border-color: var(--success);
}
.badge[data-risk="medium"] {
  color: var(--warning);
  border-color: var(--warning);
}
.badge[data-risk="high"] {
  color: var(--danger);
  border-color: var(--danger);
}

/* --- remediation plan ------------------------------------------------------ */

.remediation-steps {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 16px;
}

.remediation-step {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px 16px;
  background: var(--surface-raised);
}

.remediation-step summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  cursor: pointer;
  color: var(--text);
  font-weight: 500;
  list-style: none;
}
.remediation-step summary::-webkit-details-marker {
  display: none;
}

.remediation-step-desc {
  flex: 1 1 220px;
  min-width: 0;
}

/* The plan often sits in a narrow column (beside the findings). Its badges
   wrap under the description instead of squeezing it to a word per line.
   Command and Rollback sit above their code, which gets the step's full
   width and scrolls sideways (pre's overflow-x) instead of pushing past the
   panel's edge. It is never soft-wrapped: a wrap would read like a real
   line break, or split a switch such as -Force, in the one place the
   approver has to read the command exactly. */
.remediation-step summary {
  flex-wrap: wrap;
  justify-content: flex-start;
}
.remediation-step .stat-list {
  grid-template-columns: minmax(0, 1fr);
}
.remediation-step .stat-list dt {
  padding-bottom: 0;
  border-bottom: none;
}
/* The global input rule (width: 100%) made the checkbox take the row. */
.remediation-step-approve input[type="checkbox"] {
  width: auto;
  flex: 0 0 auto;
}

.remediation-step-body {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

.remediation-step-approve {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
  cursor: pointer;
}
.remediation-step-approve input:disabled {
  cursor: not-allowed;
}

/* A checkbox sitting under a field, e.g. the install page's "also install
   prerequisites" toggle. Same shape as .remediation-step-approve above. */
.checkbox-label {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  cursor: pointer;
  font-weight: normal;
}

/* The box itself keeps its natural size (a .field input rule would stretch
   it), and a wrapped label lines up with its first line. */
.checkbox-label input[type="checkbox"],
.checkbox-label input[type="radio"] {
  width: auto;
  flex: none;
  margin: 0;
}

/* Receiver updates: the From/until hours on one row under "Any time". */
.updates-window {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 8px 0 12px;
}
.updates-window label { margin: 0; font-weight: normal; }
.updates-window select { width: auto; }

.checkbox-label.checkbox-label-wrap {
  align-items: flex-start;
}

.checkbox-label.checkbox-label-wrap input[type="checkbox"],
.checkbox-label.checkbox-label-wrap input[type="radio"] {
  margin-top: 3px;
}

.remediation-step-flagged {
  border-color: var(--danger);
}

.remediation-scrutiny-warning {
  background: rgba(239, 87, 87, 0.12);
  border: 1px solid var(--danger);
  color: var(--text);
  border-radius: 8px;
  padding: 10px 14px;
  margin-bottom: 12px;
  font-size: 0.9rem;
}
.remediation-scrutiny-warning ul {
  margin: 6px 0 0;
  padding-left: 20px;
}

/* --- stat list -------------------------------------------------------------- */

.stat-list {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0;
  margin: 0;
  font-size: 0.85rem;
}
.stat-list dt,
.stat-list dd {
  padding: 7px 0;
  border-bottom: 1px solid var(--border);
}
.stat-list dt {
  color: var(--text-muted);
  padding-right: 20px;
  white-space: nowrap;
}
.stat-list dd {
  margin: 0;
  overflow-wrap: anywhere;
}
.stat-list dt:last-of-type,
.stat-list dd:last-of-type {
  border-bottom: none;
}

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

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}

th,
td {
  text-align: left;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
}

th {
  color: var(--text-muted);
  font-weight: 600;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

tr.clickable {
  cursor: pointer;
}
tr.clickable:hover {
  background: var(--surface-raised);
}

.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px;
  margin-bottom: 20px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
}

.panel h2 {
  margin: 0 0 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
  font-size: 1.05rem;
  font-weight: 600;
}

.findings-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}
.findings-grid > div {
  min-width: 0;
}
.findings-grid h4 {
  margin: 0 0 4px;
  font-size: 0.8rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.findings-grid p {
  margin: 0;
  white-space: pre-wrap;
}

.technician-note-row td {
  padding: 0;
  border-top: none;
}
.technician-note {
  background: rgba(255, 196, 0, 0.08);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  padding: 10px 14px;
  margin: 4px 0;
}
.badge-note {
  color: var(--accent);
  border-color: var(--accent);
}
.technician-note-meta {
  margin-left: 8px;
  color: var(--text-muted);
  font-size: 0.85rem;
}
.technician-note-body {
  margin: 6px 0 0;
  white-space: pre-wrap;
}

.error-banner {
  background: rgba(239, 87, 87, 0.12);
  border: 1px solid var(--danger);
  color: var(--danger);
  border-radius: var(--radius);
  padding: 12px 16px;
  margin-bottom: 16px;
}

.success-banner {
  background: var(--success-soft);
  border: 1px solid var(--success);
  color: var(--success);
  border-radius: var(--radius);
  padding: 12px 16px;
  margin-bottom: 16px;
}

.mismatch-banner {
  background: var(--accent-soft);
  border: 1px solid var(--warning);
  color: var(--text);
  border-radius: var(--radius);
  padding: 12px 16px;
  margin-bottom: 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.clock-skew-banner,
.uninstall-notice,
.hostname-conflict-notice,
.restore-notice {
  background: var(--accent-soft);
  border: 1px solid var(--warning);
  color: var(--text);
  border-radius: var(--radius);
  padding: 12px 16px;
  margin-bottom: 16px;
}

.uninstall-notice[data-kind="failed"] {
  border-color: var(--danger, var(--warning));
}

.empty-state {
  color: var(--text-muted);
  text-align: center;
  padding: 48px 16px;
}

code,
pre {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.82rem;
}

pre {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px;
  overflow-x: auto;
  margin: 4px 0 0;
}

details summary {
  cursor: pointer;
  color: var(--text-muted);
}

/* ITAI support access notice (dashboard, superadmins only). */
.support-banner {
  border: 1px solid #b7791f;
  background: rgba(183, 121, 31, 0.12);
  color: inherit;
  border-radius: var(--radius);
  padding: 12px 16px;
  margin-bottom: 16px;
}
.support-banner[hidden] { display: none; }

/* Diagnostics-only (remediation switch off): shown on the ticket's plan and
   in Settings. A state to know about, not an error, so amber like the
   support notice rather than red. */
.remediation-off-notice {
  border: 1px solid #b7791f;
  background: rgba(183, 121, 31, 0.12);
  color: inherit;
  border-radius: 8px;
  padding: 10px 14px;
  margin-bottom: 12px;
}

/* People screen (users.html): a group label that isn't a <label>, and the
   per-org ticks indented under "All organizations". */
.field-label {
  display: block;
  font-weight: 600;
  margin-bottom: 6px;
}
.org-choices {
  margin-left: 24px;
}
.access-fieldset,
.org-choices {
  border: 0;
  padding: 0;
  min-width: 0;
}
.table-scroll {
  overflow-x: auto;
  max-width: 100%;
}
/* Free text in a table (a ticket's notes) wraps anywhere, so one long path
   or address cannot stretch the table past its column. */
td.cell-notes {
  overflow-wrap: anywhere;
  min-width: 12rem;
}
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* --- ticket page ------------------------------------------------------------ */

/* The ticket page has a right-hand column, so it may use more of a wide
   screen than the list pages. */
.page.page-wide {
  max-width: none;
  margin-inline: 0;
}
/* Forms and settings: full width would stretch a text field across a 4K
   screen, so they keep a reading cap, centred, with their right rail beside
   them (see the wide breakpoints at the end of this file). */
.page.page-wide.page-reading {
  max-width: var(--page-reading-max);
  margin-inline: auto;
}
/* A single-column page of short panels (Account): a centred column rather
   than panels stretched across a wide screen. Fluid: it only caps, so a
   phone gets the full width. */
.page.page-wide.page-reading.page-centered {
  max-width: min(var(--page-reading-max), 52rem);
}

.ticket-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}
.ticket-title {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  min-width: 0;
}
.ticket-title h1 {
  margin: 0;
  font-size: 1.4rem;
  overflow-wrap: anywhere;
}
.ticket-subtitle {
  flex-basis: 100%;
  font-size: 0.85rem;
  overflow-wrap: anywhere;
}
.ticket-header-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.ticket-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
  align-items: start;
}
@media (min-width: 1100px) {
  .ticket-layout {
    grid-template-columns: minmax(0, 1fr) 300px;
  }
}
/* The right-hand column holds the transcript by default: wider when the
   screen allows, so a command and its output read comfortably. */
@media (min-width: 1280px) {
  .ticket-layout {
    grid-template-columns: minmax(0, 1fr) 380px;
  }
}
/* Below the wide breakpoint the page renders one column itself
   (TICKET_MOBILE_ORDER); this keeps it one column whatever the width. */
.ticket-layout.ticket-layout-single {
  grid-template-columns: minmax(0, 1fr);
}
.ticket-main,
.ticket-aside {
  min-width: 0;
}

/* Tighter panels on this page: it holds a lot. */
.ticket-layout .panel,
.ticket-notice.panel,
.ticket-banner {
  padding: 14px 16px;
  margin-bottom: 14px;
}
.ticket-layout .panel h2,
.ticket-notice.panel h2 {
  margin-bottom: 10px;
  padding-bottom: 8px;
  font-size: 1rem;
}
.ticket-aside .panel h2 {
  font-size: 0.95rem;
}
.ticket-aside .field {
  margin-bottom: 10px;
}
.ticket-aside .panel > p {
  margin: 0 0 10px;
  font-size: 0.85rem;
}

/* Findings and the remediation plan side by side when there is room for
   both, stacked when there is not; one alone takes the full width. */
.ticket-results {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr));
  gap: 14px;
  align-items: start;
}
.ticket-results > .panel {
  min-width: 0;
  margin-bottom: 0;
}
.ticket-results:not(:empty) {
  margin-bottom: 14px;
}
@media (max-width: 420px) {
  .ticket-results {
    grid-template-columns: minmax(0, 1fr);
  }
}
.findings-list h4 {
  margin: 10px 0 2px;
  font-size: 0.75rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.findings-list h4:first-child {
  margin-top: 0;
}
.findings-list p {
  margin: 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.ticket-issue {
  margin: 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* The escalation banner: why this ticket needs a technician, and the
   one-click way to say it has been handled. */
.ticket-banner {
  border: 1px solid var(--warning);
  background: rgba(224, 167, 46, 0.1);
  border-radius: var(--radius);
}
.ticket-banner h2 {
  margin: 0 0 4px;
  font-size: 1rem;
}
.ticket-banner p {
  margin: 0 0 10px;
  overflow-wrap: anywhere;
}
.ticket-banner-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: flex-start;
}
.ticket-banner-actions textarea {
  flex: 1 1 220px;
  min-width: 0;
}

/* Merged tickets (js/pages/ticket.js): the duplicate's "Merged into" banner
   is neutral, not a warning; the kept ticket lists what was merged into it. */
.ticket-banner.ticket-banner-merged {
  border-color: var(--border);
  background: var(--surface);
}
.merged-from-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.merged-from-list li {
  padding: 8px 0;
  border-top: 1px solid var(--border);
  overflow-wrap: anywhere;
}
.merged-from-list li:first-child {
  border-top: 0;
  padding-top: 0;
}
.merged-from-list .merged-from-note {
  margin: 2px 0 0;
  white-space: pre-wrap;
}
.tickets-filter {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.9rem;
}

/* Collapsible transcript. The summary carries the heading and the count. */
details.transcript-panel > summary {
  list-style: none;
  display: flex;
  align-items: baseline;
  gap: 10px;
  cursor: pointer;
  color: var(--text);
}
details.transcript-panel > summary::-webkit-details-marker {
  display: none;
}
details.transcript-panel > summary::before {
  content: "\25B8" / "";
  color: var(--text-muted);
}
details.transcript-panel[open] > summary::before {
  content: "\25BE" / "";
}
details.transcript-panel > summary h2 {
  margin: 0;
  padding: 0;
  border: none;
}
details.transcript-panel[open] > summary {
  margin-bottom: 10px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border);
}
.transcript-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.transcript-cmd {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 6px 10px;
  min-width: 0;
}
.transcript-cmd > summary,
.transcript-cmd-line {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  color: var(--text);
}
.transcript-command {
  flex: 1 1 240px;
  min-width: 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.transcript-meta {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
  font-size: 0.78rem;
  color: var(--text-muted);
}
/* Output wraps inside its box: never wider than the panel. */
.transcript-output {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  word-break: break-word;
  overflow-x: hidden;
  max-height: 420px;
  overflow-y: auto;
}
.transcript-stderr {
  border-color: var(--danger);
}
.transcript-event {
  font-size: 0.85rem;
  color: var(--text-muted);
  padding: 2px 10px;
  overflow-wrap: anywhere;
}

/* Ticket details (right column). */
.ticket-aside .stat-list dd {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}
.btn-sm {
  padding: 4px 10px;
  font-size: 0.8rem;
}
.btn-link {
  background: none;
  border: none;
  padding: 0;
  color: var(--accent);
  cursor: pointer;
  font-size: 0.8rem;
}
.number-edit {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  width: 100%;
}
.number-edit input {
  flex: 1 1 120px;
  min-width: 0;
}

/* History (right column). */
.timeline {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 0.85rem;
}
.timeline li {
  position: relative;
  padding: 0 0 10px 16px;
  border-left: 2px solid var(--border);
  overflow-wrap: anywhere;
}
.timeline li:last-child {
  padding-bottom: 0;
}
.timeline li::before {
  content: "";
  position: absolute;
  left: -5px;
  top: 5px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--text-muted);
}
.timeline li[data-kind="resolved"]::before,
.timeline li[data-kind="findings"]::before {
  background: var(--success);
}
.timeline li[data-kind="escalated"]::before,
.timeline li[data-kind="stopped"]::before {
  background: var(--warning);
}
.timeline li[data-kind="progress"]::before {
  background: var(--accent);
}
.timeline time {
  display: block;
  font-size: 0.75rem;
  color: var(--text-muted);
}

.approve-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  margin-top: 10px;
}
.approve-hint {
  margin: 0;
  font-size: 0.85rem;
}

/* The approver's responsibility, said once under the Approve button. */
.approve-responsibility {
  margin: 0.5rem 0 0;
  font-size: 0.85rem;
  font-weight: 600;
}

/* --- ticket page: panel layout ---------------------------------------------- */

/* Each panel sits in a section placed by the user's layout
   (js/ticket_layout.js). */
.layout-panel {
  position: relative;
  min-width: 0;
}
/* The collapse control sits in the panel's top-right corner. */
.panel-collapse-btn {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 1;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 6px;
  background: none;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 0.9rem;
  line-height: 1;
}
.panel-collapse-btn:hover,
.panel-collapse-btn:focus-visible {
  border-color: var(--border);
  color: var(--text);
}
.layout-panel > .panel h2,
.layout-panel > .ticket-results > .panel:last-child h2 {
  padding-right: 30px;
}
/* A collapsed panel: one slim bar that opens it again. */
.panel-expand-bar,
.panel-collapsed-preview {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  margin-bottom: 14px;
  padding: 10px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-weight: 600;
  font-size: 0.95rem;
  text-align: left;
  cursor: pointer;
}
.panel-expand-bar::before,
.panel-collapsed-preview::before {
  content: "\25B8" / "";
  color: var(--text-muted);
}
.panel-expand-bar:hover {
  border-color: var(--accent-dim);
}

/* Edit layout mode. */
.layout-editbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
  margin-bottom: 14px;
  padding: 10px 14px;
  border: 1px solid var(--accent-dim);
  border-radius: var(--radius);
  background: var(--accent-soft);
}
.layout-editbar p {
  margin: 0;
  flex: 1 1 320px;
  font-size: 0.9rem;
}
.layout-status {
  font-size: 0.85rem;
}
.layout-editbar-actions {
  display: flex;
  gap: 8px;
}
.layout-editing .layout-column {
  min-height: 160px;
  padding: 8px;
  border: 1px dashed var(--border);
  border-radius: var(--radius);
}
.layout-editing .layout-panel {
  margin-bottom: 10px;
  padding: 6px;
  border: 1px solid var(--accent-dim);
  border-radius: var(--radius);
  background: var(--surface-raised);
  cursor: grab;
}
.layout-editing .layout-panel:last-child {
  margin-bottom: 0;
}
/* While arranging, the panels are a preview: nothing inside them can be
   clicked or typed into, and they are shortened so a column fits on
   screen. */
.layout-editing .layout-panel > :not(.layout-tools) {
  pointer-events: none;
  opacity: 0.6;
  max-height: 180px;
  overflow: hidden;
}
.layout-editing .layout-panel > .panel,
.layout-editing .layout-panel > .ticket-results,
.layout-editing .layout-panel > .panel-collapsed-preview {
  margin-bottom: 0;
}
.layout-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-bottom: 6px;
}
.layout-grip {
  color: var(--text-muted);
  letter-spacing: -3px;
}
.layout-name {
  flex: 1 1 auto;
  font-weight: 600;
  font-size: 0.9rem;
}
.layout-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.layout-move-btn {
  min-width: 32px;
}
.layout-move-btn:disabled {
  opacity: 0.35;
  cursor: default;
}
.layout-panel.is-dragging {
  opacity: 0.4;
}
.layout-panel.drop-before {
  box-shadow: 0 -4px 0 var(--accent);
}
.layout-column.drop-end::after {
  content: "";
  display: block;
  height: 4px;
  margin-top: 6px;
  border-radius: 2px;
  background: var(--accent);
}
.layout-empty {
  margin: 40px 0;
  text-align: center;
}
.panel-placeholder {
  border-style: dashed;
}
.panel-placeholder p {
  margin: 0;
  font-size: 0.85rem;
}

/* The transcript in the narrow right-hand column: the command on its own
   line with its details under it, and smaller output that still wraps. */
.ticket-aside .transcript-command {
  flex-basis: 100%;
}
.ticket-aside .transcript-output {
  font-size: 0.78rem;
}
.transcript-tools {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 8px;
}

/* The transcript's wide view. */
.transcript-dialog {
  width: min(1200px, calc(100vw - 32px));
  max-height: calc(100vh - 48px);
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
}
.transcript-dialog::backdrop {
  background: rgba(0, 0, 0, 0.55);
}
.transcript-dialog-head {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}
.transcript-dialog-head h2 {
  margin: 0;
  font-size: 1rem;
}
.transcript-dialog-head button {
  margin-left: auto;
}
.transcript-dialog-body {
  padding: 12px 16px 16px;
}
.transcript-dialog-body .transcript-output {
  max-height: 60vh;
}

/* --- report a problem (sidebar, every page) ------------------------------ */
.report-panel {
  position: fixed;
  left: 16px;
  bottom: 16px;
  z-index: 20;
  width: min(360px, calc(100vw - 32px));
  max-height: calc(100vh - 32px);
  overflow: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}
.report-panel h2 {
  margin: 0 0 8px;
  font-size: 1rem;
}
.report-panel textarea {
  width: 100%;
  resize: vertical;
}
.report-actions {
  display: flex;
  gap: 8px;
}

/* --- owner page (owner.html) and its charts (js/charts.js) ---------------- */
.owner-controls {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.owner-controls .field-label {
  margin: 0;
}
.owner-subhead {
  font-size: 0.9rem;
  font-weight: 600;
  margin: 18px 0 8px;
  color: var(--text);
}
.owner-note {
  margin-top: -6px;
  font-size: 0.85rem;
}
.stat-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
  gap: 12px;
  margin-bottom: 20px;
}
.stat-tile {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px 14px;
}
.owner-panel .stat-tile {
  background: var(--surface-raised);
}
.stat-tile-label {
  font-size: 0.8rem;
  color: var(--text-muted);
}
.stat-tile-value {
  font-size: 1.4rem;
  font-weight: 700;
  margin-top: 2px;
  font-variant-numeric: tabular-nums;
}
.stat-tile-note {
  font-size: 0.78rem;
  margin-top: 2px;
}
.chart-block {
  margin-bottom: 8px;
}
.chart {
  display: block;
  width: 100%;
  height: auto;
}
.chart-grid {
  stroke: var(--border);
  stroke-width: 1;
}
.chart-axis {
  fill: var(--text-muted);
  font-size: 16px;
}
.chart-bar:hover {
  opacity: 0.8;
}
.chart-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  font-size: 0.82rem;
  color: var(--text);
  margin-bottom: 6px;
}
.chart-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.chart-swatch {
  width: 10px;
  height: 10px;
  border-radius: 2px;
  display: inline-block;
}
/* Series colours (js/charts.js chartColorClass): classes, not style="",
   which the Content-Security-Policy would drop. */
.chart-bar.chart-c1 { fill: var(--chart-1); }
.chart-bar.chart-c2 { fill: var(--chart-2); }
.chart-swatch.chart-c1 { background: var(--chart-1); }
.chart-swatch.chart-c2 { background: var(--chart-2); }
.chart-table summary {
  cursor: pointer;
  font-size: 0.82rem;
  color: var(--text-muted);
}
.chart-table table {
  font-size: 0.82rem;
}
.hbar-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.hbar-row {
  margin-bottom: 8px;
}
.hbar-head {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  font-size: 0.85rem;
}
.hbar-label {
  overflow-wrap: anywhere;
}
.hbar-value {
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
/* An <svg> holding one <rect>: the fill's width is the rect's width
   attribute (js/charts.js hbarListHtml). */
.hbar-track {
  display: block;
  width: 100%;
  height: 6px;
  background: var(--surface-raised);
  border-radius: 3px;
  margin-top: 3px;
  overflow: hidden;
}
.hbar-fill {
  fill: var(--chart-1);
}
.report-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.report-item {
  border-top: 1px solid var(--border);
  padding: 10px 0;
}
.report-meta {
  font-size: 0.78rem;
  color: var(--text-muted);
  margin-bottom: 4px;
}
.report-text {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font-size: 0.9rem;
}

/* Two-step sign-in (two-step.html). The QR code keeps a white background
   in the dark theme too: phone cameras read dark-on-light. */
.qr-code {
  display: block;
  width: 200px;
  height: 200px;
  background: #fff;
  border-radius: 8px;
  margin: 8px 0 12px;
}

.two-step-key {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 15px;
  letter-spacing: 0.05em;
  word-break: break-all;
}

.recovery-codes {
  list-style: none;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 6px 16px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 15px;
}

.two-step-notice {
  border: 1px solid #b7791f;
  background: rgba(183, 121, 31, 0.12);
  border-radius: 8px;
  padding: 10px 14px;
  margin-bottom: 12px;
}

/* --- sidebar footer: one group (Theme, Report a problem, Documentation, Account, Log out) --- */

/* Documentation, Report a problem, Account and Log out are one group. Log out
   is in it but reads as different (the danger button style) and sits a small
   gap below the rest, so a stray click is unlikely. */
.sidebar-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.sidebar-footer .sidebar-logout {
  margin-top: 8px;
}
/* Account is a full-width, centred, bordered button like its neighbours; the
   icon sits centred beside the label. Its page being open is shown with the
   accent border and soft fill. */
.sidebar-group .sidebar-account:hover {
  text-decoration: none;
}
.sidebar-group .sidebar-account.active {
  border-color: var(--accent);
  background: var(--accent-soft);
}
.sidebar-group .sidebar-account .nav-icon svg {
  width: 16px;
  height: 16px;
}
.sidebar-group .sidebar-account.active .nav-icon {
  color: var(--accent);
}

/* The theme picker: one Theme button in the footer group, and a small popover
   (position: fixed and placed by js/common.js, because the sidebar scrolls and
   would clip an absolutely placed one) listing Dark, Light, Teal and Orange Cream. */
.theme-picker {
  position: relative;
}
.theme-btn .theme-btn-icon {
  display: inline-flex;
  width: 16px;
  height: 16px;
}
.theme-btn .theme-btn-icon svg {
  width: 16px;
  height: 16px;
}
.theme-btn-compact {
  width: 36px;
  height: 36px;
  padding: 0;
}
.theme-menu {
  position: fixed;
  z-index: 30;
  min-width: 170px;
  max-width: calc(100vw - 16px);
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 6px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}
.theme-menu[hidden] {
  display: none;
}
.theme-option {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 0.9rem;
  text-align: left;
  cursor: pointer;
}
.theme-option:hover,
.theme-option:focus-visible {
  background: var(--surface-raised);
}
.theme-option:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
.theme-option[aria-checked="true"] {
  background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.theme-option-name {
  flex: 1 1 auto;
}
.theme-option-check {
  flex: none;
  width: 1em;
  color: var(--accent);
  font-weight: 700;
  visibility: hidden;
}
.theme-option[aria-checked="true"] .theme-option-check {
  visibility: visible;
}
/* A two-tone dot showing that theme's own background and accent, whatever
   theme is showing now: the --swatch-* tokens hold each theme's pair. */
.theme-swatch {
  flex: none;
  width: 18px;
  height: 18px;
  border: 1px solid var(--text-muted);
  border-radius: 50%;
}
.theme-swatch[data-swatch="dark"] {
  background: linear-gradient(135deg, var(--swatch-dark-bg) 50%, var(--swatch-dark-accent) 50%);
}
.theme-swatch[data-swatch="light"] {
  background: linear-gradient(135deg, var(--swatch-light-bg) 50%, var(--swatch-light-accent) 50%);
}
.theme-swatch[data-swatch="teal"] {
  background: linear-gradient(135deg, var(--swatch-teal-bg) 50%, var(--swatch-teal-accent) 50%);
}
.theme-swatch[data-swatch="orange-cream"] {
  background: linear-gradient(135deg, var(--swatch-orange-cream-bg) 50%, var(--swatch-orange-cream-accent) 50%);
}
@media (max-width: 720px) {
  .sidebar-group {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
  }
  .sidebar-footer .sidebar-logout {
    margin-top: 0;
    margin-left: 12px;
  }
  .theme-picker {
    align-self: center;
  }
  .theme-picker .btn-block {
    width: auto;
  }
}

/* --- two-column pages ---------------------------------------------------- */

/* The ticket page's pattern for the other pages: main content on the left,
   secondary panels (summaries, filters, actions) in a right-hand column on
   a wide screen, one stacked column on a narrow one. Put page-wide on
   <main> so the page may use the width. */
.page-cols {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
  align-items: start;
}
@media (min-width: 1100px) {
  .page-cols {
    grid-template-columns: minmax(0, 1fr) 320px;
  }
}
@media (min-width: 1280px) {
  .page-cols {
    grid-template-columns: minmax(0, 1fr) 380px;
  }
}
.page-col-main,
.page-col-side {
  min-width: 0;
}
/* The rail never has anything drawn over it. The two columns are grid tracks
   (no absolute positioning). A table wider than the main column scrolls
   sideways in its own .table-scroll. As the backstop for anything else too
   wide, the column clips what would spill sideways, so nothing can be painted
   under the rail. "clip", not "auto": auto would make the column a scroll
   container in both directions and cut off menus and focus rings; clip only
   acts on x, and the small margin leaves room for a focus ring. */
.page-col-main {
  overflow-x: clip;
  overflow-clip-margin: 6px;
}
.page-col-side .panel {
  padding: 14px 16px;
}
.page-col-side .panel h2 {
  font-size: 1rem;
}
/* Below the wide breakpoint the side column sits under the main one; an
   empty root there takes no room. */
.page-col-side:empty,
.page-col-main:empty {
  display: none;
}

/* --- Reset layout ---------------------------------------------------------------
   Every page with movable modules (owner overview, ticket) ends its module
   area with the same control, at the bottom right. */
.layout-reset-bar {
  display: flex;
  justify-content: flex-end;
  margin: 16px 0 0;
}

/* --- collapsible modules (Data & privacy, Settings) -------------------------- */

details.module {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 20px;
  margin-bottom: 16px;
}
details.module > summary {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 12px;
  cursor: pointer;
  color: var(--text);
}
details.module > summary::-webkit-details-marker {
  display: none;
}
details.module > summary::before {
  content: "\25B8" / "";
  color: var(--text-muted);
}
details.module[open] > summary::before {
  content: "\25BE" / "";
}
details.module > summary h2 {
  margin: 0;
  padding: 0;
  border: none;
  font-size: 1.05rem;
}
details.module > summary .module-summary {
  flex-basis: 100%;
  margin: 0;
  padding-left: 1.2em;
  font-size: 0.85rem;
  color: var(--text-muted);
}
details.module[open] > summary {
  margin-bottom: 12px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border);
}
details.module > .module-body > .panel {
  border: none;
  padding: 0;
  margin: 0;
  background: transparent;
}
.settings-group-title {
  margin: 24px 0 10px;
  font-size: 0.8rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* --- searchable pickers (Data & privacy download) -------------------------- */

.picker-list {
  list-style: none;
  margin: 8px 0;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  max-height: 260px;
  overflow-y: auto;
}
.picker-list li + li {
  border-top: 1px solid var(--border);
}
.picker-item {
  display: block;
  width: 100%;
  text-align: left;
  padding: 8px 12px;
  background: transparent;
  border: none;
  color: var(--text);
  cursor: pointer;
  overflow-wrap: anywhere;
}
.picker-item:hover,
.picker-item[aria-pressed="true"] {
  background: var(--accent-soft);
}
.picker-pager {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

/* A side column that holds filters or a chooser reads first on a narrow
   screen, then moves to the right on a wide one. */
@media (max-width: 1099px) {
  .page-col-first-narrow {
    order: -1;
  }
}
.page-col-side .filter-bar,
.page-col-side .tab-bar {
  flex-wrap: wrap;
}
.page-col-side .filter-bar > * {
  flex: 1 1 100%;
  min-width: 0;
}

/* --- open tickets flag (device cards and the device page) -------------------- */

.badge-open-tickets {
  background: var(--accent-soft);
  color: var(--text);
}
.card-flags {
  margin: 6px 0 0;
}
.open-ticket-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.open-ticket-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 10px;
  padding: 6px 0;
}
.open-ticket-row + .open-ticket-row {
  border-top: 1px solid var(--border);
}

/* A side column with nothing in it gives its width to the main one. Set
   from the page's script (no :has). */
.page-col-side.is-empty {
  display: none;
}
.page-cols.side-empty {
  grid-template-columns: minmax(0, 1fr);
}

/* --- reboot-aware remediation: a restart in progress ---------------------------- */

.badge-restart {
  background: rgba(224, 167, 46, 0.1); /* the ticket banner's amber tint (test_theme_teal.js ALLOWED) */
  color: var(--text);
  border: 1px solid var(--warning);
}
.ticket-banner-restart {
  border: 1px solid var(--warning);
  border-radius: var(--radius);
  background: var(--surface);
}
.ticket-banner-restart h2 {
  margin: 0 0 6px;
  font-size: 1rem;
}
.open-ticket-restart {
  font-size: 0.85rem;
}
.restart-notice {
  margin: 0;
}
.restart-timing select {
  margin-left: 8px;
}
.verification-list {
  margin: 6px 0 0;
  padding-left: 18px;
}
.verification-check code {
  overflow-wrap: anywhere;
}

/* --- themed dialogs (js/dialog.js): confirm, prompt and alert ---------------- */

/* The same look as the Export to CSV dialog above: surface, border, radius,
   the dimmed backdrop. Colours are theme tokens, except the black backdrop tint (as elsewhere). */
.itai-dialog-backdrop {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  overflow-y: auto;
  background: rgba(0, 0, 0, 0.55);
}
.itai-dialog {
  width: min(520px, calc(100vw - 32px));
  max-height: calc(100vh - 32px);
  overflow-y: auto;
  padding: 20px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  scrollbar-color: var(--border) transparent;
}
.itai-dialog-danger {
  border-color: var(--danger);
}
.itai-dialog-title {
  margin: 0 0 10px;
  font-size: 1.15rem;
}
.itai-dialog-message {
  margin: 0 0 14px;
  font-size: 0.92rem;
  /* Keeps the line breaks the caller wrote, and wraps a long hostname. */
  white-space: pre-line;
  overflow-wrap: anywhere;
}
.itai-dialog-field {
  margin: 0 0 14px;
}
.itai-dialog-input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
.itai-dialog-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 8px;
}
.itai-dialog-actions .btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
@media (max-width: 720px) {
  .itai-dialog {
    padding: 14px;
  }
  .itai-dialog-actions .btn {
    flex: 1 1 auto;
  }
}

/* --- devices page: view toggle, list view, pager ---------------------------- */

.view-toggle {
  display: flex;
  gap: 0;
  margin-bottom: 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.view-btn {
  flex: 1 1 0;
  padding: 7px 12px;
  background: var(--surface);
  border: none;
  color: var(--text-muted);
  font-family: inherit;
  font-size: 0.9rem;
  cursor: pointer;
}
.view-btn + .view-btn {
  border-left: 1px solid var(--border);
}
.view-btn:hover {
  color: var(--text);
}
.view-btn.active {
  background: var(--accent-soft);
  color: var(--text);
  font-weight: 600;
}
.view-btn:focus-visible,
.sort-btn:focus-visible,
.export-handle:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
.view-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 14px;
}
.view-row select {
  width: auto;
  min-width: 90px;
}

.device-table {
  /* Narrower than this the columns crush: scroll sideways instead. */
  min-width: 760px;
}
.device-table th,
.device-table td {
  padding: 8px 10px;
  vertical-align: top;
}
.device-table .dt-nowrap {
  white-space: nowrap;
}
.device-table .dt-name a {
  font-weight: 600;
  overflow-wrap: anywhere;
}
.device-table .dt-mono {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 0.85rem;
  overflow-wrap: anywhere;
}
.device-table .dt-flags {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px;
}
.sort-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 0;
  background: none;
  border: none;
  color: inherit;
  font: inherit;
  text-transform: inherit;
  letter-spacing: inherit;
  cursor: pointer;
  white-space: nowrap;
}
.sort-btn:hover {
  color: var(--text);
}
th[aria-sort="ascending"] .sort-btn,
th[aria-sort="descending"] .sort-btn {
  color: var(--text);
}
.sort-mark {
  font-size: 0.65rem;
  min-width: 0.7em;
}

.pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 16px;
  margin-top: 16px;
}
.pager[hidden] {
  display: none;
}
.pager-buttons {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

/* --- devices page: Export to CSV dialog ---------------------------------------- */

.export-dialog {
  width: min(520px, calc(100vw - 32px));
  max-height: calc(100vh - 32px);
  padding: 20px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  overflow: hidden;
  scrollbar-color: var(--border) transparent;
}
/* Head and buttons stay put; only the column list scrolls. */
.export-dialog[open] {
  display: flex;
  flex-direction: column;
}
.export-dialog::backdrop {
  background: rgba(0, 0, 0, 0.55);
}
.export-head h2 {
  margin: 0 0 10px;
  font-size: 1.15rem;
}
.export-scope,
.export-hint {
  margin: 0 0 8px;
  font-size: 0.85rem;
}
.export-columns {
  list-style: none;
  margin: 12px 0;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  flex: 1 1 auto;
  min-height: 96px;
  overflow-y: auto;
  scrollbar-color: var(--border) transparent;
}
.export-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  background: var(--surface);
}
.export-row + .export-row {
  border-top: 1px solid var(--border);
}
.export-row:hover {
  background: var(--surface-raised);
}
.export-handle {
  flex: none;
  padding: 4px 6px;
  background: none;
  border: none;
  border-radius: 6px;
  color: var(--text-muted);
  font-size: 1rem;
  line-height: 1;
  letter-spacing: -2px;
  cursor: grab;
}
.export-handle:hover {
  color: var(--text);
}
.export-label {
  flex: 1 1 auto;
  min-width: 0;
  overflow-wrap: anywhere;
}
.export-row .btn-sm {
  flex: none;
}
.export-status {
  min-height: 1.3em;
  margin: 0 0 8px;
  color: var(--danger);
  font-size: 0.9rem;
}
.export-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.export-actions-end {
  display: inline-flex;
  gap: 8px;
}

/* An on/off switch: a real checkbox (keyboard and screen readers) drawn as a track. */
.switch {
  position: relative;
  flex: none;
  display: inline-block;
  width: 40px;
  height: 22px;
}
.switch input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.switch-track {
  position: absolute;
  inset: 0;
  border-radius: 999px;
  background: var(--border);
  transition: background 0.15s ease;
  pointer-events: none;
}
.switch-track::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--text);
  transition: transform 0.15s ease, background 0.15s ease;
}
.switch input:checked + .switch-track {
  background: var(--accent);
}
.switch input:checked + .switch-track::after {
  transform: translateX(18px);
  background: var(--on-accent);
}
.switch input:focus-visible + .switch-track {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

@media (max-width: 720px) {
  .export-dialog {
    padding: 14px;
  }
  .export-row {
    flex-wrap: wrap;
  }
  .pager {
    justify-content: center;
  }
}
@media (prefers-reduced-motion: reduce) {
  .switch-track,
  .switch-track::after {
    transition: none;
  }
}

/* --- sign-in: "Keep me signed in" row ----------------------------------------- */

/* The whole sentence is ONE flex item (a bare text run and a span would each
   become their own item and split the line), beside the box. */
.remember-me .remember-me-text {
  min-width: 0;
  line-height: 1.4;
}
.remember-me .remember-me-note {
  margin: 6px 0 0;
  padding-left: 21px;
  font-size: 0.82rem;
  line-height: 1.45;
}

/* --- People: empty state and the role disclosure -------------------------------- */

.empty-card {
  text-align: left;
}
.empty-card h2 {
  margin: 0 0 6px;
  font-size: 1.05rem;
}
.empty-card p {
  margin: 0 0 14px;
}
details.role-help > .module-body {
  display: flex;
  flex-direction: column;
}
details.role-row {
  border-top: 1px solid var(--border);
  padding: 8px 0;
}
details.role-row:first-child {
  border-top: none;
  padding-top: 0;
}
details.role-row > summary {
  list-style: none;
  display: block;
  cursor: pointer;
  color: var(--text);
}
details.role-row > summary > .muted {
  display: block;
  padding-left: 1.2em;
  font-size: 0.85rem;
}
details.role-row > summary::-webkit-details-marker {
  display: none;
}
details.role-row > summary::before {
  display: inline-block;
  width: 1.2em;
  content: "\25B8" / "";
  color: var(--text-muted);
}
details.role-row[open] > summary::before {
  content: "\25BE" / "";
}
details.role-row > summary:focus-visible,
details.module > summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
details.role-row > p {
  margin: 6px 0 0;
  padding-left: 1.2em;
  font-size: 0.88rem;
}

/* --- Devices: toolbar across the top ----------------------------------------------- */

.devices-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 16px;
  margin-bottom: 16px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border);
}
.devices-toolbar .toolbar-group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 8px;
  min-width: 0;
}
.devices-toolbar .toolbar-find {
  flex: 1 1 520px;
}
.devices-toolbar .toolbar-view {
  flex: 0 0 auto;
  margin-left: auto;
}
.devices-toolbar .tab-btn {
  padding: 8px 10px;
}
.devices-toolbar .tab-bar {
  margin: 0;
  border-bottom: none;
}
.devices-toolbar input[type="search"] {
  flex: 1 1 130px;
  width: auto;
  min-width: 0;
}
.devices-toolbar select {
  width: auto;
  min-width: 0;
  max-width: 100%;
}
.devices-toolbar #status-select {
  flex: 0 1 8.5rem;
}
.devices-toolbar .org-filter {
  margin: 0;
}
.devices-toolbar .org-filter select {
  min-width: 0;
}
/* The select says "All clients" itself; the label stays for screen readers
   and keeps the row short enough to sit beside the search box. */
.devices-toolbar .org-filter label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
.devices-toolbar .view-toggle,
.devices-toolbar .view-row {
  margin: 0;
}

/* --- managed sites: the Devices filter, the bulk bar, the Sites panel ------ */
/* The select says "All sites" itself; the label stays for screen readers,
   as the organization filter's does. */
.devices-toolbar .site-filter {
  margin: 0;
}
.devices-toolbar .site-filter select {
  min-width: 0;
}
.devices-toolbar .site-filter label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
.bulk-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  margin-bottom: 12px;
  padding: 8px 12px;
  border: 1px solid var(--accent-dim);
  border-radius: var(--radius);
  background: var(--accent-soft);
  color: var(--text);
}
.bulk-bar[hidden] {
  display: none;
}
.bulk-count {
  font-weight: 600;
  margin-right: auto;
}
.device-table .dt-select {
  width: 2.2rem;
  padding-right: 0;
}
.device-table .dt-select input {
  width: auto;
}
.sites-table {
  min-width: 420px;
}
.sites-table th,
.sites-table td {
  padding: 8px 10px;
  vertical-align: top;
  text-align: left;
}
.sites-table .sites-name {
  font-weight: 600;
  min-width: 6rem;
  overflow-wrap: break-word;
}
.sites-table .sites-note {
  color: var(--text-muted);
  overflow-wrap: anywhere;
}
.sites-table .sites-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.sites-add {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 0 12px;
  align-items: end;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}
.sites-add .btn {
  justify-self: start;
  margin-bottom: 16px;
}
.client-links {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.devices-toolbar .view-btn {
  flex: 0 0 auto;
  padding: 7px 14px;
}
.devices-toolbar .view-row {
  justify-content: flex-start;
}
@media (max-width: 640px) {
  .devices-toolbar .toolbar-find,
  .devices-toolbar .toolbar-view {
    flex: 1 1 100%;
    margin-left: 0;
  }
  .devices-toolbar .tab-bar {
    flex: 1 1 100%;
  }
  .devices-toolbar .tab-btn {
    flex: 1 1 0;
    padding: 8px 6px;
  }
  .devices-toolbar input[type="search"] {
    flex: 1 1 100%;
  }
  .devices-toolbar .org-filter {
    flex: 1 1 100%;
  }
  .devices-toolbar .org-filter select {
    flex: 1 1 auto;
    width: 100%;
  }
  .devices-toolbar #status-select {
    flex: 1 1 100%;
  }
}

/* --- Large screens ---------------------------------------------------------------------
   The app scales with the screen. A 4K monitor at 150% is about 2560 CSS px
   wide and at 100% about 3840; a 1080p one is 1920. Lists, tables and grids
   fill the width beside the sidebar and add columns; reading pages keep a
   cap that grows with the screen and stays centred; the right-hand rail and
   the sidebar widen; and the base type size steps up a little so text does
   not shrink into the space. Sizes only: colours stay on the theme tokens. */

@media (min-width: 1280px) {
  :root {
    --page-pad-x: 48px;
  }
}
@media (min-width: 1920px) {
  :root {
    font-size: 106.25%;
    --sidebar-width: 256px;
    --page-reading-max: 1760px;
    --page-pad-x: 64px;
    --rail-width: 420px;
  }
  .page-cols {
    grid-template-columns: minmax(0, 1fr) var(--rail-width);
    gap: 24px;
  }
  .ticket-layout {
    grid-template-columns: minmax(0, 1fr) var(--rail-width);
  }
  .card-grid {
    gap: 20px;
  }
}
@media (min-width: 2560px) {
  :root {
    font-size: 118.75%;
    --sidebar-width: 280px;
    --page-reading-max: 2080px;
    --page-pad-x: 96px;
    --rail-width: 500px;
  }
}
@media (min-width: 3200px) {
  :root {
    font-size: 137.5%;
    --sidebar-width: 320px;
    --page-reading-max: 2400px;
    --page-pad-x: 128px;
    --rail-width: 560px;
  }
}

/* --- Install page: the double-click installer card ---------------------- */
/* Theme tokens only, so all three themes follow. */
.install-hero {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 20px;
  margin: 8px 0 18px;
}
.btn-large {
  padding: 14px 26px;
  font-size: 1.05rem;
}
.btn-small {
  padding: 5px 10px;
  font-size: 0.82rem;
}
.install-file-name {
  font-family: ui-monospace, Consolas, monospace;
  color: var(--text-muted);
  font-size: 0.85rem;
  overflow-wrap: anywhere;
}
.install-steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 8px;
}
.install-step {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-raised);
}
.install-step-summary {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  cursor: pointer;
  list-style: none;
  font-weight: 600;
  font-size: 0.98rem;
}
.install-step-summary::-webkit-details-marker {
  display: none;
}
.install-step-summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
  border-radius: var(--radius);
}
.install-step-title {
  flex: 1 1 auto;
  min-width: 0;
}
.install-step-icon {
  flex: 0 0 auto;
  color: var(--accent);
  line-height: 0;
}
.install-step-icon svg {
  width: 24px;
  height: 24px;
}
.install-step-chevron {
  flex: 0 0 auto;
  display: inline-flex;
  color: var(--text-muted);
  transition: transform 0.15s ease;
}
.install-step-details[open] > .install-step-summary .install-step-chevron {
  transform: rotate(180deg);
}
.install-step-summary:hover .install-step-chevron {
  color: var(--text);
}
@media (prefers-reduced-motion: reduce) {
  .install-step-chevron { transition: none; }
}
.install-step-text {
  padding: 0 14px 12px 50px;
}
.install-step-text p {
  margin: 0 0 6px;
  font-size: 0.9rem;
}
.install-step-see {
  color: var(--text-muted);
}
.install-step-see-label {
  font-weight: 600;
  color: var(--text);
}
.install-wait {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 16px 0 4px;
  padding: 10px 14px;
  border: 1px dashed var(--border);
  border-radius: var(--radius);
}
.install-wait-found {
  border-style: solid;
  border-color: var(--success);
  background: var(--success-soft);
}
.install-wait-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--accent);
  flex: 0 0 auto;
}
.install-wait-found .install-wait-dot {
  background: var(--success);
}
.install-wait-pulse {
  animation: install-wait-pulse 1.4s ease-in-out infinite;
}
@keyframes install-wait-pulse {
  0%, 100% { opacity: 1; box-shadow: 0 0 0 0 var(--accent-glow); }
  50% { opacity: 0.45; box-shadow: 0 0 0 6px var(--accent-glow); }
}
@media (prefers-reduced-motion: reduce) {
  .install-wait-pulse { animation: none; }
}
.install-note {
  font-size: 0.88rem;
  color: var(--text-muted);
  margin: 10px 0 0;
}
details.it-pros > summary {
  cursor: pointer;
  font-weight: 600;
}
details.it-pros[open] > summary {
  margin-bottom: 12px;
}
.it-pros h3 {
  font-size: 0.95rem;
  margin: 18px 0 6px;
}
.it-pros .btn {
  margin: 4px 6px 4px 0;
}

/* Billing explanation (Company settings): a "?" per term that opens a
   short explanation. A <details> element, so it works by keyboard and is
   announced by screen readers without any script. */
.info-tip {
  display: inline-block;
  position: relative;
  vertical-align: middle;
}
.info-tip > summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
}
.info-tip > summary::-webkit-details-marker { display: none; }
.info-tip > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.info-tip[open] > summary { color: var(--text); border-color: var(--accent); }
.info-tip-body {
  position: absolute;
  z-index: 20;
  left: 0;
  top: 24px;
  width: min(320px, calc(100vw - 48px));
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font-weight: normal;
  font-size: 13px;
  line-height: 1.45;
  text-align: left;
  /* The "?" often sits in a row that does not wrap (a label column); the
     explanation must wrap inside its own box, never run past it. */
  white-space: normal;
  overflow-wrap: break-word;
  box-shadow: 0 4px 16px var(--accent-soft);
}
.info-tip-right .info-tip-body { left: auto; right: 0; }
@media (max-width: 720px) {
  /* On a phone the box spans the screen, so a "?" far from the left edge
     never pushes it off the right side. */
  .info-tip-body { position: fixed; left: 16px; right: 16px; top: auto; width: auto; }
}
.label-row { display: flex; align-items: center; gap: 6px; }
.label-row label { margin: 0; }
.billing-explainer h3 { margin: 4px 0 8px; }
.billing-estimate {
  border: 1px solid var(--accent);
  background: var(--accent-soft);
  border-radius: var(--radius);
  padding: 12px 14px;
  margin: 0 0 12px;
}
.billing-estimate-label { font-size: 0.85rem; color: var(--text-muted); }
.billing-estimate-amount { font-size: 1.8rem; font-weight: 700; line-height: 1.2; }
.billing-estimate-line { margin: 4px 0 0; }
.billing-estimate-note { margin: 6px 0 0; font-size: 0.8rem; }
/* A complimentary grant (ITAI staff's), above the estimate. */
.billing-complimentary {
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  padding: 10px 14px;
  margin: 0 0 12px;
}
.billing-complimentary p { margin: 0 0 4px; }
.billing-complimentary p:last-child { margin-bottom: 0; }
.billing-complimentary-line { margin: 4px 0; }
@media (max-width: 720px) {
  .billing-explainer .stat-list { grid-template-columns: 1fr; }
  .billing-explainer .stat-list dt { border-bottom: none; padding-bottom: 0; }
}
.tier-list { margin: 4px 0 0; padding-left: 18px; color: var(--text-muted); font-size: 13px; }
.staff-legacy-billing { margin: 12px 0; }
