/* ============================================================
   Alfred Design System — Components
   Built on top of tokens.css. No inline styles required to use.
   ============================================================ */

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }

/* The [hidden] attribute is a USER-AGENT rule (display: none), so any author rule that
   sets display beats it -- a .dp-gate{display:flex} or .form-section{display:grid} stays
   fully visible with hidden set, and the element is still in the layout, still readable,
   still in view-source. Every surface here composes with display, so the guard is stated
   once, globally, rather than re-derived per component. Verify hiding by COMPUTED style,
   never by el.hidden. */
[hidden] { display: none !important; }

/* Sticky-footer scaffolding for the v2 shell. The body becomes a
   flex column at viewport height; <main> grows to consume the
   leftover space so .app-footer always sits at the bottom of the
   viewport on short pages, and rides below the content on long
   ones. Lives here (in alfred.css, loaded by _AlfredV2.cshtml's
   bundle) so every v2 surface inherits the behavior -- a page
   that ships a short table no longer parks the footer awkwardly
   below the last row with empty space underneath. */
html { height: 100%; }
body {
  font-family: var(--font-sans);
  background: var(--bg);
  color: var(--text-primary);
  font-size: var(--text-14);
  line-height: var(--leading-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: 'cv11', 'ss03';
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}
body > main[role="main"] { flex: 1 0 auto; }
body > .app-footer { flex-shrink: 0; }

button { font-family: inherit; }

/* ------------------------------------------------------------
   Focus rings are keyboard-only.
   Browsers paint the default focus outline on :focus for mouse and
   touch clicks too, which leaves a stuck blue box on anything without
   its own focus style (the header logo, nav links, image links, plain
   buttons/inputs). Suppress that ring unless the UA deems focus
   keyboard-driven (:focus-visible), and give keyboard users one
   consistent on-brand ring. Design-system components define their own
   higher-specificity :focus-visible ring (--shadow-focus) and are
   unaffected; text inputs keep their intentional :focus ring on click.
   ------------------------------------------------------------ */
:focus:not(:focus-visible) {
  outline: none;
}
:focus-visible {
  outline: 2px solid var(--brand-blue);
  outline-offset: 2px;
}

/* Numbers everywhere use tabular figures */
.num,
.mono,
.kbd {
  font-feature-settings: 'tnum';
}

/* ============================================================
   Typography utilities
   ============================================================ */
.t-display    { font-size: var(--text-28); font-weight: var(--weight-medium); letter-spacing: -0.6px; line-height: var(--leading-tight); }
/* Title classes ride on h1/h2 elements inside flex headers; the UA's
   default heading margins were never part of the design (meta offsets
   assume the title box ends at the text) and they break vertical
   centering against any adjacent icon chip or avatar. */
.t-title      { margin: 0; font-size: var(--text-22); font-weight: var(--weight-medium); letter-spacing: -0.5px; line-height: var(--leading-tight); }
.t-h2         { margin: 0; font-size: var(--text-18); font-weight: var(--weight-medium); letter-spacing: -0.3px; line-height: var(--leading-tight); }
.t-body       { font-size: var(--text-14); font-weight: var(--weight-regular); }
.t-small      { font-size: var(--text-13); font-weight: var(--weight-regular); }
.t-micro      { font-size: var(--text-12); font-weight: var(--weight-regular); }
.t-eyebrow {
  font-size: var(--text-10);
  text-transform: uppercase;
  letter-spacing: 0.7px;
  font-weight: var(--weight-medium);
  color: var(--text-tertiary);
}
.t-mono       { font-family: var(--font-mono); font-feature-settings: 'tnum'; }
.t-secondary  { color: var(--text-secondary); }
.t-tertiary   { color: var(--text-tertiary); }
.t-primary    { color: var(--text-primary); }
.t-warning    { color: var(--warning); }

/* ============================================================
   Kbd — keyboard hint chip
   ============================================================ */
.kbd {
  display: inline-flex;
  align-items: center;
  padding: 1px 5px;
  font-family: var(--font-mono);
  font-size: var(--text-10);
  color: var(--text-tertiary);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  line-height: 1.4;
}
.kbd-group {
  display: inline-flex;
  gap: 3px;
}

/* ============================================================
   Buttons
   ============================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: var(--control-h);
  padding: 0 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-size: var(--text-12);
  font-weight: var(--weight-medium);
  color: var(--text-primary);
  text-decoration: none;
  cursor: pointer;
  letter-spacing: -0.1px;
  transition: background var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease);
  white-space: nowrap;
}
.btn:hover { background: var(--surface-2); border-color: var(--border-strong); text-decoration: none; }
.btn:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.btn[disabled], .btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
  background: var(--surface);
  border-color: var(--border);
  color: var(--text-tertiary);
}
.btn[disabled]:hover, .btn:disabled:hover {
  background: var(--surface);
  border-color: var(--border);
}
.btn svg { color: currentColor; opacity: 0.85; flex-shrink: 0; }

.btn--primary {
  background: var(--brand-navy);
  color: var(--text-inverse);
  border-color: var(--brand-navy);
}
.btn--primary:hover {
  background: var(--brand-navy-hover);
  border-color: var(--brand-navy-hover);
}

.btn--ghost {
  background: transparent;
  border-color: transparent;
  color: var(--text-secondary);
}
.btn--ghost:hover { background: var(--surface-2); color: var(--text-primary); border-color: transparent; }

.btn--danger {
  color: var(--danger);
  border-color: var(--border);
}
.btn--danger:hover { background: var(--danger-soft); border-color: var(--danger-soft); }

.btn--sm { height: var(--control-h-sm); padding: 0 10px; font-size: var(--text-11); }

/* Icon-only square button */
.icon-btn {
  width: var(--control-h);
  height: var(--control-h);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  border-radius: var(--radius);
  color: var(--text-secondary);
  cursor: pointer;
  position: relative;
  transition: background var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease);
}
.icon-btn:hover { background: var(--surface-2); color: var(--text-primary); }
.icon-btn:focus-visible { outline: none; box-shadow: var(--shadow-focus); }

/* Destructive icon action. Reads as neutral at rest, like every other icon
   button in a row of them, and only owns up to what it does on hover. */
.icon-btn--danger:hover { background: var(--danger-soft); color: var(--danger); }

.icon-btn .badge-dot {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--brand-blue);
  border: 2px solid var(--surface);
}

/* ============================================================
   Field — input, search trigger, input-pill
   ============================================================ */
.field {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: var(--control-h);
  padding: 0 10px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-size: var(--text-12);
  color: var(--text-primary);
  width: 100%;
  transition: border-color var(--dur-fast) var(--ease),
              box-shadow var(--dur-fast) var(--ease);
}
.field:focus-within {
  border-color: var(--brand-blue);
  box-shadow: var(--shadow-focus);
}
.field > input,
.field > textarea {
  flex: 1;
  min-width: 0;
  border: 0;
  background: none;
  outline: none;
  font: inherit;
  font-size: var(--text-13);
  color: var(--text-primary);
}
.field > input::placeholder { color: var(--text-tertiary); }
.field > svg { color: var(--text-tertiary); flex-shrink: 0; }
.field-label {
  display: block;
  font-size: var(--text-12);
  color: var(--text-secondary);
  font-weight: var(--weight-medium);
  margin-bottom: 6px;
  letter-spacing: -0.1px;
}
.field-help {
  font-size: var(--text-11);
  color: var(--text-tertiary);
  margin-top: 4px;
}

/* .field is sized for one line -- fixed height, contents centred -- so a real
   multi-line textarea overflowed it and drew its text above the box. This is
   the multi-line variant.

   Byte-for-byte what tags.css already declares, deliberately: promoting it here
   must not restyle the screen it came from. tags.css can drop its copy once
   nothing depends on the ordering. */
.field--textarea { height: auto; min-height: 98px; align-items: flex-start; }
.field--textarea textarea::placeholder { color: var(--text-tertiary); }

/* A native <select> dressed as the combobox trigger. It lives here rather than
   in one page's stylesheet because .field styles input and textarea and nothing
   else: a <select> dropped into a .field wrapper keeps the operating system's
   own control, sized to its longest option, which is what the data point editor
   was rendering. The tag screen defines this identically in tags.css and can
   drop its copy once nothing depends on the ordering. */
.ds-select {
  width: 100%;
  min-height: var(--control-h);
  height: var(--control-h);
  padding: 0 30px 0 10px;
  appearance: none;
  -webkit-appearance: none;
  background-color: var(--surface-2);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2394A3B8' 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;
  border: 1px solid transparent;
  border-radius: var(--radius);
  font: inherit;
  font-size: var(--text-13);
  color: var(--text-primary);
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              box-shadow var(--dur-fast) var(--ease);
}
.ds-select:hover { background-color: var(--surface); border-color: var(--border-strong); }
.ds-select:focus-visible {
  outline: none;
  border-color: var(--brand-blue);
  background-color: var(--surface);
  box-shadow: var(--shadow-focus);
}
.field--error,
.field.field--error {
  border-color: var(--danger);
  box-shadow: 0 0 0 1px var(--danger);
}
.field.field--error:focus-within {
  border-color: var(--danger);
  box-shadow: 0 0 0 3px rgba(185, 28, 28, 0.18);
}

/* Input-pill: muted filter chip used in toolbars and the header */
.input-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 10px;
  background: var(--surface-2);
  border: 1px solid transparent;
  border-radius: var(--radius);
  font-size: var(--text-12);
  color: var(--text-secondary);
  cursor: pointer;
  font-family: inherit;
  /* Pills are rendered as <button> or <a> interchangeably (Refresh is a
     plain link); kill the anchor default at the component so no future
     anchor-shaped pill resurfaces the underline. */
  text-decoration: none;
  transition: background var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease);
}
.input-pill:hover { background: var(--surface); border-color: var(--border-strong); text-decoration: none; }
.input-pill:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.input-pill > svg { color: var(--text-tertiary); flex-shrink: 0; }
.input-pill .label { color: var(--text-tertiary); }
.input-pill--ghost { background: transparent; }
.input-pill--ghost:hover { background: var(--surface-2); border-color: transparent; }

/* Search trigger — taller affordance with persistent ⌘K */
.search-trigger {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: var(--control-h);
  padding: 0 6px 0 10px;
  background: var(--surface-2);
  border: 1px solid transparent;
  border-radius: var(--radius);
  font-size: var(--text-12);
  color: var(--text-tertiary);
  cursor: pointer;
  min-width: 220px;
  font-family: inherit;
  transition: background var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease);
}
.search-trigger:hover { background: var(--surface); border-color: var(--border-strong); }
.search-trigger:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.search-trigger .search-trigger__placeholder { flex: 1; text-align: left; }

/* Checkbox + radio rows (compact toolbar style) */
.checkbox-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: var(--text-12);
  color: var(--text-secondary);
  padding: 0 4px;
  cursor: pointer;
  user-select: none;
}
.checkbox-pill input { accent-color: var(--brand-blue); }

/* ============================================================
   Avatar
   ============================================================ */
.avatar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--brand-navy);
  color: var(--text-inverse);
  font-size: var(--text-11);
  font-weight: var(--weight-medium);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  letter-spacing: 0.3px;
  flex-shrink: 0;
  border: 0;
  cursor: default;
}
.avatar--sm { width: 22px; height: 22px; font-size: var(--text-10); }
.avatar--lg { width: 36px; height: 36px; font-size: var(--text-12); }
button.avatar { cursor: pointer; transition: background var(--dur-fast) var(--ease); }
button.avatar:hover { background: var(--brand-navy-hover); }
button.avatar:focus-visible { outline: none; box-shadow: var(--shadow-focus); }

/* ============================================================
   Pill — generic rounded label
   ============================================================ */
.pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 3px 8px;
  font-size: var(--text-11);
  font-weight: var(--weight-medium);
  border-radius: var(--radius-pill);
  background: var(--surface-2);
  color: var(--text-secondary);
  letter-spacing: -0.1px;
  line-height: 1.4;
  /* A pill whose label wraps is sized by shrink-to-fit, which means it takes
     the FULL width available rather than the width of its longest line. In a
     fixed grid column -- the job files table -- "Confirmation required" breaks
     over two lines inside a box as wide as the column, leaving the dot and the
     text hard against the left edge with dead space to the right.

     Centring is what makes the wrapped shape read as a pill: justify-content
     centres the dot-and-label group inside that oversized box, text-align
     centres the lines against each other. Both are needed -- the label is an
     anonymous flex item, so justify-content alone would centre the block while
     leaving its second line ragged inside it.

     No effect on a pill that fits: a shrink-wrapped box has no free space to
     distribute, so every single-line pill renders exactly as before. */
  text-align: center;
}
.pill .pip {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}

/* Status pill = pill with leading dot, semantic mapping */
.pill--success { background: var(--success-soft); color: var(--success); }
.pill--warning { background: var(--warning-soft); color: var(--warning); }
.pill--danger  { background: var(--danger-soft);  color: var(--danger); }
.pill--info    { background: var(--info-soft);    color: var(--info); }
.pill--brand   { background: var(--brand-blue-soft); color: var(--brand-blue-strong); }
.pill--neutral { background: var(--surface-2); color: var(--text-secondary); }

/* Square 'role' chip (mono-feel for code-like tags) */
.tag {
  display: inline-block;
  padding: 1px 6px;
  border-radius: var(--radius-xs);
  font-size: var(--text-10);
  font-weight: var(--weight-medium);
  letter-spacing: 0.2px;
  background: var(--surface-2);
  color: var(--text-secondary);
  text-transform: uppercase;
}
.tag--brand { background: var(--brand-blue-soft); color: var(--brand-blue-strong); }

/* Channel-style mono chip */
.tag--mono {
  font-family: var(--font-mono);
  font-size: var(--text-11);
  text-transform: none;
  letter-spacing: 0;
  background: var(--surface-2);
  color: var(--text-secondary);
  padding: 1px 6px;
}

/* Online status indicator (pulsing) */
.status-online {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  background: var(--success-soft);
  color: var(--success);
  font-size: var(--text-11);
  font-weight: var(--weight-medium);
  border-radius: var(--radius-pill);
}
.status-online .pulse {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  position: relative;
}
.status-online .pulse::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: currentColor;
  animation: alfred-ping 2s ease-out infinite;
}
@keyframes alfred-ping {
  0%   { transform: scale(1);   opacity: 0.55; }
  100% { transform: scale(2.6); opacity: 0; }
}

/* Tenant-style dot with halo */
.dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--text-tertiary);
  flex-shrink: 0;
}
.dot--live    { background: var(--success); box-shadow: 0 0 0 2px var(--success-soft); }
.dot--success { background: var(--success); }
.dot--warning { background: var(--warning); }
.dot--danger  { background: var(--danger); }
.dot--info    { background: var(--info); }
.dot--brand   { background: var(--brand-blue); }

/* ============================================================
   Surface / Card
   ============================================================ */
.surface {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
}
.surface--flat { box-shadow: none; }
.surface--clip { overflow: hidden; }

/* Metric card */
.metric {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 14px 16px;
  box-shadow: var(--shadow-card);
}
.metric__label {
  font-size: var(--text-10);
  text-transform: uppercase;
  letter-spacing: 0.7px;
  color: var(--text-tertiary);
  font-weight: var(--weight-medium);
}
.metric__value-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-top: 6px;
}
.metric__value {
  font-size: var(--text-28);
  font-weight: var(--weight-medium);
  color: var(--text-primary);
  letter-spacing: -0.6px;
  font-feature-settings: 'tnum';
  line-height: 1;
}
.metric__delta {
  font-size: var(--text-11);
  font-weight: var(--weight-medium);
  color: var(--success);
  font-feature-settings: 'tnum';
}
.metric__delta--down { color: var(--danger); }
.metric__hint {
  font-size: var(--text-11);
  color: var(--text-tertiary);
  margin-top: 6px;
}
.metric__value--info    { color: var(--info); }
.metric__value--success { color: var(--success); }
.metric__value--warning { color: var(--warning); }
.metric__value--danger  { color: var(--danger); }

/* Metric grid */
.metric-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
}
@media (max-width: 800px) {
  .metric-grid { grid-template-columns: repeat(2, 1fr); }
}

/* ============================================================
   Toolbar
   ============================================================ */
.toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}
.toolbar__right { margin-left: auto; display: flex; align-items: center; gap: 6px; }

/* ============================================================
   Data table
   ============================================================ */
.table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-13);
}
.table th {
  font-size: var(--text-10);
  text-transform: uppercase;
  letter-spacing: 0.7px;
  color: var(--text-tertiary);
  font-weight: var(--weight-medium);
  padding: 10px 16px;
  text-align: left;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.table td {
  padding: var(--row-py) 16px;
  border-bottom: 1px solid var(--border);
  color: var(--text-primary);
  vertical-align: middle;
}
.table tr:last-child td { border-bottom: 0; }
.table tbody tr:hover td { background: var(--surface-2); }
.table td.num,
.table th.num { font-feature-settings: 'tnum'; text-align: right; }

/* Mono ID column */
.id-mono {
  font-family: var(--font-mono);
  font-size: var(--text-12);
  color: var(--brand-blue-strong);
  cursor: pointer;
}
.id-mono:hover { text-decoration: underline; }

/* Progress bar */
.progress {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.progress__bar {
  width: 110px;
  height: 4px;
  background: var(--surface-3);
  border-radius: var(--radius-pill);
  overflow: hidden;
}
.progress__bar > div {
  height: 100%;
  background: var(--success);
  border-radius: var(--radius-pill);
  transition: width 200ms var(--ease);
}
.progress__bar--info > div    { background: var(--brand-blue); }
.progress__bar--warning > div { background: var(--warning); }
.progress__bar--danger > div  { background: var(--danger); }
.progress__bar--empty > div   { width: 0; }
.progress__text {
  font-family: var(--font-mono);
  font-size: var(--text-11);
  color: var(--text-secondary);
  font-feature-settings: 'tnum';
  min-width: 32px;
}

/* Priority indicator (used in cell) */
.priority {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--text-tertiary);
}
.priority::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--text-tertiary);
}
.priority--high::before  { background: var(--danger); }
.priority--med::before   { background: var(--warning); }
.priority--low::before   { background: var(--text-tertiary); }

/* ============================================================
   Breadcrumb
   ============================================================ */
.breadcrumb {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--text-12);
  color: var(--text-tertiary);
}
.breadcrumb a {
  color: var(--text-tertiary);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease);
}
.breadcrumb a:hover { color: var(--text-secondary); }
.breadcrumb .sep { color: var(--border-strong); }
.breadcrumb .current { color: var(--text-primary); font-weight: var(--weight-medium); }

/* ============================================================
   Popover (shared with dropdown menu)
   ============================================================ */
.popover {
  position: fixed;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-popover);
  z-index: var(--z-popover);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition: opacity 140ms var(--ease),
              transform 140ms var(--ease),
              visibility 140ms;
  min-width: 200px;
}
.popover.is-open {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.popover__backdrop {
  position: fixed;
  inset: 0;
  z-index: var(--z-popover-backdrop);
  display: none;
}
.popover__backdrop.is-open { display: block; }

.popover__header {
  padding: 12px 14px 10px;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.popover__header--block { display: block; padding: 14px 14px 12px; }
.popover__title { font-size: var(--text-12); font-weight: var(--weight-medium); color: var(--text-primary); }
.popover__sub   { font-size: var(--text-11); color: var(--text-tertiary); margin-top: 2px; }
.popover__header-action {
  font-size: var(--text-11);
  color: var(--text-secondary);
  background: none;
  border: 0;
  cursor: pointer;
  padding: 0;
  font-family: inherit;
}
.popover__header-action:hover { color: var(--brand-blue); }

.popover__body { padding: 4px; }
.popover__footer {
  padding: 6px;
  border-top: 1px solid var(--border);
}
.popover__divider {
  height: 1px;
  background: var(--border);
  margin: 4px 0;
}
.popover__section {
  font-size: var(--text-10);
  text-transform: uppercase;
  color: var(--text-tertiary);
  padding: 10px 12px 4px;
  letter-spacing: 0.7px;
  font-weight: var(--weight-medium);
}

/* Popover checkbox row: one toggle per line inside a popover
   body. Used by column-toggle popovers and any other
   "scroll-and-pick" list. The <label> is flex so the input +
   text sit on a single row, but each label is a block so the
   list stacks vertically -- without this rule labels render
   inline and every toggle ends up on one row. */
.popover__check {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 10px;
  font-size: var(--text-13);
  border-radius: var(--radius-sm);
  cursor: pointer;
  color: var(--text-primary);
}
.popover__check:hover { background: var(--surface-2); }
.popover__check input { accent-color: var(--brand-blue); }
.popover__check.is-locked {
  color: var(--text-tertiary);
  cursor: default;
}

/* Dropdown-menu item. Used on both <button> and <a> elements --
   <a> is needed for shortcuts the user wants to right-click /
   open-in-new-tab (notification items, "View all", row-action
   Edit / Cloud settings / View users on a paged list). The
   text-decoration: none rule below stops the browser's default
   underline from leaking onto the <a> variant; without it,
   every popover that surfaces an <a class="menu-item"> renders
   with underlines on its rows. */
.menu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 7px 10px;
  background: none;
  border: 0;
  text-align: left;
  font-size: var(--text-13);
  color: var(--text-primary);
  text-decoration: none;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-family: inherit;
  transition: background 80ms var(--ease);
}
.menu-item:hover { background: var(--surface-2); text-decoration: none; }
.menu-item > svg { color: var(--text-tertiary); flex-shrink: 0; }
.menu-item--danger { color: var(--danger); }
.menu-item--danger > svg { color: var(--danger); }
.menu-item--brand { color: var(--brand-blue-strong); font-weight: var(--weight-medium); }
.menu-item__shortcut {
  margin-left: auto;
  display: inline-flex;
  gap: 3px;
}

/* ============================================================
   Modal (used for command palette + dialogs)
   ============================================================ */
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.32);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  z-index: var(--z-modal-backdrop);
  opacity: 0;
  visibility: hidden;
  transition: opacity 160ms var(--ease),
              visibility 160ms;
}
.modal-backdrop.is-open { opacity: 1; visibility: visible; }

.modal {
  position: fixed;
  top: 96px;
  left: 50%;
  transform: translateX(-50%) translateY(-8px);
  width: 92%;
  max-width: 640px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-popover);
  z-index: var(--z-modal);
  opacity: 0;
  visibility: hidden;
  transition: opacity 160ms var(--ease),
              transform 160ms var(--ease),
              visibility 160ms;
}
.modal.is-open {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
}
.modal--centered {
  top: 50%;
  transform: translate(-50%, calc(-50% - 8px));
}
.modal--centered.is-open {
  transform: translate(-50%, -50%);
}

/* ---- Searchable list modal (cb-modal) ----
   The full-list shell shared by the header company switcher and the user
   detail screen: a head, a search row, a scrolling list of rows and an
   optional foot. One definition, reused — the host page decides what a row
   click does. This is distinct from combobox.css's .cb-modal-* full list;
   only the .modal.cb-modal container is common ground, and the values here
   match it so the two never fight. */
.modal.cb-modal {
  width: 92%;
  max-width: 520px;
  padding: 0;
  flex-direction: column;
  max-height: min(80vh, 640px);
}
.modal.cb-modal.is-open { display: flex; }
.cb-modal__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 15px 18px;
  border-bottom: 1px solid var(--border);
}
.cb-modal__head h3 { margin: 0; font-size: var(--text-15); font-weight: var(--weight-medium); }
.cb-modal__search {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 11px 16px;
  border-bottom: 1px solid var(--border);
}
.cb-modal__search svg { color: var(--text-tertiary); flex-shrink: 0; }
.cb-modal__search input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: none;
  outline: none;
  font: inherit;
  font-size: var(--text-14);
  color: var(--text-primary);
}
.cb-modal__actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 14px;
  border-bottom: 1px solid var(--border);
}
.cb-modal__list {
  flex: 1;
  overflow-y: auto;
  padding: 6px;
  min-height: 180px;
}
.cb-modal__foot {
  padding: 12px 16px;
  border-top: 1px solid var(--border);
  display: flex;
  justify-content: flex-end;
}

/* Command palette pieces */
.cmd__input-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 18px;
  border-bottom: 1px solid var(--border);
}
.cmd__input-row > svg { color: var(--text-tertiary); flex-shrink: 0; }
.cmd__input-row input {
  flex: 1;
  border: 0;
  background: none;
  font: inherit;
  font-size: var(--text-15);
  color: var(--text-primary);
  outline: none;
}
.cmd__input-row input::placeholder { color: var(--text-tertiary); }
.cmd__section { padding: 6px; }
.cmd__section-label {
  font-size: var(--text-10);
  text-transform: uppercase;
  color: var(--text-tertiary);
  letter-spacing: 0.7px;
  font-weight: var(--weight-medium);
  padding: 8px 12px 4px;
}

/* Command-palette Job-ID jump: a selectable list of matches, or a status note. */
.cmd__jobjump-note {
  padding: 6px 12px 10px;
  font-size: var(--text-12);
  color: var(--text-tertiary);
}
.cmd__jobjump-result {
  display: flex;
  align-items: center;
  gap: 10px;
}
/* Keyboard/hover selection reuses the menu-item hover surface. */
.cmd__jobjump-result.is-selected {
  background: var(--surface-2);
}
.cmd__jobjump-id {
  flex-shrink: 0;
  color: var(--text-tertiary);
}
/* The matched leading hex stands out against the dimmed remainder. */
.cmd__jobjump-hl {
  color: var(--text-primary);
  font-weight: var(--weight-medium);
  background: var(--brand-blue-soft);
  border-radius: var(--radius-xs);
  padding: 0 1px;
}
.cmd__jobjump-user {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--text-12);
  color: var(--text-secondary);
}
.cmd__jobjump-updated {
  margin-left: auto;
  flex-shrink: 0;
  font-size: var(--text-11);
  color: var(--text-tertiary);
  font-feature-settings: 'tnum';
}
.cmd__footer {
  border-top: 1px solid var(--border);
  padding: 8px 14px;
  display: flex;
  align-items: center;
  gap: 14px;
  font-size: var(--text-11);
  color: var(--text-tertiary);
}
.cmd__footer .hk { display: inline-flex; align-items: center; gap: 4px; }

/* ============================================================
   Tenant switcher (pill + popover list)
   ============================================================ */
.tenant-switcher {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  height: var(--control-h);
  padding: 0 8px 0 11px;
  background: var(--surface-2);
  border: 1px solid transparent;
  border-radius: var(--radius);
  font-size: var(--text-12);
  font-weight: var(--weight-medium);
  color: var(--text-primary);
  cursor: pointer;
  font-family: inherit;
  letter-spacing: -0.1px;
  transition: background var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease);
}
.tenant-switcher:hover { background: var(--surface); border-color: var(--border-strong); }
.tenant-switcher:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.tenant-switcher .name {
  max-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tenant-switcher .chev {
  color: var(--text-tertiary);
  flex-shrink: 0;
  transition: transform var(--dur) cubic-bezier(0.2, 0, 0.13, 1);
}

/* ---- Inline dropdown (the switcher's default surface) ----
   The pill is the combobox trigger; clicking it drops this panel anchored to
   the pill's right edge, mirroring the user-detail access combobox. It reuses
   .cb-panel / .cb-search / .cb-list / .cb-expand from combobox.css so both
   surfaces share one definition; only the pill anchoring is switcher-specific.
   The panel's "Open as full list" is the sole path to the full modal. */
.app-actions .tenant-combobox { width: auto; }
.tenant-combobox .cb-panel {
  left: auto;
  right: 0;
  width: min(320px, calc(100vw - 24px));
}
.tenant-combobox.is-open .tenant-switcher {
  background: var(--surface);
  border-color: var(--border-strong);
}
.tenant-combobox.is-open .chev { transform: rotate(180deg); }

.tenant-list {
  max-height: 360px;
  overflow-y: auto;
  padding: 4px;
}
.tenant-list::-webkit-scrollbar { width: 8px; }
.tenant-list::-webkit-scrollbar-thumb {
  background: var(--surface-3);
  border-radius: var(--radius-pill);
  border: 2px solid var(--surface);
}
.tenant-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 10px;
  font-size: var(--text-13);
  border-radius: var(--radius-sm);
  cursor: pointer;
  border: 0;
  background: none;
  text-align: left;
  width: 100%;
  color: var(--text-primary);
  font-family: inherit;
}
.tenant-item:hover { background: var(--surface-2); }
.tenant-item.is-selected {
  background: var(--brand-blue-soft);
  color: var(--brand-navy);
  font-weight: var(--weight-medium);
}
.tenant-item.is-selected svg { color: var(--brand-blue-strong); }
.tenant-item__name {
  display: flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
  flex: 1;
}
.tenant-item__name > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tenant-empty {
  padding: 24px 12px;
  text-align: center;
  color: var(--text-tertiary);
  font-size: var(--text-12);
}

/* ---- Switch in flight ----
   Picking a company POSTs and then reloads the page, which is long enough to
   read as "nothing happened". These states are applied synchronously with the
   click, before the request leaves the browser: the chosen row swaps its
   trailing slot for a spinner, every row goes disabled so the switch cannot be
   double-fired, and the header pill mirrors the same spinner so the feedback is
   still visible after the panel closes. */
.tenant-list.is-switching .tenant-item { cursor: default; }
.tenant-item:disabled:not([aria-busy="true"]) { opacity: 0.5; }
.tenant-item[aria-busy="true"] { background: var(--surface-2); }

/* The trailing check (and the pill's chevron) give up their slot to the
   spinner. Note: `hidden` on an SVG element is not honoured by the HTML UA
   stylesheet, so the swap is done here in CSS rather than in JS. */
.tenant-item[aria-busy="true"] > svg,
.tenant-switcher[aria-busy="true"] .chev { display: none; }
.tenant-switcher[aria-busy="true"] { cursor: progress; }

.tenant-spinner {
  width: 13px;
  height: 13px;
  flex-shrink: 0;
  border: 1.5px solid var(--surface-3);
  border-top-color: var(--brand-blue);
  border-radius: 50%;
  animation: tenant-spin 0.7s linear infinite;
}
@keyframes tenant-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .tenant-spinner { animation-duration: 2.4s; }
}

/* Search row inside a popover */
.popover-search {
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 8px;
}
.popover-search > svg { color: var(--text-tertiary); flex-shrink: 0; }
.popover-search input {
  flex: 1;
  border: 0;
  background: none;
  outline: none;
  font: inherit;
  font-size: var(--text-13);
  color: var(--text-primary);
}
.popover-search input::placeholder { color: var(--text-tertiary); }

/* ============================================================
   Empty state
   ============================================================ */
.empty {
  padding: 28px 16px 24px;
  text-align: center;
}
.empty__icon {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--surface-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--text-tertiary);
  margin-bottom: 10px;
}
.empty__title { font-size: var(--text-13); color: var(--text-primary); font-weight: var(--weight-medium); }
.empty__sub   { font-size: var(--text-12); color: var(--text-tertiary); margin-top: 3px; }

/* ============================================================
   Theme toggle (segmented control)
   ============================================================ */
.theme-toggle {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 6px 8px 6px 10px;
}
.theme-toggle__label { font-size: var(--text-12); color: var(--text-secondary); flex: 1; }
.theme-toggle__options {
  display: flex;
  background: var(--surface-2);
  padding: 2px;
  border-radius: var(--radius);
  gap: 0;
}
.theme-toggle__options button {
  background: none;
  border: 0;
  padding: 4px 8px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  color: var(--text-tertiary);
  display: inline-flex;
  align-items: center;
}
.theme-toggle__options button.is-active {
  background: var(--surface);
  color: var(--text-primary);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.06);
}
[data-theme="dark"] .theme-toggle__options button.is-active {
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
}

/* ============================================================
   AppHeader / AppFooter / PageHeader patterns
   ============================================================ */
.app-header {
  position: sticky;
  top: 0;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  z-index: var(--z-header);
}
.app-header__inner {
  max-width: var(--container-max);
  margin: 0 auto;
  display: flex;
  align-items: stretch;
  height: var(--header-h);
  padding: 0 var(--container-pad);
}

.brand {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-right: 28px;
  flex-shrink: 0;
}
.brand__mark { width: 22px; height: 24px; flex-shrink: 0; }
.brand__text {
  font-size: var(--text-15);
  font-weight: var(--weight-medium);
  letter-spacing: -0.3px;
  color: var(--brand-navy);
}

.app-nav {
  display: flex;
  align-items: stretch;
  flex: 1;
  min-width: 0;
}
.nav-link {
  display: inline-flex;
  align-items: center;
  padding: 0 14px;
  font-size: var(--text-13);
  font-weight: var(--weight-regular);
  color: var(--text-secondary);
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  cursor: pointer;
  position: relative;
  letter-spacing: -0.1px;
  font-family: inherit;
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease);
}
.nav-link:hover { color: var(--text-primary); }
.nav-link.is-active {
  color: var(--brand-navy);
  font-weight: var(--weight-medium);
  border-bottom-color: var(--brand-blue);
}
[data-theme="dark"] .nav-link.is-active { color: var(--text-primary); }

.app-actions {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}
.app-actions > * + * { margin-left: 0; }
.app-actions .tenant-combobox,
.app-actions .search-trigger { margin-right: 6px; }

/* THE `100%` IS WHAT KEEPS THE PAGE FROM GROWING SIDEWAYS.
   <body> is a column flex container, so this is a flex item -- and the
   `margin: 0 auto` below is why it never stretched to the viewport:
   an auto margin on the cross axis cancels the stretch, leaving the box
   sized fit-content and bounded only by the max-width. So a nowrap table
   1118px wide made THIS box 1118px wide inside a 700px viewport, and the
   table's own wrapper never scrolled despite its overflow-x:auto --
   nothing had forced it to be narrower than its content.

   Capping the box hands the overflow back to that wrapper, which then
   scrolls the table by itself as designed, and the document stops
   scrolling sideways. min() rather than a plain 100%, because the
   container-max cap still has to win on a wide desktop. */
.app-main {
  max-width: min(var(--container-max), 100%);
  margin: 0 auto;
  padding: 28px var(--container-pad) 40px;
}

.page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  margin-bottom: 24px;
  gap: 20px;
}
/* Leading identity block for page headers: an icon chip (or avatar)
   vertically centered against the title + meta column. Promoted from
   the users list so every surface with a glyph-beside-title header
   aligns the same way. */
.page-ident {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.page-ident__badge {
  width: 34px;
  height: 34px;
  border-radius: var(--radius);
  background: var(--brand-blue-soft);
  color: var(--brand-blue-strong);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.page-header__meta {
  font-size: var(--text-13);
  color: var(--text-secondary);
  margin-top: 4px;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.page-header__meta .sep { color: var(--border-strong); }
.page-header__actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

/* Footer */
.app-footer {
  border-top: 1px solid var(--border);
  background: var(--surface);
  margin-top: 40px;
}
.app-footer__inner {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 14px var(--container-pad);
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: var(--text-11);
  color: var(--text-tertiary);
  flex-wrap: wrap;
  gap: 8px;
}
.app-footer .sep { color: var(--border-strong); margin: 0 4px; }
.app-footer a {
  color: var(--text-tertiary);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease);
}
.app-footer a:hover { color: var(--text-secondary); }
.app-footer__side {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
}
.build-hash {
  font-family: var(--font-mono);
  color: var(--text-secondary);
  padding: 1px 5px;
  background: var(--surface-2);
  border-radius: var(--radius-xs);
}
.heart {
  display: inline-block;
  vertical-align: -2px;
  color: var(--danger);
  margin: 0 3px;
}

/* ============================================================
   Responsive trims
   ============================================================ */
@media (max-width: 1100px) {
  .search-trigger { min-width: 0; }
  .search-trigger .search-trigger__placeholder { display: none; }
  .tenant-switcher .name { max-width: 110px; }
}
@media (max-width: 800px) {
  .nav-link { padding: 0 10px; font-size: var(--text-12); }
  .app-nav { overflow-x: auto; }
}

/* ============================================================
   Utilities
   ============================================================ */

/* Present to assistive tech, invisible on screen. Backs the live region that
   announces a tenant switch while it is still in flight. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
