/* ============================================================================
   app.css — Apex Dash Royal Sports

   CASCADE NOTE (PLAN.md A17) — READ BEFORE ADDING A RULE
   Tailwind's browser build emits its utilities inside @layer utilities.
   Everything in this file is UNLAYERED, and unlayered CSS always beats layered
   CSS regardless of order or specificity. Consequence:

     - `apex-` classes own ALL color, radius, shadow, type and component geometry.
     - Tailwind owns layout, flex/grid, spacing and responsive prefixes ONLY.
     - Never override an `apex-` component with a utility class. Add a modifier
       (`apex-btn--ghost`) or a new component class instead.
     - Where two rules in THIS file compete for the same property on the same
       element, source order decides. The visibility rules in section 14 rely on
       that, so do not reorder them above .apex-cardlist.

   Second payoff: if the Tailwind CDN is unreachable, every visual decision still
   loads because it lives here. Only layout utilities are lost.

   Every hit target is at least var(--apex-tap) (44px) square. That is a hard
   floor from AGENTS.md, not a preference, so controls reference the token
   instead of declaring their own height.
   ========================================================================== */

/* ---------------------------------------------------------------------------
   1. Base
   --------------------------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

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

body {
  margin: 0;
  min-height: 100dvh;
  background-color: var(--apex-mist);
  color: var(--apex-ink);
  font-family: var(--apex-font);
  font-size: var(--apex-fs-body);
  font-weight: 400;
  line-height: 1.6;
  /* Prevents double-tap zoom delay and the grey flash on tap (WIG / A7). */
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

h1,
h2,
h3,
p,
figure,
dl,
dd {
  margin: 0;
}

/* Headings are the only role that takes the display face. Everything else in
   this file reads in --apex-font (Archivo). The one exception is a heading tag
   carrying a label role, not a heading — .apex-drawer__group h3 below. */
h1,
h2,
h3 {
  font-family: var(--apex-font-display);
  font-weight: 800;
  line-height: 1.3;
  text-wrap: balance;
}

a {
  color: inherit;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

button,
input,
select {
  font: inherit;
  color: inherit;
}

/* The UA's `[hidden] { display: none }` loses to any author display
   declaration, exactly as with <dialog>. Anything that is toggled with the
   hidden attribute needs this to actually hide. */
[hidden] {
  display: none !important;
}

/* Browser surfaces are part of the design (craft-floor / A12). */
::selection {
  background-color: var(--apex-ember-tint);
  color: var(--apex-field);
}

* {
  caret-color: var(--apex-ember);
}

:focus-visible {
  outline: 3px solid var(--apex-ember);
  outline-offset: 2px;
}

.apex-table tbody tr,
.apex-anchor {
  scroll-margin-top: var(--apex-sticky-offset);
}

.apex-num {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

.apex-sr {
  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;
}

/* Custom scrollbar — DESIGN.md mandates a cool-mist track and a soft slate
   thumb. This deliberately overrides operate.md's "no custom scrollbars for
   flavor": the brief wins. */
* {
  scrollbar-color: var(--apex-muted) var(--apex-mist);
  scrollbar-width: thin;
}

::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

::-webkit-scrollbar-track {
  background: var(--apex-mist);
}

::-webkit-scrollbar-thumb {
  background: var(--apex-muted);
  border: 2px solid var(--apex-mist);
  border-radius: var(--apex-r-pill);
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---------------------------------------------------------------------------
   2. Skip link
   --------------------------------------------------------------------------- */

.apex-skip {
  position: absolute;
  left: var(--apex-s4);
  top: var(--apex-s4);
  z-index: 60;
  display: inline-flex;
  align-items: center;
  min-height: var(--apex-tap);
  padding: 10px 20px;
  background-color: var(--apex-ember);
  color: var(--apex-white);
  font-size: var(--apex-fs-body);
  font-weight: 700;
  border-radius: var(--apex-r-pill);
  box-shadow: var(--apex-sh-glow);
  text-decoration: none;
  transform: translateY(-200%);
}

.apex-skip:focus-visible {
  transform: translateY(0);
}

/* ---------------------------------------------------------------------------
   3. Shell
   --------------------------------------------------------------------------- */

.apex-shell {
  display: grid;
  grid-template-columns: var(--apex-sidebar) minmax(0, 1fr);
  grid-template-rows: var(--apex-topbar) minmax(0, 1fr);
  min-height: 100dvh;
}

.apex-sidebar {
  grid-column: 1;
  grid-row: 1 / -1;
  position: sticky;
  top: 0;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  background-color: var(--apex-field);
  border-right: 1px solid var(--apex-on-field-hairline);
  overflow-y: auto;
}

.apex-topbar {
  grid-column: 2;
  grid-row: 1;
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: var(--apex-s4);
  height: var(--apex-topbar);
  padding-inline: var(--apex-s5);
  background-color: var(--apex-white);
  border-bottom: 1px solid var(--apex-line-70);
  box-shadow: var(--apex-sh-header);
}

.apex-main {
  grid-column: 2;
  grid-row: 2;
  min-width: 0;
  padding: var(--apex-s6) var(--apex-s5);
}

.apex-main:focus {
  outline: none;
}

.apex-container {
  width: 100%;
  max-width: var(--apex-content);
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: var(--apex-s5);
}

.apex-backdrop {
  display: none;
}

/* ---------------------------------------------------------------------------
   4. Sidebar brand and navigation
   --------------------------------------------------------------------------- */

.apex-brand {
  display: flex;
  align-items: center;
  gap: var(--apex-s3);
  height: var(--apex-topbar);
  padding-inline: var(--apex-s5);
  border-bottom: 1px solid var(--apex-on-field-hairline);
  flex: 0 0 auto;
}

/* The supplied brand monogram, replacing the ember disc that used to stand in
   for it. object-fit because the source is square but the mark is drawn with
   internal padding, so the frame is larger than the visible artwork; flex:0 0
   auto so the lockup text beside it can never squeeze the mark out of shape. */
.apex-brand__mark {
  display: block;
  width: 34px;
  height: 34px;
  object-fit: contain;
  flex: 0 0 auto;
}

.apex-brand__name {
  display: block;
  color: var(--apex-white);
  font-family: var(--apex-font-display);
  font-size: var(--apex-fs-subhead);
  font-weight: 800;
  letter-spacing: -0.01em;
  line-height: 1.2;
}

.apex-brand__sub {
  display: block;
  color: var(--apex-on-field-muted);
  font-size: var(--apex-fs-micro);
  font-weight: 800;
  letter-spacing: var(--apex-ls-micro);
  text-transform: uppercase;
}

.apex-nav {
  display: flex;
  flex-direction: column;
  gap: var(--apex-s1);
  padding: var(--apex-s4) var(--apex-s3);
  flex: 1 1 auto;
}

.apex-nav__group {
  padding: var(--apex-s4) var(--apex-s3) var(--apex-s1);
  color: var(--apex-on-field-muted);
  font-size: var(--apex-fs-micro);
  font-weight: 800;
  letter-spacing: var(--apex-ls-micro);
  text-transform: uppercase;
}

/* Active state (PLAN.md A1): an ember underline beneath the label — DESIGN.md's
   own nav device — never a colored left border above 1px. */
.apex-nav__item {
  display: flex;
  align-items: center;
  gap: var(--apex-s3);
  min-height: var(--apex-tap);
  padding: 0 var(--apex-s3);
  border-radius: var(--apex-r-pill);
  color: var(--apex-on-field);
  font-size: 15px;
  font-weight: 600;
  text-decoration: none;
  transition: background-color 0.2s ease, color 0.2s ease;
}

.apex-nav__item svg {
  flex: 0 0 auto;
}

.apex-nav__label {
  position: relative;
  padding-bottom: 2px;
}

.apex-nav__label::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  border-radius: var(--apex-r-pill);
  background-color: var(--apex-ember);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.2s ease;
}

.apex-nav__item:hover {
  background-color: var(--apex-on-field-hairline);
  color: var(--apex-white);
}

.apex-nav__item:hover .apex-nav__label::after,
.apex-nav__item[aria-current="page"] .apex-nav__label::after {
  transform: scaleX(1);
}

.apex-nav__item[aria-current="page"] {
  background-color: var(--apex-field-soft);
  color: var(--apex-white);
  font-weight: 700;
}

.apex-nav__item[aria-current="page"] svg {
  color: var(--apex-ember-bright);
}

.apex-sidebar__foot {
  flex: 0 0 auto;
  padding: var(--apex-s4) var(--apex-s5) var(--apex-s5);
  border-top: 1px solid var(--apex-on-field-hairline);
}

.apex-sidebar__note {
  color: var(--apex-on-field-muted);
  font-size: var(--apex-fs-micro);
  font-weight: 800;
  letter-spacing: var(--apex-ls-micro);
  text-transform: uppercase;
}

.apex-sidebar__stamp {
  display: block;
  margin-top: var(--apex-s2);
  color: var(--apex-white);
  font-size: var(--apex-fs-small);
  font-weight: 600;
}

/* ---------------------------------------------------------------------------
   5. Off-canvas navigation below lg
   --------------------------------------------------------------------------- */

/* Two classes, not one: .apex-iconbtn sets display: inline-grid further down
   this file with the same specificity, and would otherwise win on source order
   and leave the toggle visible on every desktop width. */
.apex-iconbtn.apex-nav-toggle {
  display: none;
}

/* The off-canvas needs a visible exit. Without it the only ways out are
   re-tapping the hamburger at the far corner or hitting a narrow backdrop
   strip — both poor one-handed targets. */
.apex-iconbtn.apex-nav-close {
  display: none;
  margin-inline-start: auto;
  /* flex-shrink: 0 — without it the button is squeezed below 44px in the
     brand row once the lockup text takes its space. */
  flex: 0 0 auto;
}

@media (max-width: 1023px) {
  .apex-shell {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: var(--apex-topbar) minmax(0, 1fr);
  }

  .apex-topbar,
  .apex-main {
    grid-column: 1;
  }

  .apex-sidebar {
    position: fixed;
    inset-block: 0;
    inset-inline-start: 0;
    width: var(--apex-sidebar);
    max-width: 86vw;
    z-index: 50;
    transform: translateX(-100%);
    transition: transform 0.2s ease;
    box-shadow: var(--apex-sh-ambient);
  }

  .apex-shell[data-apex-nav="open"] .apex-sidebar {
    transform: translateX(0);
  }

  .apex-iconbtn.apex-nav-toggle {
    display: inline-flex;
  }

  .apex-iconbtn.apex-nav-close {
    display: inline-grid;
  }

  .apex-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 40;
    background-color: var(--apex-field-scrim);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease;
  }

  .apex-shell[data-apex-nav="open"] .apex-backdrop {
    opacity: 1;
    pointer-events: auto;
  }

  .apex-main {
    padding: var(--apex-s5) var(--apex-s4);
  }
}

/* ---------------------------------------------------------------------------
   6. Buttons and icon buttons
   --------------------------------------------------------------------------- */

.apex-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--apex-s2);
  min-height: var(--apex-tap);
  padding: 10px 20px;
  border: 1px solid var(--apex-line);
  border-radius: var(--apex-r-pill);
  background-color: var(--apex-white);
  color: var(--apex-field-mid);
  font-size: var(--apex-fs-body);
  font-weight: 700;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease,
    box-shadow 0.2s ease;
}

.apex-btn:hover {
  border-color: var(--apex-ember);
  /* Text, not a fill: ember-dark is the step that clears 4.5:1. */
  color: var(--apex-ember-dark);
  background-color: var(--apex-ember-scrim);
}

.apex-btn:active {
  transform: translateY(1px);
}

.apex-btn[disabled],
.apex-btn[aria-disabled="true"] {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}

.apex-btn--primary {
  background-color: var(--apex-ember);
  border-color: var(--apex-ember);
  color: var(--apex-white);
  box-shadow: var(--apex-sh-glow);
}

.apex-btn--primary:hover {
  background-color: var(--apex-ember-deep);
  border-color: var(--apex-ember-deep);
  color: var(--apex-white);
}

.apex-btn--quiet {
  border-color: transparent;
  background-color: transparent;
  color: var(--apex-muted-deep);
}

.apex-btn--quiet:hover {
  background-color: var(--apex-mist);
  border-color: var(--apex-line);
  color: var(--apex-field-mid);
}

/* Same 44px floor as every other control; only the visual weight is lighter. */
.apex-btn--compact {
  min-height: var(--apex-tap);
  padding: 0 var(--apex-s3);
  font-size: var(--apex-fs-small);
}

.apex-iconbtn {
  display: inline-grid;
  place-items: center;
  width: var(--apex-tap);
  height: var(--apex-tap);
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--apex-r-pill);
  background-color: transparent;
  color: var(--apex-field-mid);
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

.apex-iconbtn:hover {
  background-color: var(--apex-mist);
  border-color: var(--apex-line);
}

.apex-iconbtn[disabled] {
  opacity: 0.35;
  cursor: not-allowed;
  pointer-events: none;
}

.apex-topbar .apex-iconbtn {
  color: var(--apex-muted-deep);
}

.apex-sidebar .apex-iconbtn {
  color: var(--apex-on-field);
}

.apex-sidebar .apex-iconbtn:hover {
  background-color: var(--apex-on-field-hairline);
  border-color: transparent;
  color: var(--apex-white);
}

/* ---------------------------------------------------------------------------
   7. Topbar contents
   --------------------------------------------------------------------------- */

/* The topbar carries the page's single h1. This is the page title, not chrome,
   so it takes the display face — which the base h1 rule already supplies, along
   with weight 800 and line-height 1.3. Only size, colour and the no-wrap guard
   are set here.
   The size steps up from md because at 320px the longest page name plus the
   mobile hamburger leaves 212px, and "Appointment Dokter" measures 200px at
   18px in this face. Above md there is room to make the h1 clearly outrank the
   18px panel h2 rather than tie with it. */
.apex-topbar__title {
  display: flex;
  align-items: center;
  min-width: 0;
  /* Pushes the date stamp to the trailing edge; the parent topbar is the row. */
  margin-inline-end: auto;
}

.apex-topbar__title h1 {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--apex-fs-headline);
  color: var(--apex-field);
  letter-spacing: -0.01em;
}

@media (min-width: 768px) {
  .apex-topbar__title h1 {
    font-size: var(--apex-fs-metric);
  }
}

.apex-stamp {
  display: none;
  padding: 0 var(--apex-s4);
  height: var(--apex-tap);
  align-items: center;
  gap: var(--apex-s2);
  border: 1px solid var(--apex-line);
  border-radius: var(--apex-r-pill);
  background-color: var(--apex-white);
  color: var(--apex-muted-deep);
  font-size: var(--apex-fs-small);
  font-weight: 600;
  white-space: nowrap;
}

@media (min-width: 1280px) {
  .apex-stamp {
    display: inline-flex;
  }
}

/* ---------------------------------------------------------------------------
   8. Page title
   The dashboards carry no title block. The page's single h1 lives in the topbar,
   so the content container starts straight into the data.
   --------------------------------------------------------------------------- */

/* ---------------------------------------------------------------------------
   9. KPI rail
   Hairline-divided, not card capsules (PLAN.md deviation 4). No sparkline and
   no accent-colored figure (amendment A3).
   --------------------------------------------------------------------------- */

/* Hairlines are drawn by each tile rather than by the rail's own background.
   The rail surface stays white on purpose: auto-fit produces as many tracks as
   fit, so a 5-tile rail at a 4-column width leaves an unfilled cell, and a
   line-coloured rail background renders that cell as a grey slab that reads as
   a tile that failed to load. */
.apex-kpi-rail {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 0;
  background-color: var(--apex-white);
  border: 1px solid var(--apex-line-70);
  border-radius: var(--apex-r-card);
  overflow: hidden;
}

.apex-kpi {
  padding: var(--apex-s4) var(--apex-s5);
  background-color: var(--apex-white);
  /* Inset ring: draws the top and left hairline inside the tile, so internal
     seams land exactly once and no divider depends on a neighbour existing. */
  box-shadow: inset 1px 1px 0 0 var(--apex-line-70);
}

.apex-kpi__label {
  display: block;
  color: var(--apex-muted);
  font-size: var(--apex-fs-label);
  font-weight: 800;
  letter-spacing: var(--apex-ls-label);
  text-transform: uppercase;
}

.apex-kpi__value {
  display: block;
  margin-top: var(--apex-s2);
  color: var(--apex-field);
  font-family: var(--apex-font-display);
  /* The one type step DESIGN.md's catalogue ramp does not carry: a dashboard
     needs a metric figure larger than a headline. Documented in PLAN.md. */
  font-size: var(--apex-fs-metric);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.01em;
}

.apex-kpi__meta {
  display: block;
  margin-top: var(--apex-s1);
  font-size: var(--apex-fs-small);
  color: var(--apex-muted-deep);
}

/* ---------------------------------------------------------------------------
   10. Panels
   --------------------------------------------------------------------------- */

.apex-panel {
  background-color: var(--apex-white);
  border: 1px solid var(--apex-line-70);
  border-radius: var(--apex-r-card);
  overflow: hidden;
}

.apex-panel__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--apex-s2) var(--apex-s4);
  padding: var(--apex-s4) var(--apex-s5);
  border-bottom: 1px solid var(--apex-line-70);
}

.apex-panel__head h2 {
  font-size: var(--apex-fs-headline);
  color: var(--apex-field);
}

.apex-panel__head p {
  color: var(--apex-muted);
  font-size: var(--apex-fs-small);
}

.apex-panel__body {
  padding: var(--apex-s5);
}

.apex-split {
  display: grid;
  gap: var(--apex-s5);
  /* Panels take their natural height. Stretching them to match the taller
     sibling leaves a void inside the shorter one, which reads as a bug. */
  align-items: start;
}

@media (min-width: 1200px) {
  .apex-split {
    grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  }
}

/* ---------------------------------------------------------------------------
   11. Filters
   --------------------------------------------------------------------------- */

.apex-filters {
  display: flex;
  flex-direction: column;
  gap: var(--apex-s3);
  padding: var(--apex-s4) var(--apex-s5);
  background-color: var(--apex-white);
  border: 1px solid var(--apex-line-70);
  border-radius: var(--apex-r-card);
}

.apex-filters__body {
  display: flex;
  flex-direction: column;
  gap: var(--apex-s3);
}

/* The disclosure exists only below md, where the bar is twelve controls and
   about 700px tall. Above md the button is hidden and the body is always
   expanded, so the collapsed state can never hide controls on a wide screen. */
.apex-filters__toggle {
  display: none;
  justify-content: center;
  width: 100%;
}

@media (max-width: 767px) {
  .apex-filters__toggle {
    display: flex;
  }
}

.apex-filters__row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--apex-s3);
}

.apex-filter {
  display: flex;
  flex-direction: column;
  gap: var(--apex-s1);
  min-width: 148px;
  border: 0;
  margin: 0;
  padding: 0;
}

.apex-filter--grow {
  flex: 1 1 240px;
  min-width: 0;
}

/* The chips row carries the status chips AND the result count and Reset, so it
   lays out as a wrapping row rather than a stacked label+control. The count's
   auto start margin is what pushes it and Reset to the trailing edge; when the
   chips fill the line they wrap together onto the next one. */
.apex-filter--chips {
  flex: 1 1 100%;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--apex-s2) var(--apex-s3);
}

.apex-filter > label,
.apex-filter__legend {
  color: var(--apex-muted);
  font-size: var(--apex-fs-label);
  font-weight: 800;
  letter-spacing: var(--apex-ls-label);
  text-transform: uppercase;
}

.apex-filters__count {
  margin-inline-start: auto;
  color: var(--apex-muted-deep);
  font-size: var(--apex-fs-small);
  font-weight: 600;
}

/* Chips wrap rather than clip. ui-ux-pro-max rates forced one-row clipping a
   High-severity defect. */
.apex-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--apex-s2);
}

.apex-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--apex-s2);
  min-height: var(--apex-tap);
  padding: 7px 16px;
  border: 1px solid var(--apex-line);
  border-radius: var(--apex-r-pill);
  background-color: var(--apex-white);
  color: var(--apex-field-mid);
  font-size: var(--apex-fs-small);
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

.apex-chip:hover {
  border-color: var(--apex-ember);
  /* Text, not a fill: ember-dark is the step that clears 4.5:1. */
  color: var(--apex-ember-dark);
}

.apex-chip[aria-pressed="true"] {
  background-color: var(--apex-ember);
  border-color: var(--apex-ember);
  color: var(--apex-white);
  box-shadow: var(--apex-sh-glow);
}

.apex-chip__count {
  font-variant-numeric: tabular-nums;
  font-weight: 800;
  opacity: 0.72;
}

/* Fields: pill, 44px, ember caret. */
.apex-field {
  height: var(--apex-tap);
  padding: 0 var(--apex-s4);
  border: 1px solid var(--apex-line);
  border-radius: var(--apex-r-pill);
  background-color: var(--apex-white);
  color: var(--apex-ink);
  font-size: var(--apex-fs-body);
}

select.apex-field {
  /* Native selects need an explicit pair, or Windows dark mode renders them dark. */
  background-color: var(--apex-white);
  color: var(--apex-ink);
  padding-inline-end: var(--apex-s5);
}

.apex-field:focus-visible {
  border-color: var(--apex-ember);
  box-shadow: 0 0 0 3px var(--apex-ember-ring);
  outline: none;
}

.apex-field--date {
  min-width: 148px;
}

/* ---------------------------------------------------------------------------
   12. Table
   The wrapper is a bounded scroll region so BOTH the sticky header and the
   sticky identity column genuinely work. Chaining is left at default so the
   page can still scroll past the table.
   --------------------------------------------------------------------------- */

/* One frame for the whole table region — header, body and pager — so a table
   page never nests containers inside containers. */
.apex-table-shell {
  background-color: var(--apex-white);
  border: 1px solid var(--apex-line-70);
  border-radius: var(--apex-r-card);
  overflow: hidden;
}

.apex-table-shell__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--apex-s2) var(--apex-s4);
  padding: var(--apex-s4) var(--apex-s5);
  border-bottom: 1px solid var(--apex-line-70);
}

.apex-table-shell__head h2 {
  font-size: var(--apex-fs-headline);
  color: var(--apex-field);
}

.apex-table-shell__head p {
  color: var(--apex-muted);
  font-size: var(--apex-fs-small);
}

.apex-table-wrap {
  overflow: auto;
  /* A bounded region is what makes the sticky header and the sticky identity
     column work — both need a scroll container. It is capped so a tall monitor
     does not turn the table into an endless page, and floored against the
     viewport so the region stays reachable on a laptop. */
  max-height: min(640px, calc(100vh - 320px));
  max-height: min(640px, calc(100dvh - 320px));
  background-color: var(--apex-white);
}

.apex-table {
  width: 100%;
  /* Fixed layout is what makes the colgroup widths authoritative and the
     ellipsis rules in the cells reliable. Without it the browser redistributes
     width by content and a dense table drifts out of its own container. */
  table-layout: fixed;
  border-collapse: separate;
  border-spacing: 0;
  font-size: var(--apex-fs-body);
}

/* Figures never wrap mid-value: "24 Sep 2026" broken across two lines reads as
   two separate facts. */
.apex-table .apex-num {
  white-space: nowrap;
}

.apex-table thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  height: var(--apex-thead);
  padding: 0 var(--apex-s2);
  background-color: var(--apex-mist);
  border-bottom: 1px solid var(--apex-line-70);
  /* Muted Deep, not Muted: these labels sit on the cool-mist header band, where
     Slate Muted measures 4.35:1. DESIGN.md names this exact substitution —
     Slate Muted Deep is the secondary text role for the cool-mist field. */
  color: var(--apex-muted-deep);
  font-size: var(--apex-fs-label);
  font-weight: 800;
  letter-spacing: var(--apex-ls-label);
  text-transform: uppercase;
  text-align: left;
  white-space: nowrap;
}

.apex-table th.is-num,
.apex-table td.is-num {
  text-align: right;
}

.apex-table__sort {
  display: inline-flex;
  align-items: center;
  gap: var(--apex-s1);
  min-height: var(--apex-tap);
  /* A narrow column such as "Jam" would otherwise shrink its own sort control
     below the hit-target floor. */
  min-width: var(--apex-tap);
  padding: 0 var(--apex-s1);
  border: 0;
  border-radius: var(--apex-r-pill);
  background: transparent;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
}

.apex-table__sort:hover {
  color: var(--apex-field-mid);
}

.apex-table th[aria-sort="ascending"] .apex-table__sort,
.apex-table th[aria-sort="descending"] .apex-table__sort {
  color: var(--apex-field);
}

.apex-table tbody td {
  padding: var(--apex-s2);
  border-bottom: 1px solid var(--apex-line-70);
  background-color: var(--apex-white);
  vertical-align: middle;
}

.apex-table tbody tr:last-child td {
  border-bottom: 0;
}

/* The hover tint exists to track a row across nine columns — a real reading aid
   on a dense grid — not to promise that the row is clickable. It is not. */
.apex-table tbody tr:hover td {
  background-image: linear-gradient(var(--apex-ember-scrim), var(--apex-ember-scrim));
}

.apex-table td.is-sticky,
.apex-table th.is-sticky {
  position: sticky;
  left: 0;
  z-index: 1;
}

.apex-table thead th.is-sticky {
  z-index: 3;
}

.apex-table td.is-sticky-end,
.apex-table th.is-sticky-end {
  position: sticky;
  right: 0;
  z-index: 1;
  /* An inset hairline rather than a border: a real border on a fixed-layout
     cell adds its width to the table and pushes the whole thing 1px past its
     own scroll container. */
  box-shadow: inset 1px 0 0 var(--apex-line-70);
}

.apex-table thead th.is-sticky-end {
  z-index: 3;
}

.apex-cell-id {
  font-weight: 700;
  color: var(--apex-field);
  white-space: nowrap;
}

.apex-cell-stack {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.apex-cell-main {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 600;
  color: var(--apex-ink);
}

.apex-cell-sub {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--apex-fs-small);
  color: var(--apex-muted);
}

/* ---------------------------------------------------------------------------
   13. Badges — four DESIGN.md families only, no green token
   --------------------------------------------------------------------------- */

.apex-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--apex-s2);
  max-width: 100%;
  padding: 4px 12px;
  border: 1px solid var(--apex-line);
  border-radius: var(--apex-r-pill);
  background-color: var(--apex-mist);
  color: var(--apex-muted-deep);
  font-size: var(--apex-fs-small);
  font-weight: 700;
  white-space: nowrap;
}

.apex-badge::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: var(--apex-r-pill);
  background-color: currentColor;
  flex: 0 0 auto;
}

.apex-badge--action {
  border-color: var(--apex-ember);
  background-color: var(--apex-ember-scrim);
  /* Navy text, not ember. Ember at 13px on white is about 3.4:1, which fails
     the body floor; the dot carries the ember and stays a non-essential accent. */
  color: var(--apex-field);
}

.apex-badge--action::before {
  background-color: var(--apex-ember);
}

.apex-badge--confirmed {
  border-color: var(--apex-field-soft);
  background-color: var(--apex-field);
  color: var(--apex-white);
}

.apex-badge--neutral {
  border-color: var(--apex-line);
  background-color: var(--apex-mist);
  color: var(--apex-muted-deep);
}

.apex-badge--failed {
  border-color: var(--apex-crimson);
  background-color: var(--apex-white);
  color: var(--apex-crimson);
}

.apex-badge--attention {
  border-color: var(--apex-error-border);
  background-color: var(--apex-white);
  color: var(--apex-error-text);
}

/* ---------------------------------------------------------------------------
   14. Which table render is exposed
   Decided here, in local CSS, rather than with Tailwind's responsive display
   utilities. Two reasons: it keeps every visual decision out of the CDN's hands
   (A17), and because the two renders are siblings, the hidden one must be
   display:none so it leaves the accessibility tree entirely rather than being
   read twice by a screen reader.

   ORDER IS LOAD-BEARING. The elements carry both `apex-cardlist` and
   `apex-cardlist-view`, so these rules must stay after .apex-cardlist's own
   display declaration or source order hands the win to the wrong one.
   --------------------------------------------------------------------------- */

.apex-table-view {
  display: none;
}

.apex-cardlist-view {
  display: none;
}

.apex-cardlist {
  display: flex;
  flex-direction: column;
  gap: var(--apex-s3);
  padding: var(--apex-s4);
}

@media (min-width: 768px) {
  .apex-table-view {
    display: block;
  }

  .apex-cardlist-view {
    display: none;
  }
}

@media (max-width: 767px) {
  .apex-cardlist-view {
    display: flex;
    flex-direction: column;
  }
}

.apex-cardlist__item {
  background-color: var(--apex-white);
  border: 1px solid var(--apex-line-70);
  border-radius: var(--apex-r-card);
  padding: var(--apex-s4);
}

.apex-cardlist__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--apex-s3);
  flex-wrap: wrap;
}

.apex-cardlist__dl {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
  gap: var(--apex-s2) var(--apex-s3);
  margin-top: var(--apex-s3);
}

.apex-cardlist__dl dt {
  color: var(--apex-muted);
  font-size: var(--apex-fs-label);
  font-weight: 800;
  letter-spacing: var(--apex-ls-label);
  text-transform: uppercase;
}

.apex-cardlist__dl dd {
  min-width: 0;
  overflow-wrap: anywhere;
  font-weight: 600;
}

.apex-cardlist__action {
  margin-top: var(--apex-s3);
}

/* ---------------------------------------------------------------------------
   15. Pager
   --------------------------------------------------------------------------- */

.apex-pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--apex-s3);
  padding: var(--apex-s3) var(--apex-s5);
  border-top: 1px solid var(--apex-line-70);
  background-color: var(--apex-white);
}

.apex-pager__status {
  color: var(--apex-muted-deep);
  font-size: var(--apex-fs-small);
  font-weight: 600;
  margin-inline-end: auto;
}

.apex-pager__pages {
  display: flex;
  align-items: center;
  gap: var(--apex-s1);
}

.apex-pager__page {
  display: inline-grid;
  place-items: center;
  min-width: var(--apex-tap);
  height: var(--apex-tap);
  padding: 0 var(--apex-s2);
  border: 1px solid var(--apex-line);
  border-radius: var(--apex-r-pill);
  background-color: var(--apex-white);
  color: var(--apex-field-mid);
  font-size: var(--apex-fs-small);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

.apex-pager__page:hover {
  border-color: var(--apex-ember);
  /* Text, not a fill: ember-dark is the step that clears 4.5:1. */
  color: var(--apex-ember-dark);
}

.apex-pager__page[aria-current="page"] {
  background-color: var(--apex-field);
  border-color: var(--apex-field);
  color: var(--apex-white);
}

.apex-pager__gap {
  color: var(--apex-muted);
  padding: 0 var(--apex-s1);
}

.apex-pager__size {
  display: flex;
  align-items: center;
  gap: var(--apex-s2);
  color: var(--apex-muted-deep);
  font-size: var(--apex-fs-small);
  font-weight: 600;
}

.apex-pager__size .apex-field {
  height: var(--apex-tap);
}

/* ---------------------------------------------------------------------------
   16. Empty state — an invitation to act, never an apology
   --------------------------------------------------------------------------- */

.apex-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--apex-s3);
  padding: var(--apex-s6) var(--apex-s5);
  text-align: center;
}

.apex-empty__icon {
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  border-radius: var(--apex-r-pill);
  background-color: var(--apex-mist);
  color: var(--apex-field-soft);
}

.apex-empty h3 {
  font-size: var(--apex-fs-headline);
  color: var(--apex-field);
}

.apex-empty p {
  max-width: 44ch;
  color: var(--apex-muted-deep);
}

/* ---------------------------------------------------------------------------
   17. Drawer — native <dialog>, protected focus
   --------------------------------------------------------------------------- */

.apex-drawer {
  margin: 0;
  margin-inline-start: auto;
  padding: 0;
  border: 0;
  /* display:none is load-bearing. Without it this rule outranks the UA's
     `dialog:not([open]) { display: none }` — author styles beat UA styles
     whatever the specificity — so every page would carry an invisible 480px
     panel parked past the right edge and gain a horizontal scrollbar. */
  display: none;
  width: min(480px, 100%);
  max-width: 480px;
  height: 100dvh;
  max-height: 100dvh;
  overflow: hidden;
  background-color: var(--apex-white);
  color: var(--apex-ink);
  border-radius: var(--apex-r-card) 0 0 var(--apex-r-card);
  box-shadow: var(--apex-sh-ambient);
  overscroll-behavior: contain;
  opacity: 0;
  transform: translateX(16px);
  transition: opacity 0.2s ease, transform 0.2s ease;
}

.apex-drawer[open] {
  display: flex;
  flex-direction: column;
  opacity: 1;
  transform: none;
}

@starting-style {
  .apex-drawer[open] {
    opacity: 0;
    transform: translateX(16px);
  }
}

.apex-drawer::backdrop {
  background-color: var(--apex-field-scrim);
}

.apex-drawer__head {
  display: flex;
  align-items: flex-start;
  gap: var(--apex-s3);
  padding: var(--apex-s4) var(--apex-s5);
  border-bottom: 1px solid var(--apex-line-70);
  background-color: var(--apex-white);
}

.apex-drawer__title {
  min-width: 0;
  margin-inline-end: auto;
}

.apex-drawer__title h2 {
  font-size: var(--apex-fs-headline);
  color: var(--apex-field);
}

.apex-drawer__title p {
  margin-top: 2px;
  color: var(--apex-muted);
  font-size: var(--apex-fs-small);
}

.apex-drawer__body {
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--apex-s5);
  display: flex;
  flex-direction: column;
  gap: var(--apex-s5);
}

.apex-drawer__group {
  display: flex;
  flex-direction: column;
  gap: var(--apex-s2);
}

.apex-drawer__group h3 {
  padding-bottom: var(--apex-s2);
  border-bottom: 1px solid var(--apex-line-70);
  color: var(--apex-muted);
  /* The group title is a tracked uppercase label, not a heading, whatever tag
     it carries — so it takes the functional face, unlike every other h3. */
  font-family: var(--apex-font);
  font-size: var(--apex-fs-label);
  font-weight: 800;
  letter-spacing: var(--apex-ls-label);
  text-transform: uppercase;
}

.apex-drawer__rows {
  display: flex;
  flex-direction: column;
  gap: var(--apex-s3);
}

.apex-drawer__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr);
  gap: var(--apex-s3);
  align-items: baseline;
}

.apex-drawer__row dt {
  color: var(--apex-muted-deep);
  font-size: var(--apex-fs-small);
  font-weight: 600;
}

.apex-drawer__row dd {
  min-width: 0;
  overflow-wrap: anywhere;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.apex-drawer__row dd.is-note {
  font-weight: 400;
  font-variant-numeric: normal;
  color: var(--apex-ink);
}

/* A one-line explanation of a field whose name does not carry its meaning. */
.apex-drawer__hint {
  display: block;
  margin-top: var(--apex-s1);
  color: var(--apex-muted);
  font-size: var(--apex-fs-small);
  font-weight: 400;
  font-variant-numeric: normal;
}

.apex-drawer__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--apex-s2);
  padding: var(--apex-s4) var(--apex-s5);
  border-top: 1px solid var(--apex-line-70);
  background-color: var(--apex-mist);
}

@media (max-width: 767px) {
  .apex-drawer {
    margin-inline: 0;
    margin-block-start: auto;
    width: 100%;
    max-width: 100%;
    height: auto;
    max-height: 88dvh;
    border-radius: var(--apex-r-card) var(--apex-r-card) 0 0;
    box-shadow: var(--apex-sh-sheet);
    transform: translateY(16px);
  }

  @starting-style {
    .apex-drawer[open] {
      transform: translateY(16px);
    }
  }
}

/* ---------------------------------------------------------------------------
   18. Charts
   --------------------------------------------------------------------------- */

.apex-chart {
  display: flex;
  flex-direction: column;
  gap: var(--apex-s3);
  min-width: 0;
}

.apex-chart__canvas {
  overflow-x: auto;
  overflow-y: hidden;
}

.apex-chart__canvas svg {
  display: block;
  width: 100%;
  height: auto;
}

.apex-chart__legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--apex-s2) var(--apex-s4);
  padding: 0;
  margin: 0;
  list-style: none;
}

.apex-chart__legend li {
  display: inline-flex;
  align-items: center;
  gap: var(--apex-s2);
  font-size: var(--apex-fs-small);
  font-weight: 600;
}

.apex-chart__swatch {
  width: 10px;
  height: 10px;
  /* Square: DESIGN.md's radius scale has no step this small, and the language
     elsewhere in the console is square rows and hairlines. */
  border-radius: 0;
  flex: 0 0 auto;
}

.apex-chart__legend em {
  font-style: normal;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--apex-field);
}

.apex-chart__fallback {
  border-top: 1px solid var(--apex-line-70);
  padding-top: var(--apex-s3);
}

/* A disclosure is a control, so it carries the 44px floor too. */
.apex-chart__fallback summary {
  display: flex;
  align-items: center;
  min-height: var(--apex-tap);
  cursor: pointer;
  color: var(--apex-muted-deep);
  font-size: var(--apex-fs-small);
  font-weight: 700;
}

.apex-chart__fallback table {
  width: 100%;
  margin-top: var(--apex-s3);
  border-collapse: collapse;
  font-size: var(--apex-fs-small);
}

.apex-chart__fallback th,
.apex-chart__fallback td {
  padding: var(--apex-s2);
  border-bottom: 1px solid var(--apex-line-70);
  text-align: left;
}

.apex-chart__fallback th {
  color: var(--apex-muted);
  font-size: var(--apex-fs-label);
  font-weight: 800;
  letter-spacing: var(--apex-ls-label);
  text-transform: uppercase;
}

.apex-chart__fallback td.is-num,
.apex-chart__fallback th.is-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.apex-chart svg text {
  font-family: var(--apex-font);
  font-size: 11px;
  font-weight: 600;
  fill: var(--apex-muted);
}

.apex-chart svg .apex-chart__label {
  fill: var(--apex-muted-deep);
  font-weight: 700;
}

.apex-chart svg .apex-chart__value {
  fill: var(--apex-field);
  font-weight: 800;
}

.apex-chart svg .apex-chart__dot {
  transform-box: fill-box;
  transform-origin: center;
}

/* ---------------------------------------------------------------------------
   19. Today rail
   --------------------------------------------------------------------------- */

.apex-daterail__svg {
  display: block;
  /* Below this the hour axis stops being readable, so the rail scrolls
     horizontally inside its panel rather than compressing into noise. */
  min-width: 820px;
}

.apex-daterail__hint {
  margin-top: var(--apex-s3);
  color: var(--apex-muted-deep);
  font-size: var(--apex-fs-small);
}

/* ---------------------------------------------------------------------------
   20. Status legend
   The four badge tones, named in words, sitting below the table they explain.
   A flat strip that is always open — not an accordion, because the whole point
   is that a first-time reader does not have to click anything to learn what the
   colours mean. One small block per family, allowed to wrap.
   --------------------------------------------------------------------------- */

.apex-legend {
  display: flex;
  flex-direction: column;
  gap: var(--apex-s2);
  padding: var(--apex-s3) var(--apex-s4);
  background-color: var(--apex-white);
  border: 1px solid var(--apex-line-70);
  border-radius: var(--apex-r-card);
}

.apex-legend__title {
  color: var(--apex-muted);
  font-size: var(--apex-fs-label);
  font-weight: 800;
  letter-spacing: var(--apex-ls-label);
  text-transform: uppercase;
}

/* auto-fit rather than a fixed count, so four blocks share one row on desktop
   and pair up on a phone. Unlike the KPI rail there is no background showing
   through the gaps here, so a collapsed empty track is invisible. */
.apex-legend__row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--apex-s2) var(--apex-s4);
  margin: 0;
  padding: 0;
  list-style: none;
}

.apex-legend__row li {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  min-width: 0;
}

/* 11px is the documented floor — AGENTS.md permits nothing smaller — which is
   what keeps this strip compact without breaking the system's own rule. The
   badge above it stays at its component size of 13px. */
.apex-legend__note {
  color: var(--apex-muted-deep);
  font-size: var(--apex-fs-micro);
  line-height: 1.45;
}

/* ---------------------------------------------------------------------------
   21. Misc
   --------------------------------------------------------------------------- */

.apex-note {
  color: var(--apex-muted-deep);
  font-size: var(--apex-fs-small);
}

.apex-tag {
  display: inline-block;
  padding: 2px 10px;
  border: 1px solid var(--apex-line);
  border-radius: var(--apex-r-pill);
  background-color: var(--apex-mist);
  color: var(--apex-muted-deep);
  font-size: var(--apex-fs-small);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.apex-noscript {
  margin: 0;
  padding: var(--apex-s4) var(--apex-s5);
  background-color: var(--apex-field);
  color: var(--apex-white);
  font-weight: 600;
}

.apex-noscript a {
  color: var(--apex-ember-bright);
}
