:root {
  --brand-purple: #5b2a86;
  --brand-purple-dark: #3d1c5c;
  --brand-purple-darker: #2a1240;

  /* Status palette (validated, fixed - see dataviz skill references/palette.md) */
  --status-good: #0ca30c;
  --status-good-bg: #e5f6e5;
  --status-warning: #fab219;
  --status-warning-bg: #fef3de;
  --status-serious: #ec835a;
  --status-serious-bg: #fdece4;
  --status-critical: #d03b3b;
  --status-critical-bg: #fbe7e7;

  /* Back-compat aliases used by earlier views */
  --ok-green: var(--status-good);
  --ok-bg: var(--status-good-bg);
  --review-amber: #a1650b;
  --review-bg: var(--status-warning-bg);
  --investigate-red: var(--status-critical);
  --investigate-bg: var(--status-critical-bg);

  /* Chart chrome */
  --chart-grid: #e1e0d9;
  --chart-axis: #c3c2b7;
  --chart-text: #52514e;
  --chart-muted: #898781;

  /* Categorical series (fixed order - never re-cycled) */
  --series-1: #2a78d6; /* blue */
  --series-2: #eb6834; /* orange */
  --series-3: #1baf7a; /* aqua */
  --series-4: #eda100; /* yellow */
}

html, body {
  height: 100%;
}

body {
  background-color: #f4f2f8;
}

/* ----- Sidebar layout shell ----- */
.app-shell {
  display: flex;
  min-height: 100vh;
  /* Not "stretch": the sidebar pins its own height via position: sticky (see the >=lg rule
     below), so it no longer needs the parent to force app-main to match its height. Stretching
     here was making app-main (and any height:100% child inside it, like a lone .chart-card)
     balloon to fill the full viewport even on short pages, leaving dead space under content
     and pushing the footer down far past where the actual content ends. */
  align-items: flex-start;
}

.app-sidebar {
  --bs-offcanvas-width: 260px;
  width: 260px;
  flex: 0 0 260px;
  background: linear-gradient(180deg, var(--brand-purple), var(--brand-purple-dark) 70%, var(--brand-purple-darker));
  color: #fff;
  display: flex;
  flex-direction: column;
}

/* At >=lg the offcanvas is docked inline (not fixed/overlay) - make it sticky so it stays
   visible for the height of the viewport without depending on flex stretch matching the
   (often much taller) main content column. */
@media (min-width: 992px) {
  .app-sidebar {
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
  }
}

.app-sidebar-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
  padding: 1.1rem 1.1rem .9rem;
  border-bottom: 1px solid rgba(255,255,255,.12);
  flex-shrink: 0;
}

.app-sidebar-brand {
  color: #fff;
  text-decoration: none;
  font-weight: 700;
  font-size: 1.05rem;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .4rem;
  line-height: 1.2;
}

.app-sidebar-brand:hover {
  color: #fff;
}

.app-sidebar-body {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  padding: .9rem .7rem;
}

.app-sidebar-nav {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: .15rem;
  flex: 1 1 auto;
}

.app-nav-link {
  display: flex;
  align-items: center;
  gap: .65rem;
  padding: .6rem .75rem;
  border-radius: 8px;
  color: rgba(255,255,255,.82);
  text-decoration: none;
  font-weight: 500;
  font-size: .93rem;
  transition: background-color .12s ease, color .12s ease;
}

.app-nav-icon {
  display: inline-flex;
  flex-shrink: 0;
  opacity: .85;
}

/* Groups sidebar links by module (Financial Control, Library, ...) once there's more than one. */
.app-nav-section {
  padding: .9rem .75rem .25rem;
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: rgba(255,255,255,.45);
}

.app-nav-section:first-child {
  padding-top: .25rem;
}

.app-nav-link:hover {
  background-color: rgba(255,255,255,.1);
  color: #fff;
}

.app-nav-link.active {
  background-color: rgba(255,255,255,.16);
  color: #fff;
  box-shadow: inset 3px 0 0 #fff;
}

.app-main {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-width: 0;
  /* Independent of .app-shell's align-items (kept flex-start - see above), this guarantees
     app-main's own column layout is at least one viewport tall. That's what lets
     .app-content's flex-grow below push the footer down to the bottom of the screen on a
     SHORT page, without going through .app-shell's stretch (which is what caused the old
     lone-chart-card-balloons-to-full-height bug) and without ever capping app-main's height
     on a LONG page - min-height only ever adds height, never removes it. */
  min-height: 100vh;
}

.app-content {
  /* flex-grow (fills any leftover space below short content, pushing the footer to the
     bottom of the viewport) but never shrinks below its own content's natural height. This
     is the standard "flexbox sticky footer" recipe: the footer is normal, non-fixed,
     in-flow content that only ever appears ONCE, right after the real content ends - never
     floating on top of it. See footer.footer below for the history of why this replaced a
     position:fixed footer, which is what "the footer scrolls with the page" was reporting. */
  flex: 1 0 auto;
  padding: 0 1.5rem 1.5rem;
}

/* ----- Persistent top bar (page context + signed-in user) ----- */
.app-topbar {
  background: #fff;
  color: var(--brand-purple-darker);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  padding: .7rem 1.25rem;
  border-bottom: 1px solid #e7e3ee;
  box-shadow: 0 1px 3px rgba(60, 20, 90, .04);
  flex-wrap: wrap;
  row-gap: .5rem;
}

.app-topbar-left {
  display: flex;
  align-items: center;
  gap: .75rem;
  min-width: 0;
}

.app-topbar-title {
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--brand-purple-darker);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.app-topbar-right {
  display: flex;
  align-items: center;
  gap: .85rem;
  flex-wrap: wrap;
}

.app-topbar-date {
  color: var(--chart-muted);
  font-size: .85rem;
}

.app-topbar-divider {
  width: 1px;
  height: 1.1rem;
  background: #e0dce8;
}

.app-topbar-user {
  display: flex;
  align-items: center;
  gap: .5rem;
}

.app-topbar-user-name {
  font-weight: 600;
  font-size: .88rem;
  color: #333;
}

.app-topbar-toggle {
  background: #f1eaf8;
  border: 1px solid #e0d3ef;
  border-radius: 6px;
  padding: .35rem .5rem;
  line-height: 1;
  color: var(--brand-purple);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.app-sidebar-logo {
  height: 38px;
  width: 38px;
  object-fit: contain;
  background: #fff;
  border-radius: 50%;
  padding: 2px;
  flex-shrink: 0;
}

.role-badge {
  background-color: #f1eaf8;
  color: var(--brand-purple);
  font-weight: 600;
}

/* ----- Login page ----- */
.login-body {
  background: linear-gradient(135deg, var(--brand-purple-darker), var(--brand-purple));
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
}

.login-card {
  background: #fff;
  border-radius: 14px;
  padding: 2.5rem;
  width: 100%;
  max-width: 400px;
  box-shadow: 0 20px 50px rgba(0,0,0,.25);
  margin: 1rem;
}

.login-brand {
  text-align: center;
}

.login-logo {
  display: inline-block;
  height: 84px;
  width: 84px;
  object-fit: contain;
  margin-bottom: .75rem;
}

.btn-brand {
  background-color: var(--brand-purple);
  border-color: var(--brand-purple);
  color: #fff;
}

.btn-brand:hover, .btn-brand:focus {
  background-color: var(--brand-purple-dark);
  border-color: var(--brand-purple-dark);
  color: #fff;
}

/* ----- Cards / sections ----- */
.control-card {
  border: none;
  border-radius: 12px;
  box-shadow: 0 2px 10px rgba(60, 20, 90, .06);
}

.section-header {
  background: var(--brand-purple);
  color: #fff;
  padding: .6rem 1rem;
  border-radius: 10px 10px 0 0;
  font-weight: 600;
}

.section-subheader {
  background: var(--brand-purple-dark);
  color: #fff;
  padding: .5rem 1rem;
  font-weight: 600;
}

/* ----- Status badges ----- */
.badge.status-ok {
  background-color: var(--ok-bg);
  color: var(--ok-green);
  font-weight: 600;
}

.badge.status-review {
  background-color: var(--review-bg);
  color: var(--review-amber);
  font-weight: 600;
}

.badge.status-investigate {
  background-color: var(--investigate-bg);
  color: var(--investigate-red);
  font-weight: 600;
}

.status-pill {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .35rem .9rem;
  border-radius: 999px;
  font-weight: 700;
  font-size: .95rem;
}

.status-pill.reconciled {
  background-color: var(--ok-bg);
  color: var(--ok-green);
}

.status-pill.attention {
  background-color: var(--investigate-bg);
  color: var(--investigate-red);
}

.status-dot {
  width: .6rem;
  height: .6rem;
  border-radius: 50%;
  display: inline-block;
}

.status-dot.green { background-color: var(--ok-green); }
.status-dot.red { background-color: var(--investigate-red); }

/* ----- Today's card ----- */
.today-card {
  border-radius: 16px;
  overflow: hidden;
}

.today-card .card-header {
  background: linear-gradient(120deg, var(--brand-purple), var(--brand-purple-dark));
  color: #fff;
  padding: 1rem 1.5rem;
}

.metric-row {
  display: flex;
  justify-content: space-between;
  padding: .55rem 0;
  border-bottom: 1px solid #eee;
}

.metric-row:last-child {
  border-bottom: none;
}

.metric-label {
  color: #555;
}

.metric-value {
  font-weight: 700;
}

/* ----- Tabs ----- */
.control-tabs .nav-link {
  color: var(--brand-purple-dark);
  font-weight: 600;
}

.control-tabs .nav-link.active {
  background-color: var(--brand-purple);
  color: #fff;
}

.table-sm td, .table-sm th {
  vertical-align: middle;
}

footer.footer {
  /* Deliberately NOT position:fixed. A fixed footer is glued to the viewport for the entire
     time the user scrolls, which means it permanently overlaps whatever content happens to
     be at the bottom of the CURRENT screen - on every page, the whole way through, not just
     at the true end of the document. That is exactly what "the footer scrolls with the
     page" was reporting, and it's also what caused the original "footer overshadows the Add
     button on a long list" complaint: a fixed footer overlapping content is what it does by
     definition, not a bug that can be padded away.
     Instead this is a normal, in-flow element - it only ever appears ONCE, right after the
     real page content ends. .app-main/.app-content above (the flexbox "sticky footer"
     recipe) push it down to the bottom of the viewport on a SHORT page so it still looks
     anchored there, but on a LONG page it simply sits after the last piece of content and
     is never fixed on top of anything. */
  background: #fff;
  border-top: 1px solid #e7e3ee;
  padding: .65rem 1.5rem;
  font-size: .85rem;
  flex-shrink: 0;
  /* Single line even on narrow phones - purely cosmetic now, not load-bearing for layout. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ----- Stat tiles (Reports / Dashboard insights) ----- */
.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: .9rem;
}

.stat-tile {
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 2px 10px rgba(60, 20, 90, .06);
  padding: 1rem 1.1rem;
}

.stat-tile .stat-label {
  font-size: .78rem;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--chart-muted);
  font-weight: 600;
}

.stat-tile .stat-value {
  font-size: 1.6rem;
  font-weight: 700;
  color: #1c1c1c;
  margin-top: .15rem;
  font-variant-numeric: tabular-nums;
}

.stat-tile .stat-sub {
  font-size: .8rem;
  color: var(--chart-text);
  margin-top: .25rem;
}

.stat-delta {
  display: inline-flex;
  align-items: center;
  gap: .2rem;
  font-weight: 600;
  font-size: .82rem;
}

.stat-delta.up { color: var(--status-good); }
.stat-delta.down { color: var(--status-critical); }
.stat-delta.flat { color: var(--chart-muted); }

/* ----- Chart cards ----- */
.chart-card {
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 2px 10px rgba(60, 20, 90, .06);
  padding: 1rem 1.1rem 1.2rem;
  height: 100%;
}

.chart-card .chart-title {
  font-weight: 700;
  font-size: .95rem;
  color: #1c1c1c;
  margin-bottom: .1rem;
}

.chart-card .chart-subtitle {
  font-size: .8rem;
  color: var(--chart-muted);
  margin-bottom: .6rem;
}

.chart-card canvas {
  max-width: 100%;
}

/* Caps a tall chart card's visible height and scrolls internally instead of growing the page -
   used for the Library Usage by Class chart, whose canvas height scales with the class count. */
.chart-scroll-area {
  max-height: 420px;
  overflow-y: auto;
  overflow-x: hidden;
}

.chart-legend-list {
  list-style: none;
  padding: 0;
  margin: .6rem 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: .5rem 1rem;
  font-size: .82rem;
}

.chart-legend-list li {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  color: var(--chart-text);
}

.chart-legend-swatch {
  width: .65rem;
  height: .65rem;
  border-radius: 3px;
  display: inline-block;
  flex-shrink: 0;
}

/* ----- Date range filter pills ----- */
.filter-pills {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  align-items: center;
}

.filter-pills .btn {
  border-radius: 999px;
  font-size: .82rem;
  padding: .3rem .85rem;
}

/* ----- Balance sheet ----- */
.balance-sheet-table td.net-positive { color: var(--status-good); font-weight: 700; }
.balance-sheet-table td.net-negative { color: var(--status-critical); font-weight: 700; }
.balance-sheet-table tfoot td { font-weight: 700; border-top: 2px solid #ddd; }

.balance-sheet-point-row { cursor: pointer; }
.balance-sheet-point-row:hover { background-color: rgba(0, 0, 0, .035); }
.balance-sheet-chevron { display: inline-block; transition: transform .15s ease; width: 1em; }
.balance-sheet-point-row[aria-expanded="true"] .balance-sheet-chevron { transform: rotate(90deg); }
.balance-sheet-breakdown { background-color: rgba(0, 0, 0, .02); }
.balance-sheet-breakdown table { background: transparent; }

.insight-card {
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 2px 10px rgba(60, 20, 90, .06);
  padding: .9rem 1.1rem;
  display: flex;
  align-items: flex-start;
  gap: .75rem;
}

.insight-icon {
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #f1eaf8;
  color: var(--brand-purple);
  font-weight: 700;
  flex-shrink: 0;
}
