:root {
    --lux-navy: #001b45; --lux-gold: #e5d0b1;
    /* One radius for every button in the app. Tracks Bootstrap's .rounded-3 token so a
       button and a Bootstrap control beside it agree without a magic number. Change it
       here, not on the button: a `rounded-3` in the markup is an !important override
       fighting this rule, and only ever fixes the one button it is written on. */
    --lux-btn-radius: var(--bs-border-radius-lg, .5rem);
}
html[data-bs-theme="dark"]  { --lux-bg: #00132f; --lux-surface: #04204d; --lux-text: #eaf0fb; }
html[data-bs-theme="light"] { --lux-bg: #f3f5fa; --lux-surface: #ffffff; --lux-text: #0b1d3a; }
/* Section headings: gold reads on the dark ground, navy on the light one. Neither reads on
   both -- gold on #f3f5fa and navy on #00132f are each near-invisible -- so the role gets its
   own token instead of a hard-coded colour. */
html[data-bs-theme="dark"]  { --lux-heading: var(--lux-gold); }
html[data-bs-theme="light"] { --lux-heading: var(--lux-navy); }

.bg-lux-navy { background-color: var(--lux-navy); }
.bg-lux-dark { background-color: #00132f; }
.text-gold { color: var(--lux-gold) !important; }
.text-navy { color: var(--lux-navy) !important; }

.lux-body { background: var(--lux-bg); color: var(--lux-text); min-height: 100vh; margin: 0; }
.lux-topbar { height: 56px; background: var(--lux-navy); color: var(--lux-gold); }
.lux-brand { font-weight: 800; letter-spacing: .5px; color: var(--lux-gold); }
.lux-brand-accent { color: #fff; }
.lux-theme-btn { border: 1px solid var(--lux-gold); color: var(--lux-gold); background: transparent; }
.lux-balance-label { color: var(--lux-gold); font-weight: 700; }
.lux-main { padding-bottom: 72px; }

/* Public layout (app.twig) — every .lux-body that is NOT the authenticated shell.
   Make it a flex column so a child with mt-auto sticks to the page bottom. The
   :not(.lux-shell) guard keeps the shell's sidebar row untouched. */
.lux-body:not(.lux-shell) { display: flex; flex-direction: column; }
.lux-body:not(.lux-shell) .lux-main { flex: 1 1 auto; display: flex; flex-direction: column; padding-bottom: 0; }
.lux-auth { min-height: calc(100vh - 56px); }
.lux-card { background: var(--lux-surface); border: 1px solid rgba(229,208,177,.14); border-radius: 16px; }

/* ---- authenticated shell: sidebar on desktop, hamburger drawer on phones ---- */
.lux-shell { display: flex; min-height: 100vh; }

/* Mobile top bar (brand + hamburger) — hidden on desktop. */
.lux-topbar-mobile {
    position: fixed; z-index: 20; top: 0; left: 0; right: 0; height: 56px;
    display: flex; align-items: center; justify-content: space-between;
    padding: 0 1rem; background: var(--lux-navy);
    border-bottom: 1px solid rgba(229,208,177,.2);
}
.lux-topbar-mobile .lux-brand { color: var(--lux-gold); font-weight: 800; letter-spacing: .5px; }
.lux-hamburger {
    display: inline-flex; align-items: center; justify-content: center;
    background: transparent; border: 1px solid var(--lux-gold); color: var(--lux-gold);
    border-radius: 8px; padding: .2rem .55rem; font-size: 1.3rem; line-height: 1; cursor: pointer;
}

/* Nav: a full-height drawer on mobile, hidden until the hamburger opens it. */
.lux-nav {
    position: fixed; z-index: 15; top: 56px; left: 0; right: 0; bottom: 0;
    display: none; flex-direction: column; gap: .25rem;
    background: var(--lux-navy); padding: 1rem; overflow-y: auto;
}
.lux-nav.is-open { display: flex; }
.lux-nav .lux-nav-brand { display: none; }        /* the top bar already shows the brand */
.lux-nav-links { display: flex; flex-direction: column; gap: .25rem; }
.lux-nav-link {
    display: flex; flex-direction: row; align-items: center; gap: .6rem;
    font-size: .95rem; text-decoration: none; color: rgba(234,240,251,.8);
    padding: .6rem .75rem; border-radius: 10px;
}
.lux-nav-link i { font-size: 1.1rem; }
.lux-nav-link.is-active { color: var(--lux-gold); background: rgba(229,208,177,.12); }
.lux-nav-logout { margin-top: .4rem; padding-top: .8rem; border-top: 1px solid rgba(229,208,177,.15); }
.lux-theme-btn { margin-top: .5rem; }
.lux-content { flex: 1; width: 100%; padding: 72px 1rem 1.5rem; }
.lux-page { max-width: 760px; margin: 0 auto; }

/* ---- signature: the balance hero ---- */
.lux-wallet {
    background: linear-gradient(150deg, #04204d 0%, #001b45 70%);
    border: 1px solid rgba(229,208,177,.22); border-radius: 22px;
    padding: 1.75rem 1.5rem; text-align: center; margin-bottom: 1.75rem;
    box-shadow: 0 18px 40px -22px rgba(0,0,0,.8), inset 0 1px 0 rgba(229,208,177,.14);
}
.lux-wallet-eyebrow { text-transform: uppercase; letter-spacing: .22em; font-size: .68rem; color: rgba(229,208,177,.75); }
.lux-wallet-figure {
    font-variant-numeric: tabular-nums lining-nums; font-weight: 800;
    font-size: clamp(2.8rem, 12vw, 4.4rem); line-height: 1; color: var(--lux-gold);
    letter-spacing: .01em; margin: .4rem 0 .1rem;
    text-shadow: 0 1px 0 rgba(0,0,0,.5), 0 -1px 0 rgba(229,208,177,.18);
}
.lux-wallet-unit { font-size: .3em; font-weight: 600; margin-left: .35rem; color: rgba(229,208,177,.7); vertical-align: super; }
.lux-wallet-rule { height: 1px; background: linear-gradient(90deg, transparent, rgba(229,208,177,.5), transparent); margin: 1rem auto 1.25rem; }
.lux-btn-gold {
    display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
    text-decoration: none;
    background: var(--lux-gold); color: var(--lux-navy); font-weight: 700;
    padding: .6rem 1.4rem; border-radius: var(--lux-btn-radius); border: 0;
}
.lux-btn-gold:hover { filter: brightness(1.05); color: var(--lux-navy); }
/* Compound, so it beats the padding above; a bare .btn-sm loses to it and every Filter
   button rendered full size. Matches Bootstrap's own .btn-sm metrics. */
.lux-btn-gold.btn-sm { padding: calc(.25rem + 1px) .75rem; font-size: .875rem; }   /* +1px: no border, so match a bordered btn-sm */

/* ---- Profiles table (profiles/list.twig) ----
   Name and email share one cell so three columns fit the page width without the horizontal
   scroll that pushed the Actions header off-screen, and the action buttons sit on one row
   instead of stacking. */
.lux-profiles td, .lux-profiles th { padding: .5rem .6rem; vertical-align: middle; }
.lux-profiles th { white-space: nowrap; font-size: .8rem; letter-spacing: .02em; }
.lux-profiles-name { font-weight: 600; line-height: 1.25; }
.lux-profiles-email {
    font-size: .8rem; color: var(--lux-text); opacity: .6; line-height: 1.25;
    max-width: 22rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lux-profiles-store { font-size: .85rem; white-space: nowrap; }
/* The status only earns a word when it is NOT the ordinary case. */
.lux-profiles-flag {
    display: inline-block; margin-left: .4rem; padding: .05rem .4rem; border-radius: 6px;
    font-size: .7rem; text-transform: uppercase; letter-spacing: .04em;
    border: 1px solid rgba(229,208,177,.5); color: var(--lux-gold);
}
[data-bs-theme="light"] .lux-profiles-flag { color: var(--lux-navy); border-color: rgba(0,27,69,.35); }
.lux-profiles-actions { white-space: nowrap; text-align: right; }
.lux-profiles-actions form { display: flex; gap: .35rem; justify-content: flex-end; flex-wrap: nowrap; }
.lux-profiles-actions .btn { white-space: nowrap; }

/* Bootstrap buttons join the same radius. Setting its variable rather than border-radius
   keeps .btn-group's first/last-child corner handling intact -- that logic is written in
   terms of this token. .btn-sm and .btn-lg each reassign it, so both are named too. */
.btn, .btn-sm, .btn-lg { --bs-btn-border-radius: var(--lux-btn-radius); }
/* btn-outline-light vanishes on the light theme and btn-outline-secondary is muddy on the
   dark one, so the neutral action gets a token-based variant that reads on both. */
.lux-btn-quiet {
    border: 1px solid rgba(229,208,177,.45); color: var(--lux-text); background: transparent;
    border-radius: var(--lux-btn-radius);
}
.lux-btn-quiet:hover { background: rgba(229,208,177,.12); color: var(--lux-text); }
/* On the light theme the gold border and gold hover wash both disappear into white, so the
   neutral button borrows navy instead. This is the variant that replaced btn-outline-light
   across the app: Bootstrap's "light" outline is white-on-white here, i.e. invisible. */
[data-bs-theme="light"] .lux-btn-quiet { border-color: rgba(0,27,69,.28); }
[data-bs-theme="light"] .lux-btn-quiet:hover { background: rgba(0,27,69,.07); }
/* Bootstrap's amber is #ffc107, which is unreadable on a near-white row. */
[data-bs-theme="light"] .lux-profiles-actions .btn-outline-warning { color: #8a5800; border-color: #b07c12; }
[data-bs-theme="light"] .lux-profiles-actions .btn-outline-warning:hover { background: #8a5800; color: #fff; }

/* ---- segmented choice: two options, each carrying its own identity colour ----
   Built for the claim type, where the pick is also a kind: navy is cash leaving
   the wallet, gold is goods. The fill IS the selected state, so the unpicked half
   stays quiet and there is no tick, badge or second signal to read.
   Markup: .lux-segment > (input.btn-check + label.lux-segment-option.lux-segment-navy|gold)*
   The label must directly follow its input -- the checked styling is a sibling rule. */
.lux-segment {
    --lux-segment-navy: var(--lux-navy);
    display: flex;
    border: 1px solid rgba(229,208,177,.35);
    /* Same radius as every button, so this control and the buttons around it agree. */
    border-radius: var(--lux-btn-radius);
    overflow: hidden;
}
/* #001b45 on the dark theme's #00132f page is a smudge, not a fill, so navy gets
   lifted here the same way --lux-surface already lifts it for cards. */
html[data-bs-theme="dark"] .lux-segment { --lux-segment-navy: #0a2c62; }

.lux-segment-option {
    flex: 1 1 0;
    display: flex; align-items: center; justify-content: center;
    text-align: center;
    margin: 0; padding: .6rem 1rem;
    cursor: pointer; font-weight: 600;
    color: var(--lux-text); background: transparent; opacity: .72;
    transition: background-color .12s ease, color .12s ease, opacity .12s ease;
}
.lux-segment-option + .lux-segment-option { border-left: 1px solid rgba(229,208,177,.35); }
.lux-segment-option:hover { opacity: 1; background: rgba(229,208,177,.08); }

.btn-check:checked + .lux-segment-navy {
    background: var(--lux-segment-navy); color: var(--lux-gold); font-weight: 700; opacity: 1;
}
.btn-check:checked + .lux-segment-gold {
    background: var(--lux-gold); color: var(--lux-navy); font-weight: 700; opacity: 1;
}
/* Inset so the ring is not clipped by the pill's overflow: hidden. */
.btn-check:focus-visible + .lux-segment-option { outline: 2px solid var(--lux-gold); outline-offset: -4px; }

/* Link variant, used by the reports tabs. Same pill, same theming -- but a tab is
   navigation rather than a form control, so the current one is marked by a class
   instead of the sibling :checked rule above. */
a.lux-segment-option { text-decoration: none; }
a.lux-segment-option.is-active {
    background: var(--lux-segment-navy); color: var(--lux-gold); font-weight: 700; opacity: 1;
}
a.lux-segment-option:focus-visible { outline: 2px solid var(--lux-gold); outline-offset: -4px; }

@media (prefers-reduced-motion: reduce) {
    .lux-segment-option { transition: none; }
}

/* Searchable combobox (public/js/combo.js) -- the rep picker. Styled from the same tokens as
   the form controls around it so it reads as one control, in both themes. */
.lux-combo { position: relative; }
.lux-combo-list {
    position: absolute; z-index: 20; left: .75rem; right: .75rem;
    margin: .125rem 0 0; padding: .25rem; list-style: none;
    max-height: 15rem; overflow-y: auto;
    background: var(--lux-surface);
    border: 1px solid rgba(229,208,177,.35);
    border-radius: var(--bs-border-radius, .375rem);
    box-shadow: 0 .5rem 1rem rgba(0,0,0,.25);
}
.lux-combo-list li {
    padding: .35rem .5rem; border-radius: .25rem; cursor: pointer;
    color: var(--lux-text); font-size: .875rem; white-space: nowrap;
    overflow: hidden; text-overflow: ellipsis;
}
.lux-combo-list li:hover,
.lux-combo-list li.is-active { background: var(--lux-gold); color: var(--lux-navy); }
.lux-combo-list li[hidden] { display: none; }

/* Report / listing tables.
   Deliberately NOT .table-dark: that forces a black table in both themes, which is what made
   the reports a black slab on the light theme. Bootstrap 5.3 follows data-bs-theme on its own,
   so only the brand-specific parts live here. */
.lux-table {
    --lux-thead-bg: var(--lux-navy);
    --lux-row-alt: rgba(229,208,177,.05);
}
/* #001b45 on the dark page is a smudge rather than a fill -- lifted the same way
   --lux-segment-navy and --lux-surface already lift it. */
html[data-bs-theme="dark"] .lux-table { --lux-thead-bg: #0a2c62; }
[data-bs-theme="light"] .lux-table { --lux-row-alt: rgba(0,27,69,.04); }

/* Nine columns have to fit the page without a horizontal scrollbar, so the type is a notch
   down from body copy and the cells are trimmed accordingly. Figures use tabular numerals so
   the right-aligned money and points columns line up digit for digit against the totals row. */
.lux-table { font-size: .8125rem; }
.lux-table > :not(caption) > * > * { padding: .45rem .5rem; }
.lux-table td.text-end, .lux-table th.text-end { font-variant-numeric: tabular-nums lining-nums; }
.lux-table thead th,
.lux-table tfoot td {
    background: var(--lux-thead-bg);
    color: var(--lux-gold);
    font-weight: 700;
    border-color: rgba(229,208,177,.25);
}
/* The header wraps rather than forcing the table wider than its container. */
.lux-table thead th { letter-spacing: .02em; }
/* Reference and date columns read badly broken across lines; the rest may wrap. */
.lux-table td:first-child, .lux-table td:last-child { white-space: nowrap; }
.lux-table tfoot td { border-top: 2px solid rgba(229,208,177,.35); }
/* Striping written here rather than via .table-striped so it tracks the brand tokens and
   stays put when a row is hovered. */
.lux-table tbody tr:nth-child(odd) > td { background-color: var(--lux-row-alt); }

.lux-section-title { color: var(--lux-heading, var(--lux-gold)); font-size: 1rem; letter-spacing: .04em; margin: 0 0 .75rem; }
.lux-list { display: flex; flex-direction: column; gap: .5rem; }
.lux-list-row {
    display: flex; justify-content: space-between; align-items: center;
    background: var(--lux-surface); border: 1px solid rgba(229,208,177,.14);
    border-radius: 14px; padding: .8rem 1rem;
}
.lux-list-ref { font-weight: 700; }
.lux-list-sub, .lux-list-pts { font-size: .82rem; }
.lux-list-pts { color: var(--lux-gold); font-variant-numeric: tabular-nums; }
.lux-status { font-size: .7rem; text-transform: uppercase; letter-spacing: .08em; padding: .12rem .5rem; border-radius: 999px; border: 1px solid currentColor; }
.lux-status-submitted { color: #e5d0b1; }
.lux-status-processed { color: #7fd6a2; }
.lux-status-queried   { color: #f0b967; }
.lux-status-draft, .lux-status-cancelled { color: #9fb0c9; }

@media (min-width: 768px) {
    .lux-topbar-mobile { display: none; }
    .lux-nav {
        position: sticky; z-index: 10; top: 0; bottom: auto; left: auto; right: auto;
        display: flex; flex-direction: column; align-items: stretch; width: 230px; height: 100vh;
        border-top: 0; border-right: 1px solid rgba(229,208,177,.2); padding: 1.25rem 1rem; overflow-y: auto;
    }
    .lux-nav .lux-nav-brand { display: block; color: var(--lux-gold); font-weight: 800; letter-spacing: .5px; margin-bottom: 1.5rem; font-size: 1.15rem; }
    .lux-nav-links { flex-direction: column; flex: 0; gap: .25rem; }
    .lux-nav-link { flex-direction: row; gap: .6rem; font-size: .95rem; padding: .55rem .75rem; }
    .lux-nav-link i { font-size: 1rem; }
    .lux-nav-logout { margin-top: 1rem; }
    .lux-theme-btn { margin-top: auto; }
    .lux-content { padding: 2rem 2.5rem; }
    .lux-page { margin: 0; }
}

.lux-sub { color: var(--lux-text); font-size: .95rem; font-weight: 700; margin: 1.25rem 0 .5rem; opacity: .85; }
.lux-list-link { text-decoration: none; color: inherit; }
.lux-list-link:hover { border-color: rgba(229,208,177,.4); }
.lux-proof-thumb { width: 96px; height: 96px; object-fit: cover; border-radius: 10px; border: 1px solid rgba(229,208,177,.25); }
/* Proof-of-sale thumbnail: hover affordance for the full-screen (Fancybox) viewer. */
.lux-proof-link { position: relative; display: inline-block; line-height: 0; }
.lux-proof-link .lux-proof-zoom {
    position: absolute; right: 4px; bottom: 4px;
    display: flex; align-items: center; justify-content: center;
    width: 22px; height: 22px; border-radius: 6px;
    background: rgba(0,27,69,.75); color: #e5d0b1; font-size: .7rem;
    opacity: 0; transition: opacity .15s ease-in-out;
}
.lux-proof-link:hover .lux-proof-zoom, .lux-proof-link:focus-visible .lux-proof-zoom { opacity: 1; }
.lux-proof-link:hover .lux-proof-thumb { border-color: rgba(229,208,177,.7); }
/* A PDF proof has no thumbnail image — show a document tile instead. */
.lux-proof-pdf {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .15rem;
    background: rgba(0,27,69,.06); color: var(--lux-navy, #001b45); line-height: 1;
}
[data-bs-theme="dark"] .lux-proof-pdf { background: rgba(229,208,177,.08); color: var(--lux-gold, #e5d0b1); }
.lux-proof-pdf .bi { font-size: 2rem; }
.lux-proof-pdf-label { font-size: .65rem; font-weight: 700; letter-spacing: .06em; }
.lux-attest, .lux-decision + label { cursor: pointer; }

/* --- Public landing page (home.twig) ---
   Layout is done with Bootstrap grid/utilities IN the template. These rules are
   visual-only (button variant, carousel frame, footer tint) so you can freely use
   .container / .container-fluid / .row / .col-* without anything here overriding them. */
.lux-btn-outline {
    display: inline-flex; align-items: center; gap: .4rem; text-decoration: none;
    background: transparent; color: var(--lux-gold); font-weight: 600;
    padding: .6rem 1.4rem; border: 1px solid var(--lux-gold);
    border-radius: var(--lux-btn-radius);
}
.lux-btn-outline:hover { background: rgba(229,208,177,.12); color: var(--lux-gold); }
.lux-landing-carousel { overflow: hidden; border: 1px solid rgba(229,208,177,.14); background: #0d0b0c; }
.lux-landing-carousel img { width: 100%; height: auto; display: block; }
/* Footer bar matches .lux-topbar (navy background, gold text). */
.lux-landing-footer { background: var(--lux-navy); color: var(--lux-gold); }
.lux-landing-footer a { color: var(--lux-gold); }
.lux-landing-footer img { vertical-align: middle; margin-left: .3rem; }
#approveBtn:disabled { opacity: .5; pointer-events: none; }

/* --- jQuery Validate: the standard Bootstrap help-block / has-error styling
   used on the auth forms (login / register / forgot / reset). Bootstrap 5 dropped
   these classes, so they're defined here. errorClass is 'help-block'; the plugin
   toggles .has-error on the field's .form-group. --- */
.help-block { display: block; margin-top: .3rem; font-size: .85rem; color: #dc3545; }
.has-error .form-control,
.has-error .form-select { border-color: #dc3545; }
.has-error .form-control:focus,
.has-error .form-select:focus { border-color: #dc3545; box-shadow: 0 0 0 .2rem rgba(220,53,69,.25); }
.has-error .form-label,
.has-error .form-check-label { color: #dc3545; }

/* --- Dashboard notices (admin-editable) + welcome card --- */
.lux-notice {
    background: var(--lux-surface); border: 1px solid rgba(229,208,177,.14);
    border-left: 4px solid var(--lux-gold); border-radius: 10px;
    padding: .9rem 1.1rem; margin-bottom: .75rem;
}
.lux-notice-title { font-weight: 700; margin-bottom: .2rem; }
.lux-notice-gold   { border-left-color: var(--lux-gold); }
.lux-notice-info   { border-left-color: #4a90d9; }
.lux-notice-danger { border-left-color: #dc3545; }
.lux-welcome summary { cursor: pointer; font-weight: 700; color: var(--lux-gold); list-style: none; }
.lux-welcome summary::-webkit-details-marker { display: none; }
.lux-welcome summary::before { content: "\25B8"; margin-right: .25rem; }   /* ▸ collapsed */
.lux-welcome[open] summary::before { content: "\25BE"; }                  /* ▾ open */
.lux-welcome p:last-child { margin-bottom: 0; }

/* --- Sale capture: datepicker field + Select2 sized to match Bootstrap 5 form controls --- */
.lux-datepicker { cursor: pointer; background-color: var(--lux-surface); }
.select2-container { width: 100% !important; }
.select2-container--default .select2-selection--single {
    height: calc(1.5em + .75rem + 2px);              /* == a .form-select */
    border: 1px solid #ced4da; border-radius: .375rem;
    background-color: var(--lux-surface);
}
.select2-container--default .select2-selection--single .select2-selection__rendered {
    line-height: calc(1.5em + .75rem);               /* vertically centre the text */
    padding-left: .75rem; padding-right: 2rem; color: var(--lux-text);
}
.select2-container--default .select2-selection--single .select2-selection__placeholder { color: #6c757d; }
.select2-container--default .select2-selection--single .select2-selection__arrow { height: calc(1.5em + .75rem); right: .5rem; }
.select2-container--default.select2-container--disabled .select2-selection--single { background-color: #e9ecef; opacity: 1; }
.select2-dropdown { border-color: #ced4da; }

/* ---- reviewer dashboard: work-queue tiles (role >= BRAND_MANAGER) ----
   These are CARDS, in the same family as .lux-list-row below them: surface
   background, real border, soft shadow. They must read as something you click,
   so they carry an icon badge, a gold edge stripe, an arrow and a hover lift.

   Themed on --lux-surface/--lux-text rather than the navy of .lux-wallet: gold
   numerals are unreadable on the light theme's white surface, and three navy
   slabs in a row sit like a foreign block on a light page.

   NOTE: do not add Bootstrap's .rounded-2 to a .lux-tile — it sets
   border-radius with !important and flattens the card corners back to 6px. */
.lux-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: .85rem; margin-bottom: 1.25rem; }
.lux-tile {
    position: relative; overflow: hidden;
    display: flex; flex-direction: column; align-items: flex-start; gap: .35rem;
    text-decoration: none; color: var(--lux-text);
    background: var(--lux-surface);
    border: 1px solid var(--lux-tile-border); border-radius: 18px;
    padding: 1.1rem 1.15rem 1rem;
    box-shadow: var(--lux-tile-shadow);
    transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
}
/* Gold edge stripe — the brand cue that survives both themes. */
.lux-tile::before {
    content: ""; position: absolute; inset: 0 auto 0 0; width: 4px;
    background: linear-gradient(180deg, var(--lux-gold), rgba(229,208,177,.35));
}
.lux-tile:hover, .lux-tile:focus-visible {
    transform: translateY(-2px); color: var(--lux-text);
    border-color: rgba(229,208,177,.55); box-shadow: var(--lux-tile-shadow-hover);
}
.lux-tile:focus-visible { outline: 2px solid var(--lux-gold); outline-offset: 2px; }
.lux-tile-icon {
    display: inline-flex; align-items: center; justify-content: center;
    width: 2.1rem; height: 2.1rem; border-radius: 50%; font-size: 1rem;
    background: var(--lux-tile-icon-bg); color: var(--lux-tile-icon-fg);
}
.lux-tile-figure {
    font-variant-numeric: tabular-nums lining-nums; font-weight: 800; line-height: 1;
    font-size: clamp(1.9rem, 7vw, 2.6rem); color: var(--lux-text);
}
/* Backlog severity. The bands come from App\Config\QueueLoad::level(), which
   emits ok | warn | hot — never a colour, so retuning the thresholds is a PHP
   change and restyling is a CSS change. Both shades sets are chosen for
   contrast against their own theme's surface, hence the tokens below.
   The colour only re-states the number, so nothing is conveyed by hue alone. */
.lux-tile-figure.is-ok   { color: var(--lux-load-ok); }
.lux-tile-figure.is-warn { color: var(--lux-load-warn); }
.lux-tile-figure.is-hot  { color: var(--lux-load-hot); }
.lux-tile-label {
    font-size: .72rem; text-transform: uppercase; letter-spacing: .1em;
    color: var(--lux-tile-label); font-weight: 600;
}
/* The "this is navigable" affordance, so a tile never reads as a bare number. */
.lux-tile-go {
    position: absolute; top: 1.15rem; right: 1.15rem; font-size: .95rem;
    color: var(--lux-tile-label); transition: transform .16s ease, color .16s ease;
}
.lux-tile:hover .lux-tile-go { transform: translateX(3px); color: var(--lux-gold); }

:root, html[data-bs-theme="light"] {
    --lux-tile-border: rgba(0,27,69,.10);
    --lux-tile-shadow: 0 1px 2px rgba(0,27,69,.06), 0 10px 24px -18px rgba(0,27,69,.35);
    --lux-tile-shadow-hover: 0 2px 4px rgba(0,27,69,.08), 0 18px 34px -20px rgba(0,27,69,.45);
    --lux-tile-icon-bg: rgba(0,27,69,.06);
    --lux-tile-icon-fg: var(--lux-navy);
    --lux-tile-label: #5c6b85;
    --lux-warn-bg: #fdf6e7;
    --lux-warn-border: #e8c67a;
    --lux-warn-text: #7a5310;
    --lux-load-ok: #1a7f4b;
    --lux-load-warn: #b4610a;
    --lux-load-hot: #b3261e;
}
html[data-bs-theme="dark"] {
    --lux-tile-border: rgba(229,208,177,.18);
    --lux-tile-shadow: 0 14px 30px -20px rgba(0,0,0,.8), inset 0 1px 0 rgba(229,208,177,.10);
    --lux-tile-shadow-hover: 0 18px 38px -20px rgba(0,0,0,.9), inset 0 1px 0 rgba(229,208,177,.16);
    --lux-tile-icon-bg: rgba(229,208,177,.12);
    --lux-tile-icon-fg: var(--lux-gold);
    --lux-tile-label: rgba(229,208,177,.72);
    --lux-warn-bg: rgba(240,185,103,.10);
    --lux-warn-border: rgba(240,185,103,.40);
    --lux-warn-text: #f0b967;
    --lux-load-ok: #7fd6a2;
    --lux-load-warn: #f0b967;
    --lux-load-hot: #ff8a80;
}

/* Ageing-queue warning. Matches .lux-notice's shape (4px left rule) and takes
   its colours from tokens, so the text keeps real contrast in BOTH themes —
   the old amber-on-amber-wash washed out to nothing on the light background. */
.lux-queue-age {
    display: flex; align-items: center; gap: .6rem;
    background: var(--lux-warn-bg); border: 1px solid var(--lux-warn-border);
    border-left: 4px solid var(--lux-warn-border); border-radius: 12px;
    color: var(--lux-warn-text); padding: .75rem 1rem; margin-bottom: 1.25rem; font-size: .88rem;
}
.lux-queue-age i { font-size: 1rem; flex: 0 0 auto; }
.lux-queue-empty {
    text-align: center; padding: 2.5rem 1.5rem; margin-bottom: 1.5rem;
    background: var(--lux-surface); border: 1px solid rgba(229,208,177,.14);
}
.lux-queue-empty i { font-size: 2.4rem; color: #7fd6a2; }
.lux-queue-empty-title { font-weight: 700; margin: .5rem 0 .25rem; }

/* ---- attestation rows (manager review screens) ----
   The reviewer confirms, one tick at a time, that the uploaded document really
   matches the captured values. These MUST stay real <input type="checkbox">
   elements: both review.js and claim_review.js gate the Approve button on the
   native .checked of `.lux-attest`, and SalesService/ClaimsService refuse the
   approval server-side unless each attestation arrives === true. A plugin that
   swaps the input for a styled div (iCheck and friends) would put that gate at
   risk, so this is CSS only — no library, no JS. */
.lux-attest-row {
    display: flex; align-items: center; gap: .65rem;
    padding: .6rem .8rem; margin-bottom: .4rem;
    background: var(--lux-attest-bg); border: 1px solid var(--lux-attest-border);
    border-radius: 10px; cursor: pointer; -webkit-user-select: none; user-select: none;
    transition: background .15s ease, border-color .15s ease;
}
.lux-attest-row:hover { border-color: rgba(229,208,177,.55); }
/* Ticked state on the whole row, so outstanding confirmations are obvious at a
   glance in a list of five. :has() needs no JS in any current browser; where it
   is unsupported the row simply stays neutral and the checkbox still shows. */
.lux-attest-row:has(.lux-attest:checked) {
    background: var(--lux-attest-bg-on); border-color: var(--lux-gold);
}
.lux-attest-row:has(.lux-attest:focus-visible) {
    outline: 2px solid var(--lux-gold); outline-offset: 2px;
}
.lux-attest-row .lux-attest {
    flex: 0 0 auto; width: 1.25rem; height: 1.25rem; margin: 0; cursor: pointer;
    border-color: var(--lux-attest-box-border);
}
/* Bootstrap's own tick path, restroked in gold on navy. */
.lux-attest-row .lux-attest:checked {
    background-color: var(--lux-navy); border-color: var(--lux-gold);
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23e5d0b1' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e");
}
.lux-attest-row .lux-attest:focus { box-shadow: none; }   /* the row carries the ring */
.lux-attest-row > span { font-size: .9rem; line-height: 1.3; }

:root, html[data-bs-theme="light"] {
    --lux-attest-bg: #fbfcfe;
    --lux-attest-bg-on: #fdfaf3;
    --lux-attest-border: rgba(0,27,69,.12);
    --lux-attest-box-border: rgba(0,27,69,.30);
}
html[data-bs-theme="dark"] {
    --lux-attest-bg: rgba(255,255,255,.03);
    --lux-attest-bg-on: rgba(229,208,177,.10);
    --lux-attest-border: rgba(229,208,177,.16);
    --lux-attest-box-border: rgba(229,208,177,.45);
}

/* Money input (sale value): the native spinner steps by 0.01, which is useless
   for a price and just crowds the field, so hide it in every engine. Decimal
   places are capped in capture.js — see the note there. */
.lux-money-input::-webkit-outer-spin-button,
.lux-money-input::-webkit-inner-spin-button { -webkit-appearance: none; appearance: none; margin: 0; }
.lux-money-input { -moz-appearance: textfield; appearance: textfield; }

/* Password reveal icon in an .input-group addon (auth forms). Bootstrap 5.3
   themes .input-group-text itself off data-bs-theme, so only the affordance
   and the focus ring need adding. */
.input-group-text .reveal { cursor: pointer; line-height: 1; }
.input-group-text .reveal:hover { opacity: .75; }
.input-group-text .reveal:focus-visible { outline: 2px solid var(--lux-gold); outline-offset: 2px; border-radius: 3px; }

/* Date field calendar (public/js/datefield.js). The input is plain text so it can display
   YYYY-MM-DD literally -- a native date input renders in the browser's locale and cannot be
   told otherwise -- and this is the picker put back in its place. */
.lux-datefield { position: relative; }
.lux-cal {
    position: absolute; z-index: 20; left: .75rem; margin-top: .125rem; padding: .5rem;
    background: var(--lux-surface);
    border: 1px solid rgba(229,208,177,.35);
    border-radius: var(--bs-border-radius, .375rem);
    box-shadow: 0 .5rem 1rem rgba(0,0,0,.25);
    width: 16rem;
}
.lux-cal-head {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: .35rem; color: var(--lux-heading, var(--lux-gold));
    font-size: .8125rem; font-weight: 700;
}
.lux-cal-nav {
    border: 0; background: transparent; cursor: pointer; line-height: 1;
    padding: .1rem .45rem; border-radius: .25rem;
    color: var(--lux-heading, var(--lux-gold)); font-size: 1.1rem;
}
.lux-cal-nav:hover { background: rgba(229,208,177,.12); }
.lux-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: .1rem; }
.lux-cal-dow {
    text-align: center; font-size: .6875rem; color: var(--lux-text); opacity: .6; padding: .15rem 0;
}
.lux-cal-day {
    border: 0; background: transparent; cursor: pointer;
    padding: .3rem 0; border-radius: .25rem;
    color: var(--lux-text); font-size: .8125rem;
}
.lux-cal-day:hover { background: rgba(229,208,177,.14); }
.lux-cal-day.is-today { outline: 1px solid rgba(229,208,177,.5); }
.lux-cal-day.is-selected { background: var(--lux-gold); color: var(--lux-navy); font-weight: 700; }

/* Whole-filter totals strip (reports/_summary.twig). Sits above the table so the figures are
   never something you scroll for, and reads as a summary of the FILTER rather than the page. */
.lux-summary {
    display: flex; flex-wrap: wrap; gap: .5rem;
    background: var(--lux-surface);
    border: 1px solid rgba(229,208,177,.18);
    border-radius: 12px; padding: .6rem .75rem;
}
.lux-summary-cell {
    display: flex; flex-direction: column; gap: .1rem;
    min-width: 6.5rem; flex: 1 1 auto; padding: 0 .5rem;
    border-left: 1px solid rgba(229,208,177,.14);
}
.lux-summary-cell:first-child { border-left: 0; }
.lux-summary-label {
    font-size: .68rem; text-transform: uppercase; letter-spacing: .1em;
    color: var(--lux-text); opacity: .6;
}
.lux-summary-figure {
    font-variant-numeric: tabular-nums lining-nums;
    font-weight: 700; font-size: 1rem; color: var(--lux-heading, var(--lux-gold));
}

/* Report pager (reports/_pager.twig). */
.lux-pager {
    display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
    gap: .5rem; margin-top: .75rem; font-size: .8125rem;
}
.lux-pager-count { color: var(--lux-text); opacity: .7; }
.lux-pager-links { display: flex; align-items: center; gap: .5rem; }
.lux-pager-at { color: var(--lux-text); opacity: .7; }
.lux-pager-link {
    text-decoration: none; padding: .25rem .6rem; border-radius: var(--lux-btn-radius);
    border: 1px solid rgba(229,208,177,.45); color: var(--lux-text);
}
.lux-pager-link:hover { background: rgba(229,208,177,.12); color: var(--lux-text); }
[data-bs-theme="light"] .lux-pager-link { border-color: rgba(0,27,69,.28); }
.lux-pager-link.is-disabled { opacity: .35; pointer-events: none; }

/* ---- one-time confirmation popup (partials/flash_dialog.twig) ---- */
.lux-dialog {
    width: min(100% - 32px, 380px); padding: 1.75rem 1.5rem 1.5rem; text-align: center;
    background: var(--lux-surface); color: var(--lux-text);
    border: 1px solid rgba(229,208,177,.28); border-radius: 16px;
    box-shadow: 0 24px 48px -16px rgba(0,0,0,.55);
}
.lux-dialog::backdrop { background: rgba(0,12,34,.62); }
.lux-dialog-icon { font-size: 2.5rem; line-height: 1; color: var(--lux-gold); margin-bottom: .75rem; }
html[data-bs-theme="light"] .lux-dialog-icon { color: var(--lux-navy); }
.lux-dialog-title { font-size: 1.25rem; font-weight: 700; margin: 0 0 .5rem; }
.lux-dialog-body { margin: 0 0 1.25rem; opacity: .85; line-height: 1.5; }
