/* ── RDS Brand Variables ────────────────────────────────────────────────── */
:root {
  --rds-navy:       #172033;
  --rds-slate:      #2F3A4A;
  --rds-gray:       #64748B;
  --rds-light-gray: #E2E8F0;
  --rds-off-white:  #F8FAFC;
  --rds-white:      #FFFFFF;

  --rds-teal:       #14B8A6;
  --rds-teal-dark:  #0d9488;
  --rds-blue:       #2563EB;
  --rds-amber:      #F59E0B;
  --rds-red:        #DC2626;
  --rds-green:      #16A34A;
  --rds-border:     #E2E8F0;
}

/* ── Global typography ──────────────────────────────────────────────────── */
body {
  letter-spacing: -0.005em;
}

h1, h2, h3, h4, h5, h6 {
  letter-spacing: -0.025em;
}

/* ── Navbar ─────────────────────────────────────────────────────────────── */
.navbar {
  box-shadow: 0 2px 12px rgba(23, 32, 51, 0.18);
  min-height: 56px;
  padding-top: 0.35rem;
  padding-bottom: 0.35rem;
}

.navbar-brand {
  font-weight: 600;
  padding-top: 0.25rem;
  padding-bottom: 0.25rem;
}

.navbar-brand img {
  max-height: 32px;
  width: auto;
}

/* bslib::input_dark_mode()'s icon color derives from --bs-emphasis-color /
   --bs-tertiary-color (page-level text colors, set inline on the element
   itself), which correctly flips between light/dark theme -- but the
   navbar's own background stays dark navy in *both* modes by design (see
   rds_theme()/rds_theme_dark()), so in light mode the icon inherits the
   light theme's dark navy text color and blends invisibly into the dark
   navbar. In dark mode it happens to look right only by coincidence
   (dark theme's emphasis-color is light, which also suits the navbar).
   Force it to always use a light color, independent of site theme mode. */
.navbar bslib-input-dark-mode {
  --bs-emphasis-color: #F8FAFC;
  --bs-tertiary-color: rgba(248, 250, 252, 0.6);
}

/* Active nav tab accent in teal */
.nav-underline .nav-link.active {
  border-bottom-color: var(--rds-teal);
  font-weight: 600;
  color: var(--rds-teal) !important;
}

/* ── Cards ──────────────────────────────────────────────────────────────── */
.card {
  border-color: var(--rds-border);
  border-radius: 0.75rem;
  box-shadow: 0 4px 16px rgba(23, 32, 51, 0.06);
}

.card:hover {
  box-shadow: 0 6px 20px rgba(23, 32, 51, 0.10);
  transition: box-shadow 0.2s ease;
}

.card-header {
  font-weight: 600;
  background-color: var(--rds-off-white);
  border-bottom-color: var(--rds-border);
}

/* Card header icon vertical alignment */
.card-header .bi {
  vertical-align: -0.1em;
}

/* Interpretation card prose */
.card-body p {
  line-height: 1.65;
  margin-bottom: 0.6rem;
}
.card-body p:last-child {
  margin-bottom: 0;
}

/* ── Value boxes ────────────────────────────────────────────────────────── */
.bslib-value-box {
  border-radius: 0.75rem;
  box-shadow: 0 4px 16px rgba(23, 32, 51, 0.06);
}

.bslib-value-box .value-box-title {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* ── Buttons ────────────────────────────────────────────────────────────── */
.btn-primary {
  background-color: var(--rds-teal);
  border-color: var(--rds-teal);
  color: var(--rds-navy);
  font-weight: 600;
}

.btn-primary:hover,
.btn-primary:focus {
  background-color: var(--rds-teal-dark);
  border-color: var(--rds-teal-dark);
  color: var(--rds-navy);
}

.btn-outline-primary {
  color: var(--rds-teal-dark);
  border-color: var(--rds-teal);
}

.btn-outline-primary:hover {
  background-color: var(--rds-teal);
  border-color: var(--rds-teal);
  color: var(--rds-navy);
}

/* ── Form controls ──────────────────────────────────────────────────────── */
.form-control:focus,
.form-select:focus {
  border-color: var(--rds-teal);
  box-shadow: 0 0 0 0.2rem rgba(20, 184, 166, 0.2);
}

/* ── Decision-point callout (amber accent) ──────────────────────────────── */
.decision-point {
  border-left: 4px solid var(--rds-amber);
  background: #FEF3C7;
  color: var(--rds-navy);
  padding: 1rem 1.25rem;
  border-radius: 0.75rem;
  margin: 1.5rem 0;
}

/* ── Inline code ────────────────────────────────────────────────────────── */
code {
  background-color: #EEF2F7;
  color: var(--rds-slate);
  border-radius: 0.25rem;
  padding: 0.1em 0.35em;
}

/* ── Muted placeholder panels ───────────────────────────────────────────── */
.text-center.text-muted.py-5 {
  padding: 4rem 2rem;
}
.text-center.text-muted.py-5 .bi {
  font-size: 2.5rem;
  display: block;
  margin-bottom: 0.75rem;
  opacity: 0.4;
}

/* ── DT table focus ─────────────────────────────────────────────────────── */
.dataTables_wrapper .dataTables_filter input:focus {
  border-color: var(--rds-teal);
  box-shadow: 0 0 0 0.2rem rgba(20, 184, 166, 0.2);
}

/* ── Dark mode ──────────────────────────────────────────────────────────── */
/* All --bs- and --rds- dark-mode variable overrides live here, in a plain
   always-linked stylesheet, rather than being pushed via
   session$setCurrentTheme()/rds_theme_dark() the way they originally were.
   That approach had two confirmed-live problems: (1) session's
   setCurrentTheme() call makes bslib tear down and re-fetch all six theme
   stylesheets (bootstrap.min.css, both Google Fonts, bslib-component-css,
   selectize.css, shiny-sass.css) with a fresh cache-busting query string on
   every single dark-mode toggle -- a real network round-trip for the whole
   bundle, not just the changed variables, and the actual cause of the
   reported light/dark toggle flicker; (2) the login page's equivalent
   static-<style>-in-head_auth workaround (see .dark_mode_css_rules() in
   app_ui.R, still used by the login/signup/reset pages, which aren't
   wrapped in this app_ui() and so can't load custom.css the normal way)
   does NOT survive shinymanager's login -> authenticated-app transition --
   confirmed live via document.styleSheets that head_auth's injected
   overrides are simply gone by the time the real app renders. custom.css
   is immune to both: it's a normal <link>, present from first paint,
   untouched by any of bslib's session-theme machinery. No !important
   needed -- confirmed via the live DOM that this file's <link> already
   loads after bootstrap.min.css's, so plain cascade order wins the
   selector tie on equal specificity. The navbar is intentionally excluded
   from the --bs-* overrides below -- it's already dark-navy in the light
   theme, so it reads correctly unchanged. */
[data-bs-theme="dark"] {
  --rds-off-white:  #0F172A;
  --rds-white:      #1E293B;
  --rds-light-gray: #334155;
  --rds-border:     #334155;
  --rds-gray:       #94A3B8;
  color-scheme: dark;
  --bs-body-bg: #0F172A;
  --bs-body-color: #E2E8F0;
  --bs-emphasis-color: #E2E8F0;
  --bs-heading-color: #E2E8F0;
  --bs-secondary: #64748B;
  --bs-secondary-rgb: 100, 116, 139;
  --bs-secondary-color: rgba(226, 232, 240, 0.75);
  --bs-secondary-color-rgb: 226, 232, 240;
  --bs-secondary-bg: #1E293B;
  --bs-tertiary-bg: #1E293B;
  --bs-border-color: #334155;
  --bs-link-color: #2DD4BF;
  --bs-link-hover-color: #5EEAD4;
  --bs-code-color: #CBD5E1;
  --bs-code-bg: #1E293B;
}

[data-bs-theme="dark"] .card,
[data-bs-theme="dark"] .bslib-value-box {
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);
}

[data-bs-theme="dark"] .card:hover {
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.5);
}

/* .btn-outline-secondary's color is compiled from a Sass variable at build
   time, not a runtime CSS custom property -- overriding --bs-secondary
   above doesn't reach it, so it needs its own explicit override here. */
[data-bs-theme="dark"] .btn-outline-secondary {
  color: #94A3B8;
  border-color: #64748B;
}
[data-bs-theme="dark"] .btn-outline-secondary:hover {
  color: #E2E8F0;
  background-color: #334155;
  border-color: #64748B;
}

[data-bs-theme="dark"] .decision-point {
  background: rgba(245, 158, 11, 0.15);
  color: #E2E8F0;
}

[data-bs-theme="dark"] code {
  background-color: var(--rds-white);
  color: #CBD5E1;
}

/* Upload tab's footer logo (mod_upload.R) is a fixed dark-navy SVG with no
   dark-mode variant -- brightness(0) flattens it to solid black regardless
   of its original colors, then invert(1) flips that to white, so it reads
   as a soft light watermark against the dark background (parent div's own
   opacity: 0.55 already keeps it subtle in both modes). */
[data-bs-theme="dark"] .footer-logo {
  filter: brightness(0) invert(1);
}

/* ── Consolidated nav bar (Back/Next/Submit + step indicator + Save/Load) ── */
/* Rendered exactly once, centrally, by app_server.R's output$main_nav_footer
   (see app_ui.R's page_navbar(header = ...)) -- every tab module still owns
   its own Back/Next/Submit buttons and observeEvent()s, it just returns them
   via a `nav_footer` reactive instead of rendering them in its own content,
   so only the active tab's version is ever mounted here.
   Pinning is JS-driven (see golem_add_external_resources()'s nav-pin script
   in app_ui.R), not a plain CSS `position: sticky`. sticky was tried first
   and looked right on short pages, but its "containing block" is the
   nearest block/flex ancestor's own box -- which for a nav_panel's content
   here is a bslib fill container sized to fit the viewport (~660px), not
   the full scrollable page. On any tab with content taller than that (e.g.
   Edit with many transactions), the bar detaches once scrolled past that
   point and scrolls away entirely -- confirmed live, and reliably
   reproduced by the guided tour's own scroll-into-view for a step whose
   target lives in this bar. The `.tour-nav-pinned` class below is toggled
   by that script based on the real navbar's position, with a placeholder
   div inserted to hold the bar's normal-flow height so content doesn't
   jump when it switches to fixed. Still safe against full_screen card
   overlays -- bslib's full-screen z-index is far higher than this, so an
   expanded chart/table still correctly covers the bar while open.

   `!important` on .tour-nav-pinned's `position: fixed` below (added
   2026-08-12) is required, not decorative: driver.js applies its own
   `.driver-position-relative { position: relative !important; }` to
   whatever element it's currently highlighting (confirmed by inspecting
   driver.min.css/js directly -- used for the highlight overlay's stacking
   context). Without a matching !important here, driver.js's rule always
   wins regardless of our higher selector specificity (2 classes vs. 1) --
   !important beats specificity entirely, at any tier. The visible bug:
   whenever a tour step's target lives in this bar *while pinned* (i.e.
   scrolled past the real navbar), the bar was silently forced out of
   position: fixed back into its normal document-flow position the moment
   driver.js highlighted it, landing the highlight box wherever that
   happened to fall instead of on the actual visible button -- e.g. the
   Review & Edit tab's "Continue" step, confirmed live landing over the
   Customize Category Labels sidebar instead of the pinned Next button. */
.tour-nav-footer {
  z-index: 20;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
  padding: 0.6rem 1rem;
  background-color: var(--rds-white);
  border-bottom: 1px solid var(--rds-border);
  box-shadow: 0 2px 8px rgba(23, 32, 51, 0.06);
}

.tour-nav-footer.tour-nav-pinned {
  position: fixed !important;
  top: 0;
  left: 0;
  right: 0;
}

.tour-nav-footer-steps {
  display: flex;
  align-items: center;
  gap: 1.1rem;
}

.tour-nav-footer-extra {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-left: auto;
  padding-left: 1rem;
  border-left: 1px solid var(--rds-border);
}

/* When there's no back/forward pair, .tour-nav-footer-buttons is empty and
   margin-left: auto on -extra already pushes it to the right on its own --
   this only matters when both groups are present. */
.tour-nav-footer-buttons:empty {
  display: none;
}

.tour-nav-step {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.78rem;
  color: var(--rds-gray);
  opacity: 0.55;
}

.tour-nav-step-complete {
  color: var(--rds-teal-dark);
  opacity: 1;
}

.tour-nav-step-current {
  color: var(--rds-navy);
  font-weight: 600;
  opacity: 1;
}

.tour-nav-footer-buttons {
  display: flex;
  gap: 0.5rem;
  margin-left: auto;
}

[data-bs-theme="dark"] .tour-nav-footer {
  background-color: var(--rds-white);
  border-bottom-color: var(--rds-border);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
}

[data-bs-theme="dark"] .tour-nav-step-current {
  color: #f8fafc;
}

/* Shiny notifications (bootstrap.min.css's high-specificity
   #shiny-notification-panel#shiny-notification-panel rule pins these to
   z-index: 1090) render underneath driver.js's tour-highlight overlay
   (.driver-highlighted-element sits at z-index: 100004, confirmed live) --
   any notification fired while a tour is active, e.g. the demo-mode
   "loaded sample data" toast in mod_upload.R, showed up as near-invisible
   dim text behind the dimming overlay. !important is needed to out-rank
   that higher-specificity double-id selector. */
#shiny-notification-panel {
  z-index: 100010 !important;
}
