/* ============================================================
   style.css
   ------------------------------------------------------------
   Global theme tokens (CSS variables) + layout for everything
   that ISN'T the sidebar (sidebar.css) or KPI cards (cards.css):
   the app shell, the page header/filters, the chart/table
   panels, the AG Grid theme overrides, and placeholder pages.

   ------------------------------------------------------------
   VERSION 2 CHANGES
   ------------------------------------------------------------
   1. Page header made sticky (`position: sticky; top: 0`) so it
      stays visible while only the content below it scrolls
      (brief item 3).
   2. Spacing/margins/gaps throughout now read from the CSS
      variables generated by layout_config.py (--page-margin,
      --card-spacing, --component-spacing, --header-height) so the
      whole page can be made more/less compact from one Python
      file (brief items 1 & 4). The shipped defaults (see
      layout_config.LAYOUT_SCALE) are tuned to fit a Full HD
      (1920x1080) screen at ~60% browser zoom without vertical
      scrolling.
   3. Added `.table-panel-fullscreen` - the Full-Screen table mode
      toggled by callbacks/filters.py::toggle_table_fullscreen()
      (brief item 5).
   4. Added `.grid-fullscreen-btn` and `.revenue-vs-dropdown`
      styling for the two new controls introduced in
      pages/profit_loss.py (brief items 5 & 12).
   ============================================================ */

@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');

:root {
  --bg: #F4F6FA;
  --card-bg: #FFFFFF;
  --sidebar-bg: #152447;
  --sidebar-bg-light: #1E3364;
  --gold: #CD9D1F;
  --gold-soft: #FBE3B8;
  --gold-dark: #C9860F;
  --navy-text: #152447;
  --text-muted: #7A8699;
  --positive: #22A85E;
  --negative: #E64545;
  --border: #E4E8F0;
  --shadow: 0 4px 16px rgba(21,36,71,0.08);
  --radius: 14px;
  --font: 'Inter', 'Segoe UI', 'Roboto', sans-serif;
  --font-serif: 'Inter', 'Segoe UI', 'Roboto', sans-serif;

  --card: var(--card-bg);
  --paper: var(--bg);
  --line: var(--border);
  --side-panel: var(--sidebar-bg);
  --side-line: #0F1E3D;
  --side-hover: rgba(255,255,255,0.10);

  /* ---- ink-* aliases - used extensively throughout the CSS for text
     color at various weights. Mapped to navy-theme equivalents so
     every existing rule using them keeps working without being
     individually hunted down. ---- */
  --ink-900: var(--navy-text);
  --ink-700: #2C3E63;
  --ink-500: var(--text-muted);
  --ink-300: #A7B0C4;
  --green-700: var(--positive);
  --red-700: var(--negative);
}

* { box-sizing: border-box; }

html, body, #react-entry-point {
  background: var(--bg);
  font-family: var(--font);
  color: var(--navy-text);
  margin: 0;
  height: 100%;
}

.app-shell {
  display: flex;
  min-height: 100vh;
}

.page-content {
  flex: 1;
  min-width: 0; /* allow inner flex/grid children to shrink properly */
  background: var(--bg);
  zoom: 85%; /* shrinks only the content area (charts/KPIs/tables) -
                the sidebar is a sibling of this element in the HTML,
                not a child of it, so it's untouched by this rule. */
  position: relative;
  z-index: 1; /* explicit and low - removes any ambiguity in how this
                 stacks against the fixed-position hamburger button
                 (z-index 2147483647), since its sticky .page-header
                 child has its own z-index: 50 */
}

/* ============================================================
   Page header (title + subtitle + filters) - VERSION 2: sticky
   ============================================================ */
.pnl-page { padding-bottom: var(--page-margin, 16px); }

.page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--component-spacing, 12px);
  background: transparent;
  padding: 10px var(--page-margin, 20px);
  min-height: var(--header-height, 60px);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 50; /* stays above chart/table panels while scrolling */
}

.page-title {
  color: var(--ink-900);
  font-family: var(--font-serif);
  font-weight: 600;
  font-size: 1.75rem;
  margin: 0;
  letter-spacing: 0.1px;
}
.page-subtitle {
  color: var(--ink-500);
  font-size: 0.78rem;
  margin-top: 1px;
}

.header-filters {
  display: flex;
  align-items: flex-end;
  gap: var(--component-spacing, 12px);
  flex-wrap: wrap;
}

.filter-group { display: flex; flex-direction: column; min-width: 150px; }
.filter-label {
  color: var(--ink-900);
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.4px;
  margin-bottom: 2px;
}
.filter-dropdown .Select-control,
.filter-dropdown > div {
  border-radius: 8px !important;
  border: 1px solid var(--border) !important;
  font-size: 0.78rem !important;
  min-height: 32px !important;
}

.last-refresh-value {
  color: var(--navy-text);
  font-size: 0.75rem;
  font-weight: 600;
  padding: 5px 0;
}

.refresh-btn {
  background: var(--navy-text);
  color: #FFFFFF;
  border: none;
  border-radius: 8px;
  width: 32px;
  height: 32px;
  font-size: 1rem;
  cursor: pointer;
  transition: transform .25s ease, background .2s ease;
}
.refresh-btn:hover {
  background: var(--gold);
  color: var(--navy-text);
  transform: rotate(90deg);
}

/* ============================================================
   Main grid layout (upper 3-chart row + lower table/chart row)
   VERSION 2: uses flex height-sharing so both rows fit within the
   remaining viewport height beneath the sticky header, eliminating
   page-level vertical scrolling on a 1920x1080 screen at ~60% zoom
   (brief item 1). The AG Grid keeps its own internal scrollbar if
   it has more rows than fit - that's expected and matches how any
   real financial statement table behaves.
   ============================================================ */
.main-grid {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr 1.15fr;
  gap: var(--card-spacing, 16px);
  margin: var(--card-spacing, 14px) var(--page-margin, 20px);
}
.main-grid-lower {
  display: grid;
  grid-template-columns: 1.5fr 1fr;
  gap: var(--card-spacing, 16px);
  margin: 0 var(--page-margin, 20px) var(--page-margin, 14px);
}

@media (max-width: 1200px) {
  .main-grid { grid-template-columns: 1fr 1fr; }
  .main-grid-lower { grid-template-columns: 1fr; }
}
@media (max-width: 700px) {
  .main-grid { grid-template-columns: 1fr; }
}

.panel {
  background: var(--card-bg);
  border-radius: var(--radius);
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
  padding: var(--component-spacing, 12px) 14px;
}

.panel-title {
  color: var(--navy-text);
  font-weight: 700;
  font-size: 0.72rem;
  letter-spacing: 0.3px;
}
.panel-title-center { text-align: center; font-weight: 700; color: var(--navy-text); font-size: 0.85rem; }
.panel-value-center {
  text-align: center;
  font-size: 1.15rem;
  font-weight: 800;
  color: var(--navy-text);
  margin: 1px 0 4px;
}
.panel-header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  flex-wrap: nowrap;
  margin-bottom: 5px;
}
.panel-header-row .panel-title {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.panel-period {
  font-style: italic;
  font-weight: 700;
  color: var(--navy-text);
  font-size: 0.78rem;
}
.panel-subtitle-italic {
  font-style: italic;
  color: var(--text-muted);
  font-size: 0.74rem;
}

/* ---- Table panel controls ---- */
.grid-search-box {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 5px 9px;
  font-size: 0.78rem;
  min-width: 150px;
}
.grid-export-btn, .grid-fullscreen-btn {
  background: var(--gold);
  color: var(--navy-text);
  border: none;
  border-radius: 8px;
  padding: 6px 12px;
  font-weight: 700;
  font-size: 0.74rem;
  cursor: pointer;
  transition: filter .15s ease;
  white-space: nowrap;
}
/* Full-Screen button gets a neutral navy style so it's visually distinct
   from the gold "Export CSV" action button (brief item 5). */
.grid-fullscreen-btn {
  background: var(--navy-text);
  color: #FFFFFF;
}
.grid-export-btn:hover, .grid-fullscreen-btn:hover { filter: brightness(0.92); }

/* ---- Revenue vs <Account> dropdown (VERSION 2, brief item 12) ---- */
.revenue-vs-dropdown {
  min-width: 260px !important;
  width: 260px !important;
  flex: 1 1 auto !important;
}
.revenue-vs-dropdown .Select-control,
.revenue-vs-dropdown > div {
  font-size: 0.72rem !important;
  min-height: 28px !important;
  width: 100% !important;
}

/* ---- Expense Analysis page (NEW): Sub Account dropdown + scrollable
   sub-account bar chart panels ---- */
.sub-account-dropdown {
  min-width: 260px !important;
  width: 260px !important;
  max-width: 100% !important;
  flex: 1 1 auto !important;
}
.sub-account-dropdown .Select-control,
.sub-account-dropdown > div {
  font-size: 0.72rem !important;
  min-height: 28px !important;
  width: 100% !important;
}
.expense-subaccount-scroll {
  /* height + overflow are set inline per-panel from
     layout_config.EXPENSE_SUBACCOUNT_PANEL_HEIGHT_PX (see
     pages/expense_analysis.py) - this rule only tidies the scrollbar's
     appearance so a long Sub Account list (e.g. ~50 OpEx accounts)
     scrolls cleanly inside its fixed-height panel. */
  scrollbar-width: thin;
}

/* ---- Monthly COGS/OpEx Trend + COGS/OpEx Sub-Accounts panel headings:
   centered text with an underline that hugs ONLY the text width (not
   the full panel width), for all 4 Expense Analysis charts. ---- */
.expense-chart-heading-inline {
  display: inline-block;
  color: var(--navy-text);
  font-weight: 700;
  font-size: 0.72rem;
  letter-spacing: 0.3px;
  white-space: nowrap;
  padding-bottom: 4px;
  border-bottom: 2px solid var(--navy-text);
}

/* Simple case (COGS/OpEx Sub-Accounts panels - no filter dropdown):
   just center the heading within its own row via the parent. */
.expense-chart-heading-wrapper {
  text-align: center;
  margin-bottom: 8px;
}

/* Filter case (Monthly COGS/OpEx Trend panels - heading shares its row
   with a Sub Account dropdown): the heading is centered in the row
   REGARDLESS of the dropdown's position (via absolute positioning),
   while the dropdown itself stays flex-pinned to the right - so both
   sit on the same visual line, with the heading still truly centered. */
.panel-header-row-centered {
  position: relative;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  min-height: 30px;
  margin-bottom: 8px;
}
.panel-header-row-centered .expense-chart-heading-inline {
  position: absolute;
  left: 0;
}

/* ---- Donut chart sub-labels (NEW - plain HTML, not Plotly annotations) ----
   "Gross Profit"/"Net Profit" (P&L page) and "COGS"/"OpEx" (Expense page)
   sit directly below their donut charts. Rendered as plain HTML/CSS
   instead of Plotly annotations, since Plotly's pie "domain" doesn't
   reliably fill 100% of its allotted space at every panel aspect ratio -
   this made text positioned relative to the domain edges land
   inconsistently (a visible gap, or an off-center deviation). A flex
   row split 50/50 to match the two side-by-side donuts is fully
   predictable. */
.donut-label-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  margin-top: -6px;
}
.donut-label {
  display: block;
  text-align: center;
  font-weight: 700;
  font-size: 0.78rem;
  color: var(--navy-text);
}

/* ---- AG Grid light/navy theme overrides ---- */
.ag-theme-alpine.pnl-grid {
  --ag-background-color: var(--card-bg);
  --ag-header-background-color: var(--sidebar-bg);
  --ag-header-foreground-color: #FFFFFF;
  --ag-odd-row-background-color: #FAFBFD;
  --ag-row-hover-color: #EFF3FB;
  --ag-border-color: var(--border);
  --ag-font-family: var(--font);
  --ag-font-size: 12px;
  border-radius: 10px;
  overflow: hidden;
}
/* Direct, high-specificity overrides for the header - the CSS-variable
   approach above (--ag-header-background-color / --ag-header-foreground-
   color) isn't reliably picked up by every bundled AG Grid theme build,
   so these target the actual header DOM elements directly as a
   guaranteed fallback. */
.ag-theme-alpine.pnl-grid .ag-header,
.ag-theme-alpine.pnl-grid .ag-header-row,
.ag-theme-alpine.pnl-grid .ag-header-cell {
  background-color: var(--sidebar-bg) !important;
}
.ag-theme-alpine.pnl-grid .ag-header-cell-text,
.ag-theme-alpine.pnl-grid .ag-header-cell-label,
.ag-theme-alpine.pnl-grid .ag-header-cell-label .ag-header-cell-text {
  color: #FFFFFF !important;
  font-weight: 700 !important;
}

/* ============================================================
   Full-Screen table mode (NEW, brief item 5)
   ------------------------------------------------------------
   Toggled by callbacks/filters.py::toggle_table_fullscreen(),
   which swaps this class onto the #table-panel element and
   resizes the AG Grid itself (via layout_config's
   TABLE_FULLSCREEN_HEIGHT_VH) to match.
   ============================================================ */
.table-panel-fullscreen {
  position: fixed;
  top: var(--header-height, 60px);
  left: var(--sidebar-width, 210px);
  right: 0;
  bottom: 0;
  z-index: 40;
  border-radius: 0;
  margin: 0;
  overflow-y: auto;
}

/* ============================================================
   Placeholder pages (the 9 not-yet-built pages)
   ============================================================ */
.placeholder-page {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: calc(100vh - 40px);
  padding: 24px;
}
.placeholder-panel {
  background: var(--card-bg);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  border: 1px solid var(--border);
  padding: 46px 54px;
  text-align: center;
  max-width: 480px;
}
.placeholder-icon { font-size: 2.4rem; margin-bottom: 10px; }
.placeholder-title { color: var(--navy-text); font-weight: 800; margin-bottom: 8px; }
.placeholder-text { color: var(--text-muted); font-size: 0.9rem; line-height: 1.5; }

/* ============================================================
   P&L ANALYSIS PAGE (NEW - replaces Expense Analysis)
   ------------------------------------------------------------
   Dark navy theme with a subtle light gradient in the top-right
   corner, gold-highlighted Main Account tile filter, and one
   deliberately DARK panel (Sub-Account bars) among otherwise-white
   chart panels - matching the confirmed reference image.
   ============================================================ */

.pnla-page {
  background: var(--bg);
  padding-bottom: var(--page-margin, 16px);
  min-height: 100%;
}
.salesan-page {
  background: var(--bg);
  padding-bottom: var(--page-margin, 16px);
  min-height: 100%;
}

/* Header sits directly on the dark page background - no separate white
   bar. Background/border are explicitly cleared here since .page-header
   (shared across every page) defaults to a white card background. */
.pnla-header {
  background: transparent;
  border-bottom: 1px solid var(--border);
}
.pnla-header .pnla-title { color: var(--navy-text); font-family: var(--font); font-weight: 700; }
.pnla-header .pnla-subtitle { color: var(--text-muted); }
.pnla-header .pnla-filter-label { color: var(--navy-text); text-transform: uppercase; letter-spacing: 0.08em; font-weight: 700; }
.pnla-header .pnla-refresh-value { color: var(--text-muted); }

/* ---- 2-row header (title+subtitle inline, then tiles + filters
   below, all within the same header panel) ---- */
.pnla-header-2row {
  display: flex;
  flex-direction: column;
  gap: 10px;
  align-items: stretch;
}
.pnla-header-row-a {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.pnla-header-titles-group {
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
}
.pnla-last-refresh-inline {
  font-size: 0.78rem;
  white-space: nowrap;
  flex: 0 0 auto;
}
.pnla-header-titles-group {
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
}
.pnla-last-refresh-inline {
  font-size: 0.75rem;
  white-space: nowrap;
}
.pnla-subtitle-inline {
  margin: 0;
}
.pnla-header-row-b {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
}
.pnla-header-row-b .pnla-tile-row {
  flex: 1 1 auto;
  margin: 0;
}
.pnla-header-row-b .header-filters {
  flex: 0 0 auto;
}

/* Combined KPI + Main Account tile row - 3 normal-sized KPI cards on
   the left, tiles filling the remaining space on the right, all in
   ONE row (per the confirmed spec - KPIs should not span the full row
   width on their own). */
.pnla-kpi-tile-row {
  display: flex;
  align-items: stretch;
  flex-wrap: wrap;
  gap: 10px;
  margin: 14px var(--page-margin, 20px) 14px;
}
.pnla-kpi-card {
  flex: 1 1 var(--kpi-card-min-width, 165px);
  min-width: var(--kpi-card-min-width, 165px);
  box-shadow: 0 6px 18px rgba(0,0,0,0.3);
}
.pnla-tile-row {
  display: flex;
  flex-wrap: wrap;
  align-content: center;
  gap: 8px;
  flex: 2 1 300px;
}
.main-account-tile {
  background: var(--sidebar-bg);
  color: #FFFFFF;
  border: 1px solid #FFFFFF;
  border-radius: 8px;
  padding: 8px 14px;
  font-size: 0.72rem;
  font-weight: 700;
  cursor: pointer;
  transition: background .15s ease, color .15s ease, transform .12s ease;
}
.main-account-tile:hover {
  background: var(--sidebar-bg-light);
  transform: translateY(-1px);
}
.main-account-tile-active {
  background: var(--gold);
  color: var(--navy-text);
  border-color: var(--gold-dark);
  box-shadow: 0 4px 14px rgba(242,169,59,0.5);
  font-size: 0.78rem;
  padding: 9px 16px;
  transform: scale(1.04);
}

.kpi-value.up { color: var(--positive); }
.kpi-value.down { color: var(--negative); }

/* Sub-Account bars panel - the ONE deliberately dark panel on this
   page (per the confirmed spec), gradient navy background with a
   subtle border, matching the reference image's "ledger" panel. */
.pnla-dark-panel {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--card-padding, 14px);
}
.pnla-dark-panel-title {
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--navy-text);
  text-align: center;
  margin-bottom: 8px;
  letter-spacing: 0.3px;
}
.pnla-dark-plot-area {
  background: transparent;
  border-radius: 8px;
}

/* ---- Chart grid: Sub-Accounts panel spans BOTH rows on the left;
   each row's remaining space on the right is its OWN 2-panel split
   with its own ratio (per the confirmed spec - row 1 is Donut:Trend
   = 0.5:1.75, row 2 is %-Trend:Waterfall = 1:0.75, so a single
   uniform grid can't represent both row's internal ratios at once -
   this nests a nested grid inside each row's right-hand cell instead). ---- */
/* ---- Row 2: Monthly % on Revenue Trend | Donut | Monthly Trend (3
   independent charts, no spanning column needed anymore). ---- */
.pnla-row2-grid {
  display: grid;
  grid-template-columns: 1.1fr 0.9fr 1fr;
  gap: var(--card-spacing, 16px);
  margin: 0 var(--page-margin, 20px) 14px;
}
/* ---- Row 3: Sub-Account (bar+line) | Waterfall. ---- */
.pnla-row3-grid {
  display: grid;
  grid-template-columns: 1fr 0.75fr 1.25fr;
  gap: var(--card-spacing, 16px);
  margin: 0 var(--page-margin, 20px) 14px;
}
.pnla-row2-grid > div, .pnla-row3-grid > div {
  min-width: 0;  /* prevents a wide scrollable chart from stretching the whole grid */
}
@media (max-width: 1100px) {
  .pnla-row2-grid, .pnla-row3-grid { grid-template-columns: 1fr; }
}
.pnla-insights-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-height: 207px;
  overflow-y: auto;
}
.pnla-insight-item {
  display: flex;
  gap: 6px;
  align-items: flex-start;
  font-size: 0.82rem;
  font-weight: 700;
  line-height: 1.4;
  color: var(--navy-text);
}
.pnla-insight-icon {
  flex: 0 0 auto;
  font-size: 0.9rem;
  margin-top: 1px;
}
.pnla-insight-icon.positive { color: var(--positive); }
.pnla-insight-icon.negative { color: var(--negative); }
.pnla-insight-icon.neutral { color: #C8821F; }

/* ---- P&L Statement table panel: navy background (matching the
   sidebar), white heading text - the AG Grid itself and its search/
   export/fullscreen controls are untouched, only the outer card and
   its title text change. ---- */
#table-panel {
  background: var(--sidebar-bg);
}
#table-panel #pnl-statement-title {
  color: #FFFFFF;
}

/* ---- P&L dashboard header: navy background (matching the sidebar),
   gold title - matching the P&L Analysis page's header treatment.
   Scoped to .pnl-header specifically so no other page sharing the
   shared .page-header/.page-title classes is affected. ---- */
.pnl-header {
  background: transparent;
  border-bottom: 1px solid var(--border);
}
.pnl-header-title {
  color: var(--ink-900);
  font-family: var(--font-serif);
  font-weight: 600;
}
.pnl-header-subtitle {
  color: var(--ink-500);
}
.pnl-header .filter-label {
  color: var(--ink-900);
}
.pnl-header .last-refresh-value {
  color: rgba(21,36,71,0.75);
}

/* ---- Sales Dashboard header: navy background (matching the sidebar),
   gold title - same treatment as the P&L Analysis / P&L dashboard
   headers. Scoped to .sales-header specifically so no other page
   sharing the shared .page-header/.page-title classes is affected. ---- */
.sales-header {
  background: transparent;
  border-bottom: 1px solid var(--border);
}
.sales-header-title {
  color: var(--navy-text);
  font-family: var(--font);
  font-weight: 700;
}
.sales-header-subtitle {
  color: var(--text-muted);
}
.sales-header .filter-label {
  color: var(--navy-text);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 700;
}
.sales-header .last-refresh-value {
  color: var(--text-muted);
}
.sales-header .pnla-refresh-value {
  color: var(--text-muted);
}

/* ---- Sales Analysis header: navy background, gold title - matching
   every other dashboard page's header treatment. ---- */
.salesan-header {
  background: transparent;
  border-bottom: 1px solid var(--border);
}
.salesan-header-title {
  color: var(--navy-text);
  font-family: var(--font);
  font-weight: 700;
}
.salesan-header-subtitle {
  color: var(--text-muted);
}
.salesan-header .filter-label {
  color: var(--navy-text);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 700;
}
.salesan-header .last-refresh-value {
  color: var(--text-muted);
}

/* ---- Sales Dashboard: custom chart-row ratios (per the confirmed
   spec) - Row 2 is Category:Region:Trend = 1:0.75:1.25, Row 3 is
   Customers:Payment:Salesperson = 1.5:0.75:0.75. ---- */
.sales-row2-grid {
  display: grid;
  grid-template-columns: 0.8fr 0.95fr 1.25fr;
  gap: var(--card-spacing, 16px);
  margin: var(--card-spacing, 14px) var(--page-margin, 20px);
}
.sales-row3-grid {
  display: grid;
  grid-template-columns: 1.5fr 0.75fr 0.75fr;
  gap: var(--card-spacing, 16px);
  margin: var(--card-spacing, 14px) var(--page-margin, 20px);
}
/* Without this, a CSS Grid item defaults to min-width:auto, which lets
   it grow to fit oversized content (the Top Customers chart's computed
   width can be 2000px+) - stretching the WHOLE grid (and page) wider
   instead of letting .sales-customer-scroll-x's own overflow-x:auto
   contain it. This is what caused the entire dashboard to scroll
   horizontally instead of just the one chart. */
.sales-row2-grid > div, .sales-row3-grid > div {
  min-width: 0;
}
@media (max-width: 1200px) {
  .sales-row2-grid, .sales-row3-grid { grid-template-columns: 1fr 1fr; }
}

/* ---- Top Customers bar+line chart: HORIZONTAL scroll (the chart's
   own computed width can be much wider than its panel, e.g. ~50
   customers at ~55px each) - this is a different scroll axis than the
   app's other scrollable charts (which scroll vertically for long
   lists), so it gets its own class rather than reusing
   .expense-subaccount-scroll. ---- */
.sales-customer-scroll-x {
  overflow-x: auto;
  overflow-y: hidden;
  width: 100%;
  max-width: 100%;
}

/* ============================================================
   SALES ANALYSIS PAGE v2 (dimension tiles + Sales/GP toggle)
   ------------------------------------------------------------
   Chart grid ratios are a DELIBERATE match to the P&L Analysis
   page's grid (same structure: a tall chart spanning 2 rows on the
   left, each row's remaining space split independently on the
   right) - kept as separate classes/numbers here (not literally
   reused) so either page's ratios can be tuned independently later
   without affecting the other.
   ============================================================ */
/* ---- Row 2: % Trend | Donuts | Monthly Trend (3 independent charts,
   no spanning column needed anymore). ---- */
.salesan-row2-grid {
  display: grid;
  grid-template-columns: 1fr 0.75fr 1.25fr;
  gap: var(--card-spacing, 16px);
  margin: 0 var(--page-margin, 20px) 14px;
}
/* ---- Row 3: Top-Item (bar+line) | Waterfall - ratio keeps the
   Waterfall panel at roughly the same absolute width it had before
   (it previously sat in a 1fr:1fr split within the right ~70% of the
   old spanning-column grid, i.e. ~35% of the total row width) - the
   Top-Item chart gets whatever space remains. ---- */
.salesan-row3-grid {
  display: grid;
  grid-template-columns: 1.1fr 0.9fr 1fr;
  gap: var(--card-spacing, 16px);
  margin: 0 var(--page-margin, 20px) 14px;
}
.salesan-insights-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-height: 207px;
  overflow-y: auto;
}
.salesan-insight-item {
  display: flex;
  gap: 6px;
  align-items: flex-start;
  font-size: 0.82rem;
  font-weight: 700;
  line-height: 1.4;
  color: var(--navy-text);
}
.salesan-insight-icon {
  flex: 0 0 auto;
  font-size: 0.9rem;
  margin-top: 1px;
}
.salesan-insight-icon.positive { color: var(--positive); }
.salesan-insight-icon.negative { color: var(--negative); }
.salesan-insight-icon.neutral { color: #C8821F; }
.salesan-row2-grid > div, .salesan-row3-grid > div {
  min-width: 0;  /* prevents a wide scrollable chart from stretching the whole grid - see the Top Customers scroll fix on the Sales Dashboard page for the full explanation */
}
@media (max-width: 1100px) {
  .salesan-row2-grid, .salesan-row3-grid { grid-template-columns: 1fr; }
}

/* ---- Combined KPI + Sales/GP toggle row ---- */
.salesan-kpi-toggle-row {
  display: flex;
  align-items: stretch;
  flex-wrap: wrap;
  gap: 10px;
  margin: 14px var(--page-margin, 20px) 10px;
}
.salesan-kpi-toggle-row .kpi-card {
  flex: 1 1 var(--kpi-card-min-width, 165px);
  min-width: var(--kpi-card-min-width, 165px);
}
.salesan-metric-toggle {
  display: flex;
  gap: 6px;
  align-items: center;
  flex: 0 0 auto;
}
.salesan-metric-btn {
  background: var(--card-bg);
  color: var(--navy-text);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 18px;
  font-size: 0.78rem;
  font-weight: 700;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.salesan-metric-btn:hover { background: #F4F6FA; }
.salesan-metric-btn-active {
  background: var(--gold);
  color: var(--navy-text);
  border-color: var(--gold-dark);
  box-shadow: 0 3px 10px rgba(242,169,59,0.35);
}

/* ---- Dimension tile row (Level 1: Category / Branches / Region /
   Payment Mode / Customer) ---- */
.salesan-tile-row {
  display: flex;
  flex-wrap: wrap;
  align-content: center;
  justify-content: flex-end;
  gap: 8px;
  flex: 0 1 auto;
}
.salesan-dimension-tile {
  background: var(--sidebar-bg);
  color: #FFFFFF;
  border: 1px solid #FFFFFF;
  border-radius: 8px;
  padding: 8px 16px;
  font-size: 0.87rem;
  font-weight: 700;
  cursor: pointer;
  transition: background .15s ease, color .15s ease, transform .12s ease;
}
.salesan-dimension-tile:hover { background: var(--sidebar-bg-light); transform: translateY(-1px); }
.salesan-dimension-tile-active {
  background: var(--gold);
  color: var(--navy-text);
  border-color: var(--gold-dark);
  box-shadow: 0 4px 14px rgba(242,169,59,0.5);
  font-size: 0.94rem;
  padding: 9px 18px;
  transform: scale(1.04);
}

/* ---- Waterfall / Top-Item horizontal scroll wrapper (reused pattern
   from the Sales Dashboard's Top Customers chart) ---- */
.salesan-scroll-x {
  overflow-x: auto;
  overflow-y: hidden;
  width: 100%;
  max-width: 100%;
}
.salesan-waterfall-heading-small {
  font-size: 0.62rem;
  white-space: normal;
  line-height: 1.3;
}

/* ---- KPI card highlighting is now handled by the tier system
   (.kpi-tier-1 through .kpi-tier-6) applied per-card by each page. ---- */

/* ---- AI Insights panel (both Sales Analysis and P&L Analysis) - navy
   background, gold heading, white insight text. ---- */
.ai-insights-panel {
  background: var(--card-bg);
  border: 2px solid var(--gold);
}
.ai-insights-panel .expense-chart-heading-inline {
  color: var(--navy-text);
  border-bottom-color: var(--navy-text);
}
.ai-insights-panel .salesan-insight-item,
.ai-insights-panel .pnla-insight-item {
  color: var(--navy-text);
}
.ai-insights-panel .pnla-expand-btn {
  border-color: var(--navy-text);
  color: var(--navy-text);
}

/* ---- Expand/collapse mechanism (P&L Analysis: Commentary, AI
   Insights, Sub-Accounts, Waterfall panels) - a small icon button in
   the panel's heading row toggles the panel to span the full grid row
   width and grow taller, IN PLACE (not a popup/modal, not full
   screen) - the other panels in that row simply wrap onto the next
   line while one is expanded. ---- */
.pnla-expand-heading-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.pnla-expand-btn {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--navy-text);
  font-size: 0.85rem;
  line-height: 1;
  padding: 3px 7px;
  cursor: pointer;
  flex: 0 0 auto;
}
.pnla-expand-btn:hover {
  background: #F4F6FA;
}
.pnla-expand-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(15, 24, 45, 0.55);
  z-index: 999;
}
.pnla-expand-backdrop.active {
  display: block;
}
.pnla-panel-expanded {
  position: fixed !important;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(65vw, 1100px);
  max-height: 80vh;
  overflow-y: auto;
  z-index: 1000;
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.45);
}
.pnla-panel-expanded .pnla-insights-list,
.pnla-panel-expanded .salesan-insights-list,
.pnla-panel-expanded .pnla-commentary-text {
  max-height: 65vh;
}

/* ---- Performance Commentary panel (Row 1) - reacts live to the
   currently selected Main Account tile / Sub Account, unlike the AI
   Insights panel which stays stable/global. ---- */
.pnla-commentary-panel {
  flex: 2 1 320px;
  background: var(--card-bg);
  border: 2px solid var(--gold);
}
.pnla-commentary-panel .expense-chart-heading-inline {
  color: var(--navy-text);
  border-bottom-color: var(--navy-text);
}
.pnla-commentary-panel .pnla-expand-btn {
  border-color: var(--navy-text);
  color: var(--navy-text);
}
.pnla-commentary-text {
  font-size: 0.8rem;
  font-weight: 600;
  line-height: 1.5;
  flex: 1 1 auto;
  min-width: 0;
}
.pnla-commentary-text > span {
  margin-right: 4px;
}


/* ---- Shared text-color classes for AI Insights + Performance
   Commentary - green=favorable, red=unfavorable, blue=neutral/context. ---- */
.pnla-color-green { color: var(--positive); }
.pnla-color-red { color: var(--negative); }
.pnla-color-blue { color: var(--navy-text); }

/* ---- Performance Commentary: heading + commentary text now sit
   INLINE on the same line, per the confirmed spec. ---- */
.pnla-commentary-inline-row {
  display: flex;
  align-items: baseline;
  flex-wrap: nowrap;
  gap: 6px;
  max-height: 130px;
  overflow-y: auto;
}
.pnla-commentary-heading-segment {
  font-weight: 700;
  color: var(--navy-text);
}

/* ---- Sales Dashboard: metric toggle sits at the end of the filter
   row, visually SEPARATE from the other filter dropdowns (its own
   left divider + extra spacing), rather than blending in as "just
   another filter". ---- */
.sales-toggle-separated {
  display: flex;
  align-items: center;
  gap: 14px;
  padding-left: 16px;
  margin-left: 8px;
  border-left: 1px solid rgba(255, 255, 255, 0.25);
}

/* ---- Filter dropdown color coding (all dashboards): golden
   background when a SPECIFIC value is selected, white when "All" -
   Date Range dropdowns are always golden (a period is always
   selected, never "All"). ---- */
.filter-dropdown-golden > div {
  background: var(--gold) !important;
}
.filter-dropdown-golden .Select-value-label,
.filter-dropdown-golden .Select-value,
.filter-dropdown-golden [class*="singleValue"],
.filter-dropdown-golden [class*="placeholder"] {
  color: var(--navy-text) !important;
  font-weight: 700 !important;
}
.filter-dropdown-golden [class*="indicatorContainer"] svg,
.filter-dropdown-golden [class*="dropdownIndicator"] svg {
  fill: var(--navy-text) !important;
}

/* ==================================================================
   SALES INTELLIGENCE PAGE
   ================================================================== */
.si-section-heading {
  color: #FFFFFF;
  font-weight: 700;
  font-size: 0.85rem;
  letter-spacing: 0.5px;
  margin: 22px var(--page-margin, 20px) 10px;
}

/* ---- Health Score badge (header, top right) ---- */
.si-health-badge {
  display: flex;
  flex-direction: column;
  align-items: center;
  background: var(--gold);
  border-radius: 10px;
  padding: 6px 18px;
  flex: 0 0 auto;
}
.si-health-score-value {
  font-size: 1.4rem;
  font-weight: 800;
  color: var(--navy-text);
  line-height: 1.1;
}
.si-health-label {
  font-size: 0.62rem;
  font-weight: 700;
  color: var(--navy-text);
  letter-spacing: 0.3px;
}

/* ---- Attention panel (differentiator feature) ---- */
.si-attention-panel {
  margin: 14px var(--page-margin, 20px) 4px;
}
.si-attention-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 6px;
}
.si-attention-item {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--navy-text);
  padding-left: 4px;
  border-left: 3px solid var(--gold);
  padding: 4px 0 4px 10px;
}

/* ---- Executive Summary cards (Section 1) ---- */
.si-exec-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  margin: 10px var(--page-margin, 20px) 4px;
}
@media (max-width: 1300px) {
  .si-exec-row { grid-template-columns: repeat(2, 1fr); }
}
.si-exec-card {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
}
.si-exec-icon {
  font-size: 1.4rem;
  flex: 0 0 auto;
}
.si-exec-text-col {
  min-width: 0;
}
.si-exec-title {
  font-size: 0.65rem;
  font-weight: 700;
  color: var(--text-muted);
  letter-spacing: 0.3px;
  text-transform: uppercase;
}
.si-exec-value {
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--navy-text);
  margin-top: 2px;
  line-height: 1.35;
}

/* ---- Stat row (Sections 3 & 7) ---- */
.si-stat-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  margin: 0 var(--page-margin, 20px) 4px;
}
.si-stat-card {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px;
  text-align: center;
}
.si-stat-label {
  font-size: 0.68rem;
  font-weight: 700;
  color: var(--text-muted);
  letter-spacing: 0.3px;
}
.si-stat-value {
  font-size: 1.3rem;
  font-weight: 800;
  color: var(--navy-text);
  margin-top: 4px;
}

/* ---- 3-column card grid (Sections 2, 4, 6) ---- */
.si-row3-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  margin: 0 var(--page-margin, 20px) 4px;
}
@media (max-width: 1300px) {
  .si-row3-grid { grid-template-columns: 1fr; }
}
.si-list-card-heading {
  font-size: 0.68rem;
}
.si-list-body {
  margin-top: 8px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.si-list-item {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--navy-text);
  display: flex;
  justify-content: space-between;
  gap: 8px;
}
.si-list-item-value {
  color: var(--text-muted);
  font-weight: 700;
  flex: 0 0 auto;
}

/* ---- Salesperson cards (Section 4, reuses si-row3-grid but with a
   different card shape - simple text card, not a top-3 list) ---- */
.si-simple-card {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px;
}
.si-simple-card-title {
  font-size: 0.68rem;
  font-weight: 700;
  color: var(--text-muted);
  letter-spacing: 0.3px;
  text-transform: uppercase;
}
.si-simple-card-text {
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--navy-text);
  margin-top: 6px;
}

/* ---- Branch table (Section 5) ---- */
.si-branch-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.78rem;
}
.si-branch-table th {
  text-align: left;
  padding: 8px 10px;
  background: var(--sidebar-bg);
  color: #FFFFFF;
  font-weight: 700;
  font-size: 0.68rem;
  letter-spacing: 0.3px;
}
.si-branch-table td {
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
  color: var(--navy-text);
  font-weight: 600;
}
.si-branch-table tr:last-child td {
  border-bottom: none;
}

/* ---- Highlight/Lowlight rows (Sales Insight's simplified Performance
   Commentary panel) ---- */
.si-highlight-row {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 0.8rem;
  font-weight: 700;
  line-height: 1.4;
}
.si-highlight-icon {
  flex: 0 0 auto;
}

/* ---- AI Insights & Actions collapsed cards (icon + title + text,
   matching the confirmed executive-summary-style format) ---- */
.si-insight-card {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}
.si-insight-icon {
  font-size: 1.1rem;
  flex: 0 0 auto;
  line-height: 1.3;
}
.si-insight-text-col {
  min-width: 0;
}
.si-insight-title {
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--navy-text);
}
.si-insight-text {
  font-size: 0.76rem;
  font-weight: 600;
  line-height: 1.3;
}

/* ---- Sales Insight header: visual '|' dividers between the filter
   groups, tiles, and toggle, per the confirmed header ordering. ---- */
.salesan-header-divider {
  width: 1px;
  align-self: stretch;
  background: var(--border);
  margin: 4px 2px 4px auto;
}

/* ---- Master Filter (Sales Insight): a persistent global scope
   filter, visually grouped and set apart from the other header
   controls with a subtle border, since it behaves differently -
   staying applied even when the Level 1 tile changes. ---- */
.si-master-filter-group {
  display: flex;
  gap: 8px;
}

/* ==================================================================
   CASH FLOW DASHBOARD
   ================================================================== */
.cf-header {
  background: transparent;
  border-bottom: 1px solid var(--border);
}
.cf-header-title {
  color: var(--navy-text);
  font-family: var(--font);
  font-weight: 700;
}
.cf-header-subtitle {
  color: var(--text-muted);
}
.cf-header .filter-label {
  color: var(--navy-text);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 700;
}
.cf-header .last-refresh-value {
  color: var(--text-muted);
}
.cf-kpi-row {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 12px;
  margin: 0 var(--page-margin, 20px) 14px;
}
@media (max-width: 1400px) {
  .cf-kpi-row { grid-template-columns: repeat(3, 1fr); }
}
.cf-row3-grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: var(--card-spacing, 16px);
  margin: 0 var(--page-margin, 20px) 14px;
}
.cf-row2-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--card-spacing, 16px);
  margin: 0 var(--page-margin, 20px) 14px;
}
.cf-heading-green {
  color: var(--positive) !important;
}
.cf-heading-red {
  color: #E64545 !important;
}
.cf-summary-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8rem;
}
.cf-summary-table th {
  text-align: left;
  padding: 8px 10px;
  background: var(--sidebar-bg);
  color: #FFFFFF;
  font-weight: 700;
  font-size: 0.68rem;
  letter-spacing: 0.3px;
}
.cf-summary-table td {
  padding: 6px 10px;
  border-bottom: 1px solid var(--border);
  color: var(--navy-text);
  font-weight: 600;
}
.cf-summary-table td.cf-amount-col {
  text-align: right;
}
.cf-summary-table tr.cf-total-row td {
  font-weight: 800;
  border-top: 2px solid var(--navy-text);
}
.cf-summary-table tr.cf-section-row td {
  font-weight: 800;
  color: var(--gold-dark, #C8821F);
}

/* ==================================================================
   KPI CARD TIER SYSTEM - tiers 1 and 2 (the first two cards in each
   row) get the hero treatment: solid navy / solid gold fill,
   alternating, per the confirmed navy/gold theme spec. Tiers 3-6 stay
   plain white cards like every other KPI card.
   ================================================================== */
.kpi-tier-3, .kpi-tier-4, .kpi-tier-5, .kpi-tier-6 {
  background: var(--card-bg);
  border: 1px solid var(--border);
}
.kpi-tier-3 .kpi-title, .kpi-tier-4 .kpi-title, .kpi-tier-5 .kpi-title, .kpi-tier-6 .kpi-title {
  color: var(--text-muted);
}
.kpi-tier-3 .kpi-value, .kpi-tier-4 .kpi-value, .kpi-tier-5 .kpi-value, .kpi-tier-6 .kpi-value {
  color: var(--navy-text);
}

.kpi-tier-1, .kpi-tier-2 {
  background: var(--card-bg);
  border: 1px solid var(--border);
}
.kpi-tier-1 .kpi-title, .kpi-tier-2 .kpi-title { color: var(--text-muted); }
.kpi-tier-1 .kpi-value, .kpi-tier-2 .kpi-value { color: var(--navy-text); }
.kpi-tier-1 .kpi-variance.up, .kpi-tier-2 .kpi-variance.up { color: var(--positive); }
.kpi-tier-1 .kpi-variance.down, .kpi-tier-2 .kpi-variance.down { color: var(--negative); }

.cf-row3-summary-grid {
  display: grid;
  grid-template-columns: 1.2fr 0.9fr 0.9fr;
  gap: var(--card-spacing, 16px);
  margin: 0 var(--page-margin, 20px) 14px;
}

.cf-category-row {
  cursor: pointer;
}
.cf-category-row:hover {
  background: rgba(21,36,71,0.04);
}
.cf-line-item-row td {
  color: var(--ink-500);
  font-weight: 500;
  font-size: 0.76rem;
}

/* ==================================================================
   PURCHASE DASHBOARD
   ================================================================== */
.purchase-header-title {
  color: var(--ink-900);
  font-family: var(--font-serif);
  font-weight: 600;
}
.purchase-header-subtitle {
  color: var(--ink-500);
}
.purchase-kpi-row {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 12px;
  margin: 0 var(--page-margin, 20px) 14px;
}
@media (max-width: 1400px) {
  .purchase-kpi-row { grid-template-columns: repeat(3, 1fr); }
}
.purchase-row3-grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: var(--card-spacing, 16px);
  margin: 0 var(--page-margin, 20px) 14px;
}

/* ---- Vertical scroll wrapper for ranked bar charts that could have
   many rows (Top Suppliers/Customers/Due-This-Month rankings) - the
   panel itself stays a fixed, reasonable height; if the chart's
   computed height exceeds it, THIS wrapper scrolls internally instead
   of the chart pushing the whole page taller. Used across Purchase,
   Receivables, and Payables dashboards. ---- */
.ranked-chart-scroll-y {
  max-height: 260px;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: thin;
}
/* Purchase Dashboard - "Purchase by Supplier" specifically, reduced
   slightly shorter than the shared default above. Applied via its own
   dedicated class (set directly in pages/purchase.py) rather than a
   CSS :has() selector, so no other page's scrollable charts (which
   all share .ranked-chart-scroll-y) are affected. */
.purchase-supplier-scroll-y {
  max-height: 210px;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: thin;
}
.cf-summary-scroll {
  max-height: 200px;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: thin;
}

/* ==================================================================
   RECEIVABLES DASHBOARD
   ================================================================== */
.receivables-header-title {
  color: var(--ink-900);
  font-family: var(--font-serif);
  font-weight: 600;
}
.receivables-header-subtitle {
  color: var(--ink-500);
}
.receivables-kpi-row {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 12px;
  margin: 0 var(--page-margin, 20px) 14px;
}
@media (max-width: 1400px) {
  .receivables-kpi-row { grid-template-columns: repeat(3, 1fr); }
}

/* ==================================================================
   PAYABLES DASHBOARD
   ================================================================== */
.payables-header-title {
  color: var(--ink-900);
  font-family: var(--font-serif);
  font-weight: 600;
}
.payables-header-subtitle {
  color: var(--ink-500);
}
.payables-kpi-row {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 12px;
  margin: 0 var(--page-margin, 20px) 14px;
}
@media (max-width: 1400px) {
  .payables-kpi-row { grid-template-columns: repeat(3, 1fr); }
}

/* ==================================================================
   BALANCE SHEET DASHBOARD
   ================================================================== */
.bs-header-title {
  color: var(--ink-900);
  font-family: var(--font-serif);
  font-weight: 600;
}
.bs-header-subtitle {
  color: var(--ink-500);
}
.bs-kpi-row {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 12px;
  margin: 0 var(--page-margin, 20px) 14px;
}
@media (max-width: 1400px) {
  .bs-kpi-row { grid-template-columns: repeat(3, 1fr); }
}
.bs-ratio-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}
.bs-ratio-card {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
}
.bs-ratio-icon {
  font-size: 1.4rem;
}
.bs-ratio-label {
  color: var(--navy-text);
  font-weight: 700;
  font-size: 0.72rem;
}
.bs-ratio-value {
  color: var(--ink-900);
  font-family: var(--font-serif);
  font-weight: 700;
  font-size: 1.1rem;
}
.bs-ratio-change {
  font-size: 0.7rem;
  font-weight: 600;
}
.bs-ratio-change.up { color: var(--positive); }
.bs-ratio-change.down { color: var(--negative); }

.purchase-row2-supplier-grid {
  display: grid;
  grid-template-columns: 0.8fr 0.95fr 1.25fr;
  gap: var(--card-spacing, 16px);
  margin: 0 var(--page-margin, 20px) 14px;
}
.purchase-row3-country-grid {
  display: grid;
  grid-template-columns: 0.6fr 0.8fr 0.8fr 0.9fr;
  gap: var(--card-spacing, 16px);
  margin: 0 var(--page-margin, 20px) 14px;
}

.receivables-row2-custom-grid {
  display: grid;
  grid-template-columns: 0.8fr 0.9fr 1.1fr 1.2fr;
  gap: var(--card-spacing, 16px);
  margin: 0 var(--page-margin, 20px) 14px;
}

/* ==================================================================
   INVENTORY DASHBOARD
   ================================================================== */
.inventory-header-title {
  color: var(--ink-900);
  font-family: var(--font-serif);
  font-weight: 600;
}
.inventory-header-subtitle {
  color: var(--ink-500);
}
.inventory-kpi-row {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 12px;
  margin: 0 var(--page-margin, 20px) 14px;
}
@media (max-width: 1400px) {
  .inventory-kpi-row { grid-template-columns: repeat(3, 1fr); }
}

/* ==================================================================
   EXECUTIVE SUMMARY DASHBOARD
   ================================================================== */
.exec-header-title {
  color: var(--ink-900);
  font-family: var(--font-serif);
  font-weight: 600;
}
.exec-header-subtitle {
  color: var(--ink-500);
}
.exec-row2-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr) repeat(2, 1.15fr);
  gap: 12px;
  margin: 0 var(--page-margin, 20px) 14px;
}
.exec-gauge-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 10px;
  overflow: hidden;
  min-width: 0;
}
.exec-gauge-label {
  font-weight: 700;
  font-size: 0.78rem;
  color: var(--ink-900);
  margin-bottom: 2px;
}

/* ==================================================================
   BUSINESS KPI DASHBOARD
   ================================================================== */
.bkpi-header-title {
  color: var(--ink-900);
  font-family: var(--font-serif);
  font-weight: 600;
}
.bkpi-header-subtitle {
  color: var(--ink-500);
}
.bkpi-kpi-row {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 10px;
  margin: 0 var(--page-margin, 20px) 12px;
}
@media (max-width: 1400px) {
  .bkpi-kpi-row { grid-template-columns: repeat(3, 1fr); }
}
.bkpi-card {
  display: flex;
  flex-direction: column;
  padding: 10px 12px;
}
.bkpi-card-top {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 2px;
}

.bkpi-card-icon {
  font-size: 1.3rem;
  flex: 0 0 auto;
}
.bkpi-footnote {
  color: var(--ink-500);
  font-size: 0.72rem;
  margin: 8px var(--page-margin, 20px) 4px;
}

.exec-gauge-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  margin: 0 var(--page-margin, 20px) 14px;
}

/* ---- Balance Sheet summary table full-screen expand, reusing the
   shared expand-panel mechanism (backdrop + fixed-position overlay). ---- */
#bs-table-panel.pnla-panel-expanded {
  width: min(90vw, 1400px) !important;
  max-height: 88vh;
  display: block !important;
}
#bs-table-panel.pnla-panel-expanded #bs-summary-table {
  max-height: 70vh;
  overflow-y: auto;
}

.inventory-row2-custom-grid {
  display: grid;
  grid-template-columns: 0.7fr 1.15fr 1.15fr;
  gap: var(--card-spacing, 16px);
  margin: 0 var(--page-margin, 20px) 14px;
}
.inventory-row3-custom-grid {
  display: grid;
  grid-template-columns: 0.8fr 0.7fr 0.7fr 0.8fr;
  gap: var(--card-spacing, 16px);
  margin: 0 var(--page-margin, 20px) 14px;
}


/* ==================================================================
   MOBILE USABILITY PASS - applies at 768px and below (phones and
   small tablets). Stacks every multi-column chart row into a single
   column, turns fixed 6-column KPI row grids into a 2-column layout
   (instead of 6 unusably tiny columns), and makes wide tables scroll
   horizontally inside their own container instead of forcing the
   whole page to scroll sideways. Sidebar collapse is handled
   separately in sidebar.css + app.py (needs a toggle, not just CSS).
   ================================================================== */
@media (max-width: 768px) {
  /* ---- Every multi-column chart/content row -> single column ---- */
  .main-grid, .main-grid-lower,
  .pnla-row2-grid, .pnla-row3-grid,
  .sales-row2-grid, .sales-row3-grid,
  .salesan-row2-grid, .salesan-row3-grid,
  .si-exec-row, .si-stat-row, .si-row3-grid,
  .cf-row2-grid, .cf-row3-grid, .cf-row3-summary-grid,
  .purchase-row3-grid, .purchase-row2-supplier-grid, .purchase-row3-country-grid,
  .receivables-row2-custom-grid,
  .bs-ratio-grid,
  .exec-row2-grid, .exec-gauge-row,
  .inventory-row2-custom-grid, .inventory-row3-custom-grid {
    grid-template-columns: 1fr !important;
  }

  /* ---- KPI card rows: one card per row (user preference - trades
     more scrolling for larger, more comfortably readable cards) ---- */
  .purchase-kpi-row, .receivables-kpi-row, .payables-kpi-row,
  .bs-kpi-row, .inventory-kpi-row, .bkpi-kpi-row {
    grid-template-columns: 1fr !important;
  }

  .kpi-card, .bkpi-card {
    min-width: 0 !important;
  }

  /* ---- Base flex-based KPI row (Executive Summary, P&L, etc.) -
     full width per card instead of ~half ---- */
  .kpi-row .kpi-card {
    flex: 1 1 100% !important;
  }

  /* ---- Filters: one per row instead of 2 squeezing in side by side
     (header-filters already wraps - this just removes the min-width
     that was letting 2 narrow ones fit before wrapping) ---- */
  .filter-group {
    width: 100% !important;
    min-width: 0 !important;
  }

  /* ---- Metric toggle (Sales/Gross Profit/Margin % etc.) - its own
     full-width row rather than squeezed next to other header
     elements; buttons inside still sit side by side as one control,
     wrapping only if they don't fit a full-width row ---- */
  .salesan-metric-toggle {
    flex: 1 1 100% !important;
    width: 100%;
    flex-wrap: wrap;
  }

  /* ---- Header should scroll away normally with the page on mobile,
     not stay pinned at the top - with filters now stacked one per
     row the header is much taller than on desktop, so keeping it
     stuck would permanently eat most of a small screen. This also
     fixes an inconsistency where some pages' headers stayed pinned
     indefinitely while others eventually released, depending on
     each page's specific container structure. ---- */
  .page-header {
    position: static !important;
  }

  /* ---- Page margins: desktop values are too wide on a narrow phone
     screen, eating usable space ---- */
  .sales-row2-grid, .sales-row3-grid, .purchase-row2-supplier-grid,
  .purchase-row3-country-grid, .receivables-row2-custom-grid,
  .cf-row2-grid, .cf-row3-grid, .inventory-row2-custom-grid,
  .inventory-row3-custom-grid, .exec-row2-grid {
    margin-left: 10px !important;
    margin-right: 10px !important;
  }

  /* ---- Any table wider than the screen scrolls inside its own
     container, not the whole page ---- */
  .cf-summary-table, .pnla-table-wrapper, table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
}

/* ==================================================================
   MOBILE SIDEBAR COLLAPSE - hamburger toggle (button + dcc.Store +
   a clientside callback in app.py flips a CSS class on click - no
   server round-trip). Desktop: the hamburger button is completely
   hidden, and the sidebar behaves exactly as before. Mobile only
   (<=768px): the sidebar starts off-screen and slides in when the
   hamburger is tapped, instead of permanently eating ~200px of a
   ~375px screen.
   ================================================================== */
.mobile-nav-label {
  display: none;
  border: none;
  padding: 0;
}

@media (max-width: 768px) {
  .mobile-nav-label {
    display: flex;
    align-items: center;
    justify-content: center;
    position: fixed;
    top: 12px;
    left: 12px;
    z-index: 2147483647; /* max possible z-index - forces this above any
                            competing stacking context, including any
                            caused by CSS zoom elsewhere on the page */
    width: 40px;
    height: 40px;
    background: var(--sidebar-bg, #152447);
    border-radius: 8px;
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(0,0,0,0.25);
    pointer-events: auto;
    -webkit-tap-highlight-color: rgba(255,255,255,0.3);
    touch-action: manipulation;
  }
  .mobile-nav-icon,
  .mobile-nav-icon::before,
  .mobile-nav-icon::after {
    content: "";
    display: block;
    width: 20px;
    height: 2px;
    background: #FFFFFF;
    position: relative;
  }
  .mobile-nav-icon::before { position: absolute; top: -6px; }
  .mobile-nav-icon::after { position: absolute; top: 6px; }

  #sidebar-container .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    z-index: 999;
    transform: translateX(-100%);
    transition: transform 0.25s ease;
    zoom: 100%; /* override the desktop-only 85% zoom - avoids the same
                   kind of zoom-vs-measurement bug seen earlier, this
                   time with translateX() instead of vh units, and the
                   mobile sidebar is a full-width overlay when open, so
                   it doesn't need the desktop shrink anyway */
  }
  #sidebar-container.mobile-nav-active .sidebar {
    transform: translateX(0);
  }

  /* Content takes the full width on mobile - sidebar is an overlay
     now, not a permanent flex column taking up space */
  .page-content {
    margin-left: 0 !important;
  }

  /* Leave room so the hamburger button doesn't sit on top of each
     page's own header/title. Also reset the desktop-only 85% content
     zoom back to 100% here - on mobile the single-column stacking
     above already solves the "doesn't fit" problem, so stacking the
     desktop zoom on top of it would just make text/charts needlessly
     tiny on an already-small phone screen. */
  .page-content {
    padding-top: 56px;
    zoom: 100%;
  }

  /* Charts were capturing touch-drag/pinch gestures meant for
     scrolling the page, making them appear to "move" or change when
     the user was just trying to scroll past them. pan-y allows normal
     vertical page scrolling to pass straight through every chart,
     while blocking the chart's own pan/zoom gesture handling.
     Filters and toggles are separate elements elsewhere on the page,
     so they're untouched by this and remain fully clickable/tappable
     as normal. */
  .js-plotly-plot, .plot-container, .js-plotly-plot .nsewdrag {
    touch-action: pan-y !important;
  }
}
