/* app.css — page glue ONLY: the shell the app mounts into.

   Everything about a mark's appearance — rest opacity, the dim-the-world
   highlight, the lit subgraph — lives in app.jsx, drawn as elements. It is
   deliberately not here: a class on the svg root that restyles thousands of
   descendants costs a full-subtree style recalc per mouse move, which is what
   made a hover blank the plate. One SSOT for appearance, and hover stays
   O(connected). */

html, body.fx-page { height: 100%; }
body.fx-page {
  margin: 0;
  background: #0A0E18;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
body.fx-page .site-header { flex-shrink: 0; }
#fx-root {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.fx-noscript {
  color: #C0C8D8;
  font: 14px/1.6 'Inter', system-ui, sans-serif;
  padding: 40px;
}
.fx-noscript a { color: var(--beam, #00A3AD); }

.fx-grid .node { cursor: pointer; }

/* ── table view ── static per-row appearance; a hover lights ONE row via the
   `lit` class on that <tr> (set by the app), never a class on an ancestor. */
.fx-table { border-collapse: separate; border-spacing: 0; width: 100%;
  font: 11px/1.3 'Inter', system-ui, sans-serif; color: #D8DFEA; }
.fx-table th, .fx-table td { padding: 5px 7px; border-bottom: 1px solid #111827; white-space: nowrap; text-align: left; }
/* Names wrap to as many lines as they need — nothing clamped or elided; a
   long registered name costs a taller row, never lost words. */
.fx-table th.grow, .fx-table td:nth-child(2) { white-space: normal; min-width: 170px; max-width: 280px; overflow-wrap: anywhere; }
.fx-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.fx-table thead th { position: sticky; top: 0; z-index: 2; background: #0C1120; color: #93A0B6;
  font-size: 9.5px; font-weight: 700; letter-spacing: 0.7px; text-transform: uppercase;
  cursor: pointer; user-select: none; border-bottom: 1px solid #1E2B42; }
.fx-table thead th:hover, .fx-table thead th.sorted { color: #F2F5FA; }
.fx-table .fx-sort-mark { color: var(--beam, #00A3AD); }
.fx-table tbody tr { cursor: pointer; }
.fx-table tbody tr:hover, .fx-table tbody tr.lit { background: #131C30; }
.fx-table tbody tr.lit td:first-child { box-shadow: inset 3px 0 0 var(--beam, #00A3AD); }
.fx-table .fx-null { color: #56688A; }

/* detail-panel position list — its own scrollbar, sized so it reads as part of
   the plate rather than as the OS chrome the dark panel sits in */
.fx-dlist { scrollbar-width: thin; scrollbar-color: #46618F #131C30; overscroll-behavior: contain; }
.fx-dlist::-webkit-scrollbar { width: 9px; }
.fx-dlist::-webkit-scrollbar-track { background: #131C30; border-radius: 5px; }
.fx-dlist::-webkit-scrollbar-thumb { background: #46618F; border-radius: 5px; border: 2px solid #131C30; }
.fx-dlist::-webkit-scrollbar-thumb:hover { background: var(--beam, #00A3AD); }

/* header tooltip (drawn by the app — see TIP_DELAY_MS) */
.fx-tip { position: fixed; z-index: 400; transform: translateX(-50%); max-width: 260px; pointer-events: none;
  background: #1A2440; color: #E4E9F2; border: 1px solid #2A3A5C; border-radius: 5px; padding: 6px 9px;
  font: 11px/1.4 'Inter', system-ui, sans-serif; text-transform: none; letter-spacing: 0; white-space: normal;
  box-shadow: 0 8px 24px rgba(0,0,0,0.45); }

/* ── CSV upsell modal ── the buttons inside are the site's .action-btn */
.fx-modal-scrim { position: fixed; inset: 0; z-index: 500; background: rgba(4, 7, 14, 0.72);
  display: grid; place-items: center; padding: 20px; backdrop-filter: blur(2px); }
.fx-modal { background: #0F1626; border: 1px solid #1E2B42; border-radius: 10px; max-width: 520px; width: 100%;
  padding: 26px 28px 24px; color: #D8DFEA; font: 14px/1.6 'Inter', system-ui, sans-serif; box-shadow: 0 24px 64px rgba(0,0,0,0.6); }
.fx-modal-title { font: 700 19px/1.25 'Inter', system-ui, sans-serif; color: #F2F5FA; margin-bottom: 12px; letter-spacing: -0.2px; }
.fx-modal p { margin: 0 0 10px; }
.fx-modal .action-btn { cursor: pointer; font-size: 0.85rem; line-height: 1.2; }
