/*
 * style.css
 *
 * Project-wide stylesheet, loaded after Bootstrap so its rules can
 * override Bootstrap defaults where needed.
 *
 * PHASE 8 (2026-08-29) - EduBudgetPro Design System. Everything below the
 * :root token block works by overriding Bootstrap 5.3's OWN CSS custom
 * properties (--bs-primary, --bs-success, --bs-warning, --bs-body-bg,
 * --bs-border-color, --bs-secondary-color/--bs-link-color, and the
 * "-bg-subtle"/"-border-subtle"/"-text-emphasis" triads Bootstrap derives
 * its .btn-*, .text-bg-*, .alert-*, .text-muted utilities from) rather than
 * hand-editing every template - the app already uses plain Bootstrap
 * classes almost everywhere (btn/btn-*, card, badge/text-bg-*, table,
 * alert-*, text-muted), so redefining the variables those classes already
 * read from gives brand-consistent buttons, badges, cards, tables and
 * alerts across all ~130 templates without touching each one. Templates
 * are only edited directly where an actual STRUCTURAL/markup change is
 * needed (page headers, KPI cards, filter panels) - never just to swap a
 * color Bootstrap's own variable cascade already carries.
 *
 * --bs-danger is DELIBERATELY left untouched everywhere in this file -
 * true error/reject/destructive red must never be reskinned toward the
 * brand's orange or any other hue (see design-system spec's own "Do NOT
 * replace true error red with orange").
 */

:root {
    /* Brand palette */
    --color-navy-dark: #052943;
    --color-navy: #073855;
    --color-blue-medium: #084A6D;
    --color-blue: #0688C6;
    --color-blue-accent: #056194;

    --color-orange: #EB720A;
    --color-orange-dark: #C64E06;

    --color-green: #63B62E;
    --color-green-dark: #3E7F30;

    --color-gold: #F4A105;

    /* Neutrals */
    --color-bg: #F5F7F9;
    --color-surface: #FFFFFF;
    --color-text: #263746;
    --color-muted: #667784;
    --color-border: #DCE3E8;
    --color-border-strong: #C8D2DA;

    /* -- Bootstrap variable overrides -----------------------------------
       Only primary/success/warning are remapped - secondary/info/danger
       are deliberately left at Bootstrap's own defaults: secondary's
       neutral gray is exactly what "DRAFT"/"Not Loaded"/"Budget Not
       Available" badges need (spec section 13/19 - never recolor these
       toward blue), and danger must stay true red (see file header note
       above). */
    --bs-body-bg: var(--color-bg);
    --bs-body-color: var(--color-text);
    --bs-border-color: var(--color-border);
    --bs-secondary-color: var(--color-muted);
    /* Link TEXT color uses --color-blue-accent, not the brighter
       --color-blue - normal-size text needs 4.5:1 contrast on white
       (WCAG AA); --color-blue only reaches ~3.9:1 there (fine for
       buttons/badges/borders, which only need the 3:1 "UI component"
       threshold, but not safe for ordinary link text). See spec section
       26's own "check contrast carefully" instruction. */
    --bs-link-color: var(--color-blue-accent);
    --bs-link-color-rgb: 5, 97, 148;
    --bs-link-hover-color: var(--color-navy);
    --bs-link-hover-color-rgb: 7, 56, 85;
    --bs-focus-ring-color: rgba(6, 136, 198, 0.35);

    /* Cards/tables/dropdowns default to --bs-body-bg in Bootstrap 5.3 -
       pinned back to the white "surface" token so they stay visually
       distinct from the page background rather than blending into it. */
    --bs-card-bg: var(--color-surface);
    --bs-dropdown-bg: var(--color-surface);
    --bs-tooltip-bg: var(--color-navy-dark);

    --bs-primary: var(--color-blue);
    --bs-primary-rgb: 6, 136, 198;
    --bs-primary-text-emphasis: var(--color-blue-accent);
    --bs-primary-bg-subtle: #DBEFF8;
    --bs-primary-border-subtle: #A9D8EC;

    /* Solid success (.btn-success/.text-bg-success) uses the DARKER
       green, not the bright one - white-on-#63B62E fails WCAG contrast
       (~2.5:1); white-on-#3E7F30 passes (~4.9:1). Bright green remains
       available as var(--color-green) for accents/borders/large text
       only (spec section 26's own accessibility note). */
    --bs-success: var(--color-green-dark);
    --bs-success-rgb: 62, 127, 48;
    --bs-success-text-emphasis: var(--color-green-dark);
    --bs-success-bg-subtle: #E6F3DC;
    --bs-success-border-subtle: #BFE0A6;

    --bs-warning: var(--color-orange);
    --bs-warning-rgb: 235, 114, 10;
    --bs-warning-text-emphasis: var(--color-orange-dark);
    --bs-warning-bg-subtle: #FCE7D3;
    --bs-warning-border-subtle: #F5BD86;

    /* --bs-info deliberately NOT overridden: Bootstrap 5.3 bakes
       .text-bg-info's TEXT color to #000 at build time (computed once
       against Bootstrap's own default light-cyan info, not a variable) -
       pairing that fixed black text with a dark navy/blue background via
       a --bs-info override would produce illegible dark-on-dark badges.
       The GENERATED status badge (app/shared/status_labels.py) keeps
       Bootstrap's default info cyan rather than risk that. */
}

/* Flex page shell (spec "footer positioning") - keeps the footer at the
   bottom of the viewport on short pages without pinning it over content
   on long ones; main simply grows to fill any remaining space and long
   reports scroll past it normally. Sticky-top on the navbar is unaffected
   - position:sticky only cares about the scrolling viewport, not whether
   its parent is a flex container. */
body {
    background-color: var(--color-bg);
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

main {
    flex: 1 0 auto;
}

.navbar-brand {
    font-weight: 600;
}

/* Accessible focus indicator (spec section 26) - visible on every
   interactive element, not just form controls Bootstrap already outlines. */
:focus-visible {
    outline: 2px solid var(--color-blue);
    outline-offset: 2px;
}

/* Bootstrap 5.3 locally re-declares --bs-card-bg ON .card itself
   (defaulting to var(--bs-body-bg)) rather than reading a :root-level
   value directly - a :root override alone is shadowed by that closer
   declaration, so it must be set here too to make cards genuinely white
   (surface token) rather than picking up the page background tint. */
.card {
    --bs-card-bg: var(--color-surface);
    border: 1px solid var(--color-border);
    box-shadow: 0 1px 2px rgba(7, 56, 85, 0.05);
}

/* ---------------------------------------------------------------------
   Application shell branding (navbar) - see app/templates/base.html.
   --------------------------------------------------------------------- */

/* PHASE 8 (2026-08-30): sticky-top (Bootstrap utility - position:
   sticky; top:0; z-index:1020) rather than position:fixed - it stays in
   normal document flow until it would scroll past the top of the
   viewport, so no manual body/main padding compensation is ever needed
   (fixed positioning would require that). The navbar's own descendants
   (dropdown-menus, the mobile collapse panel) are composited within its
   stacking context, so they render above ordinary page content
   automatically - no extra z-index tuning needed anywhere else. A small
   shadow reinforces the "floating above scrolled content" separation
   without a heavy visual effect. */
.navbar.bg-navy {
    background-color: var(--color-navy);
    box-shadow: 0 1px 4px rgba(5, 41, 67, 0.25);
}

/* Official Missions of Hope International wordmark (app/static/images/
   logo.png) sits to the LEFT of the tagline, vertically centered. The
   logo image itself already contains the org name and its coloured
   "HOPE" O - it is never recreated in CSS/text (see
   app/static/images/README.md). navbar-brand-name below is a plain-text
   FALLBACK only, rendered when navbar_logo_exists is false (e.g. the
   asset file is missing) - see app/templates/base.html. */
/* Stacked (logo on top, tagline below), not side-by-side - this wordmark
   is far wider than the old text-only lockup was, and a row layout was
   measured to consume ~350px extra width, enough to force "My Approval
   Tasks" onto multiple lines and roughly double the navbar's height at
   common laptop widths (1280-1920, measured via browser automation).
   Stacking keeps the lockup's total WIDTH down to the logo's own width
   (tagline is narrower and sits underneath), which was the one change
   that actually fixed the wrap - see also the container-xxl swap on the
   nav's own <div> in base.html, which gives a bit more room at the
   1280-1366 range specifically. */
.navbar-brand-lockup {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 0.1rem;
}

/* Native asset is 382x32 (an ~11.9:1 horizontal wordmark) - height is
   the constraining dimension so the logo stays crisp and readable;
   object-fit: contain guarantees no distortion even where max-width
   ends up the tighter constraint. 280x24 (desktop) was the largest size
   that measured a clean, non-wrapping single-line navbar across
   1280-1920px widths together with the stacked lockup above. */
.navbar-logo {
    height: 24px;
    width: auto;
    max-width: 280px;
    object-fit: contain;
    flex-shrink: 0;
}

.navbar-brand-text {
    display: flex;
    flex-direction: column;
    line-height: 1.15;
}

.navbar-brand-text .navbar-brand-name {
    font-weight: 700;
    font-size: 1.1rem;
    color: #fff;
}

.navbar-brand-text .navbar-brand-tagline {
    font-size: 0.7rem;
    font-weight: 400;
    color: rgba(255, 255, 255, 0.75);
    letter-spacing: 0.01em;
    line-height: 1.2;
}

/* Small screens: the lockup no longer competes with the nav-links row
   for space (they're behind the hamburger below the navbar's lg
   collapse breakpoint), but the logo still needs to stay clear of the
   toggler itself and keep the HOPE O legibly sized. */
@media (max-width: 575.98px) {
    .navbar-logo {
        height: 22px;
        max-width: 180px;
    }
}

.navbar-dark .navbar-nav .nav-link {
    transition: color 0.15s ease;
}

.navbar-dark .navbar-nav .nav-link:hover,
.navbar-dark .navbar-nav .nav-link:focus,
.navbar-dark .navbar-nav .dropdown-toggle:hover {
    color: #fff;
}

.navbar-dark .navbar-nav .nav-link.active {
    color: #fff;
    position: relative;
}

.navbar-dark .navbar-nav > .nav-item > .nav-link.active::after {
    content: "";
    position: absolute;
    left: 0.75rem;
    right: 0.75rem;
    bottom: 0;
    height: 2px;
    background-color: var(--color-blue);
    border-radius: 1px;
}

/* Same local-shadowing issue as .card above - .dropdown-menu itself
   re-declares --bs-dropdown-bg (defaulting to var(--bs-body-bg)), so the
   :root-level override alone never reaches it. Applies to every
   dropdown-menu in the app, not just the navbar's. */
.dropdown-menu {
    --bs-dropdown-bg: var(--color-surface);
}

.navbar-dark .dropdown-menu {
    border: 1px solid var(--color-border);
    box-shadow: 0 4px 12px rgba(5, 41, 67, 0.12);
}

/* Application footer - EduBudgetPro (the product) lives here, not the
   navbar; the navbar's own brand slot is reserved for the Missions of
   Hope International organisation identity. Flows after main via the
   body flex-shell above rather than any fixed/absolute positioning, so
   long reports always scroll past it naturally. */
.app-footer {
    background-color: var(--color-navy);
    text-align: center;
    padding: 0.9rem 0;
    flex-shrink: 0;
}

.app-footer-brand {
    font-size: 0.85rem;
    font-weight: 500;
    color: #fff;
}

.app-footer-mission {
    font-size: 0.8rem;
    letter-spacing: 0.02em;
    color: rgba(255, 255, 255, 0.75);
}

.navbar-dark .dropdown-item.active,
.navbar-dark .dropdown-item:active {
    background-color: var(--color-blue);
    color: #fff;
}

/* Setup dropdown compaction (2026-08-30, user-reported) - scoped to
   .setup-dropdown-menu ONLY (see app/templates/base.html's Setup <ul>) so
   the Reporting dropdown and any other dropdown-menu in the app keep
   Bootstrap's normal spacing; this is the one menu with 6 collapsible
   sections and 20+ possible links, so it is the one that genuinely
   outgrows a laptop viewport. Desktop values match the compact target
   (~0.28rem link padding, ~0.35rem header padding, ~0.2rem divider
   margin); mobile (below the navbar's own lg collapse breakpoint) keeps
   more generous touch-target padding - see the media query below. */
.setup-dropdown-menu {
    --bs-dropdown-padding-y: 0.35rem;
    /* Measured navbar height is ~3.76rem; 4.5rem leaves a small margin
       so the dropdown never touches the very bottom of the viewport. */
    max-height: calc(100vh - 4.5rem);
    overflow-y: auto;
    overflow-x: hidden;
}

.setup-dropdown-menu .dropdown-item {
    padding-top: 0.28rem;
    padding-bottom: 0.28rem;
    font-size: 0.95rem;
}

.setup-dropdown-menu .dropdown-header {
    padding-block: 0.35rem;
    line-height: 1.2;
}

.setup-dropdown-menu .dropdown-divider {
    margin: 0.2rem 0;
}

/* Bootstrap's own navbar-expand-lg collapse breakpoint (992px) - below
   it, links need real touch targets more than they need to save space. */
@media (max-width: 991.98px) {
    .setup-dropdown-menu .dropdown-item {
        padding-top: 0.4rem;
        padding-bottom: 0.4rem;
        font-size: 0.97rem;
    }

    .setup-dropdown-menu .dropdown-header {
        padding-block: 0.4rem;
    }
}

/* ---------------------------------------------------------------------
   Reusable page/report components (spec section 30).
   --------------------------------------------------------------------- */

.page-header {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: flex-start;
    gap: 0.75rem;
    margin-bottom: 1.25rem;
}

.page-header .page-title {
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--color-navy);
    margin-bottom: 0.15rem;
}

.page-header .page-subtitle {
    color: var(--color-muted);
    font-size: 0.92rem;
    margin-bottom: 0;
}

.page-header .page-header-actions {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.report-section {
    margin-bottom: 1.5rem;
}

.report-section-title {
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--color-navy);
    margin-bottom: 0.6rem;
}

/* KPI cards - white surface, left accent border carries the financial
   meaning (spec section 10/11: color supports the label, the words
   "Favorable"/"Within Capital Budget"/etc. always remain the primary
   signal, never color alone). */
.kpi-card {
    background-color: var(--color-surface);
    border: 1px solid var(--color-border);
    border-left: 4px solid var(--color-border-strong);
    border-radius: 0.5rem;
    padding: 0.85rem 1.1rem;
    height: 100%;
}

.kpi-card .kpi-label {
    font-size: 0.76rem;
    color: var(--color-muted);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    margin-bottom: 0.2rem;
}

.kpi-card .kpi-value {
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--color-text);
    line-height: 1.25;
    word-break: break-word;
}

.kpi-card .kpi-context {
    font-size: 0.82rem;
    color: var(--color-muted);
    margin-top: 0.15rem;
}

.kpi-card .kpi-status {
    font-size: 0.82rem;
    font-weight: 600;
    margin-top: 0.35rem;
}

.kpi-card--neutral { border-left-color: var(--color-border-strong); }
.kpi-card--income { border-left-color: var(--color-blue); }
.kpi-card--expense { border-left-color: var(--color-orange); }
.kpi-card--asset { border-left-color: var(--color-blue-medium); }
.kpi-card--liability { border-left-color: var(--color-border-strong); }
.kpi-card--surplus-positive { border-left-color: var(--color-green-dark); }
.kpi-card--surplus-negative { border-left-color: var(--bs-danger); }
.kpi-card--warning { border-left-color: var(--color-orange-dark); }
.border-capital { border-color: var(--color-blue-medium) !important; }
.kpi-card--gold { border-left-color: var(--color-gold); }

.kpi-status--favorable,
.kpi-status--positive {
    color: var(--color-green-dark);
}

.kpi-status--unfavorable,
.kpi-status--negative {
    color: var(--bs-danger);
}

.kpi-status--muted {
    color: var(--color-muted);
    font-style: italic;
    font-weight: 500;
}

/* Filter panels - the existing card+row.g-2 markup every report already
   uses (see reporting/budget_performance.html and siblings); this class
   just formalizes/accents the pattern rather than replacing it. */
.filter-panel {
    background-color: var(--color-surface);
    border: 1px solid var(--color-border);
    border-top: 3px solid var(--color-blue);
}

.filter-panel .form-label {
    color: var(--color-muted);
    font-weight: 500;
}

/* Reports landing page (2026-08-30, user-reported): the report-choice
   actions previously stacked as one long single-column list
   (reporting/index.html's own form) - this reflows them into a compact
   responsive card grid instead. Deliberately does not touch the
   separate description-only card grid further down that same page
   (already a responsive col-md-3 grid, not the reported problem). */
.report-option-card {
    background-color: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 0.5rem;
    padding: 0.75rem 0.9rem;
    height: 100%;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.report-option-card .report-option-title {
    font-weight: 600;
    font-size: 0.92rem;
    color: var(--color-text);
    line-height: 1.25;
}

/* Financial tables - compact, right-aligned numeric columns are already
   marked up with Bootstrap's text-end utility throughout the app; this
   only refines borders/header/hover treatment. */
.financial-table {
    font-size: 0.92rem;
}

.financial-table th {
    background-color: var(--color-bg);
    font-weight: 600;
    border-bottom: 2px solid var(--color-border);
    white-space: nowrap;
}

.financial-table td,
.financial-table th {
    vertical-align: middle;
}

.financial-table tbody tr:hover {
    --bs-table-accent-bg: rgba(6, 136, 198, 0.06);
}

/* Empty states (spec section 24) - a calmer, more explicit alternative
   to a bare blank table/alert; existing alert-info/table empty-row
   patterns remain valid and are not required to migrate to this. */
.empty-state {
    text-align: center;
    color: var(--color-muted);
    padding: 1.25rem 1rem;
    background-color: var(--color-bg);
    border: 1px dashed var(--color-border-strong);
    border-radius: 0.5rem;
    font-size: 0.9rem;
}

/* ---------------------------------------------------------------------
   Compact financial-reporting density (2026-08-30, user-reported) -
   scoped to .report-compact ONLY (wrapped around each report template's
   own {% block content %}: consolidated_budget.html, budget_performance.html,
   budget_vs_actual.html, monthly_trends.html) so the base .page-header/
   .filter-panel/.kpi-card/.financial-table rules above stay exactly as
   they are for the Dashboard and every other page that also uses them -
   "compact for viewing financial information, comfortable for entering/
   approving/editing" (spec's own design principle). Reusable by any
   future report template simply by adding the same wrapper class - no
   per-template font/spacing classes needed.
   --------------------------------------------------------------------- */

.report-compact .breadcrumb {
    margin-bottom: 0.5rem;
}

.report-compact .page-header {
    margin-bottom: 0.85rem;
}

.report-compact .page-title {
    /* Phase 8's own base .page-title is already 1.5rem (measured 24px) -
       smaller than this task's own suggested 1.6-1.75rem "compact"
       range, so applying that range verbatim would have made titles
       LARGER, not more compact. Font-size is intentionally left at the
       base value; only the margin below is tightened here. */
    margin-bottom: 0.1rem;
}

.report-compact .page-subtitle {
    font-size: 0.95rem;
}

/* Filter panels */
.report-compact .filter-panel .card-body {
    padding: 0.75rem 1rem;
}

.report-compact .filter-panel .form-label {
    font-size: 0.85rem;
    margin-bottom: 0.25rem;
}

.report-compact .filter-panel .form-select,
.report-compact .filter-panel .form-control {
    font-size: 0.9rem;
    padding-top: 0.3rem;
    padding-bottom: 0.3rem;
}

/* KPI cards - min-height (never a rigid height) so content is never
   clipped; a genuinely taller card (e.g. one more status line) still
   grows past this floor. */
.report-compact .kpi-card {
    padding: 0.55rem 0.8rem;
    min-height: 88px;
}

.report-compact .kpi-card .kpi-label {
    font-size: 0.78rem;
    margin-bottom: 0.1rem;
}

.report-compact .kpi-card .kpi-value {
    font-size: 1.22rem;
    line-height: 1.15;
}

.report-compact .kpi-card .kpi-context {
    font-size: 0.8rem;
    margin-top: 0.1rem;
}

.report-compact .kpi-card .kpi-status {
    font-size: 0.8rem;
    margin-top: 0.2rem;
}

/* Financial tables */
.report-compact .financial-table {
    font-size: 0.84rem;
}

/* th/td padding deliberately NOT overridden - these tables already use
   Bootstrap's own .table-sm (measured 4px/0.25rem vertical padding),
   tighter than this task's own suggested 0.35-0.45rem range; overriding
   it to that range would have made rows TALLER, not more compact. The
   font-size reduction above is what actually shrinks row height here. */

/* Section headings ("Centre Summary", "Monthly Performance", etc. - all
   plain <h2 class="h5"> in these templates) and card headers (Bootstrap's
   own .card-header, used for sub-sections like "Actual Period Coverage",
   "Top Expense Overruns"). */
.report-compact h2.h5 {
    /* Bootstrap's reboot default h1-h6 margin-bottom is 0.5rem (measured
       8px) - 0.4rem is a genuine reduction below that. */
    font-size: 1.2rem;
    margin-top: 0.25rem;
    margin-bottom: 0.4rem;
}

.report-compact .card-header {
    /* Bootstrap's own --bs-card-cap-padding-y is already 0.5rem - 0.4rem
       is a genuine (if modest) reduction below that. */
    padding: 0.4rem 0.85rem;
    font-size: 0.92rem;
}

/* Cards inside reports (exception/summary cards) - moderate padding
   reduction only; explicit status text (Favorable/Unfavorable/Capital
   Overrun/Unbudgeted/Not Available) is untouched, this only affects
   spacing. Bootstrap's own spacing utilities carry !important, so
   matching that is the only way to actually shrink them here - scoped
   tightly to .report-compact, never applied globally. */
.report-compact .card-body {
    padding: 0.75rem 0.9rem;
}

.report-compact .mb-4 {
    margin-bottom: 1rem !important;
}

.report-compact .mb-3 {
    margin-bottom: 0.75rem !important;
}

/* Mobile safeguard: relax the compact density back toward comfortable
   touch sizing below Bootstrap's own sm breakpoint - never blindly
   apply desktop density to small phones. */
@media (max-width: 575.98px) {
    .report-compact .filter-panel .form-select,
    .report-compact .filter-panel .form-control {
        font-size: 0.95rem;
        padding-top: 0.375rem;
        padding-bottom: 0.375rem;
    }

    .report-compact .kpi-card {
        padding: 0.7rem 0.9rem;
        min-height: 0;
    }

    .report-compact .financial-table {
        font-size: 0.88rem;
    }

    .report-compact .card-body {
        padding: 0.9rem 1rem;
    }

    .report-compact .card-header {
        padding: 0.5rem 0.9rem;
    }
}

/* Keeps wide tables (e.g. the 12-month budget line breakdown) scrolling
   within their own container instead of the whole page. */
.table-responsive {
    max-width: 100%;
}

/* Adjusted budget lines already get Bootstrap's table-warning background;
   this just softens it slightly so a whole month of adjusted rows stays
   readable rather than glaring. */
.table-warning {
    --bs-table-bg: #fff8e6;
}

/* Centre Budget Inputs: one compact row per Budget Item, so a Centre can
   scan/tick a long item list without excessive scrolling. Scoped to this
   table alone (not .financial-table generally) - column padding only,
   font-size is left at .financial-table's normal (not tiny) size. */
.centre-inputs-table td,
.centre-inputs-table th {
    padding-top: 0.4rem;
    padding-bottom: 0.4rem;
}

.centre-inputs-table .form-check-input {
    width: 1.15em;
    height: 1.15em;
    margin: 0;
    cursor: pointer;
}

/* The small "assumptions" toggle link inline with an account name. */
.btn-link.btn-sm {
    text-decoration: underline dotted;
    font-size: 0.8rem;
}

/* The "Recent Workflow Activity" list on the budget detail page: a thin
   left rule gives it a lightweight timeline feel without needing any
   custom markup beyond a plain Bootstrap list-group. */
.workflow-timeline.list-group {
    border-left: 2px solid rgba(0, 0, 0, 0.08);
    padding-left: 0.75rem;
}

.workflow-timeline .list-group-item {
    border: none;
    border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}

.workflow-timeline .list-group-item:last-child {
    border-bottom: none;
}

/* Budget Detail's "Budget Lines by Month" collapsible section headers:
   a right-pointing triangle when collapsed, down-pointing when expanded -
   driven purely by the aria-expanded attribute Bootstrap's collapse JS
   already keeps in sync on the toggle button, no extra JS needed. */
.month-toggle .month-toggle-icon::before {
    content: "\25B6";
    display: inline-block;
    width: 1em;
    font-size: 0.75em;
    color: #6c757d;
}

.month-toggle[aria-expanded="true"] .month-toggle-icon::before {
    content: "\25BC";
}

/* Budget Detail's month sections default to collapsed on screen (Sprint
   16B3.2) but must always be fully visible in print/PDF output - a
   printed budget review is not useful with 11 of 12 months hidden. */
@media print {
    [id^="month-body-"] {
        display: block !important;
        height: auto !important;
        visibility: visible !important;
    }
}

/* Generic collapsible-section toggle (Sprint 16B4's "Advanced Settings"
   sections on Budget Setup / Projection Rule forms) - same aria-expanded-
   driven chevron mechanism as Budget Detail's month-toggle above, kept
   as its own class so it can be reused anywhere a small collapsible
   section is needed without depending on Budget Detail's own markup. */
.collapse-toggle .collapse-toggle-icon::before {
    content: "\25B6";
    display: inline-block;
    width: 1em;
    font-size: 0.75em;
    color: #6c757d;
}

.collapse-toggle[aria-expanded="true"] .collapse-toggle-icon::before {
    content: "\25BC";
}
