/* ============================================================
   CREWTHAT — DESIGN SYSTEM (canonical card + button + color)
   ------------------------------------------------------------
   SINGLE SOURCE OF TRUTH for the three things that were drifting:
     1. COLOR   — semantic tokens (extends design-tokens.css)
     2. CARDS   — one canonical surface
     3. BUTTONS — one button system (primary/secondary/ghost/destructive)

   WHY THIS FILE EXISTS
   Audit (2026-07-20) found 33 distinct button treatments, 28 card
   treatments and 190 unique raw hexes across 63 pages, caused by three
   competing layers: app-shell.css (4px flat) vs module/cert-prep.css
   (999px pill) vs premium-app.css (which force-overrode both with
   !important). This file resolves them onto ONE spec and ALIASES every
   legacy selector to it, so pages keep their existing markup and JS.

   CANONICAL VALUES were chosen as the *already-dominant* ones
   (premium-app.css shipped on 47/63 pages) so the visual delta is
   minimal on most of the app and the 16 stragglers are pulled into line
   rather than the whole app being re-skinned.

   LOAD ORDER — this file loads LAST, after cohesion.css, on every page.
   It therefore wins the cascade without needing !important, except where
   it must beat premium-app.css's pre-existing !important declarations.

   Depends on: theme.css (--ct-*) + design-tokens.css (--color-*, --radius-*).
   Both are guaranteed present on all 63 pages as of this pass.
   ============================================================ */

/* ------------------------------------------------------------
   1. COLOR — semantic tokens
   These alias the established brand palette (theme.css --ct-*),
   they do NOT invent a new one. Raw hexes are fallbacks only, for
   the rare page that loads this file before theme.css resolves.
   ------------------------------------------------------------ */
:root {
  /* --- surfaces (back to front) --- */
  --ct-sys-bg:         var(--ct-bg-deep,   #0d0d0d);  /* page backdrop      */
  --ct-sys-surface:    var(--ct-bg,        #111111);  /* base panel         */
  --ct-sys-card:       var(--ct-bg-card,   #1a1a1a);  /* card / raised      */
  --ct-sys-input:      var(--ct-bg-input,  #141414);  /* form fields, wells */

  /* --- text --- */
  --ct-sys-text:       var(--ct-off-white, #e8e8e8);  /* body copy          */
  --ct-sys-text-hi:    var(--ct-white,     #ffffff);  /* headings, emphasis */
  --ct-sys-text-muted: var(--ct-gray,      #a9aeb9);  /* labels, secondary  */

  /* --- lines --- */
  --ct-sys-line:       var(--ct-border,    #2a2a2a);  /* default hairline   */
  --ct-sys-line-hi:    var(--ct-border-hi, #3a3a3a);  /* hover / emphasis   */

  /* --- text (extra tier) --- */
  --ct-sys-text-faint: var(--ct-gray-dim, #9aa2b0);  /* least-important text */

  /* --- brand --- */
  --ct-sys-primary:      var(--ct-red,       #cc1f1f);   /* FILL   */
  --ct-sys-primary-hi:   var(--ct-red-hover, #e02222);
  --ct-sys-primary-text: var(--ct-red-text,  #ff6b62);   /* TEXT (AA) */
  --ct-sys-accent:       var(--gold-400,     #ffb020);

  /* --- status --- */
  --ct-sys-success: var(--ct-green, #35d07f);
  --ct-sys-warning: var(--ct-amber, #ffb02e);
  --ct-sys-danger:  #ff6b62;
  --ct-sys-info:    var(--ct-blue,  #5cb3f5);

  /* status tints — for badge/pill backgrounds. colour-mix keeps these
     derived from the token above rather than hand-picked hexes. */
  --ct-sys-success-bg: color-mix(in srgb, var(--ct-sys-success) 14%, transparent);
  --ct-sys-warning-bg: color-mix(in srgb, var(--ct-sys-warning) 14%, transparent);
  --ct-sys-danger-bg:  color-mix(in srgb, var(--ct-sys-danger)  14%, transparent);
  --ct-sys-info-bg:    color-mix(in srgb, var(--ct-sys-info)    14%, transparent);

  /* --- canonical geometry: ONE radius scale --- */
  --ct-r-xs:   8px;    /* tags, tiny controls              */
  --ct-r-sm:  10px;    /* inputs, selects, small buttons    */
  --ct-r-md:  14px;    /* inner panels, list rows, thumbs   */
  --ct-r-lg:  18px;    /* cards — the canonical surface     */
  --ct-r-xl:  24px;    /* modals, hero, sheets              */
  --ct-r-full: 999px;  /* buttons, pills, badges            */

  --ct-sys-card-radius:    var(--ct-r-lg);
  --ct-sys-card-pad:       20px;
  --ct-sys-btn-radius:     var(--ct-r-full);

  /* --- elevation + soft glow (the "lit rack panel" depth) --- */
  --ct-e1: 0 1px 0 rgba(255,255,255,0.055) inset, 0 2px 6px -2px rgba(0,0,0,0.55);
  --ct-e2: 0 1px 0 rgba(255,255,255,0.06)  inset, 0 12px 30px -14px rgba(0,0,0,0.75);
  --ct-e3: 0 1px 0 rgba(255,255,255,0.07)  inset, 0 30px 70px -22px rgba(0,0,0,0.85);
  --ct-glow-primary: 0 0 0 1px rgba(224,42,36,0.32),
                     0 10px 30px -12px rgba(204,31,31,0.55),
                     0 0 26px -8px rgba(204,31,31,0.40);
  --ct-glow-accent:  0 0 0 1px rgba(255,176,32,0.30),
                     0 10px 30px -12px rgba(255,176,32,0.40);
  --ct-sys-focus-ring: 0 0 0 3px rgba(204,31,31,0.42), 0 0 0 1px var(--ct-sys-primary-hi);

  /* --- signature: the "power rail" hairline (red → gold) --- */
  --ct-rail: linear-gradient(90deg,
              var(--ct-sys-primary) 0%,
              var(--ct-sys-primary-hi) 38%,
              var(--ct-sys-accent) 100%);
}

/* Light theme: the tokens above resolve through theme.css's [data-theme="light"]
   block automatically. Only the two values theme.css has no equivalent for
   need restating. */
html[data-theme="light"] {
  --ct-sys-danger: #c62828;
  --ct-sys-focus-ring: 0 0 0 3px rgba(204,31,31,0.28), 0 0 0 1px var(--ct-sys-primary);
  --ct-e1: 0 1px 2px rgba(16,18,22,0.06),  0 1px 3px -1px rgba(16,18,22,0.10);
  --ct-e2: 0 2px 4px rgba(16,18,22,0.06),  0 12px 26px -14px rgba(16,18,22,0.28);
  --ct-e3: 0 4px 8px rgba(16,18,22,0.07),  0 28px 60px -24px rgba(16,18,22,0.34);
  --ct-glow-primary: 0 0 0 1px rgba(204,31,31,0.24), 0 10px 26px -14px rgba(204,31,31,0.45);
  --sheen: linear-gradient(180deg, rgba(255,255,255,0.9), rgba(255,255,255,0) 58%);
}

/* --- PALETTE CONVERGENCE ---------------------------------------------
   The app ran TWO near-identical dark palettes side by side:
     theme.css     #0d0d0d / #111111 / #1a1a1a / #2a2a2a / #e8e8e8
     app-shell.css #0a0b0d / #121418 / #1a1d22 / #2a2e36 / #e8eaed
   They differ by a few RGB points — imperceptible on screen, but it meant
   two sources of truth and two sets of raw hexes to maintain. Here the
   app-shell.css variables are re-pointed at the system tokens so the 25
   pages loading app-shell converge onto the same palette as everything
   else. Markup and JS are untouched; only what the var() resolves to
   changes. Light theme is handled in the block below.            */
:root {
  --bg:        var(--ct-sys-bg);
  --bg-2:      var(--ct-sys-surface);
  --bg-3:      var(--ct-sys-card);
  --bg-4:      var(--ct-sys-line);
  --line:      var(--ct-sys-line);
  --line-2:    var(--ct-sys-line-hi);
  --ink:       var(--ct-sys-text);
  --ink-dim:   #c6cbd3;                    /* kept: WCAG-AA contrast fix (61904d6) */
  --ink-faint: var(--ct-sys-text-muted);
  --accent:    var(--ct-sys-primary);
  --accent-2:  var(--ct-sys-accent);
  --danger:    var(--ct-sys-danger);
}

html[data-theme="light"] {
  --bg:        var(--ct-bg,        #f5f5f5);
  --bg-2:      var(--ct-bg-card,   #ffffff);
  --bg-3:      var(--ct-bg-deep,   #ececec);
  --bg-4:      var(--ct-border,    #d8d8d8);
  --line:      var(--ct-border,    #d8d8d8);
  --line-2:    var(--ct-border-hi, #bdbdbd);
  --ink:       var(--ct-off-white, #1a1a1a);
  --ink-dim:   #4a4f59;
  --ink-faint: var(--ct-gray,      #5a5a5a);
  --accent:    var(--ct-sys-primary);
  --accent-2:  var(--ct-amber,     #c47600);
  --danger:    var(--ct-sys-danger);
}

/* Fallback for browsers without color-mix() (Safari < 16.2). */
@supports not (color: color-mix(in srgb, red 50%, transparent)) {
  :root {
    --ct-sys-success-bg: rgba(46,204,113,0.14);
    --ct-sys-warning-bg: rgba(243,156,18,0.14);
    --ct-sys-danger-bg:  rgba(255,85,85,0.14);
    --ct-sys-info-bg:    rgba(58,158,232,0.14);
  }
}


/* ------------------------------------------------------------
   2. CARDS — one canonical surface
   ------------------------------------------------------------
   Applies to the canonical .ct-card plus every legacy card selector
   found in the audit. !important is required only to beat
   premium-app.css L163/L245, which already ships !important.
   ------------------------------------------------------------ */
.ct-card,
.card,
.panel,
.tile,
.surface,
.stat-card,
.data-card,
.stat-tile,
.crew-card,
.job-card,
.jp-card,
.tl-card,
.cl-card,
.ia-section,
.pl-card,
.fv-rcard,
.detail-panel,
.settings-section,
.integration-card,
.pt-tile {
  background: var(--ct-sys-card);
  border: 1px solid var(--ct-sys-line);
  border-radius: var(--ct-sys-card-radius) !important;
  box-shadow: var(--ct-e2);
  color: var(--ct-sys-text);
}

/* The "lit from above" sheen that premium-app introduced, kept as the
   canonical card finish so all 63 pages match the 47 that had it. */
.ct-card,
.card,
.panel,
.tile,
.surface,
.stat-card,
.data-card,
.stat-tile,
.crew-card,
.job-card,
.jp-card,
.tl-card,
.ia-section,
.pl-card,
.fv-rcard,
.detail-panel,
.settings-section,
.pt-tile {
  background-image: var(--sheen, linear-gradient(180deg, rgba(255,255,255,0.035), transparent 42%));
}

/* Padding is applied only to cards that are a single content box.
   Cards with their own header/body children (.panel, .jp-card, .tl-card,
   .ia-section, .detail-panel) keep padding:0 so their internal layout
   is untouched — this pass must not move content. */
.ct-card,
.card,
.tile,
.stat-card,
.data-card,
.stat-tile,
.crew-card,
.fv-rcard,
.pt-tile {
  padding: var(--ct-sys-card-pad);
}

/* Canonical header / body structure. Legacy .panel-header/.panel-body
   markup maps straight onto it. */
.ct-card__header,
.panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3, 0.75rem);
  padding: 14px var(--ct-sys-card-pad);
  border-bottom: 1px solid var(--ct-sys-line);
  color: var(--ct-sys-text-hi);
  font-weight: 600;
}
.ct-card__body,
.panel-body { padding: var(--ct-sys-card-pad); }

/* Interactive cards lift; static ones don't. */
.ct-card--interactive:hover,
a.card:hover,
.job-card:hover,
.crew-card:hover {
  border-color: color-mix(in srgb, var(--ct-sys-primary) 40%, var(--ct-sys-line-hi));
  box-shadow: var(--ct-e3), 0 0 30px -14px rgba(204,31,31,0.45);
  transform: translateY(-2px);
}

/* Modal cards: the identical 3-layer red glow was copy-pasted into
   cable-labels / job-pulls / truck-load. Unified here. */
.ct-card--modal,
.cl-modal-card,
.jp-modal-card,
.tl-modal-card,
.modal-card {
  background: var(--ct-sys-card);
  border: 1px solid color-mix(in srgb, var(--ct-sys-primary) 55%, var(--ct-sys-line));
  border-radius: var(--ct-r-xl) !important;
  box-shadow: var(--ct-e3), var(--ct-glow-primary);
  background-image: var(--sheen);
}

/* Auth cards: login/invite/join were authored identically, then
   premium-app overrode only .login-card. Re-unified. */
.login-card,
.invite-card,
.join-card {
  background: var(--glass-bg-strong, var(--ct-sys-card)) !important;
  border: 1px solid var(--ct-sys-line) !important;
  border-radius: var(--ct-r-xl) !important;
  box-shadow: var(--ct-e3), 0 0 60px -24px rgba(204,31,31,0.55) !important;
}

/* Card radius must NOT change at the 720px breakpoint. premium-app.css
   L245 drops it to 14px; this holds the canonical value. */
@media (max-width: 720px) {
  .ct-card, .card, .panel, .tile, .surface, .stat-card, .data-card,
  .stat-tile, .crew-card, .job-card, .jp-card, .tl-card, .ia-section,
  .pl-card, .fv-rcard, .detail-panel, .settings-section, .pt-tile {
    border-radius: var(--ct-sys-card-radius) !important;
  }
  /* Tighter padding on small screens — content density, not shape. */
  .ct-card, .card, .tile, .stat-card, .data-card, .stat-tile,
  .crew-card, .fv-rcard, .pt-tile { padding: 14px; }
  .ct-card__header, .panel-header, .ct-card__body, .panel-body { padding: 12px 14px; }
}


/* ------------------------------------------------------------
   3. BUTTONS — one system
   ------------------------------------------------------------
   Base + 4 variants + 3 sizes + full state coverage.
   Every legacy button selector from the audit is aliased onto the base.
   ------------------------------------------------------------ */

/* --- 3a. base --- */
.ct-btn,
.btn,
.c-btn,
.pub-btn,
.btn-s,
.u-btn,
.cl-btn,
.ia-btn,
.tl-btn,
.ts-btn,
.fv-abtn,
.probbtn,
.submit-btn,
.pl-appbtn,
.cat-cta,
.led-chip {
  /* shape */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  box-sizing: border-box;
  min-height: 40px;
  padding: 0 16px;
  border: 1px solid var(--ct-sys-line-hi);
  border-radius: var(--ct-sys-btn-radius) !important;

  /* type */
  font-family: var(--font-ui, Inter, system-ui, sans-serif);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;

  /* colour — secondary is the default variant */
  background: var(--ct-sys-input);
  color: var(--ct-sys-text);

  cursor: pointer;
  transition: background var(--dur-fast, 120ms) var(--ease-out, ease),
              border-color var(--dur-fast, 120ms) var(--ease-out, ease),
              transform var(--dur-fast, 120ms) var(--ease-out, ease),
              box-shadow var(--dur-fast, 120ms) var(--ease-out, ease);
}

/* --- 3b. states (shared by all variants) --- */
.ct-btn:hover, .btn:hover, .c-btn:hover, .pub-btn:hover, .btn-s:hover,
.u-btn:hover, .cl-btn:hover, .ia-btn:hover, .tl-btn:hover, .ts-btn:hover,
.fv-abtn:hover, .probbtn:hover, .submit-btn:hover, .cat-cta:hover {
  border-color: var(--ct-sys-primary);
  color: var(--ct-sys-text-hi);
}

.ct-btn:active, .btn:active, .c-btn:active, .pub-btn:active, .btn-s:active,
.u-btn:active, .cl-btn:active, .ia-btn:active, .tl-btn:active, .ts-btn:active,
.fv-abtn:active, .probbtn:active, .submit-btn:active {
  transform: translateY(1px);
}

/* Accessible focus ring (WCAG 2.4.7) — keyboard only. */
.ct-btn:focus-visible, .btn:focus-visible, .c-btn:focus-visible,
.pub-btn:focus-visible, .btn-s:focus-visible, .u-btn:focus-visible,
.cl-btn:focus-visible, .ia-btn:focus-visible, .tl-btn:focus-visible,
.ts-btn:focus-visible, .fv-abtn:focus-visible, .probbtn:focus-visible,
.submit-btn:focus-visible, button:focus-visible {
  outline: none;
  box-shadow: var(--ct-sys-focus-ring);
}

.ct-btn:disabled, .btn:disabled, .c-btn:disabled, .pub-btn:disabled,
.btn-s:disabled, .u-btn:disabled, .cl-btn:disabled, .ia-btn:disabled,
.tl-btn:disabled, .ts-btn:disabled, .submit-btn:disabled,
.ct-btn[aria-disabled="true"], .btn[aria-disabled="true"],
.ct-btn.is-disabled, .btn.is-disabled {
  opacity: 0.45;
  cursor: not-allowed;
  transform: none;
  pointer-events: none;
}

/* --- 3c. variant: PRIMARY --- */
.ct-btn--primary,
.btn.primary, .btn-primary, .btn.btn-primary,
.c-btn--primary, .pub-btn.primary,
button.primary, .submit-btn, .fv-timerbtn {
  background: var(--grad-primary, var(--ct-sys-primary)) !important;
  border-color: color-mix(in srgb, #fff 22%, var(--ct-sys-primary)) !important;
  color: #fff !important;
  box-shadow: var(--ct-glow-primary);
  text-shadow: 0 1px 0 rgba(0,0,0,0.28);
}
.ct-btn--primary:hover,
.btn.primary:hover, .btn-primary:hover, .c-btn--primary:hover,
.pub-btn.primary:hover, button.primary:hover, .submit-btn:hover {
  border-color: color-mix(in srgb, #fff 34%, var(--ct-sys-primary)) !important;
  box-shadow: 0 0 0 1px rgba(224,42,36,0.45),
              0 14px 34px -12px rgba(204,31,31,0.72),
              0 0 34px -8px rgba(204,31,31,0.55);
  color: #fff !important;
  transform: translateY(-1px);
}

/* --- 3d. variant: SECONDARY (the base look, named for clarity) --- */
.ct-btn--secondary,
.btn.secondary, .c-btn--secondary, button.secondary {
  background: var(--ct-sys-input);
  border-color: var(--ct-sys-line-hi);
  color: var(--ct-sys-text);
}

/* --- 3e. variant: GHOST --- */
.ct-btn--ghost,
.btn.ghost, .btn.btn-ghost, .c-btn--ghost, .pub-btn.ghost {
  background: rgba(255,255,255,0.02) !important;
  border-color: var(--glass-border-hi, var(--ct-sys-line)) !important;
  color: var(--ct-sys-text-muted);
}
.ct-btn--ghost:hover,
.btn.ghost:hover, .c-btn--ghost:hover, .pub-btn.ghost:hover {
  background: rgba(255,255,255,0.06) !important;
  color: var(--ct-sys-text-hi);
}

/* --- 3f. variant: DESTRUCTIVE --- */
.ct-btn--destructive,
.btn.danger, .c-btn--danger, button.danger, .btn.destructive {
  background: transparent !important;
  border-color: var(--ct-sys-danger) !important;
  color: var(--ct-sys-danger) !important;
  box-shadow: none;
}
.ct-btn--destructive:hover,
.btn.danger:hover, .c-btn--danger:hover, button.danger:hover {
  background: var(--ct-sys-danger-bg) !important;
  color: var(--ct-sys-danger) !important;
}

/* --- 3g. sizes --- */
.ct-btn--sm, .btn.sm, .c-btn--sm, .btn-s, .ts-btn, button.sm {
  min-height: 32px;
  padding: 0 11px;
  font-size: 11px;
}
.ct-btn--lg, .btn.lg, .c-btn--lg, .pub-btn.block, .big-action-btn {
  min-height: 48px;
  padding: 0 24px;
  font-size: 14px;
}
.big-action-btn { min-height: 64px; font-size: 18px; }

/* Full-width helper (replaces the ad-hoc width:100% seen on auth forms). */
.ct-btn--block, .pub-btn.block, .submit-btn { width: 100%; }

/* --- 3h. touch targets --- */
@media (max-width: 720px) {
  .ct-btn, .btn, .c-btn, .pub-btn, .u-btn, .cl-btn, .ia-btn, .tl-btn,
  .fv-abtn, .submit-btn, .icon-btn { min-height: 44px; }
  .ct-btn--sm, .btn.sm, .btn-s, .ts-btn, button.sm { min-height: 36px; }
}

/* --- 3i. bare <button> elements ---
   50 pages style bare `button {}` five mutually-incompatible ways. This
   normalises the un-classed ones while EXCLUDING every element that owns
   a deliberate non-button shape (tabs, segmented controls, icon buttons,
   the Jarvis notched sci-fi chrome, and close affordances). */
button:not([class]),
button.add-btn {
  min-height: 40px;
  padding: 0 14px;
  border: 1px solid var(--ct-sys-line-hi);
  border-radius: var(--ct-sys-btn-radius);
  background: var(--ct-sys-input);
  color: var(--ct-sys-text);
  font-family: var(--font-ui, Inter, system-ui, sans-serif);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}
button:not([class]):hover { border-color: var(--ct-sys-primary); color: var(--ct-sys-text-hi); }


/* ------------------------------------------------------------
   4. OPT-OUTS — surfaces that must keep their own identity
   ------------------------------------------------------------
   These are deliberate designs, not drift. Excluded from the
   normalisation above so this pass doesn't flatten them.
     • .jv-* / .mem-*  — Jarvis notched sci-fi chrome (clip-path)
     • .bottom-tab / .tab / .jd-tabs / .fv-seg — tab & segmented controls
     • .icon-btn — square icon affordances
     • @media print — report pages must stay ink-efficient
   ------------------------------------------------------------ */
.jv-btn, .jv-index-btn, .mem-btn,
.bottom-tab, .tab,
.jd-tabs button, .fv-seg button, .fv-box-btn,
.view-toggle button, .mode-toggle button,
.tl-tabs button, .jp-tabs button,
.icon-btn, .modal-close {
  border-radius: revert !important;
}

/* Print: strip decoration so reports stay legible and ink-cheap. */
@media print {
  .ct-card, .card, .panel, .tile, .stat-tile, .pl-card, .pt-tile {
    box-shadow: none !important;
    background-image: none !important;
    border-radius: 6px !important;
  }
  .ct-btn, .btn, .c-btn, .pub-btn, .toolbar { display: none !important; }
}

/* Respect reduced-motion. */
@media (prefers-reduced-motion: reduce) {
  .ct-btn, .btn, .c-btn, .pub-btn, .ct-card, .card, .panel, .tile {
    transition: none !important;
  }
  .ct-card--interactive:hover, a.card:hover, .job-card:hover, .crew-card:hover {
    transform: none;
  }
}


/* ------------------------------------------------------------
   5. STATUS BADGES / PILLS — consistent status colour usage
   ------------------------------------------------------------ */
.ct-badge, .badge, .pill, .chip, .status-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 10px;
  border-radius: var(--radius-full, 999px);
  border: 1px solid var(--ct-sys-line);
  background: var(--ct-sys-input);
  color: var(--ct-sys-text-muted);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  white-space: nowrap;
}
.ct-badge--success, .badge.success, .pill.success, .status-pill.active,
.status-pill.completed, .status-pill.paid {
  background: var(--ct-sys-success-bg); border-color: var(--ct-sys-success); color: var(--ct-sys-success);
}
.ct-badge--warning, .badge.warning, .pill.warning, .status-pill.pending,
.status-pill.draft {
  background: var(--ct-sys-warning-bg); border-color: var(--ct-sys-warning); color: var(--ct-sys-warning);
}
.ct-badge--danger, .badge.danger, .pill.danger, .status-pill.overdue,
.status-pill.failed, .status-pill.expired {
  background: var(--ct-sys-danger-bg); border-color: var(--ct-sys-danger); color: var(--ct-sys-danger);
}
.ct-badge--info, .badge.info, .pill.info, .status-pill.sent {
  background: var(--ct-sys-info-bg); border-color: var(--ct-sys-info); color: var(--ct-sys-info);
}


/* ════════════════════════════════════════════════════════════
   PART TWO — THE REFINE PASS (2026-08-02)
   ------------------------------------------------------------
   Part One (above) stopped the drift: one card, one button, one
   palette. It did not set a POINT OF VIEW. This part does.

   DIRECTION — "rack panel".
   CrewThat is used by an AVL crew standing in a courtroom or a
   sanctuary with a label printer in one hand. The things in that
   world — a QSC amp, an anvil road case, a patch panel — share a
   grammar: a dark machined chassis, crisply silk-screened caps
   labels, status LEDs that mean exactly one thing, and light that
   rakes across the top edge. Every rule below comes from that.

     • Surfaces are TIERED like a rack: chassis → panel → module.
       (Before this pass the three "tiers" were #0d/#11/#1a — three
       shades of black nobody could tell apart.)
     • Labels are silk-screen: mono, caps, wide-tracked — and only
       ever labels. Sentences get the UI face at a readable size.
     • Status colours are LEDs. Each glows faintly and means one
       thing. No decorative colour anywhere else.
     • The signature is the POWER RAIL: a 2px red→gold hairline on
       the top edge of whatever is currently live. It is the only
       ornament in the system, so it stays rare.

   SAFETY — this is presentation only. It changes colour, type,
   radius, shadow and padding on selectors that already existed.
   It adds no layout primitives, moves no content between parents,
   and touches no id/hook/handler/data-attribute.
   ════════════════════════════════════════════════════════════ */


/* ------------------------------------------------------------
   6. TYPOGRAPHY — hierarchy, not just "bold"
   ------------------------------------------------------------
   theme.css floors body weight at 600. That made everything the
   same weight, which is the same as having no hierarchy at all.
   The fix is not to un-bold the body — the owner wants heavy,
   readable type — it is to give the tiers ABOVE body somewhere
   to go: bigger, tighter, and in the display face.
   ------------------------------------------------------------ */
:root {
  --ct-font-ui:      var(--font-ui, Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif);
  --ct-font-display: var(--font-display, 'Bebas Neue', 'Arial Black', sans-serif);
  --ct-font-mono:    var(--font-mono, 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace);
}

body {
  font-family: var(--ct-font-ui);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  /* Inter's contextual alternates + a disambiguated 1/l/I. Small change,
     but it is what stops Inter reading as the browser default. */
  font-feature-settings: 'cv05' 1, 'cv11' 1, 'ss01' 1;
  letter-spacing: -0.005em;
}

/* Numbers align in columns everywhere they are tabulated. An AVL crew
   reads these as quantities (runs, hours, dollars), not as prose. */
table, .stat-card, .stat-tile, .data-card, .pt-tile,
.ct-stat, .ct-stat__value, .metric, .kpi, td, th,
[class*="-num"], [class*="-count"], [class*="-total"] {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

/* --- display tier: Bebas Neue.
   Bebas has no lowercase and collapses below ~18px, so it is fenced
   to the sizes it actually works at. --- */
h1, h2, h3,
.ct-h1, .ct-h2, .ct-h3,
.page-title, .hero-title, .section-title, .card-title {
  font-family: var(--ct-font-display);
  font-weight: 400;               /* Bebas ships one weight */
  letter-spacing: 0.015em;
  line-height: 1.02;
  color: var(--ct-sys-text-hi);
  text-wrap: balance;
}
h1, .ct-h1, .hero-title { font-size: clamp(30px, 3.4vw, 44px); }
h2, .ct-h2              { font-size: clamp(24px, 2.4vw, 30px); }
h3, .ct-h3              { font-size: clamp(19px, 1.7vw, 22px); }

/* --- sub-display tier: below 18px Bebas stops being legible, so h4–h6
   step back to the UI face at real weight. --- */
h4, h5, h6, .ct-h4 {
  font-family: var(--ct-font-ui);
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.25;
  color: var(--ct-sys-text-hi);
}
h4, .ct-h4 { font-size: 17px; }
h5         { font-size: 15px; }
h6         { font-size: 13px; }

/* --- body copy: the tier that was actually failing.
   Sentences need length limits and air, not more weight. --- */
p, .ct-body, .card p, .panel p, .ct-card p {
  line-height: 1.62;
  color: var(--ct-sys-text);
}
/* Long-form explanatory copy gets a measure. Applies only to paragraphs
   that are a direct child of a content surface, so it can never squeeze
   a table cell or a flex row. */
.ct-card > p, .card > p, .panel-body > p, .ct-card__body > p,
.ct-prose p, .intro p { max-width: 68ch; }

/* --- silk-screen label tier: THE house voice.
   Mono, caps, wide track. Legible because it is short by definition. --- */
.ct-label, .eyebrow, .kicker, .field-label,
legend, th, caption,
.stat-card > .label, .stat-tile > .label,
[class$="-label"], [class$="-eyebrow"], [class$="-kicker"] {
  font-family: var(--ct-font-mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ct-sys-text-muted);
  line-height: 1.4;
}
/* A bare <label> is left at its own size — half the app uses it as a caption
   and half uses it as a sentence beside a checkbox, and shrinking the second
   kind to 11px caps would be a readability regression, not a fix. It gets the
   colour and weight of the tier and nothing that can reflow a row. */
label:not([class]) {
  font-weight: 700;
  color: var(--ct-sys-text-muted);
}
/* Scoped to UNCLASSED labels only: a page that named its checkbox row
   (.cl-cat on the cable-label filters, for one) has already decided how it
   should read, and :has() would otherwise out-specify that decision. */
label:not([class]):has(> input[type="checkbox"]),
label:not([class]):has(> input[type="radio"]),
label.ct-inline, label.inline, .checkbox-label, .radio-label {
  font-family: var(--ct-font-ui);
  font-weight: 600;
  letter-spacing: normal;
  text-transform: none;
  color: var(--ct-sys-text);
}

/* --- muted / faint tiers: raised to clear AA. --- */
.muted, .dim, .subtle, .hint, .help, .meta, .secondary-text,
small, .small { color: var(--ct-sys-text-muted); }
.faint, .very-dim, .tertiary-text { color: var(--ct-sys-text-faint); }

/* Red text anywhere resolves to the AA-safe red, never the fill red. */
.text-danger, .text-red, .error, .err, .danger-text,
a.danger, .required { color: var(--ct-sys-primary-text); }

/* Links: one treatment — but scoped to links that live inside COPY.
   Colouring every <a> would recolour cards, rows, nav items and buttons
   that happen to be anchors, so the rule only fires in text contexts. */
a { text-underline-offset: 0.18em; }
p a, li a, td a, dd a,
.ct-prose a, .hint a, .help a, .muted a, .empty a, .empty-state a,
.ct-card__body > a, .panel-body > a, .intro a, .note a, .desc a {
  color: var(--ct-sys-primary-text);
}
p a:hover, li a:hover, td a:hover, .ct-prose a:hover, .hint a:hover,
.muted a:hover, .empty a:hover, .intro a:hover { color: var(--ct-sys-accent); }
a:focus-visible { outline: none; box-shadow: var(--ct-sys-focus-ring); border-radius: 6px; }


/* ------------------------------------------------------------
   7. SURFACES — real tier separation + the power rail
   ------------------------------------------------------------ */
.ct-card, .card, .panel, .tile, .surface, .stat-card, .data-card,
.stat-tile, .crew-card, .job-card, .jp-card, .tl-card, .cl-card,
.ia-section, .pl-card, .fv-rcard, .detail-panel, .settings-section,
.integration-card, .pt-tile {
  position: relative;
  /* the hairline that makes an edge read as machined rather than drawn */
  outline: 1px solid rgba(255,255,255,0.028);
  outline-offset: -1px;
}
html[data-theme="light"] .ct-card, html[data-theme="light"] .card,
html[data-theme="light"] .panel, html[data-theme="light"] .tile,
html[data-theme="light"] .stat-card, html[data-theme="light"] .stat-tile {
  outline-color: rgba(16,18,22,0.05);
}

/* THE SIGNATURE — power rail. A 2px red→gold hairline pinned to the top
   edge of whatever is currently live. Opt-in via .ct-live / [data-live],
   plus the two places that are always "the live thing" on their screen.  */
.ct-live::before,
[data-live="true"]::before,
.ct-card--primary::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 2px;
  border-radius: var(--ct-sys-card-radius) var(--ct-sys-card-radius) 0 0;
  background: var(--ct-rail);
  opacity: 0.95;
  pointer-events: none;
}

/* Stat surfaces: the number is the content, so it gets the display face
   at size and everything else gets out of its way. */
.stat-card, .stat-tile, .data-card, .pt-tile { display: flex; flex-direction: column; gap: 6px; }
.stat-card .value, .stat-tile .value, .data-card .value,
.stat-card .stat-value, .stat-tile .stat-value, .ct-stat__value,
[class$="-value"], [class$="-num"], [class$="-metric"] {
  font-family: var(--ct-font-display);
  font-size: clamp(28px, 3vw, 38px);
  line-height: 1;
  color: var(--ct-sys-text-hi);
  letter-spacing: 0.01em;
}
/* The trailing unit / denominator rides small next to the number. */
.stat-tile .unit, .stat-card .unit, [class$="-value"] .unit,
[class$="-value"] small {
  font-family: var(--ct-font-mono);
  font-size: 0.42em;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--ct-sys-text-muted);
  vertical-align: baseline;
}
[class$="-trend"], .stat-tile-trend, .stat-card-trend {
  font-family: var(--ct-font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--ct-sys-text-muted);
}


/* ------------------------------------------------------------
   8. INPUTS — one field system
   ------------------------------------------------------------
   Before: fields were #141414 wells on #1a1a1a cards — a 1.1:1
   difference, so there was no visible affordance at all. They now
   sit BELOW the card with a real border, and light up on focus.
   ------------------------------------------------------------ */
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]):not([type="submit"]):not([type="button"]),
textarea,
select {
  box-sizing: border-box;
  background: var(--ct-sys-input);
  color: var(--ct-sys-text-hi);
  border: 1px solid var(--ct-sys-line-hi);
  border-radius: var(--ct-r-sm);
  box-shadow: inset 0 1px 2px rgba(0,0,0,0.35);
  transition: border-color var(--dur-fast, 120ms) var(--ease-out, ease),
              box-shadow var(--dur-fast, 120ms) var(--ease-out, ease),
              background var(--dur-fast, 120ms) var(--ease-out, ease);
}
/* METRICS are held back from any field that carries its own inline style.
   The React surfaces (punchlist, plans, field) size compact 38px-wide
   numeric inputs inline; forcing a 42px system field on those would
   reflow their rows. Inline-styled fields keep their metrics and take
   only the colour/border/focus treatment above. */
input:not([style]):not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]):not([type="submit"]):not([type="button"]),
textarea:not([style]),
select:not([style]) {
  min-height: 42px;
  padding: 10px 13px;
  font-family: var(--ct-font-ui);
  font-size: 14px;
  line-height: 1.4;
}
textarea:not([style]) { min-height: 96px; padding: 12px 13px; }
textarea { resize: vertical; }
select:not([style]) { padding-right: 34px; }
select { cursor: pointer; }

input::placeholder, textarea::placeholder {
  color: var(--ct-sys-text-faint);
  opacity: 1;                       /* Firefox dims placeholders by default */
}

input:hover:not(:disabled), textarea:hover:not(:disabled), select:hover:not(:disabled) {
  border-color: color-mix(in srgb, var(--ct-sys-primary) 30%, var(--ct-sys-line-hi));
}
input:focus, textarea:focus, select:focus,
input:focus-visible, textarea:focus-visible, select:focus-visible {
  outline: none;
  border-color: var(--ct-sys-primary);
  background: var(--ct-sys-card);
  box-shadow: var(--ct-sys-focus-ring);
}
input:disabled, textarea:disabled, select:disabled {
  opacity: 0.5; cursor: not-allowed;
}
input[aria-invalid="true"], .input-error, .is-invalid {
  border-color: var(--ct-sys-danger);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ct-sys-danger) 22%, transparent);
}

/* Checkboxes / radios — brand-tinted, 18px, real hit area. */
input[type="checkbox"], input[type="radio"] {
  appearance: none; -webkit-appearance: none;
  width: 18px; height: 18px; flex: none;
  margin: 0;
  /* Native checkboxes ignore padding; a custom one does not. Several pages
     set a blanket `input { padding: 9px }`, which under border-box floors the
     box at padding+border and inflated the control to 24×20. */
  padding: 0 !important;
  min-height: 0;
  background: var(--ct-sys-input);
  border: 1.5px solid var(--ct-sys-line-hi);
  border-radius: 5px;
  cursor: pointer;
  display: inline-grid; place-content: center;
  transition: background var(--dur-fast, 120ms), border-color var(--dur-fast, 120ms);
}
input[type="radio"] { border-radius: 50%; }
input[type="checkbox"]::after {
  content: ''; width: 10px; height: 10px;
  transform: scale(0); transform-origin: center;
  transition: transform var(--dur-fast, 120ms) var(--ease-spring, ease);
  background: #fff;
  clip-path: polygon(14% 44%, 0 60%, 39% 100%, 100% 22%, 84% 6%, 39% 68%);
}
input[type="radio"]::after {
  content: ''; width: 8px; height: 8px; border-radius: 50%;
  transform: scale(0); transition: transform var(--dur-fast, 120ms) var(--ease-spring, ease);
  background: #fff;
}
input[type="checkbox"]:checked, input[type="radio"]:checked {
  background: var(--ct-sys-primary);
  border-color: var(--ct-sys-primary);
  box-shadow: 0 0 12px -3px rgba(204,31,31,0.6);
}
input[type="checkbox"]:checked::after, input[type="radio"]:checked::after { transform: scale(1); }
input[type="checkbox"]:focus-visible, input[type="radio"]:focus-visible {
  outline: none; box-shadow: var(--ct-sys-focus-ring);
}

/* Native date/time pickers keep their affordance on dark. */
input[type="date"], input[type="time"], input[type="datetime-local"], input[type="month"] {
  color-scheme: dark;
}
html[data-theme="light"] input[type="date"], html[data-theme="light"] input[type="time"],
html[data-theme="light"] input[type="datetime-local"], html[data-theme="light"] input[type="month"] {
  color-scheme: light;
}

/* Search fields read as search. */
input[type="search"], input[placeholder*="Search"], input[placeholder*="search"] {
  border-radius: var(--ct-r-full);
  padding-left: 15px;
}

@media (max-width: 720px) {
  /* 16px minimum stops iOS Safari zooming the viewport on focus. */
  input:not([style]):not([type="checkbox"]):not([type="radio"]),
  textarea:not([style]), select:not([style]) {
    font-size: 16px;
    min-height: 46px;
  }
}


/* ------------------------------------------------------------
   9. TABLES — one data-grid treatment
   ------------------------------------------------------------ */
table { border-collapse: separate; border-spacing: 0; width: 100%; }
thead th, table th {
  position: relative;
  padding: 11px 14px;
  text-align: left;
  background: var(--ct-sys-input);
  color: var(--ct-sys-text-muted);
  border-bottom: 1px solid var(--ct-sys-line-hi);
  white-space: nowrap;
}
tbody td, table td {
  padding: 12px 14px;
  border-bottom: 1px solid var(--ct-sys-line);
  color: var(--ct-sys-text);
  vertical-align: middle;
}
tbody tr:last-child td { border-bottom: none; }
tbody tr { transition: background var(--dur-fast, 120ms) var(--ease-out, ease); }
tbody tr:hover td { background: rgba(255,255,255,0.028); }
html[data-theme="light"] tbody tr:hover td { background: rgba(16,18,22,0.035); }
tbody tr[data-href], tbody tr.clickable, tbody tr.row-link { cursor: pointer; }

/* Round the outer corners of a table that owns its own surface. */
.ct-card > table, .card > table, .panel-body > table, .ct-card__body > table,
.table-wrap > table, .wrapx > table, .scroll-x > table {
  border-radius: var(--ct-r-md);
  overflow: hidden;
}

/* Wide tables scroll inside their own well rather than pushing the page. */
.table-wrap, .wrapx, .scroll-x, [data-scroll-x="true"] {
  border-radius: var(--ct-r-md);
  -webkit-overflow-scrolling: touch;
}


/* ------------------------------------------------------------
   10. TABS & SEGMENTED CONTROLS — one set, four ex-variants
   ------------------------------------------------------------
   The app shipped three different active-tab looks (red fill /
   white fill / red underline) on jobs, crew and punchlist. One
   look now: a recessed track, an inset raised thumb, red rail.
   ------------------------------------------------------------ */
.ct-seg, .view-toggle, .mode-toggle, .fv-seg, .jd-tabs, .tl-tabs, .jp-tabs {
  display: inline-flex;
  gap: 3px;
  padding: 3px;
  background: var(--ct-sys-input);
  border: 1px solid var(--ct-sys-line);
  border-radius: var(--ct-r-full);
  box-shadow: inset 0 1px 3px rgba(0,0,0,0.4);
}
.ct-seg > button, .view-toggle > button, .mode-toggle > button,
.fv-seg > button, .jd-tabs > button, .tl-tabs > button, .jp-tabs > button,
.ct-seg > a, .view-toggle > a, .mode-toggle > a {
  border: none;
  background: transparent;
  border-radius: var(--ct-r-full) !important;
  min-height: 32px;
  padding: 0 15px;
  font-family: var(--ct-font-ui);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: var(--ct-sys-text-muted);
  cursor: pointer;
  transition: color var(--dur-fast, 120ms) var(--ease-out, ease),
              background var(--dur-fast, 120ms) var(--ease-out, ease);
}
.ct-seg > *:hover, .view-toggle > *:hover, .mode-toggle > *:hover,
.fv-seg > *:hover, .jd-tabs > *:hover, .tl-tabs > *:hover, .jp-tabs > *:hover {
  color: var(--ct-sys-text-hi);
}
.ct-seg > .active, .ct-seg > [aria-selected="true"],
.view-toggle > .active, .mode-toggle > .active, .fv-seg > .active,
.jd-tabs > .active, .tl-tabs > .active, .jp-tabs > .active,
.view-toggle > [aria-selected="true"], .jd-tabs > [aria-selected="true"] {
  background: var(--ct-sys-card) !important;
  color: var(--ct-sys-text-hi) !important;
  box-shadow: var(--ct-e1), 0 0 0 1px var(--ct-sys-line-hi);
}

/* Underline tabs (punchlist HOME/TASKS, settings sections) — one rail. */
.tabs > .tab, .tab-bar > .tab, .ct-tabs > .tab {
  position: relative;
  background: transparent;
  border: none;
  padding: 12px 4px;
  margin-right: 22px;
  font-weight: 700;
  color: var(--ct-sys-text-muted);
  cursor: pointer;
}
.tabs > .tab.active, .tab-bar > .tab.active, .ct-tabs > .tab.active,
.tabs > .tab[aria-selected="true"] { color: var(--ct-sys-text-hi); }
.tabs > .tab.active::after, .tab-bar > .tab.active::after,
.ct-tabs > .tab.active::after, .tabs > .tab[aria-selected="true"]::after {
  content: '';
  position: absolute; left: 0; right: 0; bottom: -1px;
  height: 2px; border-radius: 2px;
  background: var(--ct-rail);
}


/* ------------------------------------------------------------
   11. CHIPS, TOGGLE-CHIPS & FILTER PILLS
   ------------------------------------------------------------
   The plans index shipped a five-colour rainbow of category chips
   (orange/blue/yellow/purple/green) that carried no meaning. Colour
   in this system is reserved for status; a selected filter is
   expressed by FILL, not by hue.
   ------------------------------------------------------------ */
.ct-chip, .filter-chip, .cat-chip, .cl-cat, .tag-chip {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 32px;
  padding: 0 13px;
  border-radius: var(--ct-r-full);
  border: 1px solid var(--ct-sys-line-hi);
  background: var(--ct-sys-input);
  color: var(--ct-sys-text-muted);
  font-family: var(--ct-font-ui);
  font-size: 12px; font-weight: 700; letter-spacing: 0.02em;
  cursor: pointer; white-space: nowrap;
  transition: all var(--dur-fast, 120ms) var(--ease-out, ease);
}
.ct-chip:hover, .filter-chip:hover, .cat-chip:hover, .cl-cat:hover {
  color: var(--ct-sys-text-hi);
  border-color: var(--ct-sys-primary);
}
.ct-chip.active, .filter-chip.active, .cat-chip.active, .cl-cat.active,
.ct-chip[aria-pressed="true"], .filter-chip[aria-pressed="true"] {
  background: color-mix(in srgb, var(--ct-sys-primary) 18%, var(--ct-sys-card));
  border-color: var(--ct-sys-primary);
  color: var(--ct-sys-text-hi);
  box-shadow: 0 0 16px -6px rgba(204,31,31,0.55);
}

/* Status LEDs — the small colour dot that precedes a status word. */
.led, .status-dot, .dot {
  width: 8px; height: 8px; border-radius: 50%; flex: none;
  background: var(--ct-sys-text-faint);
  box-shadow: 0 0 8px -1px currentColor;
}
.led.on,  .status-dot.active, .status-dot.live { background: var(--ct-sys-success); }
.led.warn,.status-dot.pending { background: var(--ct-sys-warning); }
.led.off, .status-dot.error, .status-dot.overdue { background: var(--ct-sys-danger); }

/* Category pills painted with a SOLID bright status colour need dark ink:
   white on the info blue measures 2.28:1. Dark ink on the same fill is 9:1,
   and the fill still carries the category meaning. */
.cat-pill.is-road, .cat-pill.is-info, .cat-pill.is-live,
.c-badge--roadmap, .c-badge--info, .c-badge--live,
.badge--solid, .pill--solid {
  color: #08131f !important;
  font-weight: 800;
  text-shadow: none;
}

/* Badges pick up a faint halo so they read as lit, not painted. */
.ct-badge--success, .badge.success, .pill.success, .status-pill.active,
.ct-badge--warning, .badge.warning, .pill.warning, .status-pill.pending,
.ct-badge--danger,  .badge.danger,  .pill.danger,  .status-pill.overdue,
.ct-badge--info,    .badge.info,    .pill.info,    .status-pill.sent {
  box-shadow: 0 0 14px -6px currentColor;
}


/* ------------------------------------------------------------
   12. MODALS & OVERLAYS
   ------------------------------------------------------------ */
.modal-bg, .modal-backdrop, .cl-modal-backdrop, .jp-modal-backdrop,
.tl-modal-backdrop, .overlay, .drawer-backdrop {
  background: rgba(6,7,9,0.72) !important;
  backdrop-filter: saturate(140%) blur(6px);
  -webkit-backdrop-filter: saturate(140%) blur(6px);
}
html[data-theme="light"] .modal-bg, html[data-theme="light"] .modal-backdrop {
  background: rgba(24,26,30,0.44) !important;
}
.ct-card--modal, .cl-modal-card, .jp-modal-card, .tl-modal-card, .modal-card,
.drawer, .sheet, .task-drawer {
  border-radius: var(--ct-r-xl) !important;
}
.modal-close, .drawer-close, .sheet-close {
  border-radius: var(--ct-r-full) !important;
  width: 34px; height: 34px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--ct-sys-line-hi);
  background: var(--ct-sys-input);
  color: var(--ct-sys-text-muted);
}
.modal-close:hover, .drawer-close:hover {
  color: var(--ct-sys-text-hi);
  border-color: var(--ct-sys-primary);
}


/* ------------------------------------------------------------
   13. TOASTS
   ------------------------------------------------------------ */
.toast, .ct-toast, #toast, .toast-item {
  border-radius: var(--ct-r-md) !important;
  border: 1px solid var(--ct-sys-line-hi);
  background: var(--ct-sys-card);
  color: var(--ct-sys-text-hi);
  box-shadow: var(--ct-e3);
  font-family: var(--ct-font-ui);
  font-size: 13px;
  font-weight: 600;
  padding: 12px 16px;
  letter-spacing: normal;
}
.toast.error, .ct-toast.error, .toast-item.error { border-color: var(--ct-sys-danger); }
.toast.success, .ct-toast.success { border-color: var(--ct-sys-success); }


/* ------------------------------------------------------------
   14. NAV, TOPBAR & THE FLOATING TOGGLE
   ------------------------------------------------------------ */
/* app-shell reserves a fixed first grid track for the sidebar. Pages that
   load nav.js but never call CT_NAV.render() (cable-labels) therefore left
   that track EMPTY and squeezed the whole page into 232px. Collapsing the
   track when no .sidebar child exists fixes it without touching the mount
   logic, and un-collapses itself the moment nav injects the sidebar. */
.app-shell:not(:has(> .sidebar)) { grid-template-columns: 1fr; }

.sidebar { border-right: 1px solid var(--ct-sys-line); }
.nav-item, .sidebar a, .sidebar-link {
  border-radius: var(--ct-r-sm);
  transition: background var(--dur-fast, 120ms) var(--ease-out, ease),
              color var(--dur-fast, 120ms) var(--ease-out, ease);
}
.nav-item:hover, .sidebar a:hover { background: rgba(255,255,255,0.045); }
/* The active nav item is "the live thing" — it gets the power rail, turned
   vertical to sit on the leading edge. */
.nav-item.active, .sidebar a.active, .nav-item[aria-current="page"] {
  position: relative;
  background: color-mix(in srgb, var(--ct-sys-primary) 14%, transparent);
  color: var(--ct-sys-text-hi);
}
.nav-item.active::before, .sidebar a.active::before,
.nav-item[aria-current="page"]::before {
  content: '';
  position: absolute; left: 0; top: 8px; bottom: 8px;
  width: 3px; border-radius: 0 3px 3px 0;
  background: var(--ct-rail);
}
.nav-section-title, .nav-section > .label {
  font-family: var(--ct-font-mono);
  font-size: 10px; font-weight: 700;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ct-sys-text-faint);
}

/* A topbar that opts into the signature rail (plans index). */
.ct-topbar-rail::after {
  content: '';
  position: absolute; left: 0; right: 0; top: 0; height: 2px;
  background: var(--ct-rail);
}

.topbar {
  border-bottom: 1px solid var(--ct-sys-line);
  background: color-mix(in srgb, var(--ct-sys-surface) 82%, transparent);
  backdrop-filter: saturate(150%) blur(12px);
  -webkit-backdrop-filter: saturate(150%) blur(12px);
}
/* A topbar title must never wrap: at 390px "NEW SITE VISIT" was breaking
   into three stacked lines and pushing the bar to 3× height. */
.page-title, .topbar .b, .topbar .title, .topbar .page-title {
  font-size: 21px;
  letter-spacing: 0.02em;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
@media (max-width: 560px) {
  .page-title, .topbar .b, .topbar .title { font-size: 17px; }
}

.bottom-tabs { border-top: 1px solid var(--ct-sys-line); }
.bottom-tab.active { color: var(--ct-sys-primary-text); }

/* The floating theme toggle used to sit ON TOP of sticky footer bars and
   the mobile tab rail — it clipped the "Save site visit" button. It now
   docks clear of both and drops below any modal. */
.ct-theme-toggle {
  z-index: 7000;
  border-radius: var(--ct-r-full);
  border-color: var(--ct-sys-line-hi);
  background: var(--ct-sys-card);
  color: var(--ct-sys-text-muted);
  box-shadow: var(--ct-e2);
}
.ct-theme-toggle:hover { color: var(--ct-sys-text-hi); border-color: var(--ct-sys-primary); }
@media (max-width: 880px) {
  .ct-theme-toggle { bottom: calc(var(--bottom-tabs-h, 64px) + 16px); right: 12px; }
}
/* Pages with a sticky action bar at the bottom get the toggle lifted above it
   and shrunk, so it can never overlap a primary action. */
body:has(.savebar) .ct-theme-toggle,
body:has(.sticky-actions) .ct-theme-toggle,
body:has(.form-actions--sticky) .ct-theme-toggle,
body:has(.sv-savebar) .ct-theme-toggle,
body:has(.action-bar) .ct-theme-toggle,
body:has([data-sticky-footer]) .ct-theme-toggle {
  bottom: calc(var(--bottom-tabs-h, 0px) + 82px);
  width: 34px; height: 34px; font-size: 15px;
}
/* Sticky footers get their own treatment and stay clear of the toggle column. */
.savebar, .sticky-actions, .form-actions--sticky, .sv-savebar,
.action-bar, [data-sticky-footer] {
  padding-right: 68px;
  background: color-mix(in srgb, var(--ct-sys-surface) 88%, transparent) !important;
  backdrop-filter: saturate(150%) blur(14px);
  -webkit-backdrop-filter: saturate(150%) blur(14px);
  border-top: 1px solid var(--ct-sys-line) !important;
  box-shadow: 0 -12px 30px -18px rgba(0,0,0,0.8);
}
/* …and the primary action inside one must never be squeezed to an ellipsis. */
.savebar .btn, .savebar .ct-btn, .sticky-actions .btn,
.action-bar .btn, .savebar button {
  flex: none;
  white-space: nowrap;
}
/* On mobile the bottom-tab rail owns the bottom of the screen, so a fixed
   save bar has to sit ABOVE it instead of underneath it. */
@media (max-width: 880px) {
  .savebar, .sticky-actions, .form-actions--sticky, .sv-savebar, .action-bar {
    bottom: var(--bottom-tabs-h, 64px) !important;
    padding-right: 18px;
  }
  /* A fixed save bar owns the bottom-right corner on a phone, and its height
     varies with its contents — so instead of guessing an offset, the toggle
     moves out of that corner entirely and docks under the topbar. */
  body:has(.savebar) .ct-theme-toggle,
  body:has(.sticky-actions) .ct-theme-toggle,
  body:has(.sv-savebar) .ct-theme-toggle,
  body:has(.action-bar) .ct-theme-toggle {
    top: calc(var(--topbar-h, 56px) + 10px);
    bottom: auto;
    right: 10px;
  }
}

/* Avatar initials must stay legible on the brand gradients. */
.avatar, [class*="avatar-c-"] {
  font-weight: 800;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0,0,0,0.45);
  letter-spacing: 0.02em;
  overflow: hidden;
}


/* ------------------------------------------------------------
   15. EMPTY STATES & LIST ROWS
   ------------------------------------------------------------ */
.empty, .empty-state, .cl-empty, .no-results, .placeholder-state {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px;
  min-height: 140px;
  padding: 32px 20px;
  border: 1px dashed var(--ct-sys-line-hi);
  border-radius: var(--ct-r-md);
  background: rgba(255,255,255,0.012);
  font-family: var(--ct-font-ui);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: normal;      /* undo the tracked-out mono empty states */
  text-transform: none;
  text-align: center;
  text-wrap: balance;
  /* Derived from the inherited ink rather than a dark-theme token: the print
     and report surfaces (punchlist-print / -export / -cert-report / -eod) are
     WHITE, and a fixed muted grey tuned for #1e1e1e measured 1.95:1 there. */
  color: color-mix(in srgb, currentColor 68%, transparent);
}
@supports not (color: color-mix(in srgb, red 50%, transparent)) {
  .empty, .empty-state, .cl-empty, .no-results { color: var(--ct-sys-text-muted); }
}
/* An empty state inside a grid spans it — otherwise the message sits in
   column 1 at one-quarter width and reads as a stray card. */
.cl-empty, .empty, .empty-state, .no-results { grid-column: 1 / -1; }

.list-row, .cust, .row-item, .data-row {
  border-radius: var(--ct-r-md);
  border: 1px solid var(--ct-sys-line);
  background: var(--ct-sys-card);
  transition: border-color var(--dur-fast, 120ms) var(--ease-out, ease),
              background var(--dur-fast, 120ms) var(--ease-out, ease);
}
.list-row:hover, .cust:hover, .row-item:hover, .data-row:hover {
  border-color: color-mix(in srgb, var(--ct-sys-primary) 42%, var(--ct-sys-line-hi));
  background: color-mix(in srgb, var(--ct-sys-primary) 5%, var(--ct-sys-card));
}


/* ------------------------------------------------------------
   16. SCROLLBARS, SELECTION, DIVIDERS
   ------------------------------------------------------------ */
* { scrollbar-color: var(--ct-sys-line-hi) transparent; scrollbar-width: thin; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--ct-sys-line-hi);
  border-radius: var(--ct-r-full);
  border: 2px solid transparent;
  background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--ct-sys-text-faint); background-clip: content-box; }

::selection { background: color-mix(in srgb, var(--ct-sys-primary) 55%, transparent); color: #fff; }

hr, .divider, .rule {
  border: none;
  height: 1px;
  background: var(--ct-sys-line);
  margin: var(--space-5, 1.25rem) 0;
}


/* ------------------------------------------------------------
   17. RESPONSIVE — breathing room, not just "it fits"
   ------------------------------------------------------------ */
@media (max-width: 720px) {
  .ct-card, .card, .tile, .stat-card, .data-card, .stat-tile,
  .crew-card, .fv-rcard, .pt-tile { padding: 16px; }
  .ct-card__header, .panel-header, .ct-card__body, .panel-body { padding: 14px 16px; }
  h1, .ct-h1, .hero-title { line-height: 1.05; }
  /* Toolbars stop hiding overflow off-screen and wrap instead. */
  .toolbar, .actions, .topbar-right, .cl-actions, .btn-row {
    flex-wrap: wrap;
    gap: 8px;
  }
  thead th, table th, tbody td, table td { padding: 10px 12px; }
}

/* Print: the report pages must stay ink-cheap and legible. */
@media print {
  .ct-theme-toggle, .sidebar, .bottom-tabs { display: none !important; }
  .empty, .empty-state { border: none; min-height: 0; padding: 8px 0; }
  a { color: inherit; }
  input, textarea, select { box-shadow: none; }
}

@media (prefers-reduced-motion: reduce) {
  input, textarea, select, .ct-chip, .list-row, .nav-item, tbody tr,
  input[type="checkbox"]::after, input[type="radio"]::after {
    transition: none !important;
  }
}


/* ════════════════════════════════════════════════════════════
   PART THREE — ELEVATION PASS (2026-08-03)
   ------------------------------------------------------------
   Part Two set the point of view; this part is finish work.
   Nothing here introduces a new idea — it deepens the existing
   ones: machined light on controls, a faint LED bloom on the
   numbers, spacing that comes from one scale. Presentation only,
   same safety contract as Part Two.
   ════════════════════════════════════════════════════════════ */

/* ------------------------------------------------------------
   18. SPACING RHYTHM — one scale for the gaps this file owns
   ------------------------------------------------------------ */
:root {
  --ct-sp-1: 4px;  --ct-sp-2: 8px;  --ct-sp-3: 12px; --ct-sp-4: 16px;
  --ct-sp-5: 20px; --ct-sp-6: 24px; --ct-sp-7: 32px; --ct-sp-8: 48px;
}

/* ------------------------------------------------------------
   19. MACHINED CONTROLS — light rakes the top edge
   ------------------------------------------------------------
   A rack button reads as milled because its top edge catches
   light. Primary gets a crisp top-light over the red fill;
   the neutral variants get it on hover, so rest state stays
   quiet and the cursor "finds" the control.
   ------------------------------------------------------------ */
.ct-btn--primary,
.btn.primary, .btn-primary, .btn.btn-primary,
.c-btn--primary, .pub-btn.primary,
button.primary, .submit-btn, .fv-timerbtn {
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.22), var(--ct-glow-primary);
}
.ct-btn--primary:hover,
.btn.primary:hover, .btn-primary:hover, .c-btn--primary:hover,
.pub-btn.primary:hover, button.primary:hover, .submit-btn:hover {
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.30),
              0 0 0 1px rgba(224,42,36,0.45),
              0 14px 34px -12px rgba(204,31,31,0.72),
              0 0 34px -8px rgba(204,31,31,0.55);
}

.ct-btn:hover, .btn:hover, .c-btn:hover, .pub-btn:hover, .btn-s:hover,
.u-btn:hover, .cl-btn:hover, .ia-btn:hover, .tl-btn:hover, .ts-btn:hover,
.fv-abtn:hover, .probbtn:hover, .cat-cta:hover,
button:not([class]):hover {
  background: color-mix(in srgb, #fff 4.5%, var(--ct-sys-input));
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.07), var(--ct-e1);
  transform: translateY(-1px);
}
/* …but a hover lift on a button that is busy or disabled reads as a lie. */
.ct-btn:disabled:hover, .btn:disabled:hover, .c-btn:disabled:hover,
.btn[aria-disabled="true"]:hover { transform: none; box-shadow: none; }
/* Segmented-control thumbs are a surface, not a button — they must not
   lift. Restores section 10's colour-only hover for buttons inside a track. */
.ct-seg > button:not(.active):not([aria-selected="true"]):hover,
.view-toggle > button:not(.active):not([aria-selected="true"]):hover,
.mode-toggle > button:not(.active):not([aria-selected="true"]):hover,
.fv-seg > button:not(.active):not([aria-selected="true"]):hover,
.jd-tabs > button:not(.active):not([aria-selected="true"]):hover,
.tl-tabs > button:not(.active):not([aria-selected="true"]):hover,
.jp-tabs > button:not(.active):not([aria-selected="true"]):hover,
.tabs > button:not(.active):not([aria-selected="true"]):hover,
.tab-bar > button:not(.active):not([aria-selected="true"]):hover {
  background: transparent;
  transform: none;
  box-shadow: none;
}
html[data-theme="light"] .ct-btn:hover, html[data-theme="light"] .btn:hover,
html[data-theme="light"] .c-btn:hover, html[data-theme="light"] .pub-btn:hover {
  background: color-mix(in srgb, #000 3%, var(--ct-sys-input));
  box-shadow: var(--ct-e1);
}

/* ------------------------------------------------------------
   20. LED BLOOM — the numbers glow like meters, faintly
   ------------------------------------------------------------ */
.stat-card .value, .stat-tile .value, .data-card .value,
.stat-card .stat-value, .stat-tile .stat-value, .ct-stat__value,
[class$="-value"], [class$="-num"], [class$="-metric"] {
  text-shadow: 0 0 22px color-mix(in srgb, currentColor 28%, transparent);
}
html[data-theme="light"] .stat-card .value, html[data-theme="light"] .stat-tile .value,
html[data-theme="light"] .ct-stat__value { text-shadow: none; }

/* ------------------------------------------------------------
   21. CHASSIS EDGES — topbar + sticky bars catch the light too
   ------------------------------------------------------------ */
.topbar { box-shadow: inset 0 1px 0 rgba(255,255,255,0.045); }
html[data-theme="light"] .topbar { box-shadow: inset 0 1px 0 rgba(255,255,255,0.8); }

.savebar, .sticky-actions, .form-actions--sticky, .sv-savebar, .action-bar {
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.05),
              0 -12px 30px -18px rgba(0,0,0,0.8);
}

@media (prefers-reduced-motion: reduce) {
  .ct-btn:hover, .btn:hover, .c-btn:hover, .pub-btn:hover,
  button:not([class]):hover { transform: none; }
}
