/* ============================================================================
   HyperDesk design system — theme.css
   ----------------------------------------------------------------------------
   Single stylesheet for the whole product (staff SPA, technician PWA, client
   portal, print views). No build step, no imports, no web fonts: the file is
   served as-is under a self-only CSP, so every value must be inlineable here.

   Conventions
   -----------
   - All custom properties are prefixed --hd- and live on :root so a single
     [data-theme] flip re-skins the app without touching component rules.
   - Component classes are .hd-<block>__<element>--<modifier>.
   - Colour is never used alone to convey state: chips pair colour with a label,
     icons carry shape. Required for WCAG AA / colour-blind users.
   - Density target is "Linear-like": 14px base, 8px grid, generous line-height
     inside text blocks and tight rhythm between structural elements.

   Index
   -----
    1. Tokens — primitives & scales
    2. Tokens — light theme (default)
    3. Tokens — dark theme (system + manual override)
    4. Reset & base
    5. Typography
    6. App shell & layout
    7. Cards
    8. Stat tiles
    9. Tables
   10. Buttons
   11. Forms & inputs
   12. Chips, badges, pills
   13. Tabs & segmented control
   14. Modal & drawer
   15. Toast & tooltip
   16. Progress ring & sparkline
   17. Empty states & skeletons
   18. Avatar
   19. PIN pad & photo input
   20. Utilities
   21. Print (ticket job-card rendition, plan §9.3)
   ========================================================================== */


/* ============================================================================
   1. TOKENS — PRIMITIVES & SCALES
   Scales are theme-independent; only colour changes between themes.
   ========================================================================== */
:root {
  /* -- font stacks: system only, no network requests allowed -------------- */
  --hd-font-sans: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue',
    Arial, 'Noto Sans', 'Liberation Sans', sans-serif;
  --hd-font-mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas,
    'Liberation Mono', 'Courier New', monospace;

  /* -- type scale (px kept explicit: dashboards are pixel-tuned) ---------- */
  --hd-text-2xs: 10.5px;
  --hd-text-xs: 11.5px;
  --hd-text-sm: 12.5px;
  --hd-text-base: 14px;
  --hd-text-md: 15px;
  --hd-text-lg: 17px;
  --hd-text-xl: 20px;
  --hd-text-2xl: 25px;
  --hd-text-3xl: 32px;
  --hd-text-4xl: 40px;

  --hd-leading-tight: 1.2;
  --hd-leading-snug: 1.35;
  --hd-leading-normal: 1.55;
  --hd-leading-relaxed: 1.7;

  --hd-weight-normal: 400;
  --hd-weight-medium: 500;
  --hd-weight-semibold: 600;
  --hd-weight-bold: 700;

  --hd-tracking-tight: -0.012em;
  --hd-tracking-normal: 0;
  --hd-tracking-wide: 0.02em;
  --hd-tracking-caps: 0.07em;

  /* -- 8px spacing grid (half-steps for control internals) ---------------- */
  --hd-s0: 0px;
  --hd-s1: 4px;
  --hd-s2: 8px;
  --hd-s3: 12px;
  --hd-s4: 16px;
  --hd-s5: 20px;
  --hd-s6: 24px;
  --hd-s7: 28px;
  --hd-s8: 32px;
  --hd-s10: 40px;
  --hd-s12: 48px;
  --hd-s16: 64px;
  --hd-s20: 80px;

  /* -- radii -------------------------------------------------------------- */
  --hd-r-xs: 4px;
  --hd-r-sm: 6px;
  --hd-r-md: 8px;
  --hd-r-lg: 12px;
  --hd-r-xl: 16px;
  --hd-r-2xl: 22px;
  --hd-r-full: 999px;

  /* -- layout constants --------------------------------------------------- */
  --hd-nav-h: 52px;
  --hd-actionbar-h: 64px;
  --hd-content-max: 1440px;
  --hd-tap-min: 44px;          /* iOS/Android minimum touch target */
  --hd-tap-lg: 56px;           /* one-handed field use */

  /* -- z-index ladder ----------------------------------------------------- */
  --hd-z-base: 0;
  --hd-z-raised: 10;
  --hd-z-sticky: 100;
  --hd-z-nav: 200;
  --hd-z-dropdown: 300;
  --hd-z-drawer: 400;
  --hd-z-modal: 500;
  --hd-z-toast: 600;
  --hd-z-tooltip: 700;

  /* -- motion ------------------------------------------------------------- */
  --hd-ease: cubic-bezier(0.2, 0.8, 0.3, 1);
  --hd-ease-in: cubic-bezier(0.4, 0, 1, 1);
  --hd-ease-out: cubic-bezier(0, 0, 0.2, 1);
  --hd-t-instant: 80ms;
  --hd-t-fast: 130ms;
  --hd-t-med: 200ms;
  --hd-t-slow: 320ms;
}


/* ============================================================================
   2. TOKENS — LIGHT THEME (default)
   Contrast: ink/bg 15.9:1, ink-secondary/surface 7.8:1, ink-muted/surface 4.9:1,
   every semantic *-ink on its own *-soft surface clears 4.5:1.
   ========================================================================== */
:root,
:root[data-theme='light'] {
  color-scheme: light;

  /* surfaces */
  --hd-bg: #f5f6f9;
  --hd-surface: #ffffff;
  --hd-surface-raised: #ffffff;
  --hd-surface-sunken: #eef0f5;
  --hd-surface-hover: #f3f5f9;
  --hd-surface-active: #e9edf4;
  --hd-overlay: rgba(15, 20, 30, 0.48);

  /* ink */
  --hd-ink: #0f1729;
  --hd-ink-secondary: #45526a;
  --hd-ink-muted: #616c7e;   /* AA (4.66:1) on --hd-surface-sunken, where table headers live */
  --hd-ink-faint: #858fa1;   /* decorative only (icons/rules): 3.26:1, never body text */
  --hd-ink-inverse: #ffffff;

  /* structure */
  --hd-border: #e1e5ec;
  --hd-border-strong: #c8cfda;
  --hd-border-faint: #eef1f5;
  --hd-divider: #e8ebf1;

  /* brand — HyperCode blue */
  --hd-brand: #1b6fd8;
  --hd-brand-hover: #175cb4;
  --hd-brand-active: #134c96;
  --hd-brand-ink: #12508f;      /* brand-coloured text on light surfaces */
  --hd-brand-soft: #e8f1fd;
  --hd-brand-soft-border: #bcd6f8;
  --hd-brand-contrast: #ffffff; /* text on a solid brand fill */

  /* semantic — ok / green */
  --hd-ok: #0f7b44;
  --hd-ok-ink: #0c6337;
  --hd-ok-soft: #e2f6ea;
  --hd-ok-border: #a3dcbe;

  /* semantic — warn / amber */
  --hd-warn: #b45309;
  --hd-warn-ink: #954409;
  --hd-warn-soft: #fef2e0;
  --hd-warn-border: #f3c68a;

  /* semantic — danger / red */
  --hd-danger: #b42318;
  --hd-danger-ink: #971b12;
  --hd-danger-soft: #fee8e6;
  --hd-danger-border: #f4b3ac;

  /* semantic — info / blue (distinct from brand: informational, not clickable) */
  --hd-info: #175cd3;
  --hd-info-ink: #14499f;
  --hd-info-soft: #e9f1ff;
  --hd-info-border: #b6cff8;

  /* semantic — neutral / grey */
  --hd-neutral: #475467;
  --hd-neutral-ink: #3a465a;
  --hd-neutral-soft: #eff1f5;
  --hd-neutral-border: #d3d9e2;

  /* semantic — positive-reschedule / teal
     Reserved for reason_category = emergency_callout and other "clean reason"
     signals: reads as commendable, must NOT be confused with ok-green (which
     means an SLA clock is healthy) or with warn-amber (which means review). */
  --hd-positive: #0d7490;
  --hd-positive-ink: #0a5d74;
  --hd-positive-soft: #e0f4f9;
  --hd-positive-border: #9bd8e6;

  /* focus & selection */
  --hd-focus: #1b6fd8;
  --hd-focus-halo: rgba(27, 111, 216, 0.25);
  --hd-selection-bg: #cfe1fb;
  --hd-selection-ink: #0f1729;

  /* avatar: hue comes from the person's name (JS), lightness from the theme,
     so the same person keeps one colour and both themes stay AA */
  --hd-avatar-s: 55%;
  --hd-avatar-l-bg: 91%;
  --hd-avatar-l-fg: 29%;

  /* shadows */
  --hd-shadow-xs: 0 1px 2px rgba(15, 23, 41, 0.06);
  --hd-shadow-sm: 0 1px 3px rgba(15, 23, 41, 0.08), 0 1px 2px rgba(15, 23, 41, 0.04);
  --hd-shadow-md: 0 4px 10px -2px rgba(15, 23, 41, 0.1), 0 2px 4px -2px rgba(15, 23, 41, 0.06);
  --hd-shadow-lg: 0 12px 24px -6px rgba(15, 23, 41, 0.14), 0 4px 8px -4px rgba(15, 23, 41, 0.07);
  --hd-shadow-xl: 0 24px 48px -12px rgba(15, 23, 41, 0.22);
  --hd-shadow-inset: inset 0 1px 0 rgba(255, 255, 255, 0.6);

  /* data-visualisation categorical ramp — validated (CVD-safe, fixed order,
     never cycled): brand blue, orange, aqua, yellow, magenta. Light slots 3–5
     sit below 3:1 on white, so charts always ship direct labels / tooltips /
     a table view (the relief rule). */
  --hd-viz-1: #1b6fd8;
  --hd-viz-2: #eb6834;
  --hd-viz-3: #1baf7a;
  --hd-viz-4: #eda100;
  --hd-viz-5: #e87ba4;
  --hd-viz-grid: #e4e8ef;

  /* hero band (Command centre): deep brand gradient, both themes */
  --hd-hero-bg: linear-gradient(135deg, #0d2f5e 0%, #123f80 42%, #1b5db4 100%);
  --hd-hero-ink: #f4f8ff;
  --hd-hero-ink-soft: rgba(226, 238, 255, 0.72);
  --hd-hero-tile: rgba(255, 255, 255, 0.09);
  --hd-hero-tile-hover: rgba(255, 255, 255, 0.16);
  --hd-hero-border: rgba(255, 255, 255, 0.14);
}


/* ============================================================================
   3. TOKENS — DARK THEME
   Applied by system preference AND by the manual [data-theme='dark'] switch;
   the explicit [data-theme='light'] block above wins over the media query so a
   user on a dark OS can still force light.
   ========================================================================== */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    color-scheme: dark;

    --hd-bg: #0b0d12;
    --hd-surface: #14171f;
    --hd-surface-raised: #1b1f2a;
    --hd-surface-sunken: #101319;
    --hd-surface-hover: #1c202b;
    --hd-surface-active: #232836;
    --hd-overlay: rgba(3, 5, 9, 0.68);

    --hd-ink: #e8ecf3;
    --hd-ink-secondary: #adb6c6;
    --hd-ink-muted: #838ea2;
    --hd-ink-faint: #656f81;
    --hd-ink-inverse: #0b0d12;

    --hd-border: #262b37;
    --hd-border-strong: #3a4252;
    --hd-border-faint: #1d222c;
    --hd-divider: #222732;

    --hd-brand: #4e93ee;
    --hd-brand-hover: #6ba6f4;
    --hd-brand-active: #8bbaf7;
    --hd-brand-ink: #9cc4f8;
    --hd-brand-soft: #15294a;
    --hd-brand-soft-border: #27436e;
    --hd-brand-contrast: #06111f;

    --hd-ok: #45c883;
    --hd-ok-ink: #6bd79c;
    --hd-ok-soft: #0f2a1d;
    --hd-ok-border: #205339;

    --hd-warn: #f0b429;
    --hd-warn-ink: #f5c65c;
    --hd-warn-soft: #2b2010;
    --hd-warn-border: #5c451a;

    --hd-danger: #f8776a;
    --hd-danger-ink: #fb9086;
    --hd-danger-soft: #2d1512;
    --hd-danger-border: #5e2a25;

    --hd-info: #6ba5f5;
    --hd-info-ink: #93bef8;
    --hd-info-soft: #101f36;
    --hd-info-border: #234069;

    --hd-neutral: #a5aebf;
    --hd-neutral-ink: #b9c1d0;
    --hd-neutral-soft: #1c212c;
    --hd-neutral-border: #333a49;

    --hd-positive: #4ec6de;
    --hd-positive-ink: #77d6e8;
    --hd-positive-soft: #0d2630;
    --hd-positive-border: #1e4c5c;

    --hd-focus: #6ba6f4;
    --hd-focus-halo: rgba(107, 166, 244, 0.32);
    --hd-selection-bg: #234069;
    --hd-selection-ink: #e8ecf3;

    --hd-avatar-s: 42%;
    --hd-avatar-l-bg: 24%;
    --hd-avatar-l-fg: 76%;

    /* dark shadows lean on darkness + a hairline highlight, not blur alone */
    --hd-shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.5);
    --hd-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.55), 0 1px 2px rgba(0, 0, 0, 0.4);
    --hd-shadow-md: 0 6px 14px -4px rgba(0, 0, 0, 0.6), 0 2px 6px -2px rgba(0, 0, 0, 0.45);
    --hd-shadow-lg: 0 16px 32px -8px rgba(0, 0, 0, 0.7), 0 4px 10px -4px rgba(0, 0, 0, 0.5);
    --hd-shadow-xl: 0 28px 56px -14px rgba(0, 0, 0, 0.8);
    --hd-shadow-inset: inset 0 1px 0 rgba(255, 255, 255, 0.04);

    --hd-viz-1: #3987e5;
    --hd-viz-2: #d95926;
    --hd-viz-3: #199e70;
    --hd-viz-4: #c98500;
    --hd-viz-5: #d55181;
    --hd-viz-grid: #262b37;

    --hd-hero-bg: linear-gradient(135deg, #0c1a30 0%, #10294e 46%, #16407b 100%);
    --hd-hero-ink: #eef4ff;
    --hd-hero-ink-soft: rgba(214, 229, 252, 0.66);
    --hd-hero-tile: rgba(255, 255, 255, 0.06);
    --hd-hero-tile-hover: rgba(255, 255, 255, 0.12);
    --hd-hero-border: rgba(255, 255, 255, 0.1);
  }
}

:root[data-theme='dark'] {
  color-scheme: dark;

  --hd-bg: #0b0d12;
  --hd-surface: #14171f;
  --hd-surface-raised: #1b1f2a;
  --hd-surface-sunken: #101319;
  --hd-surface-hover: #1c202b;
  --hd-surface-active: #232836;
  --hd-overlay: rgba(3, 5, 9, 0.68);

  --hd-ink: #e8ecf3;
  --hd-ink-secondary: #adb6c6;
  --hd-ink-muted: #838ea2;
  --hd-ink-faint: #656f81;
  --hd-ink-inverse: #0b0d12;

  --hd-border: #262b37;
  --hd-border-strong: #3a4252;
  --hd-border-faint: #1d222c;
  --hd-divider: #222732;

  --hd-brand: #4e93ee;
  --hd-brand-hover: #6ba6f4;
  --hd-brand-active: #8bbaf7;
  --hd-brand-ink: #9cc4f8;
  --hd-brand-soft: #15294a;
  --hd-brand-soft-border: #27436e;
  --hd-brand-contrast: #06111f;

  --hd-ok: #45c883;
  --hd-ok-ink: #6bd79c;
  --hd-ok-soft: #0f2a1d;
  --hd-ok-border: #205339;

  --hd-warn: #f0b429;
  --hd-warn-ink: #f5c65c;
  --hd-warn-soft: #2b2010;
  --hd-warn-border: #5c451a;

  --hd-danger: #f8776a;
  --hd-danger-ink: #fb9086;
  --hd-danger-soft: #2d1512;
  --hd-danger-border: #5e2a25;

  --hd-info: #6ba5f5;
  --hd-info-ink: #93bef8;
  --hd-info-soft: #101f36;
  --hd-info-border: #234069;

  --hd-neutral: #a5aebf;
  --hd-neutral-ink: #b9c1d0;
  --hd-neutral-soft: #1c212c;
  --hd-neutral-border: #333a49;

  --hd-positive: #4ec6de;
  --hd-positive-ink: #77d6e8;
  --hd-positive-soft: #0d2630;
  --hd-positive-border: #1e4c5c;

  --hd-focus: #6ba6f4;
  --hd-focus-halo: rgba(107, 166, 244, 0.32);
  --hd-selection-bg: #234069;
  --hd-selection-ink: #e8ecf3;

  --hd-avatar-s: 42%;
  --hd-avatar-l-bg: 24%;
  --hd-avatar-l-fg: 76%;

  --hd-shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.5);
  --hd-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.55), 0 1px 2px rgba(0, 0, 0, 0.4);
  --hd-shadow-md: 0 6px 14px -4px rgba(0, 0, 0, 0.6), 0 2px 6px -2px rgba(0, 0, 0, 0.45);
  --hd-shadow-lg: 0 16px 32px -8px rgba(0, 0, 0, 0.7), 0 4px 10px -4px rgba(0, 0, 0, 0.5);
  --hd-shadow-xl: 0 28px 56px -14px rgba(0, 0, 0, 0.8);
  --hd-shadow-inset: inset 0 1px 0 rgba(255, 255, 255, 0.04);

  --hd-viz-1: #3987e5;
  --hd-viz-2: #d95926;
  --hd-viz-3: #199e70;
  --hd-viz-4: #c98500;
  --hd-viz-5: #d55181;
  --hd-viz-grid: #262b37;

  --hd-hero-bg: linear-gradient(135deg, #0c1a30 0%, #10294e 46%, #16407b 100%);
  --hd-hero-ink: #eef4ff;
  --hd-hero-ink-soft: rgba(214, 229, 252, 0.66);
  --hd-hero-tile: rgba(255, 255, 255, 0.06);
  --hd-hero-tile-hover: rgba(255, 255, 255, 0.12);
  --hd-hero-border: rgba(255, 255, 255, 0.1);
}


/* ============================================================================
   4. RESET & BASE
   ========================================================================== */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* Safari PWA: keep the status-bar area painted with the app background */
  background: var(--hd-bg);
}

body {
  margin: 0;
  min-height: 100vh;
  font-family: var(--hd-font-sans);
  font-size: var(--hd-text-base);
  line-height: var(--hd-leading-normal);
  color: var(--hd-ink);
  background: var(--hd-bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-variant-ligatures: contextual;
  /* Field techs drag-scroll one-handed; kill the iOS long-press callout on
     controls but keep text selection inside content. */
  -webkit-tap-highlight-color: transparent;
}

h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd, ul, ol {
  margin: 0;
}

ul, ol {
  padding: 0;
  list-style: none;
}

img, svg, video, canvas {
  display: block;
  max-width: 100%;
}

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

a {
  color: var(--hd-brand-ink);
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}

hr {
  border: 0;
  border-top: 1px solid var(--hd-divider);
  margin: var(--hd-s4) 0;
}

code, kbd, samp, pre {
  font-family: var(--hd-font-mono);
  font-size: 0.92em;
}

kbd {
  display: inline-block;
  padding: 1px 5px;
  border: 1px solid var(--hd-border-strong);
  border-bottom-width: 2px;
  border-radius: var(--hd-r-xs);
  background: var(--hd-surface-sunken);
  font-size: var(--hd-text-xs);
  color: var(--hd-ink-secondary);
}

::selection {
  background: var(--hd-selection-bg);
  color: var(--hd-selection-ink);
}

/* Focus: always visible, never removed. :focus-visible keeps mouse clicks
   clean while guaranteeing keyboard users a ring on every interactive thing. */
:focus {
  outline: none;
}
:focus-visible {
  outline: 2px solid var(--hd-focus);
  outline-offset: 2px;
  border-radius: var(--hd-r-xs);
}

/* Scrollbars: thin and theme-aware so dark mode doesn't get a white gutter. */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--hd-border-strong) transparent;
}
*::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
*::-webkit-scrollbar-track {
  background: transparent;
}
*::-webkit-scrollbar-thumb {
  background: var(--hd-border-strong);
  border: 3px solid transparent;
  background-clip: padding-box;
  border-radius: var(--hd-r-full);
}
*::-webkit-scrollbar-thumb:hover {
  background: var(--hd-ink-faint);
  background-clip: padding-box;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}


/* ============================================================================
   5. TYPOGRAPHY
   ========================================================================== */
.hd-h1 {
  font-size: var(--hd-text-2xl);
  font-weight: var(--hd-weight-semibold);
  line-height: var(--hd-leading-tight);
  letter-spacing: var(--hd-tracking-tight);
  color: var(--hd-ink);
}
.hd-h2 {
  font-size: var(--hd-text-xl);
  font-weight: var(--hd-weight-semibold);
  line-height: var(--hd-leading-tight);
  letter-spacing: var(--hd-tracking-tight);
  color: var(--hd-ink);
}
.hd-h3 {
  font-size: var(--hd-text-lg);
  font-weight: var(--hd-weight-semibold);
  line-height: var(--hd-leading-snug);
  color: var(--hd-ink);
}
.hd-h4 {
  font-size: var(--hd-text-md);
  font-weight: var(--hd-weight-semibold);
  line-height: var(--hd-leading-snug);
  color: var(--hd-ink);
}

.hd-body {
  font-size: var(--hd-text-base);
  line-height: var(--hd-leading-normal);
  color: var(--hd-ink-secondary);
}
.hd-small {
  font-size: var(--hd-text-sm);
  line-height: var(--hd-leading-snug);
  color: var(--hd-ink-secondary);
}
.hd-tiny {
  font-size: var(--hd-text-xs);
  line-height: var(--hd-leading-snug);
  color: var(--hd-ink-muted);
}

/* Section eyebrow — the "LIVE FIELD VIEW" / "SLA RISK BOARD" labels. */
.hd-eyebrow {
  font-size: var(--hd-text-2xs);
  font-weight: var(--hd-weight-semibold);
  letter-spacing: var(--hd-tracking-caps);
  text-transform: uppercase;
  color: var(--hd-ink-muted);
}

.hd-mono {
  font-family: var(--hd-font-mono);
  font-size: 0.94em;
}

/* Tabular numerals: mandatory for tables, countdowns and any column of numbers
   — proportional digits make a ticking clock jitter and columns wobble. */
.hd-num {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1, 'lnum' 1;
  letter-spacing: var(--hd-tracking-normal);
}

.hd-ink-secondary { color: var(--hd-ink-secondary); }
.hd-ink-muted { color: var(--hd-ink-muted); }
.hd-ink-brand { color: var(--hd-brand-ink); }
.hd-ink-ok { color: var(--hd-ok-ink); }
.hd-ink-warn { color: var(--hd-warn-ink); }
.hd-ink-danger { color: var(--hd-danger-ink); }
.hd-ink-positive { color: var(--hd-positive-ink); }

.hd-truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.hd-clamp-2 {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}


/* ============================================================================
   6. APP SHELL & LAYOUT
   ========================================================================== */
.hd-app {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
  position: relative;
}

/* Ambient aura — a barely-there brand wash at the top of every screen. It sits
   behind everything, costs nothing, and stops the app reading as flat white. */
.hd-app::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(900px 420px at 12% -10%, color-mix(in srgb, var(--hd-brand) 7%, transparent), transparent 60%),
    radial-gradient(760px 380px at 88% -14%, color-mix(in srgb, var(--hd-positive) 6%, transparent), transparent 55%);
}

/* --- top nav --------------------------------------------------------------*/
.hd-nav {
  position: sticky;
  top: 0;
  z-index: var(--hd-z-nav);
  display: flex;
  align-items: center;
  gap: var(--hd-s3);
  height: var(--hd-nav-h);
  padding: 0 var(--hd-s4);
  background: var(--hd-surface);
  border-bottom: 1px solid var(--hd-border);
  /* PWA in standalone mode sits under the notch on iOS */
  padding-top: env(safe-area-inset-top, 0);
  height: calc(var(--hd-nav-h) + env(safe-area-inset-top, 0px));
}

.hd-nav__brand {
  display: inline-flex;
  align-items: center;
  gap: var(--hd-s2);
  font-weight: var(--hd-weight-semibold);
  font-size: var(--hd-text-md);
  letter-spacing: var(--hd-tracking-tight);
  color: var(--hd-ink);
  white-space: nowrap;
}
.hd-nav__brand:hover { text-decoration: none; }

.hd-nav__mark {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: var(--hd-r-sm);
  background: var(--hd-brand);
  color: var(--hd-brand-contrast);
  font-size: var(--hd-text-sm);
  font-weight: var(--hd-weight-bold);
  letter-spacing: -0.03em;
}

.hd-nav__links {
  display: flex;
  align-items: center;
  gap: var(--hd-s1);
  overflow-x: auto;
  scrollbar-width: none;
}
.hd-nav__links::-webkit-scrollbar { display: none; }

.hd-nav__link {
  display: inline-flex;
  align-items: center;
  gap: var(--hd-s2);
  height: 32px;
  padding: 0 var(--hd-s3);
  border-radius: var(--hd-r-sm);
  font-size: var(--hd-text-sm);
  font-weight: var(--hd-weight-medium);
  color: var(--hd-ink-secondary);
  white-space: nowrap;
  transition: background var(--hd-t-fast) var(--hd-ease),
    color var(--hd-t-fast) var(--hd-ease);
}
.hd-nav__link:hover {
  background: var(--hd-surface-hover);
  color: var(--hd-ink);
  text-decoration: none;
}
.hd-nav__link[aria-current='page'] {
  background: var(--hd-brand-soft);
  color: var(--hd-brand-ink);
  box-shadow: inset 0 0 0 1px var(--hd-brand-soft-border);
  position: relative;
}
.hd-nav__link[aria-current='page']::after {
  content: '';
  position: absolute;
  left: 10px;
  right: 10px;
  bottom: -1px;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--hd-brand), var(--hd-positive));
}

.hd-nav__spacer { flex: 1 1 auto; }

.hd-nav__right {
  display: flex;
  align-items: center;
  gap: var(--hd-s2);
}

/* --- content --------------------------------------------------------------*/
.hd-main {
  flex: 1 1 auto;
  width: 100%;
  max-width: var(--hd-content-max);
  margin-inline: auto;
  padding: var(--hd-s5) var(--hd-s5) var(--hd-s12);
}

.hd-page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--hd-s4);
  flex-wrap: wrap;
  margin-bottom: var(--hd-s5);
}
.hd-page-head__meta {
  display: flex;
  align-items: center;
  gap: var(--hd-s3);
  flex-wrap: wrap;
  margin-top: var(--hd-s1);
}

/* --- grids ----------------------------------------------------------------*/
.hd-grid {
  display: grid;
  gap: var(--hd-s4);
}
.hd-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.hd-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.hd-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.hd-grid--auto {
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}

/* Split pane: main column + fixed-ish rail (the Command Centre's
   "LIVE FIELD VIEW | SLA RISK BOARD" pairing). */
.hd-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 360px);
  gap: var(--hd-s4);
  align-items: start;
}
.hd-split--even { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.hd-split--wide-rail { grid-template-columns: minmax(0, 1fr) minmax(0, 460px); }
.hd-split--rail-left { grid-template-columns: minmax(0, 320px) minmax(0, 1fr); }

.hd-stack {
  display: flex;
  flex-direction: column;
  gap: var(--hd-s4);
}
.hd-stack--tight { gap: var(--hd-s2); }
.hd-stack--loose { gap: var(--hd-s6); }

.hd-row {
  display: flex;
  align-items: center;
  gap: var(--hd-s2);
  flex-wrap: wrap;
}
.hd-row--tight { gap: var(--hd-s1); }
.hd-row--between { justify-content: space-between; }
.hd-row--end { justify-content: flex-end; }
.hd-row--nowrap { flex-wrap: nowrap; }
.hd-row--top { align-items: flex-start; }

/* --- sticky bottom action bar (mobile primary actions) ------------------- */
.hd-actionbar {
  position: sticky;
  bottom: 0;
  z-index: var(--hd-z-sticky);
  display: flex;
  align-items: center;
  gap: var(--hd-s2);
  padding: var(--hd-s3) var(--hd-s4);
  padding-bottom: calc(var(--hd-s3) + env(safe-area-inset-bottom, 0px));
  background: var(--hd-surface);
  border-top: 1px solid var(--hd-border);
  box-shadow: 0 -4px 16px -8px rgba(0, 0, 0, 0.25);
}
.hd-actionbar > * { flex: 1 1 0; }
.hd-actionbar > .hd-actionbar__fixed { flex: 0 0 auto; }

@media (max-width: 1024px) {
  .hd-split,
  .hd-split--wide-rail,
  .hd-split--rail-left,
  .hd-grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hd-grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 720px) {
  .hd-main { padding: var(--hd-s4) var(--hd-s3) var(--hd-s10); }
  .hd-split,
  .hd-split--even,
  .hd-split--wide-rail,
  .hd-split--rail-left,
  .hd-grid--2,
  .hd-grid--3,
  .hd-grid--4 { grid-template-columns: minmax(0, 1fr); }
  .hd-h1 { font-size: var(--hd-text-xl); }
}


/* ============================================================================
   7. CARDS
   ========================================================================== */
.hd-card {
  display: flex;
  flex-direction: column;
  background: var(--hd-surface);
  border: 1px solid var(--hd-border);
  border-radius: var(--hd-r-xl);
  box-shadow: var(--hd-shadow-xs);
  overflow: hidden;
  transition: border-color var(--hd-t-med) var(--hd-ease),
    box-shadow var(--hd-t-med) var(--hd-ease);
}
.hd-card:hover { box-shadow: var(--hd-shadow-sm); }

.hd-card__head {
  display: flex;
  align-items: center;
  gap: var(--hd-s3);
  padding: var(--hd-s3) var(--hd-s4);
  border-bottom: 1px solid var(--hd-border-faint);
  background: var(--hd-surface);
}
.hd-card__title {
  display: flex;
  align-items: center;
  gap: var(--hd-s2);
  font-size: var(--hd-text-2xs);
  font-weight: var(--hd-weight-semibold);
  letter-spacing: var(--hd-tracking-caps);
  text-transform: uppercase;
  color: var(--hd-ink-muted);
  min-width: 0;
}
.hd-card__count {
  font-variant-numeric: tabular-nums;
  color: var(--hd-ink-muted);
}
.hd-card__actions {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--hd-s1);
  flex-shrink: 0;
}
.hd-card__body {
  padding: var(--hd-s4);
  flex: 1 1 auto;
  min-width: 0;
}
.hd-card__body--flush { padding: 0; }
.hd-card__foot {
  padding: var(--hd-s3) var(--hd-s4);
  border-top: 1px solid var(--hd-border-faint);
  background: var(--hd-surface-sunken);
}

/* Tone accents: a 3px left rail, never a full colour wash — keeps dashboards
   calm while still flagging the one card that needs attention. */
.hd-card--ok { box-shadow: inset 3px 0 0 var(--hd-ok), var(--hd-shadow-xs); }
.hd-card--warn { box-shadow: inset 3px 0 0 var(--hd-warn), var(--hd-shadow-xs); }
.hd-card--danger { box-shadow: inset 3px 0 0 var(--hd-danger), var(--hd-shadow-xs); }
.hd-card--info { box-shadow: inset 3px 0 0 var(--hd-info), var(--hd-shadow-xs); }
.hd-card--brand { box-shadow: inset 3px 0 0 var(--hd-brand), var(--hd-shadow-xs); }
.hd-card--positive { box-shadow: inset 3px 0 0 var(--hd-positive), var(--hd-shadow-xs); }

.hd-card--interactive {
  cursor: pointer;
  transition: border-color var(--hd-t-fast) var(--hd-ease),
    box-shadow var(--hd-t-fast) var(--hd-ease), transform var(--hd-t-fast) var(--hd-ease);
}
.hd-card--interactive:hover {
  border-color: var(--hd-border-strong);
  box-shadow: var(--hd-shadow-md);
}

/* Row list inside a flush card body — the sign-off / risk-board rows. */
.hd-list {
  display: flex;
  flex-direction: column;
}
.hd-list__item {
  display: flex;
  align-items: center;
  gap: var(--hd-s3);
  padding: var(--hd-s3) var(--hd-s4);
  border-bottom: 1px solid var(--hd-border-faint);
  min-width: 0;
}
.hd-list__item:last-child { border-bottom: 0; }
.hd-list__item--clickable {
  cursor: pointer;
  transition: background var(--hd-t-fast) var(--hd-ease);
}
.hd-list__item--clickable:hover { background: var(--hd-surface-hover); }
.hd-list__main { flex: 1 1 auto; min-width: 0; }
.hd-list__aside { flex: 0 0 auto; display: flex; align-items: center; gap: var(--hd-s2); }


/* ============================================================================
   8. STAT TILES
   Every number on a dashboard drills into the filtered list behind it, so the
   default tile styling reads as affordance (hover lift + brand hairline).
   ========================================================================== */
.hd-stat {
  display: flex;
  flex-direction: column;
  gap: var(--hd-s1);
  padding: var(--hd-s4);
  background: var(--hd-surface);
  border: 1px solid var(--hd-border);
  border-radius: var(--hd-r-lg);
  box-shadow: var(--hd-shadow-xs);
  text-align: left;
  min-width: 0;
}

.hd-stat__label {
  font-size: var(--hd-text-2xs);
  font-weight: var(--hd-weight-semibold);
  letter-spacing: var(--hd-tracking-caps);
  text-transform: uppercase;
  color: var(--hd-ink-muted);
}
.hd-stat__value {
  display: flex;
  align-items: baseline;
  gap: var(--hd-s2);
  font-size: var(--hd-text-3xl);
  font-weight: var(--hd-weight-semibold);
  line-height: 1.05;
  letter-spacing: var(--hd-tracking-tight);
  font-variant-numeric: tabular-nums;
  color: var(--hd-ink);
}
.hd-stat__unit {
  font-size: var(--hd-text-md);
  font-weight: var(--hd-weight-medium);
  color: var(--hd-ink-muted);
}
.hd-stat__sub {
  font-size: var(--hd-text-sm);
  color: var(--hd-ink-muted);
}
.hd-stat__trend {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: var(--hd-text-xs);
  font-weight: var(--hd-weight-semibold);
  font-variant-numeric: tabular-nums;
}
.hd-stat__trend--up { color: var(--hd-ok-ink); }
.hd-stat__trend--down { color: var(--hd-danger-ink); }
.hd-stat__trend--flat { color: var(--hd-ink-muted); }

.hd-stat--ok .hd-stat__value { color: var(--hd-ok-ink); }
.hd-stat--warn .hd-stat__value { color: var(--hd-warn-ink); }
.hd-stat--danger .hd-stat__value { color: var(--hd-danger-ink); }
.hd-stat--brand .hd-stat__value { color: var(--hd-brand-ink); }
.hd-stat--positive .hd-stat__value { color: var(--hd-positive-ink); }

button.hd-stat {
  cursor: pointer;
  font-family: inherit;
  transition: border-color var(--hd-t-fast) var(--hd-ease),
    box-shadow var(--hd-t-fast) var(--hd-ease), transform var(--hd-t-fast) var(--hd-ease);
}
button.hd-stat:hover {
  border-color: var(--hd-brand-soft-border);
  box-shadow: var(--hd-shadow-md);
  transform: translateY(-1px);
}
button.hd-stat:active { transform: translateY(0); }

.hd-stat--compact { padding: var(--hd-s3); }
.hd-stat--compact .hd-stat__value { font-size: var(--hd-text-2xl); }


/* ============================================================================
   9. TABLES
   ========================================================================== */
.hd-table-wrap {
  width: 100%;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
}

.hd-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: var(--hd-text-sm);
  font-variant-numeric: tabular-nums;
}

.hd-table thead th {
  position: sticky;
  top: 0;
  z-index: var(--hd-z-raised);
  padding: var(--hd-s2) var(--hd-s3);
  background: var(--hd-surface-sunken);
  border-bottom: 1px solid var(--hd-border);
  font-size: var(--hd-text-2xs);
  font-weight: var(--hd-weight-semibold);
  letter-spacing: var(--hd-tracking-caps);
  text-transform: uppercase;
  color: var(--hd-ink-muted);
  text-align: left;
  white-space: nowrap;
}

.hd-table tbody td {
  padding: var(--hd-s3);
  border-bottom: 1px solid var(--hd-border-faint);
  color: var(--hd-ink-secondary);
  vertical-align: middle;
}
.hd-table tbody tr:last-child td { border-bottom: 0; }

/* Zebra is subtle by design: at density, heavy striping fights the chips. */
.hd-table tbody tr:nth-child(even) td { background: var(--hd-surface-sunken); }

.hd-table tbody tr.hd-table__row--clickable { cursor: pointer; }
.hd-table tbody tr.hd-table__row--clickable:hover td { background: var(--hd-surface-hover); }
.hd-table tbody tr.hd-table__row--clickable:focus-visible {
  outline: 2px solid var(--hd-focus);
  outline-offset: -2px;
}

.hd-table__cell--num,
.hd-table th.hd-table__cell--num { text-align: right; }
.hd-table__cell--center,
.hd-table th.hd-table__cell--center { text-align: center; }

.hd-table--dense tbody td { padding: 5px var(--hd-s2); }
.hd-table--dense thead th { padding: var(--hd-s1) var(--hd-s2); }

.hd-table__key {
  font-weight: var(--hd-weight-medium);
  color: var(--hd-ink);
}
.hd-table__empty {
  padding: 0 !important;
  background: transparent !important;
}

/* Column of primary identifiers (ticket numbers) stays put while the wide
   metric columns scroll on a phone. */
.hd-table--pin-first tbody td:first-child,
.hd-table--pin-first thead th:first-child {
  position: sticky;
  left: 0;
  z-index: var(--hd-z-raised);
  background: var(--hd-surface);
  border-right: 1px solid var(--hd-border-faint);
}
.hd-table--pin-first thead th:first-child {
  z-index: calc(var(--hd-z-raised) + 1);
  background: var(--hd-surface-sunken);
}


/* ============================================================================
   10. BUTTONS
   ========================================================================== */
.hd-btn {
  --hd-btn-h: 34px;
  --hd-btn-px: var(--hd-s3);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--hd-s2);
  height: var(--hd-btn-h);
  padding: 0 var(--hd-btn-px);
  border: 1px solid transparent;
  border-radius: var(--hd-r-md);
  background: transparent;
  font-family: inherit;
  font-size: var(--hd-text-sm);
  font-weight: var(--hd-weight-medium);
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  position: relative;
  transition: background var(--hd-t-fast) var(--hd-ease),
    border-color var(--hd-t-fast) var(--hd-ease), color var(--hd-t-fast) var(--hd-ease),
    box-shadow var(--hd-t-fast) var(--hd-ease);
}
.hd-btn > svg { flex: 0 0 auto; }

.hd-btn:disabled,
.hd-btn[aria-disabled='true'] {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}

/* --- tones ---------------------------------------------------------------*/
.hd-btn--primary {
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--hd-brand) 88%, #ffffff) 0%, var(--hd-brand) 58%);
  border-color: var(--hd-brand);
  color: var(--hd-brand-contrast);
  box-shadow: 0 1px 2px color-mix(in srgb, var(--hd-brand) 40%, transparent),
    var(--hd-shadow-xs);
}
.hd-btn--primary:hover {
  background: var(--hd-brand-hover);
  border-color: var(--hd-brand-hover);
  box-shadow: 0 4px 12px -2px color-mix(in srgb, var(--hd-brand) 45%, transparent);
  transform: translateY(-1px);
}
.hd-btn--primary:active { background: var(--hd-brand-active); border-color: var(--hd-brand-active); transform: none; }

.hd-btn--secondary {
  background: var(--hd-surface);
  border-color: var(--hd-border-strong);
  color: var(--hd-ink);
  box-shadow: var(--hd-shadow-xs);
}
.hd-btn--secondary:hover { background: var(--hd-surface-hover); }
.hd-btn--secondary:active { background: var(--hd-surface-active); }

.hd-btn--ghost {
  background: transparent;
  border-color: transparent;
  color: var(--hd-ink-secondary);
}
.hd-btn--ghost:hover { background: var(--hd-surface-hover); color: var(--hd-ink); }
.hd-btn--ghost:active { background: var(--hd-surface-active); }

.hd-btn--danger {
  background: var(--hd-danger);
  border-color: var(--hd-danger);
  color: #ffffff;
  box-shadow: var(--hd-shadow-xs);
}
:root[data-theme='dark'] .hd-btn--danger { color: #2a0f0c; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .hd-btn--danger { color: #2a0f0c; }
}
.hd-btn--danger:hover { filter: brightness(1.08); }

.hd-btn--ok {
  background: var(--hd-ok);
  border-color: var(--hd-ok);
  color: #ffffff;
  box-shadow: var(--hd-shadow-xs);
}
:root[data-theme='dark'] .hd-btn--ok { color: #072016; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .hd-btn--ok { color: #072016; }
}
.hd-btn--ok:hover { filter: brightness(1.08); }

.hd-btn--soft {
  background: var(--hd-brand-soft);
  border-color: var(--hd-brand-soft-border);
  color: var(--hd-brand-ink);
}
.hd-btn--soft:hover { filter: brightness(0.97); }

/* --- sizes ---------------------------------------------------------------*/
.hd-btn--xs { --hd-btn-h: 26px; --hd-btn-px: var(--hd-s2); font-size: var(--hd-text-xs); }
.hd-btn--sm { --hd-btn-h: 30px; --hd-btn-px: 10px; font-size: var(--hd-text-xs); }
.hd-btn--md { --hd-btn-h: 34px; }
.hd-btn--lg { --hd-btn-h: var(--hd-tap-min); --hd-btn-px: var(--hd-s5); font-size: var(--hd-text-base); }
/* Field size: reachable and hittable with a thumb while holding a laptop bag. */
.hd-btn--xl {
  --hd-btn-h: var(--hd-tap-lg);
  --hd-btn-px: var(--hd-s6);
  font-size: var(--hd-text-md);
  font-weight: var(--hd-weight-semibold);
  border-radius: var(--hd-r-lg);
}

.hd-btn--block { width: 100%; }
.hd-btn--icon { --hd-btn-px: 0; width: var(--hd-btn-h); }

.hd-btn--busy { color: transparent !important; pointer-events: none; }
.hd-btn--busy::after {
  content: '';
  position: absolute;
  inset: 0;
  margin: auto;
  width: 15px;
  height: 15px;
  border: 2px solid currentColor;
  border-radius: 50%;
  border-top-color: transparent;
  color: var(--hd-ink);
  animation: hd-spin 620ms linear infinite;
}
.hd-btn--primary.hd-btn--busy::after,
.hd-btn--danger.hd-btn--busy::after,
.hd-btn--ok.hd-btn--busy::after { color: var(--hd-brand-contrast); }

@keyframes hd-spin { to { transform: rotate(360deg); } }

.hd-btn-group {
  display: inline-flex;
  align-items: center;
  gap: var(--hd-s2);
}


/* ============================================================================
   11. FORMS & INPUTS
   ========================================================================== */
.hd-field {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-width: 0;
}

.hd-field__label {
  display: flex;
  align-items: center;
  gap: var(--hd-s1);
  font-size: var(--hd-text-sm);
  font-weight: var(--hd-weight-medium);
  color: var(--hd-ink);
}
.hd-field__req {
  color: var(--hd-danger-ink);
  font-weight: var(--hd-weight-bold);
}
.hd-field__hint {
  font-size: var(--hd-text-xs);
  color: var(--hd-ink-muted);
  line-height: var(--hd-leading-snug);
}
.hd-field__error {
  display: flex;
  align-items: center;
  gap: var(--hd-s1);
  font-size: var(--hd-text-xs);
  font-weight: var(--hd-weight-medium);
  color: var(--hd-danger-ink);
}

.hd-fieldset {
  border: 1px solid var(--hd-border);
  border-radius: var(--hd-r-lg);
  padding: var(--hd-s4);
  margin: 0;
  min-width: 0;
}
.hd-fieldset > legend {
  padding: 0 var(--hd-s2);
  font-size: var(--hd-text-2xs);
  font-weight: var(--hd-weight-semibold);
  letter-spacing: var(--hd-tracking-caps);
  text-transform: uppercase;
  color: var(--hd-ink-muted);
}

/* Form rows: label/control pairs that collapse to stacked on narrow screens. */
.hd-form-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--hd-s4);
  align-items: start;
}
.hd-form-row--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.hd-form-row--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 640px) {
  .hd-form-row,
  .hd-form-row--2,
  .hd-form-row--3 { grid-template-columns: minmax(0, 1fr); }
}

.hd-input,
.hd-select,
.hd-textarea {
  width: 100%;
  min-height: 34px;
  padding: 7px var(--hd-s3);
  border: 1px solid var(--hd-border-strong);
  border-radius: var(--hd-r-md);
  background: var(--hd-surface);
  color: var(--hd-ink);
  font-family: inherit;
  font-size: var(--hd-text-base);
  line-height: var(--hd-leading-snug);
  transition: border-color var(--hd-t-fast) var(--hd-ease),
    box-shadow var(--hd-t-fast) var(--hd-ease);
}
/* Placeholders are text, so they take --hd-ink-muted (AA), not the decorative
   faint token — a placeholder nobody can read is a broken form. */
.hd-input::placeholder,
.hd-textarea::placeholder { color: var(--hd-ink-muted); }

.hd-input:hover,
.hd-select:hover,
.hd-textarea:hover { border-color: var(--hd-ink-faint); }

.hd-input:focus,
.hd-select:focus,
.hd-textarea:focus {
  outline: none;
  border-color: var(--hd-focus);
  box-shadow: 0 0 0 3px var(--hd-focus-halo);
}

.hd-input:disabled,
.hd-select:disabled,
.hd-textarea:disabled {
  background: var(--hd-surface-sunken);
  color: var(--hd-ink-muted);
  cursor: not-allowed;
}

.hd-input[aria-invalid='true'],
.hd-select[aria-invalid='true'],
.hd-textarea[aria-invalid='true'] { border-color: var(--hd-danger); }
.hd-input[aria-invalid='true']:focus,
.hd-textarea[aria-invalid='true']:focus {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--hd-danger) 25%, transparent);
}

/* Native select arrow varies wildly across platforms; draw our own. */
.hd-select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: var(--hd-s8);
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 17px) 50%, calc(100% - 12px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  cursor: pointer;
}

.hd-textarea {
  min-height: 80px;
  resize: vertical;
  line-height: var(--hd-leading-normal);
}
.hd-textarea--autosize { resize: none; overflow: hidden; }

/* Touch sizing for the field forms — 16px prevents iOS zoom-on-focus. */
.hd-input--lg,
.hd-select--lg,
.hd-textarea--lg {
  min-height: var(--hd-tap-min);
  font-size: 16px;
  padding: 10px var(--hd-s3);
  border-radius: var(--hd-r-lg);
}
@media (max-width: 720px) {
  .hd-input,
  .hd-select,
  .hd-textarea { font-size: 16px; min-height: var(--hd-tap-min); }
}

/* --- input adornments -----------------------------------------------------*/
.hd-input-wrap {
  position: relative;
  display: flex;
  align-items: center;
  min-width: 0;
}
.hd-input-wrap__icon {
  position: absolute;
  left: 10px;
  display: grid;
  place-items: center;
  color: var(--hd-ink-faint);
  pointer-events: none;
}
.hd-input-wrap__icon + .hd-input { padding-left: 34px; }

/* --- checkbox & radio -----------------------------------------------------*/
.hd-check {
  display: inline-flex;
  align-items: flex-start;
  gap: var(--hd-s2);
  cursor: pointer;
  font-size: var(--hd-text-base);
  color: var(--hd-ink);
  line-height: var(--hd-leading-snug);
  min-height: 22px;
}
.hd-check input[type='checkbox'],
.hd-check input[type='radio'] {
  appearance: none;
  -webkit-appearance: none;
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin: 1px 0 0;
  border: 1.5px solid var(--hd-border-strong);
  background: var(--hd-surface);
  cursor: pointer;
  transition: background var(--hd-t-fast) var(--hd-ease),
    border-color var(--hd-t-fast) var(--hd-ease);
}
.hd-check input[type='checkbox'] { border-radius: var(--hd-r-xs); }
.hd-check input[type='radio'] { border-radius: 50%; }

.hd-check input:hover { border-color: var(--hd-ink-faint); }
.hd-check input:checked {
  background: var(--hd-brand);
  border-color: var(--hd-brand);
}
.hd-check input[type='checkbox']:checked {
  /* tick drawn with a rotated pseudo-border so no image asset is needed */
  background-image: linear-gradient(var(--hd-brand), var(--hd-brand));
  position: relative;
}
.hd-check input[type='checkbox']:checked::after {
  content: '';
  position: absolute;
  left: 5px;
  top: 1px;
  width: 5px;
  height: 10px;
  border: solid var(--hd-brand-contrast);
  border-width: 0 2px 2px 0;
  transform: rotate(43deg);
}
.hd-check input[type='radio']:checked {
  position: relative;
  background: var(--hd-surface);
}
.hd-check input[type='radio']:checked::after {
  content: '';
  position: absolute;
  inset: 3px;
  border-radius: 50%;
  background: var(--hd-brand);
}
.hd-check input:disabled { opacity: 0.5; cursor: not-allowed; }
.hd-check--lg { min-height: var(--hd-tap-min); align-items: center; }
.hd-check--lg input { width: 24px; height: 24px; }
.hd-check--lg input[type='checkbox']:checked::after {
  left: 7px; top: 2px; width: 7px; height: 13px;
}

/* --- switch ---------------------------------------------------------------*/
.hd-switch {
  display: inline-flex;
  align-items: center;
  gap: var(--hd-s2);
  cursor: pointer;
}
.hd-switch input {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  width: 36px;
  height: 20px;
  border-radius: var(--hd-r-full);
  background: var(--hd-border-strong);
  cursor: pointer;
  transition: background var(--hd-t-fast) var(--hd-ease);
}
.hd-switch input::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #fff;
  box-shadow: var(--hd-shadow-xs);
  transition: transform var(--hd-t-fast) var(--hd-ease);
}
.hd-switch input:checked { background: var(--hd-brand); }
.hd-switch input:checked::after { transform: translateX(16px); }


/* ============================================================================
   12. CHIPS, BADGES, PILLS
   Chips always carry text; colour is reinforcement, never the sole signal.
   ========================================================================== */
.hd-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 21px;
  padding: 0 8px;
  border: 1px solid var(--hd-neutral-border);
  border-radius: var(--hd-r-full);
  background: var(--hd-neutral-soft);
  color: var(--hd-neutral-ink);
  font-size: var(--hd-text-xs);
  font-weight: var(--hd-weight-medium);
  line-height: 1;
  white-space: nowrap;
  max-width: 100%;
}
.hd-chip > svg { flex: 0 0 auto; width: 13px; height: 13px; }
.hd-chip__text { overflow: hidden; text-overflow: ellipsis; }

.hd-chip--ok { background: var(--hd-ok-soft); border-color: var(--hd-ok-border); color: var(--hd-ok-ink); }
.hd-chip--warn { background: var(--hd-warn-soft); border-color: var(--hd-warn-border); color: var(--hd-warn-ink); }
.hd-chip--danger { background: var(--hd-danger-soft); border-color: var(--hd-danger-border); color: var(--hd-danger-ink); }
.hd-chip--info { background: var(--hd-info-soft); border-color: var(--hd-info-border); color: var(--hd-info-ink); }
.hd-chip--brand { background: var(--hd-brand-soft); border-color: var(--hd-brand-soft-border); color: var(--hd-brand-ink); }
.hd-chip--positive { background: var(--hd-positive-soft); border-color: var(--hd-positive-border); color: var(--hd-positive-ink); }
.hd-chip--neutral { background: var(--hd-neutral-soft); border-color: var(--hd-neutral-border); color: var(--hd-neutral-ink); }

.hd-chip--solid-danger { background: var(--hd-danger); border-color: var(--hd-danger); color: #fff; }
.hd-chip--lg { height: 26px; padding: 0 11px; font-size: var(--hd-text-sm); }
.hd-chip--square { border-radius: var(--hd-r-sm); }
.hd-chip--num { font-variant-numeric: tabular-nums; }

/* A breached SLA must be findable at a glance across a dense board. */
.hd-chip--pulse { animation: hd-pulse 2.4s var(--hd-ease) infinite; }
@keyframes hd-pulse {
  0%, 100% { box-shadow: 0 0 0 0 transparent; }
  50% { box-shadow: 0 0 0 4px color-mix(in srgb, var(--hd-danger) 22%, transparent); }
}

/* Priority chips: P1 is the only one that shouts. */
.hd-prio {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 26px;
  height: 20px;
  padding: 0 6px;
  border-radius: var(--hd-r-xs);
  font-size: var(--hd-text-xs);
  font-weight: var(--hd-weight-bold);
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
  border: 1px solid transparent;
}
.hd-prio--p1 { background: var(--hd-danger); border-color: var(--hd-danger); color: #fff; }
:root[data-theme='dark'] .hd-prio--p1 { color: #2a0f0c; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .hd-prio--p1 { color: #2a0f0c; }
}
.hd-prio--p2 { background: var(--hd-warn-soft); border-color: var(--hd-warn-border); color: var(--hd-warn-ink); }
.hd-prio--p3 { background: var(--hd-info-soft); border-color: var(--hd-info-border); color: var(--hd-info-ink); }
.hd-prio--p4 { background: var(--hd-neutral-soft); border-color: var(--hd-neutral-border); color: var(--hd-neutral-ink); }

/* Presence dot: on-site / idle / offline in the live field view. */
.hd-dot {
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--hd-neutral);
  display: inline-block;
}
.hd-dot--ok { background: var(--hd-ok); }
.hd-dot--warn { background: var(--hd-warn); }
.hd-dot--danger { background: var(--hd-danger); }
.hd-dot--brand { background: var(--hd-brand); }
.hd-dot--idle { background: transparent; box-shadow: inset 0 0 0 1.5px var(--hd-ink-faint); }
.hd-dot--live { position: relative; }
.hd-dot--live::after {
  content: '';
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  border: 1.5px solid currentColor;
  color: inherit;
  opacity: 0.35;
  animation: hd-ping 2s var(--hd-ease-out) infinite;
}
@keyframes hd-ping {
  0% { transform: scale(0.6); opacity: 0.6; }
  70%, 100% { transform: scale(1.25); opacity: 0; }
}

/* Count badge on nav items / card titles. */
.hd-badge {
  display: inline-grid;
  place-items: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: var(--hd-r-full);
  background: var(--hd-danger);
  color: #fff;
  font-size: var(--hd-text-2xs);
  font-weight: var(--hd-weight-bold);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.hd-badge--neutral { background: var(--hd-neutral-soft); color: var(--hd-neutral-ink); }
.hd-badge--brand { background: var(--hd-brand); color: var(--hd-brand-contrast); }


/* ============================================================================
   13. TABS & SEGMENTED CONTROL
   ========================================================================== */
.hd-tabs {
  display: flex;
  align-items: center;
  gap: var(--hd-s1);
  border-bottom: 1px solid var(--hd-border);
  overflow-x: auto;
  scrollbar-width: none;
}
.hd-tabs::-webkit-scrollbar { display: none; }

.hd-tabs__tab {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--hd-s2);
  height: 36px;
  padding: 0 var(--hd-s3);
  border: 0;
  background: transparent;
  font-family: inherit;
  font-size: var(--hd-text-sm);
  font-weight: var(--hd-weight-medium);
  color: var(--hd-ink-muted);
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--hd-t-fast) var(--hd-ease);
}
.hd-tabs__tab::after {
  content: '';
  position: absolute;
  left: var(--hd-s2);
  right: var(--hd-s2);
  bottom: -1px;
  height: 2px;
  border-radius: 2px 2px 0 0;
  background: transparent;
  transition: background var(--hd-t-fast) var(--hd-ease);
}
.hd-tabs__tab:hover { color: var(--hd-ink); }
.hd-tabs__tab[aria-selected='true'] { color: var(--hd-ink); font-weight: var(--hd-weight-semibold); }
.hd-tabs__tab[aria-selected='true']::after { background: var(--hd-brand); }

.hd-segmented {
  display: inline-flex;
  padding: 2px;
  border: 1px solid var(--hd-border);
  border-radius: var(--hd-r-md);
  background: var(--hd-surface-sunken);
  gap: 2px;
}
.hd-segmented__opt {
  border: 0;
  background: transparent;
  padding: 0 var(--hd-s3);
  height: 28px;
  border-radius: var(--hd-r-sm);
  font-family: inherit;
  font-size: var(--hd-text-xs);
  font-weight: var(--hd-weight-medium);
  color: var(--hd-ink-muted);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--hd-t-fast) var(--hd-ease),
    color var(--hd-t-fast) var(--hd-ease), box-shadow var(--hd-t-fast) var(--hd-ease);
}
.hd-segmented__opt:hover { color: var(--hd-ink); }
.hd-segmented__opt[aria-pressed='true'] {
  background: var(--hd-surface);
  color: var(--hd-ink);
  font-weight: var(--hd-weight-semibold);
  box-shadow: var(--hd-shadow-xs);
}
.hd-segmented--lg .hd-segmented__opt { height: var(--hd-tap-min); padding: 0 var(--hd-s4); font-size: var(--hd-text-base); }
.hd-segmented--block { display: flex; }
.hd-segmented--block .hd-segmented__opt { flex: 1 1 0; }


/* ============================================================================
   14. MODAL & DRAWER
   ========================================================================== */
.hd-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--hd-z-modal);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--hd-s4);
  background: var(--hd-overlay);
  animation: hd-fade var(--hd-t-fast) var(--hd-ease);
}
@keyframes hd-fade { from { opacity: 0; } }

.hd-modal {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 520px;
  max-height: min(88vh, 780px);
  background: var(--hd-surface-raised);
  border: 1px solid var(--hd-border);
  border-radius: var(--hd-r-xl);
  box-shadow: var(--hd-shadow-xl);
  overflow: hidden;
  animation: hd-modal-in var(--hd-t-med) var(--hd-ease);
}
@keyframes hd-modal-in {
  from { opacity: 0; transform: translateY(8px) scale(0.985); }
}
.hd-modal--sm { max-width: 400px; }
.hd-modal--md { max-width: 520px; }
.hd-modal--lg { max-width: 760px; }
.hd-modal--xl { max-width: 1040px; }

.hd-modal__head {
  display: flex;
  align-items: center;
  gap: var(--hd-s3);
  padding: var(--hd-s4);
  border-bottom: 1px solid var(--hd-border-faint);
}
.hd-modal__title {
  font-size: var(--hd-text-md);
  font-weight: var(--hd-weight-semibold);
  color: var(--hd-ink);
  min-width: 0;
}
.hd-modal__close { margin-left: auto; flex: 0 0 auto; }
.hd-modal__body {
  padding: var(--hd-s4);
  overflow-y: auto;
  flex: 1 1 auto;
  color: var(--hd-ink-secondary);
}
.hd-modal__foot {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--hd-s2);
  padding: var(--hd-s3) var(--hd-s4);
  border-top: 1px solid var(--hd-border-faint);
  background: var(--hd-surface-sunken);
}

/* On a phone a modal becomes a bottom sheet: thumb-reachable actions. */
@media (max-width: 600px) {
  .hd-overlay { align-items: flex-end; padding: 0; }
  .hd-modal {
    max-width: none;
    max-height: 92vh;
    border-radius: var(--hd-r-xl) var(--hd-r-xl) 0 0;
    padding-bottom: env(safe-area-inset-bottom, 0);
    animation: hd-sheet-in var(--hd-t-med) var(--hd-ease);
  }
  @keyframes hd-sheet-in { from { transform: translateY(100%); } }
  .hd-modal__foot { flex-direction: column-reverse; }
  .hd-modal__foot > .hd-btn { width: 100%; height: var(--hd-tap-min); }
}

/* --- drawer ---------------------------------------------------------------*/
.hd-overlay--drawer { align-items: stretch; justify-content: flex-end; padding: 0; }

.hd-drawer {
  display: flex;
  flex-direction: column;
  width: min(520px, 100%);
  height: 100%;
  background: var(--hd-surface-raised);
  border-left: 1px solid var(--hd-border);
  box-shadow: var(--hd-shadow-xl);
  animation: hd-drawer-in var(--hd-t-med) var(--hd-ease);
}
@keyframes hd-drawer-in { from { transform: translateX(24px); opacity: 0; } }
.hd-drawer--sm { width: min(400px, 100%); }
.hd-drawer--lg { width: min(760px, 100%); }
.hd-drawer--left { border-left: 0; border-right: 1px solid var(--hd-border); }
.hd-overlay--drawer-left { justify-content: flex-start; }

/* Drawers reuse the modal head/body/foot parts so both share one API. */
.hd-drawer .hd-modal__head,
.hd-drawer .hd-modal__body,
.hd-drawer .hd-modal__foot { flex-shrink: 0; }
.hd-drawer .hd-modal__body { flex: 1 1 auto; }

@media (max-width: 600px) {
  .hd-drawer { width: 100%; animation: hd-sheet-in var(--hd-t-med) var(--hd-ease); }
}


/* ============================================================================
   15. TOAST & TOOLTIP
   ========================================================================== */
.hd-toast-layer {
  position: fixed;
  z-index: var(--hd-z-toast);
  right: var(--hd-s4);
  bottom: var(--hd-s4);
  display: flex;
  flex-direction: column;
  gap: var(--hd-s2);
  align-items: flex-end;
  pointer-events: none;
  max-width: min(400px, calc(100vw - var(--hd-s8)));
}

.hd-toast {
  pointer-events: auto;
  display: flex;
  align-items: flex-start;
  gap: var(--hd-s2);
  padding: 10px var(--hd-s3);
  border: 1px solid var(--hd-border);
  border-radius: var(--hd-r-md);
  background: var(--hd-surface-raised);
  box-shadow: var(--hd-shadow-lg);
  font-size: var(--hd-text-sm);
  color: var(--hd-ink);
  animation: hd-toast-in var(--hd-t-med) var(--hd-ease);
}
@keyframes hd-toast-in { from { opacity: 0; transform: translateY(8px); } }
.hd-toast--out { animation: hd-toast-out var(--hd-t-med) var(--hd-ease) forwards; }
@keyframes hd-toast-out { to { opacity: 0; transform: translateY(4px); } }

.hd-toast__icon { flex: 0 0 auto; margin-top: 1px; }
.hd-toast__text { flex: 1 1 auto; min-width: 0; }
.hd-toast--ok { border-color: var(--hd-ok-border); }
.hd-toast--ok .hd-toast__icon { color: var(--hd-ok-ink); }
.hd-toast--warn { border-color: var(--hd-warn-border); }
.hd-toast--warn .hd-toast__icon { color: var(--hd-warn-ink); }
.hd-toast--danger { border-color: var(--hd-danger-border); }
.hd-toast--danger .hd-toast__icon { color: var(--hd-danger-ink); }
.hd-toast--info .hd-toast__icon { color: var(--hd-info-ink); }

@media (max-width: 600px) {
  /* Bottom-right collides with the sticky action bar's thumb zone on mobile. */
  .hd-toast-layer {
    right: var(--hd-s3);
    left: var(--hd-s3);
    bottom: auto;
    top: calc(var(--hd-nav-h) + env(safe-area-inset-top, 0px) + var(--hd-s2));
    align-items: stretch;
    max-width: none;
  }
}

/* --- tooltip --------------------------------------------------------------*/
.hd-tip {
  position: relative;
  display: inline-flex;
}
.hd-tip__bubble {
  position: absolute;
  z-index: var(--hd-z-tooltip);
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  padding: 5px 9px;
  border-radius: var(--hd-r-sm);
  background: var(--hd-ink);
  color: var(--hd-ink-inverse);
  font-size: var(--hd-text-xs);
  font-weight: var(--hd-weight-medium);
  line-height: 1.35;
  white-space: nowrap;
  max-width: 260px;
  box-shadow: var(--hd-shadow-md);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--hd-t-fast) var(--hd-ease), visibility var(--hd-t-fast);
}
.hd-tip:hover .hd-tip__bubble,
.hd-tip:focus-within .hd-tip__bubble { opacity: 1; visibility: visible; }
.hd-tip__bubble--wrap { white-space: normal; width: max-content; }


/* ============================================================================
   16. PROGRESS RING & SPARKLINE
   ========================================================================== */
.hd-ring {
  display: inline-grid;
  place-items: center;
  position: relative;
  flex: 0 0 auto;
}
.hd-ring > svg { transform: rotate(-90deg); }
.hd-ring__track { stroke: var(--hd-border); }
.hd-ring__fill {
  stroke: var(--hd-brand);
  stroke-linecap: round;
  transition: stroke-dashoffset var(--hd-t-slow) var(--hd-ease);
}
.hd-ring--ok .hd-ring__fill { stroke: var(--hd-ok); }
.hd-ring--warn .hd-ring__fill { stroke: var(--hd-warn); }
.hd-ring--danger .hd-ring__fill { stroke: var(--hd-danger); }
.hd-ring--brand .hd-ring__fill { stroke: var(--hd-brand); }
.hd-ring--neutral .hd-ring__fill { stroke: var(--hd-neutral); }
.hd-ring__label {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: var(--hd-text-xs);
  font-weight: var(--hd-weight-semibold);
  font-variant-numeric: tabular-nums;
  color: var(--hd-ink);
  line-height: 1;
  text-align: center;
}

.hd-spark {
  display: inline-block;
  vertical-align: middle;
  line-height: 0;
}
.hd-spark__line { fill: none; stroke: var(--hd-viz-1); stroke-width: 1.5; stroke-linejoin: round; stroke-linecap: round; }
.hd-spark__area { fill: var(--hd-viz-1); opacity: 0.12; stroke: none; }
.hd-spark__last { fill: var(--hd-viz-1); }
.hd-spark--ok .hd-spark__line, .hd-spark--ok .hd-spark__last { stroke: var(--hd-ok); fill: var(--hd-ok); }
.hd-spark--ok .hd-spark__line { fill: none; }
.hd-spark--ok .hd-spark__area { fill: var(--hd-ok); }
.hd-spark--warn .hd-spark__line, .hd-spark--warn .hd-spark__last { stroke: var(--hd-warn); fill: var(--hd-warn); }
.hd-spark--warn .hd-spark__line { fill: none; }
.hd-spark--warn .hd-spark__area { fill: var(--hd-warn); }
.hd-spark--danger .hd-spark__line, .hd-spark--danger .hd-spark__last { stroke: var(--hd-danger); fill: var(--hd-danger); }
.hd-spark--danger .hd-spark__line { fill: none; }
.hd-spark--danger .hd-spark__area { fill: var(--hd-danger); }
.hd-spark--neutral .hd-spark__line, .hd-spark--neutral .hd-spark__last { stroke: var(--hd-ink-muted); fill: var(--hd-ink-muted); }
.hd-spark--neutral .hd-spark__line { fill: none; }
.hd-spark--neutral .hd-spark__area { fill: var(--hd-ink-muted); }

/* Horizontal meter for reconciliation ("14 scheduled ▸ 9 done"). */
.hd-meter {
  display: flex;
  height: 6px;
  border-radius: var(--hd-r-full);
  overflow: hidden;
  background: var(--hd-surface-sunken);
}
.hd-meter__seg { height: 100%; }
.hd-meter__seg--ok { background: var(--hd-ok); }
.hd-meter__seg--warn { background: var(--hd-warn); }
.hd-meter__seg--danger { background: var(--hd-danger); }
.hd-meter__seg--positive { background: var(--hd-positive); }
.hd-meter__seg--neutral { background: var(--hd-border-strong); }


/* ============================================================================
   17. EMPTY STATES & SKELETONS
   Plan §14.0: empty states are designed ("No tickets at risk — all clocks
   green"), never a blank div.
   ========================================================================== */
.hd-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--hd-s2);
  padding: var(--hd-s8) var(--hd-s4);
  text-align: center;
}
.hd-empty__icon {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin-bottom: var(--hd-s1);
  border-radius: var(--hd-r-full);
  background: var(--hd-surface-sunken);
  color: var(--hd-ink-faint);
}
.hd-empty__title {
  font-size: var(--hd-text-md);
  font-weight: var(--hd-weight-semibold);
  color: var(--hd-ink);
}
.hd-empty__body {
  font-size: var(--hd-text-sm);
  color: var(--hd-ink-muted);
  max-width: 44ch;
  line-height: var(--hd-leading-normal);
}
.hd-empty--sm { padding: var(--hd-s5) var(--hd-s4); }
.hd-empty--ok .hd-empty__icon { background: var(--hd-ok-soft); color: var(--hd-ok-ink); }

.hd-skeleton {
  display: flex;
  flex-direction: column;
  gap: var(--hd-s2);
}
.hd-skeleton__bar {
  height: 12px;
  border-radius: var(--hd-r-xs);
  background: linear-gradient(
    90deg,
    var(--hd-surface-sunken) 0%,
    var(--hd-surface-active) 50%,
    var(--hd-surface-sunken) 100%
  );
  background-size: 200% 100%;
  animation: hd-shimmer 1.4s linear infinite;
}
@keyframes hd-shimmer { to { background-position: -200% 0; } }


/* ============================================================================
   18. AVATAR
   ========================================================================== */
.hd-avatar {
  display: inline-grid;
  place-items: center;
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: hsl(var(--hd-avatar-h, 214) var(--hd-avatar-s) var(--hd-avatar-l-bg));
  color: hsl(var(--hd-avatar-h, 214) calc(var(--hd-avatar-s) + 10%) var(--hd-avatar-l-fg));
  font-size: var(--hd-text-xs);
  font-weight: var(--hd-weight-semibold);
  letter-spacing: 0.01em;
  line-height: 1;
  user-select: none;
  border: 1px solid transparent;
}
.hd-avatar--xs { width: 20px; height: 20px; font-size: var(--hd-text-2xs); }
.hd-avatar--sm { width: 24px; height: 24px; font-size: var(--hd-text-2xs); }
.hd-avatar--md { width: 28px; height: 28px; }
.hd-avatar--lg { width: 36px; height: 36px; font-size: var(--hd-text-sm); }
.hd-avatar--xl { width: 48px; height: 48px; font-size: var(--hd-text-md); }

.hd-avatar-group { display: inline-flex; }
.hd-avatar-group > .hd-avatar { margin-left: -7px; border-color: var(--hd-surface); }
.hd-avatar-group > .hd-avatar:first-child { margin-left: 0; }


/* ============================================================================
   19. PIN PAD & PHOTO INPUT
   ========================================================================== */
.hd-pinpad {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--hd-s5);
  width: 100%;
  max-width: 300px;
  margin-inline: auto;
}

.hd-pinpad__dots {
  display: flex;
  gap: var(--hd-s3);
}
.hd-pinpad__dot {
  width: 13px;
  height: 13px;
  border-radius: 50%;
  border: 1.5px solid var(--hd-border-strong);
  background: transparent;
  transition: background var(--hd-t-fast) var(--hd-ease),
    border-color var(--hd-t-fast) var(--hd-ease), transform var(--hd-t-fast) var(--hd-ease);
}
.hd-pinpad__dot--filled {
  background: var(--hd-brand);
  border-color: var(--hd-brand);
  transform: scale(1.08);
}
.hd-pinpad--error .hd-pinpad__dot {
  border-color: var(--hd-danger);
  background: transparent;
}
.hd-pinpad--error { animation: hd-shake 320ms var(--hd-ease); }
@keyframes hd-shake {
  10%, 90% { transform: translateX(-2px); }
  30%, 70% { transform: translateX(4px); }
  50% { transform: translateX(-4px); }
}

.hd-pinpad__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--hd-s3);
  width: 100%;
}
.hd-pinpad__key {
  height: 60px;
  border: 1px solid var(--hd-border);
  border-radius: var(--hd-r-lg);
  background: var(--hd-surface);
  color: var(--hd-ink);
  font-family: inherit;
  font-size: var(--hd-text-2xl);
  font-weight: var(--hd-weight-medium);
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: background var(--hd-t-instant) var(--hd-ease),
    transform var(--hd-t-instant) var(--hd-ease);
}
.hd-pinpad__key:hover { background: var(--hd-surface-hover); }
.hd-pinpad__key:active { background: var(--hd-surface-active); transform: scale(0.97); }
.hd-pinpad__key--util {
  font-size: var(--hd-text-base);
  color: var(--hd-ink-secondary);
  background: var(--hd-surface-sunken);
}
.hd-pinpad__key:disabled { opacity: 0.4; cursor: not-allowed; }
.hd-pinpad__msg {
  font-size: var(--hd-text-sm);
  color: var(--hd-ink-muted);
  text-align: center;
  min-height: 20px;
}
.hd-pinpad__msg--error { color: var(--hd-danger-ink); font-weight: var(--hd-weight-medium); }

/* --- photo input ----------------------------------------------------------*/
.hd-photo { display: flex; flex-direction: column; gap: var(--hd-s3); }
.hd-photo__drop {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--hd-s2);
  min-height: 104px;
  padding: var(--hd-s4);
  border: 1.5px dashed var(--hd-border-strong);
  border-radius: var(--hd-r-lg);
  background: var(--hd-surface-sunken);
  color: var(--hd-ink-muted);
  font-size: var(--hd-text-sm);
  text-align: center;
  cursor: pointer;
  transition: border-color var(--hd-t-fast) var(--hd-ease),
    background var(--hd-t-fast) var(--hd-ease), color var(--hd-t-fast) var(--hd-ease);
}
.hd-photo__drop:hover,
.hd-photo__drop--over {
  border-color: var(--hd-brand);
  background: var(--hd-brand-soft);
  color: var(--hd-brand-ink);
}
.hd-photo__thumbs {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(76px, 1fr));
  gap: var(--hd-s2);
}
.hd-photo__thumb {
  position: relative;
  aspect-ratio: 1;
  border-radius: var(--hd-r-md);
  overflow: hidden;
  border: 1px solid var(--hd-border);
  background: var(--hd-surface-sunken);
}
.hd-photo__thumb img { width: 100%; height: 100%; object-fit: cover; }
.hd-photo__remove {
  position: absolute;
  top: 3px;
  right: 3px;
  width: 22px;
  height: 22px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: rgba(10, 12, 18, 0.7);
  color: #fff;
  cursor: pointer;
}


/* ============================================================================
   19b. INLINE ICONS & LIVE VALUES
   ========================================================================== */
.hd-icon {
  display: inline-block;
  flex: 0 0 auto;
  vertical-align: -0.14em;
  overflow: visible;
}
.hd-flip-y { transform: rotate(180deg); }

/* Countdown chips re-tone themselves every second; the width must not jump as
   digits change, hence tabular numerals plus a minimum inline size. */
.hd-countdown {
  font-variant-numeric: tabular-nums;
  font-weight: var(--hd-weight-semibold);
  white-space: nowrap;
}
.hd-chip .hd-countdown { font-weight: var(--hd-weight-semibold); color: inherit; }


/* ============================================================================
   20. UTILITIES
   ========================================================================== */
.hd-sr-only {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.hd-hidden { display: none !important; }
.hd-flex-1 { flex: 1 1 auto; min-width: 0; }
.hd-ml-auto { margin-left: auto; }
.hd-mt-2 { margin-top: var(--hd-s2); }
.hd-mt-4 { margin-top: var(--hd-s4); }
.hd-mb-2 { margin-bottom: var(--hd-s2); }
.hd-mb-4 { margin-bottom: var(--hd-s4); }
.hd-gap-1 { gap: var(--hd-s1); }
.hd-gap-2 { gap: var(--hd-s2); }
.hd-gap-3 { gap: var(--hd-s3); }
.hd-gap-4 { gap: var(--hd-s4); }
.hd-p-4 { padding: var(--hd-s4); }
.hd-w-full { width: 100%; }
.hd-text-right { text-align: right; }
.hd-text-center { text-align: center; }
.hd-nowrap { white-space: nowrap; }
.hd-scroll-y { overflow-y: auto; }
.hd-divider { border-top: 1px solid var(--hd-divider); }

/* Show/hide by viewport — the technician cockpit collapses aggressively. */
.hd-only-mobile { display: none !important; }
@media (max-width: 720px) {
  .hd-only-mobile { display: revert !important; }
  .hd-only-desktop { display: none !important; }
}


/* ============================================================================
   21. PRINT — ticket job-card rendition (plan §9.3)
   The printed page must read like the paper Consultant Job Card: visible
   section borders, forced backgrounds for the header grid, no app chrome.
   ========================================================================== */
@media print {
  @page {
    size: A4;
    margin: 14mm 13mm 16mm;
  }

  :root,
  :root[data-theme='dark'],
  :root[data-theme='light'] {
    /* Print always renders the light palette — dark-mode ink wastes toner and
       fails on white paper regardless of the on-screen theme. */
    --hd-bg: #ffffff;
    --hd-surface: #ffffff;
    --hd-surface-raised: #ffffff;
    --hd-surface-sunken: #f2f4f7;
    --hd-ink: #000000;
    --hd-ink-secondary: #1f2937;
    --hd-ink-muted: #4b5563;
    --hd-ink-faint: #6b7280;
    --hd-border: #9aa3b0;
    --hd-border-strong: #6b7280;
    --hd-border-faint: #c4cad3;
    --hd-divider: #9aa3b0;
    color-scheme: light;
  }

  html,
  body {
    background: #fff !important;
    color: #000 !important;
    font-size: 10.5pt;
    line-height: 1.4;
  }

  /* Chips/badges carry meaning on a signed job card — force their fills. */
  *,
  *::before,
  *::after {
    -webkit-print-color-adjust: exact !important;
    print-color-adjust: exact !important;
    box-shadow: none !important;
    text-shadow: none !important;
    animation: none !important;
    transition: none !important;
  }

  .hd-nav,
  .hd-actionbar,
  .hd-toast-layer,
  .hd-tabs,
  .hd-overlay,
  .hd-drawer,
  .hd-noprint,
  .hd-btn,
  .hd-segmented { display: none !important; }

  .hd-print-only { display: revert !important; }
  .hd-app { display: block; min-height: 0; }
  .hd-main { max-width: none; padding: 0; margin: 0; }

  /* Sections become the bordered blocks of the paper form. */
  .hd-card {
    border: 1px solid #000 !important;
    border-radius: 0;
    break-inside: avoid;
    page-break-inside: avoid;
    margin-bottom: 6mm;
  }
  .hd-card__head {
    background: var(--hd-surface-sunken) !important;
    border-bottom: 1px solid #000 !important;
    padding: 2mm 3mm;
  }
  .hd-card__title { color: #000; font-size: 8.5pt; }
  .hd-card__body { padding: 3mm; }

  .hd-table { font-size: 9.5pt; }
  .hd-table thead th {
    position: static;
    background: var(--hd-surface-sunken) !important;
    border: 1px solid #000 !important;
    color: #000;
  }
  .hd-table tbody td {
    border: 1px solid #000 !important;
    background: #fff !important;
    color: #000;
  }
  .hd-table thead { display: table-header-group; }
  .hd-table tr { break-inside: avoid; page-break-inside: avoid; }

  .hd-chip,
  .hd-prio {
    border: 1px solid #000 !important;
    border-radius: 2px;
  }

  /* Signature block: the legally interesting part, never split across pages. */
  .hd-print-sign {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 6mm;
    margin-top: 6mm;
    break-inside: avoid;
    page-break-inside: avoid;
  }
  .hd-print-sign__box {
    border: 1px solid #000;
    padding: 3mm;
    min-height: 26mm;
  }
  .hd-print-sign__label {
    font-size: 8pt;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #000;
    margin-bottom: 2mm;
  }
  .hd-print-sign__attest { font-size: 8.5pt; color: #1f2937; }

  .hd-page-break { break-before: page; page-break-before: always; }

  /* Print the destination of links so a paper job card stays traceable. */
  a[href^='http']::after {
    content: ' (' attr(href) ')';
    font-size: 8pt;
    color: #4b5563;
  }
}

/* Screen-side counterpart of the print-only helper. */
.hd-print-only { display: none; }


/* ============================================================================
   === dashboards ===
   Owner Command Centre + Technician My Day cockpit (plan §14). Everything
   else the two dashboard views need (cards, stats, tables, lists, chips,
   sparklines, the sticky action bar) already exists above; these two rules
   are the only genuinely new surface — the "NOW" hero strip that leads the
   technician cockpit (and doubles, in its quieter --idle tone, as the "next
   visit" state) and a smaller live-elapsed number reused in list rows (the
   Command Centre's Live Field View).
   ========================================================================== */
.hd-now {
  display: flex;
  flex-direction: column;
  gap: var(--hd-s1);
  padding: var(--hd-s5);
  border-radius: var(--hd-r-lg);
  border: 1px solid var(--hd-ok-border);
  background: var(--hd-ok-soft);
}
.hd-now--idle {
  border-color: var(--hd-brand-soft-border);
  background: var(--hd-brand-soft);
}
.hd-now__label {
  display: flex;
  align-items: center;
  gap: var(--hd-s2);
  font-size: var(--hd-text-2xs);
  font-weight: var(--hd-weight-semibold);
  letter-spacing: var(--hd-tracking-caps);
  text-transform: uppercase;
  color: var(--hd-ink-muted);
}
.hd-now__title {
  font-size: var(--hd-text-lg);
  font-weight: var(--hd-weight-semibold);
  color: var(--hd-ink);
}
.hd-now__meta { font-size: var(--hd-text-sm); color: var(--hd-ink-secondary); }
.hd-now__time {
  font-size: var(--hd-text-3xl);
  font-weight: var(--hd-weight-bold);
  font-variant-numeric: tabular-nums;
  color: var(--hd-ok-ink);
  line-height: var(--hd-leading-tight);
}

/* Compact live-elapsed number for list rows (Live Field View aside). */
.hd-elapsed {
  font-variant-numeric: tabular-nums;
  font-weight: var(--hd-weight-semibold);
  color: var(--hd-ok-ink);
}

/* ============================================================================
   === client portal ===
   Plan §15. A separate shell (frontend/portal.html + portal.js) from the
   staff SPA, so its own header/login/user-menu classes live here rather than
   reusing the (not-yet-styled) hd-appbar/hd-login pair app.js references —
   but layout primitives, cards, chips, buttons, forms etc. above are shared
   as-is so the two apps read as one product. Calm, plain-spoken, phone-first.
   ========================================================================== */

/* --- top bar: reuses .hd-nav/.hd-nav__* (§6) as-is; only a small size bump
   for the larger brand mark on the sign-in screen lives here. -------------- */
.hd-nav__mark--lg {
  width: 40px;
  height: 40px;
  border-radius: var(--hd-r-md);
  font-size: var(--hd-text-lg);
}

.hd-portal-usermenu { position: relative; }
.hd-portal-usermenu__btn {
  display: flex;
  align-items: center;
  border: 0;
  background: none;
  padding: 0;
  border-radius: var(--hd-r-full);
  cursor: pointer;
}
.hd-portal-usermenu__btn:focus-visible {
  outline: 2px solid var(--hd-focus);
  outline-offset: 2px;
}
.hd-portal-usermenu__panel {
  position: absolute;
  top: calc(100% + var(--hd-s2));
  right: 0;
  z-index: var(--hd-z-dropdown);
  min-width: 220px;
  display: none;
  flex-direction: column;
  padding: var(--hd-s2);
  background: var(--hd-surface-raised);
  border: 1px solid var(--hd-border);
  border-radius: var(--hd-r-lg);
  box-shadow: var(--hd-shadow-lg);
}
.hd-portal-usermenu.is-open .hd-portal-usermenu__panel { display: flex; }
.hd-portal-usermenu__head {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--hd-s2) var(--hd-s3) var(--hd-s3);
  border-bottom: 1px solid var(--hd-divider);
  margin-bottom: var(--hd-s2);
}
.hd-portal-usermenu__head strong { font-size: var(--hd-text-sm); color: var(--hd-ink); }
.hd-portal-usermenu__head span { font-size: var(--hd-text-xs); color: var(--hd-ink-muted); }
.hd-portal-usermenu__item {
  display: flex;
  align-items: center;
  gap: var(--hd-s2);
  width: 100%;
  padding: var(--hd-s2) var(--hd-s3);
  border: 0;
  background: none;
  border-radius: var(--hd-r-sm);
  font-size: var(--hd-text-sm);
  color: var(--hd-ink-secondary);
  text-align: left;
  cursor: pointer;
}
.hd-portal-usermenu__item:hover { background: var(--hd-surface-hover); color: var(--hd-ink); }

/* --- sign-in screen -------------------------------------------------------*/
.hd-portal-login {
  min-height: 100vh;
  min-height: 100dvh;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
}

/* --- left: what this is and what it is for ------------------------------- */
.hd-plogin-hero {
  position: relative;
  display: flex;
  align-items: center;
  padding: var(--hd-s12) var(--hd-s10);
  background: var(--hd-hero-bg);
  color: var(--hd-hero-ink);
  overflow: hidden;
}
.hd-plogin-hero::before,
.hd-plogin-hero::after {
  content: '';
  position: absolute;
  border-radius: 50%;
  filter: blur(72px);
  opacity: 0.45;
  pointer-events: none;
}
.hd-plogin-hero::before {
  width: 430px; height: 430px; left: -130px; top: -150px;
  background: radial-gradient(circle, rgba(78, 168, 255, 0.55), transparent 70%);
}
.hd-plogin-hero::after {
  width: 360px; height: 360px; right: -120px; bottom: -140px;
  background: radial-gradient(circle, rgba(232, 39, 28, 0.30), transparent 70%);
}
.hd-plogin-hero__inner {
  position: relative;
  z-index: 1;
  max-width: 470px;
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: var(--hd-s5);
}
.hd-plogin-hero__title {
  margin: var(--hd-s2) 0 0;
  font-size: clamp(25px, 3vw, 35px);
  font-weight: var(--hd-weight-bold);
  line-height: 1.18;
  letter-spacing: -0.02em;
}
.hd-plogin-hero__title em {
  font-style: normal;
  background: linear-gradient(90deg, #7db8ff, #23d3ee);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.hd-plogin-hero__lede {
  margin: 0;
  font-size: var(--hd-text-md);
  line-height: var(--hd-leading-normal);
  color: var(--hd-hero-ink-soft);
}
.hd-plogin-hero__points {
  list-style: none;
  margin: var(--hd-s2) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--hd-s4);
}
.hd-plogin-hero__point {
  display: flex;
  align-items: flex-start;
  gap: var(--hd-s3);
  font-size: var(--hd-text-sm);
  line-height: var(--hd-leading-normal);
  color: var(--hd-hero-ink-soft);
}
.hd-plogin-hero__point .hd-icon { color: #23d3ee; flex: none; margin-top: 2px; }
.hd-plogin-hero__point strong { color: var(--hd-hero-ink); font-weight: var(--hd-weight-semibold); }

/* --- right: the one thing they came to do -------------------------------- */
.hd-portal-login__panel {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--hd-s8) var(--hd-s6);
  background: var(--hd-bg);
}
.hd-portal-login__panel-inner {
  width: 100%;
  max-width: 420px;
  display: flex;
  flex-direction: column;
  gap: var(--hd-s5);
}

.hd-portal-login__reassure {
  display: flex;
  align-items: center;
  gap: var(--hd-s2);
  margin: var(--hd-s1) 0 0;
  font-size: var(--hd-text-xs);
  color: var(--hd-ink-muted);
}
.hd-portal-login__reassure .hd-icon { color: var(--hd-ok); flex: none; }

/* numbered "what happens next" after the link is sent */
.hd-portal-login__steps {
  margin: 0;
  padding-left: var(--hd-s5);
  display: flex;
  flex-direction: column;
  gap: var(--hd-s2);
  font-size: var(--hd-text-sm);
  line-height: var(--hd-leading-normal);
  color: var(--hd-ink-secondary);
}

@media (max-width: 900px) {
  .hd-portal-login { grid-template-columns: minmax(0, 1fr); }
  .hd-plogin-hero { display: none; }
  .hd-portal-login__panel { padding: var(--hd-s6) var(--hd-s4); min-height: 100dvh; }
}
.hd-portal-login__brand {
  display: flex;
  align-items: center;
  gap: var(--hd-s3);
}
/* The old markup here was <strong>HyperDesk</strong><span>Support portal</span>.
   It is now HD.logo(), and a bare `span` selector was repainting every part of
   the lockup muted grey — the brand colours are set by .hd-logo__* instead. */
.hd-portal-login__card {
  width: 100%;
  max-width: 400px;
  padding: var(--hd-s6);
  background: var(--hd-surface);
  border: 1px solid var(--hd-border);
  border-radius: var(--hd-r-2xl);
  box-shadow: var(--hd-shadow-md);
}
.hd-portal-login__icon {
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  margin: 0 auto;
  border-radius: var(--hd-r-full);
  background: var(--hd-brand-soft);
  color: var(--hd-brand-ink);
}
.hd-portal-login__icon--ok { background: var(--hd-ok-soft); color: var(--hd-ok-ink); }
.hd-portal-login__foot { font-size: var(--hd-text-sm); color: var(--hd-ink-muted); text-align: center; }

/* --- home hero + primary actions ------------------------------------------*/
.hd-plogin-hero { padding: var(--hd-s2) 0 0; }

.hd-portal-cta-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--hd-s3);
}
.hd-portal-cta {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--hd-s2);
  padding: var(--hd-s4);
  background: var(--hd-surface);
  border: 1px solid var(--hd-border);
  border-radius: var(--hd-r-xl);
  color: var(--hd-ink);
  text-align: left;
  cursor: pointer;
  transition: border-color var(--hd-t-fast) var(--hd-ease), transform var(--hd-t-fast) var(--hd-ease);
}
.hd-portal-cta:hover { border-color: var(--hd-brand); transform: translateY(-1px); }
.hd-portal-cta strong { display: block; font-size: var(--hd-text-md); }
.hd-portal-cta .hd-small { color: var(--hd-ink-muted); }
.hd-portal-cta--primary {
  background: var(--hd-brand-soft);
  border-color: var(--hd-brand-soft-border);
  color: var(--hd-brand-ink);
}

@media (max-width: 560px) {
  .hd-portal-cta-row { grid-template-columns: 1fr; }
}

/* --- ticket / booking / report rows ---------------------------------------*/
.hd-portal-ticket-row {
  display: flex;
  flex-direction: column;
  gap: var(--hd-s1);
  width: 100%;
  padding: var(--hd-s3);
  background: var(--hd-surface);
  border: 1px solid var(--hd-border-faint);
  border-radius: var(--hd-r-lg);
  color: inherit;
  text-align: left;
  cursor: pointer;
  transition: background var(--hd-t-fast) var(--hd-ease), border-color var(--hd-t-fast) var(--hd-ease);
}
.hd-portal-ticket-row:hover { background: var(--hd-surface-hover); border-color: var(--hd-border); }
.hd-portal-ticket-row--static { cursor: default; }
.hd-portal-ticket-row--static:hover { background: var(--hd-surface); border-color: var(--hd-border-faint); }
.hd-portal-ticket-row__top {
  display: flex;
  align-items: center;
  gap: var(--hd-s2);
  min-width: 0;
}
.hd-portal-ticket-row__title { flex: 1 1 auto; min-width: 0; font-weight: var(--hd-weight-medium); }
.hd-portal-ticket-row__bottom {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--hd-s2);
}

/* --- SLA promise panel (shown BEFORE submitting a fault) -------------------*/
.hd-portal-sla-promise {
  display: flex;
  flex-direction: column;
  gap: var(--hd-s2);
  padding: var(--hd-s4);
  background: var(--hd-brand-soft);
  border: 1px solid var(--hd-brand-soft-border);
  border-radius: var(--hd-r-lg);
  font-size: var(--hd-text-sm);
  color: var(--hd-ink);
}

/* --- generic narrow form page (raise-a-ticket, booking steps) -------------*/
.hd-portal-form-page {
  max-width: 560px;
  margin: 0 auto;
}

/* --- booking wizard ---------------------------------------------------- */
.hd-portal-step-dot {
  display: inline-grid;
  place-items: center;
  width: 26px;
  height: 26px;
  flex: 0 0 auto;
  border-radius: var(--hd-r-full);
  background: var(--hd-brand);
  color: var(--hd-brand-contrast);
  font-size: var(--hd-text-xs);
  font-weight: var(--hd-weight-bold);
}

.hd-portal-pick-list {
  display: flex;
  flex-direction: column;
  gap: var(--hd-s2);
}
.hd-portal-pick {
  display: flex;
  align-items: center;
  gap: var(--hd-s3);
  width: 100%;
  padding: var(--hd-s3) var(--hd-s4);
  background: var(--hd-surface);
  border: 1px solid var(--hd-border);
  border-radius: var(--hd-r-lg);
  text-align: left;
  color: var(--hd-ink);
  cursor: pointer;
}
.hd-portal-pick:hover { border-color: var(--hd-brand); background: var(--hd-surface-hover); }
.hd-portal-pick strong { display: block; font-size: var(--hd-text-sm); }
.hd-portal-pick .hd-small { color: var(--hd-ink-muted); }

.hd-portal-slot-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
  gap: var(--hd-s2);
  margin-top: var(--hd-s2);
}
.hd-portal-slot {
  padding: var(--hd-s2) var(--hd-s3);
  background: var(--hd-surface);
  border: 1px solid var(--hd-border);
  border-radius: var(--hd-r-md);
  font-size: var(--hd-text-sm);
  font-variant-numeric: tabular-nums;
  color: var(--hd-ink);
  cursor: pointer;
}
.hd-portal-slot:hover { border-color: var(--hd-brand); background: var(--hd-brand-soft); color: var(--hd-brand-ink); }

/* --- ticket detail: checklist + timeline -----------------------------------*/
.hd-portal-checklist-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--hd-s2) 0;
  border-bottom: 1px solid var(--hd-divider);
}
.hd-portal-checklist-item:last-child { border-bottom: 0; }

.hd-portal-timeline {
  display: flex;
  flex-direction: column;
  gap: 0;
}
.hd-portal-timeline__item {
  position: relative;
  display: flex;
  gap: var(--hd-s3);
  padding: 0 0 var(--hd-s4) var(--hd-s4);
  border-left: 2px solid var(--hd-divider);
}
.hd-portal-timeline__item:last-child { border-left-color: transparent; padding-bottom: 0; }
.hd-portal-timeline__dot {
  position: absolute;
  left: -6px;
  top: 2px;
  width: 10px;
  height: 10px;
  border-radius: var(--hd-r-full);
  background: var(--hd-brand);
  border: 2px solid var(--hd-surface);
}
.hd-portal-timeline__body { padding-top: 0; font-size: var(--hd-text-sm); color: var(--hd-ink); }

/* --- phones: everything above already collapses via the shared grid rules
   (§6); a little extra breathing room for the sticky nav's link row. ------ */
@media (max-width: 720px) {
  .hd-portal-login__card { padding: var(--hd-s5); }
}

/* ============================================================================
   === ticket forms ===
   Callout "Consultant Job Card" (§9.1) + scheduled-visit "IT Managed Services
   Checklist" (§9.2) — frontend/views/tickets.js + ticket-detail.js. A handful
   of generic primitives (.hd-page, .hd-banner, .hd-prose, .hd-form__error /
   .hd-form__ok) are defined here too: account.js already assumes their
   existence but nothing had shipped them yet, and both ticket screens lean on
   them just as much (signature warnings, validation summaries, read-only
   signed content).
   ========================================================================== */

/* --- generic page scaffold ------------------------------------------------ */
.hd-page { display: flex; flex-direction: column; gap: var(--hd-s5); }
.hd-page--narrow { max-width: 640px; }
.hd-page__head { display: flex; flex-direction: column; gap: var(--hd-s1); margin-bottom: var(--hd-s2); }
.hd-page__sub { font-size: var(--hd-text-sm); color: var(--hd-ink-secondary); }

/* --- inline banners: signature warnings, hold-reason notes, re-sign risk - */
.hd-banner {
  display: flex;
  align-items: flex-start;
  gap: var(--hd-s2);
  padding: var(--hd-s3) var(--hd-s4);
  border-radius: var(--hd-r-md);
  border: 1px solid var(--hd-border);
  background: var(--hd-surface-sunken);
  font-size: var(--hd-text-sm);
  color: var(--hd-ink-secondary);
}
.hd-banner > svg { flex: 0 0 auto; margin-top: 2px; }
.hd-banner--info { background: var(--hd-info-soft); border-color: var(--hd-info-border); color: var(--hd-info-ink); }
.hd-banner--ok { background: var(--hd-ok-soft); border-color: var(--hd-ok-border); color: var(--hd-ok-ink); }
.hd-banner--warn { background: var(--hd-warn-soft); border-color: var(--hd-warn-border); color: var(--hd-warn-ink); }
.hd-banner--danger { background: var(--hd-danger-soft); border-color: var(--hd-danger-border); color: var(--hd-danger-ink); }

/* --- read-only prose: signed solution text, locked conclusion ------------- */
.hd-prose {
  font-size: var(--hd-text-sm);
  line-height: var(--hd-leading-relaxed);
  color: var(--hd-ink);
  white-space: pre-wrap;
}

/* --- form-level messages (account.js + the new-ticket form) -------------- */
.hd-form__error {
  display: flex;
  flex-direction: column;
  gap: var(--hd-s1);
  padding: var(--hd-s3);
  border-radius: var(--hd-r-md);
  border: 1px solid var(--hd-danger-border);
  background: var(--hd-danger-soft);
  color: var(--hd-danger-ink);
  font-size: var(--hd-text-sm);
}
.hd-form__error ul { margin: 0; padding-left: var(--hd-s5); }
.hd-form__ok {
  padding: var(--hd-s3);
  border-radius: var(--hd-r-md);
  border: 1px solid var(--hd-ok-border);
  background: var(--hd-ok-soft);
  color: var(--hd-ok-ink);
  font-size: var(--hd-text-sm);
}

/* --- SLA promise, shown live once a client + fault type are chosen ------- */
.hd-sla-promise {
  display: flex;
  align-items: center;
  gap: var(--hd-s2);
  padding: var(--hd-s3) var(--hd-s4);
  border-radius: var(--hd-r-md);
  border: 1px solid var(--hd-brand-soft-border);
  background: var(--hd-brand-soft);
  color: var(--hd-brand-ink);
  font-size: var(--hd-text-sm);
  font-weight: var(--hd-weight-medium);
}

/* --- job-card header grid (§9.1): "Client Name / Incident No / Consultant /
   Incident Date / Product Name / Contact" — reads instantly like the paper. */
.hd-jobcard-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--hd-s4);
}
@media (max-width: 640px) {
  .hd-jobcard-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* --- IT Managed Services Checklist rows (§9.2) — big one-tap targets, since
   this gets filled in standing up, one-handed, in a server room. ---------- */
.hd-checklist {
  display: flex;
  flex-direction: column;
  gap: var(--hd-s4);
}
.hd-checklist__item {
  display: flex;
  flex-direction: column;
  gap: var(--hd-s2);
  padding-bottom: var(--hd-s4);
  border-bottom: 1px solid var(--hd-border-faint);
}
.hd-checklist__item:last-child { border-bottom: 0; padding-bottom: 0; }
.hd-checklist__item--critical { box-shadow: inset 3px 0 0 var(--hd-warn); padding-left: var(--hd-s3); }
.hd-checklist__label {
  display: flex;
  align-items: center;
  gap: var(--hd-s2);
  font-size: var(--hd-text-base);
  font-weight: var(--hd-weight-medium);
  color: var(--hd-ink);
}
.hd-checklist__actions {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--hd-s2);
}
.hd-checklist__actions .hd-btn { min-height: var(--hd-tap-lg); }
.hd-checklist__note-error {
  display: flex;
  align-items: center;
  gap: var(--hd-s1);
  font-size: var(--hd-text-xs);
  color: var(--hd-danger-ink);
}

/* --- sticky mobile progress header (checklist "9/11" while scrolling) ---- */
.hd-sticky-progress {
  position: sticky;
  top: calc(var(--hd-nav-h) + env(safe-area-inset-top, 0px));
  z-index: var(--hd-z-sticky);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--hd-s3);
  padding: var(--hd-s2) var(--hd-s3);
  background: var(--hd-surface);
  border: 1px solid var(--hd-border);
  border-radius: var(--hd-r-md);
  box-shadow: var(--hd-shadow-md);
}

@media (max-width: 720px) {
  .hd-checklist__actions { gap: var(--hd-s1); }
}

/* ============================================================================
   === calendar, admin & reports ===
   frontend/views/calendar.js, reconciliation.js, clients.js, reports.js,
   settings.js. Lane-per-technician week calendar, the reconciliation
   claim-vs-evidence layout, the ranked sign-off/RRULE editors on the client
   detail page, and the settings admin screens (weekday-hours grid, audit
   payload dumps). Tones reuse the existing semantic tokens only.
   ========================================================================== */

/* --- calendar: week grid, lane per technician ----------------------------- */
.hd-cal-scroll { overflow-x: auto; }

.hd-cal-grid {
  display: grid;
  grid-template-columns: minmax(112px, 152px) repeat(7, minmax(96px, 1fr));
  gap: 1px;
  background: var(--hd-border-faint);
  border: 1px solid var(--hd-border-faint);
  border-radius: var(--hd-r-md);
  overflow: hidden;
  min-width: 760px;
}

.hd-cal-corner,
.hd-cal-daycol-head,
.hd-cal-lane-head,
.hd-cal-cell {
  background: var(--hd-surface);
  padding: var(--hd-s2);
}

.hd-cal-daycol-head {
  font-size: var(--hd-text-xs);
  font-weight: var(--hd-weight-semibold);
  color: var(--hd-ink-secondary);
  text-align: center;
  position: sticky;
  top: 0;
  z-index: var(--hd-z-raised);
}
.hd-cal-daycol-head--today { color: var(--hd-brand-ink); background: var(--hd-brand-soft); }

.hd-cal-lane-head {
  display: flex;
  align-items: center;
  gap: var(--hd-s2);
  font-size: var(--hd-text-sm);
  font-weight: var(--hd-weight-medium);
  color: var(--hd-ink);
  position: sticky;
  left: 0;
  z-index: var(--hd-z-raised);
}

.hd-cal-cell {
  display: flex;
  flex-direction: column;
  gap: var(--hd-s1);
  min-height: 56px;
}

.hd-cal-chip {
  display: flex;
  align-items: baseline;
  gap: var(--hd-s1);
  width: 100%;
  border: none;
  border-radius: var(--hd-r-xs);
  padding: 3px var(--hd-s1);
  font: inherit;
  font-size: var(--hd-text-2xs);
  line-height: var(--hd-leading-snug);
  text-align: left;
  cursor: default;
  background: var(--hd-neutral-soft);
  color: var(--hd-neutral-ink);
}
.hd-cal-chip--click { cursor: pointer; }
.hd-cal-chip--click:hover { filter: brightness(0.97); }
.hd-cal-chip--dim { opacity: 0.6; text-decoration: line-through; }
.hd-cal-chip__time { font-weight: var(--hd-weight-semibold); flex: 0 0 auto; }
.hd-cal-chip__label { flex: 1 1 auto; min-width: 0; }

.hd-cal-chip--brand { background: var(--hd-brand-soft); color: var(--hd-brand-ink); }
.hd-cal-chip--info { background: var(--hd-info-soft); color: var(--hd-info-ink); }
.hd-cal-chip--ok { background: var(--hd-ok-soft); color: var(--hd-ok-ink); }
.hd-cal-chip--warn { background: var(--hd-warn-soft); color: var(--hd-warn-ink); }
.hd-cal-chip--danger { background: var(--hd-danger-soft); color: var(--hd-danger-ink); }
.hd-cal-chip--neutral { background: var(--hd-neutral-soft); color: var(--hd-neutral-ink); }

.hd-cal-chip--outline {
  background: transparent;
  border: 1.5px dashed var(--hd-warn-border);
  color: var(--hd-warn-ink);
}

.hd-cal-chip--block {
  background: repeating-linear-gradient(45deg, var(--hd-surface-sunken), var(--hd-surface-sunken) 4px,
    var(--hd-border) 4px, var(--hd-border) 8px);
  color: var(--hd-ink-secondary);
}

.hd-cal-chip--ms {
  background: repeating-linear-gradient(45deg, var(--hd-brand-soft), var(--hd-brand-soft) 4px,
    var(--hd-border-strong) 4px, var(--hd-border-strong) 8px);
  color: var(--hd-ink-secondary);
  cursor: default;
}
.hd-cal-chip--stale { outline: 1.5px dashed var(--hd-warn-border); outline-offset: -1px; }

.hd-cal-legend { flex-wrap: wrap; }
.hd-cal-legend__swatch {
  display: inline-block;
  width: 14px;
  height: 14px;
  border-radius: var(--hd-r-xs);
  vertical-align: middle;
}

.hd-cal-empty-row { grid-column: 1 / -1; padding: var(--hd-s6); }

.hd-cal-daypicker { display: none; }

@media (max-width: 720px) {
  .hd-cal-daypicker.hd-only-mobile { display: flex; }
  .hd-cal-grid { min-width: 0; grid-template-columns: minmax(96px, 120px) 1fr; }
  .hd-cal-grid[data-active-day='0'] [data-day]:not([data-day='0']) { display: none; }
  .hd-cal-grid[data-active-day='1'] [data-day]:not([data-day='1']) { display: none; }
  .hd-cal-grid[data-active-day='2'] [data-day]:not([data-day='2']) { display: none; }
  .hd-cal-grid[data-active-day='3'] [data-day]:not([data-day='3']) { display: none; }
  .hd-cal-grid[data-active-day='4'] [data-day]:not([data-day='4']) { display: none; }
  .hd-cal-grid[data-active-day='5'] [data-day]:not([data-day='5']) { display: none; }
  .hd-cal-grid[data-active-day='6'] [data-day]:not([data-day='6']) { display: none; }
}

/* --- reconciliation: reason preview + claim-vs-evidence -------------------- */
.hd-recon-reasonpreview:empty { display: none; }

.hd-recon-evidence {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--hd-s3);
  min-width: 220px;
}
.hd-recon-evidence__col { min-width: 0; }
.hd-recon-evidence__label {
  font-size: var(--hd-text-2xs);
  font-weight: var(--hd-weight-semibold);
  text-transform: uppercase;
  letter-spacing: var(--hd-tracking-caps);
  color: var(--hd-ink-muted);
  margin-bottom: 2px;
}

/* --- ranked list editor (client sign-off contacts) ------------------------ */
.hd-rank-row {
  padding: var(--hd-s2) var(--hd-s3);
  border: 1px solid var(--hd-border);
  border-radius: var(--hd-r-md);
  background: var(--hd-surface);
}

/* --- settings: weekday open/close grid (staff hours, business hours) ------ */
.hd-weekgrid { display: flex; flex-direction: column; gap: var(--hd-s2); }
.hd-weekgrid__row {
  display: grid;
  grid-template-columns: 96px auto 1fr 1fr;
  align-items: center;
  gap: var(--hd-s2);
}
.hd-weekgrid__day { font-size: var(--hd-text-sm); color: var(--hd-ink-secondary); }

@media (max-width: 640px) {
  .hd-weekgrid__row { grid-template-columns: 72px auto 1fr 1fr; gap: var(--hd-s1); }
}

/* --- small colour swatch (staff list) -------------------------------------- */
.hd-swatch {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: var(--hd-r-full);
  border: 1px solid var(--hd-border-strong);
  flex: 0 0 auto;
}

/* --- compact JSON dumps (audit payload, job detail) ------------------------ */
.hd-audit-payload {
  margin: 0;
  max-width: 360px;
  max-height: 4.5em;
  overflow: auto;
  white-space: pre-wrap;
  word-break: break-word;
  font-family: var(--hd-font-mono);
  font-size: var(--hd-text-2xs);
  color: var(--hd-ink-secondary);
}

/* ═══════════════════════════════════════════════════════════════════════════
   APP SHELL
   The chrome app.js and portal.js build: login, top bar, navigation, user
   menu, command search and the view container. These were referenced by the
   shell before this layer existed, which left the login page unstyled.
   .hd-nav ships as a standalone sticky bar; inside .hd-appbar it becomes a
   plain flex row so the two do not both try to stick.
   ═══════════════════════════════════════════════════════════════════════════ */

/* --- boot + skip link ---------------------------------------------------- */
.hd-boot {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 60vh;
}
.hd-boot__spinner {
  width: 26px;
  height: 26px;
  border: 2px solid var(--hd-border);
  border-top-color: var(--hd-brand);
  border-radius: var(--hd-r-full);
  animation: hd-spin 700ms linear infinite;
}
@keyframes hd-spin { to { transform: rotate(360deg); } }

.hd-skip {
  position: absolute;
  left: var(--hd-s3);
  top: -60px;
  z-index: var(--hd-z-toast);
  padding: var(--hd-s2) var(--hd-s4);
  border-radius: var(--hd-r-md);
  background: var(--hd-brand);
  color: var(--hd-brand-contrast);
  font-size: var(--hd-text-sm);
  font-weight: var(--hd-weight-semibold);
  text-decoration: none;
  transition: top var(--hd-t-fast) var(--hd-ease);
}
.hd-skip:focus { top: var(--hd-s3); }

/* --- sign in ------------------------------------------------------------- */
.hd-login {
  flex: 1 1 auto;
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  min-height: 100dvh;
}

/* Left: the brand hero — deep gradient, floating light orbs, product pitch. */
.hd-login__hero {
  position: relative;
  display: flex;
  align-items: center;
  padding: var(--hd-s12) var(--hd-s10);
  background: var(--hd-hero-bg);
  color: var(--hd-hero-ink);
  overflow: hidden;
}
.hd-login__hero::before,
.hd-login__hero::after {
  content: '';
  position: absolute;
  border-radius: 50%;
  filter: blur(70px);
  opacity: 0.5;
  pointer-events: none;
}
.hd-login__hero::before {
  width: 420px; height: 420px;
  left: -120px; top: -140px;
  background: radial-gradient(circle, rgba(78, 168, 255, 0.55), transparent 70%);
  animation: hd-orb-a 16s ease-in-out infinite alternate;
}
.hd-login__hero::after {
  width: 380px; height: 380px;
  right: -110px; bottom: -130px;
  background: radial-gradient(circle, rgba(35, 211, 238, 0.4), transparent 70%);
  animation: hd-orb-b 20s ease-in-out infinite alternate;
}
@keyframes hd-orb-a { to { transform: translate(70px, 50px) scale(1.15); } }
@keyframes hd-orb-b { to { transform: translate(-60px, -50px) scale(1.1); } }
@media (prefers-reduced-motion: reduce) {
  .hd-login__hero::before, .hd-login__hero::after { animation: none; }
}

.hd-login__hero-inner {
  position: relative;
  z-index: 1;
  max-width: 480px;
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: var(--hd-s6);
}
.hd-login__hero-brand {
  display: flex;
  align-items: center;
  gap: var(--hd-s3);
  font-size: var(--hd-text-lg);
  font-weight: var(--hd-weight-bold);
  letter-spacing: var(--hd-tracking-tight);
}
.hd-login__hero-brand .hd-appbar__mark--lg {
  background: rgba(255, 255, 255, 0.14);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.22);
  color: #fff;
}
.hd-login__headline {
  margin: 0;
  font-size: clamp(26px, 3.2vw, 38px);
  font-weight: var(--hd-weight-bold);
  line-height: 1.16;
  letter-spacing: -0.02em;
}
.hd-login__headline em {
  font-style: normal;
  background: linear-gradient(90deg, #7db8ff, #23d3ee);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.hd-login__sub {
  margin: 0;
  font-size: var(--hd-text-md);
  line-height: var(--hd-leading-normal);
  color: var(--hd-hero-ink-soft);
}
.hd-login__points {
  display: flex;
  flex-direction: column;
  gap: var(--hd-s3);
  margin-top: var(--hd-s2);
}
.hd-login__point {
  display: flex;
  align-items: center;
  gap: var(--hd-s3);
  font-size: var(--hd-text-sm);
  color: var(--hd-hero-ink-soft);
}
.hd-login__point .hd-icon { color: #23d3ee; flex: none; }
.hd-login__point strong { color: var(--hd-hero-ink); font-weight: var(--hd-weight-semibold); }

/* Right: the form panel. */
.hd-login__panel {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--hd-s8) var(--hd-s6);
  background: var(--hd-bg);
}

.hd-login__card {
  width: 100%;
  max-width: 400px;
  padding: var(--hd-s7);
  border: 1px solid var(--hd-border);
  border-radius: var(--hd-r-2xl);
  background: var(--hd-surface);
  box-shadow: var(--hd-shadow-lg, 0 12px 34px rgba(18, 38, 63, .10));
}
.hd-login__panel .hd-login__card {
  border: 0;
  background: transparent;
  box-shadow: none;
  padding: 0;
}

@media (max-width: 900px) {
  .hd-login { grid-template-columns: minmax(0, 1fr); }
  .hd-login__hero { display: none; }
  .hd-login__panel { padding: var(--hd-s6) var(--hd-s4); }
  .hd-login__panel .hd-login__card {
    border: 1px solid var(--hd-border);
    background: var(--hd-surface);
    box-shadow: var(--hd-shadow-lg);
    padding: var(--hd-s7);
  }
}
.hd-login__brand {
  display: flex;
  align-items: center;
  gap: var(--hd-s3);
  margin-bottom: var(--hd-s6);
}
.hd-login__brand > div { display: flex; flex-direction: column; line-height: 1.25; }
.hd-login__brand strong {
  font-size: var(--hd-text-md);
  font-weight: var(--hd-weight-bold);
  letter-spacing: var(--hd-tracking-tight);
  color: var(--hd-ink);
}
/* Scoped to the text column only. A bare `.hd-login__brand span` also matched
   the monogram and, being more specific than .hd-appbar__mark, repainted it
   muted grey on the brand fill. */
.hd-login__brand > div > span {
  font-size: var(--hd-text-xs);
  color: var(--hd-ink-muted);
}
.hd-login__card h1 {
  margin: 0 0 var(--hd-s5);
  font-size: var(--hd-text-2xl, 1.5rem);
  font-weight: var(--hd-weight-bold);
  letter-spacing: var(--hd-tracking-tight);
  color: var(--hd-ink);
}
.hd-login__form { display: flex; flex-direction: column; gap: var(--hd-s4); }
.hd-login__form .hd-btn { margin-top: var(--hd-s2); }
.hd-login__hint {
  margin: var(--hd-s6) 0 0;
  padding-top: var(--hd-s5);
  border-top: 1px solid var(--hd-divider);
  font-size: var(--hd-text-xs);
  color: var(--hd-ink-muted);
  text-align: center;
}
.hd-login__hint a { color: var(--hd-brand); font-weight: var(--hd-weight-medium); }

/* --- top bar ------------------------------------------------------------- */
.hd-appbar {
  position: sticky;
  top: 0;
  z-index: var(--hd-z-nav);
  display: flex;
  align-items: center;
  gap: var(--hd-s4);
  height: var(--hd-nav-h);
  padding: 0 var(--hd-s5);
  border-bottom: 1px solid var(--hd-border);
  background: color-mix(in srgb, var(--hd-surface) 88%, transparent);
  backdrop-filter: saturate(180%) blur(12px);
}
@supports not (backdrop-filter: blur(1px)) {
  .hd-appbar { background: var(--hd-surface); }
}

.hd-appbar__brand {
  display: inline-flex;
  align-items: center;
  gap: var(--hd-s2);
  text-decoration: none;
  flex: none;
}
.hd-appbar__mark {
  display: inline-grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: var(--hd-r-md);
  background: linear-gradient(135deg, var(--hd-brand) 0%, var(--hd-positive) 130%);
  color: #ffffff;
  font-size: 11px;
  font-weight: var(--hd-weight-bold);
  letter-spacing: .02em;
  box-shadow: 0 2px 6px -1px color-mix(in srgb, var(--hd-brand) 55%, transparent);
}
.hd-appbar__mark--lg {
  width: 40px;
  height: 40px;
  border-radius: var(--hd-r-lg);
  font-size: var(--hd-text-sm);
}
.hd-appbar__name {
  font-size: var(--hd-text-sm);
  font-weight: var(--hd-weight-bold);
  letter-spacing: var(--hd-tracking-tight);
  color: var(--hd-ink);
}
.hd-appbar__right {
  display: flex;
  align-items: center;
  gap: var(--hd-s2);
  margin-left: auto;
  flex: none;
}
.hd-appbar__menu {
  display: none;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: var(--hd-r-md);
  background: transparent;
  color: var(--hd-ink-secondary);
  cursor: pointer;
}
.hd-appbar__menu:hover { background: var(--hd-surface-hover); color: var(--hd-ink); }

/* Nested in the bar, .hd-nav is a plain row — the bar owns the sticking. */
.hd-appbar .hd-nav {
  position: static;
  height: auto;
  padding: 0;
  border: 0;
  background: none;
  backdrop-filter: none;
  overflow-x: auto;
  scrollbar-width: none;
}
.hd-appbar .hd-nav::-webkit-scrollbar { display: none; }

.hd-nav__badge { display: inline-flex; align-items: center; margin-right: var(--hd-s1); cursor: pointer; }

/* --- mobile navigation drawer ------------------------------------------- */
.hd-nav-scrim {
  position: fixed;
  inset: 0;
  z-index: calc(var(--hd-z-nav) - 1);
  background: var(--hd-overlay);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--hd-t-fast) var(--hd-ease);
}
body.hd-nav-open .hd-nav-scrim { opacity: 1; pointer-events: auto; }

@media (max-width: 900px) {
  .hd-appbar { gap: var(--hd-s2); padding: 0 var(--hd-s3); }
  .hd-appbar__menu { display: inline-flex; }
  .hd-appbar__name { display: none; }

  .hd-appbar .hd-nav {
    position: fixed;
    inset: var(--hd-nav-h) auto 0 0;
    z-index: var(--hd-z-nav);
    width: 244px;
    flex-direction: column;
    align-items: stretch;
    gap: var(--hd-s1);
    padding: var(--hd-s4) var(--hd-s3);
    border-right: 1px solid var(--hd-border);
    background: var(--hd-surface);
    transform: translateX(-100%);
    transition: transform var(--hd-t-med) var(--hd-ease-out);
    overflow-y: auto;
  }
  body.hd-nav-open .hd-appbar .hd-nav { transform: none; }
  .hd-appbar .hd-nav__link { height: 40px; font-size: var(--hd-text-sm); }
}

/* --- account menu -------------------------------------------------------- */
.hd-usermenu { position: relative; flex: none; }
.hd-usermenu__btn {
  display: inline-flex;
  padding: 0;
  border: 0;
  border-radius: var(--hd-r-full);
  background: transparent;
  cursor: pointer;
  line-height: 0;
}
.hd-usermenu__btn:focus-visible { outline: 2px solid var(--hd-focus); outline-offset: 2px; }
.hd-usermenu__panel {
  position: absolute;
  top: calc(100% + var(--hd-s2));
  right: 0;
  z-index: var(--hd-z-dropdown);
  min-width: 224px;
  padding: var(--hd-s2);
  border: 1px solid var(--hd-border);
  border-radius: var(--hd-r-lg);
  background: var(--hd-surface-raised);
  box-shadow: var(--hd-shadow-lg, 0 12px 34px rgba(18, 38, 63, .14));
  opacity: 0;
  transform: translateY(-4px);
  pointer-events: none;
  transition: opacity var(--hd-t-fast) var(--hd-ease), transform var(--hd-t-fast) var(--hd-ease);
}
.hd-usermenu.is-open .hd-usermenu__panel { opacity: 1; transform: none; pointer-events: auto; }
.hd-usermenu__head {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--hd-s2) var(--hd-s3) var(--hd-s3);
  margin-bottom: var(--hd-s1);
  border-bottom: 1px solid var(--hd-divider);
}
.hd-usermenu__head strong { font-size: var(--hd-text-sm); color: var(--hd-ink); }
.hd-usermenu__head span { font-size: var(--hd-text-xs); color: var(--hd-ink-muted); }
.hd-usermenu__item {
  display: flex;
  align-items: center;
  gap: var(--hd-s3);
  width: 100%;
  padding: var(--hd-s2) var(--hd-s3);
  border: 0;
  border-radius: var(--hd-r-md);
  background: transparent;
  color: var(--hd-ink-secondary);
  font: inherit;
  font-size: var(--hd-text-sm);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.hd-usermenu__item:hover { background: var(--hd-surface-hover); color: var(--hd-ink); }

/* --- command search ------------------------------------------------------ */
.hd-search { display: flex; flex-direction: column; gap: var(--hd-s3); }
.hd-search__results {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: 46vh;
  overflow-y: auto;
}
.hd-search__hit {
  display: flex;
  align-items: center;
  gap: var(--hd-s3);
  width: 100%;
  padding: var(--hd-s3);
  border: 0;
  border-radius: var(--hd-r-md);
  background: transparent;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.hd-search__hit:hover { background: var(--hd-surface-hover); }
.hd-search__num {
  flex: none;
  font-family: var(--hd-font-mono);
  font-size: var(--hd-text-xs);
  color: var(--hd-ink-muted);
}
.hd-search__title {
  flex: 1 1 auto;
  min-width: 0;
  font-size: var(--hd-text-sm);
  color: var(--hd-ink);
}
.hd-search__org {
  flex: none;
  font-size: var(--hd-text-xs);
  color: var(--hd-ink-muted);
}

/* --- view container ------------------------------------------------------ */
.hd-view { display: block; width: 100%; }

/* --- client portal shell ------------------------------------------------- */
.hd-portal-app { display: flex; flex-direction: column; min-height: 100vh; min-height: 100dvh; }
.hd-portal-view {
  flex: 1 1 auto;
  width: 100%;
  max-width: 940px;
  margin-inline: auto;
  padding: var(--hd-s5) var(--hd-s4) var(--hd-s12);
}

/* --- gaps found by the shell audit -------------------------------------- */
.hd-ink-neutral { color: var(--hd-ink-muted); }
.hd-now--live { border-color: var(--hd-positive-border); background: var(--hd-positive-soft); }
.hd-photo__placeholder {
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  border: 1px dashed var(--hd-border-strong);
  border-radius: var(--hd-r-md);
  color: var(--hd-ink-muted);
  font-size: var(--hd-text-xs);
}

/* ═══════════════════════════════════════════════════════════════════════════
   SHELL AUDIT FIXES
   Gaps found by rendering every screen in a real browser: tone variants the
   views ask for that the kit never defined, and density corrections where an
   empty panel was eating a third of the dashboard.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Tone variants the views request but the kit omitted. */
.hd-stat--neutral { border-color: var(--hd-border); }
.hd-stat--neutral .hd-stat__value { color: var(--hd-ink); }
.hd-card--neutral { border-color: var(--hd-border); }
.hd-meter__seg--info { background: var(--hd-info); }
.hd-spark--brand { color: var(--hd-brand); }

/* An empty panel should say "nothing here" quietly, not occupy the fold.
   The standalone .hd-empty keeps its generous padding for full-page states. */
.hd-card .hd-empty { padding: var(--hd-s6) var(--hd-s4); }
.hd-card .hd-empty__icon { width: 34px; height: 34px; }
.hd-card .hd-empty__title { font-size: var(--hd-text-sm); }

/* Photo slots sit in an auto-fill grid; without a floor they collapse to a
   sliver and wrap their label. */
.hd-photo__placeholder {
  min-width: 96px;
  min-height: 96px;
  padding: var(--hd-s3);
  text-align: center;
  line-height: var(--hd-leading-snug);
}

/* A dense metric table needs real room; at 360px it scrolled behind the card
   edge and read as broken. */
@media (min-width: 1200px) {
  .hd-split { grid-template-columns: minmax(0, 1fr) minmax(0, 460px); }
}

/* Split/grid modifiers must stand on their own. They previously set only
   grid-template-columns, so a view using the modifier without the base class
   got no `display: grid` at all and silently rendered as stacked blocks —
   which is how the owner dashboard lost its two-column rows. */
.hd-split--even,
.hd-split--wide-rail,
.hd-split--rail-left {
  display: grid;
  gap: var(--hd-s4);
  align-items: start;
}

/* Four empty panels stacked full-height made the command centre read as mostly
   whitespace. Cap them so an empty dashboard still fits the fold. */
.hd-card .hd-empty { padding: var(--hd-s5) var(--hd-s4); }
.hd-card .hd-empty__body { max-width: 42ch; }


/* ═══════════════════════════════════════════════════════════════════════════
   22. DATA VISUALISATION — charts.js (HD.viz)
   Interactive SVG charts: crosshair + tooltip on series, hover-lift + drill on
   marks, legend toggles, chart⇄table relief. Colour comes exclusively from the
   validated --hd-viz-* slots and the semantic tokens, so theme flips re-skin
   every chart live.
   ═══════════════════════════════════════════════════════════════════════════ */
.hd-viz { display: flex; flex-direction: column; gap: var(--hd-s2); min-width: 0; }
.hd-vizhost { width: 100%; min-width: 0; }
.hd-viz__svg { display: block; max-width: 100%; }
.hd-viz__svg:focus-visible { outline: 2px solid var(--hd-focus); outline-offset: 2px; border-radius: var(--hd-r-md); }
.hd-viz__svg--drill { cursor: pointer; }

.hd-viz__grid { stroke: var(--hd-viz-grid); stroke-width: 1; }
.hd-viz__tick {
  fill: var(--hd-ink-muted);
  font-size: 10.5px;
  font-family: var(--hd-font-sans);
  font-variant-numeric: tabular-nums;
}
.hd-viz__catlabel {
  fill: var(--hd-ink-secondary);
  font-size: 11.5px;
  font-weight: 500;
  font-family: var(--hd-font-sans);
}
.hd-viz__val {
  fill: var(--hd-ink-secondary);
  font-size: 10.5px;
  font-weight: 600;
  font-family: var(--hd-font-sans);
  font-variant-numeric: tabular-nums;
}
.hd-viz__lede {
  margin: 0 0 var(--hd-s2);
  font-size: var(--hd-text-sm);
  color: var(--hd-ink-muted);
}

/* line + area */
.hd-viz__line { fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.hd-viz__area { opacity: 0.1; }
.hd-viz__dot { stroke: var(--hd-surface); stroke-width: 2; }

/* crosshair layer */
.hd-viz__cross {
  stroke: var(--hd-ink-faint);
  stroke-width: 1;
  opacity: 0;
  transition: opacity var(--hd-t-instant) linear;
  pointer-events: none;
}
.hd-viz__cross.is-on { opacity: 0.7; }
.hd-viz__focusdot {
  stroke: var(--hd-surface);
  stroke-width: 2;
  opacity: 0;
  pointer-events: none;
}
.hd-viz__focusdot.is-on { opacity: 1; }

/* bars / segments / cells */
.hd-viz__bar { transition: filter var(--hd-t-fast) var(--hd-ease), opacity var(--hd-t-fast) var(--hd-ease); }
.hd-viz__bar.is-hover { filter: brightness(1.12) saturate(1.05); }
.hd-viz__bar--drill { cursor: pointer; }
.hd-viz__bar--drill:focus-visible { outline: 2px solid var(--hd-focus); outline-offset: 1px; }
.hd-viz__cell { fill: var(--hd-surface-sunken); transition: filter var(--hd-t-fast) var(--hd-ease); }
.hd-viz__cell.is-hover { filter: brightness(1.15); }

/* donut */
.hd-viz--donut { flex-direction: row; align-items: center; gap: var(--hd-s5); flex-wrap: wrap; }
.hd-viz__donut-plot { position: relative; flex: none; }
.hd-viz__donut-plot .hd-viz__svg { overflow: visible; }
.hd-viz__seg {
  transition: transform var(--hd-t-fast) var(--hd-ease), filter var(--hd-t-fast) var(--hd-ease);
}
.hd-viz__seg:hover { filter: brightness(1.08); }
.hd-viz__donut-empty { stroke: var(--hd-surface-sunken); }
.hd-viz__donut-center {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  pointer-events: none;
  text-align: center;
}
.hd-viz__donut-value {
  font-size: var(--hd-text-2xl);
  font-weight: var(--hd-weight-bold);
  letter-spacing: var(--hd-tracking-tight);
  color: var(--hd-ink);
  line-height: 1;
}
.hd-viz__donut-label {
  font-size: var(--hd-text-2xs);
  font-weight: var(--hd-weight-semibold);
  letter-spacing: var(--hd-tracking-caps);
  text-transform: uppercase;
  color: var(--hd-ink-muted);
}

/* legend — identity channel; buttons toggle series */
.hd-vizlegend {
  display: flex;
  align-items: center;
  gap: var(--hd-s3) var(--hd-s4);
  flex-wrap: wrap;
}
.hd-vizlegend__item {
  display: inline-flex;
  align-items: center;
  gap: var(--hd-s2);
  font-size: var(--hd-text-xs);
  font-weight: var(--hd-weight-medium);
  color: var(--hd-ink-secondary);
}
.hd-vizlegend__item--btn {
  border: 0;
  background: transparent;
  padding: 2px 6px;
  margin: -2px -6px;
  border-radius: var(--hd-r-sm);
  cursor: pointer;
  font-family: inherit;
  transition: background var(--hd-t-fast) var(--hd-ease), opacity var(--hd-t-fast) var(--hd-ease);
}
.hd-vizlegend__item--btn:hover { background: var(--hd-surface-hover); }
.hd-vizlegend__item.is-off { opacity: 0.45; }
.hd-vizlegend__item.is-off > span:not(.hd-vizlegend__key) { text-decoration: line-through; }
.hd-vizlegend__key {
  width: 10px;
  height: 10px;
  border-radius: 3px;
  flex: none;
}
.hd-vizlegend__key--line { height: 3px; border-radius: 2px; width: 14px; }
.hd-vizlegend__value {
  font-variant-numeric: tabular-nums;
  font-weight: var(--hd-weight-semibold);
  color: var(--hd-ink);
}

/* tooltip — values lead, labels follow; colour keys are strokes not boxes */
.hd-viztip {
  position: fixed;
  z-index: var(--hd-z-tooltip);
  min-width: 130px;
  max-width: 280px;
  padding: var(--hd-s2) var(--hd-s3);
  border: 1px solid var(--hd-border);
  border-radius: var(--hd-r-md);
  background: var(--hd-surface-raised);
  box-shadow: var(--hd-shadow-lg);
  pointer-events: none;
  opacity: 0;
  transform: translateY(3px);
  transition: opacity var(--hd-t-instant) linear, transform var(--hd-t-fast) var(--hd-ease);
}
.hd-viztip.is-on { opacity: 1; transform: none; }
.hd-viztip__title {
  font-size: var(--hd-text-xs);
  font-weight: var(--hd-weight-semibold);
  color: var(--hd-ink);
  margin-bottom: var(--hd-s1);
}
.hd-viztip__row {
  display: flex;
  align-items: center;
  gap: var(--hd-s2);
  font-size: var(--hd-text-xs);
  padding: 1px 0;
}
.hd-viztip__row--muted { opacity: 0.62; }
.hd-viztip__key { width: 12px; height: 3px; border-radius: 2px; flex: none; }
.hd-viztip__value {
  font-weight: var(--hd-weight-bold);
  font-variant-numeric: tabular-nums;
  color: var(--hd-ink);
  min-width: 3ch;
}
.hd-viztip__label { color: var(--hd-ink-muted); }
.hd-viztip__hint {
  margin-top: var(--hd-s1);
  padding-top: var(--hd-s1);
  border-top: 1px solid var(--hd-border-faint);
  font-size: var(--hd-text-2xs);
  color: var(--hd-brand-ink);
}

/* delta chip on stat tiles */
.hd-vizdelta {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-size: var(--hd-text-xs);
  font-weight: var(--hd-weight-semibold);
  font-variant-numeric: tabular-nums;
  padding: 1px 7px;
  border-radius: var(--hd-r-full);
}
.hd-vizdelta--good { color: var(--hd-ok-ink); background: var(--hd-ok-soft); }
.hd-vizdelta--bad { color: var(--hd-danger-ink); background: var(--hd-danger-soft); }
.hd-vizdelta--flat { color: var(--hd-ink-muted); background: var(--hd-neutral-soft); }

/* viz card body keeps charts off the card edge */
.hd-vizcard__body { min-width: 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   23. HERO BAND & KPI TILES — the Command centre opening
   A deep-brand gradient panel that carries the page title and the headline
   KPIs as glass tiles. Same band in both themes: it IS the dark element of the
   light theme, and blends into the dark theme.
   ═══════════════════════════════════════════════════════════════════════════ */
.hd-heroband {
  position: relative;
  border-radius: var(--hd-r-2xl);
  padding: var(--hd-s6) var(--hd-s6) var(--hd-s6);
  background: var(--hd-hero-bg);
  color: var(--hd-hero-ink);
  overflow: hidden;
  box-shadow: var(--hd-shadow-md);
}
.hd-heroband::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(560px 260px at 85% -30%, rgba(84, 178, 255, 0.28), transparent 65%),
    radial-gradient(420px 220px at 8% 120%, rgba(35, 211, 238, 0.18), transparent 60%);
}
.hd-heroband > * { position: relative; }

.hd-heroband__top {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--hd-s4);
  flex-wrap: wrap;
  margin-bottom: var(--hd-s5);
}
.hd-heroband__eyebrow {
  font-size: var(--hd-text-2xs);
  font-weight: var(--hd-weight-semibold);
  letter-spacing: var(--hd-tracking-caps);
  text-transform: uppercase;
  color: var(--hd-hero-ink-soft);
}
.hd-heroband__title {
  margin: 2px 0 0;
  font-size: var(--hd-text-2xl);
  font-weight: var(--hd-weight-bold);
  letter-spacing: var(--hd-tracking-tight);
  color: var(--hd-hero-ink);
}
.hd-heroband__meta { display: flex; align-items: center; gap: var(--hd-s2); flex-wrap: wrap; }
.hd-heroband__meta .hd-btn--ghost { color: var(--hd-hero-ink-soft); }
.hd-heroband__meta .hd-btn--ghost:hover { background: var(--hd-hero-tile-hover); color: var(--hd-hero-ink); }

.hd-heroband__tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--hd-s3);
}

.hd-kpi {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: var(--hd-s4);
  border-radius: var(--hd-r-lg);
  border: 1px solid var(--hd-hero-border);
  background: var(--hd-hero-tile);
  backdrop-filter: blur(6px);
  color: var(--hd-hero-ink);
  text-align: left;
  font-family: inherit;
  cursor: default;
  min-width: 0;
  transition: background var(--hd-t-fast) var(--hd-ease), transform var(--hd-t-fast) var(--hd-ease),
    border-color var(--hd-t-fast) var(--hd-ease);
}
button.hd-kpi { cursor: pointer; }
button.hd-kpi:hover {
  background: var(--hd-hero-tile-hover);
  border-color: rgba(255, 255, 255, 0.26);
  transform: translateY(-2px);
}
button.hd-kpi:focus-visible { outline: 2px solid #9ecbff; outline-offset: 2px; }

.hd-kpi__label {
  display: flex;
  align-items: center;
  gap: var(--hd-s1);
  font-size: var(--hd-text-2xs);
  font-weight: var(--hd-weight-semibold);
  letter-spacing: var(--hd-tracking-caps);
  text-transform: uppercase;
  color: var(--hd-hero-ink-soft);
  white-space: nowrap;
}
.hd-kpi__value {
  display: flex;
  align-items: baseline;
  gap: var(--hd-s2);
  font-size: var(--hd-text-3xl);
  font-weight: var(--hd-weight-bold);
  line-height: 1.02;
  letter-spacing: var(--hd-tracking-tight);
}
.hd-kpi__sub {
  font-size: var(--hd-text-xs);
  color: var(--hd-hero-ink-soft);
}
.hd-kpi--alarm .hd-kpi__value { color: #ff9d92; }
.hd-kpi--watch .hd-kpi__value { color: #ffd370; }
.hd-kpi--fine .hd-kpi__value { color: #7ce3ad; }
.hd-kpi .hd-spark { margin-top: var(--hd-s1); }
.hd-kpi .hd-spark__line { stroke: rgba(255, 255, 255, 0.85); }
.hd-kpi .hd-spark__area { fill: rgba(255, 255, 255, 0.16); }
.hd-kpi .hd-spark__last { fill: #ffffff; }

@media (max-width: 720px) {
  .hd-heroband { padding: var(--hd-s5) var(--hd-s4); border-radius: var(--hd-r-xl); }
  .hd-heroband__tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   24. MICRO-MOTION — views breathe in; respect reduced-motion.
   ═══════════════════════════════════════════════════════════════════════════ */
@keyframes hd-rise {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}
.hd-view > * { animation: hd-rise 280ms var(--hd-ease-out) both; }
.hd-view > *:nth-child(2) { animation-delay: 40ms; }
.hd-view > *:nth-child(3) { animation-delay: 80ms; }
.hd-view > *:nth-child(4) { animation-delay: 120ms; }
.hd-view > *:nth-child(n+5) { animation-delay: 150ms; }
@media (prefers-reduced-motion: reduce) {
  .hd-view > * { animation: none; }
  .hd-viz__line { transition: none !important; }
}

/* stat-tile icon medallion (ui.js statTile now renders o.icon) */
.hd-stat { position: relative; }
.hd-stat__medal {
  position: absolute;
  top: var(--hd-s3);
  right: var(--hd-s3);
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: var(--hd-r-md);
  background: var(--hd-brand-soft);
  color: var(--hd-brand-ink);
}
.hd-stat--ok .hd-stat__medal { background: var(--hd-ok-soft); color: var(--hd-ok-ink); }
.hd-stat--warn .hd-stat__medal { background: var(--hd-warn-soft); color: var(--hd-warn-ink); }
.hd-stat--danger .hd-stat__medal { background: var(--hd-danger-soft); color: var(--hd-danger-ink); }
.hd-stat--positive .hd-stat__medal { background: var(--hd-positive-soft); color: var(--hd-positive-ink); }

/* ═══════════════════════════════════════════════════════════════════════════
   25. WEEKDAY PICKER — multi-select day toggles for recurring visit schedules
   Real <button aria-pressed>, so keyboard and screen readers get toggle
   semantics without any JS role plumbing. Narrow screens fall back to a single
   initial per day; wider ones show the three-letter abbreviation.
   ═══════════════════════════════════════════════════════════════════════════ */
.hd-daypick {
  display: flex;
  gap: var(--hd-s1);
  flex-wrap: wrap;
}

.hd-daypick__day {
  /* Grow to fill a narrow row, but never stretch into slabs on a wide screen —
     they should read as a compact row of day chips. */
  flex: 1 1 0;
  max-width: 96px;
  min-width: 44px;
  min-height: var(--hd-tap-min);
  padding: 0 var(--hd-s2);
  border: 1px solid var(--hd-border-strong);
  border-radius: var(--hd-r-md);
  background: var(--hd-surface);
  color: var(--hd-ink-secondary);
  font-family: inherit;
  font-size: var(--hd-text-sm);
  font-weight: var(--hd-weight-medium);
  cursor: pointer;
  user-select: none;
  transition: background var(--hd-t-fast) var(--hd-ease),
    border-color var(--hd-t-fast) var(--hd-ease),
    color var(--hd-t-fast) var(--hd-ease),
    box-shadow var(--hd-t-fast) var(--hd-ease);
}
.hd-daypick__day:hover {
  background: var(--hd-surface-hover);
  border-color: var(--hd-brand-soft-border);
  color: var(--hd-ink);
}
.hd-daypick__day:focus-visible {
  outline: 2px solid var(--hd-focus);
  outline-offset: 2px;
}

/* Selected state carries a fill AND a checkmark-weight border, so it never
   depends on colour alone. */
.hd-daypick__day[aria-pressed='true'] {
  background: var(--hd-brand);
  border-color: var(--hd-brand);
  color: var(--hd-brand-contrast);
  font-weight: var(--hd-weight-semibold);
  box-shadow: 0 1px 3px color-mix(in srgb, var(--hd-brand) 40%, transparent);
}
.hd-daypick__day[aria-pressed='true']:hover {
  background: var(--hd-brand-hover);
  border-color: var(--hd-brand-hover);
  color: var(--hd-brand-contrast);
}

.hd-daypick__initial { display: none; }
.hd-daypick__short { display: inline; }

@media (max-width: 560px) {
  .hd-daypick__day { min-width: 0; padding: 0; }
  .hd-daypick__initial { display: inline; }
  .hd-daypick__short { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   26. MONTH CALENDAR — 7 columns × 6 week rows
   The week view stays a lane-per-technician grid; the month view merges every
   technician into one cell per date, because at 30+ columns lanes stop being
   readable and the question a month answers is "how busy is that day".
   ═══════════════════════════════════════════════════════════════════════════ */
.hd-month {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 1px;
  background: var(--hd-border);
  border: 1px solid var(--hd-border);
  border-radius: var(--hd-r-lg);
  overflow: hidden;
}

.hd-month__dow {
  padding: var(--hd-s2) var(--hd-s3);
  background: var(--hd-surface-sunken);
  font-size: var(--hd-text-2xs);
  font-weight: var(--hd-weight-semibold);
  letter-spacing: var(--hd-tracking-caps);
  text-transform: uppercase;
  color: var(--hd-ink-muted);
  text-align: left;
}

.hd-month__cell {
  display: flex;
  flex-direction: column;
  gap: 3px;
  align-items: stretch;
  min-height: 104px;
  padding: var(--hd-s2);
  border: 0;
  background: var(--hd-surface);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: background var(--hd-t-fast) var(--hd-ease);
}
.hd-month__cell:hover { background: var(--hd-surface-hover); }
.hd-month__cell:focus-visible { outline: 2px solid var(--hd-focus); outline-offset: -2px; }

/* Days spilling in from the neighbouring months stay present but recede. */
.hd-month__cell.is-outside { background: var(--hd-surface-sunken); }
.hd-month__cell.is-outside .hd-month__date { color: var(--hd-ink-faint); }

.hd-month__date {
  font-size: var(--hd-text-sm);
  font-weight: var(--hd-weight-semibold);
  font-variant-numeric: tabular-nums;
  color: var(--hd-ink-secondary);
  flex: none;
}
.hd-month__cell.is-today .hd-month__date {
  display: inline-grid;
  place-items: center;
  min-width: 22px;
  height: 22px;
  padding: 0 5px;
  border-radius: var(--hd-r-full);
  background: var(--hd-brand);
  color: var(--hd-brand-contrast);
}

.hd-month__chips { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

.hd-month__chip {
  display: flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
  padding: 1px var(--hd-s1);
  border-radius: var(--hd-r-xs);
  font-size: var(--hd-text-2xs);
  line-height: 1.5;
}
.hd-month__chip-who {
  flex: none;
  font-weight: var(--hd-weight-bold);
  opacity: 0.75;
  font-size: 9px;
  letter-spacing: 0.02em;
}
.hd-month__chip-text { min-width: 0; }

.hd-month__more {
  font-size: var(--hd-text-2xs);
  font-weight: var(--hd-weight-medium);
  color: var(--hd-ink-muted);
  padding-left: var(--hd-s1);
}

/* Leave reads as a distinct state from a manual block: a person is away for the
   day, not merely busy for an hour. Striped so it never relies on hue alone. */
.hd-cal-chip--leave,
.hd-month__chip.hd-cal-chip--leave {
  background: repeating-linear-gradient(
    135deg,
    var(--hd-positive-soft),
    var(--hd-positive-soft) 5px,
    transparent 5px,
    transparent 10px
  );
  color: var(--hd-positive-ink);
  box-shadow: inset 0 0 0 1px var(--hd-positive-border);
}

@media (max-width: 720px) {
  /* A 7-column month on a phone gives ~50px cells: keep the shape, drop the
     text, and let the count carry the load. Tapping a day opens its week. */
  .hd-month__cell { min-height: 64px; padding: var(--hd-s1); }
  .hd-month__chip-text { display: none; }
  .hd-month__chip { justify-content: center; padding: 1px 2px; }
  .hd-month__dow { padding: var(--hd-s1); text-align: center; font-size: 9px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   27. KNOWLEDGE BASE
   A read model over resolved tickets, so the fix leads and the reported
   symptom is secondary — the reverse of the ticket screen's hierarchy.
   ═══════════════════════════════════════════════════════════════════════════ */
.hd-kb__title {
  font-size: var(--hd-text-md);
  font-weight: var(--hd-weight-semibold);
  color: var(--hd-ink);
  line-height: var(--hd-leading-snug);
}

.hd-kb__solution {
  padding: var(--hd-s3);
  border-radius: var(--hd-r-md);
  background: var(--hd-ok-soft);
  box-shadow: inset 2px 0 0 var(--hd-ok);
}
.hd-kb__solution-label {
  display: flex;
  align-items: center;
  gap: var(--hd-s1);
  margin-bottom: var(--hd-s1);
  font-size: var(--hd-text-2xs);
  font-weight: var(--hd-weight-semibold);
  letter-spacing: var(--hd-tracking-caps);
  text-transform: uppercase;
  color: var(--hd-ok-ink);
}
.hd-kb__solution-body {
  margin: 0;
  font-size: var(--hd-text-sm);
  line-height: var(--hd-leading-normal);
  color: var(--hd-ink);
  white-space: pre-wrap;
}

.hd-kb__reported > summary {
  cursor: pointer;
  font-size: var(--hd-text-xs);
  color: var(--hd-ink-muted);
  padding: var(--hd-s1) 0;
}
.hd-kb__reported > summary:hover { color: var(--hd-ink-secondary); }
.hd-kb__reported-body {
  margin: var(--hd-s1) 0 0;
  padding-left: var(--hd-s3);
  border-left: 2px solid var(--hd-border);
  font-size: var(--hd-text-sm);
  line-height: var(--hd-leading-normal);
  color: var(--hd-ink-secondary);
  white-space: pre-wrap;
}

/* compact hit used by the "have we fixed this before?" panel */
.hd-kb__hit {
  display: block;
  width: 100%;
  padding: var(--hd-s2) var(--hd-s3);
  border: 1px solid var(--hd-border-faint);
  border-radius: var(--hd-r-md);
  background: var(--hd-surface);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color var(--hd-t-fast) var(--hd-ease),
    background var(--hd-t-fast) var(--hd-ease);
}
.hd-kb__hit:hover {
  background: var(--hd-surface-hover);
  border-color: var(--hd-brand-soft-border);
}
.hd-kb__hit-solution {
  margin: 2px 0;
  font-size: var(--hd-text-xs);
  line-height: var(--hd-leading-snug);
  color: var(--hd-ink-secondary);
  /* two lines is enough to recognise the fix; the ticket has the rest */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ═══════════════════════════════════════════════════════════════════════════
   28. BRAND — HyperCode mark & lockup
   The mark is inline SVG (HD.mark) so it stays sharp at any size and needs no
   second request; the wordmark is real text so it stays selectable and sharp,
   and the two brand colours come straight from the printed logo.
   ═══════════════════════════════════════════════════════════════════════════ */
:root {
  --hc-blue: #3F6FD8;
  --hc-blue-deep: #123F87;
  --hc-red: #E8271C;
  --hc-orange: #F04A28;
}

.hd-mark { display: block; flex: none; }

.hd-logo {
  display: inline-flex;
  align-items: center;
  gap: var(--hd-s3);
  line-height: 1;
}
.hd-logo__word {
  display: grid;
  /* HYPER and CODE sit tight, the way the printed lockup stacks them. */
  line-height: 0.94;
  letter-spacing: -0.01em;
}
.hd-logo__hyper,
.hd-logo__code {
  font-weight: var(--hd-weight-bold);
  font-size: 1.05em;
}
.hd-logo__hyper { color: var(--hc-blue); }
.hd-logo__code {
  color: var(--hc-red);
  /* the printed logo indents CODE under HYPER */
  padding-left: 0.42em;
}
.hd-logo__tag {
  margin-top: 0.28em;
  font-size: 0.4em;
  font-weight: var(--hd-weight-medium);
  letter-spacing: 0.04em;
  color: var(--hc-blue-deep);
  padding-left: 0.5em;
}

/* On the dark login hero the deep-blue tagline would disappear. */
.hd-logo--onDark .hd-logo__hyper { color: #8FB4FF; }
/* The brand red is only ~3:1 on the deep-navy hero; this step keeps the logo
   unmistakably red while staying legible against it. */
.hd-logo--onDark .hd-logo__code { color: #FF6B5E; }
.hd-logo--onDark .hd-logo__tag { color: rgba(226, 238, 255, 0.72); }

/* Dark theme: the deep navy tagline needs lifting off the dark surface too. */
:root[data-theme='dark'] .hd-logo__tag { color: #8FB4FF; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .hd-logo__tag { color: #8FB4FF; }
}

/* --- appbar brand: mark + two-line product name ------------------------- */
.hd-appbar__brand { gap: var(--hd-s2); }
.hd-appbar__name {
  display: flex;
  flex-direction: column;
  line-height: 1.12;
}
.hd-appbar__name strong {
  font-size: var(--hd-text-sm);
  font-weight: var(--hd-weight-bold);
  letter-spacing: var(--hd-tracking-tight);
  color: var(--hd-ink);
}
.hd-appbar__name small {
  font-size: 9.5px;
  font-weight: var(--hd-weight-medium);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--hd-ink-muted);
}

/* The login hero sizes its lockup larger and gives it room to breathe. */
.hd-login__hero .hd-logo { font-size: 26px; }
.hd-login__brand .hd-logo { font-size: 20px; }
.hd-portal-login__brand .hd-logo { font-size: 21px; }

@media (max-width: 900px) {
  .hd-appbar__name small { display: none; }
}

/* Verification code: read off one screen, typed into another — usually a phone. */
.hd-codeinput {
  font-family: var(--hd-font-mono);
  font-size: var(--hd-text-2xl);
  font-weight: var(--hd-weight-bold);
  letter-spacing: 0.42em;
  text-align: center;
  text-indent: 0.42em;   /* re-centres text that letter-spacing pushes left */
  padding-block: var(--hd-s3);
}

/* ═══════════════════════════════════════════════════════════════════════════
   29. CLIENT PORTAL POLISH
   The portal is the paying customer's window into the product, so its pieces
   get the same finish as the staff app: gradient icon medallions on the
   action tiles, real card-grade ticket rows, and the shared hero band above.
   ═══════════════════════════════════════════════════════════════════════════ */
.hd-portal-cta {
  display: flex;
  align-items: center;
  gap: var(--hd-s4);
  padding: var(--hd-s5);
  border: 1px solid var(--hd-border);
  border-radius: var(--hd-r-xl);
  background: var(--hd-surface);
  box-shadow: var(--hd-shadow-xs);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color var(--hd-t-fast) var(--hd-ease),
    box-shadow var(--hd-t-fast) var(--hd-ease),
    transform var(--hd-t-fast) var(--hd-ease);
}
.hd-portal-cta:hover {
  border-color: var(--hd-brand-soft-border);
  box-shadow: var(--hd-shadow-md);
  transform: translateY(-2px);
}
.hd-portal-cta > .hd-icon {
  flex: none;
  box-sizing: content-box;
  padding: var(--hd-s3);
  border-radius: var(--hd-r-lg);
  background: var(--hd-brand-soft);
  color: var(--hd-brand-ink);
}
.hd-portal-cta--primary > .hd-icon {
  background: linear-gradient(135deg, var(--hd-brand) 0%, var(--hd-positive) 130%);
  color: #ffffff;
  box-shadow: 0 3px 8px -2px color-mix(in srgb, var(--hd-brand) 55%, transparent);
}
.hd-portal-cta strong { font-size: var(--hd-text-md); color: var(--hd-ink); }

.hd-portal-ticket-row {
  border: 1px solid var(--hd-border-faint);
  border-radius: var(--hd-r-lg);
  background: var(--hd-surface);
  transition: border-color var(--hd-t-fast) var(--hd-ease),
    background var(--hd-t-fast) var(--hd-ease),
    transform var(--hd-t-fast) var(--hd-ease);
}
.hd-portal-ticket-row:hover {
  background: var(--hd-surface-hover);
  border-color: var(--hd-brand-soft-border);
  transform: translateX(2px);
}
