.btn{font-family:var(--font-ui);font-size:13px;font-weight:500;padding:8px 14px;border-radius:var(--r-sm);border:1px solid transparent;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;gap:7px;line-height:1;background:var(--bg-raised);color:var(--text-1);transition:background .15s,border-color .15s,color .15s}
.btn svg{width:15px;height:15px}
@keyframes icon-spin360{to{transform:rotate(360deg)}}
.icon-spin{animation:icon-spin360 .8s linear infinite;transform-origin:center}
.btn-primary{background:var(--accent-strong);color:#fff;border-color:transparent}
.btn-primary:hover{background:var(--accent)}
.btn-secondary{background:var(--bg-raised);color:var(--text-1);border-color:var(--border)}
.btn-secondary:hover{background:var(--bg-2);border-color:var(--border-strong)}
.btn-ghost{background:transparent;color:var(--text-2);border-color:transparent}
.btn-ghost:hover{background:var(--bg-raised);color:var(--text-1)}
.btn-icon{padding:7px;gap:0}
.btn:disabled{opacity:.5;cursor:not-allowed}
.state{margin:auto;max-width:34ch;text-align:center;padding:var(--s5);color:var(--text-muted)}
.state h3{color:var(--text-1);font-size:14px;margin-bottom:4px}
.state .skel{height:13px;border-radius:5px;background:linear-gradient(90deg,#16202f 25%,#1d293b 50%,#16202f 75%);background-size:200% 100%;animation:sh 1.3s infinite;margin:9px auto;max-width:240px}
@keyframes sh{0%{background-position:200% 0}100%{background-position:-200% 0}}

/* ── btn-danger (solid, confirmDialog) + danger-ghost (subtle destructive) ──── */
.btn-danger{background:var(--danger-strong);color:#fff;border-color:transparent}
.btn-danger:hover{background:var(--danger)}
.btn-danger-ghost{background:transparent;color:var(--danger);border-color:color-mix(in srgb,var(--danger) 30%,transparent)}
.btn-danger-ghost:hover{background:var(--danger-dim);border-color:var(--danger)}

/* ── Badge ───────────────────────────────────────────────────────────────────
   <span class="badge badge-<variant>"> */
.badge{display:inline-flex;align-items:center;gap:5px;font-family:var(--font-mono);font-size:10px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;padding:2px 7px;border-radius:var(--r-pill);line-height:1.6;white-space:nowrap}
.badge-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}
/* live — pulsing green */
.badge-live{background:color-mix(in srgb,var(--live) 14%,transparent);color:var(--live)}
.badge-live .badge-dot{background:var(--live);animation:pulse-dot 1.6s ease-in-out infinite}
@keyframes pulse-dot{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.4;transform:scale(.7)}}
/* up — blue */
.badge-up{background:var(--accent-soft);color:var(--accent)}
.badge-up .badge-dot{background:var(--accent)}
/* ok — green */
.badge-ok{background:var(--ok-dim);color:var(--ok)}
.badge-ok .badge-dot{background:var(--ok)}
/* warn — amber */
.badge-warn{background:var(--warn-dim);color:var(--warn)}
.badge-warn .badge-dot{background:var(--warn)}
/* danger — red */
.badge-danger{background:var(--danger-dim);color:var(--danger)}
.badge-danger .badge-dot{background:var(--danger)}
/* ended / neutral — grey */
.badge-ended,.badge-neutral{background:color-mix(in srgb,var(--border) 40%,transparent);color:var(--text-muted)}
.badge-ended .badge-dot,.badge-neutral .badge-dot{background:var(--text-muted)}

/* ── Chip ────────────────────────────────────────────────────────────────────
   <button class="chip [active]"> */
.chip{font-family:var(--font-ui);font-size:12px;font-weight:500;padding:4px 12px;border-radius:var(--r-pill);border:1px solid var(--border);background:transparent;color:var(--text-2);cursor:pointer;line-height:1.5;transition:background .15s,color .15s,border-color .15s}
.chip:hover{background:var(--bg-raised);color:var(--text-1);border-color:var(--border-strong)}
.chip.active{background:var(--accent-soft);color:var(--accent);border-color:var(--accent)}

/* ── Card ────────────────────────────────────────────────────────────────────
   <section class="card"> */
.card{background:var(--bg-card);border:1px solid var(--border-subtle);border-radius:var(--r-md);overflow:hidden}
.card-header{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--s3);padding:var(--s4);border-bottom:1px solid var(--border-subtle)}
.card-title-group{flex:1;min-width:0}
.card-title{font-family:var(--font-ui);font-size:13px;font-weight:600;color:var(--text-1);margin:0;line-height:1.3}
.card-subtitle{font-family:var(--font-ui);font-size:11px;color:var(--text-muted);margin:3px 0 0}
.card-actions{display:flex;align-items:center;gap:var(--s2);flex-shrink:0}
.card-body{padding:var(--s4)}

/* ── StatCard ────────────────────────────────────────────────────────────────
   <div class="stat-card"> */
.stat-card{background:var(--bg-card);border:1px solid var(--border-subtle);border-radius:var(--r-md);padding:var(--s4) var(--s4) var(--s3)}
.stat-label{font-family:var(--font-mono);font-size:10px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--text-muted);margin-bottom:var(--s2)}
.stat-value{font-family:var(--font-mono);font-size:28px;font-weight:700;color:var(--text-1);font-variant-numeric:tabular-nums;line-height:1}
.stat-value.accent{color:var(--accent)}

/* ── DataTable ───────────────────────────────────────────────────────────────
   <div style="overflow-x:auto"><table class="dt"> */
.dt{width:100%;border-collapse:collapse;font-family:var(--font-ui);font-size:13px;color:var(--text-1)}
.dt thead{position:sticky;top:0;z-index:1;background:var(--bg-1)}
.dt th{font-family:var(--font-mono);font-size:10px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:var(--text-muted);padding:8px 12px;text-align:left;border-bottom:1px solid var(--border);white-space:nowrap;user-select:none}
.dt th[style*="cursor: pointer"]:hover,.dt th[style*="cursor:pointer"]:hover{color:var(--text-1)}
.sort-indicator{color:var(--accent);margin-left:3px;font-size:9px}
.dt td{padding:9px 12px;border-bottom:1px solid var(--border-subtle);color:var(--text-1);vertical-align:middle}
.dt td.mono{font-family:var(--font-mono);font-variant-numeric:tabular-nums}
.dt tbody tr:hover td{background:var(--bg-raised)}

/* ── Band library (org-bands) — collapsible region sections ────────────────────
   Ported from spectrum-platform-pages .band-section*, remapped to next tokens.
   <section class="band-section"><button class="band-section-header">… */
.band-section{margin-bottom:12px}
/* top offset: sticks below the (now also sticky) global topbar on nav-shell
   pages — --stick-under-nav is the topbar height there (base.css), 0 elsewhere. */
.band-section-header{display:flex;align-items:center;gap:8px;width:100%;text-align:left;padding:7px 12px;background:var(--bg-card);border:1px solid var(--border-subtle);border-radius:var(--r-sm);cursor:pointer;user-select:none;font-family:var(--font-mono);font-size:11px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:var(--text-2);position:sticky;top:var(--stick-under-nav,0px);z-index:2;transition:background .15s,border-color .15s}
.band-section-header:hover{background:var(--bg-raised);border-color:var(--border)}
.band-section-header .chevron{display:inline-block;transition:transform 120ms ease-out;color:var(--text-muted)}
.band-section.collapsed .band-section-header .chevron{transform:rotate(-90deg)}
.band-section-header .band-section-title{color:var(--text-1)}
.band-section-header .count{margin-left:auto;color:var(--text-muted);font-size:11px;letter-spacing:0;text-transform:none}
.band-section-body{overflow-x:auto}
.band-section.collapsed .band-section-body{display:none}
/* Inline-edit affordance: editable cells get a soft hover ring (custom bands). */
.band-section .dt td [data-field][style*="cursor:cell"]:hover,
.band-section .dt td [data-field][style*="cursor: cell"]:hover{box-shadow:inset 0 0 0 1px var(--accent-soft);border-radius:var(--r-sm)}

/* ── Segmented ───────────────────────────────────────────────────────────────
   <div class="segmented" role="tablist"> */
.segmented{display:inline-flex;background:var(--bg-0);border:1px solid var(--border);border-radius:var(--r-sm);padding:2px;gap:2px}
.seg-btn{font-family:var(--font-ui);font-size:12px;font-weight:500;color:var(--text-muted);background:transparent;border:none;border-radius:calc(var(--r-sm) - 2px);padding:5px 12px;cursor:pointer;line-height:1.4;display:inline-flex;align-items:center;gap:6px;transition:color .15s,background .15s}
.seg-btn:hover{color:var(--text-1)}
.seg-btn.active{background:var(--bg-raised);color:var(--text-1);box-shadow:0 1px 3px rgba(0,0,0,.4)}
.seg-count{font-family:var(--font-mono);font-size:10px;font-weight:600;background:var(--border);color:var(--text-muted);border-radius:var(--r-pill);padding:1px 6px;line-height:1.4}
.seg-btn.active .seg-count{background:var(--accent-soft);color:var(--accent)}
/* Status verdict dot (e.g. Channel Health tab worst-verdict) */
.seg-dot{width:7px;height:7px;border-radius:50%;background:var(--text-muted);flex-shrink:0}
.seg-dot.is-green{background:var(--ok)}
.seg-dot.is-amber{background:var(--warn)}
.seg-dot.is-red{background:var(--danger)}

/* ── Modal ───────────────────────────────────────────────────────────────────
   .modal-overlay > .modal */
.modal-overlay{position:fixed;inset:0;z-index:900;display:flex;align-items:center;justify-content:center;background:rgba(5,7,10,.72);backdrop-filter:blur(2px)}
.modal{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--r-lg);width:min(520px,calc(100vw - 32px));max-height:calc(100vh - 64px);display:flex;flex-direction:column;overflow:hidden;box-shadow:0 24px 64px rgba(0,0,0,.6)}
.modal--wide{width:min(800px,calc(100vw - 32px))}
/* xwide: the Devices Grid view — wide enough for ~10 large tiles per row */
.modal--xwide{width:min(1760px,calc(100vw - 32px))}
.modal-header{display:flex;align-items:center;justify-content:space-between;padding:var(--s4) var(--s4) var(--s3);border-bottom:1px solid var(--border-subtle);flex-shrink:0}
.modal-title{font-family:var(--font-ui);font-size:14px;font-weight:600;color:var(--text-1);margin:0}
.modal-close{background:none;border:none;color:var(--text-muted);cursor:pointer;font-size:14px;padding:2px 6px;border-radius:var(--r-sm);line-height:1}
.modal-close:hover{color:var(--text-1);background:var(--bg-raised)}
.modal-body{padding:var(--s4);overflow-y:auto;flex:1;color:var(--text-1);font-size:13px;line-height:1.6}
.modal-footer{display:flex;align-items:center;justify-content:flex-end;gap:var(--s2);padding:var(--s3) var(--s4);border-top:1px solid var(--border-subtle);flex-shrink:0}
/* phone: full-screen sheet */
@media(max-width:640px){
  .modal,.modal--wide{width:100%;max-height:90vh;border-bottom-left-radius:0;border-bottom-right-radius:0;margin-top:auto}
  .modal-overlay{align-items:flex-end}
}

/* ── Dialog helpers ──────────────────────────────────────────────────────────*/
.dialog-message{font-size:13px;color:var(--text-2);margin:0;line-height:1.6}
.dialog-footer{display:flex;gap:var(--s2)}

/* ── Toast ───────────────────────────────────────────────────────────────────
   .toast-stack > .toast */
.toast-stack{position:fixed;bottom:var(--s5);right:var(--s4);z-index:1000;display:flex;flex-direction:column;gap:var(--s2);pointer-events:none}
.toast{pointer-events:all;display:flex;align-items:center;gap:var(--s3);background:var(--bg-raised);border:1px solid var(--border);border-left-width:3px;border-radius:var(--r-sm);padding:10px var(--s3);min-width:240px;max-width:360px;font-size:13px;color:var(--text-1);box-shadow:0 8px 24px rgba(0,0,0,.5);animation:toast-in .2s ease}
.toast span:first-child{flex:1}
.toast-close{background:none;border:none;color:var(--text-muted);cursor:pointer;font-size:12px;padding:0 2px;line-height:1;flex-shrink:0}
.toast-close:hover{color:var(--text-1)}
/* type tints — left border */
.toast-info{border-left-color:var(--accent)}
.toast-ok{border-left-color:var(--ok)}
.toast-warn{border-left-color:var(--warn)}
.toast-error{border-left-color:var(--danger)}
@keyframes toast-in{from{opacity:0;transform:translateX(16px)}to{opacity:1;transform:none}}
.toast-out{animation:toast-out .25s ease forwards}
@keyframes toast-out{to{opacity:0;transform:translateX(16px)}}

/* ── Popover ─────────────────────────────────────────────────────────────────
   .popover */
.popover{position:fixed;z-index:800;background:var(--bg-card);border:1px solid var(--border);border-radius:var(--r-md);box-shadow:0 12px 40px rgba(0,0,0,.55);padding:var(--s3);min-width:160px;max-width:320px;font-size:13px;color:var(--text-1);animation:pop-in .12s ease}
@keyframes pop-in{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}

/* ── Touch targets (mobile foundation, Wave 4 batch 1) ────────────────────────
   Raise interactive controls to >=var(--tap-min) (44px, WCAG 2.5.5 / Apple HIG)
   on touch devices AND narrow viewports. `pointer:coarse` catches phones/tablets
   regardless of width; `max-width:760px` (our mobile breakpoint) also catches a
   narrow window/resized viewport — so the bump is verifiable in a narrow desktop
   preview and a small window gets usable targets too. Wide-window mouse/desktop
   is left EXACTLY as-is. Sizing uses min-height/min-width + padding + centering
   (NOT a fixed height) so text can still wrap without clipping. Some controls
   (.m-star, the usage pins, the monitor checkboxes/SSA range sliders) are themed
   in view-specific CSS that loads AFTER this file, so their selectors are doubled
   (.x.x) here to win on specificity from components.css without touching views. */
@media (pointer:coarse), (max-width:760px){
  /* Shared button kit */
  .btn{min-height:var(--tap-min);padding-top:0;padding-bottom:0;align-items:center}
  .btn-icon{min-width:var(--tap-min);min-height:var(--tap-min);padding:0}
  /* Chips + segmented controls — grow the hit area, keep the pill/visual look */
  .chip{min-height:var(--tap-min);padding-top:0;padding-bottom:0;display:inline-flex;align-items:center;justify-content:center}
  .seg-btn{min-height:calc(var(--tap-min) - 6px);padding-top:0;padding-bottom:0;align-items:center}
  /* Bottom tab bar links (responsive nav, base.css) */
  .tabbar a{min-height:var(--tap-min);justify-content:center}
  /* Pin/star toggle buttons (view CSS: monitor .m-star, usage row/legend/marker
     pins). Doubled selector beats the single-class view rules. */
  .m-star.m-star,
  .usage-row-pin.usage-row-pin,
  .usage-legend-pin.usage-legend-pin,
  .usage-marker-pin.usage-marker-pin{min-width:var(--tap-min);min-height:var(--tap-min)}
  /* Checkboxes / radios — natively ~14px; enlarge the box + give it a roomier
     hit area. accent-color (set in view CSS) is preserved. */
  input[type="checkbox"],
  input[type="radio"]{min-width:24px;min-height:24px;transform:scale(1.25);transform-origin:center}
  /* Doubled to also win over the explicit 14px sizes in views-monitor.css. */
  .m-check.m-check,
  .m-checkrow input{min-width:24px;min-height:24px}
  /* Range slider thumb — enlarge so it's draggable by finger. The track stays
     thin; we only fatten the thumb across the vendor pseudo-elements. */
  input[type="range"]{height:var(--tap-min)}
  input[type="range"]::-webkit-slider-thumb{width:24px;height:24px}
  input[type="range"]::-moz-range-thumb{width:24px;height:24px}
}

/* ── Responsive table → card reflow utility (.rtable) ─────────────────────────
   REUSABLE pattern; NOT applied to any table yet (a later batch converts the
   real tables). Contract:
     1. add class `rtable` to the <table>
     2. add data-label="ColumnName" to each <td>
   On desktop it is a normal table. Under <=760px (the codebase layout
   breakpoint) each <tr> becomes a bordered card and each <td> becomes a
   label/value row, with the column name injected from data-label via ::before.
   A <td> without a data-label (e.g. an actions/icon cell) renders no stray
   label. Pair with a wrapping `overflow-x:auto` only if you keep table mode on
   small screens — this utility replaces horizontal scroll with vertical cards. */
@media (max-width:760px){
  .rtable thead{display:none}
  .rtable tr{display:block;border:1px solid var(--border);border-radius:var(--r-sm);padding:var(--s3);margin-bottom:var(--s2)}
  .rtable td{display:flex;justify-content:space-between;gap:var(--s3);padding:4px 0;border:0;min-width:0;overflow-wrap:anywhere}
  .rtable td::before{content:attr(data-label);color:var(--text-2);font-weight:600;margin-right:var(--s3);flex:0 0 auto}
  /* No stray empty label for cells that opt out of a data-label. */
  .rtable td:not([data-label])::before{content:none}
  /* Action/icon cells (no data-label) hold several buttons — let them wrap
     left-aligned inside the card instead of forcing it wider than the viewport. */
  .rtable td:not([data-label]){flex-wrap:wrap;justify-content:flex-start;gap:var(--s2)}
}

/* === PWA install banner (js/install-prompt.js) ==========================
   Floating "Add to Home Screen" / [Install] card, restored from the v1
   spectrum-platform-pages port. Themed to next's dark tokens (v1 was a white
   card). Self-hides when installed/dismissed; on iOS shows A2HS instructions,
   on Chrome/Edge a real [Install] button. Sits above page content but below
   modal overlays (z 900+) so a modal cleanly covers it. Safe-area insets keep
   the card clear of the notch (landscape) and home indicator (portrait).
   base.css reserves matching bottom space on non-immersive routes via
   --install-banner-height (published by setupBannerSizing). */
.install-banner {
  position: fixed;
  left: calc(12px + env(safe-area-inset-left, 0px));
  right: calc(12px + env(safe-area-inset-right, 0px));
  bottom: calc(12px + env(safe-area-inset-bottom, 0px));
  z-index: 850;
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: var(--s3) var(--s4);
  background: var(--bg-raised);
  color: var(--text-1);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  font-size: 13px;
  line-height: 1.35;
  /* Stacked shadows: soft wide depth + a tighter darker edge so the card reads
     as clearly "in front of" the chart/map behind it. */
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.55), 0 2px 6px rgba(0, 0, 0, 0.4);
}
.install-banner-text {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--text-1);
}
.install-banner-install {
  flex: 0 0 auto;
  width: auto;
  padding: 7px 16px;
  height: 32px;
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: var(--r-sm);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  margin: 0;
}
.install-banner-install:hover { background: var(--accent-strong); }
.install-banner-dismiss {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  padding: 0;
  background: transparent;
  color: var(--text-muted);
  border: none;
  border-radius: var(--r-pill);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  margin: 0;
  /* Explicit centering so the × glyph sits flush regardless of font. */
  display: flex;
  align-items: center;
  justify-content: center;
}
.install-banner-dismiss:hover { color: var(--text-1); background: var(--bg-2); }
