/* ============================================================================
   Shared 3-theme token system + card component (27-Jul-2026).
   ----------------------------------------------------------------------------
   Every page that needed Dark/Light/Blue support so far (UserManagement,
   Module Launcher, FinanzasBanano) built its own private color values and its
   own card CSS from scratch — same colors typed three times under three
   different class prefixes (the um-prefixed tokens scoped to .um-page, the
   lin-prefixed tokens scoped to .lin-root, .fe-banano-tile's own hardcoded
   hex). Every new page repeated the same Blue-theme gap, the same "light
   canvas should be white not grey" fix, the same grid-toggle-vs-opaque-card
   interaction bug, because there was nothing shared to fix ONCE.

   This file is that shared layer. It does two things:
   1. Defines the pg- and um-prefixed tokens GLOBALLY on body.tw-shell (not
      inside a page-scoped class), for all three themes, using the exact values already
      established on UserManagement (the reference implementation — see
      reference_icon_rail_sidebar_and_3_themes.md in project memory for the
      full per-theme token table this was copied from).
   2. Defines .tw-tile — a themed, clickable card/tile component (icon chip +
      title + meta) any page can drop in directly. It already handles: Blue's
      transparent-card-over-canvas look with glass blur, Dark/Light's opaque
      card look, and the grid-toggle occlusion fix (a transparent card must
      repaint the canvas itself so ancestor grid-lines don't bleed through it;
      an opaque card blocks them for free).

   New pages should use .tw-tile (or read var(--pg-surface) / var(--um-accent)
   etc. directly) instead of inventing their own palette. Existing pages
   (UserManagement, Module Launcher) were NOT migrated onto this file in this
   pass — their own CSS already matches these values exactly, so nothing to
   fix there; migrating them to actually reference these shared rules (instead
   of duplicating the same values locally) is a safe follow-up cleanup, not
   done here to avoid touching already-verified pages.
   ============================================================================ */

/* ── Dark (default — no data-bs-theme/data-tw-theme attribute needed).
   larkon-light-palette.css has a MORE specific pre-existing rule,
   `html[data-tw-theme="dark"][data-menu-color] body.tw-shell { --pg-surface:
   #2d2c2b; }`, that silently overrides a plain `body.tw-shell` selector
   whenever Dark is explicitly selected (not just the no-attribute default
   state) — so every selector variant below is listed explicitly, with
   !important, to guarantee this always wins regardless of which dark-theme
   attribute combination is present. ── */
html[data-tw-theme="dark"] body.tw-shell,
html[data-tw-theme="dark"][data-menu-color] body.tw-shell,
body.tw-shell {
    --pg-surface:      #1a1a1f !important;
    --pg-surface-2:    #23232a !important;
    --pg-border:       #26262b !important;
    --um-radius:       14px !important;
    --um-shadow:       0 1px 2px rgba(0,0,0,.3), 0 10px 28px -12px rgba(0,0,0,.5) !important;
    --um-accent:       #d97757 !important;
    --um-accent-soft:  #3d2c24 !important;
    --um-accent-ink:   #e2917a !important;
    --um-accent-grad:  linear-gradient(135deg, #d97757, #c96442) !important;
    --um-amber:        #c8956c !important;   --um-amber-soft:   #3a322a !important;
    --um-red:          #e07a63 !important;   --um-red-soft:     #3a2620 !important;
    --um-blue:         #9fb4c7 !important;   --um-blue-soft:    #2e3339 !important;
    --um-success:      #8fce9f !important;   --um-success-soft: #22301f !important;
}

/* Generic Bootstrap .card in Light theme reads a SEPARATE, older token
   (--larkon-card, from larkon-light-palette.css's client-approved palette,
   #EAEAEA) instead of --pg-surface — a second, disconnected token family for
   the exact same "card background" concept. Align it to the same white the
   rest of the app's light theme now uses (27-Jul-2026: "cards match theme
   design in all pages, like users page"), so every page using plain .card
   (most of the FinanzasExportacion dashboards) gets the same white cards for
   free, not just the pages already migrated onto --pg-surface. */
html[data-bs-theme="light"] {
    --larkon-card: #ffffff !important;
}

/* ── Light — !important for the same reason as the Dark block above (a
   competing rule with an extra attribute could otherwise silently win). ── */
html[data-bs-theme="light"] body.tw-shell {
    --pg-surface:      #ffffff !important;
    --pg-surface-2:    #efefed !important;
    --pg-border:       #e9e9e7 !important;
    --pg-text:         #18181c !important;
    --pg-text-2:       #55555e !important;
    --pg-text-3:       #9d9da6 !important;
    --um-radius:       14px !important;
    --um-shadow:       0 1px 2px rgba(26,35,51,.05), 0 8px 24px -12px rgba(26,35,51,.12) !important;
    --um-accent:       #2563b0 !important;
    --um-accent-soft:  #e3edf9 !important;
    --um-accent-ink:   #1d4e8f !important;
    --um-accent-grad:  linear-gradient(135deg, #2f6fc4, #2563b0) !important;
    --um-amber:        #9a7222 !important;   --um-amber-soft:   #f5edd8 !important;
    --um-red:          #b3402f !important;   --um-red-soft:     #f6e2dd !important;
    --um-blue:         #2563b0 !important;   --um-blue-soft:    #e3edf9 !important;
    --um-success:      #1e7a45 !important;   --um-success-soft: #e0f1e7 !important;
}

/* ── Deep Blue — runs on data-bs-theme="dark" underneath; --um-accent MUST be
   set here explicitly or it silently falls through to Dark's terracotta value
   (see reference_icon_rail_sidebar_and_3_themes.md — this exact bug bit
   UserManagement's active-chip border once already). ── */
html[data-tw-theme="blue"] body.tw-shell {
    --pg-surface:      transparent !important;
    --pg-surface-2:    rgba(3,7,18,.5) !important;
    --pg-border:       rgba(255,255,255,.09) !important;
    --pg-text:         #e8eaf0 !important;
    --pg-text-2:       #a3a8b8 !important;
    --pg-text-3:       #6b7285 !important;
    --um-radius:       14px !important;
    --um-shadow:       0 1px 2px rgba(0,0,0,.35), 0 10px 28px -12px rgba(0,0,0,.55) !important;
    --um-accent:       #3b82f6 !important;
    --um-accent-soft:  rgba(59,130,246,.16) !important;
    --um-accent-ink:   #8ab4ff !important;
    --um-accent-grad:  linear-gradient(180deg, #0b0b0d, #000000) !important;
    --um-blue:         #3b82f6 !important;   --um-blue-soft:    rgba(59,130,246,.16) !important;
    --um-amber:        #e2a33c !important;   --um-amber-soft:   rgba(226,163,60,.16) !important;
    --um-red:          #ef6a6a !important;   --um-red-soft:     rgba(239,106,106,.16) !important;
    --um-success:      #34d399 !important;   --um-success-soft: rgba(52,211,153,.16) !important;
}

/* ============================================================================
   Blue-theme escape hatch for `data-bs-theme="dark"`-scoped rules.
   ----------------------------------------------------------------------------
   Blue theme runs with data-bs-theme="dark" underneath (reuses Dark's
   contrast/text rules) — so any EXISTING rule scoped only to
   `html[data-bs-theme="dark"]` (not also checking data-tw-theme) silently
   catches Blue too. larkon-light-palette.css has exactly this for the
   `.alert-*`/`.kpi-card`/`.summary-card`/etc family (27-Jul-2026, found on
   FinanzasExportacion/Alertas: "cards showing black" in Blue theme) — it
   hardcodes a literal opaque dark fill (`rgb(26,26,31)`) with higher
   specificity than the generic `var(--pg-surface)` rule these classes
   otherwise already use, so Blue's transparent canvas gets silently painted
   over. Force it back to the token (transparent in Blue, correct in every
   other theme) by matching that exact selector shape with
   `html[data-tw-theme="blue"]` swapped in. Same root cause as the
   `--um-accent` fallthrough bug — see
   reference_icon_rail_sidebar_and_3_themes.md. */
html[data-tw-theme="blue"] body.tw-shell .page-content .alert-kpi,
html[data-tw-theme="blue"] body.tw-shell .page-content .alert-card,
html[data-tw-theme="blue"] body.tw-shell .page-content .expense-card,
html[data-tw-theme="blue"] body.tw-shell .page-content .alert-filter-tab,
html[data-tw-theme="blue"] body.tw-shell .page-content .btn-under-review,
html[data-tw-theme="blue"] body.tw-shell .page-content .kpi-card,
html[data-tw-theme="blue"] body.tw-shell .page-content .summary-card,
html[data-tw-theme="blue"] body.tw-shell .page-content .info-card,
html[data-tw-theme="blue"] body.tw-shell .page-content .detail-card,
html[data-tw-theme="blue"] body.tw-shell .fe-al-page .alert-kpi,
html[data-tw-theme="blue"] body.tw-shell .fe-al-page .alert-card {
    background: var(--pg-surface) !important;
    border-color: var(--pg-border) !important;
    color: var(--pg-text) !important;
}

/* Same leak, different elements on the same Alertas page (27-Jul-2026 —
   "still some cards" screenshot: the top CRITICAL/HIGH/MEDIUM/LOW severity
   counter strip + the Impacto/Tiempo/Status/Priority metric row inside each
   alert card were still solid black in Blue). larkon-light-palette.css hard-
   codes rgb(26,26,31)/rgb(35,35,40) for these under a plain
   `html[data-bs-theme="dark"]` selector too. */
html[data-tw-theme="blue"] body.tw-shell .fin-strip-cell,
html[data-tw-theme="blue"] body.tw-shell .fe-al-page .fin-strip-cell,
html[data-tw-theme="blue"] body.tw-shell .fe-al-page .alert-metrics {
    background: var(--pg-surface) !important;
    border-color: var(--pg-border) !important;
}
html[data-tw-theme="blue"] body.tw-shell .fin-strip-cell-num,
html[data-tw-theme="blue"] body.tw-shell .fe-al-page .fin-strip-cell-num,
html[data-tw-theme="blue"] body.tw-shell .fe-al-page .metric-val {
    color: var(--pg-text) !important;
}
html[data-tw-theme="blue"] body.tw-shell .fin-strip-cell-lbl,
html[data-tw-theme="blue"] body.tw-shell .fe-al-page .fin-strip-cell-lbl,
html[data-tw-theme="blue"] body.tw-shell .fe-al-page .metric-lbl {
    color: var(--pg-text-3) !important;
}

/* ============================================================================
   Finanzas module — the `--f*` private palette (27-Jul-2026).
   ----------------------------------------------------------------------------
   The ~12 FinanzasExportacion pages each declare their OWN `:root` palette
   (--fbg/--fborder/--ftext/--fmuted plus --fp/--fs/--fd/--fw/--fi and their
   `-s` soft companions) with LIGHT values, and every `.fin-*` component reads
   those vars. tw-page-skin.css / tw-shell-skin.css then hijack the vars per
   theme on `[class*="fin-card"], [class*="fin-kpi"], .fin-wrap, .fin-page` —
   but only for DARK (unscoped) and LIGHT. That leaves two holes:

     1. BLUE has no block, so it falls through to the DARK values and
        `--fbg: #1a1a1f` paints an opaque slate slab over the whole blue
        radial canvas — the "black block" on every Finanzas page.
     2. The five soft variants are never overridden in ANY dark theme, so
        --fp-s #eef2ff / --fs-s #e8f8f5 / --fd-s #fdeeea / --fw-s #fff6e3 /
        --fi-s #e8f4fb stay LIGHT pastels, making badges and chips glow
        bright on the dark page.

   Both are fixed here once, for every Finanzas page at the same time, instead
   of per page. Selector shape mirrors the tw-page-skin.css block it has to
   beat, plus the theme attribute so it wins on specificity; `.fe-al-page`
   (Alertas) is included so that page shares the same palette.
   ============================================================================ */

/* Dark — supply the soft variants the base skins never set. */
body.tw-shell [class*="fin-card"],
body.tw-shell [class*="fin-kpi"],
body.tw-shell .fin-wrap,
body.tw-shell .fin-page,
body.tw-shell .fe-al-page {
    --fp-s: rgba(59,130,246,.16) !important;
    --fs-s: rgba(78,203,126,.16) !important;
    --fd-s: rgba(229,77,46,.16)  !important;
    --fw-s: rgba(245,165,36,.16) !important;
    --fi-s: rgba(56,189,248,.16) !important;
}

/* Blue — full palette mapped onto the shared tokens. --fbg MUST be
   transparent so the page's radial canvas shows through the wrapper. */
html[data-tw-theme="blue"] body.tw-shell [class*="fin-card"],
html[data-tw-theme="blue"] body.tw-shell [class*="fin-kpi"],
html[data-tw-theme="blue"] body.tw-shell .fin-wrap,
html[data-tw-theme="blue"] body.tw-shell .fin-page,
html[data-tw-theme="blue"] body.tw-shell .fe-al-page {
    --fbg:     transparent !important;
    --fborder: rgba(255,255,255,.09) !important;
    --ftext:   #e8eaf0 !important;
    --fmuted:  #a3a8b8 !important;
    --fp: #3b82f6 !important;  --fp-s: rgba(59,130,246,.16) !important;
    --fs: #34d399 !important;  --fs-s: rgba(52,211,153,.16) !important;
    --fd: #ef6a6a !important;  --fd-s: rgba(239,106,106,.16) !important;
    --fw: #e2a33c !important;  --fw-s: rgba(226,163,60,.16) !important;
    --fi: #38bdf8 !important;  --fi-s: rgba(56,189,248,.16) !important;
}

/* The page wrapper itself: in Blue it must not paint a surface at all (the
   canvas lives on .page-content), and its own border/shadow would outline the
   invisible slab. Dark/Light keep their opaque card look. */
html[data-tw-theme="blue"] body.tw-shell .fin-page,
html[data-tw-theme="blue"] body.tw-shell .fin-wrap {
    background: transparent !important;
    border-color: var(--pg-border) !important;
    box-shadow: none !important;
}

/* Panel Ejecutivo / Préstamos entre empresas use a SECOND private palette
   (`--text`/`--border`/`--muted` + accents on .fe-pe-panel/.fe-pe-wrap, see
   tw-page-skin.css ~L1170) with the same gap: Dark + Light blocks exist, Blue
   does not, so borders and muted text keep Dark's slate tones over the blue
   canvas. Their cards already read --pg-* so there was never a black slab —
   this is the remaining tone mismatch. */
html[data-tw-theme="blue"] body.tw-shell .fe-pe-panel,
html[data-tw-theme="blue"] body.tw-shell .fe-pe-wrap {
    --border:  rgba(255,255,255,.09) !important;
    --muted:   #a3a8b8 !important;
    --text:    #e8eaf0 !important;
    --primary: #3b82f6 !important;
    --success: #34d399 !important;
    --danger:  #ef6a6a !important;
    --warning: #e2a33c !important;
    --info:    #38bdf8 !important;
}

/* ============================================================================
   Dashboard `--ld-*` palette — Blue theme (27-Jul-2026).
   ----------------------------------------------------------------------------
   The home dashboard carries a THIRD private palette (`--ld-surface`,
   `--ld-border`, `--ld-text`… on `.dashboard-home`, tw-dashboard-skin.css ~L19)
   with — again — a Dark block and a Light block but no Blue one. So in Blue the
   widgets that read it (`.dashboard-meter-card` "Indicadores de avance",
   `.dashboard-pillbar-card` "Actividad semanal") inherited Dark's near-black
   `#0e0e10` and rendered as two solid black slabs among otherwise transparent
   blue cards. Third occurrence of the identical private-palette gap.
   ============================================================================ */
html[data-tw-theme="blue"] body.tw-shell .dashboard-home {
    --ld-bg:        transparent !important;
    --ld-surface:   transparent !important;
    --ld-surface-2: rgba(3,7,18,.5) !important;
    --ld-elev:      rgba(255,255,255,.05) !important;
    --ld-border:    rgba(255,255,255,.09) !important;
    --ld-border-2:  rgba(255,255,255,.14) !important;
    --ld-text:      #e8eaf0 !important;
    --ld-text-2:    #a3a8b8 !important;
    --ld-text-3:    #6b7285 !important;
    --ld-text-4:    #6b7285 !important;
    --ld-accent:    #3b82f6 !important;
    --ld-accent-2:  #60a5fa !important;
    --ld-success:   #34d399 !important;
    --ld-warning:   #e2a33c !important;
    --ld-danger:    #ef6a6a !important;
    --ld-info:      #38bdf8 !important;
}

/* ============================================================================
   `.pg-page-head` — the shared page-title header (27-Jul-2026).
   ----------------------------------------------------------------------------
   Lifted verbatim from UserManagement's `.um-header` / `.um-title-wrap` so any
   page can show the same title treatment (Playfair Display on dark, Lora on
   light, 26px, -.02em) instead of inventing its own — or, as the Finanzas
   pages did, showing NO page title at all and opening straight on a lede
   sentence. Fonts come from _HeadCSS so this works app-wide.
   ============================================================================ */
.pg-page-head {
    display: flex; align-items: center; justify-content: space-between;
    gap: 16px; margin-top: 10px; margin-bottom: 18px; flex-wrap: wrap;
}
.pg-page-head-titles { display: flex; align-items: baseline; gap: 12px; min-width: 0; }
.pg-page-title {
    margin: 0;
    font-family: 'Playfair Display', serif;
    font-size: 26px; font-weight: 600; letter-spacing: -.02em; line-height: 1.15;
    color: var(--pg-text);
}
html[data-bs-theme="light"] .pg-page-title { font-family: 'Lora', serif; }
.pg-page-sub {
    font-size: 12.5px; color: var(--pg-text-3); font-weight: 500;
    white-space: nowrap;
}
@media (max-width: 575.98px) {
    .pg-page-title { font-size: 21px; }
}

/* ============================================================================
   `.fin-kpi-rich` KPI cards — theme coverage (27-Jul-2026).
   ----------------------------------------------------------------------------
   These cards (Proyección Semanal, Punto de Equilibrio) are defined ONLY in
   the two views' inline <style>, with `background:#fff` and pastel icon chips
   (#e8f4fb / #fff8e6 / #fdeeea). No shared stylesheet ever knew about them —
   grep for "fin-kpi-rich" across wwwroot/css returns nothing — so they stayed
   pure WHITE in Dark and Blue: bright cards on a dark canvas, with the emoji
   icon nearly invisible (1.1:1 contrast) on its pale chip.
   Route them through the shared tokens like every other card.
   ============================================================================ */
body.tw-shell .fin-kpi-rich {
    background: var(--pg-surface) !important;
    border-color: var(--pg-border) !important;
    color: var(--pg-text) !important;
    box-shadow: none !important;
}
body.tw-shell .fin-kpi-rich__value { color: var(--pg-text) !important; }
body.tw-shell .fin-kpi-rich__title,
body.tw-shell .fin-kpi-rich__desc { color: var(--pg-text-3) !important; }

/* Icon chips: translucent tints of the same accents, so the glyph stays legible
   on both the dark and the blue canvas (was pale-on-pale). */
body.tw-shell .fin-kpi-rich__ico--rev,
body.tw-shell .fin-kpi-rich__ico--exp { background: var(--um-blue-soft) !important;    color: var(--um-blue) !important; }
body.tw-shell .fin-kpi-rich__ico--pay { background: var(--um-amber-soft) !important;   color: var(--um-amber) !important; }
body.tw-shell .fin-kpi-rich__ico--cash,
body.tw-shell .fin-kpi-rich__ico--cas { background: var(--um-red-soft) !important;     color: var(--um-red) !important; }

/* Light theme keeps opaque white cards, matching the users page convention. */
html[data-bs-theme="light"] body.tw-shell .fin-kpi-rich {
    background: #ffffff !important;
}

/* ============================================================================
   Table action buttons — one consistent shape everywhere (27-Jul-2026).
   ----------------------------------------------------------------------------
   larkon-light-palette.css squeezes EVERY `.btn` inside a `<td>` into a fixed
   32x32 box with `padding: 0 !important`. That is right for icon-only actions
   (trash, eye) but wrong for buttons that carry a LABEL — "$ Abono" got
   crushed into 32px with no padding, so the icon and text collided with the
   border and with the neighbouring button (reported on Préstamos entre
   empresas; the same idiom is used across the ERP).

   Fix: stop hard-sizing. `min-width/min-height` keeps icon-only buttons square
   while label buttons grow to fit their text, and real padding + a gap between
   adjacent buttons restores breathing room. Radius/:gap follow the
   UserManagement `.um-btn` reference (8px radius) so table actions match the
   users page, which is the style the rest of the app is being aligned to.
   ============================================================================ */
body.tw-shell .page-content td .btn,
body.tw-shell .page-content td .btn-sm,
body.tw-shell .page-content td .d-flex .btn-sm,
body.tw-shell .page-content .table td .btn {
    width: auto !important;
    height: auto !important;
    min-width: 32px !important;
    min-height: 32px !important;
    padding: 6px 10px !important;
    border-radius: 8px !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 6px !important;
    line-height: 1.15 !important;
    white-space: nowrap !important;
}

/* Space between stacked/adjacent row actions (the <td> is a table-cell, so
   `gap` on the cell does nothing — margin on the following button is what
   actually separates them). */
body.tw-shell .page-content td .btn + .btn,
body.tw-shell .page-content td .btn + a.btn,
body.tw-shell .page-content td a.btn + .btn {
    margin-left: 6px !important;
}

/* Keep a row's actions on ONE line. Without this the action column is sized by
   the table to whatever is left over (95px on Préstamos) while the buttons need
   ~115px, so the second button wrapped underneath the first — which is what
   read as the buttons overlapping. `nowrap` makes the table reserve the width
   the actions actually need. */
body.tw-shell .page-content td:has(> .btn),
body.tw-shell .page-content td:has(> a.btn),
body.tw-shell .page-content td:has(> .btn-group),
body.tw-shell .page-content td:has(> .d-flex > .btn) {
    white-space: nowrap !important;
}

/* ============================================================================
   Inline light-background neutralizers — Blue theme.
   ----------------------------------------------------------------------------
   Many pages hardcode pale inline backgrounds (`style="background:#f8f9fa"` on
   note/summary boxes). larkon-light-palette.css neutralizes those for dark by
   forcing an OPAQUE `#23232a`, scoped only to `html[data-bs-theme="dark"]` —
   so Blue inherits it and every such box becomes a solid slab on the glass
   canvas (found on Alertas; applies to any page using this idiom). Repaint
   them as a translucent lift instead, preserving the visual grouping while the
   canvas shows through. Selector list mirrors the source rule exactly.
   ============================================================================ */
html[data-tw-theme="blue"] body.tw-shell .page-content [style*="background:#f8f9fa"],
html[data-tw-theme="blue"] body.tw-shell .page-content [style*="background: #f8f9fa"],
html[data-tw-theme="blue"] body.tw-shell .page-content [style*="background:#f3f6f9"],
html[data-tw-theme="blue"] body.tw-shell .page-content [style*="background: #f3f6f9"],
html[data-tw-theme="blue"] body.tw-shell .page-content [style*="background:#f1f5f9"],
html[data-tw-theme="blue"] body.tw-shell .page-content [style*="background: #f1f5f9"],
html[data-tw-theme="blue"] body.tw-shell .page-content [style*="background:#f4f4f5"],
html[data-tw-theme="blue"] body.tw-shell .page-content [style*="background: #f4f4f5"],
html[data-tw-theme="blue"] body.tw-shell .page-content [style*="background:#fbfcfd"],
html[data-tw-theme="blue"] body.tw-shell .page-content [style*="background: #fbfcfd"],
html[data-tw-theme="blue"] body.tw-shell .page-content [style*="background:#fafafa"],
html[data-tw-theme="blue"] body.tw-shell .page-content [style*="background: #fafafa"],
html[data-tw-theme="blue"] body.tw-shell .page-content [style*="background:#e9ebec"],
html[data-tw-theme="blue"] body.tw-shell .page-content [style*="background: #e9ebec"],
html[data-tw-theme="blue"] body.tw-shell .page-content [style*="background:#e2e8f0"],
html[data-tw-theme="blue"] body.tw-shell .page-content [style*="background: #e2e8f0"],
html[data-tw-theme="blue"] body.tw-shell .fe-al-page [style*="background:#f8f9fa"],
html[data-tw-theme="blue"] body.tw-shell .fe-al-page [style*="background: #f8f9fa"],
html[data-tw-theme="blue"] body.tw-shell .fe-al-page [style*="background:#f3f6f9"],
html[data-tw-theme="blue"] body.tw-shell .fe-al-page [style*="background: #f3f6f9"],
html[data-tw-theme="blue"] body.tw-shell .fe-al-page [style*="background:#e9ebec"],
html[data-tw-theme="blue"] body.tw-shell .fe-al-page [style*="background: #e9ebec"],
html[data-tw-theme="blue"] body.tw-shell .fe-al-page [style*="background:#fde8e4"],
html[data-tw-theme="blue"] body.tw-shell .fe-al-page [style*="background: #fde8e4"] {
    background: rgba(255,255,255,.05) !important;
    background-color: rgba(255,255,255,.05) !important;
}

/* ============================================================================
   Inline COLOURED pastel chips — Dark + Blue (27-Jul-2026).
   ----------------------------------------------------------------------------
   KPI icon chips are written as literal inline hex: `style="background:#eef2ff"`
   (Créditos Bancarios, Plan de Pagos, Proyección Semanal, …). larkon-light-
   palette.css only neutralizes these under `.fe-al-page`, i.e. Alertas alone —
   so on every OTHER page they stay pale mint/peach/lilac in BOTH dark themes,
   with the glyph nearly invisible on them. Map each to the matching translucent
   accent. Scoped `html:not([data-bs-theme="light"])` so light keeps the pastels.
   ============================================================================ */
html:not([data-bs-theme="light"]) body.tw-shell .page-content [style*="background:#eef2ff"],
html:not([data-bs-theme="light"]) body.tw-shell .page-content [style*="background: #eef2ff"] {
    background: rgba(59,130,246,.16) !important; color: #8ab4ff !important;
}
html:not([data-bs-theme="light"]) body.tw-shell .page-content [style*="background:#e8f4fb"],
html:not([data-bs-theme="light"]) body.tw-shell .page-content [style*="background: #e8f4fb"] {
    background: rgba(56,189,248,.16) !important; color: #7dd3fc !important;
}
html:not([data-bs-theme="light"]) body.tw-shell .page-content [style*="background:#e8f8f5"],
html:not([data-bs-theme="light"]) body.tw-shell .page-content [style*="background: #e8f8f5"] {
    background: rgba(52,211,153,.16) !important; color: #4ade80 !important;
}
html:not([data-bs-theme="light"]) body.tw-shell .page-content [style*="background:#fdeeea"],
html:not([data-bs-theme="light"]) body.tw-shell .page-content [style*="background: #fdeeea"],
html:not([data-bs-theme="light"]) body.tw-shell .page-content [style*="background:#fde8e4"],
html:not([data-bs-theme="light"]) body.tw-shell .page-content [style*="background: #fde8e4"] {
    background: rgba(239,106,106,.16) !important; color: #fca5a5 !important;
}
html:not([data-bs-theme="light"]) body.tw-shell .page-content [style*="background:#fff6e3"],
html:not([data-bs-theme="light"]) body.tw-shell .page-content [style*="background: #fff6e3"],
html:not([data-bs-theme="light"]) body.tw-shell .page-content [style*="background:#fff8e6"],
html:not([data-bs-theme="light"]) body.tw-shell .page-content [style*="background: #fff8e6"] {
    background: rgba(226,163,60,.16) !important; color: #fbbf24 !important;
}

/* ============================================================================
   Global page canvas — Light theme only.
   <html>, body.tw-shell, .wrapper and .page-content/.container-fluid each
   carry their OWN separate background rule elsewhere in the CSS (tw-shell-
   skin.css, tw-page-skin.css, larkon-light-palette.css) — four different
   elements, each a slightly different near-white grey (#f4f6fa / #f5f5f5 /
   #f4f4f5). Fixing just one of them (as done per-page on UserManagement and
   the Module Launcher, scoped via :has()) leaves the other three showing the
   old grey at the edges on every OTHER page. Doing it globally here instead
   of per-page (27-Jul-2026: same edge-strip bug found again on
   FinanzasExportacion/PanelEjecutivo) means it's fixed for every page at
   once, past and future, matching the "cards/page = white" convention
   established on UserManagement. `.wrapper` is included in the chain (not
   just `.page-content`) because a competing rule with that extra class
   outranks a plain `.page-content` override — see
   reference_icon_rail_sidebar_and_3_themes.md. */
html[data-bs-theme="light"],
html[data-bs-theme="light"]:has(body.tw-shell) {
    background-color: #ffffff !important;
}
html[data-bs-theme="light"] body.tw-shell {
    background-color: #ffffff !important;
}
html[data-bs-theme="light"] body.tw-shell .wrapper,
html[data-bs-theme="light"] body.tw-shell .wrapper .page-content,
html[data-bs-theme="light"] body.tw-shell .wrapper .page-content > .container-fluid,
html[data-bs-theme="light"] body.tw-shell .page-content,
html[data-bs-theme="light"] body.tw-shell .page-content > .container-fluid {
    background: #ffffff !important;
}

/* ============================================================================
   .tw-tile — shared clickable card/tile (icon chip + title + meta line).
   Use for module-launcher-style navigation grids. Reads the tokens above, so
   it auto-adapts to whichever theme is active with zero page-specific CSS.
   ============================================================================ */
.tw-tile {
    display: flex; flex-direction: column; align-items: flex-start; gap: 10px;
    padding: 14px;
    border-radius: var(--um-radius);
    border: 1px solid var(--pg-border);
    background: var(--pg-surface);
    box-shadow: var(--um-shadow);
    text-decoration: none !important;
    color: inherit;
    cursor: pointer;
    transition: border-color .12s ease, background-color .12s ease, transform .12s ease, box-shadow .12s ease;
}
.tw-tile:hover {
    background: var(--pg-surface-2);
    transform: translateY(-1px);
    text-decoration: none;
}
.tw-tile-icon {
    width: 38px; height: 38px; flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 8px;
    background: var(--pg-surface-2);
    border: 1px solid var(--pg-border);
    color: var(--pg-text-2);
    font-size: 18px;
}
.tw-tile-icon.is-primary,
.tw-tile-icon.is-info      { background: var(--um-blue-soft);    color: var(--um-blue); }
.tw-tile-icon.is-warning   { background: var(--um-amber-soft);   color: var(--um-amber); }
.tw-tile-icon.is-success   { background: var(--um-success-soft); color: var(--um-success); }
.tw-tile-icon.is-danger    { background: var(--um-red-soft);     color: var(--um-red); }
.tw-tile-icon.is-secondary { background: var(--pg-surface-2);    color: var(--pg-text-2); }
.tw-tile-title {
    font-size: 14px; font-weight: 600; line-height: 1.3; width: 100%;
    color: var(--pg-text);
}
.tw-tile-meta {
    font-size: 11.5px;
    color: var(--pg-text-3);
    display: inline-flex; align-items: center; gap: 5px;
}
.tw-tile-meta i, .tw-tile-meta iconify-icon { font-size: 12px; }

/* Blue theme: glass card over the radial canvas, matching the sidebar/search
   treatment elsewhere. --pg-surface is already `transparent` from the token
   block above, so no background override is needed here — just the blur. */
html[data-tw-theme="blue"] .tw-tile {
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
}

/* Grid-toggle occlusion — ONLY needed in Blue theme. Dark/Light's .tw-tile is
   OPAQUE (--pg-surface is a solid color there), which already blocks the
   ancestor's grid-on painting for free — matching how Slate Dark's own
   .um-table-card never needed this rule. Blue's .tw-tile is transparent, so
   without this the grid painted on .page-content would bleed straight through
   it; repaint the same fixed radial canvas (no lines) directly on the tile to
   block it, exactly like .um-table-card/.lin-root do. */
html[data-tw-theme="blue"][data-tw-gridbg="on"] .tw-tile {
    background-color: transparent !important;
    background-image: radial-gradient(circle at center, #1E40AF, #000000) !important;
    background-size: cover !important;
    background-attachment: fixed !important;
    background-repeat: no-repeat !important;
}

/* ===================================================================
   28-Jul-2026 — Two systemic theme leaks, fixed at the source.

   LEAK 1 — "dark-scoped rules also hit Blue".
   Blue runs on data-bs-theme="dark" (see the topbar toggle: bsFor.blue
   = 'dark'). So EVERY rule written as html[data-bs-theme="dark"] silently
   applies to Blue too, painting Blue's glass surfaces with Dark's opaque
   neutral greys. That is why cards kept coming back "black" on Blue.
   The fix is to re-target the same selector with the extra
   [data-tw-theme="blue"] attribute — strictly higher specificity than the
   dark rule, and this file loads after both app.css and
   larkon-light-palette.css, so it wins without needing a specificity war.

   LEAK 2 — components with NO theme coverage in ANY theme.
   Several .fin-* blocks live in per-page <style> tags with hardcoded
   light colors (#fff / #f8f9fa) and were never given Dark or Blue
   variants — verified: they render white in Dark, Light AND Blue.
   Those are handled below with the shared --pg-* tokens so all three
   themes are covered from one place instead of per page.
   =================================================================== */

/* ---- LEAK 1a: dashboard card footers (app.css paints --bs-card-bg,
   an opaque #282F36, onto .card-footer.bg-white under data-bs-theme
   dark — which includes Blue). ---- */
html[data-bs-theme="dark"][data-tw-theme="blue"] .dashboard-table-card .card-footer,
html[data-bs-theme="dark"][data-tw-theme="blue"] .dashboard-table-card .card-footer.bg-white,
html[data-bs-theme="dark"][data-tw-theme="blue"] body.tw-shell .page-content .card-footer,
html[data-bs-theme="dark"][data-tw-theme="blue"] body.tw-shell .page-content .card-footer.bg-white {
    background: transparent !important;
    background-color: transparent !important;
}

/* ---- LEAK 1b: the inline-style neutralizers in larkon-light-palette.css
   are all scoped html[data-bs-theme="dark"] and repaint any element whose
   style attribute carries a light colour with a near-black (#1a1a1f).
   On Blue that reads as a black slab (e.g. the cornsilk "upcoming payment"
   rows on Créditos bancarios). Mirror the whole family for Blue, mapping
   to the translucent blue surface instead.

   NOTE ON THE `:not(#_)` BELOW — it is load-bearing, not a typo.
   The larkon rules end in a chain of four :not([style*=...]) clauses, and
   :not() contributes its argument's specificity. That makes them (0,8,2) —
   higher than a plain mirror of the same selector plus one attribute (0,5,2),
   so the mirror silently lost and the rows stayed black. `:not(#_)` adds an
   ID-level (1,0,0) with zero matching risk (no element has id="_"), which
   beats any number of class/attribute clauses without having to hand-copy
   and maintain each :not() chain. */
html[data-bs-theme="dark"][data-tw-theme="blue"] body.tw-shell .page-content [style*="background:#fff"]:not(#_),
html[data-bs-theme="dark"][data-tw-theme="blue"] body.tw-shell .page-content [style*="background: #fff"]:not(#_),
html[data-bs-theme="dark"][data-tw-theme="blue"] body.tw-shell .page-content [style*="background:#FFF"]:not(#_),
html[data-bs-theme="dark"][data-tw-theme="blue"] body.tw-shell .page-content [style*="background: #FFF"]:not(#_),
html[data-bs-theme="dark"][data-tw-theme="blue"] body.tw-shell .page-content [style*="background-color:#fff"]:not(#_),
html[data-bs-theme="dark"][data-tw-theme="blue"] body.tw-shell .page-content [style*="background-color: #fff"]:not(#_),
html[data-bs-theme="dark"][data-tw-theme="blue"] body.tw-shell .page-content [style*="background:#f8f9fa"]:not(#_),
html[data-bs-theme="dark"][data-tw-theme="blue"] body.tw-shell .page-content [style*="background: #f8f9fa"]:not(#_),
html[data-bs-theme="dark"][data-tw-theme="blue"] body.tw-shell .page-content [style*="background:#f3f6f9"]:not(#_),
html[data-bs-theme="dark"][data-tw-theme="blue"] body.tw-shell .page-content [style*="background: #f3f6f9"]:not(#_),
html[data-bs-theme="dark"][data-tw-theme="blue"] body.tw-shell .page-content [style*="background:#f1f5f9"]:not(#_),
html[data-bs-theme="dark"][data-tw-theme="blue"] body.tw-shell .page-content [style*="background: #f1f5f9"]:not(#_),
html[data-bs-theme="dark"][data-tw-theme="blue"] body.tw-shell .page-content [style*="background:#f4f4f5"]:not(#_),
html[data-bs-theme="dark"][data-tw-theme="blue"] body.tw-shell .page-content [style*="background: #f4f4f5"]:not(#_),
html[data-bs-theme="dark"][data-tw-theme="blue"] body.tw-shell .page-content [style*="background:#fbfcfd"]:not(#_),
html[data-bs-theme="dark"][data-tw-theme="blue"] body.tw-shell .page-content [style*="background: #fbfcfd"]:not(#_),
html[data-bs-theme="dark"][data-tw-theme="blue"] body.tw-shell .page-content [style*="background:#fafafa"]:not(#_),
html[data-bs-theme="dark"][data-tw-theme="blue"] body.tw-shell .page-content [style*="background: #fafafa"]:not(#_) {
    background-color: rgba(255,255,255,.05) !important;
    color: var(--pg-text) !important;
}

/* ---- LEAK 2a: Bootstrap accordions. --bs-accordion-bg resolves to the
   opaque #282F36 under data-bs-theme="dark", so every collapsed section on
   the client Statement rendered as a grey slab on Blue. Token-driven so all
   three themes are covered at once. ---- */
body.tw-shell .page-content .accordion,
body.tw-shell .page-content .accordion-item {
    --bs-accordion-bg: transparent;
    --bs-accordion-btn-bg: transparent;
    --bs-accordion-active-bg: transparent;
    background-color: var(--pg-surface) !important;
    border-color: var(--pg-border) !important;
}
body.tw-shell .page-content .accordion-button,
body.tw-shell .page-content .accordion-body {
    background-color: transparent !important;
    color: var(--pg-text) !important;
}
body.tw-shell .page-content .accordion-button:not(.collapsed) {
    box-shadow: none !important;
}
body.tw-shell .page-content .accordion-item + .accordion-item {
    border-top-color: var(--pg-border) !important;
}

/* ---- LEAK 2b: .fin-* blocks defined in per-page <style> tags with
   hardcoded light colours. Verified white in Dark, Light and Blue before
   this rule existed, so these are theme-agnostic (token) rules rather than
   Blue-only patches. ---- */
body.tw-shell .fin-kpi-mini,
body.tw-shell .fin-sug-bar {
    background: var(--pg-surface-2) !important;
    border-color: var(--pg-border) !important;
    color: var(--pg-text) !important;
}
body.tw-shell .fin-var-card,
body.tw-shell .fin-hist-tab {
    background: var(--pg-surface) !important;
    border-color: var(--pg-border) !important;
    color: var(--pg-text) !important;
}
body.tw-shell .fin-kpi-mini *,
body.tw-shell .fin-var-card *,
body.tw-shell .fin-sug-bar > strong { color: inherit; }
/* Labels/captions inside those tiles stay secondary, values stay primary. */
body.tw-shell .fin-kpi-mini > :first-child,
body.tw-shell .fin-var-card > :first-child { color: var(--pg-text-3) !important; }

/* Active history tab keeps the accent treatment in every theme. */
body.tw-shell .fin-hist-tab.active,
body.tw-shell .fin-hist-tab[aria-selected="true"] {
    background: var(--um-blue-soft) !important;
    color: var(--um-blue) !important;
    border-color: var(--um-blue) !important;
}

/* ---- LEAK 2c: the "Consolidado" chip (.fin-badge.fb-m) is set to a fixed
   #f3f6f9 in larkon-light-palette.css with no theme scope at all, so it was
   a white chip in all three themes. ---- */
body.tw-shell .fin-badge.fb-m {
    background: var(--pg-surface-2) !important;
    color: var(--pg-text-2) !important;
    border-color: var(--pg-border) !important;
}

/* ---- LEAK 2d: bare <pre> (the suggestion output on Proyección semanal)
   renders on a near-black #08090a in dark-based themes, which sat as a black
   box inside a light bar. ---- */
body.tw-shell .page-content pre:not([class*="language-"]):not(.hljs),
body.tw-shell .page-content code:not([class*="language-"]):not(.hljs) {
    background: var(--pg-surface-2) !important;
    color: var(--pg-text-2) !important;
    border-color: var(--pg-border) !important;
}

/* ---- LEAK 2e: pastel status chips (.fin-stat-ok / .fin-stat-warn) are
   declared in page <style> blocks as solid pastels (#e8f8f5 / #fdeeea) with
   dark ink. Those read as bright stickers on both dark-based themes. Swap to
   the translucent accent-soft tokens; Light keeps the original pastels. ---- */
html:not([data-bs-theme="light"]) body.tw-shell .fin-stat-ok {
    background: var(--um-success-soft) !important;
    color: var(--um-success) !important;
}
html:not([data-bs-theme="light"]) body.tw-shell .fin-stat-warn {
    background: var(--um-red-soft) !important;
    color: var(--um-red) !important;
}

/* ---- QT audit: category chips on Clasificación de Clientes. .fb-d/.fb-s/.fb-w read
   `background: var(--fd-s)` + `color: var(--fd)`, but outside the `.fin-card`/`.fin-page`
   scopes the soft `-s` token resolves to the SOLID accent — so background equalled the
   ink and "Riesgoso" measured 1.00:1, i.e. completely invisible. Pin both sides to the
   shared accent tokens so the pair can never collapse again.

   Deliberately NOT theme-scoped: --um-red/--um-red-soft (and the success/amber
   twins) are already redefined per theme in the three blocks at the top of this
   file, so one rule gives Dark, Blue AND Light their own correct pair. An earlier
   pass scoped this to `html:not([data-bs-theme="light"])`, which left Light on
   larkon-light-palette.css's `body.tw-shell .fin-badge.fb-*` — that rule reads the
   page's private `--fd-s`/`--fd` and measured 3.93 / 2.94 / 3.26, all under AA for
   11px text. The leading bare `html` is what beats that rule: identical class count
   (3), so it comes down to element count (2 vs 1) — source order alone would also
   win (this file loads after larkon-light-palette.css in _HeadCSS.cshtml) but the
   specificity bump keeps it from depending on link order.
   Measured on the REAL page (/FinanzasExportacion/Clasificacion, chip inside
   `.fin-decision-banner`), fb-d / fb-s / fb-w — Dark 4.83 / 7.61 / 4.77,
   Blue 4.83 / 7.32 / 6.30, Light 4.56 / 4.56 / 5.38. The Light amber and Blue
   opacity follow-ups right below are what carry Light's fb-w and all of Blue.
   Measure on the real page, not an isolated repro: a chip on a neutral card
   reads ~1 point higher than the same chip inside a tinted banner. ---- */
html body.tw-shell .fin-badge.fb-d {
    background: var(--um-red-soft) !important;
    color: var(--um-red) !important;
}
html body.tw-shell .fin-badge.fb-s {
    background: var(--um-success-soft) !important;
    color: var(--um-success) !important;
}
html body.tw-shell .fin-badge.fb-w {
    background: var(--um-amber-soft) !important;
    color: var(--um-amber) !important;
}

/* Light is the one theme where the --um-amber pair is too close to carry 11px
   text: #9a7222 on #f5edd8 measures 3.74:1. Darkening --um-amber itself would
   move it everywhere it is used (tile icons, KPI chips, the ~17 amber+white-ink
   pages still on the audit backlog), so this only re-inks THIS chip — #7d5a12
   on the same soft amber = 5.38:1. Dark and Blue already clear AA and are left
   alone. ---- */
html[data-bs-theme="light"] body.tw-shell .fin-badge.fb-w {
    color: #7d5a12 !important;
}

/* Blue is the only theme whose --um-*-soft tokens are TRANSLUCENT (rgba …,.16);
   Dark and Light both resolve to opaque tints. That matters here because the
   canvas behind them is `radial-gradient(circle, #1e40af, #000)` — so a 16% wash
   has no fixed contrast at all, it drifts with where the chip lands on the
   gradient. Worse, on Clasificación the chip sits inside
   `.fin-decision-banner.fin-decision-d`, which carries the SAME .16 red wash, so
   the two stack red-on-red and "Riesgoso" measured 3.55:1 on the real page (my
   isolated repro put the chip on a neutral card and wrongly read 4.49).
   Pin Blue to opaque tints so the chip is independent of both the gradient
   position and any tinted container it is dropped into. ---- */
html[data-tw-theme="blue"] body.tw-shell .fin-badge.fb-d {
    background: #37232b !important;
    color: #ef6a6a !important;
}
html[data-tw-theme="blue"] body.tw-shell .fin-badge.fb-s {
    background: #17302a !important;
    color: #34d399 !important;
}
html[data-tw-theme="blue"] body.tw-shell .fin-badge.fb-w {
    background: #322c1e !important;
    color: #e2a33c !important;
}

/* ===================================================================
   28-Jul-2026 — findings from the full 251-page sweep.
   Everything below was measured as broken in Dark AND Blue (and in the
   Choices case, in Light too), not inferred from reading the markup.
   =================================================================== */

/* ---- Choices.js searchable dropdowns. The vendor stylesheet hardcodes
   #f9f9f9 and was never themed, so on every Add/Edit form the searchable
   selects rendered as white boxes sitting next to correctly-themed dark
   .form-control inputs (measured rgb(249,249,249) in all three themes).
   Mirror .form-control exactly so the two read as one control. ---- */
body.tw-shell .choices__inner {
    background: var(--pg-surface-2) !important;
    border-color: var(--pg-border) !important;
    color: var(--pg-text) !important;
}
/* Light's .form-control is pure white (not --pg-surface-2), so match that. */
html[data-bs-theme="light"] body.tw-shell .choices__inner,
html[data-bs-theme="light"] body.tw-shell .choices__list--dropdown,
html[data-bs-theme="light"] body.tw-shell .choices__list[aria-expanded] {
    background: #ffffff !important;
}
body.tw-shell .choices.is-focused .choices__inner,
body.tw-shell .choices.is-open .choices__inner {
    border-color: var(--um-blue) !important;
}
body.tw-shell .choices__list--dropdown,
body.tw-shell .choices__list[aria-expanded] {
    background: var(--pg-surface-2) !important;
    border-color: var(--pg-border) !important;
    color: var(--pg-text) !important;
}
body.tw-shell .choices__list--dropdown .choices__item,
body.tw-shell .choices__list[aria-expanded] .choices__item {
    color: var(--pg-text) !important;
}
body.tw-shell .choices__list--dropdown .choices__item--selectable.is-highlighted,
body.tw-shell .choices__list[aria-expanded] .choices__item--selectable.is-highlighted {
    background: var(--um-blue-soft) !important;
    color: var(--um-blue) !important;
}
/* Placeholder was 3.05:1 against the white box — below AA even before the
   theme mismatch. --pg-text-3 is the established muted token. */
body.tw-shell .choices__placeholder { color: var(--pg-text-3) !important; opacity: 1 !important; }
body.tw-shell .choices__input { background: transparent !important; color: var(--pg-text) !important; }
/* Multi-select chips */
body.tw-shell .choices__list--multiple .choices__item {
    background: var(--um-blue-soft) !important;
    border-color: var(--um-blue) !important;
    color: var(--um-blue) !important;
}

/* ---- Hardcoded light bars/cells in page <style> blocks ----
   .fps-track   → background:#eef0f3 (RecuperacionFinanciera.cshtml:137)
   .fin-range-cell → background:#fafbfc (SimulacionRentabilidad.cshtml:579)
   Both painted a white strip across a dark card. */
body.tw-shell .fps-track,
body.tw-shell .fin-range-cell {
    background: var(--pg-surface-2) !important;
    border-color: var(--pg-border) !important;
    color: var(--pg-text) !important;
}
html[data-bs-theme="light"] body.tw-shell .fps-track { background: #eef0f3 !important; }
html[data-bs-theme="light"] body.tw-shell .fin-range-cell { background: #fafbfc !important; }

/* ---- Bootstrap's .bg-body-secondary resolves to an opaque neutral under
   data-bs-theme="dark", which Blue inherits (see the LEAK 1 note above). ---- */
html[data-bs-theme="dark"][data-tw-theme="blue"] body.tw-shell .page-content .bg-body-secondary:not(#_) {
    background-color: rgba(255,255,255,.05) !important;
    color: var(--pg-text) !important;
}
