/* =====================================================================
   BBP System — Design Tokens & Base Styles
   Barangay Budget Preparation System

   ANG DESIGN TOKENS: Ang mga custom property sa ibaba (yung mga nagsisimula
   sa "--", hal. --color-primary) ay tinatawag na "CSS Custom Properties"
   (mga "CSS variable"). Sa halip na isulat mo ang parehong hex code
   (#184F95) sa 50 different lugar, minsan mo lang ide-define dito, tapos
   tatawagin mo na lang gamit ang var(--color-primary) kahit saan. Kapag
   gusto mong palitan ang buong itsura ng app (halimbawa palitan ang
   primary color), ISANG LINYA lang babaguhin mo dito, hindi 50 files.

   Desktop-first ito, min-width 1280px — hindi natin pinag-aalala ang
   mobile/tablet layout sa unang bersyon (per BBP_System_Flow.md).
   ===================================================================== */

/* ---------------------------------------------------------------------
   1. DESIGN TOKENS
   --------------------------------------------------------------------- */
:root {
    /* --- Primary (actions lang: buttons, links, focus, active states) ---
       Deep civic blue — propesyonal, hindi generic "startup purple".
       ISANG kulay lang ito para sa buong app; huwag magdagdag ng iba
       pang "primary" na kulay kahit saan. */
    --color-primary: #184f95;
    --color-primary-hover: #104281;
    --color-primary-active: #0d366b;
    --color-primary-tint: #cde2fb;      /* light wash — selected states, info banners */
    --color-primary-tint-weak: #eaf1fb; /* mas magaan pa — hover backgrounds */

    /* --- Neutrals: cool blue-gray scale (hindi pure gray, may bahid
       ng primary blue para magkatugma ang buong app) --- */
    --gray-0: #ffffff;
    --gray-50: #f7f9fc;
    --gray-100: #eef2f7;
    --gray-200: #e1e7ef;
    --gray-300: #cbd5e1;
    --gray-400: #9faec0;
    --gray-500: #71829a;
    --gray-600: #526079;
    --gray-700: #3c4759;
    --gray-800: #26303e;
    --gray-900: #151b24;

    /* --- Sidebar: hiwalay na deep navy, distinct sa primary blue,
       para malinaw ang structural hierarchy (dark rail vs light content),
       tulad ng Xero/QuickBooks reference --- */
    --color-sidebar-bg: #0f1f33;
    --color-sidebar-bg-active: rgba(255, 255, 255, 0.08);
    --color-sidebar-text: #aebdd4;
    --color-sidebar-text-active: #ffffff;
    --color-sidebar-border: rgba(255, 255, 255, 0.08);

    /* --- Text tokens (gamitin ito sa halip na direktang gray-XXX,
       para kung magbago ang color scheme, dito na lang babaguhin) --- */
    --text-primary: var(--gray-900);
    --text-secondary: var(--gray-600);
    --text-muted: var(--gray-500);
    --text-on-primary: #ffffff;

    /* --- Surfaces --- */
    --surface-page: var(--gray-50);
    --surface-card: var(--gray-0);
    --border-color: var(--gray-200);
    --border-color-strong: var(--gray-300);

    /* --- Status colors — GAMITIN LANG PARA SA VALIDATION STATUS.
       Huwag gamitin bilang decorative accent o pang-ibang purpose.
       Ang mga kulay na ito ay mula sa validated na status palette
       (accessible sa colorblind/CVD, distinct sa chart categories sa
       ibaba) — na kasama sa dataviz na skill/reference. --- */
    --status-good: #0ca30c;
    --status-good-bg: #e6f6e6;
    --status-warning: #b8790a;      /* pinatingkad mula sa raw #fab219 para
                                        sapat ang contrast bilang TEXT sa
                                        puting background — ang raw hex ay
                                        para sa mga background fill/icon lang */
    --status-warning-icon: #fab219;
    --status-warning-bg: #fdf1da;
    --status-critical: #d03b3b;
    --status-critical-bg: #fbe9e9;

    /* --- Chart categorical colors — GA / BSF / SPA lang ang gamit dito.
       Mula sa unang 3 slots ng validated 8-hue categorical palette
       (blue/orange/aqua) — pinatunayan pumasa ang combinasyong ito sa
       colorblind-safety checks kahit "all-pairs" (i.e. tatlong beses
       paired sa isa't-isa, hindi lang magkatabi). --- */
    --chart-ga: #2a78d6;   /* blue */
    --chart-bsf: #eb6834;  /* orange */
    --chart-spa: #1baf7a;  /* aqua/green — ginagamit pa rin ito ng SPA Breakdown progress bars */

    /* --- Dagdag na 2 hue para sa "PPA by Sector" donut kapag hiniwalay
       ang SPA papuntang sub-categories nito (20% DF/5% BDRRM/Other SPA,
       sa halip na iisang "SPA" segment) — 5 slots na ngayon sa donut na
       'yon. PAALALA: HINDI ito na-verify gamit ang validate_palette.js
       (masyadong lumang Node sa environment na 'to, hindi kayang i-parse
       ang script) — sa halip, sinunod na lang ang written guidance ng
       palette (blue/orange/aqua = unang 3 slots, pinatunayan nang pumasa
       sa "all-pairs" check) at INIWASAN ang partikular na kombinasyong
       alam na FAIL doon (yellow/slot4 katabi ng orange/slot2) sa
       pamamagitan ng paglukso papuntang violet/red (slot7/8, malayo sa
       blue-orange-aqua cluster). Hindi 100% garantisadong ligtas kahit
       gaano pa kaingat ang pagpili nang walang tunay na validator run —
       PERO may existing na "relief" na rin naman: may text label pa rin
       ang bawat segment sa legend (hindi kailanman kulay lang), kaya
       hindi lubos na umaasa sa pagkakaiba ng kulay ang pagkilala. */
    --chart-20df: #1baf7a;      /* aqua — parehong hue ng dating lump "SPA" */
    --chart-bdrrm: #4a3aa7;     /* violet */
    --chart-other-spa: #e34948; /* red */
    --chart-sk-fund: #e0a52c;   /* gold/amber — malinaw na naiiba sa red/orange/green/violet sa itaas */

    /* --- Typography ---
       "Century Gothic" muna (kung naka-install na ito sa computer ng
       user — karaniwang naka-preinstall ito sa Windows/Office), tapos
       bumaba papuntang system font stack bilang fallback — walang
       kailangang i-download/external request (@font-face/Google Fonts),
       mabilis pa ring lumoad kahit wala nito ang user. */
    --font-sans: "Century Gothic", CenturyGothic, AppleGothic, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

    --text-xs: 0.75rem;    /* 12px — captions, small labels */
    --text-sm: 0.8125rem;  /* 13px — table cells, secondary text */
    --text-base: 0.875rem; /* 14px — default body (dense data app) */
    --text-md: 1rem;       /* 16px — emphasized body, card titles */
    --text-lg: 1.25rem;    /* 20px — section headers */
    --text-xl: 1.75rem;    /* 28px — page titles */
    --text-2xl: 2.25rem;   /* 36px — hero figures sa stat cards */

    --weight-regular: 400;
    --weight-medium: 500;
    --weight-semibold: 600;
    --weight-bold: 700;

    --leading-tight: 1.25;
    --leading-normal: 1.5;

    /* --- Spacing scale (4px base grid) --- */
    --space-1: 0.25rem;  /* 4px */
    --space-2: 0.5rem;   /* 8px */
    --space-3: 0.75rem;  /* 12px */
    --space-4: 1rem;     /* 16px */
    --space-5: 1.25rem;  /* 20px */
    --space-6: 1.5rem;   /* 24px */
    --space-8: 2rem;     /* 32px */
    --space-10: 2.5rem;  /* 40px */
    --space-12: 3rem;    /* 48px */
    --space-16: 4rem;    /* 64px */

    /* --- Radius --- */
    --radius-sm: 4px;
    --radius-md: 8px;
    --radius-lg: 12px;
    --radius-full: 999px;

    /* --- Shadows (subtle — propesyonal, hindi flashy) --- */
    --shadow-sm: 0 1px 2px rgba(15, 27, 36, 0.06);
    --shadow-md: 0 2px 8px rgba(15, 27, 36, 0.08);
    --shadow-lg: 0 8px 24px rgba(15, 27, 36, 0.12);

    /* --- Transitions --- */
    --transition-fast: 120ms ease;
    --transition-base: 200ms ease;
    --transition-slow: 320ms ease;

    /* --- Layout --- */
    --sidebar-width: 264px;
    --topbar-height: 64px;
    --content-max-width: 1440px;

    /* --- Z-index scale --- */
    --z-sidebar: 100;
    --z-topbar: 90;
    --z-dropdown: 200;
    --z-modal: 400;
    --z-toast: 500;
}

/* ---------------------------------------------------------------------
   2. RESET / BASE
   --------------------------------------------------------------------- */
*,
*::before,
*::after {
    box-sizing: border-box;
}

html,
body {
    height: 100%;
}

body {
    /* Desktop-first pa rin (hindi ito totoong mobile-responsive design),
       PERO hindi na dapat kailangang mag-zoom-out ang user sa mas
       maliliit na laptop screen/naka-scale na display para makita ang
       buong page — mas mababa ang floor na 'to (dating 1280px), at
       kung may sarili pang mas malapad na table/grid sa loob (Form 2
       spreadsheet grid, atbp.), IYON na lang ang mag-scroll nang
       pahalang (tingnan ang .page-body/.grid-scroll-area overflow-x),
       hindi na ang buong page. */
    min-width: 1024px;
    margin: 0;
    background: var(--surface-page);
    color: var(--text-primary);
    font-family: var(--font-sans);
    font-size: var(--text-base);
    line-height: var(--leading-normal);
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, p {
    margin: 0;
}

/* ANG "hidden" ATTRIBUTE BUG: Ang built-in na browser rule ([hidden] {
   display: none;}) ay may PAREHONG specificity sa kahit anong class
   selector (hal. .badge { display: inline-flex; }). Sa CSS, kapag
   PAREHO ang specificity ng dalawang magkasalungat na rule, ang
   NAHULING nabasa (dito, ang SARILI nating style.css, dahil sumusunod
   ito sa default browser stylesheet) ang SIYANG NANANALO — kaya kahit
   naka-set na ang "hidden" attribute sa isang element, LUMALABAS pa
   rin ito kung may .badge/.entry-row (o kahit anong) class itong
   nakadikit na nagse-set ng "display" property. Dito natin ito
   pinipilit na manalo LAGI, kahit anong ibang class pa ang mayroon
   ang element — ito ang dahilan kung bakit "nakikita pa rin" ang mga
   dapat sana ay nakatago (hal. ang "Kailangan ng breakdown" badge). */
[hidden] {
    display: none !important;
}

a {
    color: var(--color-primary);
    text-decoration: none;
}

a:hover {
    text-decoration: underline;
}

button {
    font-family: inherit;
}

/* Numero na dapat pantay-pantay ang hanay (mga column ng pera, table
   rows) — ito ang "tabular figures" na hiniling. Ang normal na font ay
   iba-iba ang lapad ng bawat digit (proportional), kaya "gumagalaw" ang
   decimal point sa magkakasunod na row. Sa tabular-nums, PAREHONG LAPAD
   lahat ng digit (0-9), kaya diretso ang pagkakahanay. */
.tabular-nums,
.stat-card__value,
.data-table td.is-numeric,
.progress-row__amounts {
    font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------------
   3. LAYOUT PRIMITIVES
   --------------------------------------------------------------------- */
.app-shell {
    display: flex;
    min-height: 100vh;
}

.sidebar {
    width: var(--sidebar-width);
    flex-shrink: 0;
    background: var(--color-sidebar-bg);
    color: var(--color-sidebar-text);
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
}

.main {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.page-header {
    padding: var(--space-8) var(--space-10) var(--space-6);
    max-width: var(--content-max-width);
}

/* Sa Form 2 lang (".main--grid-page" — tingnan ang paalala sa itaas,
   iisa lang ang gumagamit nito) — pinaliit ang header papuntang mas
   compact, dahil DITO lang FIXED ang header (hindi ito sumasama sa
   pag-scroll ng grid, tingnan ang .main--grid-page/.grid-scroll-area),
   kaya direktang naka-apekto sa BILANG NG ROW na makikita nang hindi na
   kailangang mag-scroll pa. Sa ibang pages, sumasama namang sa scroll
   ang buong header kaya hindi gaanong mahalaga ang taas nito doon —
   kaya hindi na natin ito ginalaw sa ".page-header" base rule sa itaas,
   dito lang na-scope. */
.main--grid-page .page-header {
    padding: var(--space-4) var(--space-10) var(--space-3);
}

.main--grid-page .page-header__title {
    margin-top: 2px;
}

.main--grid-page .page-header__subtitle {
    margin-top: 2px;
}

/* Variant ng ".page-header" na may action buttons (Print/Export, atbp.)
   sa kanang gilid ng title — ginagamit sa Form 1-A/2/2A/3/BESF. Dating
   inline style ito sa bawat isa (magkapareho sa 9 pages) — ni-extract
   dito bilang class para magamit ng media query (di-gaya ng inline
   style, hindi ito basta ma-o-override ng mobile stacking rule sa
   ibaba). */
.page-header--actions {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-4);
}

.page-header__eyebrow {
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.page-header__title {
    font-size: var(--text-xl);
    font-weight: var(--weight-bold);
    color: var(--text-primary);
    margin-top: var(--space-1);
}

.page-header__subtitle {
    font-size: var(--text-base);
    color: var(--text-secondary);
    margin-top: var(--space-1);
}

.page-body {
    padding: 0 var(--space-10) var(--space-10);
    max-width: var(--content-max-width);
    display: flex;
    flex-direction: column;
    gap: var(--space-6);
    /* Safety net: kapag mas malapad ang laman sa loob (fixed-width na
       table/colgroup gaya ng Form 1-A/Form 3/Form 2A) kaysa sa
       available na espasyo, ITO na lang ang mag-sc-scroll pahalang —
       hindi na kailangang palakihin ng buong <body> (na siyang
       nagpipilit sa user na mag-zoom-out para makita lahat). */
    overflow-x: auto;
}

/* ---------------------------------------------------------------------
   4. SIDEBAR NAV
   --------------------------------------------------------------------- */
.sidebar__brand {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-4) var(--space-5);
    border-bottom: 1px solid var(--color-sidebar-border);
}

.sidebar__brand-mark {
    width: 40px;
    height: 40px;
    border-radius: var(--radius-md);
    background: var(--color-primary);
    color: var(--text-on-primary);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: var(--weight-bold);
    font-size: var(--text-md);
    flex-shrink: 0;
}

.sidebar__brand-name {
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    color: var(--color-sidebar-text-active);
    line-height: var(--leading-tight);
}

.sidebar__brand-sub {
    font-size: var(--text-xs);
    color: var(--color-sidebar-text);
    margin-top: 2px;
}

.sidebar__section {
    padding: var(--space-2) var(--space-3) var(--space-1);
}

.sidebar__section-label {
    padding: 0 var(--space-3);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: rgba(174, 189, 212, 0.6);
    margin-bottom: var(--space-1);
}

.nav-item {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-1) var(--space-3);
    border-radius: var(--radius-md);
    color: var(--color-sidebar-text);
    font-size: 11px;
    cursor: pointer;
    transition: background var(--transition-fast), color var(--transition-fast);
}

.nav-item:hover {
    background: var(--color-sidebar-bg-active);
    color: var(--color-sidebar-text-active);
    text-decoration: none;
}

.nav-item.is-active {
    background: var(--color-primary);
    color: var(--text-on-primary);
    font-weight: var(--weight-medium);
}

.nav-item.is-disabled {
    color: rgba(174, 189, 212, 0.4);
    cursor: not-allowed;
}

.nav-item.is-disabled:hover {
    background: transparent;
    color: rgba(174, 189, 212, 0.4);
}

.nav-item--sub {
    padding-left: var(--space-8);
    font-size: 11px;
}

.nav-item__label {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.nav-item__icon {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Status dot/badge sa dulo ng bawat nav item — ito ang "check mark kung
   tapos, warning badge kung may issue" na hiniling. */
.status-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
    background: var(--gray-500);
}

.status-dot.is-complete {
    background: var(--status-good);
}

.status-dot.is-warning {
    background: var(--status-warning-icon);
}

/* ---------------------------------------------------------------------
   4B. ANNOUNCEMENT BELL (Dashboard page-header, katabi ng "FY"/"Quick
   Print" buttons) — admin broadcast, "parang Facebook" notification.
   ".announcement-anchor" ay "position:relative" lang para dito mag-anchor
   ang dropdown panel (".announcement-dropdown", "position:absolute").
   --------------------------------------------------------------------- */
.announcement-anchor {
    position: relative;
    flex-shrink: 0;
}

.announcement-bell-icon {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border: 1px solid var(--border-color-strong);
    border-radius: var(--radius-md);
    background: var(--surface-card);
    color: var(--text-primary);
    cursor: pointer;
    transition: background var(--transition-fast), color var(--transition-fast);
}

.announcement-bell-icon:hover {
    background: var(--gray-50);
}

.announcement-bell__badge {
    position: absolute;
    top: -3px;
    right: -3px;
    min-width: 15px;
    height: 15px;
    padding: 0 3px;
    border-radius: 999px;
    background: var(--status-critical);
    color: #fff;
    font-size: 10px;
    line-height: 15px;
    text-align: center;
    font-weight: var(--weight-semibold);
}

/* "top:100%" + "right:0" — nasa ITAAS ng page ang bell button
   (page-header, katabi ng "FY"/"Quick Print"), kaya PABABA bumukas ang
   dropdown; naka-align sa KANANG gilid ng bell (hindi kaliwa) para
   hindi ito lumagpas sa kanang dulo ng viewport. */
.announcement-dropdown {
    position: absolute;
    top: 100%;
    right: 0;
    margin-top: var(--space-2);
    width: 320px;
    max-width: calc(100vw - var(--space-6));
    max-height: 420px;
    overflow-y: auto;
    background: var(--surface-card);
    color: var(--text-primary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg, 0 8px 24px rgba(0, 0, 0, 0.18));
    z-index: 50;
}

.announcement-dropdown__header {
    padding: var(--space-3) var(--space-4);
    font-weight: var(--weight-semibold);
    font-size: var(--text-sm);
    border-bottom: 1px solid var(--border-color);
}

.announcement-dropdown__empty {
    padding: var(--space-4);
    font-size: var(--text-sm);
    color: var(--text-muted);
}

.announcement-dropdown__list {
    display: flex;
    flex-direction: column;
}

.announcement-item {
    padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--border-color);
    font-size: var(--text-sm);
}

.announcement-item:last-child {
    border-bottom: none;
}

.announcement-item.is-unread {
    background: var(--gray-50);
}

.announcement-item__message {
    color: var(--text-primary);
    line-height: 1.5;
    overflow-wrap: break-word;
}

.announcement-item__meta {
    display: flex;
    justify-content: space-between;
    gap: var(--space-2);
    margin-top: var(--space-2);
    font-size: var(--text-xs);
    color: var(--text-muted);
}

/* Sa makitid na screen — huwag masyadong lumapad (baka lumagpas sa
   viewport), "max-width" na sa itaas ang bahalang bumawas kung
   kailangan. */
@media (max-width: 400px) {
    .announcement-dropdown {
        width: calc(100vw - var(--space-6));
    }
}

.sidebar__footer {
    margin-top: auto;
    padding: var(--space-3) var(--space-5);
    border-top: 1px solid var(--color-sidebar-border);
    font-size: var(--text-xs);
    color: var(--color-sidebar-text);
}

.sidebar__fy-badge {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-1) var(--space-3);
    background: var(--color-sidebar-bg-active);
    border-radius: var(--radius-full);
    font-weight: var(--weight-medium);
    color: var(--color-sidebar-text-active);
}

.sidebar__user {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    margin-top: var(--space-3);
}

.sidebar__user-name {
    color: var(--color-sidebar-text-active);
    font-weight: var(--weight-medium);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sidebar__logout {
    color: var(--color-sidebar-text);
    text-decoration: underline;
    flex-shrink: 0;
}

.sidebar__logout:hover {
    color: var(--color-sidebar-text-active);
}

/* ---------------------------------------------------------------------
   5. CARDS
   --------------------------------------------------------------------- */
.card {
    background: var(--surface-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
}

.card__header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    padding: var(--space-5) var(--space-6) 0;
}

.card__title {
    font-size: var(--text-md);
    font-weight: var(--weight-semibold);
    color: var(--text-primary);
}

.card__subtitle {
    font-size: var(--text-sm);
    color: var(--text-muted);
    margin-top: 2px;
}

.card__body {
    padding: var(--space-5) var(--space-6) var(--space-6);
}

/* "PPA by Sector" donut chart card lang — naka-scope via :has() (walang
   ibang .card ang may .donut-panel-radial), dahil "align-items:stretch"
   sa .insight-grid, kapag mas MABABA ang laman nito kaysa sa katabing
   "Statutory Compliance" card (mas mahaba dahil 6 fund), naiiwan itong
   sakto sa taas lang, sayang ang blangkong espasyo sa ibaba. Dito,
   ginagawang flex column ang .card mismo + flex:1 sa .card__body para
   talagang mapuno ang stretched height, saka i-center ang laman
   (donut chart) sa loob nito — parang "nasa gitna" na sa halip na
   "nakadikit sa taas." */
.card:has(.donut-panel-radial) {
    display: flex;
    flex-direction: column;
}

.card:has(.donut-panel-radial) .card__body {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

/* Maliit na icon bago ang isang text label (card title, quick-link
   item, atbp.) — "currentColor" ang gamit ng SVG (tingnan ang
   bbp_icon() sa helpers.php), kaya awtomatikong tumutugma sa kulay ng
   text sa paligid nito, hindi na kailangang i-set kada gamit. */
.icon-inline {
    display: inline-flex;
    vertical-align: -3px;
    margin-right: var(--space-2);
    color: var(--text-muted);
    flex-shrink: 0;
}

/* Kapag ang ".card" ay isa palang <details> (collapsible card, gaya ng
   "Quick Print / Export" sa Dashboard): ang ".card__header" ay may
   0 bottom padding by design (dati, laging may ".card__body" na kaagad
   sumusunod, may sarili itong top padding, kaya walang puwang na
   nawawala). PERO kapag SARADO ang <details>, walang ".card__body" na
   lumalabas — kaya kailangan ng sariling bottom padding ang summary
   mismo dito, para hindi "naiipit" ang text sa gilid ng box. */
details.card:not([open]) > summary.card__header {
    padding-bottom: var(--space-5);
}

.stat-grid {
    display: grid;
    /* auto-fit + minmax sa halip na "repeat(3, 1fr)" — kapag masikip na
       ang espasyo (mas maliit na screen/naka-scale na display), lumiliit
       muna ang bawat card hanggang 220px bago mag-wrap sa 2 o 1 column,
       sa halip na sapilitang pipigain ang 3 sa isang linya kahit hindi
       na kasya. */
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: var(--space-5);
}

.stat-card {
    background: var(--surface-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    padding: var(--space-5) var(--space-6);
}

.stat-card__top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-2);
}

.stat-card__label {
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}

.stat-card__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: var(--radius-md);
    background: var(--color-primary-tint-weak);
    color: var(--color-primary);
    flex-shrink: 0;
}

.stat-card__icon--good { background: var(--status-good-bg); color: var(--status-good); }
.stat-card__icon--critical { background: var(--status-critical-bg); color: var(--status-critical); }

.stat-card__value {
    font-size: var(--text-2xl);
    font-weight: var(--weight-bold);
    color: var(--text-primary);
    margin-top: var(--space-2);
    line-height: var(--leading-tight);
}

.stat-card__value--good { color: var(--status-good); }
.stat-card__value--critical { color: var(--status-critical); }

/* Generic na text-color utility (hindi lang para sa .stat-card__value) —
   ginagamit sa kahit anong table cell/text na kailangang ipakita bilang
   "tumaas" (good) o "bumaba" (critical) na halaga, hal. yung Difference/
   % Change column sa "Previous vs Current Budget". */
.text-good { color: var(--status-good); }
.text-critical { color: var(--status-critical); }

.stat-card__meta {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-top: var(--space-2);
    font-size: var(--text-sm);
    color: var(--text-secondary);
}

.insight-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(420px, 1fr));
    gap: var(--space-5);
    align-items: stretch;
}

/* ---------------------------------------------------------------------
   6. BADGES / PILLS — status GAMIT LANG. Laging may icon + text, hindi
      kulay lang, para sa accessibility (hindi lahat nakakakita ng kulay
      nang pareho).
   --------------------------------------------------------------------- */
.badge {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: 3px var(--space-3);
    border-radius: var(--radius-full);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    line-height: 1.4;
    white-space: nowrap;
}

.badge--good {
    background: var(--status-good-bg);
    color: var(--status-good);
}

.badge--warning {
    background: var(--status-warning-bg);
    color: var(--status-warning);
}

.badge--critical {
    background: var(--status-critical-bg);
    color: var(--status-critical);
}

.badge--neutral {
    background: var(--gray-100);
    color: var(--text-secondary);
}

/* ---------------------------------------------------------------------
   7. DONUT CHART + LEGEND (GA / BSF / SPA split)
   --------------------------------------------------------------------- */
.donut-panel {
    display: flex;
    align-items: center;
    gap: var(--space-8);
}

.donut-chart {
    flex-shrink: 0;
}

.donut-chart__total-value {
    font-size: var(--text-lg);
    font-weight: var(--weight-bold);
    fill: var(--text-primary);
    font-family: var(--font-sans);
}

.donut-chart__total-label {
    font-size: 10px;
    font-weight: var(--weight-semibold);
    fill: var(--text-muted);
    font-family: var(--font-sans);
    letter-spacing: 0.04em;
}

.legend {
    display: flex;
    flex-direction: column;
    flex: 1;
}

/* Manipis na hairline sa pagitan ng bawat legend row — mas madaling
   sundan ang mata paibaba, lalo na ngayong 5 posibleng segment na (GA/
   BSF + 20DF/BDRRM/Other SPA), hindi na 2-3 lang gaya dati. */
.legend__item {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-2);
    margin: 0 calc(var(--space-2) * -1);
    border-bottom: 1px solid var(--border-color);
}

.legend__item:last-child {
    border-bottom: none;
}

.legend__swatch {
    width: 12px;
    height: 12px;
    border-radius: 3px;
    flex-shrink: 0;
}

.legend__text {
    flex: 1;
    min-width: 0;
}

.legend__label {
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    color: var(--text-primary);
}

.legend__amount {
    font-size: var(--text-sm);
    color: var(--text-secondary);
}

.legend__pct {
    flex-shrink: 0;
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
    background: var(--gray-100);
    padding: var(--space-1) var(--space-2);
    border-radius: var(--radius-full, 999px);
}

/* ---------------------------------------------------------------------
   7A. DONUT CHART — RADIAL/LEADER-LINE variant (DESKTOP lang, tingnan
   ang @media pababa) — "infographic" na istilo: mga label na nakapalibot
   sa bilog (kaliwa/kanan, batay sa mid-angle ng bawat segment), may
   manipis na linya papuntang kani-kanyang hiwa. Ang ".legend" list sa
   itaas ang MOBILE fallback (".donut-panel--mobile-only") — hindi kasya
   ang istilong ito sa maliit na screen, kailangan ng espasyo sa
   MAGKABILANG gilid ng bilog.
   --------------------------------------------------------------------- */
.donut-panel--mobile-only {
    display: none;
}

.donut-panel-radial {
    display: flex;
    justify-content: center;
}

.donut-chart-radial {
    width: 100%;
    max-width: 600px;
    height: auto;
}

.donut-radial__leader {
    stroke-width: 1.5;
    opacity: 0.55;
    animation: donutLeaderDrawIn 0.35s ease-out backwards;
}

/* Kaparehong "stroke-dasharray 0 -> buo" na trick ng donutSegmentDrawIn
   sa ibaba, pero para sa TUWID na linya (hindi bilog) — "--leader-length"
   ang eksaktong haba ng bawat linya (kinukuha sa PHP via distance formula,
   dashboard.php), dahil magkaiba-iba ang haba ng bawat leader line
   (depende sa posisyon ng segment sa bilog). Nag-start ito PAGKATAPOS
   magsimulang gumuhit ang mga segment (300ms delay, tingnan ang
   animation-delay sa <line> mismo, staggered pa per-line) — parang
   "sumisibol" ang mga connector line papunta sa labels matapos lumitaw
   ang bilog. */
@keyframes donutLeaderDrawIn {
    from { stroke-dasharray: 0 var(--leader-length, 200); }
}

.donut-radial__label {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    height: 100%;
    cursor: pointer;
    padding: var(--space-1);
    margin: calc(var(--space-1) * -1);
    border-radius: var(--radius-md);
    transition: background var(--transition-fast);
}

.donut-radial__label:hover,
.donut-radial__label:focus-visible,
.donut-radial__label.is-highlighted {
    background: var(--surface-page);
}

.donut-radial__label:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 1px;
}

.donut-radial__dot {
    width: 8px;
    height: 8px;
    margin-top: 4px;
    border-radius: 50%;
    flex-shrink: 0;
}

.donut-radial__text {
    min-width: 0;
}

.donut-radial__title {
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    color: var(--text-primary);
    line-height: 1.25;
}

.donut-radial__meta {
    font-size: var(--text-xs);
    color: var(--text-secondary);
    font-variant-numeric: tabular-nums;
    margin-top: 2px;
}

/* ---- "Wow factor": entrance animation + hover interactivity ---- */

/* Bawat segment ng donut ay "gumuguhit" papasok (0 -> tamang haba) sa
   unang pagbukas ng page — ang stroke-dashoffset na naka-set na sa PHP
   (custom property --seg-offset) ang FINAL na posisyon; dito, mula sa
   buong circumference (nakatago, parang walang laman) papuntang doon. */
/* "0 439.8" — ang 439.8 ay LUMANG hardcoded na circumference (2πr sa
   radius=70, ang RADIUS noon). Kapag nagbago ang radius (tingnan ang
   $radius sa dashboard.php), hindi na tumutugma ang "gap" dito sa
   TUNAY na circumference ng bilog, kaya sira ang huling itsura ng
   animation (parang "nawawala" ang ibang segment — na-verify ito
   nang personal, lumitaw pagkatapos palakihin ang radius mula 70
   papuntang 95). Ginawa na dynamic gamit ang isang CSS custom
   property (--donut-circumference, naka-set bilang inline style sa
   bawat <circle>, tingnan ang dashboard.php) sa halip na hardcoded
   na numero — awtomatiko na itong tama kahit anong radius pa ang
   gamitin sa hinaharap. */
@keyframes donutSegmentDrawIn {
    from { stroke-dasharray: 0 var(--donut-circumference, 439.8); }
}

.donut-chart__segment {
    animation: donutSegmentDrawIn 0.8s ease-out backwards;
    transition: opacity var(--transition-fast), stroke-width var(--transition-fast);
    cursor: pointer;
    transform-origin: 100px 100px;
}

.donut-chart__segment.is-highlighted {
    stroke-width: 30;
}

.donut-chart__segment.is-dimmed {
    opacity: 0.35;
}

.donut-chart__total-value,
.donut-chart__total-label {
    animation: fadeInUp 0.5s ease-out 0.6s backwards;
}

@keyframes fadeInUp {
    from { opacity: 0; transform: translateY(4px); }
    to { opacity: 1; transform: translateY(0); }
}

.legend__item {
    animation: fadeInUp 0.4s ease-out backwards;
    cursor: pointer;
    border-radius: var(--radius-md);
    transition: background var(--transition-fast), transform var(--transition-fast);
}

.legend__item:hover,
.legend__item:focus-visible,
.legend__item.is-highlighted {
    background: var(--surface-page);
    transform: translateX(2px);
}

.legend__item:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 1px;
}

/* ---------------------------------------------------------------------
   8. PROGRESS BARS (statutory compliance)
   --------------------------------------------------------------------- */
.progress-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
}

.progress-row__top {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    /* Kapag mahaba ang label (may "pending confirmation" badge, hal.
       GAD/SC-PWD) AT mahaba rin ang base_label (hal. "5% of Total
       Receipts"), pwede silang mag-overflow/magkumpol-kumpol sa isang
       linya kung walang wrap — kaya pinapayagan dito na mag-stack sila
       sa hiwalay na linya kapag kailangan (dating mobile-only lang ito,
       tingnan sa ibaba, pero totoong desktop-width problem din pala). */
    flex-wrap: wrap;
    row-gap: var(--space-1);
    margin-bottom: var(--space-2);
}

.progress-row__label {
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    color: var(--text-primary);
}

.progress-row__amounts {
    font-size: var(--text-xs);
    color: var(--text-muted);
    white-space: nowrap;
}

.progress-track {
    height: 8px;
    border-radius: var(--radius-full);
    background: var(--gray-100);
    overflow: hidden;
}

.progress-fill {
    height: 100%;
    border-radius: var(--radius-full);
    background: var(--status-good);
    transition: width var(--transition-slow);
}

.progress-fill.is-warning {
    background: var(--status-warning-icon);
}

.progress-fill.is-critical {
    background: var(--status-critical);
}

.progress-row__bottom {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: var(--space-2);
}

/* ---------------------------------------------------------------------
   8A. COMPARISON BARS (Dashboard — Previous vs Current Budget) — 2
   bar bawat sub-program (Past Year/Current), sa halip na table. Muling
   ginagamit ang .progress-track/.progress-fill sa itaas, pero may
   sariling wrapper para sa label+bar+value/input na 3-column na flex
   row (hindi kagaya ng .progress-row na 1 bar lang bawat isa).
   --------------------------------------------------------------------- */
/* ---------------------------------------------------------------------
   VERTICAL BAR CHART — "Previous vs Current Budget". Totoong Y-axis
   (5 gridline/tick, mula sa $comparisonAxisTicks, 0/25/50/75/100% ng
   max) + PATAYONG column bawat sub-program, DALAWANG bar bawat isa
   (Past Year/Current) — hiling ng user, gaya ng "grouped column chart"
   na reference image.

   DALAWANG hiwalay na row (.vbar-chart__plot para sa mismong bars,
   .vbar-chart__labels para sa pangalan/delta/editable Past Year input)
   sa loob ng IISANG container (.vbar-chart__scroll) — pareho silang
   gumagamit ng "flex: 1 1 0" (pantay-pantay na paghahati ng available
   width, hindi fixed px) bawat column, kaya awtomatikong naka-align
   ang bawat column sa dalawang row nang walang kailangang JS
   measurement/sync — basta magkatugma ang BILANG ng column sa dalawa,
   magkatugma na rin awtomatiko ang lapad nila (pareho namang "flex: 1
   1 0" ang parehong row). "Overflow-x: auto" na lang bilang safety
   net kung sobrang kitid (hindi na dapat kailangan sa normal na
   screen — hiling ng user, tumugon dito ang columns sa halip na
   mag-scroll). */
:root {
    --vbar-plot-height: 200px;
}

.vbar-chart__legend {
    display: flex;
    gap: var(--space-4);
    margin-top: calc(-1 * var(--space-3));
    margin-bottom: var(--space-4);
}

.vbar-chart__legend-item {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-xs);
    color: var(--text-secondary);
    animation: fadeInUp 0.4s ease-out backwards;
}

.vbar-chart__swatch {
    width: 10px;
    height: 10px;
    border-radius: 3px;
    flex-shrink: 0;
}

.vbar-chart__body {
    display: flex;
    gap: var(--space-3);
}

/* Y-axis — HIWALAY na column sa kaliwa (hindi sumasabay mag-scroll),
   parehong height (--vbar-plot-height) ng .vbar-chart__plot para
   tumugma ang bottom:X% ng bawat tick doon sa TAMANG taas dito. */
.vbar-chart__yaxis {
    flex-shrink: 0;
    width: 60px;
    height: var(--vbar-plot-height);
    position: relative;
}

.vbar-chart__yaxis-tick {
    position: absolute;
    left: 0;
    right: var(--space-2);
    text-align: right;
    font-size: var(--text-xs);
    color: var(--text-muted);
    white-space: nowrap;
    transform: translateY(50%);
}

/* Unang tick (0%, pinakababa) — bottom-anchored (hindi center), para
   hindi ito lumagpas sa ilalim ng --vbar-plot-height box. */
.vbar-chart__yaxis-tick:first-child {
    transform: translateY(100%);
}

/* Huling tick (100%, pinakataas) — top-anchored, para hindi lumagpas
   sa itaas ng box. */
.vbar-chart__yaxis-tick:last-child {
    transform: translateY(0);
}

.vbar-chart__scroll {
    flex: 1;
    /* "auto" pa rin (hindi "hidden") — safety net lang ito ngayon
       para sa sobrang kitid na screen (maraming column pa rin,
       11 BSF sub-program), pero HINDI na dapat kailangan mag-scroll
       sa normal na desktop/tablet width — ang mga column mismo ang
       naka-flex (tingnan sa ibaba) para umangkop sa available width
       sa halip na fixed width bawat isa (hiling ng user: "diko na
       islide"). */
    overflow-x: auto;
    min-width: 0;
}

.vbar-chart__plot {
    position: relative;
    height: var(--vbar-plot-height);
    width: 100%;
}

/* Gridline — position:absolute na "left:0; right:0" laban sa
   .vbar-chart__plot (position:relative) mismo — awtomatikong
   sumasaklaw sa buong lapad nito. */
.vbar-chart__gridline {
    position: absolute;
    left: 0;
    right: 0;
    height: 1px;
    background: var(--border-color);
}

.vbar-chart__columns {
    position: relative;
    z-index: 1;
    display: flex;
    height: 100%;
    width: 100%;
}

/* "flex: 1 1 0" (hindi na fixed width) — pantay-pantay na hinahati
   ng LAHAT ng column ang available width, umaangkop nang awtomatiko
   sa laki ng screen (mas maliit sila kapag mas marami ang sub-
   program o mas makitid ang screen) — kaya hindi na kailangang
   mag-scroll sa normal na sitwasyon. "min-width: 44px" — huwag
   masyadong lumiit (mababasa pa rin ang pangalan/bar). */
.vbar-group {
    flex: 1 1 0;
    min-width: 44px;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    gap: 3px;
    padding: 0 var(--space-1);
}

/* Manipis na bar (dataviz mark spec), rounded lang sa itaas (data-end),
   flush sa ilalim (baseline) — parehong-pareho ang lapad ng dalawa.
   "flex" (hindi fixed px) para umangkop din sa lumiliit na column,
   may "max-width" lang para hindi masyadong lumapad kapag konti ang
   sub-program. */
.vbar {
    flex: 1;
    max-width: 26px;
    border-radius: 3px 3px 0 0;
    min-height: 2px;
    transition: height var(--transition-fast);
    cursor: default;
    transform-origin: bottom;
    animation: vbarGrowIn 0.5s ease-out backwards;
}

/* "scaleY" lang (hindi "height") ang ini-animate — sa height:X% na naka-
   inline per bar, "from height:0" ang aabutin ng browser bago pa man
   maka-layout nang tama (walang kilalang starting box), habang ang
   scaleY(0) → scaleY(1) ay laging tumutugma sa FINAL height, kahit ano
   pang halaga ang naka-inline dito. */
@keyframes vbarGrowIn {
    from { transform: scaleY(0); }
}

/* Mobile-only na listahan (tingnan ang @media sa ibaba) — tago by
   default sa desktop, ang ".vbar-chart__body" (yung totoong chart) ang
   nakikita doon. */
.vbar-mobile-list {
    display: none;
}

.vbar-chart__labels {
    display: flex;
    width: 100%;
    margin-top: var(--space-2);
    padding-top: var(--space-3);
    border-top: 1px solid var(--border-color);
}

.vbar-label-col {
    flex: 1 1 0;
    min-width: 44px;
    padding: 0 var(--space-1);
    text-align: center;
    animation: fadeInUp 0.4s ease-out backwards;
}

/* 2-linyang clamp (hindi 1 lang, madalas mahaba ang pangalan ng
   sub-program, hal. "Health, Nutrition and Environmental Protection")
   — "title" attribute pa rin ang buong pangalan (tooltip) kung
   naputol. */
.vbar-label-col__name {
    font-size: var(--text-xs);
    color: var(--text-secondary);
    font-weight: var(--weight-semibold);
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    line-height: 1.3;
    min-height: calc(1.3em * 2);
}

.vbar-label-col__delta {
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    margin-top: var(--space-1);
    font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------------
   8B. QUICK LINKS GRID (Dashboard — Quick Print)
   --------------------------------------------------------------------- */
.quick-links-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: var(--space-3);
}

.quick-links-grid__item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    background: var(--surface-page);
    transition: border-color var(--transition-fast), background var(--transition-fast);
}

.quick-links-grid__item:hover {
    border-color: var(--color-primary);
    background: var(--color-primary-tint-weak);
}

.quick-links-grid__label {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    color: var(--text-primary);
    line-height: var(--leading-tight);
}

.quick-links-grid__label svg {
    color: var(--text-muted);
    flex-shrink: 0;
}

/* ---------------------------------------------------------------------
   9. BUTTONS
   --------------------------------------------------------------------- */
.btn {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-4);
    border-radius: var(--radius-md);
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    border: 1px solid transparent;
    cursor: pointer;
    transition: background var(--transition-fast), border-color var(--transition-fast);
}

.btn--primary {
    background: var(--color-primary);
    color: var(--text-on-primary);
}

.btn--primary:hover {
    background: var(--color-primary-hover);
    text-decoration: none;
}

.btn--secondary {
    background: var(--surface-card);
    color: var(--text-primary);
    border-color: var(--border-color-strong);
}

.btn--secondary:hover {
    background: var(--gray-50);
    text-decoration: none;
}

.btn--danger {
    background: var(--status-critical);
    color: #fff;
}

.btn--danger:hover {
    background: #b52f2f;
    text-decoration: none;
}

/* --- Bulk select (checkbox per row + "N selected" action bar) ---
   Reusable sa BAWAT list na may delete: Form3 personnel, Form2A projects
   (Klase A/B), Form2/Form1A particulars — isang beses lang gawa ang
   pattern na 'to, tingnan ang updateBulkBar()/toggleBulkSelect() sa
   kani-kanyang JS file (parehong ID convention, duplicated code — walang
   shared JS file ang project na ito, gaya ng postForm()/showToast()). */
.bulk-action-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-2) var(--space-4);
    margin-bottom: var(--space-3);
    background: var(--status-critical-bg);
    border: 1px solid var(--status-critical);
    border-radius: var(--radius-md);
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    color: var(--status-critical);
}

.row-select-cell {
    display: flex;
    align-items: center;
    gap: var(--space-1);
}

/* ---------------------------------------------------------------------
   9a2. LOGIN PAGE — bahagyang mas "branded"/pino ang itsura kaysa sa
   ibang plain na pages (unang makikita ng sinumang treasurer, kaya
   dapat maganda ang unang impression), pero hindi sobra/flashy — dapat
   pa rin mukhang seryoso/opisyal na gobyernong financial tool.
   --------------------------------------------------------------------- */
.page-login {
    /* Ang buong LABAS ng ".login-split" box (hindi ito, sarili niyang
       gradient na 'yon) — dating "-weak" tint lang papunta sa
       surface-page (parehong halos-puti na kulay, #eaf1fb -> #f7f9fc,
       kaya kahit gradient talaga, mukhang plain white pa rin sa mata).
       Dito, mas TUNAY na kulay ang ginamit (--color-primary-tint,
       hindi na "-weak"), UMAABOT sa BUONG height (100%, hindi na
       55%), PLUS dalawang malabo/malaking "blob glow" (radial-gradient,
       walang extra HTML/SVG kailangan — layer lang ng background),
       parehong ugali ng mga blob sa illustration panel sa kanan, para
       may pagkakaugnay ang buong page. */
    background:
        radial-gradient(650px circle at 10% 12%, rgba(24, 79, 149, 0.12), transparent 60%),
        radial-gradient(550px circle at 92% 85%, rgba(24, 79, 149, 0.10), transparent 58%),
        linear-gradient(160deg, var(--color-primary-tint) 0%, var(--surface-page) 100%);
}

.login-card {
    /* Mas mabigat na shadow kaysa sa normal na ".card" (--shadow-sm) —
       ito lang ang nag-iisang focal element sa buong page, dapat
       kapansin-pansin ang "pag-lutang" nito sa ibabaw ng background. */
    box-shadow: var(--shadow-lg);
}

/* Dalawang-column na layout (form sa kaliwa, illustration panel sa
   kanan) — tingnan ang includes/login_art.php para sa kanang bahagi. */
.login-split {
    display: flex;
    width: 100%;
    max-width: 900px;
    margin: 0 var(--space-6);
    /* Gradient "frame" — UMAABOT SA BUONG login-split (parehong kaliwa
       AT kanan), hindi lang sa illustration side, para pareho ang
       background sa likod ng dalawang panig — dito na lang mag-"pop"
       bilang HIWALAY na lumulutang na card ang ".login-split__card" sa
       kaliwa (tingnan sa ibaba), sa halip na basta direktang kulay
       niya rin ang buong kaliwang kalahati. */
    background: linear-gradient(160deg, var(--color-primary-tint-weak) 0%, var(--surface-page) 100%);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    overflow: hidden;
    animation: modalEnter 0.25s ease-out;
}

.login-split__left {
    flex: 0 0 400px;
    padding: var(--space-8);
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.login-split__card {
    /* Mas mabigat na shadow kaysa sa normal na ".card" (--shadow-sm) —
       dapat kapansin-pansin ang "paglutang" nito sa ibabaw ng gradient
       frame sa likod nito. */
    box-shadow: var(--shadow-lg);
}

.login-split__art {
    flex: 1;
    min-width: 300px;
    position: relative;
    overflow: hidden;
}

.login-split__art-blobs {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
}

.login-split__art-content {
    position: relative;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    /* "flex-end" (hindi na "center") — dahil ang "tao"/desk mismo ay
       nasa ILALIM-GITNA na ng SVG background (tingnan ang login_art.php),
       kaya dapat nasa ILALIM na lang ang caption text, hindi na
       basta-basta sa dead-center ng buong panel (mag-o-overlap na 'yon
       sa ulo/katawan ng silhouette). */
    justify-content: flex-end;
    text-align: center;
    padding: var(--space-8);
}

.login-split__art-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-full, 999px);
    background: var(--surface-card);
    color: var(--color-primary);
    box-shadow: var(--shadow-lg);
}

.login-split__art-badge--sm {
    position: absolute;
    width: 48px;
    height: 48px;
}

/* Nakalutang ang 3 maliliit na badge sa ITAAS na bahagi ng panel
   (paligid ng ulo ng silhouette), hindi na sa gitna/ilalim — para
   hindi sila mag-overlap sa katawan/desk sa ibaba. */
.login-split__art-badge--1 { top: 14%; left: 12%; }
.login-split__art-badge--2 { top: 10%; right: 15%; }
.login-split__art-badge--3 { top: 36%; right: 8%; }

.login-split__art-caption {
    max-width: 260px;
    font-size: var(--text-sm);
    color: var(--text-secondary);
    line-height: var(--leading-normal);
}

/* ---------------------------------------------------------------------
   LOGIN PAGE — ANIMATION. Dalawang klase: (1) "entrance" — isang beses
   lang, papasok nang paisa-isa ang bawat piraso (brand -> card ->
   badges -> caption), gamit ang PAREHONG "fadeInUp" keyframe na ginamit
   na sa ibang parte ng app (donut chart legend, atbp.) — hindi na
   kailangang gumawa ng bago. (2) "ambient" — walang-hanggan, mahinang
   float ng mga blob/badge, para may buhay ang page habang nakatingin
   ang user sa form — NAKA-GUARD sa prefers-reduced-motion (unang beses
   ito gamitin sa buong app na ito — dito lang muna, dahil ito lang ang
   may TULOY-TULOY/infinite na motion; yung "entrance" ay isang beses
   lang at napakaikli, hindi na kailangang i-guard, kagaya ng ibang
   fadeInUp sa app na ito). */
.login-split__brand {
    animation: fadeInUp 0.4s ease-out 80ms backwards;
}

.login-split__brand-type {
    display: inline-block;
    position: relative;
}

.login-split__card--enter {
    animation: fadeInUp 0.45s ease-out 160ms backwards;
}

.login-split__art-badge--enter {
    animation: fadeInUp 0.45s ease-out backwards;
}

.login-split__art-badge--1.login-split__art-badge--enter { animation-delay: 260ms; }
.login-split__art-badge--2.login-split__art-badge--enter { animation-delay: 330ms; }
.login-split__art-badge--3.login-split__art-badge--enter { animation-delay: 400ms; }

.login-split__art-caption--enter {
    animation: fadeInUp 0.45s ease-out 480ms backwards;
}

@media (prefers-reduced-motion: no-preference) {
    /* Mahinang "paglutang" — 4-6s bawat cycle (napakabagal, hindi
       dapat mapansin agad na "gumagalaw", ambient lang), magkaibang
       tagal/timing bawat isa para hindi mukhang naka-sync/robotic. */
    .login-blob {
        animation: loginBlobFloat 7s ease-in-out infinite;
    }
    .login-blob--1 { animation-duration: 8s; }
    .login-blob--2 { animation-duration: 6.5s; animation-delay: -2s; }
    .login-blob--3 { animation-duration: 5.5s; animation-delay: -4s; }

    /* Ang bawat badge ay may DALAWANG animation nang SABAY (entrance
       fadeInUp + walang-hanggang loginBadgeFloat) — kailangang PAREHONG
       compound selector (".login-split__art-badge--N.login-split__art-badge--enter",
       kaparehong specificity ng base rule sa itaas) para talagang
       ma-override ito, hindi lang "animation-delay" na hiwalay (ang
       "animation" shorthand kasi ay pinapalitan NANG BUO ang property,
       hindi puwedeng "idagdag na lang" ang pangalawang animation sa
       hiwalay na rule). */
    .login-split__art-badge--1.login-split__art-badge--enter {
        animation: fadeInUp 0.45s ease-out 260ms backwards, loginBadgeFloat 4.5s ease-in-out 0s infinite;
    }
    .login-split__art-badge--2.login-split__art-badge--enter {
        animation: fadeInUp 0.45s ease-out 330ms backwards, loginBadgeFloat 4.5s ease-in-out -1.5s infinite;
    }
    .login-split__art-badge--3.login-split__art-badge--enter {
        animation: fadeInUp 0.45s ease-out 400ms backwards, loginBadgeFloat 4.5s ease-in-out -3s infinite;
    }

    /* Yung "tao" sa desk — mahinang paghinga/bob (hindi kagaya ng
       blob/badge float na malaki ang galaw, dito konti lang, 2px, para
       hindi mukhang lumulundag) + blinking text-cursor sa loob ng
       monitor niya (nag-e-encode, parang aktibong nagta-type). */
    .login-person {
        animation: loginPersonBob 5s ease-in-out infinite;
        transform-origin: 50% 100%;
    }

    .login-person__cursor {
        animation: loginCursorBlink 1.1s linear infinite;
    }

    /* Pangalan ng system — "nagta-type" siya papasok (parang kasabay ng
       nag-e-encode na "tao" sa illustration), tapos may caret na
       kumurap nang ilang beses lang (3x) at tumitigil na — hindi
       walang-hanggan kagaya ng ambient float sa itaas, dahil malapit
       ito sa email/password field, ayaw nating may laging-kumukurap na
       bagay habang nagta-type ang totoong user ng password niya. Isang
       beses lang ang buong sequence na 'to kaya "entrance" siya sa
       diwa, pero mas mahaba/mas kumplikado kaysa sa ibang fadeInUp
       entrance dito kaya hiwalay pa ring naka-guard sa
       prefers-reduced-motion (hindi tulad ng ibang maiikling entrance
       na hindi na kailangang i-guard). GUMAMIT NG clip-path, HINDI
       width — kung width ang iaanimate (0 -> buong lapad), kailangan
       mo munang HULAAN o SUKATIN (JS) ang eksaktong lapad ng text bago
       mag-start, at kung mali/hindi eksakto 'yon, "aadjust" ang laki ng
       box pagkatapos mag-type (na siyang aktwal na nangyari, na-report
       ng user). Sa clip-path, hindi nagbabago ang laki/layout ng box
       kahit kailan — mula frame 1, buo na ang espasyong inuukupa
       niya sa page, ang nagbabago lang ay kung gaano karami ang
       nakikitang bahagi (paint-only), kaya hindi na posible ang
       ganitong klaseng bug. */
    .login-split__brand-type {
        clip-path: inset(0 100% 0 0);
        animation: loginTypewriterReveal 1.7s steps(34, end) 300ms 1 forwards;
    }

    .login-split__brand-type::after {
        content: '';
        position: absolute;
        top: 2px;
        bottom: 2px;
        right: -4px;
        width: 2px;
        background: var(--color-primary);
        opacity: 0;
        animation: loginTypewriterCaret 0.7s step-end 2000ms 3 forwards;
    }
}

@keyframes loginBlobFloat {
    0%, 100% { transform: translate(0, 0); }
    50% { transform: translate(-3%, -4%); }
}

@keyframes loginBadgeFloat {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-8px); }
}

@keyframes loginPersonBob {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-2px); }
}

@keyframes loginCursorBlink {
    0%, 45% { opacity: 1; }
    50%, 100% { opacity: 0; }
}

@keyframes loginTypewriterReveal {
    to { clip-path: inset(0 0 0 0); }
}

@keyframes loginTypewriterCaret {
    0%, 49% { opacity: 1; }
    50%, 100% { opacity: 0; }
}

/* Sa maliit na screen, itago na lang ang illustration panel (dekorasyon
   lang naman ito) — bumalik sa dating simpleng isang-column na form,
   gaya ng ginawa na natin sa ibang pages (tingnan ang body.has-mobile-nav). */
@media (max-width: 860px) {
    .login-split__art {
        display: none;
    }

    .login-split__left {
        flex: 1;
    }
}

/* ---------------------------------------------------------------------
   DASHBOARD — ENTRANCE ANIMATION. Kapareho ng diwa ng sa login page:
   mabilis na fadeInUp lang, isang beses, walang ambient/infinite dito
   (hindi tulad ng login art) — greeting header muna, tapos yung 3 stat
   card nang paisa-isa. Naka-scope sa "body.page-dashboard" dahil GENERIC
   ang .page-header/.stat-card classes (ginagamit din sa ibang pages
   tulad ng form1a.php/besf.php/manage_users.php) — kung hindi ito
   naka-scope, maa-apektuhan din sana ang mga 'yon. Hindi na kailangang
   i-guard sa prefers-reduced-motion (isang beses lang at napakaikli,
   kagaya ng ibang fadeInUp entrance sa app na ito). */
body.page-dashboard .page-header {
    animation: fadeInUp 0.35s ease-out 40ms backwards;
}

body.page-dashboard .stat-card {
    animation: fadeInUp 0.35s ease-out backwards;
}

body.page-dashboard .stat-card:nth-child(1) { animation-delay: 100ms; }
body.page-dashboard .stat-card:nth-child(2) { animation-delay: 160ms; }
body.page-dashboard .stat-card:nth-child(3) { animation-delay: 220ms; }

/* ---------------------------------------------------------------------
   9b. LOGIN FORM INPUTS — ginamit lang sa login.php sa ngayon, pero
       generic na pangalan ang class dahil puwede rin itong magamit
       balang araw sa ibang simpleng form.
   --------------------------------------------------------------------- */
.login-label {
    display: block;
    font-size: var(--text-sm);
    color: var(--text-secondary);
    margin-bottom: var(--space-2);
}

.login-input {
    display: block;
    width: 100%;
    padding: var(--space-2) var(--space-3);
    margin-bottom: var(--space-4);
    font-family: var(--font-sans);
    font-size: var(--text-base);
    color: var(--text-primary);
    background: var(--surface-card);
    border: 1px solid var(--border-color-strong);
    border-radius: var(--radius-md);
    box-sizing: border-box;
}

/* Maliit na icon sa KALIWANG gilid ng email/password field sa login.php
   (person/lock) — parehong diwa ng .amount-field, pero dekorasyon lang
   (walang function/click), kaya "pointer-events: none" (para dumaan
   diretso ang click/tap papunta sa input mismo sa likod nito). */
.field-icon-left {
    position: relative;
}

.field-icon-left .login-input {
    padding-left: calc(var(--space-3) + 26px);
}

.field-icon-left__icon {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
    pointer-events: none;
}

/* "Show/hide password" toggle sa login.php — parehong diwa ng
   .amount-field (isang absolutely-positioned na button/icon sa loob ng
   input), pero sa KANANG gilid dito sa halip na kaliwa. */
.password-field {
    position: relative;
}

.password-field .login-input {
    padding-right: calc(var(--space-3) + 28px);
}

.password-field__toggle {
    position: absolute;
    top: 0;
    right: 0;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    border: none;
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
    padding: 0;
}

.password-field__toggle:hover {
    color: var(--text-primary);
}

/* "input" lang, HINDI "select" — ang CSS :read-only ay tumutugma sa
   KAHIT ANONG element na hindi text-editable bilang default (kasama na
   ang <select>, dahil hindi ito "type-able" kailanman), kaya kung
   generic ".login-input:read-only" lang ang gamit, MAAAPEKTUHAN ang
   LAHAT ng dropdown sa buong app (Sector, atbp.) — parang naka-disable
   kahit hindi naman. Dapat "input" lang, hindi kailanman "select". */
input.login-input:read-only {
    color: var(--text-muted);
    background: var(--surface-page);
    cursor: not-allowed;
}

/* Required-field marker sa label (hal. "PPA Description *") — pula, para
   agad mapansin, pero HINDI kasing-lakas ng buong error text (icon +
   text lang gaya ng .badge), simpleng asterisk lang. */
.login-label__required {
    color: var(--status-critical);
}

/* Naka-toggle via JS kapag sinubukang i-submit ang form nang blangko pa
   ang isang required field — pulang border, katulad ng .cell-input
   pattern pero para sa .login-input (modal forms). Naaalis ito agad sa
   susunod na 'input' event (tingnan ang js/klase_b.js). */
.login-input.is-invalid {
    border-color: var(--status-critical);
}

/* Peso prefix sa loob ng isang money input (hal. sa "+ Add Project"
   modal) — WALANG epekto sa aktwal na VALUE ng input (parang "visual
   only" na overlay lang ito sa itaas), kaya hindi na kailangang
   baguhin ang parseAmount()/format_peso() logic kahit saan. */
.amount-field {
    position: relative;
}

.amount-field__prefix {
    position: absolute;
    left: var(--space-3);
    top: 50%;
    transform: translateY(-50%);
    color: var(--text-muted);
    font-size: var(--text-base);
    pointer-events: none;
}

.amount-field .login-input {
    padding-left: calc(var(--space-3) + 14px);
}

/* ANG native <select> ARROW: bawat browser may sariling built-in
   drawing nito, at hindi ito palaging sumusunod sa lapad/padding na
   itinakda natin — kaya minsan "lumalampas" o sumisiksik ito sa gilid.
   Solusyon: "appearance: none" muna para PATAYIN ang built-in arrow,
   tapos gagawa tayo ng SARILI nating arrow gamit ang isang maliit na
   SVG bilang background-image — palagi na itong eksaktong kasya sa
   loob ng box, kahit anong browser pa.

   PAALALA: sa Edge/IE, HINDI SAPAT ang "appearance: none" mag-isa —
   may HIWALAY pang built-in arrow doon na "::-ms-expand" ang tawag
   (espesyal na "pseudo-element" na Edge/IE lang ang may alam), kaya
   kung hindi rin natin ito isasara, DALAWANG arrow ang lalabas nang
   magkatabi (yung sarili nating SVG + yung likas na Edge/IE arrow) —
   ito talaga ang naging "maraming arrow" na nakita mo dati. */
select.login-input {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    padding-right: var(--space-8);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%23526079' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 7.5L10 12.5L15 7.5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right var(--space-3) center;
    background-size: 16px;
}

select.login-input::-ms-expand {
    display: none;
}

/* Maliit na bersyon ng select.login-input — ginagamit sa mga compact na
   inline dropdown (hal. Statutory Fund Settings modal, per-barangay
   fiscal year override sa manage_users.php). MAHALAGA: HUWAG i-override
   ang padding-right dito (kailangan pa rin ng buong var(--space-8) para
   sa custom arrow SVG sa itaas — kung babawasan ito via inline style,
   magkakapatong ang text sa arrow icon). */
.login-input--compact {
    width: auto;
    padding-top: var(--space-1);
    padding-bottom: var(--space-1);
    padding-left: var(--space-2);
    font-size: var(--text-xs);
    flex-shrink: 0;
}

/* Kapag DISABLED ang isang select, wala nang arrow na ipinapakita
   (hindi lang pinapalitan ng mas magaan na kulay) — dahil hindi naman
   ito puwedeng i-click sa ngayon, mas malinaw kung wala na lang
   talagang arrow (hindi na rin nagkakaroon ng chance na mag-duplicate
   ang arrow kung paano man iba ang pag-render ng ibang browser sa
   disabled na dropdown). */
select.login-input:disabled {
    background-image: none;
}

.login-input:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-primary-tint);
}

.login-input:disabled {
    background: var(--gray-50);
    color: var(--text-muted);
    cursor: not-allowed;
}

.login-label__hint {
    color: var(--text-muted);
    font-weight: var(--weight-regular);
    text-transform: none;
    letter-spacing: normal;
}

.btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}
.btn:disabled:hover {
    background: var(--surface-card);
}
.btn--primary:disabled:hover {
    background: var(--color-primary);
}

/* ---------------------------------------------------------------------
   10. TOAST NOTIFICATIONS (kapalit ng alert() — hindi ito ni-block ang
       buong screen, lumalabas sa gilid, nawawala rin nang tahimik)
   --------------------------------------------------------------------- */
.toast-stack {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: var(--z-toast);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-2);
}

.toast {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    min-width: 200px;
    padding: var(--space-2) var(--space-3);
    background: var(--gray-900);
    color: var(--gray-0);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    font-size: var(--text-xs);
}

.toast--success { border-left: 3px solid var(--status-good); }
.toast--warning { border-left: 3px solid var(--status-warning-icon); }
.toast--critical { border-left: 3px solid var(--status-critical); }

/* ---------------------------------------------------------------------
   11. DATA TABLE (base — palalawakin pa sa Form 2 grid mismo)
   --------------------------------------------------------------------- */
.data-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--text-sm);
}

.data-table th {
    text-align: left;
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    padding: var(--space-2) var(--space-3);
    border-bottom: 1px solid var(--border-color);
}

.data-table td {
    padding: var(--space-3);
    border-bottom: 1px solid var(--border-color);
    color: var(--text-primary);
}

.data-table td.is-numeric,
.data-table th.is-numeric {
    text-align: right;
}

/* =====================================================================
   12. FORM 2 GRID — ito ang "spreadsheet-style" na exception sa buong
   app. Lahat ng iba pang screen ay app-na-app ang dating; dito lang
   dahil dito talaga paulit-ulit ang pag-encode ng numero.
   ===================================================================== */

/* Column widths — IISANG SET lang ito, ginagamit parehas ng sticky
   "column labels" header (div-based, hindi totoong <table>) AT ng
   <colgroup> ng bawat tunay na <table> sa baba. Kaya kahit magkahiwalay
   na tables ang GA/bawat BSF sub-program/SPA, magkakatugma pa rin ang
   lapad ng mga column — parang isa lang silang tuloy-tuloy na grid. */
/* Na-rebalance (2026-08-14) — mas malaki na ang espasyo ng Description
   (ang mismong laman/content ng bawat linya) at Amount, pinaliit ang
   BAIP Ref./Performance Indicator/Target — madalas na blangko ang mga
   ito sa maraming row (lalo na ang mga auto-flow gaya ng Honoraria/
   Bonuses), kaya nauubos lang doon ang espasyo kung pantay-pantay ang
   paghati. Iisang set pa rin ito (tingnan ang paalala sa itaas), kaya
   apektado LAHAT ng Form 2 table (GA/bawat BSF sub-program/SPA) nang
   magkatugma pa rin. --f2-col-actions HINDI ginalaw — ginagamit din ito
   ng form3_render.php para sa sarili nitong Actions column.
   Pinaliit PA (2026-08-14, part 2) — kagaya ng Form 1-A, kailangan pang
   mag-zoom-out ng user, dating 1264px minimum ang kabuuang lapad
   (masyadong malaki para sa mas maliliit na screen). Bagong total: ~960px. */
:root {
    --f2-col-desc: 320px;
    --f2-col-code: 75px;
    --f2-col-baip: 70px;
    --f2-col-output: 140px;
    --f2-col-indicator: 110px;
    --f2-col-target: 85px;
    --f2-col-amount: 120px;
    --f2-col-actions: 44px;
}

/* Sa Form 2 lang, hindi tulad ng ibang pages, hindi tumataas ang buong
   page kapag na-scroll — nakapirmi ang sidebar/header, at ang GRID MISMO
   ang may sariling scroll area (para gumana ang sticky footer totals). */
.main--grid-page {
    height: 100vh;
    overflow: hidden;
}

.grid-scroll-area {
    flex: 1;
    min-height: 0;
    overflow: auto;
    padding: 0 var(--space-10);
}

.form2-search-bar {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: 0 var(--space-10);
    margin: 0 0 var(--space-3);
}

.form2-search-bar .login-input {
    max-width: 420px;
    margin-bottom: 0;
}

.form2-search-bar__count {
    font-size: var(--text-sm);
    color: var(--text-muted);
    white-space: nowrap;
}

/* "Column titles" sa pinakaunahan ng grid — TOTOONG <table> ito ngayon
   (may sariling <thead>), gumagamit ng PAREHONG .entry-table class +
   render_colgroup() gaya ng lahat ng ibang table sa baba nito — kaya
   garantisadong magkatugma na ang lapad ng bawat column (iisang
   mekanismo na lang, table-layout:fixed + colgroup, sa likod ng
   dalawa — hindi na hinuhulaan ng isang hiwalay na div/grid). */
.entry-header-table {
    position: sticky;
    top: 0;
    z-index: 10;
    background: var(--surface-page);
    margin-bottom: var(--space-4);
}

.entry-header-table th {
    padding: var(--space-1) var(--space-3);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    text-align: left;
    border-bottom: 1px solid var(--border-color);
    border-right: 1px solid var(--border-color);
}

.entry-header-table th:last-child {
    border-right: none;
}

.entry-header-table th.is-numeric {
    text-align: right;
}

.entry-section {
    margin-top: var(--space-6);
}

.entry-section__title {
    font-size: var(--text-md);
    font-weight: var(--weight-semibold);
    color: var(--text-primary);
    margin-bottom: var(--space-3);
}

.entry-table {
    width: 100%;
    min-width: 960px;
    border-collapse: collapse;
    table-layout: fixed;
    background: var(--surface-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    overflow: hidden;
}

/* Column titles para sa Klase B tables (GAD/1% BCPC/1% SC-PWD, tingnan
   ang klase_b_page_body.php) — IISANG <table> lang ito (hindi tulad ng
   Form 2, na maraming hiwalay na <table> kaya kailangan doon ng
   sarili-nitong "sticky header table" na trick), kaya sapat na ang
   normal na <thead> DIRESTO sa loob ng parehong .entry-table — awtomatiko
   nang tumutugma ang lapad sa <colgroup>, at awtomatiko ring nagiging
   invisible ang mga column na naka-"klase-b-hidden-col" (Expense Label/
   tracking fields) dahil column-level (hindi per-cell) ang visibility:
   collapse — sakop na nito ang thead AT tbody nang sabay. */
.entry-table thead th {
    padding: var(--space-2) var(--space-3);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    text-align: left;
    background: var(--gray-50);
    border-bottom: 1px solid var(--border-color);
    border-right: 1px solid var(--border-color);
}

.entry-table thead th:last-child {
    border-right: none;
}

.entry-table thead th.is-numeric {
    text-align: right;
}

/* Form 2 lang ang talagang kailangan ng 1308px floor sa itaas (sarili
   niyang .grid-scroll-area, sinadyang hindi umuurong ang mga column) —
   ang Form 2A (Klase A/B: 20% DF, BDRRM, GAD, BCPC, SC-PWD) ay gumagamit
   din ng .entry-table PERO gusto ng buong table na kumasya sa view nang
   hindi na kailangang mag-slide pahalang, kaya % ang <col> width ng mga
   ito (tingnan ang render_form2a_colgroup()/render_klase_b_colgroup())
   sa halip na fixed px — kailangan lang alisin dito ang min-width para
   talagang umurong ang buong table kasabay ng mas maliit na screen. */
.entry-table--fluid {
    min-width: 0;
}

.entry-table td {
    padding: var(--space-2) var(--space-3);
    border-bottom: 1px solid var(--border-color);
    border-right: 1px solid var(--border-color);
    vertical-align: middle;
}

.entry-table td:last-child {
    border-right: none;
}

/* Mas compact PARA LANG sa Form 2 mismo (naka-scope sa #grid-scroll-area,
   iisa lang ang gumagamit nito) — hindi ito ginagalaw sa GAD/1% BCPC/
   1% SC-PWD/20% DF/5% BDRRM (na gumagamit din ng .entry-table pero WALA
   sa loob ng #grid-scroll-area), dahil hindi naman doon humihiling ang
   user, at fluid % widths na naman ang mga column doon (iba ang sitwasyon). */
#grid-scroll-area .entry-table td {
    padding: var(--space-1) var(--space-3);
    font-size: var(--text-sm);
}

.entry-table tr:last-child td {
    border-bottom: none;
}

/* Ang group-header-row/subtotal-row/spa-fund-label ay gumagamit ng
   colspan (sumasakop sa maraming column bilang isang malaking cell) —
   walang saysay ang vertical divider sa loob nito, kaya tinatanggal
   natin ito dito lang. */
.group-header-row td,
.subtotal-row td,
.spa-fund-label td,
.add-line-row td,
.child-wrap-row td {
    border-right: none;
}

/* Group header row — hal. "PERSONAL SERVICES (PS)" o pangalan ng
   sub-program. Hindi ito entry, kaya iba ang itsura. */
.group-header-row td {
    background: var(--gray-50);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-secondary);
    padding-top: var(--space-3);
    padding-bottom: var(--space-3);
}

/* "Ghost" row — hal. Honoraria bago pa na-encode ang Form 3. Walang
   laman sa database, paalala/placeholder text lang ito, kaya sinadya
   nating gawing MALINAW na naiiba ito sa isang totoong entry row
   (dashed border sa halip na solid, italic, walang input). */
.entry-row--placeholder td {
    padding: var(--space-2) var(--space-3);
    border-bottom: 1px dashed var(--border-color-strong);
    border-right: none;
    font-size: var(--text-sm);
    font-style: italic;
    color: var(--text-muted);
    background: var(--gray-50);
}

.group-header-row__subtotal {
    float: right;
    font-variant-numeric: tabular-nums;
    color: var(--text-muted);
}

.subtotal-row td {
    background: var(--color-primary-tint-weak);
    font-weight: var(--weight-semibold);
    color: var(--text-primary);
}

/* Statutory compliance line — kasunod agad ng grand-total row (tingnan
   ang form2a_page_body.php/klase_b_page_body.php), ipinapakita ang
   Required/Actual laban sa statutory percentage ng fund na 'to (hal.
   "GAD (Gender and Development): ₱114,000.00 / ₱190,061.70 (5% of Total
   Receipts)"), gamit ang parehong report na ginagamit na ng Dashboard
   (build_statutory_compliance_report(), includes/validation_engine.php)
   — para consistent ang datos, hindi na kailangang balikan pa ang
   Dashboard para malaman kung kulang pa ba ang fund na 'to. */
.statutory-compliance-row td {
    background: var(--surface-page);
    font-size: var(--text-sm);
    color: var(--text-secondary);
    padding-top: var(--space-3);
    padding-bottom: var(--space-3);
}

.statutory-compliance-row .badge {
    margin-left: var(--space-2);
}

/* --- Entry row (isang Object of Expenditure) --- */
.entry-row__desc {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.entry-row__desc-main {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
}

/* Ang listahan ng AKTWAL na naka-link na Klase B project (hal. "1% BCPC:
   conduct garantisadong pambata incentive program") ay nasa loob na ng
   particulars-list mismo ngayon (render_klase_b_source_row() sa
   form2_render.php, .particular-row--readonly) — kaparehong itsura ng
   totoong particulars, hindi na hiwalay na naka-cramp na text dito sa
   description cell (hiling ng user: "parang particular din yan"). */

.row-expand-toggle {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    border: none;
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
    font-size: var(--text-sm);
    transition: transform var(--transition-fast);
    display: flex;
    align-items: center;
    justify-content: center;
}

.row-expand-toggle.is-expanded {
    transform: rotate(90deg);
}

.row-expand-toggle:disabled {
    visibility: hidden;
}

.entry-row__object-name {
    font-size: var(--text-sm);
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.entry-row__account-code {
    font-size: var(--text-xs);
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

/* Ang inputs SA LOOB mismo ng cell — walang border/background bago
   ma-focus, para hindi parang normal na form ang dating, kundi
   direktang "type mo na lang dito" tulad ng spreadsheet. */
.cell-input {
    width: 100%;
    min-width: 0;
    border: 1px solid transparent;
    background: transparent;
    padding: var(--space-1) var(--space-2);
    border-radius: var(--radius-sm);
    font-family: var(--font-sans);
    font-size: var(--text-sm);
    color: var(--text-primary);
    transition: border-color var(--transition-fast), background var(--transition-fast);
    /* Kapag masikip na ang column (fluid % width, tingnan ang
       .entry-table--fluid), "…" ang lalabas sa dulo ng putol na text sa
       halip na basta mag-abrupt cut — malinaw kung na-truncate lang ang
       laman (klik/focus para makita ang buo, gumagana pa rin 'to kahit
       naka-ellipsis, sini-scroll lang papunta sa cursor). */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cell-input:hover {
    background: var(--gray-50);
}

.cell-input:focus {
    outline: none;
    border-color: var(--color-primary);
    background: var(--surface-card);
    box-shadow: 0 0 0 3px var(--color-primary-tint);
}

/* "input" lang bago ":read-only" — tingnan ang parehong paalala sa
   ".login-input:read-only" (malapit sa .login-input base rule): kung ".cell-input:read-only"
   lang, maaapektuhan ang MGA <select class="cell-input"> na hindi naman
   dapat mukhang naka-disable (hal. yung Expense Label dropdown) dahil
   HINDI kailanman ":read-write" ang <select>, kaya laging tumutugma sa
   ":read-only" kahit hindi 'yon ang intensyon. ":disabled" lang ang
   dapat generic (parehong input/select, dahil totoong estado 'yon). */
input.cell-input:read-only,
.cell-input:disabled {
    color: var(--text-muted);
    background: transparent;
    cursor: not-allowed;
}

.cell-input--amount {
    text-align: right;
    font-variant-numeric: tabular-nums;
    font-weight: var(--weight-medium);
}

.entry-row__actions {
    text-align: center;
}

.row-delete-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border: none;
    background: transparent;
    color: var(--status-critical);
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-size: var(--text-sm);
    transition: background var(--transition-fast), color var(--transition-fast), transform var(--transition-fast);
}

.row-delete-btn:hover {
    background: var(--status-critical-bg);
    color: var(--status-critical);
    transform: scale(1.08);
}

/* Save state indicator — maliit na dot sa tabi ng Amount cell habang
   nagta-type/nagse-save, para may instant visual feedback bago pa
   lumabas ang toast. */
.save-indicator {
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    margin-left: var(--space-2);
    background: transparent;
    transition: background var(--transition-fast);
}

.save-indicator.is-pending { background: var(--status-warning-icon); }
.save-indicator.is-saved { background: var(--status-good); }
.save-indicator.is-error { background: var(--status-critical); }

/* Klase B (GAD/BCPC/SC-PWD) "Target (Form 2 Line)" column — readable
   label ("GA · Honoraria") + isang maliit na button para i-link/baguhin. */
/* Dating nasa <td> mismo ang "display:flex" na 'to — SIRA pala nito ang
   normal na table-cell height-stretching (na-verify: lumiit ang <td> sa
   KALAHATI ng row height, may kakaibang blangkong espasyo/guhit sa
   ilalim nang laman). Kaya ngayon, INNER <div> na lang ang may flex
   (tingnan ang render_klase_b_project_row() sa klase_b_render.php) —
   normal na block-level element ang <div> na 'to, kaya awtomatiko na
   lang siyang "sumusunod" sa taas ng <td> nito (walang special CSS
   rule na kailangan pang idagdag). */
.klase-b-target-cell {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

/* Gustong makita ang BUONG target label nang hindi naka-ellipsis (kahit
   pang-dalawang linya, hal. "BSF › Agriculture › Training Expenses") —
   kaya pinalawak na ang Target column mismo (tingnan ang
   render_klase_b_colgroup() sa klase_b_render.php, 9% -> 14%) para
   bihira na lang mag-wrap. Kapag nag-wrap pa rin (mahabang sub-program/
   object name), tinatanggap na lang na mas mataas ang row na 'yon kumpara
   sa kapitbahay nito — mas mabuti kesa itago ang impormasyon. */
.klase-b-target-label {
    font-size: var(--text-xs);
    color: var(--text-primary);
    min-width: 0;
    flex: 1;
}

.klase-b-target-label[data-empty="1"] {
    color: var(--status-warning);
    font-style: italic;
}

.klase-b-standalone-badge {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-1) var(--space-3);
    border-radius: var(--radius-full, 999px);
    background: var(--status-warning-bg);
    color: var(--status-warning);
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    white-space: nowrap;
}

/* --- Child rows (particulars) — div-based, HINDI modal, lumalabas
   nang diretso sa ilalim ng parent row nang may smooth transition. --- */
.child-wrap-row td {
    padding: 0;
    background: var(--gray-50);
}

.child-rows {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows var(--transition-slow);
}

.child-rows.is-open {
    grid-template-rows: 1fr;
}

.child-rows__inner {
    overflow: hidden;
    /* Default ng grid items ay min-height:auto — hindi papayagan
       shrink-in below sa laki ng laman nito. Kailangan i-override
       para gumana ang 0fr collapse trick sa .child-rows. */
    min-height: 0;
}

.particular-row {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-1) var(--space-4) var(--space-1) 32px;
}

.particular-row__desc {
    flex: 1;
    min-width: 0;
}

.particular-row__amount {
    width: var(--f2-col-amount);
    flex-shrink: 0;
}

.particular-row__actions {
    width: var(--f2-col-actions);
    flex-shrink: 0;
    text-align: center;
}

/* Particular row SPECIFIC sa Form 2 — GRID (hindi flex, di-tulad ng
   ibang particular-row na WALANG ganitong modifier), eksaktong
   tumutugma sa 8 column ng parent entry-row (render_colgroup() sa
   form2_render.php: Desc/Code/BAIP/Output/Indicator/Target/Amount/
   Actions) — kaparehong dahilan/pattern ng .particular-row--form1a sa
   ibaba. Hiling ng user: ipakita ang Expected Output/Performance
   Indicator/Target bilang column (dating "Details" badge na lang),
   AT tumpak na ma-align ang Amount sa TAMANG column nito sa parent —
   parehong solusyon ito ng GRID (eksaktong track width), hindi flex. */
.particular-row--form2 {
    display: grid;
    /* fr (RATIO), HINDI var(--f2-col-*) (fixed px) — MAHALAGA ito: ang
       totoong <table> (table-layout:fixed + width:100%) ay
       PROPORTIONAL na PINALALAKI ang mga <col> width kapag mas malapad
       ang aktwal na table kaysa sa SUM ng mga ito (320+75+70+140+110+
       85+120+44 = 964px, madalas mas malapad pa ang totoong table kaysa
       rito) — kaya HINDI eksaktong 320px ang totoong Description column,
       mas malapad pa. Kung fixed px lang ang gagamitin dito sa grid
       (hindi proportional), MANATILING 964px lang ang buong grid,
       mas MAIKLI kaysa totoong table — kaya "lumiliit"/lumilihis nang
       papalayo ang bawat susunod na column (Output/Indicator/Target/
       Amount), mas kapansin-pansin habang papalayo sa kanan. Ang
       numero (320/75/70/.../44) ay PAREHONG RATIO ng var(--f2-col-*)
       sa itaas — kung magbabago man ang mga variable na 'yon, dapat
       ding i-update ito. */
    grid-template-columns: 320fr 75fr 70fr 140fr 110fr 85fr 120fr 44fr;
    /* "start" (hindi "center", tingnan ang base .particular-row) — dahil
       puwede nang mag-WRAP (2+ linya) ang text sa ilalim, hiling ng user,
       sa halip na i-truncate ng "..." — mas malinis tumingin ang top-
       aligned kaysa center kapag magkaiba ang taas ng bawat column. */
    align-items: start;
    /* gap: 0 dito (i-o-override ang WARISANG gap: var(--space-2) mula sa
       base .particular-row) — MAHALAGA ito: ang totoong parent <table>
       (#grid-scroll-area .entry-table) ay WALANG extra gap sa pagitan ng
       column, PADDING lang sa LOOB ng bawat <td> (parehong-parehong
       laki, tingnan sa baba). Kung may CSS grid "gap" pa dagdag dito,
       LUMALAYO ang bawat susunod na column sa TAMANG posisyon nito kada
       column (gap × index), kaya "hindi pantay sa title column" — mas
       kapansin-pansin habang papalayo sa kanan (mas maraming column
       bago rito, mas maraming naipong "gap"). */
    gap: 0;
    /* padding: 0 horizontal dito (i-o-override ang WARISANG "32px kaliwa,
       16px kanan" mula sa base .particular-row) — ITO PALA ang TUNAY na
       dahilan bakit hindi pantay ang Expected Output (at lahat ng column
       pagkatapos ng Description): NILILIPAT ng padding-left NG BUONG
       GRID CONTAINER ang LAHAT ng column pantay-pantay ng 32px pakanan —
       hindi lang ang Description, kasama na ang Code/BAIP/Output/
       Indicator/Target/Amount/Actions. Ang 32px "indent" (para malaman
       na "child" ng parent row ito) ay dapat sa LOOB LANG ng Description
       column mismo mangyari (tingnan ang .particular-row__desc sa baba),
       hindi sa BUONG grid — kung hindi, sumasabay ito sa lahat ng
       column, kaya lagpas sa tamang posisyon nila laban sa totoong
       <table> (na walang katulad na indent sa alinmang column). */
    padding: var(--space-1) 0;
}

.particular-row--form2 .particular-row__desc {
    display: flex;
    align-items: flex-start;
    gap: var(--space-1);
    min-width: 0;
    /* 44px kaliwa = 32px (nesting indent, dating nasa buong row) + 12px
       (var(--space-3), parehong base padding ng totoong <td>) — DITO NA
       LANG ito, sa LOOB ng column na 'to mismo (320px, --f2-col-desc),
       kaya HINDI naaapektuhan ang posisyon ng mga susunod na column. */
    padding: 0 var(--space-3) 0 44px;
}

.particular-row--form2 .particular-row__desc-text {
    min-width: 0;
    overflow-wrap: break-word;
}

.particular-row--form2 .particular-row__cell {
    min-width: 0;
    overflow-wrap: break-word;
    color: var(--text-secondary);
    font-size: var(--text-sm);
    font-style: italic;
    padding: 0 var(--space-3);
}

.particular-row--form2 .particular-row__amount {
    width: auto;
    font-style: italic;
    padding: 0 var(--space-3);
}

.particular-row--form2 .particular-row__actions {
    /* WALANG horizontal padding dito (di-tulad ng ibang column) —
       dalawang maliliit na icon button lang ang laman (edit+delete), sa
       loob ng maikling 44px na column, kaya kailangan ang BUONG espasyo
       para dito, gaya ng ORIHINAL (pre-grid) na batayan nito. */
    width: auto;
}

.particular-row--add .cell-input {
    color: var(--text-muted);
}

.add-particular-btn {
    width: 26px;
    height: 26px;
    border: 1px dashed var(--border-color-strong);
    background: transparent;
    color: var(--color-primary);
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-weight: var(--weight-bold);
}

.add-particular-btn:hover {
    background: var(--color-primary-tint-weak);
}

.breakdown-badge {
    margin-left: var(--space-2);
}

/* --- Tags column (GAD / 1% BCPC / 1% SC-PWD) — 3 maliliit na toggle
   button, hindi checkbox, para hindi kumain ng espasyo. Klik = on/off,
   nagsa-save agad (walang debounce, discrete click naman ito). GA at
   BSF entries lang ito, wala sa SPA rows. --- */
/* --- "+ Magdagdag ng linya" row + searchable object picker --- */
.add-line-row td {
    padding: var(--space-2) var(--space-3);
}

.add-line-trigger {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    border: none;
    background: transparent;
    color: var(--color-primary);
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    cursor: pointer;
    padding: var(--space-1) var(--space-2);
    border-radius: var(--radius-sm);
}

.add-line-trigger:hover {
    background: var(--color-primary-tint-weak);
}

.object-picker {
    position: relative;
    max-width: 420px;
}

.object-picker__input {
    width: 100%;
    padding: var(--space-2) var(--space-3);
    border: 1px solid var(--border-color-strong);
    border-radius: var(--radius-md);
    font-family: var(--font-sans);
    font-size: var(--text-sm);
}

.object-picker__input:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-primary-tint);
}

.object-picker__list {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    max-height: 260px;
    overflow-y: auto;
    background: var(--surface-card);
    border: 1px solid var(--border-color-strong);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    z-index: var(--z-dropdown);
}

.object-picker__option {
    display: flex;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-2) var(--space-3);
    cursor: pointer;
    font-size: var(--text-sm);
}

.object-picker__option:hover,
.object-picker__option.is-highlighted {
    background: var(--color-primary-tint-weak);
}

.object-picker__option-code {
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
}

/* Object na naka-encode na sa section na ito — HINDI na itinatago sa
   listahan (dating ganon, tingnan ang paalala sa filterObjects() sa
   form2.js) dahil pipiliin man ito ulit, mag-a-add na lang ito ng
   BAGONG particular sa ilalim ng existing linya, hindi na mag-e-error. */
.object-picker__option-used {
    font-size: var(--text-xs);
    color: var(--text-muted);
    background: var(--gray-100);
    border-radius: var(--radius-sm);
    padding: 1px var(--space-2);
    white-space: nowrap;
}

.object-picker__empty {
    padding: var(--space-3);
    font-size: var(--text-sm);
    color: var(--text-muted);
    text-align: center;
}

/* --- BSF sub-program collapsible group (native <details>, walang
   JS na kailangan para dito — libre na ang keyboard/screen-reader
   support). --- */
.subprogram-group {
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    margin-bottom: var(--space-3);
    background: var(--surface-card);
    overflow: hidden;
}

.subprogram-group > summary {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    padding: var(--space-3) var(--space-4);
    cursor: pointer;
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    color: var(--text-primary);
    text-align: left;
    list-style: none;
}

.subprogram-group > summary::-webkit-details-marker {
    display: none;
}

.subprogram-group > summary::before {
    content: '\25B8';
    display: inline-block;
    margin-right: var(--space-2);
    color: var(--text-muted);
    transition: transform var(--transition-fast);
}

.subprogram-group[open] > summary::before {
    transform: rotate(90deg);
}

.subprogram-group__body {
    padding: 0 var(--space-4) var(--space-4);
}

.subprogram-group__subtotal {
    margin-left: auto;
    font-variant-numeric: tabular-nums;
    color: var(--text-secondary);
    font-weight: var(--weight-regular);
}

/* --- SPA section — mas simple, walang cascade, walang child rows --- */
.spa-fund-label td {
    background: var(--gray-50);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-secondary);
}

/* --- Sticky footer — HINDI kasama sa scroll area, laging makikita --- */
.grid-footer-totals {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: var(--space-8);
    padding: var(--space-4) var(--space-10);
    background: var(--gray-900);
    color: var(--gray-0);
    border-top: 1px solid var(--border-color);
}

.grid-footer-totals__item {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.grid-footer-totals__item--grand {
    margin-left: auto;
    align-items: flex-end;
}

.grid-footer-totals__label {
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: rgba(255, 255, 255, 0.6);
}

.grid-footer-totals__value {
    font-size: var(--text-md);
    font-weight: var(--weight-semibold);
    font-variant-numeric: tabular-nums;
}

.grid-footer-totals__item--grand .grid-footer-totals__value {
    font-size: var(--text-lg);
    font-weight: var(--weight-bold);
    color: var(--color-primary-tint);
}

/* =====================================================================
   13. FORM 1-A — mas simple kaysa Form 2 (3 column lang: Paglalarawan,
   Account Code, Halaga), pero muling ginagamit ang parehong entry-row/
   particular-row/child-rows classes sa itaas.
   ===================================================================== */
/* Pinaliit (2026-08-14) mula 460/140/150 papuntang 320/90/100 — dating
   1350px minimum ang kabuuang lapad (460+140+150×5), sobrang laki para
   sa mas maliliit na screen (kailangan pang mag-zoom-out ng user).
   Sinubukan munang 380/100/120 (1080px) — hindi pa rin sapat sa 1366px
   window (na-verify sa screenshot, na-cut pa rin ang Budget Year column)
   dahil kasama pa ang 264px sidebar + 80px page padding. Bagong total:
   320+90+100×5 = 910px — mas may margin na. */
:root {
    --f1a-col-desc: 320px;
    --f1a-col-code: 90px;
    --f1a-col-amount: 100px;
}

/* Particular row SPECIFIC sa Form 1-A — GRID (hindi flex, di-tulad ng
   shared .particular-row base) dahil 7 column na ang parent row nito
   (Desc/Code/Past Year/1st Sem/2nd Sem/Total/Budget Year), hindi lang
   isa ang "amount" gaya ng Form 2. Sa flex, isang "flex:1" na desc lang
   ang tumutukoy sa lahat ng natitirang espasyo — walang paraan doon na
   tumpak na ma-align ang 2 amount input (Total, Budget Year) sa TAMANG
   column nila (5 at 6) nang hindi rin isinasama ang 3 column sa
   pagitan (Past Year/1st Sem/2nd Sem, walang laman ang particular doon)
   sa espasyong iyon. Sa GRID, eksaktong track width (--f1a-col-amount)
   ang ginagamit, tapos "grid-column" ang nagtuturo kung saang column
   dapat lumagay ang bawat piraso — garantisadong tutugma sa <colgroup>
   ng totoong table. */
.particular-row--form1a {
    display: grid;
    /* ANIM (6) na track lang — TUMPAK na tumutugma sa 7 tunay na <col>
       ng parent table (Desc+Code magkasama sa 1fr, tapos limang
       --f1a-col-amount) — WALANG ikapitong "Actions" column dito,
       dahil WALA talagang ganoong column ang parent table ng Form
       1-A (hindi kagaya ng Form 2) — laging fixed/hindi buburahin ang
       10 income line items nito. */
    grid-template-columns:
        1fr
        var(--f1a-col-amount)
        var(--f1a-col-amount)
        var(--f1a-col-amount)
        var(--f1a-col-amount)
        var(--f1a-col-amount);
    gap: var(--space-2);
    align-items: center;
}

.particular-row--form1a .particular-row__desc {
    /* Dito na isinisiksik ang delete button (hindi sa Budget Year) —
       dahil kailangang MANATILING EKSAKTO ang 150px ng DALAWANG amount
       column (Total, Budget Year) para talagang tumugma sa numero sa
       parent row sa itaas. Ang desc column ("1fr", walang ibang numero
       na dapat kasing-lapad) ang mas ligtas na lugar para dito — kahit
       bahagyang lumiit ang text input, hindi ito kasing-kapansin-pansin
       gaya kung lumiit ang isang amount column. */
    grid-column: 1;
    display: flex;
    align-items: center;
    gap: var(--space-1);
}

.particular-row--form1a .particular-row__desc .cell-input {
    flex: 1;
    min-width: 0;
}

.particular-row__amount--total {
    grid-column: 5; /* Total */
}

.particular-row__amount--budget-year {
    grid-column: 6; /* Budget Year (Proposed) — buong 150px, walang ibang laman */
}

.form1a-table {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
    background: var(--surface-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    overflow: hidden;
    margin-bottom: var(--space-4);
}

/* Particular row ng BESF (besf.php AT print_besf.php — SHARED na
   function ito, tingnan ang render_besf_income_rows() sa
   includes/besf_render.php). Naka-scope sa DALAWANG ancestor (.form1a-table
   PARA sa interactive, .print-table PARA sa print) dahil parehong
   nakikita ito ng dalawang page (naka-load ang style.css sa print_besf.php
   din) — isang beses lang isinulat, gumagana sa dalawa. */
.form1a-table .besf-particular-row td,
.print-table .besf-particular-row td {
    color: var(--text-secondary);
    font-style: italic;
}

.form1a-table .besf-particular-row td:not(.is-numeric),
.print-table .besf-particular-row td:not(.is-numeric) {
    padding-left: 32px;
}

.form1a-table .besf-particular-row td.is-numeric,
.print-table .besf-particular-row td.is-numeric {
    text-align: center;
}

.form1a-table th {
    padding: var(--space-1) var(--space-3);
    border-bottom: 1px solid var(--border-color-strong);
    background: var(--gray-50);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    text-align: left;
}

.form1a-table th.is-numeric {
    text-align: right;
}

/* Ang "Total" column ay PLAIN TEXT lang (walang <input> sa loob, di
   tulad ng ibang amount column) — kaya kailangan natin itong i-right-
   align nang direkta rito, dahil walang .cell-input--amount na
   susuporta rito. Idinagdag din ang parehong lapad ng padding ng
   isang .cell-input (space-2) bilang extra padding-right, para
   TALAGANG magkatugma ang posisyon ng numero rito laban sa mga
   numerong nasa loob ng <input> sa magkabilang gilid nito (may sariling
   dagdag na padding ang mga input na 'yon bukod sa padding ng <td>). */
.form1a-table td.is-numeric {
    text-align: right;
    font-weight: var(--weight-medium);
    padding-right: calc(var(--space-3) + var(--space-2));
}

.form1a-th-hint {
    text-transform: none;
    font-weight: var(--weight-regular);
    letter-spacing: normal;
}

.form1a-table td {
    padding: var(--space-1) var(--space-3);
    border-bottom: 1px solid var(--border-color);
    vertical-align: middle;
    font-size: var(--text-sm);
}

.form1a-table tr:last-child td {
    border-bottom: none;
}

.subtotal-row--grand td {
    background: var(--gray-900);
    color: var(--gray-0);
    font-size: var(--text-md);
    font-weight: var(--weight-bold);
}

/* =====================================================================
   14. FORM 3 — simpleng listahan (walang master catalog, walang
   particulars). Muling ginagamit ang entry-table/entry-row/cell-input
   classes.
   ===================================================================== */
:root {
    --f3-col-position: 240px;
    --f3-col-name: 220px;
    --f3-col-amount: 160px;
}

.form3-table {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
    background: var(--surface-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    overflow: hidden;
}

.form3-table th {
    text-align: left;
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    padding: var(--space-2) var(--space-3);
    border-bottom: 1px solid var(--border-color-strong);
    background: var(--gray-50);
}

.form3-table th.is-numeric {
    text-align: right;
}

/* Read-only na display na lang ang mga row ngayon (dati, <input> —
   doon nagmula ang right-align niya via .cell-input--amount) — kaya
   kailangan na natin itong i-right-align nang direkta rito, kung
   hindi, hindi ito tutugma sa right-aligned na header sa itaas. */
.form3-table td.is-numeric {
    text-align: right;
}

.form3-table td {
    padding: var(--space-2) var(--space-3);
    border-bottom: 1px solid var(--border-color);
    vertical-align: middle;
}

.form3-table tr:last-child td {
    border-bottom: none;
}

/* =====================================================================
   15. FORM 2A — project lists (20% DF / 5% BDRRM Fund). Muling
   ginagamit ang entry-table/entry-row/group-header-row classes.
   ===================================================================== */
:root {
    --f2a-col-desc: 280px;
    --f2a-col-output: 220px;
}

/* Itinatago ang Past Year/1st Sem/2nd Sem/Total tracking columns AT ang
   Expense Label column sa TABLE ng GAD/1% BCPC/1% SC-PWD (tatlo, tingnan
   ang $hideTrackingColumns sa klase_b_page_body.php — laging true na
   ngayon) — "visibility: collapse" sa <col> mismo (hindi sa mga <td>)
   ang pinakamalinis na paraan dito: nawawala ang buong column (walang
   gap) kahit table-layout:fixed, AT hindi na kailangang galawin ang
   render_klase_b_project_row() (nananatili ang lahat ng <td> sa DOM/PHP,
   tinatago lang sa CSS) — importante ito dahil parehong umaasa ang
   js/klase_b.js (openKlaseBModal, na nagbabasa MULA sa mga cell na 'to;
   saka saveEditedKlaseBProject, na naghahambing AT sumusulat PABALIK sa
   mga cell na 'to) sa pagkakaroon pa rin ng mga cell sa DOM. Ang mismong
   PORSYENTO ng column width (hindi lang ang pagtago) ay kailangan ding
   baguhin nang hiwalay — tingnan ang render_klase_b_colgroup($hideTracking)
   sa klase_b_render.php. Ang mga field sa "+ Magdagdag ng Proyekto" MODAL
   ay SINADYANG hindi ginagalaw — kailangan pa rin doon ang Expense Label
   AT ang Past Year/1st Sem/2nd Sem/Total. */
.klase-b-hidden-col {
    visibility: collapse;
}

/* =====================================================================
   16. MODAL (<dialog>) — unang beses ginamit sa Form 3 add/edit.
   Karamihan sa "modal behavior" (centering, backdrop, ESC to close) ay
   LIBRE na mula sa <dialog> element mismo — ang CSS dito ay para lang
   sa ITSURA (panel styling, spacing), hindi sa mekanismo ng pagbukas/
   pagsara.
   ===================================================================== */
.modal {
    padding: 0;
    border: none;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    width: 100%;
    max-width: 480px;
    /* Kailangan dito para hindi mag-double-scroll — kung mataas ang
       laman, ".modal__body" na lang mismo (may sarili nang max-height +
       overflow-y:auto) ang dapat mag-scroll; kung "visible"/walang
       overflow rule ang buong ".modal"/<dialog> mismo, posibleng
       MAGKAROON pa ito ng sarili nitong scrollbar sa LABAS ng
       scrollbar ng modal__body (dalawang magkapatong na scrollbar). */
    overflow: hidden;
    animation: modalEnter 0.2s ease-out;
}

/* Para sa mas maraming field (hal. "Magdagdag ng PPA" — 8 field). */
.modal--wide {
    max-width: 640px;
}

/* Para sa modal na may TABLE sa loob (hal. "All Bonuses" sa Form 3) —
   kailangan ng mas malawak na espasyo para hindi na-truncate ang mga
   text column (Position Title/Name of Incumbent) kasabay ng mga amount
   column. */
.modal--extra-wide {
    max-width: 960px;
}

/* Mahahabang modal (maraming field, gaya ng Add Project/Add PPA) ay
   kadalasang umaabot na mismo sa max-height nila (tingnan ang
   .modal__body sa ibaba) — kaya masikip/malapit na sa gilid ng screen
   ang footer. Pinaliit ang padding ng header/footer PARA LANG dito
   (hindi sa base .modal__header/footer — maiiksing modal, gaya ng
   confirm dialogs, ang gumagamit non'un, hindi kailangan doon ang
   ganitong pag-compact) — kahit konting bawas, may extra breathing
   room na ang buong modal sa itaas/ibaba nito. */
.modal--wide .modal__header {
    padding: var(--space-4) var(--space-6);
}

.modal--wide .modal__footer {
    padding: var(--space-3) var(--space-6);
}

/* Mas compact na laman (mas maliit na padding/font) para sa LAHAT ng
   .form3-table — parehong sa aktwal na Form 3 page (#form3-table) AT sa
   "All Bonuses" modal (#form3-all-bonuses-table, tingnan ang paalala sa
   .modal__body override sa ibaba) — gusto ng user na mas madaming
   personnel ang kasya sa view nang hindi na kailangang mag-scroll.
   "th" lang ang padding ang binabago (panatilihin ang --text-xs nito,
   huwag palakihin), "td" ang parehong padding AT font-size (mula sa
   default text-base 14px pababa sa text-sm 13px, mas compact ang laman). */
.form3-table th {
    padding: var(--space-1) var(--space-3);
}

.form3-table td {
    padding: var(--space-1) var(--space-3);
    font-size: var(--text-sm);
}

/* Mas maliit pa rin PARA LANG sa "All Bonuses" modal (hindi sa aktwal
   na Form 3 page mismo) — hiniling pa ulit na paliitin lampas pa sa
   pinakamaliit na text token (text-xs, 12px), kaya explicit 10px na
   ang ginamit dito sa halip na isang variable. Mas mataas ang
   specificity nito (#id td) kumpara sa ".form3-table td" sa itaas
   (.class td), kaya ito ang mananalo dito lang. */
#form3-all-bonuses-table th,
#form3-all-bonuses-table td {
    padding: var(--space-1) var(--space-3);
    font-size: 10px;
}

/* Pinapadikit ang Position Title/Name of Incumbent (column 1 at 2) sa
   isa't-isa (binabawasan lang ang GITNANG puwang sa pagitan nila) —
   iniiwan pa rin ang normal na padding sa magkabilang DULO ng dalawang
   column na 'to (kaliwa ng col 1, kanan ng col 2), para hindi masyadong
   sumiksik sa border ng table. */
#form3-all-bonuses-table th:nth-child(1),
#form3-all-bonuses-table td:nth-child(1) {
    padding-right: 0;
}

#form3-all-bonuses-table th:nth-child(2),
#form3-all-bonuses-table td:nth-child(2) {
    padding-left: 0;
}

/* Ang mga <input> (YEB/MYB, Cash Gift, Other Bonus fields) ay HINDI
   nagmamana ng font-size mula sa parent na <td> (form elements, sinadya
   ng browser default na hindi ito nagmamana) — kailangan silang i-target
   nang direkta, hindi lang yung <td> wrapper. */
#form3-all-bonuses-table .cell-input {
    font-size: 10px;
}

/* Mas mataas na max-height PARA LANG sa modal na 'to (hindi sa base
   .modal__body rule, na ginagamit ng LAHAT ng modal) — dahil mahaba ang
   listahan ng personnel dito, gusto nating mas malaking bahagi ng
   viewport ang magamit bago pa mag-scroll. */
#form3-all-bonuses-modal .modal__body {
    max-height: calc(100vh - 80px);
}

/* Bahagyang "pop in" (fade + slight scale/lift) sa pagbukas ng
   KAHIT ANONG modal sa app — hindi na basta biglaang lumalabas. */
@keyframes modalEnter {
    from {
        opacity: 0;
        transform: scale(0.96) translateY(8px);
    }
    to {
        opacity: 1;
        transform: scale(1) translateY(0);
    }
}

@keyframes modalBackdropEnter {
    from { opacity: 0; }
    to { opacity: 1; }
}

.ppa-modal-selected-object {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    margin-top: var(--space-2);
    margin-bottom: var(--space-4);
    padding: var(--space-2) var(--space-3);
    background: var(--color-primary-tint-weak);
    border: 1px solid var(--color-primary-tint);
    border-radius: var(--radius-md);
    font-size: var(--text-sm);
}

/* ANG ::backdrop: espesyal na "pseudo-element" na AWTOMATIKONG
   ginagawa ng browser sa likod ng <dialog> kapag binuksan ito via
   showModal() (hindi sa plain .show() o sa walang JS na pagpapakita) —
   dito natin ina-istilo ang madilim na overlay sa likod ng modal. */
.modal::backdrop {
    background: rgba(15, 27, 36, 0.55);
    animation: modalBackdropEnter 0.2s ease-out;
}

.modal__form {
    display: flex;
    flex-direction: column;
}

.modal__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-5) var(--space-6);
    border-bottom: 1px solid var(--border-color);
}

.modal__title {
    font-size: var(--text-lg);
    font-weight: var(--weight-semibold);
    margin: 0;
}

.modal__close {
    border: none;
    background: transparent;
    color: var(--text-muted);
    font-size: var(--text-xl);
    line-height: 1;
    cursor: pointer;
    padding: var(--space-1);
}

.modal__close:hover {
    color: var(--text-primary);
}

.modal__body {
    padding: var(--space-6);
    /* Ang <dialog> mismo ay may built-in max-height mula sa browser
       (para hindi ito lumampas sa viewport), pero WALANG kasamang
       scroll sa laman nito by default — kaya kung mas mataas ang laman
       kaysa sa max-height na 'yon, basta na lang naputol/hindi
       makikita ang sobra. Dito na lang natin sinisigurado na maski
       anong tangkad ng laman (hal. Quick Print na may 9 na link),
       ma-scroll pa rin ito sa loob ng modal. */
    max-height: calc(100vh - 160px);
    overflow-y: auto;
}

.modal__grid-2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-4);
}

.modal__footer {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--space-3);
    padding: var(--space-4) var(--space-6);
    border-top: 1px solid var(--border-color);
    background: var(--gray-50);
    border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}

/* View-only na "label: value" na listahan sa loob ng modal (hal.
   Form 3 — Bonuses breakdown). */
.bonus-view-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-3) 0;
    border-bottom: 1px solid var(--border-color);
}

.bonus-view-row:last-child {
    border-bottom: none;
}

.bonus-view-row__label {
    font-size: var(--text-sm);
    color: var(--text-secondary);
}

.bonus-view-row__value {
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
}

.bonus-view-row--total .bonus-view-row__label,
.bonus-view-row--total .bonus-view-row__value {
    font-weight: var(--weight-bold);
    color: var(--text-primary);
}

.row-edit-btn {
    width: 26px;
    height: 26px;
    border: none;
    background: transparent;
    color: var(--text-muted);
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-size: var(--text-sm);
}

.row-edit-btn:hover {
    background: var(--color-primary-tint-weak);
    color: var(--color-primary);
}

/* ---------------------------------------------------------------------
   17. RESPONSIVE — MOBILE NAV (SHARED) — hamburger button + off-canvas
   sidebar drawer + backdrop. Dating "body.page-dashboard" lang ang gamit
   nito (Dashboard-only, unang pass) — ngayong pangalawang page na ang
   gagamit din nito (Form 1-A), in-generalize na sa "body.has-mobile-nav"
   (idinadagdag sa <body> ng BAWAT page na may sariling hamburger button/
   backdrop markup, tingnan ang partials/sidebar.php + bawat *.php).
   Dashboard-specific/Form1A-specific na CONTENT overrides (stat cards,
   donut, form1a-table, atbp.) ay hiwalay pa ring naka-scope sa sarili
   nilang body class — tingnan ang 17A/17B pababa. Ang BUONG APP ay
   desktop-only pa rin by default (min-width: 1024px, walang media query)
   maliban sa mga pages na dinagdagan na natin ng "has-mobile-nav".
   --------------------------------------------------------------------- */
/* Ang wrapper na ito (button + eyebrow label) ay katabi lang ginagawa sa
   MOBILE (tingnan sa media query sa ibaba) — sa desktop, "display:none"
   pa rin ang button kaya normal block lang ang eyebrow sa loob nito,
   walang pinagbago sa itsura. */
.page-header__mobile-bar {
    display: block;
}

.mobile-nav-toggle {
    display: none; /* mobile width lang lalabas ito, tingnan sa ibaba */
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    background: var(--surface-card);
    color: var(--text-primary);
    cursor: pointer;
    flex-shrink: 0;
}

.mobile-nav-toggle:hover {
    background: var(--gray-50);
}

/* Laging naka-tago ito sa lahat ng LAPAD (kahit sa pages na wala pang
   "has-mobile-nav") — sa loob lang ng media query sa ibaba ito nagiging
   "totoong" backdrop overlay. */
.sidebar-backdrop {
    display: none;
}

@media (max-width: 768px) {
    body.has-mobile-nav {
        min-width: 0;
    }

    body.has-mobile-nav .app-shell {
        display: block; /* hindi na kailangan ang flex row — "off-canvas" na ang sidebar */
    }

    /* Sidebar → off-canvas drawer (tago by default), binubuksan ng
       hamburger button (.mobile-nav-toggle) sa page-header. */
    body.has-mobile-nav .sidebar {
        position: fixed;
        top: 0;
        left: 0;
        z-index: 50;
        width: min(84vw, 300px);
        transform: translateX(-100%);
        transition: transform var(--transition-slow);
        box-shadow: var(--shadow-lg);
    }

    body.has-mobile-nav .sidebar.is-open {
        transform: translateX(0);
    }

    body.has-mobile-nav .sidebar-backdrop {
        display: block;
        position: fixed;
        inset: 0;
        background: rgba(15, 27, 36, 0.5);
        z-index: 40;
        opacity: 0;
        pointer-events: none;
        transition: opacity var(--transition-slow);
    }

    body.has-mobile-nav .sidebar-backdrop.is-visible {
        opacity: 1;
        pointer-events: auto;
    }

    body.has-mobile-nav .mobile-nav-toggle {
        display: inline-flex;
    }

    /* Katabi na ng eyebrow label ang hamburger button (compact top
       bar), sa halip na hiwalay na row sa ibabaw nito. */
    body.has-mobile-nav .page-header__mobile-bar {
        display: flex;
        align-items: center;
        gap: var(--space-2);
        margin-bottom: var(--space-2);
    }

    body.has-mobile-nav .page-header {
        position: relative;
        padding: var(--space-5) var(--space-4) var(--space-4);
    }

    body.has-mobile-nav .page-header__title {
        font-size: var(--text-lg);
    }

    /* Title block sa itaas, action buttons (Print/Export) sa ibaba nito
       — kung magkatabi pa rin (row), hindi kasya ang malapad na "Export
       to Excel" button katabi ng title sa makipot na screen. */
    body.has-mobile-nav .page-header--actions {
        flex-direction: column;
        align-items: stretch;
    }

    /* Dashboard header action row ("FY 2027" + "Quick Print") — 2
       magkakatabing button, masikip sa makipot na screen. Payagang
       mag-wrap kung talagang kailangan, at hayaang lumaki/magkapantay
       ang dalawa (mas malaking touch target + mas madaling basahin).
       Ang bell mismo ay INALIS na dito (tingnan sa ibaba) — nasa
       taas-kanan na siya ngayon, katabi ng hamburger, hindi na kasama
       sa row na 'to. */
    body.has-mobile-nav .dashboard-header-actions {
        flex-wrap: wrap;
        width: 100%;
    }

    body.has-mobile-nav .dashboard-header-actions #fiscal-year-btn,
    body.has-mobile-nav .dashboard-header-actions #quick-print-btn {
        flex: 1;
        justify-content: center;
        white-space: nowrap;
    }

    /* Bell notification — sa taas-KANAN na ng page-header (katapat ng
       hamburger sa taas-kaliwa), sa halip na kasama sa ibabang row ng
       FY/Quick Print. "position:absolute" (base sa .page-header na
       "position:relative" sa itaas) kaya lumalabas ito sa normal na
       flex flow ng .dashboard-header-actions — walang guwang na
       naiiwan doon. Dashboard-only ang ".announcement-anchor" kaya
       "body.page-dashboard" ang scope, ligtas na hindi maapektuhan ang
       ibang pages. */
    body.page-dashboard.has-mobile-nav .announcement-anchor {
        position: absolute;
        top: var(--space-5);
        right: var(--space-4);
    }

    body.has-mobile-nav .page-body {
        padding: 0 var(--space-4) var(--space-6);
        gap: var(--space-4);
    }

    body.has-mobile-nav .card__header {
        padding: var(--space-4) var(--space-4) 0;
    }

    /* "Quick Print" (Dashboard) ay <details>/<summary> — kapag SARADO,
       ang summary mismo (na may class="card__header" din) ang may
       bottom padding (walang card__body na sumusunod). Dapat tumugma sa
       bagong mas-maliit na --space-4 padding sa itaas, hindi na yung
       desktop --space-5. */
    body.has-mobile-nav details.card:not([open]) > summary.card__header {
        padding-bottom: var(--space-4);
    }

    body.has-mobile-nav .card__body {
        padding: var(--space-4);
    }

    /* NOTE: .progress-row__top flex-wrap ay nasa base rule na ngayon
       (hindi na mobile-only) — tingnan sa itaas ng file. */
}

/* ---------------------------------------------------------------------
   17A. RESPONSIVE — MOBILE (DASHBOARD-SPECIFIC content)
   --------------------------------------------------------------------- */
@media (max-width: 768px) {
    body.page-dashboard .stat-grid {
        grid-template-columns: 1fr;
        gap: var(--space-3);
    }

    /* Ang ".stat-card" ay hindi pa nagagalaw dati (desktop padding/font-
       size pa rin) — kaya iba ang "tightness" nito kumpara sa ibang
       cards na na-adjust na sa taas (card__header/card__body). Sinasadya
       ring bawasan ang laki ng ".stat-card__value" (36px -> 28px) dahil
       ang isang mahabang halaga (hal. "₱6,978,113.00") ay hindi kasya sa
       isang linya sa 36px kapag kumitid na ang card sa telepono —
       nagiging 2 linya, halatang hindi maayos ang proportion. */
    body.page-dashboard .stat-card {
        padding: var(--space-4);
    }

    body.page-dashboard .stat-card__value {
        font-size: var(--text-xl);
    }

    /* "Hero metric" — karaniwang pattern sa mobile dashboard design:
       isang pinaka-mahalagang numero ang kapansin-pansin/una makikita,
       ang mga sumusuportang stat ay mas maliit/compact sa ibaba nito.
       Dito, "Ending Balance" ang hero (ito ang "sagot" — balanse ba o
       sobra ang plano) — "order:-1" ang nag-uunang lumitaw dito sa
       stack, kahit HULING <div> ito sa HTML mismo (huwag baguhin ang
       PHP, order lang sa CSS side). ":has()" ang gamit para malaman
       kung "good" o "critical" ang status (parehong may sariling
       nakalaang color token na, --status-good-bg/--status-critical-bg —
       ginagamit na rin ito ng badge sa ibang parte ng app). */
    body.page-dashboard .stat-card:has(.stat-card__value--good),
    body.page-dashboard .stat-card:has(.stat-card__value--critical) {
        order: -1;
        padding: var(--space-5) var(--space-4);
        border-color: transparent;
    }

    body.page-dashboard .stat-card:has(.stat-card__value--good) {
        background: var(--status-good-bg);
    }

    body.page-dashboard .stat-card:has(.stat-card__value--critical) {
        background: var(--status-critical-bg);
    }

    /* "clamp()" sa halip na direktang "--text-2xl" (36px) — malalaking
       halaga (hal. "₱6,978,113.00") ay baka hindi kumasya sa isang
       linya sa napakaliit na telepono (320-360px), kaya may safety
       margin: 28px ang pinakamaliit (parehong laki ng ibang stat-card),
       36px ang pinakamalaki, umaangkop sa pagitan batay sa lapad ng
       screen. */
    body.page-dashboard .stat-card:has(.stat-card__value--good) .stat-card__value,
    body.page-dashboard .stat-card:has(.stat-card__value--critical) .stat-card__value {
        font-size: clamp(var(--text-xl), 7vw, var(--text-2xl));
    }

    body.page-dashboard .insight-grid {
        grid-template-columns: 1fr;
    }

    /* Radial/leader-line na donut ay DESKTOP lang — walang espasyo sa
       magkabilang gilid ng bilog sa maliit na screen. Ibalik sa
       simpleng bilog + list-legend (na-hide by default, tingnan sa
       itaas). */
    body.page-dashboard .donut-panel-radial {
        display: none;
    }

    body.page-dashboard .donut-panel--mobile-only {
        display: flex;
    }

    /* Donut + legend: magkatabi (row) sa desktop, pero PATAYONG
       nakasunod na lang (column) dito — kung row pa rin ang gamit,
       hindi kasya ang 260px na bilog + legend text sa maliit na screen.
       KAILANGAN i-reset ang align-items pabalik sa "stretch" (default) —
       ang base rule (".donut-panel") ay "align-items: center" (tama
       para sa ROW direction), pero kung IWAN ito sa COLUMN direction,
       ang ".legend" ay hindi na mag-e-extend sa buong lapad (sisiksikin
       na lang sa gitna, hindi na naka-align ang % sa kanang gilid). */
    body.page-dashboard .donut-panel {
        flex-direction: column;
        align-items: stretch;
        gap: var(--space-5);
    }

    body.page-dashboard .donut-chart {
        margin: 0 auto;
    }

    /* Vertical bar chart ("Previous vs Current Budget") — masyadong
       marami ang column (11 sub-program) para ma-compress pa nang
       maayos sa maliit na screen kahit i-scroll pa (mahirap i-compare
       ang magkatabing bar kung isa-isa lang makikita), kaya SARADO na
       lang ito dito, at ang ".vbar-mobile-list" (listahan, patayong
       mini-bar bawat sub-program — "scroll pababa" sa halip na "scroll
       pakanan", mas natural sa telepono) ang lumalabas sa halip. */
    .vbar-chart__body {
        display: none;
    }

    .vbar-mobile-list {
        display: flex;
        flex-direction: column;
        gap: var(--space-3);
    }

    .vbar-mobile-item {
        padding: var(--space-3);
        border: 1px solid var(--border-color);
        border-radius: var(--radius-md);
    }

    .vbar-mobile-item__head {
        display: flex;
        justify-content: space-between;
        align-items: baseline;
        gap: var(--space-2);
        margin-bottom: var(--space-2);
    }

    .vbar-mobile-item__name {
        font-weight: var(--weight-semibold);
        font-size: var(--text-sm);
    }

    .vbar-mobile-item__delta {
        flex-shrink: 0;
        font-size: var(--text-xs);
        font-weight: var(--weight-semibold);
        font-variant-numeric: tabular-nums;
    }

    .vbar-mobile-item__row {
        display: flex;
        align-items: center;
        gap: var(--space-2);
        margin-top: var(--space-1);
    }

    .vbar-mobile-item__label {
        flex-shrink: 0;
        width: 62px;
        font-size: var(--text-xs);
        color: var(--text-muted);
    }

    .vbar-mobile-item__track {
        flex: 1;
        height: 8px;
        border-radius: 4px;
        background: var(--gray-100);
        overflow: hidden;
    }

    .vbar-mobile-item__fill {
        height: 100%;
        border-radius: 4px;
        min-width: 2px;
    }

    .vbar-mobile-item__amount {
        flex-shrink: 0;
        width: 76px;
        text-align: right;
        font-size: var(--text-xs);
        font-variant-numeric: tabular-nums;
        color: var(--text-secondary);
    }
}

/* Hiwalay na media query (HINDI naka-nest sa loob ng max-width block sa
   itaas — hindi suportado ng lahat ng browser ang nested @media sa
   plain CSS na walang build step) — ".vbar-mobile-item" mismo ay
   "display:none" pa rin sa desktop (parent nito, ".vbar-mobile-list"),
   kaya walang epekto ang animation na 'to doon, gumagana lang talaga
   kapag mobile na. */
@media (prefers-reduced-motion: no-preference) {
    .vbar-mobile-item {
        animation: fadeInUp 0.4s ease-out backwards;
    }
}

/* ---------------------------------------------------------------------
   17B. RESPONSIVE — MOBILE (FORM 1-A) — ang ".form1a-table" ay may 7
   column na puno ng editable input (Desc/Code/Past Year/1st Sem/2nd
   Sem/Total/Budget Year) — imposibleng basta paliitin ang mga column
   nito, magiging unusable. Sa halip, "card-per-row" transform: bawat
   <tr class="entry-row"> ay nagiging isang card, ang UNANG <td> (Source
   of Income Particulars) ang "pamagat" ng card, ang natitirang 6 <td>
   ay nagiging "label: value" na row gamit ang data-label attribute
   (nasa PHP, tingnan ang render_form1a_line_row() sa
   includes/form1a_render.php) bilang laman ng CSS ::before.
   --------------------------------------------------------------------- */
@media (max-width: 768px) {
    body.page-form1a .form1a-table,
    body.page-form1a .form1a-table tbody {
        display: block;
        width: 100%;
    }

    /* Hindi na kailangan ang <colgroup> fixed-% widths (block layout na,
       hindi table layout) at ang <thead> (data-label na sa mismong cell
       ang gumaganap ng papel ng column header). */
    body.page-form1a .form1a-table colgroup,
    body.page-form1a .form1a-table thead {
        display: none;
    }

    body.page-form1a .form1a-table tr.entry-row {
        display: block;
        border: 1px solid var(--border-color);
        border-radius: var(--radius-md);
        padding: var(--space-3);
        margin-bottom: var(--space-3);
        background: var(--surface-card);
    }

    /* Unang <td> (Source of Income Particulars) = "pamagat" ng card,
       hindi "label: value" na row gaya ng iba. */
    body.page-form1a .form1a-table tr.entry-row td:first-child {
        display: block;
        padding: 0 0 var(--space-2);
        border-bottom: 1px solid var(--border-color);
        margin-bottom: var(--space-2);
    }

    /* Ang natitirang 6 <td> (Account Code + 5 amount) — bawat isa
       "label: value" na row na. */
    body.page-form1a .form1a-table tr.entry-row td:not(:first-child) {
        display: flex;
        align-items: center;
        gap: var(--space-2);
        padding: var(--space-1) 0;
    }

    body.page-form1a .form1a-table tr.entry-row td[data-label]::before {
        content: attr(data-label);
        flex-shrink: 0;
        width: 110px;
        font-size: var(--text-xs);
        color: var(--text-muted);
    }

    /* Ang input mismo (na dating "width:100%" ng buong <td>) ay dapat
       na lang mag-fill ng NATITIRANG espasyo pagkatapos ng label
       (flex:1), hindi buong lapad ng card. */
    body.page-form1a .form1a-table tr.entry-row td .cell-input {
        flex: 1;
        width: auto;
        min-width: 0;
    }

    /* Manipis na hairline sa pagitan ng bawat "label: value" row —
       mas madaling basahin/tignan nang isa-isa (hal. "settings list"
       na itsura), sa halip na 6 magkakadikit na linya. */
    body.page-form1a .form1a-table tr.entry-row td:not(:first-child):not(:last-child) {
        border-bottom: 1px solid var(--border-color);
    }

    /* Ang "Budget Year" (huling field, ang PROPOSED figure — ito talaga
       ang "sagot"/resulta ng buong card) ay dapat kapansin-pansin kaysa
       sa ibang 5 field: hiwalay na section (may sariling puwang + mas
       mabigat na divider sa itaas, sa halip na parehong hairline lang),
       mas malaki/mabigat ang font ng numero. Hindi ginagalaw ang KULAY
       (nananatiling naka-ugnay sa existing ":read-only" muted-color
       convention — malinaw pa rin kung locked/derived ang value o
       hindi, size/weight lang ang dagdag na senyales ng importansya). */
    body.page-form1a .form1a-table tr.entry-row td:last-child {
        margin-top: var(--space-1);
        padding-top: var(--space-3);
        border-top: 2px solid var(--border-color-strong);
    }

    body.page-form1a .form1a-table tr.entry-row td:last-child::before {
        font-weight: var(--weight-semibold);
        color: var(--text-secondary);
    }

    body.page-form1a .form1a-table tr.entry-row td:last-child .cell-input {
        font-size: var(--text-md);
        font-weight: var(--weight-bold);
    }

    /* Group header ("1. Tax Revenue") at subtotal rows ("Total Tax
       Revenue") — colspan na "buod" lang, hindi per-field na data, kaya
       simpleng full-width block na lang (walang data-label kailangan,
       malinaw naman ang laman mula sa sarili nitong text). Binilugan
       ang gilid + may sariling margin (hindi na flat full-bleed bar)
       para tumugma sa "card" na itsura ng mga entry-row sa paligid
       nito, hindi parang natigil na table row. */
    body.page-form1a .form1a-table tr.group-header-row,
    body.page-form1a .form1a-table tr.subtotal-row {
        display: block;
        margin-bottom: var(--space-3);
    }

    body.page-form1a .form1a-table tr.group-header-row td,
    body.page-form1a .form1a-table tr.subtotal-row td {
        display: block;
        padding: var(--space-2) var(--space-3);
        border-radius: var(--radius-md);
    }

    /* Mas malaki/mabigat ang numero ng subtotal (hal. "Total Tax
       Revenue") — ito yung mga sub-total na dapat kapansin-pansin habang
       nagsa-scroll, hindi lang basta parehong laki ng ordinaryong text. */
    body.page-form1a .form1a-table tr.subtotal-row td.is-numeric {
        font-size: var(--text-md);
    }

    body.page-form1a .form1a-table tr.subtotal-row--grand td {
        border: 1px solid var(--color-primary-tint);
    }

    /* Ang "particulars breakdown" (child-wrap-row, lumalabas lang kapag
       na-expand) ay colspan="7" na td — dapat ding full-width block. */
    body.page-form1a .form1a-table tr.child-wrap-row td {
        display: block;
        padding: 0;
    }

    /* ".particular-row--form1a" ay CSS GRID sa desktop (6 fixed-px na
       track, tumutumbas sa <colgroup> ng parent table) — dito, block/
       stacked na lang, kaparehong "card-per-row" na diwa ng entry-row
       sa itaas pero mas maliit (walang sariling border/background,
       nasa loob na ng isang naka-indent na listahan). */
    body.page-form1a .particular-row--form1a {
        display: block;
        padding: var(--space-2) var(--space-3);
        border: 1px solid var(--border-color);
        border-radius: var(--radius-sm);
        margin-bottom: var(--space-2);
        background: var(--surface-page);
    }

    body.page-form1a .particular-row--form1a .particular-row__desc {
        grid-column: unset;
        margin-bottom: var(--space-2);
    }

    body.page-form1a .particular-row--form1a .particular-row__amount {
        grid-column: unset;
        width: auto;
        display: flex;
        align-items: center;
        gap: var(--space-2);
        margin-bottom: var(--space-1);
    }

    body.page-form1a .particular-row--form1a .particular-row__amount:last-child {
        margin-bottom: 0;
    }

    body.page-form1a .particular-row--form1a .particular-row__amount--total::before {
        content: "Total:";
        flex-shrink: 0;
        width: 90px;
        font-size: var(--text-xs);
        color: var(--text-muted);
    }

    body.page-form1a .particular-row--form1a .particular-row__amount--budget-year::before {
        content: "Budget Year:";
        flex-shrink: 0;
        width: 90px;
        font-size: var(--text-xs);
        color: var(--text-muted);
    }

    body.page-form1a .particular-row--form1a .particular-row__amount .cell-input {
        flex: 1;
        width: auto;
        min-width: 0;
    }

    /* --- MAS "USER-FRIENDLY" NA TOUCH TARGETS --- ang mga ito ay
       dating sinukat/idinisenyo para sa MOUSE (hover para makita, maliit
       na icon dahil eksaktong laki lang ang kailangan sa cursor) —
       hindi comportableng i-tap ng daliri. */

    /* Ang "▶" expand toggle ay 20x20px lang sa desktop — masyadong
       maliit para sa daliri (dapat ~36-44px ang minimum touch target).
       Pinalaki dito, PAREHONG laki pa rin ang icon sa loob (font-size
       hindi ginagalaw), padding na lang ang nagpapalaki ng box. */
    body.page-form1a .row-expand-toggle {
        width: 36px;
        height: 36px;
    }

    body.page-form1a .add-particular-btn,
    body.page-form1a .row-delete-btn {
        width: 34px;
        height: 34px;
    }

    /* Ang ".cell-input" ay "invisible hanggang ma-focus/ma-hover" by
       disenyo (parang spreadsheet) — pero WALANG ":hover" sa touch
       device, kaya walang paraan malaman ng user kung saan pwedeng
       i-tap/i-edit hangga't hindi pa niya na-tap. Dito, palagi nang
       may bahagyang border/background ang input mismo (hindi na
       kailangan pang i-hover/i-focus muna) — malinaw kaagad kung alin
       ang editable field. */
    body.page-form1a .form1a-table .cell-input,
    body.page-form1a .particular-row--form1a .cell-input {
        border-color: var(--border-color);
        background: var(--surface-page);
        padding: var(--space-2);
    }

    body.page-form1a .form1a-table input.cell-input:read-only {
        border-color: transparent;
        background: transparent;
    }
}

/* ---------------------------------------------------------------------
   17C. RESPONSIVE — MOBILE (BESF) — kaparehong "card-per-row" na diwa ng
   Form 1-A sa itaas, pero IBA ang hugis ng laman (besf_render.php):
   walang "entry-row"/"data-label" — plain <tr> lang, PAREHONG 7 column
   PALAGI (Particulars, Account Code, Past Year, 1st Sem, 2nd Sem, Total,
   Budget Year — besf.php ay laging "particularsFirst:true", kaya fixed
   ang pagkakasunod), kaya nth-child + static ::before content na lang
   (walang PHP change kailangan). Blangkong <td> (zero amount — tingnan
   ang render_besf_amount()) ay ":empty" na lang, itinatago.
   --------------------------------------------------------------------- */
@media (max-width: 768px) {
    body.page-besf .form1a-table,
    body.page-besf .form1a-table tbody {
        display: block;
        width: 100%;
    }

    body.page-besf .form1a-table colgroup,
    body.page-besf .form1a-table thead {
        display: none;
    }

    /* Group header ("1. Tax Revenue ... subtotal") — colspan na "buod"
       lang, simpleng full-width block. */
    body.page-besf .form1a-table tr.group-header-row {
        display: block;
        margin-bottom: var(--space-2);
    }

    body.page-besf .form1a-table tr.group-header-row td {
        display: block;
        padding: var(--space-2) var(--space-3);
        border-radius: var(--radius-md);
    }

    /* Subtotal rows ("Total Tax Revenue", "TOTAL RECEIPTS") — variable
       ang bilang ng numeric <td> dito (depende sa params ng
       render_form1a_subtotal_row()), kaya hindi maaasahan ang nth-child
       — "block" na lang bawat <td>, gaano man karami. */
    body.page-besf .form1a-table tr.subtotal-row {
        display: block;
        margin-bottom: var(--space-2);
    }

    body.page-besf .form1a-table tr.subtotal-row td {
        display: block;
        padding: var(--space-1) var(--space-3);
        border-radius: var(--radius-md);
        text-align: left;
    }

    body.page-besf .form1a-table tr.subtotal-row td.is-numeric {
        text-align: left;
        font-size: var(--text-md);
        padding-top: 0;
    }

    body.page-besf .form1a-table tr.subtotal-row--grand td {
        border: 1px solid var(--color-primary-tint);
    }

    /* --- Data rows: plain <tr> (income/expenditure line) AT
       ".besf-particular-row" — parehong 7 column, IISANG "card"
       treatment. --- */
    body.page-besf .form1a-table tr:not(.group-header-row):not(.subtotal-row) {
        display: block;
        border: 1px solid var(--border-color);
        border-radius: var(--radius-md);
        padding: var(--space-3);
        margin: 0 0 var(--space-2);
        background: var(--surface-card);
    }

    /* Particular row (child ng isang line item) — konting kaibahan sa
       itsura (naka-indent, mas maliwanag na background) para malinaw pa
       ring "kabilang sa parent" ito, kagaya ng desktop treatment nito
       (italic + indent). */
    body.page-besf .form1a-table tr.besf-particular-row {
        margin-left: var(--space-4);
        background: var(--surface-page);
    }

    /* Unang <td> (Particulars, laging una dito) = pamagat ng card. */
    body.page-besf .form1a-table tr:not(.group-header-row):not(.subtotal-row) td:first-child {
        display: block;
        padding: 0 0 var(--space-1);
        font-weight: var(--weight-semibold);
        font-style: normal;
        border-bottom: none;
    }

    /* 2nd <td> (Account Code) — maliit, muted na subtitle sa ilalim ng
       pamagat. Itinatago kung blangko (maraming particular row walang
       account code). */
    body.page-besf .form1a-table tr:not(.group-header-row):not(.subtotal-row) td:nth-child(2) {
        display: block;
        padding: 0 0 var(--space-2);
        font-size: var(--text-xs);
        font-style: normal;
        color: var(--text-muted);
        border-bottom: 1px solid var(--border-color);
        margin-bottom: var(--space-2);
    }

    body.page-besf .form1a-table tr:not(.group-header-row):not(.subtotal-row) td:nth-child(2):empty {
        display: none;
        border-bottom: none;
        margin-bottom: 0;
    }

    /* Ang 5 numeric column (Past Year/1st Sem/2nd Sem/Total/Budget
       Year) — "label: value" na row, LAKTAWAN kung blangko. */
    body.page-besf .form1a-table tr:not(.group-header-row):not(.subtotal-row) td:nth-child(n+3) {
        display: flex;
        justify-content: space-between;
        align-items: center;
        gap: var(--space-2);
        padding: var(--space-1) 0;
        padding-right: 0;
        text-align: right;
        border-bottom: 1px solid var(--border-color);
    }

    body.page-besf .form1a-table tr:not(.group-header-row):not(.subtotal-row) td:nth-child(n+3):empty {
        display: none;
        border-bottom: none;
    }

    body.page-besf .form1a-table tr:not(.group-header-row):not(.subtotal-row) td:nth-child(n+3)::before {
        flex-shrink: 0;
        font-size: var(--text-xs);
        font-weight: var(--weight-regular);
        color: var(--text-muted);
        text-align: left;
    }

    body.page-besf .form1a-table tr:not(.group-header-row):not(.subtotal-row) td:nth-child(3):not(:empty)::before { content: "Past Year (Actual)"; }
    body.page-besf .form1a-table tr:not(.group-header-row):not(.subtotal-row) td:nth-child(4):not(:empty)::before { content: "1st Semester (Actual)"; }
    body.page-besf .form1a-table tr:not(.group-header-row):not(.subtotal-row) td:nth-child(5):not(:empty)::before { content: "2nd Semester (Estimate)"; }
    body.page-besf .form1a-table tr:not(.group-header-row):not(.subtotal-row) td:nth-child(6):not(:empty)::before { content: "Total"; }
    body.page-besf .form1a-table tr:not(.group-header-row):not(.subtotal-row) td:nth-child(7):not(:empty)::before { content: "Budget Year (Proposed)"; }

    /* "Budget Year" (huling column) = ang "sagot"/resulta ng buong card
       — dapat kapansin-pansin, kaparehong ugali ng Form 1-A sa itaas. */
    body.page-besf .form1a-table tr:not(.group-header-row):not(.subtotal-row) td:nth-child(7):not(:empty) {
        margin-top: var(--space-1);
        padding-top: var(--space-2);
        border-top: 2px solid var(--border-color-strong);
        border-bottom: none;
        font-size: var(--text-md);
        font-weight: var(--weight-bold);
    }

    body.page-besf .form1a-table tr:not(.group-header-row):not(.subtotal-row) td:last-child {
        border-bottom: none;
    }
}
