/* Predict application styles; imports the font and token files below. */
@import url("fonts.css");
@import url("tokens/colors.css");
@import url("tokens/typography.css");
@import url("tokens/spacing.css");
@import url("tokens/elevation.css");
@import url("pages.css");

/* Short aliases for older class names used in template inline styles. */
:root {
  --bg:      var(--surface-page);
  --panel:   var(--surface-card);
  --panel-2: var(--surface-sunken);
  --line:    var(--border-subtle);
  --text:    var(--text-body);
  --muted:   var(--text-muted);
  --accent:  var(--brand-primary);
  --green:   var(--status-healthy-ink);
  --amber:   var(--status-watch-ink);
  --red:     var(--status-critical-ink);
  --radius:  var(--radius-md);
  font-synthesis: none;
}

* { box-sizing: border-box; }

/* The hidden attribute always wins: any class setting display (flex, inline-block, ...) would
   otherwise override the browser's built-in [hidden] rule and the element stays visible. */
[hidden] { display: none !important; }

/* Show a focus ring only for keyboard navigation, not mouse clicks: the soft sapphire glow
   from the design system, hugging each element's own border-radius (not a square outline). */
:focus-visible { outline: none; box-shadow: var(--shadow-focus); }

/* Skip-to-content link, hidden off-screen until focused. */
.skip-link { position: absolute; left: 8px; top: -48px; z-index: var(--z-sticky); background: var(--brand-primary);
  color: var(--text-on-brand); padding: 8px 14px; border-radius: var(--radius-md); transition: top var(--duration-fast) var(--ease-standard); }
.skip-link:focus { top: 8px; text-decoration: none; }

/* Make placeholder text fully opaque instead of the faint browser default. */
::placeholder { color: var(--text-subtle); opacity: 1; }

body {
  margin: 0;
  font-family: var(--font-body);
  background: var(--surface-page);
  color: var(--text-body);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
h1, h2, h3, h4, h5, h6 { font-family: var(--font-display); color: var(--text-strong); margin: 0; line-height: var(--leading-tight); font-weight: var(--weight-semibold); }
a { color: var(--text-link); text-decoration: none; }
a:hover { text-decoration: underline; }
small { color: var(--text-muted); }

/* Optional helper classes for brand-styled labels and numbers. */
.predict-eyebrow { font-family: var(--font-display); font-weight: var(--weight-semibold); text-transform: uppercase;
  letter-spacing: var(--tracking-caps); font-size: var(--text-2xs); color: var(--text-muted); }
.predict-numeric { font-family: var(--font-display); font-weight: var(--weight-bold); font-variant-numeric: tabular-nums; letter-spacing: var(--tracking-tight); }

/* Layout */
/* minmax(0,1fr), not 1fr: a bare 1fr track keeps min-width:auto, so a wide inner scroller
   (e.g. the inspection-photo gallery) expands the column and scrolls the whole page instead
   of scrolling itself. minmax(0,…) lets the column shrink so inner overflow scrollers work. */
.layout { display: grid; grid-template-columns: var(--sidebar-width) minmax(0, 1fr); min-height: 100vh; }

/* Dark gunmetal sidebar with white text. */
.sidebar {
  background: var(--surface-inverse);
  border-right: 1px solid color-mix(in srgb, var(--white) 8%, transparent);
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh;
  width: var(--sidebar-width);
}
.brand { display: flex; align-items: center; gap: 10px; padding: 16px 18px 14px; border-bottom: 1px solid color-mix(in srgb, var(--white) 8%, transparent); }
.sidebar .brand { align-items: flex-start; justify-content: space-between; gap: 8px; padding: 20px 20px 16px; }
.brand-lockup { min-width: 0; }
.brand-word { height: 30px; width: auto; display: block; }
/* The Predict flame logo mark (login card; sidebar shows it only in the collapsed rail). */
.brand-mark { flex: 0 0 auto; width: 34px; height: 34px; background: url("/static/img/predict/predict-flame.png") center / contain no-repeat; }
.sidebar .brand-mark { display: none; width: 28px; height: 28px; }
.brand-site { margin-top: 10px; font-size: var(--text-xs); color: color-mix(in srgb, var(--white) 55%, transparent); white-space: nowrap; }
.brand-text { display: flex; flex-direction: column; font-family: var(--font-display); font-weight: var(--weight-bold);
  text-transform: uppercase; letter-spacing: var(--tracking-wide); line-height: 1.1; color: var(--white); }
.brand-text small { font-family: var(--font-body); font-weight: var(--weight-regular); text-transform: none; letter-spacing: normal; color: color-mix(in srgb, var(--white) 60%, transparent); }
/* Collapse/pin toggle in the brand row. */
.nav-pin { flex: none; width: 30px; height: 30px; display: inline-flex; align-items: center; justify-content: center;
  border: none; cursor: pointer; border-radius: var(--radius-md); background: transparent; color: color-mix(in srgb, var(--white) 78%, transparent);
  transition: background var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard); }
.nav-pin:hover { color: var(--white); background: color-mix(in srgb, var(--white) 8%, transparent); }
.nav-pin .pin-open, body.nav-collapsed .nav-pin .pin-close { display: none; }
body.nav-collapsed .nav-pin .pin-open { display: inline-flex; }
nav { padding: 12px; overflow-y: auto; overflow-x: hidden; flex: 1; }
.nav-group { display: flex; flex-direction: column; gap: 2px; margin: 0; }
.nav-group-label { font-family: var(--font-display); font-weight: var(--weight-semibold); font-size: var(--text-2xs);
  text-transform: uppercase; letter-spacing: var(--tracking-caps); color: color-mix(in srgb, var(--white) 45%, transparent); padding: 12px 12px 4px; }
.nav-link { display: flex; align-items: center; gap: 11px; padding: 9px 12px; border-radius: var(--radius-md);
  font-family: var(--font-display); font-size: var(--text-md); font-weight: var(--weight-semibold); letter-spacing: .01em;
  color: color-mix(in srgb, var(--white) 72%, transparent); white-space: nowrap;
  transition: background var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard); }
.nav-link .nav-label { flex: 1; overflow: hidden; text-overflow: ellipsis; }
.nav-link:hover { background: color-mix(in srgb, var(--white) 8%, transparent); color: var(--white); text-decoration: none; }
.nav-link.is-active { background: var(--sapphire-500); color: var(--white); }
/* the active row still gives interaction feedback: hover deepens, press deepens further */
.nav-link.is-active:hover { background: var(--sapphire-600); }
.nav-link.is-active:active { background: var(--sapphire-700); }
.sidebar-foot { border-top: 1px solid color-mix(in srgb, var(--white) 8%, transparent); padding: 16px; display: flex; align-items: center; gap: 10px; }
.foot-id { flex: 1; min-width: 0; }
.foot-name { font-size: var(--text-sm); font-weight: var(--weight-semibold); color: var(--white); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.foot-role { font-size: var(--text-2xs); color: color-mix(in srgb, var(--white) 50%, transparent); text-transform: capitalize; }
.logout-form { margin: 0; flex: none; }
/* Logout is a POST button styled as a quiet icon. */
.logout-btn { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px;
  border: none; border-radius: var(--radius-md); background: transparent; color: color-mix(in srgb, var(--white) 55%, transparent); cursor: pointer;
  transition: background var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard); }
.logout-btn:hover { color: var(--white); background: color-mix(in srgb, var(--white) 8%, transparent); }

/* Collapsed rail (desktop): 64px of icons. A first-class state, not a preview - hovering
   never expands it. Icons carry their label as a tooltip (data-tip, set by app.js); the
   pin stays visible in the rail and is the only way to widen the menu back. */
@media (min-width: 821px) {
  body.nav-collapsed .layout { grid-template-columns: 64px minmax(0, 1fr); }
  body.nav-collapsed .sidebar { width: 64px; overflow: hidden;
    transition: width var(--duration-normal) var(--ease-standard); }
  /* brand: the flame mark with the pin stacked under it, centred */
  body.nav-collapsed .sidebar .brand { flex-direction: column; align-items: center; gap: 8px; padding: 16px 0 10px; }
  body.nav-collapsed .sidebar .brand-word,
  body.nav-collapsed .sidebar .brand-site,
  body.nav-collapsed .sidebar .nav-label,
  body.nav-collapsed .sidebar .foot-id { display: none; }
  body.nav-collapsed .sidebar .brand-mark { display: block; width: 30px; height: 30px; }
  /* keep each group heading's full height (text hidden) so every icon sits at the same
     Y as in the expanded menu - toggling collapse must not shift the icons up or down */
  body.nav-collapsed .sidebar .nav-group-label span { visibility: hidden; }
  /* centre each icon in the rail */
  body.nav-collapsed .sidebar .nav-link { justify-content: center; padding: 9px 0; }
  /* footer: avatar over an icon-only logout */
  body.nav-collapsed .sidebar-foot { flex-direction: column; gap: 8px; padding: 12px 0; }
}

.content { display: flex; flex-direction: column; min-width: 0; }
.topbar { display: flex; align-items: center; gap: 16px; height: var(--topbar-height);
  padding: 0 24px; background: var(--surface-card); border-bottom: 1px solid var(--border-subtle); }
.topbar h1 { font-family: var(--font-display); font-weight: var(--weight-bold); font-size: var(--text-xl); line-height: 1.1; white-space: nowrap; margin: 0; }
.topbar-actions { display: flex; align-items: center; gap: 12px; }
/* Data-freshness note on pages with no page-specific actions. */
.freshness { display: inline-flex; align-items: center; gap: 16px; font-size: var(--text-xs); color: var(--text-muted); white-space: nowrap; }
.fresh-item { display: inline-flex; align-items: center; gap: 6px; }
a.fresh-item { color: inherit; text-decoration: none; transition: color var(--duration-fast) var(--ease-standard); }
a.fresh-item:hover { color: var(--text-link); text-decoration: underline; }
.fresh-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--status-healthy); flex: none; }
.fresh-dot.is-stale { background: var(--status-critical); }
/* a localised timestamp never wraps mid-date (the Audit WHEN column broke over three lines) */
time.js-localtime { white-space: nowrap; }
.page { padding: 24px; }

/* Part identity colour picker (catalog page). */

/* Chips / badges */
/* Role chip: white chip with coloured text, used in the sidebar and users table. */
.role-chip { font-family: var(--font-display); font-weight: var(--weight-semibold); font-size: var(--text-2xs); padding: 2px 9px;
  border-radius: var(--radius-pill); text-transform: capitalize; letter-spacing: var(--tracking-wide);
  background: var(--surface-card); border: 1px solid var(--border-subtle); }
.role-admin { color: var(--sapphire-700); }
.role-user { color: var(--ink-600); }

/* Animated bouncing-letters "Loading..." (CSS-only, reduced-motion safe). Shared: the Data
   Explorer's first plot load and the script editor's Monaco loading veil both use it. */
.xpl-loader {
  --w: 10ch;
  --c: var(--text-muted);
  --fs: 22px;
  --lift: -10px;
  display: inline-block;
  font-family: var(--font-mono); font-weight: var(--weight-bold); font-size: var(--fs); line-height: 1.4em;
  letter-spacing: var(--w); width: var(--w); overflow: hidden; white-space: nowrap; color: transparent;
  text-shadow:
    calc(0*var(--w)) 0 var(--c),calc(-1*var(--w)) 0 var(--c),calc(-2*var(--w)) 0 var(--c),calc(-3*var(--w)) 0 var(--c),calc(-4*var(--w)) 0 var(--c),
    calc(-5*var(--w)) 0 var(--c),calc(-6*var(--w)) 0 var(--c),calc(-7*var(--w)) 0 var(--c),calc(-8*var(--w)) 0 var(--c),calc(-9*var(--w)) 0 var(--c);
  animation: xpl-load 2s infinite linear;
}
.xpl-loader[hidden] { display: none; }
.xpl-loader::before { content: "Loading..."; }
.xpl-loader.is-updating { --fs: 13px; --lift: -6px; }
.xpl-loader.is-updating::before { content: "Updating.."; }
@keyframes xpl-load {
  9.09%  { text-shadow: calc(0*var(--w)) var(--lift) var(--c),calc(-1*var(--w)) 0 var(--c),calc(-2*var(--w)) 0 var(--c),calc(-3*var(--w)) 0 var(--c),calc(-4*var(--w)) 0 var(--c),calc(-5*var(--w)) 0 var(--c),calc(-6*var(--w)) 0 var(--c),calc(-7*var(--w)) 0 var(--c),calc(-8*var(--w)) 0 var(--c),calc(-9*var(--w)) 0 var(--c); }
  18.18% { text-shadow: calc(0*var(--w)) 0 var(--c),calc(-1*var(--w)) var(--lift) var(--c),calc(-2*var(--w)) 0 var(--c),calc(-3*var(--w)) 0 var(--c),calc(-4*var(--w)) 0 var(--c),calc(-5*var(--w)) 0 var(--c),calc(-6*var(--w)) 0 var(--c),calc(-7*var(--w)) 0 var(--c),calc(-8*var(--w)) 0 var(--c),calc(-9*var(--w)) 0 var(--c); }
  27.27% { text-shadow: calc(0*var(--w)) 0 var(--c),calc(-1*var(--w)) 0 var(--c),calc(-2*var(--w)) var(--lift) var(--c),calc(-3*var(--w)) 0 var(--c),calc(-4*var(--w)) 0 var(--c),calc(-5*var(--w)) 0 var(--c),calc(-6*var(--w)) 0 var(--c),calc(-7*var(--w)) 0 var(--c),calc(-8*var(--w)) 0 var(--c),calc(-9*var(--w)) 0 var(--c); }
  36.36% { text-shadow: calc(0*var(--w)) 0 var(--c),calc(-1*var(--w)) 0 var(--c),calc(-2*var(--w)) 0 var(--c),calc(-3*var(--w)) var(--lift) var(--c),calc(-4*var(--w)) 0 var(--c),calc(-5*var(--w)) 0 var(--c),calc(-6*var(--w)) 0 var(--c),calc(-7*var(--w)) 0 var(--c),calc(-8*var(--w)) 0 var(--c),calc(-9*var(--w)) 0 var(--c); }
  45.45% { text-shadow: calc(0*var(--w)) 0 var(--c),calc(-1*var(--w)) 0 var(--c),calc(-2*var(--w)) 0 var(--c),calc(-3*var(--w)) 0 var(--c),calc(-4*var(--w)) var(--lift) var(--c),calc(-5*var(--w)) 0 var(--c),calc(-6*var(--w)) 0 var(--c),calc(-7*var(--w)) 0 var(--c),calc(-8*var(--w)) 0 var(--c),calc(-9*var(--w)) 0 var(--c); }
  54.54% { text-shadow: calc(0*var(--w)) 0 var(--c),calc(-1*var(--w)) 0 var(--c),calc(-2*var(--w)) 0 var(--c),calc(-3*var(--w)) 0 var(--c),calc(-4*var(--w)) 0 var(--c),calc(-5*var(--w)) var(--lift) var(--c),calc(-6*var(--w)) 0 var(--c),calc(-7*var(--w)) 0 var(--c),calc(-8*var(--w)) 0 var(--c),calc(-9*var(--w)) 0 var(--c); }
  63.63% { text-shadow: calc(0*var(--w)) 0 var(--c),calc(-1*var(--w)) 0 var(--c),calc(-2*var(--w)) 0 var(--c),calc(-3*var(--w)) 0 var(--c),calc(-4*var(--w)) 0 var(--c),calc(-5*var(--w)) 0 var(--c),calc(-6*var(--w)) var(--lift) var(--c),calc(-7*var(--w)) 0 var(--c),calc(-8*var(--w)) 0 var(--c),calc(-9*var(--w)) 0 var(--c); }
  72.72% { text-shadow: calc(0*var(--w)) 0 var(--c),calc(-1*var(--w)) 0 var(--c),calc(-2*var(--w)) 0 var(--c),calc(-3*var(--w)) 0 var(--c),calc(-4*var(--w)) 0 var(--c),calc(-5*var(--w)) 0 var(--c),calc(-6*var(--w)) 0 var(--c),calc(-7*var(--w)) var(--lift) var(--c),calc(-8*var(--w)) 0 var(--c),calc(-9*var(--w)) 0 var(--c); }
  81.81% { text-shadow: calc(0*var(--w)) 0 var(--c),calc(-1*var(--w)) 0 var(--c),calc(-2*var(--w)) 0 var(--c),calc(-3*var(--w)) 0 var(--c),calc(-4*var(--w)) 0 var(--c),calc(-5*var(--w)) 0 var(--c),calc(-6*var(--w)) 0 var(--c),calc(-7*var(--w)) 0 var(--c),calc(-8*var(--w)) var(--lift) var(--c),calc(-9*var(--w)) 0 var(--c); }
  90.90% { text-shadow: calc(0*var(--w)) 0 var(--c),calc(-1*var(--w)) 0 var(--c),calc(-2*var(--w)) 0 var(--c),calc(-3*var(--w)) 0 var(--c),calc(-4*var(--w)) 0 var(--c),calc(-5*var(--w)) 0 var(--c),calc(-6*var(--w)) 0 var(--c),calc(-7*var(--w)) 0 var(--c),calc(-8*var(--w)) 0 var(--c),calc(-9*var(--w)) var(--lift) var(--c); }
}
@media (prefers-reduced-motion: reduce) { .xpl-loader { animation: none; } }

/* JS-loading veil over a JS-required area (script editor, pipeline editor):
   server-rendered (or JS-inserted) and lifted by the page script once it is fully wired.
   Pair with .load-host (or any positioned ancestor). Blocks clicks; add `inert` on the host
   to block keyboard focus too. */
.load-host { position: relative; }
.load-veil { position: absolute; inset: 0; z-index: var(--z-sticky); display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--white) 60%, transparent); backdrop-filter: blur(1px); }
/* Initial placeholder inside a client-rendered page mount (Activity, Schedule) - replaced by the page JS. */
.page-loading { display: flex; justify-content: center; padding: 70px 0; }

/* Traffic-light status dot used on the fleet view. */
.light { display: inline-block; width: 12px; height: 12px; border-radius: var(--radius-pill); vertical-align: middle; }
.light.green { background: var(--status-healthy); box-shadow: 0 0 0 3px var(--status-healthy-soft); }
.light.amber { background: var(--status-watch); box-shadow: 0 0 0 3px var(--status-watch-soft); }
.light.red { background: var(--status-critical); box-shadow: 0 0 0 3px var(--status-critical-soft); }
.pill { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border-radius: var(--radius-pill); font-size: var(--text-xs); border: 1px solid var(--border-subtle); background: var(--surface-card); }
.pill.green { color: var(--status-healthy-ink); background: var(--status-healthy-soft); border-color: transparent; }
.pill.amber { color: var(--status-watch-ink); background: var(--status-watch-soft); border-color: transparent; }
.pill.red { color: var(--status-critical-ink); background: var(--status-critical-soft); border-color: transparent; }

/* Cards / summary */
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; margin-bottom: 22px; }
.card { background: var(--surface-card); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); box-shadow: var(--elevation-card); padding: 16px 18px; }
.card .n { font-family: var(--font-display); font-weight: var(--weight-bold); font-variant-numeric: tabular-nums; letter-spacing: var(--tracking-tight); font-size: var(--text-3xl); color: var(--text-strong); }
.card .k { font-family: var(--font-display); font-weight: var(--weight-semibold); color: var(--text-muted); font-size: var(--text-2xs); text-transform: uppercase; letter-spacing: var(--tracking-caps); }

/* Tables */
table { width: 100%; border-collapse: collapse; background: var(--surface-card); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); box-shadow: var(--elevation-card); overflow: hidden; }
th, td { text-align: left; padding: 10px 14px; border-bottom: 1px solid var(--border-subtle); }
th { font-family: var(--font-display); color: var(--text-muted); font-weight: var(--weight-semibold); font-size: var(--text-2xs); text-transform: uppercase; letter-spacing: var(--tracking-caps); background: var(--grey-50); }
tr:last-child td { border-bottom: none; }
tbody tr:hover { background: var(--grey-50); }
/* Right-aligned cells are numeric columns; line up the digits. */
td.right { font-variant-numeric: tabular-nums; }
.muted { color: var(--text-muted); }
.right { text-align: right; }

/* sortable / filterable data tables (tables.js) */
.table-tools { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.table-search { width: auto; min-width: 220px; max-width: 320px; padding: 7px 11px; }
.table-count { font-size: var(--text-xs); }
th.sortable { cursor: pointer; user-select: none; transition: color var(--duration-fast) var(--ease-standard); }
th.sortable:hover { color: var(--text-strong); }
th .sort-ind { font-size: 10px; color: var(--brand-primary); }
/* Clickable header link that re-sorts the whole result set on the server. */
a.th-sort { color: inherit; display: inline-flex; align-items: center; gap: 5px; transition: color var(--duration-fast) var(--ease-standard); }
a.th-sort:hover { color: var(--text-strong); text-decoration: none; }
a.th-sort.is-sorted { color: var(--text-strong); }
.table-empty-row td { text-align: center; padding: 22px; }

/* inline "why?" hover marker: the circle-help SVG, ring and glyph in one path set. A CSS
   border drawn around a text "?" landed half a pixel off it at some zooms/DPRs. */
.info-dot { display: inline-flex; color: var(--text-muted); cursor: help; vertical-align: middle; transition: color var(--duration-fast) var(--ease-standard); }
.info-dot:hover, .info-dot:focus-visible { color: var(--brand-primary); }

/* Forms / buttons */
.panel { background: var(--surface-card); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); box-shadow: var(--elevation-card); padding: 22px; max-width: 720px; }
label { display: block; font-family: var(--font-display); font-weight: var(--weight-semibold); text-transform: uppercase;
  letter-spacing: var(--tracking-caps); font-size: var(--text-2xs); margin: 14px 0 6px; color: var(--text-muted); }
/* One height contract for every control: a text field, a select, a date trigger and a button
   sitting in the same row are all --field-height. Compact contexts step down to
   --field-height-sm (32) or the 28px card-header tier - never to an accidental padding total. */
input, select, textarea {
  width: 100%; height: var(--field-height); padding: 0 12px; background: var(--surface-card); color: var(--text-body);
  border: 1px solid var(--border-default); border-radius: var(--radius-md); font: inherit; font-family: var(--font-body);
  transition: border-color var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard);
}
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--border-brand); box-shadow: var(--shadow-focus); }
/* controls whose size is their content, not the field box */
input[type="color"], input[type="checkbox"], input[type="radio"], input[type="file"], input[type="range"] { height: auto; }
textarea { height: auto; min-height: 120px; padding: 9px 12px; resize: vertical; }
select[multiple], select[size]:not([size="1"]) { height: auto; padding: 9px 12px; }

/* Every select carries the design system's chevron instead of the OS arrow, so a dropdown
   looks the same on every page and in every browser. The DS draws it as a sibling element;
   here it is a background image, which needs no per-select markup. The stroke has to be a
   literal (a data: URI cannot read a CSS variable) - it is --ink-500. Selects that size to
   their own content opt out below rather than reserve 30px they do not have.
   Must follow the `background` shorthand above, which would otherwise reset the image. */
select {
  appearance: none; -webkit-appearance: none; padding-right: 30px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b7c84' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 10px center; background-size: 15px 15px;
}
select[multiple], select[size]:not([size="1"]) { background-image: none; padding-right: 12px; }

/* Native date/time fields - one look on every page that picks a date (audit filters, script /
   pipeline run ranges, the Activity/Schedule custom-range popovers, the shutdowns drawer).
   The popup calendar stays the browser's; accent-color brands its selection. */
input[type="date"], input[type="time"], input[type="datetime-local"] {
  font-variant-numeric: tabular-nums; cursor: pointer;
  color-scheme: light; accent-color: var(--brand-primary);
}
input[type="date"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator,
input[type="datetime-local"]::-webkit-calendar-picker-indicator {
  cursor: pointer; opacity: 0.55; transition: opacity var(--duration-fast) var(--ease-standard);
}
input[type="date"]:hover::-webkit-calendar-picker-indicator,
input[type="date"]:focus::-webkit-calendar-picker-indicator,
input[type="time"]:hover::-webkit-calendar-picker-indicator,
input[type="time"]:focus::-webkit-calendar-picker-indicator,
input[type="datetime-local"]:hover::-webkit-calendar-picker-indicator,
input[type="datetime-local"]:focus::-webkit-calendar-picker-indicator { opacity: 1; }
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: var(--field-height); box-sizing: border-box;
  background: var(--brand-primary); color: var(--text-on-brand); border: 1px solid transparent;
  padding: 0 16px; border-radius: var(--radius-md); font-family: var(--font-display); font-size: var(--text-md); font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide); white-space: nowrap; cursor: pointer; transition: background var(--duration-fast) var(--ease-standard), border-color var(--duration-fast) var(--ease-standard); }
.btn:hover { background: var(--brand-primary-hover); text-decoration: none; }
.btn:active { background: var(--brand-primary-active); }
.btn.ghost { background: var(--surface-card); border: 1px solid var(--border-default); color: var(--text-body); }
.btn.ghost:hover { background: var(--grey-50); border-color: var(--border-strong); }
/* secondary: white with sapphire text - a middle emphasis tier between primary and ghost */
.btn.secondary { background: var(--surface-card); border: 1px solid var(--border-default); color: var(--sapphire-700); }
.btn.secondary:hover { background: var(--sapphire-50); }
.btn.secondary:active { background: var(--sapphire-100); }
/* danger: solid critical red for destructive actions */
.btn.danger { background: var(--status-critical); }
.btn.danger:hover { background: color-mix(in srgb, var(--status-critical) 88%, black); }
.btn.danger:active { background: color-mix(in srgb, var(--status-critical) 76%, black); }
/* sm: the 32px compact tier for dense toolbars and page toolbars */
.btn.sm { height: var(--field-height-sm); padding: 0 12px; font-size: var(--text-sm); }
/* Scope-choice dialog (PI.choose) - the recurring-series "this / following / all" question */
.p-choice { border: 1px solid var(--border-subtle); border-radius: var(--radius-md); background: var(--surface-card);
  box-shadow: var(--elevation-overlay); padding: 18px; min-width: 300px; max-width: 380px; }
.p-choice::backdrop { background: color-mix(in srgb, var(--ink-900) 35%, transparent); }
.p-choice-title { font-family: var(--font-display); font-size: var(--text-md); font-weight: var(--weight-semibold);
  color: var(--text-strong); margin-bottom: 12px; }
.p-choice-opts { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; }
.p-choice-opts .btn { width: 100%; text-align: left; }
.p-choice-cancel { width: 100%; }
.row { display: flex; gap: 12px; flex-wrap: wrap; }
.row > * { flex: 1; min-width: 200px; }
/* Checkbox rows: plain inline labels, not the uppercase field-label style. */
.check { display: flex; align-items: center; gap: 8px; font-family: var(--font-body); font-weight: var(--weight-regular);
  text-transform: none; letter-spacing: normal; font-size: var(--text-sm); color: var(--text-body); }
.check input { width: auto; }
.check-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 8px 16px; margin-top: 6px; }
.check-grid .check { margin: 0; }
/* Fieldset used as a panel: fix the flex min-width and style the legend as a heading. */
fieldset { min-width: 0; }
legend { padding: 0 4px; font-family: var(--font-display); font-weight: var(--weight-semibold); color: var(--text-strong); }

/* Panel section heading with a leading icon (asset editor, etc.). Specificity beats `.page h2`. */

/* Key/value editor: rows of key + value inputs with a remove button, plus an "Add row" button. */
.kv-rows { display: flex; flex-direction: column; gap: 8px; }
.kv-row { display: flex; gap: 8px; align-items: center; }
.kv-row input { flex: 1; margin: 0; }
.kv-row .kv-key { max-width: 240px; }
/* Locked (required) row: fixed key reads as muted, lock glyph sits where the delete button would. */
.kv-row .kv-key[readonly] { background: var(--surface-sunken); color: var(--text-muted); cursor: default; }
.kv-lock { display: inline-flex; width: 28px; justify-content: center; color: var(--text-muted); }
.kv-lock.is-double { width: auto; gap: 1px; }

/* Section headings on content pages. */
.page h2 { font-size: var(--text-lg); margin: 22px 0 10px; }
.page h2:first-child { margin-top: 0; }
.page h3 { font-size: var(--text-md); margin: 18px 0 8px; }

/* Confirmation control that works without JS: a details/summary that reveals the real submit button. */
.confirm { display: inline-block; }
.confirm > summary { display: inline-flex; list-style: none; cursor: pointer; }
.confirm > summary::-webkit-details-marker { display: none; }
.confirm > summary::marker { content: ""; }
.confirm-pop { margin-top: 8px; padding: 12px 14px; border: 1px solid var(--border-subtle); border-radius: var(--radius-md);
  background: var(--surface-card); box-shadow: var(--elevation-raised); max-width: 360px; }
.confirm-pop p { margin: 0 0 10px; }

/* Tabs */
.tabs { display: flex; gap: 4px; margin: 6px 0 20px; border-bottom: 1px solid var(--border-subtle); }
.tabs a { padding: 8px 14px; font-family: var(--font-display); font-weight: var(--weight-semibold); color: var(--text-muted); border-bottom: 2px solid transparent;
  transition: color var(--duration-fast) var(--ease-standard), border-color var(--duration-fast) var(--ease-standard); }
.tabs a:hover { color: var(--text-strong); text-decoration: none; }
.tabs a.is-active { color: var(--text-strong); border-bottom-color: var(--brand-primary); }

/* Misc */
/* Empty states, two intents: .empty = minor/in-table "nothing here" (dashed, admin list pages);
   .empty-card (pages.css) = full-page empty state with an icon + title (predictive-maintenance pages). */
.empty { padding: 40px; text-align: center; color: var(--text-muted); background: var(--surface-card); border: 1px dashed var(--border-default); border-radius: var(--radius-md); }
.note { background: var(--status-info-soft); border: 1px solid var(--sapphire-200); border-radius: var(--radius-md); padding: 10px 14px; font-size: var(--text-sm); color: var(--status-info-ink); margin-bottom: 16px; }
.note strong { color: var(--status-info-ink); }
/* Floating flash toast: fixed near the top, above content. Fades in; fades out on dismiss. */
.toast { position: fixed; top: 16px; left: 50%; transform: translateX(-50%); z-index: var(--z-toast);
  display: flex; align-items: center; gap: 10px; max-width: min(560px, calc(100vw - 32px));
  padding: 10px 12px 10px 14px; border: 1px solid; border-radius: var(--radius-md);
  box-shadow: var(--elevation-overlay); font-size: var(--text-sm);
  animation: toast-in var(--duration-normal) var(--ease-out); }
.toast > span { flex: 1; }
.toast.toast-hide { opacity: 0; transition: opacity var(--duration-slow) var(--ease-standard); }
.toast-x { display: inline-flex; padding: 2px; border: 0; background: transparent; color: inherit; opacity: 0.7; cursor: pointer;
  transition: opacity var(--duration-fast) var(--ease-standard); }
.toast-x:hover { opacity: 1; }
.toast-info    { background: var(--status-info-soft);     border-color: var(--sapphire-200);    color: var(--status-info-ink); }
.toast-success { background: var(--status-healthy-soft);  border-color: var(--status-healthy);  color: var(--status-healthy-ink); }
.toast-error   { background: var(--status-critical-soft); border-color: var(--status-critical); color: var(--status-critical-ink); }
.toast-warn    { background: var(--status-watch-soft);    border-color: var(--status-watch);    color: var(--status-watch-ink); }
@keyframes toast-in { from { opacity: 0; transform: translate(-50%, -8px); } to { opacity: 1; transform: translate(-50%, 0); } }
.split { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.kv { display: grid; grid-template-columns: 160px 1fr; gap: 6px 14px; }
.kv dt { color: var(--text-muted); }
.kv dd { margin: 0; }
pre { background: var(--surface-sunken); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); padding: 14px; overflow-x: auto; font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text-body); }
.tag { display: inline-block; background: var(--sapphire-50); border: 1px solid var(--sapphire-100); color: var(--sapphire-700); border-radius: var(--radius-sm); padding: 1px 7px; font-size: var(--text-xs); margin: 1px; }

/* Login */
.auth-wrap { min-height: 100vh; display: grid; place-items: center; background: var(--surface-page); padding: 24px; }
.auth-card { background: var(--surface-card); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); box-shadow: var(--elevation-card); padding: 36px; width: 380px; }
.auth-card .brand { border: none; padding: 0 0 18px; }
.auth-card .brand-text { color: var(--text-strong); }
.auth-card .brand-text small { color: var(--text-muted); }

/* Admin script editor */
.monaco-host { display: none; height: 420px; border: 1px solid var(--border-subtle); border-radius: var(--radius-md); overflow: hidden; }
.code-fallback { width: 100%; min-height: 420px; background: var(--surface-card); color: var(--text-body); border: 1px solid var(--border-default); border-radius: var(--radius-md); font-family: var(--font-mono); font-size: var(--text-sm); padding: 10px; resize: vertical; }
/* Script run output: a dark console log panel. */
/* Status chip: the one soft-filled, token-coloured pill for run states (queued…skipped) and entity
   states (assets/users/tokens: active/retired/revoked/inactive). The admin table spans and the
   import-result chips all emit `run-chip run-<state>`. */
.run-chip { display: inline-block; padding: 1px 9px; border-radius: var(--radius-pill); font-size: var(--text-xs); font-weight: var(--weight-semibold); text-transform: capitalize; }
.run-running   { background: var(--status-info-soft);     color: var(--status-info-ink); }
.run-succeeded { background: var(--status-healthy-soft);  color: var(--status-healthy-ink); }
.run-failed    { background: var(--status-critical-soft); color: var(--status-critical-ink); }
.run-stopped   { background: var(--status-watch-soft);    color: var(--status-watch-ink); }
.run-queued,
.run-cancelled,

/* colour-coded signal-type icon (raw / calc / object) - the Data Explorer list, its type
   filter, and the Variables header filter all share it */
.sig-ico { display: inline-flex; align-items: center; justify-content: center; flex: none; }
.sig-ico-raw  { color: var(--sapphire-500); }
.sig-ico-calc { color: var(--gold-600); }
.sig-ico-obj  { color: var(--ink-500); }
.sig-ico-insp { color: var(--ink-600); }

/* Inspection photos */

/* Pagination */
.pager { display: flex; align-items: center; gap: 12px; margin-top: 12px; flex-wrap: wrap; }
.pager-info { font-size: var(--text-xs); }
.btn.is-disabled { opacity: .45; pointer-events: none; }

/* wide tables scroll horizontally instead of overflowing (wrapper added by tables.js) */
.table-scroll { width: 100%; overflow-x: auto; }

/* Upload loading overlay */
.overlay { position: fixed; inset: 0; background: color-mix(in srgb, var(--ink-800) 55%, transparent); display: grid; place-items: center; z-index: var(--z-overlay); }
.overlay[hidden] { display: none; }
.overlay-card { background: var(--surface-card); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); box-shadow: var(--elevation-overlay); padding: 18px 22px; display: flex; align-items: center; gap: 12px; font-weight: var(--weight-semibold); }
.spinner { width: 18px; height: 18px; border: 2px solid var(--border-subtle); border-top-color: var(--brand-primary); border-radius: 50%; animation: predict-spin .8s linear infinite; }
@keyframes predict-spin { to { transform: rotate(360deg); } }

/* Mobile nav toggle and backdrop, shown only on small screens. */
.nav-toggle { display: none; background: transparent; border: 1px solid var(--border-default); color: var(--text-body); width: var(--field-height); height: var(--field-height); border-radius: var(--radius-md); font-size: var(--text-lg); cursor: pointer; line-height: 1;
  transition: background var(--duration-fast) var(--ease-standard), border-color var(--duration-fast) var(--ease-standard); }
.nav-toggle:hover { background: var(--grey-50); border-color: var(--border-strong); }
.nav-backdrop { display: none; }

/* Responsive */
@media (max-width: 820px) {
  .layout { grid-template-columns: 1fr; }
  .sidebar { position: fixed; top: 0; left: 0; z-index: calc(var(--z-overlay) + 1); width: 264px; max-width: 84vw;
    transform: translateX(-100%); transition: transform .2s ease; }
  body.nav-open .sidebar { transform: none; box-shadow: var(--shadow-xl); }
  .nav-backdrop { position: fixed; inset: 0; background: color-mix(in srgb, var(--ink-800) 45%, transparent); z-index: var(--z-overlay); }
  body.nav-open .nav-backdrop { display: block; }
  .nav-toggle { display: inline-grid; place-items: center; }
  .topbar { height: auto; min-height: var(--topbar-height); padding: 10px 16px; gap: 12px; flex-wrap: wrap; }
  .topbar h1 { font-size: var(--text-lg); }
  .nav-pin, .freshness { display: none; }
  .page { padding: 16px; }
  .split { grid-template-columns: 1fr; }
  .kv { grid-template-columns: 120px 1fr; }
  .cards { grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); }
  .panel { padding: 16px; }
}

/* Generated utility classes, moved here from inline style attributes. */
.u-display-flex-gap-10px-align-item { display:flex;gap:var(--space-4);align-items:flex-end;flex-wrap:wrap; }
.u-display-inline { display:inline; }
.u-flex-1-min-width-200px { flex:1;min-width:200px; }
.u-flex-2-min-width-260px { flex:2;min-width:260px; }
.u-font-size-12px { font-size: var(--text-xs); }
.u-font-size-15px-margin-26px-0-10p { font-size: var(--text-base);margin:var(--space-7) 0 var(--space-4);display:flex;align-items:center;gap:var(--space-3); }
.u-font-weight-400 { font-weight: var(--weight-regular); }
.u-margin-0 { margin:0; }
.u-margin-6px-0-10px { margin:var(--space-3) 0 var(--space-4); }
.u-margin-bottom-18px { margin-bottom:var(--space-6); }
.u-margin-left-auto { margin-left:auto; }
.u-margin-top-0 { margin-top:0; }
.u-margin-top-10px { margin-top:var(--space-4); }
.u-margin-top-12px { margin-top:var(--space-4); }
.u-margin-top-14px { margin-top:var(--space-5); }
.u-margin-top-18px { margin-top:var(--space-6); }
.u-margin-top-18px-width-100 { margin-top:var(--space-6);width:100%; }
.u-margin-top-6px { margin-top:var(--space-3); }
.u-user-select-all-white-space-pre- { user-select:all;white-space:pre-wrap;word-break:break-all;background:var(--ink-900);color:var(--ink-100);padding:var(--space-4);border-radius:var(--radius-sm);margin:0; }
.u-width-100-text-align-center { width:100%;text-align:center; }
.u-width-auto { width:auto; }
.swatch { vertical-align: middle; }

