
/* ═══════════════════════════════════════════════════════════════════════════
   RESPONSIVE LAYER - phone / tablet / desktop
   Loaded last on purpose: it has to win over the equal-specificity rules in
   the stylesheets above without every one of them needing an !important.
   Breakpoints
     <= 1180px   small laptop + landscape tablet : 4-7 column grids drop to 2
     <=  900px   portrait tablet                 : everything drops to 1
     <=  620px   phone                           : tighter type, stacked forms
     <=  380px   small phone                     : last bit of padding removed
   Page bodies here set grid-template-columns inline, so the [style*=...]
   selectors are how we reach them without touching every template. Only
   fr-based grids are collapsed - grids with px or auto tracks (avatar rows,
   icon + label + value strips) already read fine narrow and are left alone.
   ══════════════════════════════════════════════════════════════════════════ */
/* ── universal guards: nothing may force the page to scroll sideways ────── */
*, *::before, *::after { box-sizing: border-box; }
/* clip, not hidden: clip contains the overflow WITHOUT turning html/body
   into scroll containers, so programmatic scrolling (anchors,
   scrollIntoView) keeps working. Old engines fall back to hidden. */
html, body { max-width: 100%; overflow-x: clip; }
@supports not (overflow: clip) {
  html, body { overflow-x: hidden; }
}
img, svg, video, canvas, iframe { max-width: 100%; }
.wrap, .fpage, .fpanel, .sf-card, .dash-card { min-width: 0; }
pre, code { overflow-x: auto; word-break: break-word; }
h1, h2, h3, .fhead, .ph-title { overflow-wrap: anywhere; }
/* grid items default to min-width:auto, so a nowrap KPI value (a long
   hostname, an IP list) fixes the track width and blows the auto-fit grid
   past the viewport. Items must be shrinkable; the value itself ellipsizes. */
.ap-kpis > .ap-kpi { min-width: 0; }
/* ── legacy engine compatibility ─────────────────────────────────────────
   Older iOS Safari / Android WebViews: kill the 300 ms tap delay and the
   double-tap zoom on controls, and square cells keep a usable floor size
   where aspect-ratio is unsupported. */
a, button, input, select, textarea, label, summary, [role="button"] {
  touch-action: manipulation;
}
@supports not (aspect-ratio: 1) {
  .cal-cell { min-height: 44px; }
}
/* ── tables get their own scroll box instead of widening the page ───────── */
.tscroll { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.tscroll > table { min-width: max-content; }
/* fixed-layout patch tables size to their container and wrap their cells
   (overflow-wrap:anywhere) - max-content sizing would let one long token
   blow a column out to thousands of px inside the plan/fix output */
.tscroll > table.pm-pf { min-width: 0; }
/* ═══ TABLE TEMPLATE - the RESULTS ▸ IP INTELLIGENCE look, everywhere ════ */
/* Every scrollable data table becomes a bordered, rounded, titled box with
   an opaque sticky header band and an accent scrollbar. The IP INTELLIGENCE
   table in /results is the reference. (Feeds' .vi-table-wrap keeps its own
   scroll - no pinned header - but still gets the boxed look/scrollbar.) */
.tscroll, .hist-scroll, .fl-wrap, .mt-table-wrap, .vi-table-wrap {
  border: 1px solid var(--border2, #33333b);
  border-radius: 9px;
  background: var(--bg2, #111114);
}
.tscroll::-webkit-scrollbar, .hist-scroll::-webkit-scrollbar,
.fl-wrap::-webkit-scrollbar, .mt-table-wrap::-webkit-scrollbar,
.vi-table-wrap::-webkit-scrollbar { width: 9px; height: 9px; }
.tscroll::-webkit-scrollbar-track, .hist-scroll::-webkit-scrollbar-track,
.fl-wrap::-webkit-scrollbar-track, .mt-table-wrap::-webkit-scrollbar-track,
.vi-table-wrap::-webkit-scrollbar-track { background: var(--bg3, #070712); }
.tscroll::-webkit-scrollbar-thumb, .hist-scroll::-webkit-scrollbar-thumb,
.fl-wrap::-webkit-scrollbar-thumb, .mt-table-wrap::-webkit-scrollbar-thumb,
.vi-table-wrap::-webkit-scrollbar-thumb { background: var(--acc); border-radius: 4px;
  border: 2px solid var(--bg3, #070712); }
/* pinned header band (boxed tables only) */
.hist-scroll thead th, .fl-wrap thead th, .mt-table-wrap thead th {
  background: var(--bg3, #16161a);
  border-bottom: 2px solid var(--edge2, #3a3a44);
  box-shadow: 0 1px 0 var(--edge2, #3a3a44);
}
/* ══ <= 1180px - wide grids become two columns ═════════════════════════════ */
@media (max-width: 1180px) {
  [style*="repeat(4,minmax(0,1fr))"], [style*="repeat(4, 1fr)"],
  [style*="repeat(5,minmax(0,1fr))"], [style*="repeat(5, 1fr)"],
  [style*="repeat(6,minmax(0,1fr))"], [style*="repeat(6, 1fr)"],
  [style*="repeat(7,minmax(0,1fr))"], [style*="repeat(7, 1fr)"],
  [style*="repeat(8,minmax(0,1fr))"], [style*="repeat(8, 1fr)"] {
    grid-template-columns: repeat(2, 1fr) !important;
  }
  .g4, .kpis, .kpi-row { grid-template-columns: repeat(2, 1fr) !important; }
}
/* ══ <= 900px - single column, roomier touch targets ═══════════════════════ */
@media (max-width: 900px) {
  [style*="repeat(2,minmax(0,1fr))"], [style*="repeat(2, 1fr)"],
  [style*="repeat(3,minmax(0,1fr))"], [style*="repeat(3, 1fr)"],
  [style*="repeat(4,minmax(0,1fr))"], [style*="repeat(4, 1fr)"],
  [style*="repeat(5,minmax(0,1fr))"], [style*="repeat(5, 1fr)"],
  [style*="repeat(6,minmax(0,1fr))"], [style*="repeat(6, 1fr)"],
  [style*="repeat(7,minmax(0,1fr))"], [style*="repeat(7, 1fr)"],
  [style*="repeat(8,minmax(0,1fr))"], [style*="repeat(8, 1fr)"],
  [style*="columns:1fr 1fr"], [style*="columns: 1fr 1fr"],
  [style*="columns:1fr 1.1fr"], [style*="columns:1fr 1.2fr"],
  [style*="columns:1fr 1.3fr"], [style*="columns:1fr 2fr"],
  [style*="columns:1.1fr 1fr"], [style*="columns:1.2fr 1fr"],
  [style*="columns:1.3fr 1fr"], [style*="columns:2fr 1fr"] {
    grid-template-columns: 1fr !important;
  }
  .g2, .g3, .g4, .kpis, .kpi-row,
  .dash-grid, .sf-grid, .chg, .vi-kpis, .calc-grid,
  .ex-grid, .rw-grid, .poc-grid, .lp-cards, .lp-mods, .lp-svc,
  /* these three declare a fixed multi-column grid and ship no mobile
     fallback of their own */
  .ap-grid, .mt-facts, .lp-cap {
    grid-template-columns: 1fr !important;
  }
  .wrap, .fpage { padding-left: 14px; padding-right: 14px; }
  .fpanel, .sf-card, .dash-card { padding: 14px; }
  /* comfortable hit targets everywhere, not just in the nav drawer */
  button, .fbtn, .btn, a.fbtn, input[type="submit"] { min-height: 44px; }
}
/* ══ <= 700px - catch-all for inline grids the explicit selectors miss ════ */
@media (max-width: 700px) {
  /* Any inline multi-column grid that slipped past the enumeration above
     (e.g. "grid-template-columns:1fr 1.6fr") collapses to one column.
     repeat(auto-fit/fill) and auto-track rows (icon + label + value strips)
     are left alone because they already reflow correctly when narrow. */
  [style*="grid-template-columns:"][style*="fr"]:not([style*="auto"]):not([style*="repeat("]):not([style*="minmax("]) {
    grid-template-columns: 1fr !important;
  }
}
/* ══ <= 620px - phone ══════════════════════════════════════════════════════ */
@media (max-width: 620px) {
  /* 16px is the threshold below which iOS Safari zooms on focus */
  input, select, textarea { font-size: 16px !important; max-width: 100%; }
  .wrap, .fpage { padding-left: 11px; padding-right: 11px; }
  .fhead, .ph-title { font-size: 21px; line-height: 1.25; }
  .fsub { font-size: 12.5px; }
  h1 { font-size: 22px; }
  h2 { font-size: 18px; }
  /* KPI figures are sized for a desktop card and overflow at this width */
  .kpi-val, .kpi-num, .sf-kpi-v, .big-num { font-size: 26px !important; }
  /* stack anything laid out as a row of controls */
  .fform-row, .frow, .fbar, .ftoolbar, .filters {
    flex-direction: column; align-items: stretch;
  }
  .fform-row > *, .frow > *, .fbar > * { width: 100%; min-width: 0; }
  .fbtn, .btn { width: 100%; justify-content: center; }
  .fbtn.inline, .btn.inline { width: auto; }
  table { font-size: 12px; }
  th, td { padding: 7px 8px !important; }
}
/* ══ <= 380px - small phones ═══════════════════════════════════════════════ */
@media (max-width: 380px) {
  .wrap, .fpage { padding-left: 8px; padding-right: 8px; }
  .fpanel, .sf-card, .dash-card { padding: 11px; }
  .fhead, .ph-title { font-size: 19px; }
}
/* ── mobile nav/drawer touch behaviour ──────────────────────────────────── */
@media (max-width: 1000px) {
  .sb a, .sb button { touch-action: manipulation; }
  .sb a, .sb button { -webkit-tap-highlight-color: transparent; }
  /* fast taps must never be aborted by a scroll catch in the drawer */
  .sb { overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
  /* CRITICAL: this lives in <head>, not only in the end-of-body fix layer.
     The fix layer renders after the whole 1 MiB document, so on a cold slow
     connection the browser paints before reaching it - then the strip
     padding applies and shoves the entire page down 54px (CLS 0.37 on the
     dashboard). Declaring it here makes the first paint correct. */
  .has-sb { padding-top: 54px; padding-bottom: env(safe-area-inset-bottom, 0px); }
  .has-sb .wrap, .has-sb .fpage { padding-top: 0; }
}
/* ═══════════════════════════════════════════════════════════════════════════
   ACCESSIBILITY LAYER
   Keyboard, screen-reader and low-vision affordances that apply to every
   page, so individual templates do not each have to remember them.
   ══════════════════════════════════════════════════════════════════════════ */
/* ── keyboard focus must always be visible ──────────────────────────────── */
/* :focus-visible only fires for keyboard users, so mouse users see nothing
   change while keyboard users always know where they are. */
a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible, summary:focus-visible,
[tabindex]:focus-visible, [role="button"]:focus-visible,
[role="tab"]:focus-visible, [role="menuitem"]:focus-visible {
  outline: 3px solid var(--acc, #ffd400);
  outline-offset: 2px;
  border-radius: 4px;
}
/* never leave an element with no focus indicator at all */
:focus-visible { outline: 3px solid var(--acc, #ffd400); outline-offset: 2px; }
/* the skip link stays hidden until it is focused */
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 2000;
  padding: 12px 18px; background: var(--bg2, #111114); color: var(--text, #f6f6f8);
  border: 2px solid var(--acc, #ffd400); border-radius: 0 0 8px 0;
  font-family: var(--fm); font-size: 14px; text-decoration: none;
}
.skip-link:focus, .skip-link:focus-visible { left: 0; }
/* main region is focus target for the skip link but must not show a ring */
#main-content:focus { outline: none; }
/* ── screen-reader-only helper ──────────────────────────────────────────── */
.sr-only, .visually-hidden {
  position: absolute !important; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}
/* ── MOBILE READABILITY (first-paint critical) ─────────────────────────────
   The shell pins body to 13px globally; phones get a real reading size.
   These rules deliberately live in <head>, NOT in the end-of-body fix
   layer: on a cold slow load the browser paints before the parser reaches
   the end of a 1 MiB document, and layout rules that arrive after that
   paint shove the whole page (measured CLS 0.37 on the dashboard). */
@media (max-width: 620px) {
  body, :root[data-theme="light"] body {
    font-size: 16px !important;
    line-height: 1.55 !important;
  }
  h1, .fhead { font-size: 23px !important; }
  h2 { font-size: 19px !important; }
  h3 { font-size: 16px !important; }
  h4 { font-size: 15px !important; }
  /* denser cards: less chrome, more data per screen */
  .fpanel, .panel, .card {
    padding: 12px !important;
    margin-bottom: 12px !important;
  }
  .fhead, .panel-label, .card-title { letter-spacing: .04em !important; }
  /* panel intros and helper text stay legible */
  .fsub, .chc-s, .pm-drv, .hbar-h span {
    font-size: 12.5px !important;
  }
  /* KPI numbers keep their weight but fit narrower cards */
  .fc3d .v, .chc-v { overflow-wrap: anywhere; }
  /* the dashboard header stacks deterministically and keeps its band, so
     the late webfont settle can't re-wrap it and push the page down */
  .ys-pagehead { min-height: 112px; flex-direction: column;
    align-items: flex-start; gap: 10px; }
  .ys-pagehead > div { max-width: 100%; }
}
/* ── scrollable table boxes must be reachable by keyboard ───────────────── */
/* A div that scrolls is unusable without a mouse unless it can take focus;
   the script below adds tabindex, this makes the focus state legible. */
.tscroll:focus-visible { outline: 3px solid var(--acc, #ffd400); outline-offset: 2px; }
/* ── motion ─────────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
/* ── high contrast / forced colours ─────────────────────────────────────── */
@media (prefers-contrast: more) {
  :root { --muted: #e8e8ef; --border: #6a6a78; --border2: #8a8a99; }
  a { text-decoration: underline; }
}
@media (forced-colors: active) {
  * { forced-color-adjust: auto; }
  a:focus-visible, button:focus-visible { outline: 3px solid Highlight; }
}
/* ── target size: WCAG 2.2 asks for 24x24 minimum ───────────────────────── */
button, [role="button"], a.fbtn, .btn, input[type="checkbox"], input[type="radio"] {
  min-height: 24px; min-width: 24px;
}
/* ── respect the user's font size; never disable zoom ───────────────────── */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
/* ── printing / very wide screens keep the desktop layout untouched ─────── */
@media (min-width: 1181px) { .tscroll { overflow-x: visible; } }
