/* ===== rotacloud_analytics_html (HTML form, scoped) =====
   The RotaCloud dashboard 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 ROTACLOUD LINKS, so the shell's rules win
   every equal-specificity tie against a child asset. Each child asset that
   needs a second class to buy that point back carries one, with a note saying so.

   ROOT RULE, BARE CLASS; the dark restatement is
   [data-theme="dark"] .rc-dashboard.

   THE TOKENS ARE ON THE ROOT RULE. An unscoped :root block in a head-linked
   sheet would declare --px-chart-cyan / -violet / -coral / -amber / -emerald
   app-wide, and the gross profit section declares the same five names for
   itself; a collision would be benign by luck alone. Every consumer is a descendant of .rc-dashboard —
   including the budget modal, which is reparented into #rc-dashboard before it
   is shown, and the KPI overlays, which are already inside it — so inheritance
   reaches all of them.

   FOUR GLOBAL BLOCKS BECAME TAKEOVER RULES at the foot of this file, gated on
   html.rc-live: the box-sizing reset, the scrollbar rules, the Anvil spinner
   suppression and the print block. Head-linked and ungated they would apply to
   every screen in the app for the whole session; :where(.rc-dashboard)-scoped
   they would stop reaching the page-level nodes they reach today (the port's
   own scrollbar, Anvil's spinner). rotacloud.mjs adds the class on the shell's
   show and removes it on the FIRST line of the shell's hide, unconditionally.
   This is the pharmacyflow_pivot html.pfp-takeover pattern and carries its debt. */

.rc-dashboard {
    font-family: var(--px-font-display);
    /* Fills the viewport without owning a scroll. The layout's
       .px-nav-content is the one vertical scroll port; this box only has
       to reach the bottom of it so the background gradient does not stop
       short on a page with little content.

       The 16px is NOT arbitrary: .px-nav-content is height
       --px-nav-content-height with padding 8px 0 under border-box, so the
       space it actually offers a child is that height minus those two 8px
       bands. At 980px and up that height is 100dvh, so matching it exactly
       fills the viewport and overflows by nothing, so no second scrollbar
       comes back. Below 980px the 56px top bar comes off that height, so
       the screen overspills the port by 56px. Change that padding in the
       dependency and this constant must change with it.

       overflow: auto is NOT carried across. The root of an HTML form is a
       flex item inside the layout's scroller, and an overflow declaration
       on it stops the port scrolling; flex: 1 0 auto is what the format
       needs instead. */
    min-height: calc(100dvh - 16px);
    background:
        radial-gradient(circle at top left, rgba(8, 145, 178, 0.08), transparent 40%),
        linear-gradient(180deg, #ecfeff 0%, #f1f5f9 100%);
    padding: 1.5rem;
    position: relative;
    isolation: isolate;
    z-index: 0;
    flex: 1 0 auto;

    /* ROTACLOUD CHART HUES (Light - Default). The surface / text / border /
       shadow tokens are the unified --px-* set (3T-08, OD-01), supplied by
       PX_TOKENS_CSS. Only the tokens with no unified equivalent are declared
       here, under the --px-chart-* / --px-glow-* prefixes. */
    --px-chart-cyan: #0891b2;
    --px-chart-violet: #7c3aed;
    --px-chart-coral: #dc2626;
    --px-chart-amber: #d97706;
    --px-chart-yellow: #f59e0b;
    --px-chart-lime: #16a34a;
    --px-chart-emerald: #059669;
    --px-chart-blue: #2563eb;
    --px-chart-pink: #db2777;
    /* RF-MS-058 — the Budget panel has always READ these two and
       nothing anywhere declared them, so five of its texts fell back to
       inherited body colour. Light values recovered from the rgba() the
       same rules already paint beside them (rc_budget_html
       .rc-month-badge.current rgba(13,148,136) / .next rgba(79,70,229)). */
    --px-chart-teal: #0d9488;
    --px-chart-indigo: #4f46e5;
    --px-chart-bg-void: #f8fafc;
    --px-chart-input-bg: #f1f5f9;
    --px-chart-btn-text: #ffffff;
    --px-chart-map-filter: none;
    --px-glow-cyan: 0 4px 24px rgba(8,145,178,0.15);
    --px-glow-coral: 0 4px 24px rgba(220,38,38,0.15);
    --px-glow-blue: 0 4px 24px rgba(37,99,235,0.15);
    --px-glow-pink: 0 4px 24px rgba(219,39,119,0.15);
    --px-glow-violet: 0 4px 24px rgba(139,92,246,0.15);
}

/* ROTACLOUD CHART HUES (Dark), merged with the dark gradient the shell already
   restated on this selector. The token half is on .rc-dashboard for the same
   reason the light half is, and its extra point of specificity is what keeps
   it beating the light values on the same
   element. Screen only: printing keeps the light values for paper, and so does
   the shared px-print-ink, which rotacloud.mjs sets while it redraws the charts to print. */
@media not print {
[data-theme="dark"] .rc-dashboard:not(.px-print-ink) {
    background:
        radial-gradient(circle at top left, rgba(0, 212, 255, 0.12), transparent 40%),
        linear-gradient(180deg, #0c2a3d 0%, #0f172a 100%);
    --px-chart-cyan: #00d4ff;
    --px-chart-violet: #a78bfa;
    --px-chart-coral: #ff6b6b;
    --px-chart-amber: #fbbf24;
    --px-chart-yellow: #fde68a;
    --px-chart-lime: #a3e635;
    --px-chart-emerald: #34d399;
    --px-chart-blue: #3b82f6;
    --px-chart-pink: #f472b6;
    /* RF-MS-058 — CHOSEN, not recovered: dark mode had no design
       to recover, so these step one shade lighter exactly as cyan,
       violet and emerald do in this block. */
    --px-chart-teal: #2dd4bf;
    --px-chart-indigo: #818cf8;
    --px-chart-bg-void: #05070a;
    --px-chart-input-bg: #1a2332;
    --px-chart-btn-text: #05070a;
    --px-chart-map-filter: invert(1) hue-rotate(180deg);
    --px-glow-cyan: 0 0 60px rgba(0,212,255,0.15);
    --px-glow-coral: 0 0 60px rgba(255,107,107,0.15);
    --px-glow-blue: 0 0 60px rgba(59,130,246,0.15);
    --px-glow-pink: 0 0 60px rgba(244,114,182,0.15);
    --px-glow-violet: 0 0 60px rgba(167,139,250,0.15);
}
}


/* Subtle noise texture. Unscoped on purpose: it names the root itself. The url
   resolves against THIS FILE now rather than against the app, so
   _/theme/noise.png becomes ../noise.png. */
.rc-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 the dependency's PX theme (position: absolute;
   inset: 0), which has the same specificity (0,1,0) as this rule. Without the
   :not() the overlay computes position: relative and paints in normal flow —
   form_show leaves the initial active overlay unpinned across several Skulpt
   suspensions before _load_data reaches showLoading, so the flow-positioned
   overlay is actually painted. theme.css uses the identical exclusion for
   .px-noise > *.

   Every direct child of the root is a slot wrapper, which is the second reason
   the shell carries no anvil:name anywhere: a named element is reparented into
   an <anvil-dropzone> with display: contents, so this rule would land on the
   dropzone, which generates no box, and the section containers would silently
   lose position: relative and paint under the noise layer. */
.rc-dashboard > *:not(.px-loading-overlay) {
    position: relative;
    /* Removed z-index: 1 to prevent stacking context issues with modals */
}

@media (max-width: 768px) {
    .rc-dashboard {
        padding: 1rem;
    }
}

:where(.rc-dashboard) .rc-header-slot {
    margin-bottom: 2rem;
}

/* =============================================
   ROTACLOUD CHART HUES + SCREEN SURFACES (Light - Default)
   The surface / text / border / shadow tokens are the unified --px-*
   set (3T-08, OD-01), supplied by PX_TOKENS_CSS. Only the tokens with
   no unified equivalent are declared here, under the --px-chart-* /
   --px-glow-* prefixes.
   ============================================= */
/* =============================================
   ROTACLOUD CHART HUES + SCREEN SURFACES (Dark)
   ============================================= */
[data-theme="dark"] :where(.rc-dashboard) .rc-modal-overlay { background: rgba(0,0,0,0.7); }
[data-theme="dark"] :where(.rc-dashboard) .rc-th-tooltip .rc-tooltip-text { box-shadow: 0 8px 32px rgba(0,0,0,0.4), 0 0 0 1px rgba(255,255,255,0.05); }
[data-theme="dark"] :where(.rc-dashboard) .rc-upcoming-badge { background: color-mix(in srgb, var(--px-chart-emerald) 10%, transparent); border-color: color-mix(in srgb, var(--px-chart-emerald) 20%, transparent); }
/* Consolidated from children (Section 11.5). The month picker's icon comes
   from the shared color-scheme: dark, so it needs no filter here. */
[data-theme="dark"] :where(.rc-dashboard) .rc-month-badge.current { background: color-mix(in srgb, var(--px-chart-teal) 10%, transparent); border-color: color-mix(in srgb, var(--px-chart-teal) 20%, transparent); }
[data-theme="dark"] :where(.rc-dashboard) .rc-month-badge.next { background: color-mix(in srgb, var(--px-chart-indigo) 10%, transparent); border-color: color-mix(in srgb, var(--px-chart-indigo) 20%, transparent); color: color-mix(in srgb, var(--px-chart-indigo) 45%, var(--px-text-primary)); }
/* =============================================
   SHARED SECTION STYLES
   ============================================= */
:where(.rc-dashboard) .rc-section {
  font-family: var(--px-font-display);
}
:where(.rc-dashboard) .rc-section-card {
  background: var(--px-bg-card);
  border: 1px solid var(--px-border);
  border-radius: 16px;
  overflow: hidden;
  box-shadow: var(--px-shadow);
}
:where(.rc-dashboard) .rc-section-header {
  padding: 1.25rem 1.5rem;
  border-bottom: 1px solid var(--px-border);
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 1rem;
}
:where(.rc-dashboard) .rc-section-title {
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--px-text-primary);
}
:where(.rc-dashboard) .rc-section-subtitle {
  font-size: 0.7rem;
  color: var(--px-text-muted);
  margin-top: 0.125rem;
}
:where(.rc-dashboard) .rc-section-body {
  padding: 1.5rem;
}
/* RF-AD-045 — the two-column section split. Declared identically (and
   three times over) in rc_lateness_html, rc_sickness_html and
   rc_training_html; one declaration here, one class name on the
   markup. NOT .rc-leave-grid: that one stretches its children and
   reflows at 768px instead of 1024/640, so merging it would move where
   the leave section breaks. */
:where(.rc-dashboard) .rc-split-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
}
:where(.rc-dashboard) .rc-split-grid > div {
  min-width: 0; /* Prevent grid blowout */
}
@media (max-width: 1024px) {
  :where(.rc-dashboard) .rc-split-grid {
  grid-template-columns: 1fr;
}
}
@media (max-width: 640px) {
  :where(.rc-dashboard) .rc-split-grid {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}
  :where(.rc-dashboard) .rc-split-grid > div {
  width: 100%;
}
}
/* RF-AD-045 — the constrained, scrollable list panel (~5 items visible
   on a phone). Was .rc-offenders-container-wrapper in lateness and
   .rc-absent-container-wrapper in sickness, declaration for
   declaration. The SIBLING resets inside each child's 640px block
   (.rc-role-container-wrapper / .rc-individual-container-wrapper)
   differ and deliberately stay in their own files. */
:where(.rc-dashboard) .rc-scroll-wrapper {
  max-height: 300px;
  overflow-y: auto;
}
@media (max-width: 640px) {
  :where(.rc-dashboard) .rc-scroll-wrapper {
  max-height: 220px !important;
  overflow-y: auto !important;
  min-height: auto;
}
}
:where(.rc-dashboard) .rc-kpi-meta-value {
  font-family: 'Space Mono', monospace;
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--px-text-primary);
}
:where(.rc-dashboard) .rc-kpi-meta-label {
  font-size: 0.65rem;
  color: var(--px-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
:where(.rc-dashboard) .rc-chart-title {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--px-text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-bottom: 1rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
:where(.rc-dashboard) .rc-chart-title::before {
  content: '';
  width: 3px;
  height: 14px;
  background: var(--px-chart-cyan);
  border-radius: 2px;
}
:where(.rc-dashboard) .rc-component-container {
  min-height: 280px;
}
:where(.rc-dashboard) .rc-trends-section {
  margin-bottom: 2rem;
}
/* =============================================
   SHARED EMPTY STATE
   Consolidated from children (CSS consolidation pass 2)
   ============================================= */
:where(.rc-dashboard) .rc-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  min-height: 200px;
  color: var(--px-text-muted);
  font-family: var(--px-font-display);
  font-size: 0.85rem;
  text-align: center;
  padding: 1rem;
  gap: 0.5rem;
}
:where(.rc-dashboard) .rc-empty-state svg {
  width: 32px;
  height: 32px;
  opacity: 0.4;
}
/* =============================================
   SHARED KPI CARD STYLES
   Consolidated from kpi_bagging, kpi_dispatch, kpi_variance
   ============================================= */
:where(.rc-dashboard) .rc-kpi-card {
  background: var(--px-bg-card);
  border: 1px solid var(--px-border);
  border-radius: 16px;
  padding: 1.5rem;
  position: relative;
  overflow: hidden;
  transition: opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1), transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), background-color 0.3s cubic-bezier(0.4, 0, 0.2, 1), color 0.3s cubic-bezier(0.4, 0, 0.2, 1), border-color 0.3s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  box-shadow: var(--px-shadow);
  cursor: pointer;
}
:where(.rc-dashboard) .rc-kpi-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 1rem;
  gap: 0.5rem;
}
:where(.rc-dashboard) .rc-kpi-label {
  font-family: 'Space Mono', monospace;
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--px-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.1em;
}
:where(.rc-dashboard) .rc-kpi-unit {
  font-size: 0.75rem;
  color: var(--px-text-muted);
  font-weight: 400;
}
:where(.rc-dashboard) .rc-kpi-sparkline {
  height: 70px;
  margin: 1rem 0 0.75rem 0;
  overflow: visible;
}
:where(.rc-dashboard) .rc-kpi-meta {
  display: flex;
  justify-content: space-around;
  padding-top: 1rem;
  border-top: 1px solid var(--px-border);
  gap: 1rem;
}
:where(.rc-dashboard) .rc-kpi-meta-item {
  text-align: center;
  min-width: 0;
}
/* =============================================
   SHARED MODAL STYLES
   Consolidated from kpi_bagging, kpi_dispatch, kpi_variance
   ============================================= */
:where(.rc-dashboard) .rc-modal-overlay {
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;
  background: rgba(0,0,0,0.5);
  backdrop-filter: blur(12px);
  display: none;
  justify-content: center;
  align-items: center;
  z-index: 99999;
  padding: 1rem;
}
:where(.rc-dashboard) .rc-modal-overlay.active {
  display: flex;
}
:where(.rc-dashboard) .rc-modal {
  background: var(--px-bg-card);
  border: 1px solid var(--px-border);
  border-radius: 20px;
  box-shadow: 0 25px 80px rgba(0,0,0,0.25);
  width: 100%;
  max-width: 900px;
  max-height: 85vh;
  overflow: hidden;
  animation: rc-modalSlideIn 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
@keyframes rc-modalSlideIn {
  from { opacity: 0; transform: translateY(30px) scale(0.95); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
:where(.rc-dashboard) .rc-modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1.25rem 1.75rem;
  border-bottom: 1px solid var(--px-border);
  background: var(--px-bg-elevated);
}
:where(.rc-dashboard) .rc-modal-title {
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--px-text-primary);
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 0;
}
:where(.rc-dashboard) .rc-modal-close {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  border: 1px solid var(--px-border);
  background: var(--px-bg-card);
  color: var(--px-text-secondary);
  font-size: 1.5rem;
  cursor: pointer;
  transition: opacity 0.2s, transform 0.2s, background-color 0.2s, color 0.2s, border-color 0.2s, box-shadow 0.2s;
  display: flex;
  align-items: center;
  justify-content: center;
}
:where(.rc-dashboard) .rc-modal-close:hover {
  background: var(--px-danger);
  border-color: var(--px-danger);
  color: var(--px-text-on-fill);
  transform: rotate(90deg);
}
:where(.rc-dashboard) .rc-modal-body {
  padding: 1.75rem;
  overflow-y: auto;
  max-height: calc(85vh - 80px);
  color: var(--px-text-primary);
}
/* =============================================
   SHARED DRILL TABLE STYLES
   Consolidated from kpi_bagging, kpi_dispatch, kpi_variance
   ============================================= */
:where(.rc-dashboard) .rc-drill-chart {
  height: 180px;
  margin-bottom: 1.5rem;
  background: var(--px-bg-elevated);
  border-radius: 12px;
  padding: 0.5rem;
}
:where(.rc-dashboard) .rc-drill-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
}
:where(.rc-dashboard) .rc-drill-table th {
  text-align: left;
  padding: 0.875rem 1rem;
  background: var(--px-bg-elevated);
  color: var(--px-text-secondary);
  font-weight: 600;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  border-bottom: 1px solid var(--px-border);
  position: sticky;
  top: 0;
}
:where(.rc-dashboard) .rc-drill-table td {
  padding: 0.875rem 1rem;
  border-bottom: 1px solid var(--px-border);
}
:where(.rc-dashboard) .rc-drill-table tbody tr {
  transition: opacity 0.2s, transform 0.2s, background-color 0.2s, color 0.2s, border-color 0.2s, box-shadow 0.2s;
}
:where(.rc-dashboard) .rc-drill-table tbody tr.highlighted td {
  color: var(--px-text-on-fill);
}
/* =============================================
   SHARED TOOLTIP STYLES
   Consolidated from kpi_bagging, kpi_dispatch, kpi_variance
   Color accents overridden per-component via ID selectors
   ============================================= */
:where(.rc-dashboard) .rc-th-tooltip {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  cursor: help;
}
:where(.rc-dashboard) .rc-th-tooltip .rc-tooltip-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  color: var(--px-text-on-fill);
  font-size: 9px;
  font-weight: 700;
  font-style: normal;
  font-family: 'Georgia', serif;
  transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}
:where(.rc-dashboard) .rc-th-tooltip:hover .rc-tooltip-icon {
  transform: scale(1.1);
}
:where(.rc-dashboard) .rc-th-tooltip .rc-tooltip-text {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 8px);
  transform: translateX(-50%) translateY(4px);
  min-width: 220px;
  padding: 0.75rem 1rem;
  background: var(--px-bg-card);
  border: 1px solid var(--px-border);
  border-radius: 10px;
  box-shadow: 0 8px 32px rgba(0,0,0,0.12), 0 2px 8px rgba(0,0,0,0.08);
  font-size: 0.72rem;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0.01em;
  line-height: 1.5;
  color: var(--px-text-primary);
  white-space: normal;
  text-align: left;
  z-index: 1000;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.25s cubic-bezier(0.4, 0, 0.2, 1), transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
  pointer-events: none;
}
:where(.rc-dashboard) .rc-th-tooltip .rc-tooltip-text::before {
  content: '';
  position: absolute;
  left: 50%;
  bottom: -6px;
  transform: translateX(-50%) rotate(45deg);
  width: 10px;
  height: 10px;
  background: var(--px-bg-card);
  border-right: 1px solid var(--px-border);
  border-bottom: 1px solid var(--px-border);
}
:where(.rc-dashboard) .rc-th-tooltip .rc-tooltip-text .rc-tooltip-title {
  display: block;
  font-weight: 700;
  margin-bottom: 0.35rem;
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
:where(.rc-dashboard) .rc-th-tooltip .rc-tooltip-text .rc-tooltip-calc {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  margin-top: 0.5rem;
  padding-top: 0.5rem;
  border-top: 1px dashed var(--px-border);
  font-family: 'Space Mono', monospace;
  font-size: 0.65rem;
  color: var(--px-text-secondary);
}
:where(.rc-dashboard) .rc-th-tooltip .rc-tooltip-text .rc-tooltip-calc span {
  display: flex;
  justify-content: space-between;
}
:where(.rc-dashboard) .rc-th-tooltip:hover .rc-tooltip-text {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
}
/* =============================================
   SHARED BACK BUTTON, SUMMARY ROW, HINT
   Consolidated from kpi_dispatch, kpi_variance
   ============================================= */
:where(.rc-dashboard) .rc-back-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.625rem 1rem;
  background: var(--px-bg-elevated);
  border: 1px solid var(--px-border);
  border-radius: 10px;
  color: var(--px-text-secondary);
  font-family: var(--px-font-display);
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
  transition: opacity 0.2s, transform 0.2s, background-color 0.2s, color 0.2s, border-color 0.2s, box-shadow 0.2s;
  margin-bottom: 1.25rem;
}
:where(.rc-dashboard) .rc-summary-row {
  display: flex;
  gap: 2rem;
  margin: 1rem 0;
  padding: 1rem;
  background: var(--px-bg-elevated);
  border-radius: 12px;
  flex-wrap: wrap;
}
:where(.rc-dashboard) .rc-hint {
  margin-top: 1rem;
  font-size: 0.8rem;
  color: var(--px-text-secondary);
}
:where(.rc-dashboard) .rc-kpi-badge {
  font-family: 'Space Mono', monospace;
  font-size: 0.6rem;
  padding: 3px 8px;
  border-radius: 12px;
  background: var(--px-warning-bg);
  color: var(--px-warning-text);
  border: 1px solid var(--px-warning-border);
  white-space: nowrap;
}
:where(.rc-dashboard) .rc-success-state {
  text-align: center;
  padding: 2.5rem 1.5rem;
}
:where(.rc-dashboard) .rc-success-icon {
  font-size: 2.5rem;
  margin-bottom: 0.75rem;
}
/* =============================================
   PER-CARD ACCENT RULES (RF-AD-046)
   One copy of the nine rules kpi_bagging, kpi_dispatch and
   kpi_variance share. Each child names its own colour by setting
   --px-chart-accent (and --px-chart-accent-glow on the card) on its
   #kpi-*-card and #*-modal-overlay roots, so the three cards keep
   their own hues instead of the last-loaded child painting all of
   them. Every selector is scoped under .rc-kpi-card or
   .rc-modal-overlay, both of which live only on this screen.
   ============================================= */
:where(.rc-dashboard) .rc-kpi-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: linear-gradient(90deg, var(--px-chart-accent), transparent);
}
:where(.rc-dashboard) .rc-kpi-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--px-shadow), var(--px-chart-accent-glow);
}
:where(.rc-dashboard) .rc-kpi-card .rc-kpi-value {
  font-family: 'Space Mono', monospace;
  font-size: clamp(2rem, 6vw, 2.75rem);
  font-weight: 700;
  line-height: 1;
  margin-bottom: 0.25rem;
  color: var(--px-chart-accent);
}
:where(.rc-dashboard) .rc-modal-overlay .rc-modal::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: linear-gradient(90deg, var(--px-chart-accent), transparent);
}
:where(.rc-dashboard) .rc-modal-overlay .rc-drill-table tbody tr.highlighted {
  background: var(--px-chart-accent);
  color: var(--px-text-on-fill);
}
:where(.rc-dashboard) .rc-modal-overlay .rc-drill-table .rc-drill-value {
  font-family: 'Space Mono', monospace;
  font-weight: 600;
  color: var(--px-chart-accent);
}
/* Keeps a highlighted row's value cells readable. The accent rule
   just above carries three classes, so it outranks the plain
   .rc-drill-table tbody tr.highlighted td colour rule in the drill-table
   section and would otherwise paint accent text on an accent background.
   This is the scoped stand-in for the per-child
   tbody tr.highlighted .rc-drill-value copies. */
:where(.rc-dashboard) .rc-modal-overlay .rc-drill-table tbody tr.highlighted td {
  color: var(--px-text-on-fill);
}
/* The variance tables' id-led signed colours outrank the rule above, so
   they are restated for a highlighted row on the accent fill. */
:where(.rc-dashboard) :is(#variance-drill-table, #variance-daily-table) tbody tr.highlighted:not(:hover) .rc-drill-value:is(.positive, .negative) {
  color: var(--px-text-on-fill);
}
:where(.rc-dashboard) #variance-daily-table .rc-unpublished-count {
  color: var(--px-warning-ink);
}
:where(.rc-dashboard) #variance-daily-table tbody tr.highlighted:not(:hover) .rc-unpublished-count {
  color: var(--px-text-on-fill);
}
/* Under the pointer these tables' id-led :hover fill replaces the accent
   with the elevated surface, so the row's text goes back to page text. */
:where(.rc-dashboard) :is(#dispatch-drill-table, #variance-drill-table, #variance-daily-table) tbody tr.highlighted:hover td:not(.positive, .negative) {
  color: var(--px-text-primary);
}
:where(.rc-dashboard) .rc-modal-overlay .rc-back-btn:hover {
  background: var(--px-chart-accent);
  border-color: var(--px-chart-accent);
  color: var(--px-chart-btn-text);
}
:where(.rc-dashboard) .rc-modal-overlay .rc-th-tooltip .rc-tooltip-icon { background: var(--px-chart-accent); }
:where(.rc-dashboard) .rc-modal-overlay .rc-th-tooltip .rc-tooltip-text .rc-tooltip-title { color: var(--px-chart-accent); }
/* =============================================
   DASHBOARD LAYOUT
   ============================================= */
/* Subtle noise texture */
/* 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), which has the same specificity (0,1,0) as this
   rule but loses on document order (theme.css is head-linked, this
   form's inline style block is body-level). Without the :not() the
   overlay computes position: relative and paints in normal flow —
   form_show leaves the initial `active` overlay unpinned across
   several Skulpt suspensions before _load_data reaches rcShowLoading,
   so the flow-positioned overlay is actually painted. theme.css:625
   uses the identical exclusion for .px-noise > *. */
/* =============================================
   KPI GRID
   ============================================= */
:where(.rc-dashboard) .rc-kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1.5rem;
  margin-bottom: 2rem;
}
/* =============================================
   SECTION ANIMATIONS
   ============================================= */
:where(.rc-dashboard) .rc-section-container {
  margin-bottom: 2rem;
  transition: opacity 0.6s cubic-bezier(0.4, 0, 0.2, 1), transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}
/* Designer gate. The two hiding declarations are split out and gated on the
   takeover class, because .visible is added only by animateSectionsVisible,
   which _load_data calls — Python the designer never runs. Ungated, all seven
   slot wrappers compute opacity 0 and sit 20px low on the canvas, so staff
   cannot see or drag the sections. The gate is the live class on <html>, not
   on the root, because that is where rotacloud.mjs puts it; addTakeover() runs
   on the first line of the shell's form_show, before _load_data, so runtime is
   unchanged. Both compound selectors stay inside :where() to keep this rule at
   (0,1,0): html.rc-live unwrapped would compute (0,2,1) and beat the
   .rc-section-container.visible reveal at (0,2,0), which never reveals. */
:where(html.rc-live) :where(.rc-dashboard) .rc-section-container {
  opacity: 0;
  transform: translateY(20px);
}
:where(.rc-dashboard) .rc-section-container.visible {
  opacity: 1;
  transform: translateY(0);
}
/* =============================================
   MOBILE RESPONSIVE
   ============================================= */
@media (max-width: 768px) {
    :where(.rc-dashboard) .rc-kpi-grid {
  grid-template-columns: 1fr;
}
}
/* =============================================
   SCROLLBAR
   ============================================= */
/* =============================================
   ANVIL SPINNER SUPPRESSION
   ============================================= */
/* Hide Anvil's own spinner - this screen shows the shared loading overlay instead */

/* =============================================
   TAKEOVER, html.rc-live
   The four blocks below reach page-level nodes OUTSIDE .rc-dashboard, so
   :where(.rc-dashboard) would stop them reaching what they reach today, and no
   gate at all would apply them to every screen in the app for the whole
   session. rotacloud.mjs adds html.rc-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 without its
   spinner until a page reload.
   ============================================= */
html.rc-live * {
    box-sizing: border-box;
}

/* These style .px-nav-content's own scrollbar while RotaCloud is mounted. */
html.rc-live ::-webkit-scrollbar {
    width: 6px;
    height: 6px;
}

html.rc-live ::-webkit-scrollbar-track {
    background: transparent;
}

html.rc-live ::-webkit-scrollbar-thumb {
    background: var(--px-border);
    border-radius: 3px;
}

html.rc-live ::-webkit-scrollbar-thumb:hover {
    background: var(--px-text-muted);
}

/* Hide Anvil's own spinner - this screen shows the shared loading overlay instead */
html.rc-live .anvil-spinner,
html.rc-live .anvil-loading-spinner,
html.rc-live .anvil-app-loading-spinner {
    display: none !important;
}

@media print {
    html.rc-live {
        --px-bg-deep: #ffffff !important;
        --px-bg-card: #ffffff !important;
        --px-bg-elevated: #f8fafc !important;
        --px-text-primary: #0f172a !important;
        --px-text-secondary: #334155 !important;
        --px-text-muted: #64748b !important;
        --px-border: rgba(0,0,0,0.12) !important;
        --px-shadow: none !important;
    }
    html.rc-live .rc-dashboard {
        background: #ffffff !important;
    }
    html.rc-live .rc-dashboard::before {
        display: none !important;
    }
    html.rc-live .apexcharts-canvas {
        background: #ffffff !important;
    }
    /* A chart keeps the width it was drawn at on screen. beforeprint gives
       each SVG a viewBox, so here it shrinks to the page instead of being cut
       off at the card's edge, and it never splits across two pages. */
    html.rc-live .rc-dashboard .apexcharts-canvas {
        width: auto !important;
        height: auto !important;
        break-inside: avoid;
    }
    html.rc-live .rc-dashboard .apexcharts-svg {
        max-width: 100%;
        height: auto;
    }
    /* Chart text and gridlines were drawn in dark-mode colours; paper needs
       the print text and border colours. */
    html.rc-live[data-theme="dark"] .rc-dashboard :is(.apexcharts-xaxis-label, .apexcharts-yaxis-label, .apexcharts-xaxis-title-text, .apexcharts-yaxis-title-text) {
        fill: var(--px-text-secondary) !important;
    }
    html.rc-live[data-theme="dark"] .rc-dashboard .apexcharts-legend-text {
        color: var(--px-text-secondary) !important;
    }
    html.rc-live[data-theme="dark"] .rc-dashboard .apexcharts-gridline {
        stroke: var(--px-border) !important;
    }
    /* A list panel prints every item, beating the 640px screen cap. */
    html.rc-live .rc-dashboard .rc-scroll-wrapper {
        max-height: none !important;
        overflow: visible !important;
    }
}
