/* ===== nucare_analytics_html (HTML form, scoped) =====
   The NuCare Analytics shell's styling. Loaded eagerly from
   anvil.yaml native_deps.head_html, which is what styles the designer canvas
   as well as the running app.

   THIS FILE SORTS LAST AMONG THE NUCARE LINKS ("." is 0x2E and "_" is 0x5F, so
   nucare.css sorts after every na_*.css).

   NO TIE EXISTS BETWEEN THEM, and that was checked name by name rather than
   assumed. This file declares .na-dashboard, .na-content, .na-two-col,
   #na-kpi-grid, #na-kpi-profit, #na-kpi-missed-profit and the html.na-live
   scrollbar block. The five child assets declare .na-chart-*, .na-rejected-*,
   .na-exception-*, .na-profit-* and #na-filters-bar plus .na-filters-title,
   .na-filter-group, .na-filter-sep, .na-rates-label and .na-rates-row. No name
   is declared on both sides. A future rule that must beat a rule in another
   NuCare asset takes a second class, never a moved link line.

   ROOT RULE, BARE CLASS, so it outranks the :where()-scoped rules below and so
   the dark restatement stays readable as [data-theme="dark"] .na-dashboard {.

   THE LAYOUT BLOCK DROPS overflow: auto AND GAINS flex: 1 0 auto. The root is
   a flex item inside the shared layout's scroller, .px-nav-content, which owns
   the vertical scroll; overflow on the root would stop the port scrolling.
   overflow: auto was inert vertically here (a minimum and no maximum, so the
   box never scrolled) but it did clip horizontal overflow: if a child overflows
   horizontally, the fix is overflow-x: clip on that child, never on this root.
   The Python half of the same lock goes with it - __init__.py keeps only the
   document-body write.

   min-height: 100vh IS KEPT BYTE FOR BYTE. The port is the layout's
   --px-nav-content-height, so the screen overflows it by the layout's own
   padding, exactly as it does today, and below 980px by the top bar as well.
   Changing that is a visible change and is the owner's call, so it is
   recorded as a deviation rather than taken here.

   ONE DESIGNER GATE. .px-section-reveal { opacity: 0 } needs none: the
   dependency injects it into the head at runtime, so the designer canvas never
   loads it. The KPI hide below does, because the four anvil:name blocks in the
   template are the grid's children and a display:none parent leaves them with
   no box to select or drag on the canvas, so both rules carry html.na-live.

   No @keyframes and no @font-face in this file, so nothing to prefix and
   nothing to drop. */

/* =============================================
   NUCARE ANALYTICS — SCREEN-SCOPED TOKEN OVERRIDES
   3T-08: no private token namespace. Everything below is the unified
   --px-* set, overridden ONLY where this screen's violet brand surface
   genuinely differs from the estate default. Text and shadow tokens are
   inherited from PX_TOKENS_CSS (OD-01).
   ============================================= */
.na-dashboard {
  --accent: #7c3aed;
  --accent-hover: #6d28d9;
  --accent-subtle: rgba(124, 58, 237, 0.10);
  --accent-text: #ffffff;
  --accent-rgb: 124, 58, 237;
  --px-loading-accent: #7c3aed;
  --px-bg-deep: #faf5ff;
  --px-bg-elevated: #f5f3ff;
  --px-border: rgba(124, 58, 237, 0.22);
  --px-border-strong: rgba(124, 58, 237, 0.4);
  --px-chart-hero-from: #7c3aed;
  --px-chart-hero-to: #581c87;
}

/* Dark palette is screen-only: printing from dark keeps the light violet
   palette above plus the shared light print tokens. */
@media screen {
[data-theme="dark"] .na-dashboard {
  --accent: #a78bfa;
  --accent-hover: #c4b5fd;
  --accent-subtle: rgba(167, 139, 250, 0.12);
  --accent-text: #0f172a;
  --accent-rgb: 167, 139, 250;
  --px-loading-accent: #a78bfa;
  --px-bg-deep: #0f0720;
  --px-bg-card: #1a1033;
  --px-bg-elevated: #2d1f4e;
  --px-border: rgba(167, 139, 250, 0.12);
  --px-border-strong: rgba(167, 139, 250, 0.25);
  --px-chart-hero-from: #581c87;
  --px-chart-hero-to: #3b0764;
  background:
    radial-gradient(circle at top left, rgba(167, 139, 250, 0.18), transparent 40%),
    linear-gradient(180deg, #1a0533 0%, #0f172a 100%);
}
}

.na-dashboard,
.na-dashboard * { box-sizing: border-box; }

/* =============================================
   MAIN LAYOUT
   ============================================= */
.na-dashboard {
  font-family: var(--px-font-display);
  min-height: 100vh;
  flex: 1 0 auto;
  background:
    radial-gradient(circle at top left, rgba(124, 58, 237, 0.08), transparent 40%),
    linear-gradient(180deg, #faf5ff 0%, #f1f5f9 100%);
  position: relative;
  isolation: isolate;
  z-index: 0;
}

.na-dashboard::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0; bottom: 0;
  background-image: url('../noise.png');
  background-repeat: repeat;
  opacity: 0.015;
  pointer-events: none;
  z-index: 0;
}

/* RF-AD-044: the loading overlay MUST be excluded from this
   noise-layer lift. The overlay's position comes from the shared
   .px-loading-overlay rule in theme/assets/theme.css (position: absolute;
   inset: 0). This rule wins on SPECIFICITY, (0,2,0) against (0,1,0), and that
   is the whole reason the exclusion is written as a :not() rather than left to
   document order: both sheets are head-linked now that the shell is an HTML
   form, and their relative order is not something this app controls. Without
   the :not() the overlay would compute position: relative and paint in normal
   flow instead of covering the dashboard. theme.css:625 uses the identical
   exclusion for .px-noise > *. */
.na-dashboard > *:not(.px-loading-overlay) {
  position: relative;
}

/* =============================================
   CONTENT AREA
   ============================================= */
:where(.na-dashboard) .na-content {
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

/* =============================================
   KPI GRID
   RF-AD-042: no private .na-kpi-* copies. The tiles use the shared
   .px-kpi-grid / .px-kpi-card / .px-kpi-label / .px-kpi-value rules
   in theme/assets/theme.css, so the dashboard tile look is maintained
   in one place.
   At and below a 1024px VIEWPORT theme.css's own responsive block
   pins .px-kpi-grid to two columns at 1024px and 768px and to one at
   480px.
   ABOVE 1024px the count is not fixed. The shared base rule is
   repeat(auto-fit, minmax(200px, 1fr)) with gap: 1rem, which needs a
   CONTAINER of 4*200 + 3*16 = 848px before a fourth track fits.
   The container is narrower than the viewport here: the M3 drawer is
   permanently fixed at >= 980px and insets this content by its width,
   and .na-content adds 1.5rem of padding on each side (48px). So for
   viewports just over 1024px the container falls short of 848px and
   these four tiles render THREE across — e.g. with a 300px drawer the
   three-across band runs from roughly 1025px to 1196px of viewport,
   which includes a 1152px-wide window. Wider than that, four across.
   Only the one layout-parity override below stays local:
   .px-kpi-grid carries margin-bottom: 1.5rem for screens that stack
   their own sections, whereas this grid sits inside .na-content's
   flex column with its own 1.5rem gap. It stays a BARE selector at
   (0,2,0) so it beats the shared (0,1,0) rule on specificity rather
   than on the order two head links happen to load in.
   ============================================= */
.na-dashboard .px-kpi-grid {
  margin-bottom: 0;
}

#na-kpi-profit { color: #059669; }
#na-kpi-missed-profit { color: #e11d48; }
@media screen {
  [data-theme="dark"] #na-kpi-profit { color: #34d399; }
  [data-theme="dark"] #na-kpi-missed-profit { color: #fb7185; }
}

/* The grid is hidden until the first KPI render. A template may carry no
   inline styling, so the hide is the rule below and the reveal is the
   .na-kpis-shown class nucare.mjs's showKpis adds. display: grid is spelled
   out because the hide rule outranks the shared .px-kpi-grid { display: grid }
   rule in theme/assets/theme.css. The column counts stay entirely with
   theme.css — nothing here restates one.

   BOTH RULES ARE GATED ON html.na-live, which nucare.mjs's addTakeover() adds
   on the first line of the shell's form_show. The reveal still wins, (1,2,1)
   over (1,1,1). On the designer canvas neither matches, theme.css's
   .px-kpi-grid { display: grid } takes over and the four anvil:name KPI cards
   have a box to select and drag — which is the whole point of the migration.
   At runtime the pre-show window shows no flash, because the grid also carries
   px-section-reveal and so sits at opacity: 0 until pxAnimateSections. */
html.na-live #na-kpi-grid { display: none; }
html.na-live #na-kpi-grid.na-kpis-shown { display: grid; }

/* =============================================
   TWO-COLUMN GRID
   ============================================= */
:where(.na-dashboard) .na-two-col {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
}

/* =============================================
   RESPONSIVE
   RF-AD-042: no local fixed-column overrides, because theme.css
   declares the counts for .px-kpi-grid at these breakpoints (2 at
   1024px, 2 at 768px, 1 at 480px). Above 1024px there is no such
   pin; see the KPI GRID note above. No 768px corner override either:
   theme.css's own 768px block sets 12px, which is also what
   --px-radius resolves to.
   ============================================= */
@media (max-width: 1024px) {
  :where(.na-dashboard) .na-two-col {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 768px) {
  :where(.na-dashboard) .na-content {
    padding: 1rem;
  }
  .na-dashboard .px-kpi-grid {
    gap: 0.75rem;
  }
  .na-dashboard .px-kpi-card {
    padding: 1rem;
  }
  .na-dashboard .px-kpi-value {
    font-size: 1.5rem;
  }
}

@media (max-width: 480px) {
  .na-dashboard .px-kpi-value {
    font-size: 1.25rem;
  }
}

/* =============================================
   SCROLLBAR — TAKEOVER, html.na-live
   The four rules below carry no ancestor selector today, so while NuCare is
   mounted they style EVERY scrollbar on the page, including the shared
   layout's port .px-nav-content, which is the one the user actually drags;
   they stop the moment the template's <style> block leaves the DOM. A head
   link cannot do that. Ungated they would restyle every scrollbar in the app
   for the whole session, and :where(.na-dashboard)-scoped they would silently
   stop reaching the port. nucare.mjs adds html.na-live on the shell's show and
   removes it on the FIRST line of the shell's hide, never in cleanup() —
   cleanup() is isinstance-gated and main/__init__.py's _dispose_screen
   swallows its exception, so a throw there would leave every later screen
   wearing these scrollbars until a page reload.

   EACH SELECTOR CARRIES A ZERO-WEIGHT EXCLUSION, and that is what keeps this
   move pixel-neutral. Two NuCare boxes wear the dependency's themed-scrollbar
   class (.na-rejected-body and .na-exception-body), and the dependency
   declares .themed-scrollbar::-webkit-scrollbar-thumb at (0,1,1). Today's bare
   ::-webkit-scrollbar-thumb is (0,0,1), so the dependency wins there and both
   boxes draw #64748b. A bare html.na-live ::-webkit-scrollbar-thumb would be
   (0,1,2) and would BEAT it, flipping both inner scrollbars. :where() adds
   nothing, so each rule below stays (0,1,2) and simply does not match the two
   themed boxes, leaving the dependency's rule to reach them unopposed exactly
   as it does today.

   .px-nav-menu-wrapper is excluded for the same reason and it is the nav
   drawer's own list. It wears no .themed-scrollbar class, and the shared
   layout styles it itself at (0,1,1) (px_ui/nav_shell_html, 8px wide, track
   var(--px-bg-elevated), radius 4px). A bare (0,0,1) rule loses to that;
   an (0,1,2) rule would beat it and narrow the drawer's scrollbar for as long
   as NuCare is mounted.
   ============================================= */
html.na-live :where(:not(.themed-scrollbar):not(.px-nav-menu-wrapper))::-webkit-scrollbar { width: 6px; height: 6px; }
html.na-live :where(:not(.themed-scrollbar):not(.px-nav-menu-wrapper))::-webkit-scrollbar-track { background: transparent; }
html.na-live :where(:not(.themed-scrollbar):not(.px-nav-menu-wrapper))::-webkit-scrollbar-thumb { background: var(--px-border-strong); border-radius: 3px; }
html.na-live :where(:not(.themed-scrollbar):not(.px-nav-menu-wrapper))::-webkit-scrollbar-thumb:hover { background: var(--px-text-muted); }
