/* ig.css — shared InvisaGig tokens and Pico overrides. Loaded last on every page. */

/* ── tokens ── */
:root,
:root[data-theme="dark"] {
  --ig-accent: #5c7cfa;
  --ig-accent-deep: #4a62d8;
  --ig-accent-text: #7d95fb;
  --ig-good: #2dc653;
  --ig-fair: #f89f0d;
  --ig-poor: #e57373;

  --pico-primary: #7d95fb;
  --pico-primary-background: var(--ig-accent-deep);
  --pico-primary-border: var(--ig-accent-deep);
  --pico-primary-underline: rgba(125, 149, 251, 0.5);
  --pico-primary-hover: #a3b4fc;
  --pico-primary-hover-background: #4259cc;
  --pico-primary-hover-border: #4259cc;
  --pico-primary-hover-underline: var(--pico-primary-hover);
  --pico-primary-focus: rgba(92, 124, 250, 0.5);
  --pico-primary-inverse: #fff;
  --pico-text-selection-color: rgba(92, 124, 250, 0.35);
  --pico-card-box-shadow: none;
  /* Pico's #7b8495 is 4.4:1 on inset surfaces; this clears 4.5:1 on every dark surface. */
  --pico-muted-color: #848d9e;
}

/* Light theme: darker accent and signal hues so text clears 4.5:1 on white. */
:root[data-theme="light"] {
  --ig-accent: #4a62d8;
  --ig-accent-deep: #4a62d8;
  --ig-accent-text: #3d56d0;
  --ig-good: #137534;
  --ig-fair: #9a5b00;
  --ig-poor: #b83f3f;

  --pico-primary: #3d56d0;
  --pico-primary-background: var(--ig-accent-deep);
  --pico-primary-border: var(--ig-accent-deep);
  --pico-primary-underline: rgba(61, 86, 208, 0.5);
  --pico-primary-hover: #2f45b0;
  --pico-primary-hover-background: #3d56d0;
  --pico-primary-hover-border: #3d56d0;
  --pico-primary-hover-underline: var(--pico-primary-hover);
  --pico-primary-focus: rgba(74, 98, 216, 0.4);
  --pico-text-selection-color: rgba(74, 98, 216, 0.25);
  --pico-card-box-shadow: none;
}

/* ── browser surfaces ── */
[x-cloak] { display: none !important; }
/* Pico sizes code at 0.875em, which drops below 11px inside small hints. */
code, kbd { font-size: max(0.875em, 11px); }
html { accent-color: var(--ig-accent-deep); scrollbar-color: var(--pico-muted-border-color, #2a3140) transparent; }
body { font-variant-numeric: tabular-nums; }
::selection { background: var(--pico-text-selection-color); }
:focus-visible { outline-color: var(--ig-accent); }

/* Pico rescopes --pico-color to the inverse inside <button>; ghost buttons need the page text color. */
:root { --ig-text: var(--pico-color); }
.range-btn:hover,
.range-btn.active { color: var(--ig-text); }

/* ── shell: top bar + tab bar (markup rendered by ig-shell.js) ── */
header.topbar {
  position: sticky; top: 0; z-index: 100;
  padding: 0 1.5rem;
  background: var(--pico-background-color);
  border-bottom: 1px solid var(--pico-muted-border-color);
}
header.topbar :is(ul, li) { margin: 0; padding: 0; list-style: none; }
.topbar-row { display: flex; align-items: center; gap: 1.5rem; min-height: 56px; }

.brand { display: flex; align-items: center; flex-shrink: 0; text-decoration: none; }
.brand-logo { display: block; height: 28px; width: auto; }
.brand-text { display: none; font-weight: 700; font-size: 1.05rem; letter-spacing: -0.01em; color: var(--ig-text); }
.brand-text span { color: var(--ig-accent-text); }
[data-theme="light"] .brand-logo { display: none; }
[data-theme="light"] .brand-text { display: block; }

/* Groups: the current group expands into a track of its pages; the others collapse to one link. */
header.topbar .groups { display: flex; align-items: center; justify-content: flex-start; gap: 0.25rem; flex: 1; min-width: 0; }
.group-link,
.subnav a {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 32px; margin: 0; padding: 0 0.75rem;
  border-radius: 6px;
  font-size: 0.875rem; white-space: nowrap; text-decoration: none;
  color: var(--pico-muted-color);
  transition: color 0.15s, background 0.15s;
}
.group-link:hover,
.subnav a:hover { color: var(--ig-text); background: var(--pico-card-background-color); }
.group-track {
  display: flex; align-items: center; gap: 2px;
  padding: 3px;
  border: 1px solid var(--pico-muted-border-color);
  border-radius: 8px;
  background: var(--pico-card-sectioning-background-color);
}
.group-name {
  margin-right: 2px; padding: 0 0.65rem 0 0.55rem;
  border-right: 1px solid var(--pico-muted-border-color);
  font-size: 0.875rem; font-weight: 600; color: var(--ig-text);
}
.subnav { display: flex; align-items: center; gap: 2px; }
.subnav a { min-height: 30px; padding: 0 0.7rem; }
.subnav a.active { color: var(--ig-accent-text); background: rgba(92, 124, 250, 0.15); font-weight: 600; }

.topbar-tools { display: flex; align-items: center; gap: 0.25rem; flex-shrink: 0; margin-left: auto; }
.topbar-tools form { margin: 0; }
.stream-status {
  display: flex; align-items: center; gap: 0.35rem;
  padding: 0 0.6rem;
  font-size: 0.75rem; white-space: nowrap; color: var(--pico-muted-color);
}
.stream-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--pico-muted-color); transition: background 0.4s; }
.stream-dot.live  { background: var(--ig-good); }
.stream-dot.error { background: var(--ig-poor); }
.theme-btn,
.signout {
  display: inline-flex; align-items: center; gap: 0.4rem;
  min-height: 32px; margin: 0; padding: 0 0.6rem;
  border: none; border-radius: 6px; background: none;
  font-size: 0.875rem; color: var(--pico-muted-color);
  cursor: pointer; transition: color 0.15s, background 0.15s;
}
.theme-btn:hover,
.signout:hover { color: var(--ig-text); background: var(--pico-card-background-color); }
.theme-icon-dark,
.theme-icon-light { display: inline-flex; }
[data-theme="light"] .theme-icon-dark,
:root:not([data-theme="light"]) .theme-icon-light { display: none; }
.signout svg { display: none; }

.tabbar { display: none; }

@media (max-width: 959px) {
  header.topbar { padding: 0 1rem; }
  .topbar-row { flex-wrap: wrap; gap: 0 0.75rem; min-height: 0; }
  .brand { min-height: 52px; }
  .topbar-tools { order: 2; }
  header.topbar .groups {
    order: 3; flex-basis: 100%;
    margin: 0 -1rem; padding: 0 1rem 0.5rem;
    overflow-x: auto; scrollbar-width: none;
  }
  header.topbar .groups::-webkit-scrollbar { display: none; }
  .group-link,
  .group-name { display: none; }
  .group-track { flex: 1; padding: 0; border: none; background: none; }
  .subnav { flex: 1; }
  .subnav li { flex: 1 1 auto; }
  .subnav a { width: 100%; min-height: 36px; padding: 0 0.5rem; }
  .signout span { display: none; }
  .signout svg { display: block; }

  .tabbar {
    display: flex;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 100;
    padding-bottom: env(safe-area-inset-bottom);
    background: var(--pico-background-color);
    border-top: 1px solid var(--pico-muted-border-color);
  }
  .tabbar a {
    flex: 1;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
    min-height: 56px;
    font-size: 0.75rem; font-weight: 500; text-decoration: none;
    color: var(--pico-muted-color);
  }
  .tabbar a.active { color: var(--ig-accent-text); font-weight: 600; }
  body.has-tabbar { padding-bottom: calc(56px + env(safe-area-inset-bottom)); }
}

/* ── signal gauge (Aim, Dashboard hero): RSRP −130…−60 dBm on the signal scale ──
   Size with --gauge-h / --gauge-cursor-w; position the cursor with style="left:N%". */
:root { --ig-gauge-cursor: #fff; }
:root[data-theme="light"] { --ig-gauge-cursor: #373c44; }
.ig-gauge {
  position: relative;
  height: var(--gauge-h, 14px);
  border-radius: 999px;
  background: linear-gradient(to right, var(--ig-poor) 0%, var(--ig-fair) 42%, var(--ig-good) 100%);
}
.ig-gauge.is-empty { opacity: 0.3; }
.ig-gauge-cursor {
  position: absolute; top: 50%;
  width: var(--gauge-cursor-w, 5px);
  height: calc(var(--gauge-h, 14px) + 10px);
  border-radius: 3px;
  background: var(--ig-gauge-cursor);
  box-shadow: 0 0 8px rgba(255, 255, 255, 0.55);
  transform: translate(-50%, -50%);
  transition: left 0.5s;
  pointer-events: none;
}

/* ── confirm dialog (igConfirm in ig-shell.js) ── */
.overlay {
  position: fixed; inset: 0; z-index: 200;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0, 0, 0, 0.6);
}
.overlay-box {
  width: 90%; max-width: 420px;
  padding: 1.75rem;
  border: 1px solid var(--pico-muted-border-color);
  border-radius: 10px;
  background: var(--pico-card-background-color);
}
.ig-dialog-title { margin: 0 0 0.6rem; font-size: 1.05rem; line-height: 1.3; color: var(--ig-text); }
.ig-dialog-body { margin: 0 0 1rem; font-size: 0.9rem; color: var(--pico-muted-color); }
.ig-dialog-facts {
  display: grid; grid-template-columns: auto 1fr; gap: 0.4rem 1rem;
  margin: 0 0 1.5rem; padding: 0.75rem 0.9rem;
  border-radius: 6px;
  background: var(--pico-card-sectioning-background-color);
  font-size: 0.85rem;
}
.ig-dialog-facts div { display: contents; }
.ig-dialog-facts dt { font-weight: 400; color: var(--pico-muted-color); }
.ig-dialog-facts dd { margin: 0; color: var(--ig-text); }
.btn-row { display: flex; gap: 0.75rem; justify-content: flex-end; }
.btn-row button { margin: 0; }

/* ── recovery monitor (igWatchRecovery) ── */
@keyframes ig-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } }
.ig-recovery {
  position: fixed; right: 1.5rem; bottom: 1.5rem; z-index: 150;
  display: flex; align-items: center; gap: 0.75rem;
  max-width: 26rem; padding: 0.8rem 0.9rem 0.8rem 1rem;
  border: 1px solid var(--pico-form-element-border-color, #2a3140);
  border-radius: 10px;
  background: var(--pico-card-background-color);
  font-size: 0.85rem;
}
.ig-recovery-dot { flex-shrink: 0; width: 8px; height: 8px; border-radius: 50%; background: var(--ig-accent); }
.ig-recovery.is-wait .ig-recovery-dot { animation: ig-pulse 1.2s ease-in-out infinite; }
.ig-recovery.is-ok   .ig-recovery-dot { background: var(--ig-good); }
.ig-recovery.is-fail .ig-recovery-dot { background: var(--ig-poor); }
.ig-recovery-text { display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; }
.ig-recovery-text strong { font-weight: 600; color: var(--ig-text); }
.ig-recovery-text span { color: var(--pico-muted-color); }
.ig-recovery-btn {
  flex-shrink: 0; margin: 0 0 0 auto; padding: 0.3rem 0.7rem;
  border: 1px solid var(--pico-muted-border-color); border-radius: 6px;
  background: none; font-size: 0.8rem; color: var(--pico-muted-color);
  cursor: pointer;
}
.ig-recovery-btn:hover { color: var(--ig-text); border-color: var(--pico-muted-color); }
@media (max-width: 959px) {
  .ig-recovery { left: 1rem; right: 1rem; max-width: none; bottom: 1rem; }
  body.has-tabbar .ig-recovery { bottom: calc(56px + env(safe-area-inset-bottom) + 0.75rem); }
}

/* ── live signal strip (data-live-strip, rendered by ig-shell.js) ── */
.ig-live {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem 1.25rem;
  margin: 0 0 1.25rem; padding: 0.6rem 0.9rem;
  border: 1px solid var(--pico-muted-border-color);
  border-radius: 8px;
  background: var(--pico-card-sectioning-background-color);
  font-size: 0.85rem; color: var(--pico-muted-color);
}
.ig-live-state { display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.78rem; }
.ig-live-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--pico-muted-color); }
.ig-live-state.is-live .ig-live-dot { background: var(--ig-good); }
.ig-live-state.is-lost .ig-live-dot { background: var(--ig-poor); }
.ig-live-leg b { font-weight: 600; color: var(--ig-text); }
.ig-live-leg strong { font-size: 1rem; font-weight: 700; color: var(--ig-text); }
.ig-live-leg strong.is-good { color: var(--ig-good); }
.ig-live-leg strong.is-fair { color: var(--ig-fair); }
.ig-live-leg strong.is-poor { color: var(--ig-poor); }
.ig-live-band { color: var(--ig-text); }
.ig-live-reg { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.05em; }
.ig-live-legend { margin-left: auto; font-size: 0.75rem; }
@media (max-width: 700px) { .ig-live-legend { display: none; } }
/* Pico cards go full-bleed below 576px; the strip follows so its corners aren’t clipped. */
@media (max-width: 575px) { .ig-live { border-radius: 0; border-left: none; border-right: none; } }

/* ── visually hidden, still announced ── */
.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;
}

/* ── "active / selected" pill: the accent, never a signal color ── */
.pill.accent { background: rgba(92, 124, 250, 0.15); color: var(--ig-accent-text); }
/* Neutral status pill: muted grey on its own grey tint falls under 4.5:1, so use the text color. */
.pill.grey { color: var(--ig-text); }
.pill.accent .pill-dot { background: var(--ig-accent); }

/* ── amber banner above anything that drops the connection ── */
.warn-banner {
  margin-bottom: 1.25rem; padding: 0.6rem 0.9rem;
  border: 1px solid rgba(248, 159, 13, 0.3);
  border-radius: 6px;
  background: rgba(248, 159, 13, 0.1);
  font-size: 0.82rem; color: var(--ig-fair);
}

/* ── disabled controls read as unavailable, not as a lighter enabled button ── */
:is(button, [role="button"], input[type="submit"]):disabled { opacity: 0.45; cursor: not-allowed; }

/* ── destructive confirm ── */
button.danger {
  --pico-background-color: #c94c4c;
  --pico-border-color: #c94c4c;
  --pico-color: #fff;
}
button.danger:is(:hover, :focus-visible) {
  --pico-background-color: #b83f3f;
  --pico-border-color: #b83f3f;
}
button.danger:focus-visible { --pico-box-shadow: 0 0 0 0.125rem rgba(229, 115, 115, 0.5); }

/* ── notch / home-indicator insets (pages opt in with viewport-fit=cover) ── */
body { padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right); }

/* Short landscape phones: let the top bar scroll away and slim the tab bar,
   so the page keeps more than half of a ~390px-tall viewport. */
@media (max-width: 959px) and (max-height: 500px) {
  header.topbar { position: static; }
  .tabbar a { flex-direction: row; gap: 0.5rem; min-height: 44px; }
  body.has-tabbar { padding-bottom: calc(44px + env(safe-area-inset-bottom)); }
}

/* Confirm dialogs become bottom sheets on phones: consequence text on top, both buttons in thumb reach. */
@media (max-width: 600px) {
  .overlay { align-items: flex-end; }
  .overlay-box {
    width: 100%; max-width: none;
    padding: 1.5rem 1.25rem calc(1.25rem + env(safe-area-inset-bottom));
    border-radius: 14px 14px 0 0;
    text-align: left;
  }
  .overlay-box :is(.btn-row, .overlay-btns) { justify-content: stretch; }
  .overlay-box :is(.btn-row, .overlay-btns) button { flex: 1; min-height: 48px; margin: 0; }
}

/* ── touch: tactile targets on coarse pointers ── */
@media (pointer: coarse) {
  :is(button, [role="button"], input[type="submit"]):not(.sms-del) { min-height: 40px; }
  .group-link,
  .subnav a { min-height: 40px; }
  .theme-btn,
  .signout { min-width: 40px; min-height: 40px; justify-content: center; }
  .range-btn { min-width: 44px; }
  /* iOS zooms the page when a focused field is under 16px. */
  input:not([type="checkbox"], [type="radio"], [type="range"]), select, textarea { font-size: 16px; }
  .band-chip { min-height: 40px; padding-left: 0.75rem; padding-right: 0.75rem; }
  .sms-del { min-width: 32px; min-height: 32px; }
}

/* ── motion: light, fast, and only where it explains something ──
   Arrivals ease out (--ig-ease-out); exits are quicker than entrances. */
:root { --ig-ease-out: cubic-bezier(0.16, 1, 0.3, 1); }
@keyframes ig-fade-in  { from { opacity: 0; } }
@keyframes ig-fade-out { to   { opacity: 0; } }
@keyframes ig-rise     { from { opacity: 0; transform: translateY(6px); } }
@keyframes ig-dialog-in { from { opacity: 0; transform: translateY(8px) scale(0.98); } }
@keyframes ig-sheet-in  { from { transform: translateY(100%); } }
@keyframes ig-beat     { 0% { transform: scale(1); } 35% { transform: scale(1.6); } 100% { transform: scale(1); } }

/* Page-to-page: a quick crossfade while the top bar and tab bar hold still. */
@view-transition { navigation: auto; }
header.topbar { view-transition-name: ig-topbar; }
.tabbar { view-transition-name: ig-tabbar; }
::view-transition-old(root),
::view-transition-new(root) { animation-duration: 160ms; }

/* Confirm dialog rises in (sheet slides up on phones) and leaves faster than it came. */
.overlay { animation: ig-fade-in 160ms ease-out; }
.overlay-box { animation: ig-dialog-in 220ms var(--ig-ease-out); }
.overlay.is-closing { animation: ig-fade-out 120ms ease-in forwards; }
@media (max-width: 600px) { .overlay-box { animation: ig-sheet-in 260ms var(--ig-ease-out); } }

/* Status that appears: recovery panel, feedback lines, results arriving as a list. */
.ig-recovery { animation: ig-rise 240ms var(--ig-ease-out); }
.ig-recovery-dot { transition: background 0.3s; }
.feedback { animation: ig-rise 180ms var(--ig-ease-out); }
.ig-row-in { animation: ig-rise 260ms var(--ig-ease-out) backwards; animation-delay: calc(min(var(--i, 0), 8) * 28ms); }

/* A fresh live sample gives the strip's dot one beat (the strip re-renders per sample). */
.ig-live-state.is-live .ig-live-dot { animation: ig-beat 500ms var(--ig-ease-out); }

/* Press feedback: controls give a little under the finger. */
:is(button, [role="button"], input[type="submit"]) {
  transition: background-color var(--pico-transition), border-color var(--pico-transition),
              color var(--pico-transition), box-shadow var(--pico-transition), transform 90ms ease-out;
}
:is(button, [role="button"], input[type="submit"]):active:not(:disabled) { transform: scale(0.97); }
.band-chip { transition: background 0.12s, border-color 0.12s, color 0.12s, transform 90ms ease-out; }
.band-chip:active { transform: scale(0.96); }

/* Reduced motion: no travel, no scaling, no beats; keep the fades that carry state. */
@media (prefers-reduced-motion: reduce) {
  .pulse-dot,
  .ig-recovery-dot,
  .ig-live-state.is-live .ig-live-dot { animation: none !important; }
  .overlay-box,
  .ig-recovery,
  .feedback,
  .ig-row-in { animation-name: ig-fade-in !important; animation-delay: 0ms !important; }
  :is(button, [role="button"], input[type="submit"]):active:not(:disabled),
  .band-chip:active { transform: none; }
  ::view-transition-old(root),
  ::view-transition-new(root) { animation-duration: 80ms; }
}
