/* =========================================================================
   _il_shell.css — IntraLogic enterprise APP SHELL + design system (redesign).
   Loaded AFTER _enterprise.css. Owns the new left-sidebar layout, slim top bar,
   active-client bar, and the shared component vocabulary (MetricCard,
   SectionCard, DataTable, RightDetailsPanel, StatusBadge) the mockups define.
   Light-first. Accent sampled from the mockups (#2360c4).
   ========================================================================= */

/* ── TOKENS LIVE IN _enterprise.css ────────────────────────────────────────
   This file used to declare the whole palette, the radius/shadow scale, the
   shell geometry and the z-index ladder under `html:root, html:not([data-theme
   ="dark"])`. Two problems with that:

     1. Twelve token values were declared in BOTH sheets with DIFFERENT values
        (--bg, --line, --text, --muted, --muted2, --panel2, --accent-hover,
        --focus-ring, --il-hover, --il-hover-strong, --il-border-soft and
        --radius-sm 6px vs 8px). This file loads second, so it quietly won —
        which meant the effective palette depended on link ORDER, and on
        profile.html, where the two links are reversed, the app really did
        render a different grey.
     2. `html:root` matches even when data-theme="dark" is set. Loading after
        _enterprise.css, this block overwrote ten of the dark tokens with their
        light values, and supplied --ok/--warn/--crit and the --blue/--green/…
        aliases to dark pages as LIGHT colours, because dark had no twins.

   Every token now lives in _enterprise.css under three blocks: theme-independent
   on `html:root`, light on `html:not([data-theme="dark"])`, dark on
   `html[data-theme="dark"]`. The values were carried over verbatim from here —
   whichever value was winning is the value that survived — so nothing moved on
   screen. This file consumes them like every page does. Add a new token there,
   never here. */

/* =======================================================================
   LAYOUT — fixed sidebar + main column. Body becomes the shell host.
   ======================================================================= */
html body.il-shell {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: Inter, system-ui, -apple-system, sans-serif;
}
.il-sidebar {
  position: fixed; top: 0; left: 0; bottom: 0; width: var(--sidebar-w);
  background: var(--panel); border-right: 1px solid var(--line);
  display: flex; flex-direction: column; z-index: var(--z-sidebar);
  transition: width .16s ease;
}
body.il-rail .il-sidebar { width: var(--sidebar-w-collapsed); }
.il-shellmain {
  margin-left: var(--sidebar-w);
  min-height: 100vh; display: flex; flex-direction: column;
  transition: margin-left .16s ease;
}
body.il-rail .il-shellmain { margin-left: var(--sidebar-w-collapsed); }

/* Embedded in an iframe (Administration renders whole pages this way, e.g.
   admin → Rules). `.il-embed` hides the sidebar, but the margin that reserved
   space for it lived only here — so every embedded page rendered against a
   ~248px dead column inside its own frame, on top of the host page's sidebar.
   Cleared once for the shell rather than per page, since the shell owns this. */
.il-embed .il-shellmain { margin-left: 0; }

/* =======================================================================
   SIDEBAR — logo, grouped nav, active highlight, badges, collapse.
   ======================================================================= */
.il-sb-brand {
  display: flex; align-items: center; gap: 10px;
  height: var(--topbar-h); padding: 0 18px; flex-shrink: 0;
  border-bottom: 1px solid var(--line);
  font-weight: 800; letter-spacing: .04em; font-size: 14px; color: var(--text);
  white-space: nowrap; overflow: hidden;
}
.il-sb-brand .il-sb-mark { width: 22px; height: 22px; flex-shrink: 0; color: var(--accent); }

/* ── Brand wordmark ─────────────────────────────────────────────────────────
   The same mark the marketing site uses, and deliberately the same TECHNIQUE:
   real text in two spans, not an image, so it stays selectable, scales, and
   recolours from the theme tokens. Poppins 700 is self-hosted (7.6KB) — the
   only webfont in the app, loaded for this one word. font-display:swap, so it
   never blocks a login. */
@font-face{font-family:'Poppins';font-style:normal;font-weight:700;font-display:swap;
  src:url('fonts/poppins-700.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
.il-wm{font-family:Poppins,Inter,system-ui,sans-serif;font-weight:700;letter-spacing:-.01em;
  white-space:nowrap;text-transform:none}
.il-wm-a{color:var(--blue)}
.il-wm-b{color:var(--text)}
/* Reversed treatment, for the slate report cover and email masthead. */
.il-wm--on-dark .il-wm-a{color:#93b4f0}
.il-wm--on-dark .il-wm-b{color:#fff}
/* Lockup — the bare four-node glyph beside the wordmark (decided 2026-08-03).
   The glyph takes currentColor, so it tints with whatever surface it sits on.
   Markup comes from IlBrand.lockup() in _il_brand.js; these are the only rules
   it needs, and they live here rather than in a page so nothing forks again. */
.il-wm-lockup{display:inline-block;line-height:1;color:var(--blue)}
.il-wm-lockup-row{display:inline-flex;align-items:center;gap:.42em}
.il-wm-glyph{flex:0 0 auto;display:block}
.il-wm-tag{font-size:.5em;font-weight:600;letter-spacing:.14em;text-transform:uppercase;
  color:var(--muted2);margin-top:2px}

body.il-rail .il-sb-brand .il-sb-wordmark { display: none; }

.il-sb-scroll { flex: 1; overflow-y: auto; overflow-x: hidden; padding: 10px 10px 16px; }
.il-sb-group { margin-top: 14px; }
.il-sb-group:first-child { margin-top: 4px; }
.il-sb-grouph {
  display: flex; align-items: center; gap: 6px; width: 100%;
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .08em;
  color: var(--muted2); padding: 8px 10px 4px; border: 0; background: none;
  cursor: pointer; font-family: inherit; text-align: left;
}
.il-sb-grouph span { flex: 1; }
.il-sb-grouph:hover { color: var(--muted); }
.il-sb-gchev { width: 13px; height: 13px; color: var(--muted2); flex-shrink: 0; transition: transform .15s ease; }
.il-sb-group.collapsed .il-sb-gchev { transform: rotate(-90deg); }
.il-sb-group.collapsed .il-sb-gitems { display: none; }
body.il-rail .il-sb-grouph { opacity: 0; height: 8px; padding: 0; pointer-events: none; }
/* In rail mode, always show items regardless of group-collapse. */
body.il-rail .il-sb-group.collapsed .il-sb-gitems { display: block; }

/* Brand wordmark (no icon mark) + tagline, matching the mockup. */
.il-sb-brand { align-items: center; }
.il-sb-brandtext { overflow: hidden; }
.il-sb-wordmark { font-size: 17px; line-height: 1.1; }
.il-sb-tag { font-size: 8.5px; font-weight: 700; letter-spacing: .12em; color: var(--muted2); text-transform: uppercase; margin-top: 2px; }
body.il-rail .il-sb-tag { display: none; }

.il-sb-item {
  display: flex; align-items: center; gap: 11px; width: 100%;
  padding: 8px 10px; margin-bottom: 2px; border-radius: var(--radius-sm);
  color: #3c4a5e; font-size: 13px; font-weight: 500; text-decoration: none;  /* darker nav label per mockup */
  cursor: pointer; border: 0; background: none; font-family: inherit; text-align: left;
  white-space: nowrap; position: relative;
}
.il-sb-item:hover { background: var(--panel2); color: var(--text); }
.il-sb-item.active { background: var(--accent-soft); color: var(--accent); font-weight: 600; }
.il-sb-item.active .il-sb-ic { color: var(--accent); }
.il-sb-ic { width: 18px; height: 18px; flex-shrink: 0; color: var(--muted); }
.il-sb-item:hover .il-sb-ic { color: var(--text); }
.il-sb-label { flex: 1; overflow: hidden; text-overflow: ellipsis; }
body.il-rail .il-sb-label { display: none; }
.il-sb-badge {
  font-size: 10px; font-weight: 800; line-height: 1; padding: 3px 6px;
  border-radius: var(--radius-pill); background: var(--crit); color: #fff; flex-shrink: 0;
}
body.il-rail .il-sb-badge { position: absolute; top: 4px; right: 6px; padding: 2px 4px; font-size: 8px; }

.il-sb-foot { flex-shrink: 0; border-top: 1px solid var(--line); padding: 8px 10px; }
.il-sb-collapse {
  display: flex; align-items: center; gap: 11px; width: 100%; padding: 8px 10px;
  border: 0; background: none; color: var(--muted); font: inherit; font-size: 12px;
  cursor: pointer; border-radius: var(--radius-sm);
}
.il-sb-collapse:hover { background: var(--panel2); color: var(--text); }
.il-sb-collapse svg { width: 18px; height: 18px; flex-shrink: 0; transition: transform .16s ease; }
body.il-rail .il-sb-collapse svg { transform: rotate(180deg); }
body.il-rail .il-sb-collapse span { display: none; }

/* =======================================================================
   TOP BAR — slim, sticky. Search (left-center) + right controls.
   ======================================================================= */
.il-topbar {
  height: var(--topbar-h); flex-shrink: 0; position: sticky; top: 0; z-index: var(--z-topbar);
  display: flex; align-items: center; gap: 14px; padding: 0 20px;
  background: rgba(255,255,255,.86); backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.il-tb-search {
  display: inline-flex; align-items: center; gap: 9px; width: min(420px, 42%);
  padding: 8px 12px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--panel2); color: var(--muted2); cursor: text; font-size: 13px;
}
.il-tb-search:hover { border-color: var(--muted2); }
.il-tb-search svg { width: 15px; height: 15px; }
.il-tb-search .il-tb-kbd { margin-left: auto; font-size: 10px; font-weight: 700; padding: 2px 6px;
  border: 1px solid var(--line); border-radius: 5px; background: var(--panel); }
.il-tb-spacer { flex: 1; }
.il-tb-right { display: inline-flex; align-items: center; gap: 8px; }
.il-tb-icon {
  width: 34px; height: 34px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius-sm); border: 1px solid transparent; background: none;
  color: var(--muted); cursor: pointer;
}
.il-tb-icon:hover { background: var(--panel2); color: var(--text); }
.il-tb-icon svg { width: 18px; height: 18px; }

/* =======================================================================
   ACTIVE-CLIENT BAR — thin blue-tinted strip under the top bar.
   ======================================================================= */
.il-clientbar {
  display: flex; align-items: center; gap: 10px; padding: 8px 22px;
  background: var(--accent-softer); border-bottom: 1px solid var(--line);
  font-size: 12px; color: var(--muted);
}
.il-clientbar .il-cb-label { text-transform: uppercase; letter-spacing: .06em; font-size: 10px; font-weight: 700; color: var(--accent); }
.il-clientbar .il-cb-name { font-weight: 700; color: var(--text); font-size: 13px; }
.il-clientbar .il-cb-switch { margin-left: auto; color: var(--accent); text-decoration: none; font-weight: 600; }
.il-clientbar .il-cb-switch:hover { text-decoration: underline; }

/* Page content padding host */
.il-page { padding: 20px 24px; }

/* =======================================================================
   COMPONENTS — the shared vocabulary the pages compose from.
   ======================================================================= */
/* MetricCard — KPI tile */
.il-metric { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius-card);
  box-shadow: var(--shadow-card); padding: 13px 15px; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.il-metric .il-m-label { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; font-weight: 600; }
.il-metric .il-m-value { font-size: 22px; font-weight: 800; color: var(--text); line-height: 1.1; letter-spacing: -.01em; }
.il-metric .il-m-sub { font-size: 11px; color: var(--muted2); }
.il-metric-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; }

/* SectionCard */
.il-section { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius-card);
  box-shadow: var(--shadow-card); }
.il-section-h { display: flex; align-items: center; gap: 10px; padding: 13px 16px; border-bottom: 1px solid var(--line); }
.il-section-h h3 { margin: 0; font-size: 13px; font-weight: 700; color: var(--text); }
.il-section-h .il-section-act { margin-left: auto; font-size: 12px; color: var(--accent); text-decoration: none; font-weight: 600; white-space: nowrap; }
.il-section-h .il-section-act:hover { text-decoration: underline; }
.il-section-b { padding: 14px 16px; }

/* StatusBadge */
.il-badge { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; font-weight: 700;
  padding: 2px 9px; border-radius: var(--radius-pill); border: 1px solid transparent; white-space: nowrap; }
.il-badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.il-badge.ok   { color: var(--ok);   background: rgba(31,157,87,.10);  border-color: rgba(31,157,87,.22); }
.il-badge.warn { color: var(--warn); background: rgba(217,138,31,.10); border-color: rgba(217,138,31,.22); }
.il-badge.crit { color: var(--crit); background: rgba(210,69,69,.10);  border-color: rgba(210,69,69,.22); }
.il-badge.neutral { color: var(--muted); background: var(--panel2); border-color: var(--line); }

/* DataTable */
.il-dtable { width: 100%; border-collapse: collapse; font-size: 13px; }
.il-dtable thead th { text-align: left; font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; color: var(--muted2); padding: 10px 14px; border-bottom: 1px solid var(--line); white-space: nowrap; }
.il-dtable tbody td { padding: 8px 14px; border-bottom: 1px solid var(--line); color: var(--text); vertical-align: middle; }
.il-dtable tbody tr:hover { background: var(--panel2); cursor: pointer; }
.il-dtable tbody tr:last-child td { border-bottom: 0; }

/* RightDetailsPanel */
.il-rpanel { background: var(--panel); border-left: 1px solid var(--line); width: 320px; flex-shrink: 0;
  display: flex; flex-direction: column; }
.il-rpanel-tabs { display: flex; border-bottom: 1px solid var(--line); }
.il-rpanel-tab { flex: 1; padding: 11px 8px; background: none; border: 0; border-bottom: 2px solid transparent;
  color: var(--muted2); font: inherit; font-size: 12px; font-weight: 600; cursor: pointer; }
.il-rpanel-tab:hover { color: var(--text); }
.il-rpanel-tab.active { color: var(--accent); border-bottom-color: var(--accent); }
.il-rpanel-b { flex: 1; overflow-y: auto; padding: 16px; }

/* =======================================================================
   TOP BAR controls (added) — mode toggle, page actions, user chip.
   ======================================================================= */
.il-tb-actions { display: inline-flex; align-items: center; gap: 8px; }
.il-btn { font-size: 13px; font-weight: 600; padding: 7px 13px; border-radius: var(--radius-sm);
  border: 1px solid var(--line); background: var(--panel); color: var(--text); cursor: pointer; font-family: inherit; }
.il-btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.il-btn:hover { background: var(--panel2); }
.il-btn.primary:hover { background: var(--accent-hover); }

.il-tb-mode { display: inline-flex; align-items: center; gap: 2px; }
.il-tb-mode button { border: 1px solid transparent; background: none; color: var(--muted); font: inherit;
  font-size: 12.5px; font-weight: 600; padding: 5px 11px; border-radius: var(--radius-pill); cursor: pointer; }
.il-tb-mode button:hover { color: var(--text); }
.il-tb-mode button.active { background: var(--accent-soft); color: var(--accent); }
.il-tb-mode button[data-mode="simulate"].active { background: rgba(217,138,31,.12); color: var(--warn); }
.il-tb-mode button[data-mode="edit"].active { background: rgba(31,157,87,.12); color: var(--ok); }

.il-tb-icon { position: relative; }
.il-tb-dot { position: absolute; top: 7px; right: 8px; width: 7px; height: 7px; border-radius: 50%;
  background: var(--crit); border: 1.5px solid var(--panel); }

.il-tb-user { display: inline-flex; }
.il-tb-userbtn { display: inline-flex; align-items: center; gap: 9px; border: 0; background: none;
  cursor: pointer; padding: 4px 6px 4px 4px; border-radius: var(--radius-pill); font: inherit; }
.il-tb-userbtn:hover { background: var(--panel2); }
.il-tb-avatar { width: 30px; height: 30px; border-radius: 50%; background: var(--accent); color: #fff;
  display: inline-flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 800; flex-shrink: 0; }
.il-tb-uname { display: flex; flex-direction: column; line-height: 1.15; text-align: left; }
.il-tb-uname .n { font-size: 12.5px; font-weight: 700; color: var(--text); }
.il-tb-uname .r { font-size: 10px; color: var(--muted2); text-transform: capitalize; }
.il-tb-user { position: relative; }
.il-tb-ucaret { font-size: 13px; line-height: 1; color: var(--muted); flex-shrink: 0; margin-left: 1px; }
/* Mode pill (injected by _il_mode.js into #ilTopnavMode) — light-mode chrome. */
.il-tb-modeslot { display: inline-flex; }
.il-shell .il-mode-pill { border: 0; background: none; padding: 0; gap: 2px; }
html:not([data-theme="dark"]) .il-shell .il-mode-seg { color: var(--muted); }
html:not([data-theme="dark"]) .il-shell .il-mode-seg:hover { color: var(--text); background: var(--panel2); }
.il-tb-usermenu { position: absolute; top: calc(100% + 8px); right: 0; min-width: 244px; z-index: 60;
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px; padding: 6px;
  box-shadow: 0 16px 40px rgba(16,32,64,.16), 0 4px 12px rgba(16,32,64,.08); }
.il-tb-usermenu[hidden] { display: none; }
.il-um-sub { font-size: 10px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--muted2); padding: 8px 10px 3px; }
.il-um-head { padding: 2px 10px 10px; }
.il-um-head .n { font-size: 13px; font-weight: 700; color: var(--text); }
.il-um-head .e { font-size: 11px; color: var(--muted2); margin-top: 1px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.il-um-head .r { font-size: 10px; color: var(--muted2); text-transform: uppercase; letter-spacing: .05em; margin-top: 4px;
  display: inline-flex; align-items: center; gap: 6px; }
.il-um-ro { font-size: 9px; font-weight: 700; color: var(--warn); background: rgba(217,138,31,.12);
  border: 1px solid rgba(217,138,31,.3); border-radius: 4px; padding: 1px 5px; letter-spacing: .03em; }
.il-um-divider { height: 1px; background: var(--line); margin: 5px 4px; }
.il-um-theme { display: flex; gap: 6px; padding: 2px 8px 4px; }
.il-um-theme button { flex: 1; padding: 6px 10px; border: 1px solid var(--line); border-radius: 7px;
  background: var(--panel); color: var(--muted); font: inherit; font-size: 12px; font-weight: 600; cursor: pointer; }
.il-um-theme button:hover { background: var(--panel2); }
.il-um-theme button.active { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }
.il-um-item { display: flex; align-items: center; gap: 10px; width: 100%; padding: 9px 10px; border: 0;
  background: none; border-radius: 8px; font: inherit; font-size: 13px; color: var(--text); cursor: pointer;
  text-decoration: none; text-align: left; }
.il-um-item svg { width: 16px; height: 16px; color: var(--muted2); flex-shrink: 0; }
.il-um-item:hover { background: var(--panel2); }
.il-um-item.danger { color: var(--crit); }
.il-um-item.danger:hover { background: rgba(210,69,69,.08); }
.il-um-item.danger svg { color: var(--crit); }

/* =======================================================================
   PAGE HEADER, TOOLBAR, VIEW TOGGLE, PAGINATION (added)
   ======================================================================= */
.il-pagehdr { display: flex; align-items: flex-start; gap: 14px; margin-bottom: 16px; }
.il-pagehdr .h { flex: 1; }
.il-pagehdr .h .t { font-size: 18px; font-weight: 700; color: var(--text); letter-spacing: -.01em; }
.il-pagehdr .h .s { font-size: 12px; color: var(--muted); margin-top: 2px; }

.il-toolbar { display: flex; align-items: center; gap: 10px; padding: 12px 16px; border-bottom: 1px solid var(--line); }
.il-toolbar .il-tinput { flex: 1; max-width: 320px; display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 11px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--panel2);
  color: var(--muted2); font-size: 13px; }
.il-toolbar .il-tinput svg { width: 14px; height: 14px; flex-shrink: 0; }
.il-toolbar .il-tinput input { flex: 1; min-width: 0; border: 0; outline: none; background: none; padding: 0;
  font: inherit; font-size: 13px; color: var(--text); }
.il-toolbar .il-tinput input::placeholder { color: var(--muted2); }
.il-toolbar .il-tinput:focus-within { border-color: var(--accent); }
.il-toolbar .il-tfilter { padding: 7px 11px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--panel); color: var(--text); font-size: 13px; cursor: pointer; }
.il-toolbar .il-tspacer { flex: 1; }
.il-viewtoggle { display: inline-flex; border: 1px solid var(--line); border-radius: var(--radius-sm); overflow: hidden; }
.il-viewtoggle button { border: 0; background: var(--panel); color: var(--muted); padding: 7px 9px; cursor: pointer; display: inline-flex; }
.il-viewtoggle button.active { background: var(--accent-soft); color: var(--accent); }
.il-viewtoggle button svg { width: 16px; height: 16px; }

.il-pager { display: flex; align-items: center; gap: 8px; padding: 11px 16px; border-top: 1px solid var(--line);
  font-size: 12px; color: var(--muted); }
.il-pager .il-pspacer { flex: 1; }
.il-pager select, .il-pager button { border: 1px solid var(--line); border-radius: 6px; background: var(--panel);
  color: var(--text); font: inherit; font-size: 12px; padding: 4px 8px; cursor: pointer; }
.il-pager .pg { min-width: 26px; text-align: center; }
.il-pager .pg.active { background: var(--accent); color: #fff; border-color: var(--accent); }

/* Top-finding-categories bar rows */
.il-tfc-row { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 8px; padding: 5px 0; font-size: 12px; }
.il-tfc-row .bar { grid-column: 1 / -1; height: 5px; border-radius: 3px; background: var(--panel2); overflow: hidden; }
.il-tfc-row .bar > span { display: block; height: 100%; border-radius: 3px; background: var(--accent); }

/* Donut + legend (portfolio / status summaries) */
.donut-wrap { display: flex; align-items: center; gap: 14px; }
.donut-legend { font-size: 11.5px; color: var(--muted); display: flex; flex-direction: column; gap: 6px; flex: 1; }
.donut-legend .row { display: flex; align-items: center; gap: 7px; }
.donut-legend .dot { width: 8px; height: 8px; border-radius: 2px; flex-shrink: 0; }
.donut-legend b { margin-left: auto; color: var(--text); }
.donut-legend-links .row { text-decoration: none; color: inherit; border-radius: 6px; padding: 2px 5px; margin: 0 -5px;
  cursor: pointer; transition: background .12s; }
.donut-legend-links .row:hover { background: var(--panel2); }
.donut-legend-links .row:hover b { color: var(--accent); }

/* Table secondary text + numeric cells */
.csub { font-size: 11px; color: var(--muted2); font-weight: 400; margin-top: 1px; }
.il-dtable td.num { text-align: right; font-variant-numeric: tabular-nums; }
.il-dtable td.num b { font-weight: 700; }
/* A value read CHARACTER BY CHARACTER rather than as a word — a version, a
   serial, a MAC, an MTU. Tabular figures line the digits up by position, which
   is the whole reason 17.09.04a jumps out of a column of 17.12.04 instead of
   having to be inspected. On a surface whose entire job is spotting one value
   that differs from five others, proportional digits work against the reader. */
.il-dtable td.val, .il-val {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-variant-numeric: tabular-nums;
  font-size: 12.5px;
}
.il-dtable td.num .hi { font-size: 11px; display: block; }

/* Activity rows (recent client / change feeds) */
.act-row { display: flex; gap: 9px; padding: 8px 0; font-size: 12px; border-bottom: 1px solid var(--line); }
.act-row:last-child { border-bottom: 0; }
.act-row .ad { width: 7px; height: 7px; border-radius: 50%; margin-top: 5px; flex-shrink: 0; }

/* =======================================================================
   CLIENT DASHBOARD (client_hub) — overall health, infra grid, feeds
   ======================================================================= */
.spark { width: 100%; height: 22px; display: block; }
/* Overall-health strip */
.oh { display: grid; grid-template-columns: auto 1fr; gap: 20px; align-items: center; }
.oh-kpis { display: grid; grid-template-columns: repeat(6, 1fr); gap: 0; }
.oh-kpi { padding: 0 16px; border-left: 1px solid var(--line); }
/* A KPI that navigates has to say so. These are real <a>s (see client_hub), so
   they are keyboard-reachable for free; this is the affordance. */
.oh-kpi--link { display: block; text-decoration: none; color: inherit; position: relative; border-radius: 8px; transition: background .12s; }
.oh-kpi--link:hover { background: var(--il-hover); }
.oh-kpi--link:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.oh-kpi-go { position: absolute; top: 2px; right: 8px; font-size: 12px; color: var(--muted2); opacity: 0; transition: opacity .12s; }
.oh-kpi--link:hover .oh-kpi-go, .oh-kpi--link:focus-visible .oh-kpi-go { opacity: 1; }
.oh-kpi:first-child { border-left: 0; padding-left: 4px; }
.oh-kpi .l { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--muted2); }
.oh-kpi .v { font-size: 24px; font-weight: 800; color: var(--text); line-height: 1.1; margin-top: 2px; }
.oh-kpi .s { font-size: 11px; color: var(--muted); margin-top: 2px; }
/* Infrastructure overview cards */
.infra-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 12px; }
.infra-card { background: var(--panel); border: 1px solid var(--line); border-radius: 12px; padding: 12px;
  box-shadow: var(--shadow-card); display: block; text-decoration: none; color: inherit; cursor: pointer;
  transition: border-color .15s, box-shadow .15s, transform .12s; }
.infra-card:hover { border-color: var(--accent); box-shadow: 0 4px 14px rgba(35,96,196,.12); transform: translateY(-1px); }
.infra-card .go { width: 14px; height: 14px; color: var(--muted2); flex-shrink: 0; transition: transform .12s, color .12s; }
.infra-card:hover .go { color: var(--accent); transform: translateX(2px); }
.infra-card .top { display: flex; align-items: flex-start; gap: 8px; }
.infra-card .ic { width: 18px; height: 18px; color: var(--muted); flex-shrink: 0; }
.infra-card .nm { font-size: 12px; font-weight: 700; color: var(--text); flex: 1; line-height: 1.25; }
.infra-card .pct { font-size: 11px; font-weight: 800; }
.infra-card .mets { display: flex; gap: 14px; margin: 9px 0 6px; font-size: 11px; color: var(--muted); }
.infra-card .mets b { color: var(--text); font-weight: 700; display: block; font-size: 14px; }
.infra-card .st { font-size: 10.5px; font-weight: 600; }
/* change / finding / activity rows */
.ch-row { display: flex; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--line); align-items: flex-start; }
.ch-row:last-child { border-bottom: 0; }
.ch-row .pill { font-size: 9px; font-weight: 800; padding: 2px 6px; border-radius: 5px; text-transform: uppercase; flex-shrink: 0; }
.ch-row .pill.crit { background: rgba(210,69,69,.12); color: var(--crit); }
.ch-row .pill.warn { background: rgba(217,138,31,.12); color: var(--warn); }
.ch-row .pill.ok   { background: rgba(31,157,87,.12);  color: var(--ok); }
.ch-row .tt { font-size: 12.5px; font-weight: 600; color: var(--text); }
.ch-row .sub { font-size: 11px; color: var(--muted2); margin-top: 1px; }
.ch-row .tm { margin-left: auto; font-size: 11px; color: var(--muted2); white-space: nowrap; }
.fd-row { display: flex; gap: 10px; padding: 9px 0; align-items: center; border-bottom: 1px solid var(--line); }
.fd-row:last-child { border-bottom: 0; }
.fd-row .n { width: 20px; height: 20px; border-radius: 50%; background: var(--accent-soft); color: var(--accent);
  font-size: 11px; font-weight: 800; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.ac-row { display: flex; gap: 10px; padding: 8px 0; font-size: 12px; border-bottom: 1px solid var(--line); }
.ac-row:last-child { border-bottom: 0; }
.ac-row .tm { margin-left: auto; color: var(--muted2); white-space: nowrap; }
.ac-row .d { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); margin-top: 5px; flex-shrink: 0; }
/* asset summary */
.as-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 0; }
.as-card { padding: 6px 14px; border-left: 1px solid var(--line); text-align: left; }
.as-card:first-child { border-left: 0; padding-left: 4px; }
.as-card .ic { width: 18px; height: 18px; color: var(--muted); margin-bottom: 6px; }
.as-card .v { font-size: 22px; font-weight: 800; color: var(--text); line-height: 1; }
.as-card .l { font-size: 11px; color: var(--muted); margin-top: 2px; }
/* About / capacity info rows (reframed bottom cards) */
.il-inforow { display: flex; justify-content: space-between; gap: 12px; padding: 6px 0; font-size: 12.5px; border-bottom: 1px solid var(--line); }
.il-inforow:last-child { border-bottom: 0; }
.il-inforow .k { color: var(--muted2); }
.il-inforow .v { color: var(--text); font-weight: 600; text-align: right; }
.il-captrack { height: 7px; border-radius: 4px; background: var(--panel2); overflow: hidden; margin: 8px 0 4px; }
.il-captrack > span { display: block; height: 100%; background: var(--accent); }
.il-captrack.warn > span { background: var(--warn); }
.il-captrack.full > span { background: var(--crit); }

/* ── Admin-mode sidebar header (admin.html) ─────────────────────────────── */
.il-sb-adminback { color: var(--accent) !important; font-weight: 600; }
.il-sb-adminback .il-sb-ic { color: var(--accent); }
.il-sb-adminctx { margin-top: 4px; border-top: 1px solid var(--line); padding-top: 12px; }
body.il-rail .il-sb-adminback .il-sb-label, body.il-rail .il-sb-adminctx { display: none; }

/* =======================================================================
   GLOBAL KEYBOARD FOCUS (WCAG 2.4.7 — Option A phase D)
   ONE visible affordance for keyboard/AT focus on interactive controls that
   aren't form fields (those get --focus-ring elsewhere). Same --focus-ring halo
   for a consistent look. `:focus-visible` = keyboard/AT focus only, so mouse
   clicks never draw a ring. _il_shell.css loads LAST on every page, so at equal
   specificity these WIN over the ~26 per-page `:focus{outline:none}` rules that
   otherwise leave keyboard users with no focus indicator.
   ======================================================================= */
a:focus-visible,
button:focus-visible,
[role="button"]:focus-visible,
[tabindex]:focus-visible,
summary:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

/* =======================================================================
   THREE-COLUMN PAGE LAYOUT — left rail · content · right rail.

   This is shell chrome, not page content, and it was forked four ways:

     storage      280px 1fr 300px · gap 16 · padding 18 · max-h 100vh-88px
     virtual      300px 1fr 320px · gap 14 · padding 14 · max-h 100vh-84px
     vdi          300px 1fr 360px · gap 14 · padding 14
     roles_apps   300px 1fr 320px · gap 14 · padding 14

   — while virtual.html's own comment claimed it "matches physical.html /
   storage.html", which it did not. The rails visibly jumped as an operator moved
   between pages, so four views of one estate read as four different products.
   The 4px disagreement in the sticky max-height is the same story in miniature:
   two people solved the same problem twice and landed one rounding apart.

   One definition, derived from --topbar-h so it cannot drift from the shell it
   sits under. Pages consume it; a page that genuinely needs a different rail
   states it as a modifier rather than redeclaring the whole grid.
   ======================================================================= */
.layout {
  display: grid;
  grid-template-columns: var(--rail-left, 300px) minmax(0, 1fr) var(--rail-right, 320px);
  gap: var(--sp-6);
  padding: var(--sp-6);
  align-items: flex-start;
  min-height: calc(100vh - 60px);
}
/* Rails that scroll independently, so a long array/pool/detail list never drags
   the whole page. Opt-in: pages whose right rail hosts a diagram or a canvas
   want it to grow with the content instead. */
.layout--sticky-rails > .col {
  position: sticky;
  top: calc(var(--topbar-h) + 12px);
  max-height: calc(100vh - var(--topbar-h) - 32px);
  overflow-y: auto;
  overflow-x: hidden;
}
/* Grid children floor at min-content, so one long unbroken string — an FQDN, a
   WWN, a datastore path — widens the whole track and pushes the rails around. */
.layout > * { min-width: 0; }

/* ── Field-laptop widths ──────────────────────────────────────────────────────
   1366×768 is still the common MSP technician laptop, and the three-column
   layout was tuned for 1920. Measured at 1366 with the shell sidebar taking
   248px, the CENTRE pane — the one holding the topology diagram, whose nodes
   are 130px wide — came out at 352px. Two and a half nodes.

   The rails hold lists and detail panes, which read fine narrower; the centre
   holds a diagram, which does not. So the rails give up width first, and below
   1280 the right rail stops being a column at all and moves under the centre. */
@media (max-width: 1500px) {
  .layout {
    --rail-left: 260px;
    --rail-right: 288px;
    gap: var(--sp-5);
    padding: var(--sp-5);
  }
}
@media (max-width: 1280px) {
  .layout { grid-template-columns: var(--rail-left, 240px) minmax(0, 1fr); }
  /* The right rail becomes a full-width band beneath the two columns rather
     than a 288px sliver. */
  .layout > aside.right,
  .layout > .col--right,
  .layout > *:nth-child(3) { grid-column: 1 / -1; }
  /* A sticky rail that now spans the full width must stop being sticky, or it
     pins a full-width band over the content as you scroll. */
  .layout--sticky-rails > .col { position: static; max-height: none; }
}

/* =======================================================================
   FRESHNESS STAMP + KPI EXTRAS (see _il_dash.js)

   Only health_score.html ever said when its numbers were true. Every other
   dashboard surface presented a discovery snapshot as live state, which is the
   one thing an infrastructure dashboard must not do — the operator schedules a
   change window on it.
   ======================================================================= */
.il-fresh {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--fs-xs); color: var(--muted2); white-space: nowrap;
}
.il-fresh-dot {
  width: 6px; height: 6px; border-radius: 50%; flex: none;
  background: var(--ok);
}
/* Stale has to LOOK stale. A timestamp alone is not noticeable: "as of 06:12"
   reads as fine until you work out that it is now 19:40. Colour plus the word
   "stale" plus a hollow dot — three channels, so it survives greyscale. */
.il-fresh--stale { color: var(--warn); }
.il-fresh--stale .il-fresh-dot { background: transparent; border: 1.5px solid var(--warn); }
.il-fresh--unknown { color: var(--muted2); }
.il-fresh--unknown .il-fresh-dot { background: transparent; border: 1.5px dashed var(--muted2); }

/* Unknown is not zero. */
.il-metric .il-m-value.is-unknown { color: var(--muted2); font-weight: 700; font-size: 15px; }
.il-metric .il-m-unit { font-size: 13px; color: var(--muted2); font-weight: 600; margin-left: 1px; }
.il-metric .il-m-sub--warn { color: var(--warn); }
.il-metric .il-m-sub--crit { color: var(--crit); }
.il-metric .il-m-sub--ok   { color: var(--ok); }

/* A tile naming a number worth acting on should lead somewhere. */
.il-metric--link { text-decoration: none; transition: border-color .15s ease, box-shadow .15s ease; }
.il-metric--link:hover { border-color: var(--accent); box-shadow: var(--shadow-card); }
.il-metric--link:focus-visible { outline: none; box-shadow: var(--focus-ring); }
