/* ECHO responsive system
 * ------------------------------------------------------------------
 * 1) Aligns the sticky top header with the centered max-width content
 *    box below it, at ANY viewport width. Each page sets --echo-cw to
 *    its own content width; the header mirrors that centering with
 *    padding, so the title never drifts left of the content on wide
 *    screens (the sticky bar + border still span full width).
 *
 * 2) Scales the whole board up in steps on large monitors. A SOC wall
 *    display should USE the space and stay legible from a distance, so
 *    we apply a uniform zoom (content + type grow together, layout
 *    proportions preserved, everything stays centered).
 * ------------------------------------------------------------------ */

:root { --echo-cw: 1360px; }   /* fallback; each page overrides to match its content box */

/* header title aligns to the centered content container below it */
header[style*="position:sticky"] {
  padding-left:  max(24px, calc((100% - var(--echo-cw)) / 2)) !important;
  padding-right: max(24px, calc((100% - var(--echo-cw)) / 2)) !important;
}

/* keep the content box centered (its max-width is set inline per page) */
main > div { margin-left: auto !important; margin-right: auto !important; }

/* ── large-monitor scale-up (stepped) ──────────────────────────────
 * zoom keeps proportions and enlarges px type that can't scale via rem.
 * Media queries read the true viewport, so there is no feedback loop. */
@media (min-width: 1600px) { :root { zoom: 1.12; } }
@media (min-width: 1920px) { :root { zoom: 1.28; } }
@media (min-width: 2560px) { :root { zoom: 1.60; } }
@media (min-width: 3200px) { :root { zoom: 2.00; } }

@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }


/* ==================================================================
 * INTERACTION STATES  — brand-indigo hover language
 * ------------------------------------------------------------------
 * Shared hover / active treatment for the main nav and white primary
 * buttons. Tokens:
 *   hover text/icon  → oklch(0.72 0.16 275)        (~#8E82F0)
 *   hover bg tint    → oklch(0.55 0.22 275 / 0.12)
 *   hover border     → oklch(0.55 0.22 275 / 0.5)  (drawn as inset
 *                       box-shadow so there is no 1px layout jump)
 *   active/pressed   → oklch(0.62 0.20 275)        (pushed-in)
 * ================================================================== */

:root {
  --echo-brand:        oklch(0.72 0.16 275);   /* brightened — for text/icon on dark */
  --echo-brand-tint:   oklch(0.55 0.22 275 / 0.12);
  --echo-brand-tint-2: oklch(0.55 0.22 275 / 0.18);
  --echo-brand-line:   oklch(0.55 0.22 275 / 0.5);
  --echo-brand-press:  oklch(0.62 0.20 275);
  --echo-brand-fill:       oklch(0.55 0.22 275);  /* true brand indigo (#6a5ed9) — button fill */
  --echo-brand-fill-press: oklch(0.47 0.20 275);  /* pressed: one step darker */
}

/* Treat hover like a TEXT LINK: just the indigo colour shift — no background
 * tint, no border pill. (Active/pressed drops to a deeper indigo.) */

/* ── main nav ─────────────────────────────────────────────────── */
aside nav a { transition: color .15s ease; }
aside nav a:hover,
aside nav a:focus-visible { color: var(--echo-brand) !important; outline: none; }
aside nav a:hover > span:first-child,
aside nav a:focus-visible > span:first-child { color: var(--echo-brand) !important; }

aside nav a:active { color: var(--echo-brand-press) !important; }
aside nav a:active > span:first-child { color: var(--echo-brand-press) !important; }

/* ── white primary buttons ────────────────────────────────────────
 * Hover changes the BUTTON colour: the fill shifts from white to the
 * true brand indigo (#6a5ed9). The label flips to white so it stays
 * legible on the saturated fill; pressed drops one step darker. */
/* Screens are tokenised, so the primary fill is now `var(--foreground)`.
 * Both spellings are matched: the token form is what ships, the hex form is
 * kept so any untokenised or legacy markup still gets the treatment. */
button[style*="background:#fafafa"],
button[style*="background:var(--foreground)"] { transition: background-color .15s ease, color .15s ease; }
button[style*="background:#fafafa"]:hover,
button[style*="background:#fafafa"]:focus-visible,
button[style*="background:var(--foreground)"]:hover,
button[style*="background:var(--foreground)"]:focus-visible { background-color: var(--echo-brand-fill) !important; color:#fff !important; outline: none; }
button[style*="background:#fafafa"]:hover span,
button[style*="background:#fafafa"]:focus-visible span,
button[style*="background:var(--foreground)"]:hover span,
button[style*="background:var(--foreground)"]:focus-visible span { color:#fff !important; }
button[style*="background:#fafafa"]:active,
button[style*="background:var(--foreground)"]:active { background-color: var(--echo-brand-fill-press) !important; }

/* ── logo mark (non-link) ─────────────────────────────────────────
 * The mark is decorative status light only — no navigation. */


/* ==================================================================
 * RESPONSIVE — 390px phone → SOC wall display
 * ------------------------------------------------------------------
 * Screens are authored desktop-first with inline styles, so every rule
 * here overrides a structure echo-chrome.js or the pages actually emit.
 * Nothing is per-page: this is the only file where layout adapts, so
 * breakpoints cannot drift from screen to screen.
 *
 * Ladder:
 *   >=1600     scale UP (zoom steps above) — wall displays
 *   1180-1599  desktop as authored
 *   <=1179     sidebar becomes an off-canvas drawer; columns collapse
 *   <=767      single column; feed tables drop secondary columns
 *
 * Note: the ECHO nav is text-only (no icons), so there is deliberately
 * NO icon-rail tier — collapsing labels would leave empty boxes. The
 * sidebar goes straight from full to drawer.
 * ================================================================== */

/* zoom steps are for large monitors only — never let a high-DPI phone
 * in landscape inherit a 1.12+ scale */
@media (max-width: 1599px) { :root { zoom: 1; } }

/* ── <=1179 · off-canvas drawer ───────────────────────────────────── */
@media (max-width: 1179px) {
  aside[data-echo-nav] {
    width: 264px !important;
    position: fixed !important; inset-block: 0; left: 0; z-index: 70;
    transform: translateX(-100%) !important;
    transition: transform 200ms cubic-bezier(0.4, 0, 0.2, 1);
    box-shadow: 0 0 60px rgba(0,0,0,0.6);
  }
  html.echo-nav-open aside[data-echo-nav] { transform: translateX(0) !important; }

  #echoNavToggle { display: inline-flex !important; }
  #echoScrim { display: block !important; }
  html.echo-nav-open #echoScrim { opacity: 1 !important; pointer-events: auto !important; }

  /* the sidebar is fixed now, so the page must not reserve a column */
  body > div[style*="display:flex"] { display: block !important; }
  header[style*="position:sticky"] { padding-left: 64px !important; }

  /* content columns collapse at the same point the sidebar leaves flow,
   * otherwise a 2fr/1fr split has to survive on ~900px and overflows */
  main [style*="grid-template-columns:minmax(0,2fr)"],
  main [style*="grid-template-columns:minmax(0, 2fr)"],
  main [style*="grid-template-columns:1fr 1fr"] { grid-template-columns: minmax(0,1fr) !important; }
  main [style*="grid-template-columns:repeat(4,1fr)"],
  main [style*="grid-template-columns:repeat(3,1fr)"] { grid-template-columns: repeat(2, minmax(0,1fr)) !important; }
}

/* ── <=767 · phone ────────────────────────────────────────────────── */
@media (max-width: 767px) {
  main { padding: 16px 14px 32px !important; }
  header[style*="position:sticky"] { height: 64px !important; padding-left: 60px !important; padding-right: 14px !important; }
  header .echo-search-hero { display: none !important; }   /* search is secondary on a phone */

  /* Feed/intercept tables are a 5-column grid
   * (dot · threat · source · seen · score) that cannot fit 390px.
   * Keep the decision-critical columns — the tier dot, the threat name
   * and the score — and drop source/seen, which are supporting meta. */
  main [style*="grid-template-columns:26px minmax(0,1fr)"] {
    grid-template-columns: 20px minmax(0,1fr) auto !important;
    gap: 10px !important; padding-left: 12px !important; padding-right: 12px !important;
  }
  main [style*="grid-template-columns:26px minmax(0,1fr)"] > *:nth-child(3),
  main [style*="grid-template-columns:26px minmax(0,1fr)"] > *:nth-child(4) { display: none !important; }

  /* maps and globes need usable height once the column narrows */
  .globe-well { aspect-ratio: 1/1 !important; }
  [style*="aspect-ratio:1000/"] { min-height: 200px; }

  /* never let an inner min-width force the page sideways */
  html, body { overflow-x: hidden; max-width: 100%; }
  main [style*="min-width:"] { min-width: 0 !important; }
}

/* ── touch ────────────────────────────────────────────────────────
 * The scoped-monochrome system reveals colour on :hover. Touch has no
 * hover, so without this the board would stay grey on a phone and the
 * whole signal system would silently stop working. */
@media (hover: none) {
  .echo-region { filter: none !important; }
  aside[data-echo-nav] nav a { min-height: 44px; }
  #echoNavToggle { min-width: 44px; min-height: 44px; }
}

/* ── embed mode (?embed=1) ────────────────────────────────────────
 * Drops nav + header so an iframe shows only the dashboard surface. */
html.echo-embed aside[data-echo-nav],
html.echo-embed header[style*="position:sticky"],
html.echo-embed #echoNavToggle,
html.echo-embed #echoScrim { display: none !important; }
html.echo-embed body > div[style*="display:flex"] { display: block !important; }
html.echo-embed main { padding: 12px !important; }
html.echo-embed main > div { max-width: none !important; }
