/*
 * Site-wide theme tokens. Originated in virtualcfo/landing.css (2026-07-25) as a
 * one-page ledger/navy/brass palette; promoted here so every app can share the
 * same contract instead of redefining its own light/dark values.
 *
 * Token names are the seam: a new theme (system default, or eventually an
 * organisation's corporate palette) only needs to supply new values for these
 * same names, never new selectors elsewhere in the codebase.
 *
 * Precedence: prefers-color-scheme sets the default when the user hasn't
 * chosen explicitly; [data-theme] on <html> (set server-side from a saved
 * preference, or client-side via the navbar toggle) always wins over it.
 */

:root {
  --ink: #16213a;
  --paper: #f6f3ec;
  --paper-raised: #efeade;
  --brass: #a9793c;
  --brass-strong: #8f6530;
  --slate: #5c6470;
  --rule: #d8d0bf;
  --ok: #2f6b44;
  --ok-bg: #e7f2ea;
  --warn: #a6432b;
  --warn-bg: #f7e9e3;
  --caution: #8a6d1f;
  --caution-bg: #fdf3d9;
  --focus: #2f6b44;

  /* Variance-cell gradient hues (dash_app_filters.calculate_gradient_color).
     Protected/semantic like --ok/--warn - same hue in both themes, only the
     --paper they blend toward via color-mix() changes. */
  --variance-negative: #41a4ff;
  --variance-positive: #de6a73;

  /* Bootstrap's .btn-close icon is a hardcoded black SVG (fill #000) with no
     CSS-variable hook in 5.0.2, so it can't be retoned via --ink like everything
     else - the filter is the only lever. Same fix Bootstrap ships itself as
     .btn-close-white, just driven by the theme token instead of a fixed class. */
  --icon-filter: none;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ink: #ede7d9;
    --paper: #11172a;
    --paper-raised: #161d33;
    --brass: #c79b54;
    --brass-strong: #ddb46e;
    --slate: #a2a8b8;
    --rule: #2b3350;
    --ok: #5fae79;
    --ok-bg: #16241b;
    --warn: #e08064;
    --warn-bg: #2c1a17;
    --caution: #e0b34c;
    --caution-bg: #2c2410;
    --focus: #5fae79;
    --icon-filter: invert(1) grayscale(100%) brightness(200%);
  }
}

:root[data-theme="dark"] {
  --ink: #ede7d9;
  --paper: #11172a;
  --paper-raised: #161d33;
  --brass: #c79b54;
  --brass-strong: #ddb46e;
  --slate: #a2a8b8;
  --rule: #2b3350;
  --ok: #5fae79;
  --ok-bg: #16241b;
  --warn: #e08064;
  --warn-bg: #2c1a17;
  --caution: #e0b34c;
  --caution-bg: #2c2410;
  --focus: #5fae79;
  --icon-filter: invert(1) grayscale(100%) brightness(200%);
}

/*
 * Bootstrap hardcodes body { background-color: #fff; color: #212529; }. Every page's
 * own content wrapper (.vcfo-landing/.vcfo-page/.vcfo-auth/.vcfo-content) already
 * covers its own area with the right token color, but on a page shorter than the
 * viewport the leftover space below the footer falls through to this rule - white,
 * regardless of theme. Same root cause as the navbar/header/footer bugs already
 * fixed, just one layer further down; safe to set now that every page extending
 * base.html has a themed wrapper of its own to take precedence over this default.
 *
 * `html body` (not bare `body`) is load-bearing: this file loads before bootstrap.css,
 * so a plain `body` selector ties with Bootstrap's own on specificity and loses on
 * source order - exactly the .nav-link.active bug from earlier, recurring here. The
 * extra type selector bumps specificity just enough to win regardless of load order.
 */
html body {
  background: var(--paper);
  color: var(--ink);
}

/*
 * Site-wide: alert dismiss (partials/messages.html) and every modal's close
 * button (email_query.html, modal_commentary.html) all use Bootstrap's plain
 * .btn-close - a black X with no light-mode/dark-mode awareness of its own.
 * In dark mode it was rendering black-on-navy, i.e. fully invisible, not just
 * low-contrast (see the email modal screenshot this was caught from).
 */
.btn-close {
  filter: var(--icon-filter);
}

/*
 * .alert-success/-info/-warning/-danger (Bootstrap) keep their hardcoded
 * light pastel backgrounds in both themes - nothing here retones them for
 * dark mode. So the dark-mode invert above (right for modals, which sit on
 * a themed dark --paper/--paper-raised background) turns the alert's own
 * close icon near-white-on-pale-mint - low enough contrast to read as
 * invisible (see the "You have signed out." screenshot this was caught
 * from). The plain black icon already has good contrast against that
 * background regardless of theme, since the background itself never
 * changes - so opt alerts back out of the invert rather than inverting them.
 */
.alert .btn-close {
  filter: none;
}

/*
 * templates/partials/header.html - the page-title banner shared by ~14 templates
 * (budgets, accounts, data_exchange). Was hardcoded Bootstrap bg-dark/text-light,
 * always dark regardless of theme - the same "navbar doesn't tie in" mismatch this
 * whole theming effort started from, just in a different component.
 */
.site-page-header {
  background: var(--paper-raised);
  color: var(--ink);
  border-bottom: 1px solid var(--rule);
}
/* Scoped to the header itself, not left to whichever page-wrapper class happens to
   surround it (.vcfo-page had its own .btn-outline-secondary rule; .vcfo-auth/.vcfo-content
   never did, so the same header markup rendered as plain unthemed Bootstrap grey on those
   pages - the back button should look identical everywhere regardless of what body style
   the rest of the page uses). */
.site-page-header .btn-outline-secondary {
  color: var(--slate);
  border-color: var(--rule);
}
.site-page-header .btn-outline-secondary:hover {
  background: var(--paper);
  color: var(--ink);
  border-color: var(--rule);
}

/*
 * templates/partials/footer.html - lives directly in <body>, outside every page's
 * own content_wrapper_class div, so it never got any theme treatment at all and sat
 * on the raw (white) body background on every single page - the white strip visible
 * at the bottom of every screenshot this whole session. Same root cause as
 * .site-page-header, just never traced back this far until now.
 */
.site-footer {
  background: var(--paper-raised);
  border-top: 1px solid var(--rule);
}
.site-footer, .site-footer a { color: var(--slate); }

/*
 * Theme-swapped image pairs: pair a .theme-img-light and .theme-img-dark
 * <img> in markup, this shows/hides them to match this file's own
 * precedence (prefers-color-scheme default, [data-theme] override).
 */
.theme-img-dark {
  display: none;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-img-light {
    display: none;
  }

  :root:not([data-theme="light"]) .theme-img-dark {
    display: inline-block;
  }
}

:root[data-theme="dark"] .theme-img-light {
  display: none;
}

:root[data-theme="dark"] .theme-img-dark {
  display: inline-block;
}

/*
 * Subtle "lift off the page" treatment for hero/placeholder screenshots
 * (Power BI-style card shadow) - two layers, a tight low-blur one for edge
 * definition plus a wider soft one for depth, rather than one flat shadow.
 * Dark mode gets a lighter touch: shadows read heavier against --paper's
 * dark navy than against light paper, so full-strength values would look
 * like a black smudge instead of a lift.
 */
.theme-img-shadow {
  border-radius: 8px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12), 0 12px 28px rgba(0, 0, 0, 0.14);
}

:root[data-theme="dark"] .theme-img-shadow {
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25), 0 12px 24px rgba(0, 0, 0, 0.3);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-img-shadow {
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25), 0 12px 24px rgba(0, 0, 0, 0.3);
  }
}
.site-footer a:hover { color: var(--brass-strong); }
