/* matrix-ui.css — the shadcn-grounded design system for matrix.dnode.ca.
 * Extracted from the approved redesign mockup. Self-contained: system-font
 * stack, CSS-variable tokens, light+dark. Pages opt in by linking this file
 * and using the v2 shell; pages still on the old shell are unaffected.
 * NOTE: .page/.active SPA-toggle rules are harmless for real multi-page use. */

/* ============ TOKENS (shadcn-grounded, broadcast-tuned) ============ */
  :root{
    --radius: 0.65rem;
    --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, "Helvetica Neue", sans-serif;
    --font-mono: "SF Mono", ui-monospace, "JetBrains Mono", "Cascadia Code", Menlo, Consolas, monospace;

    /* light theme (default) */
    --bg: 240 20% 99%;
    --fg: 240 12% 12%;
    --card: 0 0% 100%;
    --elevated: 240 30% 99%;
    --muted: 240 6% 95%;
    --muted-fg: 240 4% 44%;
    --border: 240 6% 89%;
    --ring: 243 75% 58%;
    --primary: 243 75% 58%;
    --primary-fg: 0 0% 100%;
    --sidebar: 240 24% 98%;
    --sidebar-border: 240 6% 90%;

    --live: 152 60% 38%;
    --live-soft: 152 55% 92%;
    --warn: 33 90% 44%;
    --warn-soft: 40 90% 92%;
    --danger: 0 72% 48%;
    --danger-soft: 0 80% 95%;
    --idle: 240 4% 58%;

    --shadow-sm: 0 1px 2px 0 hsl(240 20% 20% / .06);
    --shadow-md: 0 8px 24px -8px hsl(240 30% 20% / .14);
  }
  @media (prefers-color-scheme: dark){
    :root{
      --bg: 240 12% 5%;
      --fg: 240 14% 92%;
      --card: 240 11% 8%;
      --elevated: 240 10% 11%;
      --muted: 240 8% 14%;
      --muted-fg: 240 6% 60%;
      --border: 240 8% 16%;
      --ring: 243 82% 68%;
      --primary: 243 82% 67%;
      --primary-fg: 240 40% 8%;
      --sidebar: 240 13% 4%;
      --sidebar-border: 240 9% 13%;

      --live: 151 58% 47%;
      --live-soft: 152 45% 14%;
      --warn: 38 92% 56%;
      --warn-soft: 36 60% 14%;
      --danger: 0 74% 60%;
      --danger-soft: 0 55% 15%;
      --idle: 240 5% 42%;

      --shadow-sm: 0 1px 2px 0 hsl(240 40% 2% / .5);
      --shadow-md: 0 12px 32px -10px hsl(240 60% 2% / .6);
    }
  }
  /* explicit toggle wins over OS in BOTH directions */
  :root[data-theme="light"]{
    --bg:240 20% 99%; --fg:240 12% 12%; --card:0 0% 100%; --elevated:240 30% 99%;
    --muted:240 6% 95%; --muted-fg:240 4% 44%; --border:240 6% 89%; --ring:243 75% 58%;
    --primary:243 75% 58%; --primary-fg:0 0% 100%; --sidebar:240 24% 98%; --sidebar-border:240 6% 90%;
    --live:152 60% 38%; --live-soft:152 55% 92%; --warn:33 90% 44%; --warn-soft:40 90% 92%;
    --danger:0 72% 48%; --danger-soft:0 80% 95%; --idle:240 4% 58%;
    --shadow-sm:0 1px 2px 0 hsl(240 20% 20% / .06); --shadow-md:0 8px 24px -8px hsl(240 30% 20% / .14);
  }
  :root[data-theme="dark"]{
    --bg:240 12% 5%; --fg:240 14% 92%; --card:240 11% 8%; --elevated:240 10% 11%;
    --muted:240 8% 14%; --muted-fg:240 6% 60%; --border:240 8% 16%; --ring:243 82% 68%;
    --primary:243 82% 67%; --primary-fg:240 40% 8%; --sidebar:240 13% 4%; --sidebar-border:240 9% 13%;
    --live:151 58% 47%; --live-soft:152 45% 14%; --warn:38 92% 56%; --warn-soft:36 60% 14%;
    --danger:0 74% 60%; --danger-soft:0 55% 15%; --idle:240 5% 42%;
    --shadow-sm:0 1px 2px 0 hsl(240 40% 2% / .5); --shadow-md:0 12px 32px -10px hsl(240 60% 2% / .6);
  }

  *,*::before,*::after{box-sizing:border-box}
  html{-webkit-text-size-adjust:100%}
  body{
    margin:0; font-family:var(--font-sans);
    background:hsl(var(--bg)); color:hsl(var(--fg));
    font-size:14px; line-height:1.5; -webkit-font-smoothing:antialiased;
    font-feature-settings:"cv11","ss01";
  }
  a{color:inherit;text-decoration:none}
  button{font-family:inherit}
  :focus-visible{outline:2px solid hsl(var(--ring)); outline-offset:2px; border-radius:6px}
  ::selection{background:hsl(var(--primary)/.25)}

  /* ============ LAYOUT ============ */
  .layout{display:grid; grid-template-columns:248px 1fr; min-height:100vh}
  .layout.collapsed{grid-template-columns:64px 1fr}

  /* ---- Sidebar ---- */
  .sidebar{
    background:hsl(var(--sidebar)); border-right:1px solid hsl(var(--sidebar-border));
    display:flex; flex-direction:column; position:sticky; top:0; height:100vh; overflow:hidden; z-index:40;
  }
  .brand{display:flex; align-items:center; gap:.6rem; padding:.95rem .85rem; height:57px; border-bottom:1px solid hsl(var(--sidebar-border))}
  /* the company mark — assets/img/matrix-logo.png carries its own dark ground */
  .brand-mark{width:30px;height:30px;border-radius:9px;flex:none;overflow:hidden;
    display:grid;place-items:center; box-shadow:0 0 0 1px hsl(var(--primary)/.4), var(--shadow-sm)}
  .brand-mark img{width:100%;height:100%;object-fit:cover;display:block}
  .brand-txt{display:flex;flex-direction:column;line-height:1.05;min-width:0}
  .brand-txt b{font-size:.85rem;font-weight:650;letter-spacing:-.01em}
  .brand-txt span{font-size:.66rem;color:hsl(var(--muted-fg));letter-spacing:.02em}
  .collapsed .brand-txt, .collapsed .nav-group-label, .collapsed .nav-link .lbl, .collapsed .nav-badge, .collapsed .side-foot .u-meta{display:none}
  .collapsed .brand{justify-content:center;padding-inline:0}
  .collapsed .nav-link{justify-content:center;padding-inline:0}

  .nav{flex:1; overflow-y:auto; padding:.7rem .6rem; display:flex;flex-direction:column;gap:.75rem}
  .nav::-webkit-scrollbar{width:8px}
  .nav::-webkit-scrollbar-thumb{background:hsl(var(--border));border-radius:8px}
  .nav-group-label{font-size:.66rem;text-transform:uppercase;letter-spacing:.09em;color:hsl(var(--muted-fg));
    padding:0 .55rem .3rem; font-weight:600}
  .nav-list{display:flex;flex-direction:column;gap:4px}
  /* Geometry follows shadcn's SidebarMenuButton size="sm": h-7 (28px), gap-2, p-2,
     rounded-md, [&>svg]:size-4 — with SidebarMenu's gap-1 above. The rail was 39px
     per row before; the height (not the gap, which was already tighter than shadcn's)
     was what made it read loose. 13 items no longer overflow a 560px rail. */
  .nav-link{
    display:flex;align-items:center;gap:.5rem;height:28px;padding:0 .5rem;border-radius:6px;
    color:hsl(var(--fg)/.78); font-size:.78rem;font-weight:500;position:relative;cursor:pointer;
    border:1px solid transparent; transition:background .12s, color .12s;
  }
  .nav-link svg{width:16px;height:16px;flex:none;color:hsl(var(--muted-fg));transition:color .12s}
  /* The Account group drops to the foot of the rail behind a rule, so it reads as
     chrome rather than as another destination alongside Platform. `:not(:first-child)`
     guards the case where app_nav_sections() returns no secondary group — without it
     the PRIMARY nav would get pinned to the bottom instead. */
  .nav > div:last-child:not(:first-child){
    margin-top:auto; border-top:1px solid hsl(var(--sidebar-border)); padding-top:.7rem;
  }
  /* hover + active = the TEXT turns the accent colour. No box, no outline. */
  .nav-link:hover{color:hsl(var(--primary))}
  .nav-link:hover svg{color:hsl(var(--primary))}
  .nav-link.active{color:hsl(var(--primary));font-weight:600}
  .nav-link.active svg{color:hsl(var(--primary))}
  /* keyboard focus stays visible for a11y (invisible to mouse users) */
  .nav-link:focus-visible{outline:2px solid hsl(var(--ring));outline-offset:-2px}
  .nav-badge{margin-left:auto;font-size:.6rem;font-weight:600;padding:.1rem .38rem;border-radius:6px;
    background:hsl(var(--muted));color:hsl(var(--muted-fg));text-transform:uppercase;letter-spacing:.04em}
  .nav-badge.live{background:hsl(var(--live)/.16);color:hsl(var(--live))}
  .side-foot{border-top:1px solid hsl(var(--sidebar-border));padding:.6rem;display:flex;align-items:center;gap:.55rem}
  .avatar{width:30px;height:30px;border-radius:8px;flex:none;background:hsl(var(--muted));display:grid;place-items:center;
    font-size:.72rem;font-weight:650;color:hsl(var(--fg))}
  .u-meta{min-width:0;line-height:1.15}
  .u-meta b{font-size:.78rem;font-weight:600;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .u-meta span{font-size:.68rem;color:hsl(var(--muted-fg))}

  /* ---- Main + topbar ---- */
  .main{display:flex;flex-direction:column;min-width:0}
  .topbar{
    position:sticky;top:0;z-index:30;height:57px;display:flex;align-items:center;gap:.85rem;
    padding:0 1.4rem; border-bottom:1px solid hsl(var(--border));
    background:hsl(var(--bg)/.82); backdrop-filter:blur(10px) saturate(140%);
  }
  .icon-btn{width:34px;height:34px;border-radius:8px;border:1px solid hsl(var(--border));background:hsl(var(--card));
    display:grid;place-items:center;cursor:pointer;color:hsl(var(--fg));transition:background .12s,border-color .12s}
  .icon-btn:hover{background:hsl(var(--muted))}
  .icon-btn svg{width:17px;height:17px}
  /* The collapse chevron points where the nav is GOING, not where it is:
     "<" while expanded (click to tuck it away), ">" once collapsed (click to bring
     it back). Rotating rather than swapping icons keeps the motion readable. */
  [data-collapse] svg{transition:transform .22s ease}
  .layout.collapsed [data-collapse] svg{transform:rotate(180deg)}
  .crumbs{display:flex;align-items:center;gap:.5rem;min-width:0}
  .crumbs .pg{font-weight:650;font-size:.98rem;letter-spacing:-.01em}
  .crumbs .sub{color:hsl(var(--muted-fg));font-size:.8rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .sep{color:hsl(var(--border))}
  .spacer{flex:1}
  .sync-pill{display:inline-flex;align-items:center;gap:.5rem;font-size:.74rem;color:hsl(var(--muted-fg));
    padding:.32rem .6rem;border-radius:999px;border:1px solid hsl(var(--border));background:hsl(var(--card))}
  .sync-dot{width:7px;height:7px;border-radius:999px;background:hsl(var(--live))}
  .sync-pill.pulling .sync-dot{background:hsl(var(--warn))}

  .content{padding:1.5rem 1.4rem 3rem;max-width:1200px;width:100%;margin:0 auto;display:flex;flex-direction:column;gap:1.25rem}
  .page{display:none}
  .page.active{display:flex;flex-direction:column;gap:1.25rem;animation:fade .22s ease}
  @keyframes fade{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}

  /* ============ PRIMITIVES ============ */
  .card{background:hsl(var(--card));border:1px solid hsl(var(--border));border-radius:var(--radius);box-shadow:var(--shadow-sm)}
  .card-pad{padding:1.05rem 1.15rem}
  .card-head{display:flex;align-items:flex-start;justify-content:space-between;gap:1rem;padding:1rem 1.15rem;border-bottom:1px solid hsl(var(--border))}
  .card-title{font-weight:620;font-size:.95rem;letter-spacing:-.01em}
  .card-desc{color:hsl(var(--muted-fg));font-size:.8rem;margin-top:.15rem}

  .h-eyebrow{font-size:.68rem;text-transform:uppercase;letter-spacing:.11em;color:hsl(var(--muted-fg));font-weight:650}
  .row{display:flex;align-items:center;gap:.6rem}
  .between{display:flex;align-items:center;justify-content:space-between;gap:1rem}
  .wrap{flex-wrap:wrap}
  .grid{display:grid;gap:.9rem}
  .muted{color:hsl(var(--muted-fg))}
  .mono{font-family:var(--font-mono);font-variant-numeric:tabular-nums;letter-spacing:-.01em}
  .num{font-variant-numeric:tabular-nums}

  /* buttons */
  .btn{display:inline-flex;align-items:center;justify-content:center;gap:.45rem;height:34px;padding:0 .8rem;
    border-radius:8px;font-size:.83rem;font-weight:550;cursor:pointer;border:1px solid transparent;
    background:hsl(var(--muted));color:hsl(var(--fg));transition:background .12s,border-color .12s,transform .06s;white-space:nowrap}
  .btn:active{transform:translateY(.5px)}
  .btn svg{width:15px;height:15px}
  .btn-primary{background:hsl(var(--primary));color:hsl(var(--primary-fg))}
  .btn-primary:hover{background:hsl(var(--primary)/.9)}
  .btn-outline{background:transparent;border-color:hsl(var(--border));color:hsl(var(--fg))}
  .btn-outline:hover{background:hsl(var(--muted))}
  .btn-ghost{background:transparent;color:hsl(var(--muted-fg))}
  .btn-ghost:hover{background:hsl(var(--muted));color:hsl(var(--fg))}
  .btn-danger{background:hsl(var(--danger)/.12);color:hsl(var(--danger));border-color:hsl(var(--danger)/.22)}
  .btn-danger:hover{background:hsl(var(--danger)/.18)}
  .btn-sm{height:28px;padding:0 .6rem;font-size:.77rem;border-radius:7px}
  .btn:disabled{opacity:.45;cursor:not-allowed}
  /* standardise action buttons so pairs (Start/Stop, Enable/Disable) are identical footprints */
  .btn-sm:not(.btn-ghost){min-width:74px}
  .btn-ghost{min-width:0;padding-inline:.4rem}
  .btn-group{display:inline-flex;gap:.4rem;flex:none}
  .btn-group .btn{flex:1}

  /* badges / pills */
  .badge{display:inline-flex;align-items:center;gap:.35rem;font-size:.72rem;font-weight:600;padding:.16rem .5rem;
    border-radius:999px;border:1px solid transparent;white-space:nowrap;line-height:1}
  .badge-live{background:hsl(var(--live)/.14);color:hsl(var(--live));border-color:hsl(var(--live)/.2)}
  .badge-warn{background:hsl(var(--warn)/.14);color:hsl(var(--warn));border-color:hsl(var(--warn)/.24)}
  .badge-danger{background:hsl(var(--danger)/.13);color:hsl(var(--danger));border-color:hsl(var(--danger)/.22)}
  .badge-idle{background:hsl(var(--muted));color:hsl(var(--muted-fg));border-color:hsl(var(--border))}
  .badge-outline{background:transparent;color:hsl(var(--muted-fg));border-color:hsl(var(--border))}

  /* status dot */
  .dot{width:9px;height:9px;border-radius:999px;flex:none;position:relative;background:hsl(var(--idle))}
  .dot.on{background:hsl(var(--live))}
  .dot.warn{background:hsl(var(--warn))}
  .dot.bad{background:hsl(var(--danger))}
  .dot.on::after{content:"";position:absolute;inset:-4px;border-radius:999px;border:2px solid hsl(var(--live)/.5);animation:ping 1.8s cubic-bezier(0,0,.2,1) infinite}
  @keyframes ping{0%{transform:scale(.7);opacity:.9}80%,100%{transform:scale(1.9);opacity:0}}

  /* stat cards */
  .stats{display:grid;grid-template-columns:repeat(5,1fr);gap:.9rem}
  .stat{background:hsl(var(--card));border:1px solid hsl(var(--border));border-radius:var(--radius);padding:.95rem 1rem;
    display:flex;flex-direction:column;gap:.35rem;box-shadow:var(--shadow-sm);position:relative;overflow:hidden}
  .stat .lbl{font-size:.72rem;color:hsl(var(--muted-fg));font-weight:550;display:flex;align-items:center;gap:.4rem}
  .stat .val{font-size:1.7rem;font-weight:680;letter-spacing:-.02em;font-variant-numeric:tabular-nums;line-height:1.1}
  .stat .val small{font-size:.9rem;font-weight:600;color:hsl(var(--muted-fg))}
  .stat .foot{font-size:.72rem;color:hsl(var(--muted-fg));display:flex;align-items:center;gap:.35rem}
  .trend-up{color:hsl(var(--live));font-weight:600}
  .stat-spark{position:absolute;right:0;bottom:0;opacity:.5;pointer-events:none}

  /* tables */
  .tbl{width:100%;border-collapse:collapse;font-size:.83rem}
  .tbl th{text-align:left;font-weight:600;color:hsl(var(--muted-fg));font-size:.71rem;text-transform:uppercase;
    letter-spacing:.05em;padding:.55rem .9rem;border-bottom:1px solid hsl(var(--border));background:hsl(var(--muted)/.4)}
  .tbl td{padding:.6rem .9rem;border-bottom:1px solid hsl(var(--border));vertical-align:middle}
  .tbl tr:last-child td{border-bottom:none}
  .tbl tbody tr{transition:background .1s}
  .tbl tbody tr:hover{background:hsl(var(--muted)/.45)}
  .tbl .r{text-align:right}
  .tbl-wrap{overflow-x:auto}
  .cellname{font-weight:600}
  .cellsub{font-size:.72rem;color:hsl(var(--muted-fg))}

  /* switch */
  .switch{position:relative;width:38px;height:22px;border-radius:999px;background:hsl(var(--muted));cursor:pointer;
    border:1px solid hsl(var(--border));transition:background .16s;flex:none}
  .switch::after{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:999px;background:#fff;
    box-shadow:var(--shadow-sm);transition:left .16s}
  .switch.on{background:hsl(var(--live))}
  .switch.on::after{left:18px}

  /* skeleton */
  .skel{background:linear-gradient(100deg,hsl(var(--muted)) 30%,hsl(var(--muted)/.5) 50%,hsl(var(--muted)) 70%);
    background-size:200% 100%;animation:sk 1.3s ease-in-out infinite;border-radius:6px}
  @keyframes sk{0%{background-position:200% 0}100%{background-position:-200% 0}}
  .loading-only{display:none}
  .page.is-loading .loading-only{display:block}
  .page.is-loading .data-only{display:none}

  /* input & quick-create */
  .field{display:flex;flex-direction:column;gap:.32rem}
  .field label{font-size:.68rem;text-transform:uppercase;letter-spacing:.06em;color:hsl(var(--muted-fg));font-weight:600}
  .input{height:34px;background:hsl(var(--bg));border:1px solid hsl(var(--border));border-radius:8px;padding:0 .65rem;
    color:hsl(var(--fg));font-size:.85rem;width:100%}
  .input:focus{outline:none;border-color:hsl(var(--ring));box-shadow:0 0 0 3px hsl(var(--ring)/.16)}
  .copyfield{display:flex;align-items:center;gap:.5rem;background:hsl(var(--muted)/.55);border:1px solid hsl(var(--border));
    border-radius:8px;padding:.35rem .5rem .35rem .65rem}
  .copyfield .v{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.78rem}
  .copy{width:26px;height:26px;border-radius:6px;border:1px solid hsl(var(--border));background:hsl(var(--card));
    display:grid;place-items:center;cursor:pointer;color:hsl(var(--muted-fg));flex:none}
  .copy:hover{color:hsl(var(--fg));background:hsl(var(--muted))}
  .copy svg{width:13px;height:13px}

  /* resource row (flows/channels) */
  .rrow{display:flex;align-items:center;gap:.85rem;padding:.85rem 1.05rem;border-bottom:1px solid hsl(var(--border))}
  .rrow:last-child{border-bottom:none}
  .rrow .meta{flex:1;min-width:0}
  .rrow .meta b{font-weight:600;font-size:.9rem}
  .rrow .meta .sub{font-size:.74rem;color:hsl(var(--muted-fg));margin-top:.1rem}
  .chips{display:flex;gap:.35rem;flex-wrap:wrap}
  .chip{font-size:.7rem;font-family:var(--font-mono);color:hsl(var(--muted-fg));background:hsl(var(--muted)/.6);
    border:1px solid hsl(var(--border));border-radius:6px;padding:0 .45rem;height:24px;display:inline-flex;align-items:center}

  /* distribution output rows — switch sits tight to the row, vertically centred */
  .out-list{display:flex;flex-direction:column;border:1px solid hsl(var(--border));border-radius:var(--radius);overflow:hidden}
  .out-row{display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:.7rem .9rem;border-bottom:1px solid hsl(var(--border))}
  .out-row:last-child{border-bottom:none}
  .out-row .out-meta{min-width:0}
  .out-row .switch{flex:none}
  .toggle-line{display:inline-flex;align-items:center;gap:.5rem;font-size:.83rem;user-select:none}

  /* status page */
  .hero-status{display:flex;align-items:center;gap:1rem}
  .hero-ring{width:46px;height:46px;border-radius:13px;display:grid;place-items:center;flex:none}
  .hero-ring.good{background:hsl(var(--live)/.15);color:hsl(var(--live))}
  .svc-row{display:flex;align-items:center;gap:.85rem;padding:.8rem 1.05rem;border-bottom:1px solid hsl(var(--border))}
  .svc-row:last-child{border-bottom:none}
  .svc-row .svc-meta{flex:1;min-width:0}

  /* account page */
  .form-grid{display:flex;flex-direction:column;gap:1rem;max-width:560px}
  .checkline{display:flex;align-items:center;gap:.55rem;font-size:.83rem}
  .checkbox{width:18px;height:18px;border-radius:5px;border:1.5px solid hsl(var(--border));background:hsl(var(--bg));flex:none;cursor:pointer;display:grid;place-items:center}
  .checkbox.on{background:hsl(var(--primary));border-color:hsl(var(--primary))}
  .checkbox svg{width:12px;height:12px;color:hsl(var(--primary-fg));opacity:0}
  .checkbox.on svg{opacity:1}

  /* signal strip (the signature element) */
  .signal{display:flex;align-items:center;gap:.9rem;flex-wrap:wrap;font-family:var(--font-mono);font-size:.76rem;color:hsl(var(--muted-fg))}
  .signal .seg{display:flex;align-items:center;gap:.35rem}
  .signal .seg b{color:hsl(var(--fg));font-weight:600}
  .signal .div{width:1px;height:12px;background:hsl(var(--border))}

  /* section title */
  .sec-title{display:flex;align-items:center;gap:.6rem;font-weight:620;font-size:.92rem}
  .count-tag{font-size:.7rem;font-weight:600;color:hsl(var(--muted-fg));background:hsl(var(--muted));border-radius:6px;padding:.1rem .4rem}

  /* banner */
  .banner{display:flex;align-items:center;gap:.7rem;padding:.7rem .95rem;border-radius:var(--radius);
    border:1px solid hsl(var(--primary)/.25);background:hsl(var(--primary)/.07);font-size:.82rem}
  .banner svg{width:16px;height:16px;color:hsl(var(--primary));flex:none}
  .banner.warn{border-color:hsl(var(--warn)/.3);background:hsl(var(--warn)/.09)}
  .banner.warn svg{color:hsl(var(--warn))}

  /* toast */
  .toast{position:fixed;bottom:20px;left:50%;transform:translateX(-50%) translateY(20px);opacity:0;
    background:hsl(var(--fg));color:hsl(var(--bg));padding:.55rem .9rem;border-radius:9px;font-size:.82rem;font-weight:500;
    box-shadow:var(--shadow-md);transition:.2s;z-index:80;pointer-events:none}
  .toast.show{opacity:1;transform:translateX(-50%) translateY(0)}

  /* chart */
  .chart{width:100%;height:150px;display:block}
  .chart-grid{stroke:hsl(var(--border));stroke-width:1}
  .chart-area{fill:url(#areaGrad)}
  .chart-line{fill:none;stroke:hsl(var(--primary));stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
  .chart-end{fill:hsl(var(--primary));stroke:hsl(var(--card));stroke-width:2}

  .mobile-only{display:none}
  .backdrop{display:none}

  /* ============ RESPONSIVE ============ */
  @media (max-width:1080px){
    .stats{grid-template-columns:repeat(2,1fr)}
    .g3{grid-template-columns:1fr !important}
  }
  @media (max-width:860px){
    .layout{grid-template-columns:1fr}
    .sidebar{position:fixed;left:0;top:0;width:248px;transform:translateX(-100%);transition:transform .22s ease;box-shadow:var(--shadow-md)}
    .layout.mobile-open .sidebar{transform:translateX(0)}
    .backdrop{display:none;position:fixed;inset:0;background:hsl(240 30% 3% / .5);z-index:35}
    .layout.mobile-open .backdrop{display:block}
    .mobile-only{display:grid}
    .crumbs .sub{display:none}
    .content{padding:1.1rem 1rem 3rem}
  }
  @media (max-width:560px){
    .stats{grid-template-columns:1fr 1fr}
    .hide-sm{display:none !important}
  }
  @media (prefers-reduced-motion:reduce){
    *{animation-duration:.001ms !important;animation-iteration-count:1 !important;transition-duration:.001ms !important}
    .dot.on::after{display:none}
  }

/* --- row titles that deep-link to their resource (dashboard + flows) ---
 * Underline on hover only: a list of these should still scan as a list, not as a
 * wall of links. */
.rowlink{color:inherit;text-decoration:none}
.rowlink:hover b{color:hsl(var(--primary));text-decoration:underline;text-underline-offset:2px}
.rowlink:focus-visible b{color:hsl(var(--primary))}

/* --- deep-link arrival: ring the row the operator asked for, briefly --- */
@keyframes deepflash{0%,100%{box-shadow:0 0 0 0 hsl(var(--primary)/0)}12%,62%{box-shadow:0 0 0 3px hsl(var(--primary)/.45)}}
.deep-flash{animation:deepflash 1.9s ease;border-radius:var(--radius)}
@media (prefers-reduced-motion:reduce){
  /* no pulse, but still mark the row — the point is orientation, not motion */
  .deep-flash{animation:none;box-shadow:0 0 0 3px hsl(var(--primary)/.45)}
}

/* --- icon-only actions (Inputs / Channels / Distribution / Players) ---
 * Square footprint; the label lives in aria-label + title, never on screen.
 * Declared AFTER `.btn-sm:not(.btn-ghost){min-width:74px}` on purpose: that rule
 * has the same specificity, so source order is what lets a fixed width win. */
.btn-icon{min-width:0;width:34px;padding:0;flex:none}
.btn-sm.btn-icon{min-width:0;width:28px}
.btn-icon svg{width:15px;height:15px}
.btn-sm.btn-icon svg{width:14px;height:14px}
/* Quiet destructive: reads neutral in a list and only commits to red on hover,
 * so a column of delete buttons doesn't shout at an operator scanning rows. */
.btn-quiet-danger{background:transparent;border-color:transparent;color:hsl(var(--muted-fg))}
.btn-quiet-danger:hover{background:hsl(var(--danger)/.12);color:hsl(var(--danger))}
.btn-quiet-danger:focus-visible{color:hsl(var(--danger))}

/* --- nav submenu (Graphics → Graphics / Health check) ---
 * All-new selectors, so every existing page is byte-identical until an item in
 * app_nav_sections() declares `children`. The parent row keeps its own link and
 * gains a sibling chevron; the submenu is a plain indented list hung off the
 * rail's rule so it reads as "inside Graphics", not as two more destinations. */
.nav-parent{display:flex;align-items:center;gap:2px}
.nav-parent > .nav-link{flex:1;min-width:0}
.nav-chev{width:22px;height:26px;flex:none;display:grid;place-items:center;border:1px solid transparent;
  border-radius:6px;background:transparent;color:hsl(var(--muted-fg));cursor:pointer;padding:0}
.nav-chev:hover{background:hsl(var(--muted));color:hsl(var(--fg))}
.nav-chev svg{width:13px;height:13px;transition:transform .16s ease}
.nav-chev[aria-expanded="true"] svg{transform:rotate(90deg)}
.nav-sub{display:none;flex-direction:column;gap:2px;margin:2px 0 2px .95rem;padding-left:.6rem;
  border-left:1px solid hsl(var(--sidebar-border))}
.nav-sub.is-open{display:flex}
.nav-sub .nav-link{height:26px;font-size:.75rem}
/* Collapsed rail is a 64px icon strip — a text-only submenu has nothing to show
 * there, and the chevron would be a second hit target inside a 40px column. */
.collapsed .nav-sub,
.collapsed .nav-chev{display:none}
.collapsed .nav-parent{display:block}
@media (prefers-reduced-motion:reduce){.nav-chev svg{transition:none}}

/* --- button loading state + inline spinner (shared action UX) --- */
.btn-spin{width:13px;height:13px;border-radius:999px;border:2px solid currentColor;border-top-color:transparent;display:inline-block;animation:btnspin .6s linear infinite;flex:none;vertical-align:-2px}
.btn.is-loading{pointer-events:none;opacity:.9}
.icon-btn.is-loading{pointer-events:none;opacity:.9}
@keyframes btnspin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.btn-spin{animation-duration:1.2s}}
