/* ============================================================
   Greenacres Design System — style.css
   Layers: tokens → base → components → utilities
   ============================================================ */

@layer tokens, base, components, utilities;

/* ── Self-hosted fonts ───────────────────────────────────── */
@font-face {
  font-family: 'DM Sans';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('/assets/fonts/DMSans-300.woff2') format('woff2');
}
@font-face {
  font-family: 'DM Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/DMSans-400.woff2') format('woff2');
}
@font-face {
  font-family: 'DM Sans';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/DMSans-400-italic.woff2') format('woff2');
}
@font-face {
  font-family: 'DM Sans';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/assets/fonts/DMSans-500.woff2') format('woff2');
}
@font-face {
  font-family: 'DM Sans';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/assets/fonts/DMSans-600.woff2') format('woff2');
}
@font-face {
  font-family: 'DM Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/assets/fonts/DMSans-700.woff2') format('woff2');
}
@font-face {
  font-family: 'DM Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/DMMono-400.woff2') format('woff2');
}
@font-face {
  font-family: 'DM Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/assets/fonts/DMMono-500.woff2') format('woff2');
}
@font-face {
  font-family: 'Instrument Serif';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/InstrumentSerif-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Instrument Serif';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/InstrumentSerif-400-italic.woff2') format('woff2');
}

/* ── Animatable custom properties ────────────────────────── */
@property --accent {
  syntax: '<color>';
  inherits: true;
  initial-value: oklch(82% 0.17 193);
}
@property --ok {
  syntax: '<color>';
  inherits: true;
  initial-value: oklch(72% 0.22 148);
}
@property --warn {
  syntax: '<color>';
  inherits: true;
  initial-value: oklch(73% 0.22 62);
}
@property --crit {
  syntax: '<color>';
  inherits: true;
  initial-value: oklch(68% 0.27 15);
}

@layer tokens {
  :root {
    color-scheme: dark;
    /* ── Surfaces — wider lightness steps for clear card depth ── */
    --bg:         oklch(9%    0.008 240);
    --bg-raised:  oklch(13.5% 0.012 244);
    --bg-card:    oklch(17.5% 0.016 244);
    --bg-overlay: oklch(22%   0.018 244);

    /* ── Borders ── */
    --border:     oklch(100% 0 0 / 0.13);
    --border-h:   oklch(100% 0 0 / 0.26);
    --border-act: color-mix(in oklch, var(--accent) 45%, transparent);

    /* ── Text ── */
    --fg:         oklch(94%  0.010 240);
    --fg-dim:     oklch(68%  0.018 244);
    --fg-faint:   oklch(60%  0.015 248);

    /* ── Brand — richer, more vivid teal ── */
    --accent:     oklch(82%  0.17  193);
    --accent-bg:  color-mix(in oklch, var(--accent) 11%, transparent);
    --accent-brd: color-mix(in oklch, var(--accent) 30%, transparent);

    /* ── Status — balanced brightness, higher chroma ── */
    --ok:         oklch(72%  0.22  148);
    --warn:       oklch(73%  0.22   62);
    --crit:       oklch(68%  0.27   15);
    --info:       oklch(72%  0.17  242);
    --idle:       var(--fg-faint);
    --heat:       oklch(72% 0.21 45);

    /* ── Legacy compat aliases ── */
    --green:      var(--ok);
    --accent-2:   oklch(75% 0.12 330);
    --surface-2:  var(--bg-raised);

    --ok-bg:   color-mix(in oklch, var(--ok)   12%, transparent);
    --warn-bg: color-mix(in oklch, var(--warn) 12%, transparent);
    --crit-bg: color-mix(in oklch, var(--crit) 12%, transparent);
    --info-bg: color-mix(in oklch, var(--info) 12%, transparent);

    /* ── Typography ── */
    --font:       'DM Sans', system-ui, -apple-system, sans-serif;
    --font-serif: 'Instrument Serif', Georgia, serif;
    --font-mono:  'DM Mono', 'Fira Code', ui-monospace, monospace;

    --text-xs:      11px;
    --text-sm:      12.5px;
    --text-base:    14px;
    --text-md:      15px;
    --text-lg:      17px;
    --text-xl:      22px;
    --text-display: clamp(2rem, 5vw, 3.4rem);

    --leading-tight: 1.25;
    --leading-body:  1.6;

    /* ── Spacing (4px grid) ── */
    --s1:  4px;
    --s2:  8px;
    --s3:  12px;
    --s4:  16px;
    --s5:  20px;
    --s6:  24px;
    --s7:  28px;
    --s8:  32px;
    --s10: 40px;
    --s12: 48px;
    --s16: 64px;

    --pad-card:    20px 24px;
    --pad-card-lg: 28px 32px;
    --gap-section: 48px;
    --max-w:       1080px;

    /* ── Shape ── */
    --radius:    12px;
    --radius-sm:  8px;
    --radius-xs:  6px;

    /* ── Motion ── */
    --dur-fast:   150ms;
    --dur-base:   250ms;
    --ease-out:   cubic-bezier(0.16, 1, 0.3, 1);
    --ease-spring: linear(0, 0.6 20%, 1.04 40%, 0.98 60%, 1);
  }

  /* ── Mobile token overrides ── */
  @media (max-width: 640px) {
    :root {
      --text-base:    15px;
      --text-md:      16px;
      --text-sm:      13px;
      --text-xs:      12px;
      --gap-section:  36px;
      --pad-card:     16px 16px;
    }
  }

  /* ── Small phone (iPhone SE / mini, ≤390px) ── */
  @media (max-width: 390px) {
    :root {
      --text-base:    14px;
      --text-sm:      12.5px;
      --gap-section:  28px;
      --pad-card:     14px 14px;
    }
    .section-label { letter-spacing: 0.07em; }
  }
}

@layer base {
  *, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
  }

  html {
    scroll-behavior: smooth;
    scroll-padding-top: 70px;
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
  }

  body {
    font-family: var(--font);
    font-size: var(--text-base);
    line-height: var(--leading-body);
    color: var(--fg);
    background: var(--bg);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
    overflow-x: hidden;
    -webkit-text-size-adjust: 100%;
  }

  a { color: inherit; text-decoration: none; }
  img { max-width: 100%; height: auto; display: block; }

  /* Film grain overlay — one treatment across all pages */
  body::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: 100;
    pointer-events: none;
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.03'/%3E%3C/svg%3E");
    background-size: 180px;
    opacity: 0.5;
  }

  main {
    animation: pageIn var(--dur-base) var(--ease-out) both;
    padding-bottom: var(--s16);
  }

  @keyframes pageIn {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: translateY(0); }
  }

  @keyframes pulse {
    0%, 100% { opacity: 1; }
    50%       { opacity: 0.4; }
  }

  @keyframes shimmer {
    from { background-position: -400px 0; }
    to   { background-position:  400px 0; }
  }

  @keyframes fadeUp {
    from { opacity: 0; transform: translateY(16px); }
    to   { opacity: 1; transform: translateY(0); }
  }

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

@layer components {

  /* ── Skip link ─────────────────────────────────────────── */
  .skip-link {
    position: absolute;
    top: -40px;
    left: 0;
    background: var(--bg-overlay);
    color: var(--fg);
    padding: var(--s2) var(--s4);
    border-radius: 0 0 var(--radius-xs) 0;
    font-size: var(--text-sm);
    font-weight: 500;
    z-index: 9000;
    transition: top var(--dur-fast);
  }
  .skip-link:focus { top: 0; }

  /* ── Navigation ────────────────────────────────────────── */
  /* Full-width sticky bar wrapper */
  .topnav-bar {
    position: sticky;
    top: 0;
    z-index: 200;
    backdrop-filter: blur(20px) saturate(1.4);
    -webkit-backdrop-filter: blur(20px) saturate(1.4);
    background: oklch(9% 0.010 250 / 0.75);
    border-bottom: 1px solid var(--border);
    view-transition-name: topnav;
  }
  .topnav-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    max-width: var(--max-w);
    margin: 0 auto;
    padding: var(--s4) 28px;
  }

  .nav-brand {
    display: flex;
    align-items: center;
    gap: var(--s3);
    font-weight: 600;
    font-size: var(--text-lg);
    letter-spacing: -0.02em;
    color: var(--fg);
    flex-shrink: 0;
  }
  .nav-logo { width: 32px; height: 32px; }

  .nav-links {
    display: flex;
    align-items: center;
    gap: var(--s1);
  }
  .nav-links a {
    padding: 6px var(--s4);
    border-radius: 999px;
    font-size: var(--text-sm);
    font-weight: 500;
    color: var(--fg-dim);
    transition: color var(--dur-fast), background var(--dur-fast);
    white-space: nowrap;
  }
  .nav-links a:hover {
    color: var(--fg);
    background: oklch(100% 0 0 / 0.06);
  }
  .nav-links a.active,
  .nav-links a[aria-current="page"] {
    color: var(--fg);
    background: oklch(100% 0 0 / 0.06);
    position: relative;
  }
  .nav-links a.active::after,
  .nav-links a[aria-current="page"]::after {
    content: '';
    position: absolute;
    bottom: -1px;
    left: 50%;
    transform: translateX(-50%);
    width: 16px;
    height: 2px;
    border-radius: 1px;
    background: var(--accent);
  }

  /* ⌘K trigger button */
  .nav-cmd {
    display: flex;
    align-items: center;
    gap: var(--s2);
    padding: 6px var(--s3);
    border-radius: var(--radius-xs);
    background: var(--bg-card);
    border: 1px solid var(--border);
    color: var(--fg-dim);
    font-size: var(--text-xs);
    font-family: var(--font-mono);
    cursor: pointer;
    transition: border-color var(--dur-fast), color var(--dur-fast);
    white-space: nowrap;
    margin-left: var(--s4);
  }
  .nav-cmd:hover { border-color: var(--border-h); color: var(--fg); }
  .nav-cmd kbd {
    font-family: var(--font-mono);
    font-size: 10px;
    background: var(--bg-raised);
    padding: 1px 5px;
    border-radius: 4px;
    border: 1px solid var(--border-h);
  }

  /* Mobile nav toggle (hidden on desktop) */
  .nav-toggle {
    display: none;
    background: none;
    border: none;
    color: var(--fg-dim);
    cursor: pointer;
    padding: var(--s2);
    min-height: 44px;
    min-width: 44px;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-xs);
  }

  @media (max-width: 640px) {
    .topnav, .topnav-inner { padding: var(--s3) var(--s5); }
    .nav-links { display: none; }
    .nav-cmd   { display: none; }
    .nav-toggle { display: flex; }
    body { padding-bottom: 72px; } /* room for bottom nav */
  }

  /* ── Page header (operational pages) ──────────────────── */
  .page-header {
    max-width: var(--max-w);
    margin: 0 auto;
    padding: var(--s8) 28px var(--s6);
    view-transition-name: page-header;
    border-bottom: 1px solid color-mix(in oklch, var(--accent) 12%, var(--border));
  }
  .page-header h1 {
    font-family: var(--font-serif);
    font-weight: 400;
    font-style: italic;
    font-size: clamp(1.8rem, 4vw, 2.6rem);
    line-height: var(--leading-tight);
    letter-spacing: -0.02em;
    margin-bottom: var(--s2);
  }
  .page-header p {
    color: var(--fg-dim);
    font-size: var(--text-md);
  }
  .page-header-meta {
    display: flex;
    align-items: center;
    gap: var(--s4);
    margin-top: var(--s3);
    font-size: var(--text-xs);
    color: var(--fg-faint);
  }
  .live-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--ok);
    box-shadow: 0 0 6px color-mix(in oklch, var(--ok) 60%, transparent);
    animation: pulse 2.5s ease infinite;
    flex-shrink: 0;
  }
  .live-dot.stale  { background: var(--warn); box-shadow: 0 0 6px color-mix(in oklch, var(--warn) 60%, transparent); }
  .live-dot.dead   { background: var(--crit); box-shadow: none; animation: none; }

  @media (max-width: 640px) {
    .page-header { padding: var(--s6) var(--s5) var(--s5); }
  }

  /* ── Section layout ────────────────────────────────────── */
  .page-body {
    max-width: var(--max-w);
    margin: 0 auto;
    padding: 0 28px var(--s16);
  }

  section {
    max-width: var(--max-w);
    margin: 0 auto;
    padding: 0 28px;
  }

  .section-block      { margin-top: var(--gap-section); }
  /* Legacy section class aliases — inner pages use these */
  .services-section   { margin-top: var(--gap-section); }
  .bulletin-section   { margin-top: var(--gap-section); }
  .network-section    { margin-top: var(--gap-section); }

  .section-label {
    font-size: var(--text-xs);
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--fg-faint);
    margin-bottom: var(--s4);
    padding-left: 8px;
    border-left: 2px solid var(--accent-brd);
  }

  @media (max-width: 640px) {
    .page-body, section { padding-left: var(--s5); padding-right: var(--s5); }
  }

  /* ── Cards ─────────────────────────────────────────────── */
  .card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: var(--s3);
    container-type: inline-size;
  }

  .card {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: var(--pad-card);
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    transition:
      border-color var(--dur-fast),
      transform var(--dur-fast) var(--ease-spring),
      box-shadow var(--dur-fast);
    cursor: pointer;
    container-type: inline-size;
  }
  .card:hover {
    border-color: var(--border-h);
    transform: translateY(-2px);
    box-shadow: 0 8px 28px oklch(0% 0 0 / .35);
  }
  .card:active {
    transform: scale(0.98);
    box-shadow: none;
    transition-duration: 60ms;
  }

  /* Semantic top-border states */
  .card-ok   { border-top: 2px solid color-mix(in oklch, var(--ok)   50%, transparent); }
  .card-warn { border-top: 2px solid color-mix(in oklch, var(--warn) 50%, transparent); }
  .card-crit { border-top: 2px solid color-mix(in oklch, var(--crit) 50%, transparent); }
  .card-info { border-top: 2px solid color-mix(in oklch, var(--info) 40%, transparent); }
  .card-accent { border-top: 2px solid color-mix(in oklch, var(--accent) 40%, transparent); }

  /* Named page cards (landing) */
  .card-dashboard { border-top: 2px solid color-mix(in oklch, var(--accent) 40%, transparent); }
  .card-controls  { border-top: 2px solid oklch(75% 0.12 330 / 0.35); }
  .card-analytics { border-top: 2px solid oklch(68% 0.15 270 / 0.35); }
  .card-status    { border-top: 2px solid color-mix(in oklch, var(--ok) 50%, transparent); }
  .card-editor    { border-top: 2px solid oklch(80% 0.14 80 / 0.35); }
  .card-admin     { border-top: 2px solid oklch(60% 0.02 250 / 0.30); }

  .card-icon {
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-sm);
    margin-bottom: var(--s5);
    background: oklch(100% 0 0 / 0.04);
    border: 1px solid var(--border);
    color: var(--fg-dim);
    transition: color var(--dur-fast), background var(--dur-fast);
    flex-shrink: 0;
  }
  .card:hover .card-icon {
    color: var(--accent);
    background: var(--accent-bg);
  }

  .card h3 {
    font-size: var(--text-lg);
    font-weight: 600;
    letter-spacing: -0.01em;
    margin-bottom: var(--s2);
    line-height: var(--leading-tight);
  }
  .card p {
    font-size: var(--text-sm);
    color: var(--fg-dim);
    line-height: var(--leading-body);
    flex: 1;
  }

  .card-arrow {
    position: absolute;
    top: 20px;
    right: 20px;
    font-size: 16px;
    color: var(--fg-faint);
    transition: color var(--dur-fast), transform var(--dur-fast) var(--ease-spring);
  }
  .card:hover .card-arrow {
    color: var(--accent);
    transform: translateX(3px);
  }

  /* ── Bento grid ─────────────────────────────────────────── */
  .bento {
    display: grid;
    gap: var(--s3);
    container-type: inline-size;
  }
  .bento-2 { grid-template-columns: 1fr 1fr; }
  .bento-3 { grid-template-columns: 1fr 1fr 1fr; }
  .bento-4 { grid-template-columns: 1fr 1fr 1fr 1fr; }
  .bento-cell {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: var(--pad-card);
    transition: border-color var(--dur-fast);
  }
  .bento-cell:hover { border-color: var(--border-h); }
  .bento-cell.span-2 { grid-column: span 2; }
  .bento-cell.span-3 { grid-column: span 3; }

  @container (max-width: 600px) {
    .bento-2, .bento-3, .bento-4 { grid-template-columns: 1fr; }
    .bento-cell.span-2, .bento-cell.span-3 { grid-column: span 1; }
  }

  /* ── Status dots ────────────────────────────────────────── */
  .dot {
    display: inline-block;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--idle);
    flex-shrink: 0;
    vertical-align: middle;
  }
  .dot-ok   { background: var(--ok);   box-shadow: 0 0 7px color-mix(in oklch, var(--ok)   60%, transparent); }
  .dot-warn { background: var(--warn); box-shadow: 0 0 7px color-mix(in oklch, var(--warn) 60%, transparent); }
  .dot-crit { background: var(--crit); box-shadow: 0 0 7px color-mix(in oklch, var(--crit) 60%, transparent); }
  .dot-info { background: var(--info); }
  .dot-idle { background: var(--idle); }
  .dot-off  { background: var(--fg-faint); }
  .dot-live { background: var(--ok); box-shadow: 0 0 7px color-mix(in oklch, var(--ok) 60%, transparent); animation: pulse 2.5s ease infinite; }

  /* Legacy alias */
  .dot.green { background: var(--ok); box-shadow: 0 0 8px color-mix(in oklch, var(--ok) 55%, transparent); animation: pulse 2.5s ease infinite; }

  /* ── Badges ─────────────────────────────────────────────── */
  .badge {
    display: inline-flex;
    align-items: center;
    gap: var(--s1);
    padding: 3px 10px;
    border-radius: 999px;
    font-size: var(--text-xs);
    font-weight: 600;
    letter-spacing: 0.04em;
    white-space: nowrap;
  }
  .badge-accent { background: var(--accent-bg); color: var(--accent); border: 1px solid var(--accent-brd); }
  .badge-ok     { background: var(--ok-bg);   color: var(--ok);   border: 1px solid color-mix(in oklch, var(--ok)   25%, transparent); }
  .badge-warn   { background: var(--warn-bg); color: var(--warn); border: 1px solid color-mix(in oklch, var(--warn) 25%, transparent); }
  .badge-crit   { background: var(--crit-bg); color: var(--crit); border: 1px solid color-mix(in oklch, var(--crit) 25%, transparent); }
  .badge-info   { background: var(--info-bg); color: var(--info); border: 1px solid color-mix(in oklch, var(--info) 25%, transparent); }
  .badge-idle   { background: oklch(100% 0 0 / 0.04); color: var(--fg-faint); border: 1px solid var(--border); }

  /* Large badge variant for version display */
  .badge-lg { padding: 5px 14px; font-size: var(--text-sm); }

  /* Legacy chip aliases */
  .chip {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 6px var(--s4);
    border-radius: 999px;
    font-size: var(--text-sm);
    font-weight: 500;
    background: var(--bg-raised);
    border: 1px solid var(--border);
    color: var(--fg-dim);
  }
  .chip-green { color: var(--ok); }
  .chip-sm    { padding: 4px 10px; font-size: var(--text-xs); }

  /* ── Buttons ────────────────────────────────────────────── */
  .btn {
    display: inline-flex;
    align-items: center;
    gap: var(--s2);
    padding: 9px 20px;
    border-radius: var(--radius-sm);
    font-family: var(--font);
    font-size: var(--text-sm);
    font-weight: 500;
    cursor: pointer;
    border: none;
    transition: background var(--dur-fast), color var(--dur-fast), border-color var(--dur-fast);
    min-height: 44px;
    white-space: nowrap;
  }
  .btn-primary {
    background: var(--accent);
    color: oklch(10% 0.01 250);
  }
  .btn-primary:hover { background: color-mix(in oklch, var(--accent) 85%, white); }
  .btn-secondary {
    background: transparent;
    color: var(--accent);
    border: 1px solid var(--accent-brd);
  }
  .btn-secondary:hover { background: var(--accent-bg); }
  .btn-ghost {
    background: transparent;
    color: var(--fg-dim);
    border: 1px solid var(--border);
  }
  .btn-ghost:hover { background: oklch(100% 0 0 / 0.04); color: var(--fg); }

  /* ── Skeletons ──────────────────────────────────────────── */
  .skeleton {
    background: linear-gradient(
      90deg,
      var(--bg-raised) 25%,
      var(--bg-card)   50%,
      var(--bg-raised) 75%
    );
    background-size: 400px 100%;
    animation: shimmer 1.4s ease infinite;
    border-radius: var(--radius-xs);
  }
  .skeleton-text  { height: 14px; border-radius: 4px; }
  .skeleton-title { height: 20px; border-radius: 4px; }
  .skeleton-card  { height: 120px; border-radius: var(--radius); }

  /* ── Service pills ──────────────────────────────────────── */
  .services-grid { display: flex; flex-wrap: wrap; gap: var(--s3); }
  .service-pill {
    display: flex;
    align-items: center;
    gap: var(--s3);
    padding: var(--s4) 20px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    transition: border-color var(--dur-fast), transform var(--dur-fast), box-shadow var(--dur-fast);
    min-height: 44px;
  }
  .service-pill:hover { border-color: var(--border-h); transform: translateY(-1px); box-shadow: 0 2px 8px oklch(0% 0 0 / .2); }
  .service-pill span { font-weight: 600; font-size: var(--text-base); }
  .service-pill small { color: var(--fg-faint); font-size: var(--text-sm); margin-left: 2px; }

  /* ── Hero (landing page) ────────────────────────────────── */
  .hero {
    position: relative;
    text-align: center;
    padding: 88px 28px 56px;
    max-width: var(--max-w);
    margin: 0 auto;
    overflow: hidden;
  }
  .hero-glow {
    position: absolute;
    top: -30%;
    left: 50%;
    transform: translateX(-50%);
    width: 600px;
    height: 360px;
    background: radial-gradient(ellipse at center,
      color-mix(in oklch, var(--accent) 8%, transparent) 0%,
      transparent 70%);
    pointer-events: none;
    filter: blur(60px);
  }
  .hero-eyebrow {
    font-size: var(--text-xs);
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--accent);
    margin-bottom: var(--s4);
    animation: fadeUp 0.6s var(--ease-out) both;
  }
  .hero-title {
    font-family: var(--font-serif);
    font-weight: 400;
    font-size: var(--text-display);
    line-height: var(--leading-tight);
    letter-spacing: -0.02em;
    color: var(--fg);
    animation: fadeUp 0.6s var(--ease-out) 0.07s both;
  }
  .hero-title em {
    font-style: italic;
    color: var(--accent);
  }
  .hero-sub {
    margin-top: var(--s5);
    font-size: var(--text-md);
    color: var(--fg-dim);
    line-height: var(--leading-body);
    animation: fadeUp 0.6s var(--ease-out) 0.14s both;
  }
  .hero-chips {
    display: flex;
    justify-content: center;
    gap: var(--s3);
    flex-wrap: wrap;
    margin-top: var(--s8);
    animation: fadeUp 0.6s var(--ease-out) 0.21s both;
  }

  @media (max-width: 640px) {
    .hero { padding: 56px var(--s5) 40px; }
  }

  /* ── Placeholder / empty pages ──────────────────────────── */
  .placeholder-page {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    min-height: 60vh;
    padding: var(--s16) 28px;
    max-width: var(--max-w);
    margin: 0 auto;
    animation: fadeUp 0.5s var(--ease-out) both;
  }
  .placeholder-icon {
    width: 64px;
    height: 64px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 18px;
    background: oklch(100% 0 0 / 0.03);
    border: 1px solid var(--border);
    color: var(--fg-faint);
    margin-bottom: var(--s8);
  }
  .placeholder-page h1 {
    font-family: var(--font-serif);
    font-weight: 400;
    font-style: italic;
    font-size: clamp(1.8rem, 4vw, 2.6rem);
    letter-spacing: -0.02em;
    margin-bottom: var(--s3);
  }
  .placeholder-page p { color: var(--fg-dim); font-size: var(--text-md); max-width: 360px; }
  .back-link {
    display: inline-flex;
    align-items: center;
    gap: var(--s2);
    margin-top: var(--s8);
    padding: 10px 20px;
    border-radius: 999px;
    font-size: var(--text-sm);
    font-weight: 500;
    color: var(--accent);
    background: var(--accent-bg);
    border: 1px solid var(--accent-brd);
    transition: background var(--dur-fast);
    min-height: 44px;
  }
  .back-link:hover { background: color-mix(in oklch, var(--accent) 15%, transparent); }

  /* ── Site footer ────────────────────────────────────────── */
  .site-footer {
    max-width: var(--max-w);
    margin: 0 auto;
    padding: var(--s5) 28px var(--s8);
    font-size: var(--text-xs);
    color: var(--fg-faint);
    border-top: 1px solid var(--border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--s3);
  }
  @media (max-width: 640px) {
    .site-footer { padding: var(--s5); flex-direction: column; align-items: flex-start; }
  }

  /* ── Bottom nav (mobile, injected by app.js) ────────────── */
  .bottom-nav {
    display: none;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 200;
    background: color-mix(in oklch, var(--bg) 92%, transparent);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border-top: 1px solid var(--border);
    padding: var(--s2) var(--s2) max(var(--s2), env(safe-area-inset-bottom));
  }
  .bottom-nav-inner {
    display: flex;
    justify-content: space-around;
    align-items: stretch;
    max-width: 480px;
    margin: 0 auto;
  }
  .bottom-nav-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    flex: 1;
    padding: var(--s2) var(--s1);
    border-radius: var(--radius-sm);
    color: var(--fg-faint);
    font-size: 11px;
    font-weight: 500;
    min-height: 52px;
    transition: color var(--dur-fast), background var(--dur-fast), transform 60ms;
    cursor: pointer;
    letter-spacing: -0.01em;
  }
  .bottom-nav-item svg { width: 23px; height: 23px; stroke: currentColor; fill: none; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
  .bottom-nav-item.active { color: var(--accent); background: var(--accent-bg); font-weight: 600; }
  .bottom-nav-item:hover  { color: var(--fg); background: oklch(100% 0 0 / 0.05); }
  .bottom-nav-item:active { transform: scale(0.90); }

  @media (max-width: 640px) {
    .bottom-nav { display: block; }
  }

  /* ── Command palette (injected by app.js) ───────────────── */
  .cmd-backdrop {
    position: fixed;
    inset: 0;
    z-index: 8000;
    background: oklch(5% 0.01 250 / 0.7);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding-top: 15vh;
    animation: fadeIn 0.15s var(--ease-out);
  }
  @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

  .cmd-palette {
    width: 100%;
    max-width: 560px;
    background: var(--bg-overlay);
    border: 1px solid var(--border-h);
    border-radius: var(--radius);
    box-shadow: 0 24px 64px oklch(0% 0 0 / 0.5);
    overflow: hidden;
    animation: cmdIn 0.2s var(--ease-out);
  }
  @keyframes cmdIn {
    from { opacity: 0; transform: translateY(-12px) scale(0.97); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
  }

  .cmd-input-wrap {
    display: flex;
    align-items: center;
    gap: var(--s3);
    padding: var(--s4) var(--s5);
    border-bottom: 1px solid var(--border);
  }
  .cmd-input-wrap svg { width: 18px; height: 18px; color: var(--fg-faint); flex-shrink: 0; stroke: currentColor; fill: none; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
  .cmd-input {
    flex: 1;
    background: none;
    border: none;
    outline: none;
    font-family: var(--font);
    font-size: var(--text-md);
    color: var(--fg);
    caret-color: var(--accent);
  }
  .cmd-input::placeholder { color: var(--fg-faint); }

  .cmd-results {
    max-height: 320px;
    overflow-y: auto;
    padding: var(--s2);
  }
  .cmd-item {
    display: flex;
    align-items: center;
    gap: var(--s3);
    padding: var(--s3) var(--s4);
    border-radius: var(--radius-xs);
    font-size: var(--text-base);
    color: var(--fg-dim);
    cursor: pointer;
    transition: background var(--dur-fast), color var(--dur-fast);
  }
  .cmd-item:hover,
  .cmd-item.selected {
    background: color-mix(in oklch, var(--accent) 8%, transparent);
    color: var(--fg);
  }
  .cmd-item svg { width: 16px; height: 16px; flex-shrink: 0; stroke: currentColor; fill: none; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; color: var(--fg-faint); }
  .cmd-footer {
    padding: var(--s3) var(--s5);
    border-top: 1px solid var(--border);
    display: flex;
    gap: var(--s5);
    font-size: 11px;
    color: var(--fg-faint);
  }
  .cmd-footer kbd {
    font-family: var(--font-mono);
    background: var(--bg-card);
    padding: 1px 5px;
    border-radius: 3px;
    border: 1px solid var(--border-h);
    margin-right: 4px;
  }

  /* ── Net cards ──────────────────────────────────────────── */
  .network-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: var(--s3); }
  .net-card {
    padding: var(--pad-card);
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    transition: border-color var(--dur-fast), transform var(--dur-fast), box-shadow var(--dur-fast);
  }
  .net-card:hover { border-color: var(--border-h); transform: translateY(-1px); box-shadow: 0 4px 14px oklch(0% 0 0 / .22); }
  .net-card:active { transform: scale(0.99); box-shadow: none; transition-duration: 60ms; }
  @media (max-width: 640px) {
    .net-card { padding: 14px 16px; }
  }
  .net-card-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--s3); }
  .net-badge { display: inline-flex; align-items: center; gap: var(--s1); padding: 3px 10px; border-radius: 999px; font-size: var(--text-xs); font-weight: 700; letter-spacing: 0.06em; background: var(--accent-bg); color: var(--accent); border: 1px solid var(--accent-brd); }
  .net-badge.opi { background: oklch(75% 0.12 330 / 0.10); color: oklch(75% 0.12 330); border-color: oklch(75% 0.12 330 / 0.25); }
  .net-ip { font-family: var(--font-mono); font-size: var(--text-xl); font-weight: 700; color: var(--fg); margin-bottom: var(--s1); font-variant-numeric: tabular-nums; }
  .net-desc { font-size: var(--text-sm); color: var(--fg-faint); }
  .bulletin-card { padding: var(--pad-card); background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); color: var(--fg-dim); font-size: var(--text-base); font-style: italic; }

  /* ── Trend chart ────────────────────────────────────────── */
  .trend-chart { display: flex; gap: 6px; align-items: flex-end; padding: 0 4px; }
  .trend-col { display: flex; flex-direction: column; align-items: center; gap: 4px; flex: 1; min-width: 0; }
  .trend-bars { display: flex; flex-direction: column-reverse; gap: 1px; width: 100%; border-radius: 3px 3px 0 0; overflow: hidden; }
  .trend-seg { width: 100%; }
  .s-crit { background: var(--crit); }
  .s-warn { background: var(--warn); }
  .s-info { background: color-mix(in oklch, var(--accent) 45%, transparent); }
  .trend-val { font-size: 11px; color: var(--fg-faint); font-variant-numeric: tabular-nums; text-align: center; min-height: 13px; }
  .trend-day { font-size: 11px; color: var(--fg-faint); text-align: center; white-space: nowrap; }
  .trend-col.today .trend-day { color: var(--accent); font-weight: 700; }
  .trend-col.today .trend-bars { outline: 1px solid var(--accent-brd); border-radius: 3px 3px 0 0; }

  /* ── Severity count chips (large) ───────────────────────── */
  .sev-strip { display: flex; gap: 10px; flex-wrap: wrap; }
  .sev-chip-lg { display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 12px 18px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-card); min-width: 72px; transition: border-color var(--dur-fast), transform var(--dur-fast); }
  .sev-chip-lg:hover { border-color: var(--border-h); transform: translateY(-1px); }
  .sev-chip-lg .sev-n { font-size: 1.6rem; font-weight: 300; line-height: 1; font-variant-numeric: tabular-nums; color: var(--fg-dim); }
  .sev-chip-lg .sev-l { font-size: 10px; letter-spacing: .07em; text-transform: uppercase; color: var(--fg-faint); }
  .sev-chip-lg.sev-crit { border-color: color-mix(in oklch, var(--crit) 30%, transparent); background: var(--crit-bg); }
  .sev-chip-lg.sev-crit .sev-n { color: var(--crit); }
  .sev-chip-lg.sev-warn { border-color: color-mix(in oklch, var(--warn) 30%, transparent); background: var(--warn-bg); }
  .sev-chip-lg.sev-warn .sev-n { color: var(--warn); }
  .sev-chip-lg.sev-info .sev-n { color: var(--accent); }
  .sev-chip-lg.sev-ok { border-color: color-mix(in oklch, var(--ok) 30%, transparent); background: var(--ok-bg); }
  .sev-chip-lg.sev-ok .sev-n { color: var(--ok); }

  /* ── Prose / markdown content ──────────────────────────── */
  .markdown {
    max-width: var(--max-w);
    margin: 0 auto;
    padding: var(--s8) 28px var(--s16);
    line-height: var(--leading-body);
  }
  .markdown h1 {
    font-family: var(--font-serif);
    font-weight: 400;
    font-style: italic;
    font-size: clamp(1.8rem, 4vw, 2.6rem);
    letter-spacing: -0.02em;
    margin-bottom: var(--s6);
    line-height: var(--leading-tight);
  }
  .markdown h2 {
    font-size: var(--text-lg);
    font-weight: 600;
    letter-spacing: -0.01em;
    margin-top: var(--s10);
    margin-bottom: var(--s4);
    color: var(--fg);
  }
  .markdown h3 {
    font-size: var(--text-md);
    font-weight: 600;
    margin-top: var(--s6);
    margin-bottom: var(--s3);
    color: var(--fg-dim);
  }
  .markdown p { margin-bottom: var(--s4); color: var(--fg-dim); }
  .markdown ul, .markdown ol {
    padding-left: var(--s6);
    margin-bottom: var(--s5);
    display: flex;
    flex-direction: column;
    gap: var(--s2);
  }
  .markdown li { color: var(--fg-dim); }
  .markdown code {
    font-family: var(--font-mono);
    font-size: var(--text-sm);
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-xs);
    padding: 1px 6px;
    color: var(--accent);
  }
  .markdown a { color: var(--accent); }
  .markdown a:hover { text-decoration: underline; }
  @media (max-width: 640px) {
    .markdown { padding: var(--s6) var(--s5) var(--s12); }
  }

  /* ── Data flash (value changed) ─────────────────────────── */
  @keyframes dataFlash {
    0%   { color: var(--ok); }
    100% { color: inherit; }
  }
  .flashed { animation: dataFlash 0.4s ease; }
}

@layer utilities {
  /* Accessibility */
  .sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0,0,0,0);
    white-space: nowrap;
    border: 0;
  }

  /* Focus */
  :focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
    border-radius: 4px;
  }

  /* Typography helpers */
  .mono    { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
  .tabular { font-variant-numeric: tabular-nums; }
  .serif   { font-family: var(--font-serif); }
  .dim     { color: var(--fg-dim); }
  .faint   { color: var(--fg-faint); }
  .ok      { color: var(--ok); }
  .warn    { color: var(--warn); }
  .crit    { color: var(--crit); }
  .accent  { color: var(--accent); }

  /* Touch targets */
  .touch { min-height: 44px; min-width: 44px; }

  /* Global empty state */
  .empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--s3);
    padding: var(--s10) var(--s6);
    text-align: center;
    color: var(--fg-faint);
    font-size: var(--text-sm);
  }
  .empty-state::before {
    content: '—';
    font-size: 1.4rem;
    color: var(--border-h);
    line-height: 1;
  }

  /* Truncate long text */
  .truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  /* Word-wrap for event bodies */
  .break-words { word-break: break-word; overflow-wrap: anywhere; }

  /* Shared: empty / no-data inline text */
  .no-data { color: var(--fg-faint); font-style: italic; font-size: 14px; }

  /* Controls: device state classes (H12) */
  .unavail { opacity: 0.5; }
  .temp-proxy { opacity: 0.75; }
  .mode-cool { color: var(--accent); }
  .mode-heat { color: oklch(72% 0.18 35); }
  .mode-idle { color: var(--fg-dim); }
  .lock-locked { color: var(--ok); }
  .lock-unlocked { color: var(--warn); }
  .batt-crit { color: var(--crit); }
  .batt-warn { color: var(--warn); }
  .batt-warn-border { border-left: 3px solid color-mix(in oklch, var(--crit) 60%, transparent); }

  /* Stale-data / connection-lost toast banner (app.js) */
  .ga-stale-banner {
    position: fixed; bottom: 72px; left: 50%; transform: translateX(-50%);
    background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px;
    padding: 8px 14px; font-size: 12px; color: var(--fg-dim); z-index: 9999;
    box-shadow: 0 4px 16px oklch(0% 0 0 / .4); pointer-events: none; white-space: nowrap;
  }
  .ga-stale-banner.warn { color: var(--warn, #f59e0b); }

  /* CA cert install banner (app.js) */
  .gc-ca-bar {
    position: fixed; bottom: 64px; left: 0; right: 0; z-index: 9100;
    background: var(--bg); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
    color: var(--fg-dim); font-size: 13px; padding: 10px 14px 10px 16px;
    display: flex; align-items: center; gap: 12px;
    border-top: 1px solid var(--accent-brd);
    box-shadow: 0 -2px 16px oklch(0% 0 0 / .4);
  }
  .gc-ca-bar-text { flex: 1; line-height: 1.4; }
  .gc-ca-link { color: var(--accent); font-weight: 600; }
  .gc-ca-dismiss {
    flex-shrink: 0; background: var(--accent-bg); border: 1px solid var(--border-act);
    color: var(--accent); padding: 4px 12px; border-radius: 6px;
    font-size: 12px; font-weight: 600; cursor: pointer; white-space: nowrap; font-family: inherit;
  }
}
