/* Typography base */
html, body {
    font-family: "DM Sans", "Roboto", "Segoe UI", system-ui, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* ---------- Pearl Design System tokens ----------
   Pearl palette is the source of truth (see docs/Design-Guidelines.md and the
   prototype docs/pearl-design-system.html).

   IMPORTANT — dark mode strategy:
   MudBlazor v9 does NOT add `.mud-theme-dark` class to the DOM — it only flips
   the `--mud-palette-*` CSS variables at `:root` via the inline <style> block
   emitted by MudThemeProvider. So our Pearl tokens MUST chain to those
   palette tokens for them to flip automatically with IsDarkMode.

   Tokens with no direct MudBlazor equivalent (accent-soft, accent-strong,
   text-tertiary, border-strong, on-primary) are derived via `color-mix()` so
   they too flip via the chain. Soft variants intentionally chain to
   `transparent` (rgba over surface) per Pearl Design-Guidelines §2.3. */
:root {
    /* Surface scale — chained to MudBlazor palette */
    --bg: var(--mud-palette-background);
    --surface: var(--mud-palette-surface);
    --surface-2: var(--mud-palette-background-gray);
    --surface-3: var(--mud-palette-gray-lighter);

    /* Text scale — chained, with text-tertiary derived via color-mix */
    --text: var(--mud-palette-text-primary);
    --text-muted: var(--mud-palette-text-secondary);
    --text-tertiary: color-mix(in srgb, var(--text-muted) 60%, var(--surface));
    --text-disabled: var(--mud-palette-text-disabled);

    /* Primary brand color = text in both modes (near-black light, near-white dark);
       --on-primary = text-on-amber-button (white light, dark-bg dark) — set via
       PaletteLight/Dark.PrimaryContrastText in EjmAdminDashboardTheme.cs. */
    --primary: var(--mud-palette-text-primary);
    --on-primary: var(--mud-palette-primary-text);

    /* Brand accent + variants */
    --accent: var(--mud-palette-primary);
    --accent-hover: color-mix(in srgb, var(--accent) 80%, var(--text));
    --accent-soft: color-mix(in srgb, var(--accent) 18%, transparent);
    --accent-strong: color-mix(in srgb, var(--accent) 55%, var(--text));
    --accent-2: var(--mud-palette-secondary);

    /* Semantic colors */
    --success: var(--mud-palette-success);
    --success-soft: color-mix(in srgb, var(--success) 16%, transparent);
    --danger: var(--mud-palette-error);
    --danger-soft: color-mix(in srgb, var(--danger) 16%, transparent);
    --warning: var(--mud-palette-warning);
    --warning-soft: color-mix(in srgb, var(--warning) 16%, transparent);

    /* Borders + neutrals */
    --border: var(--mud-palette-lines-default);
    --border-light: var(--mud-palette-table-lines);
    --border-strong: color-mix(in srgb, var(--border) 55%, var(--text));
    --neutral: var(--mud-palette-text-secondary);

    --scrim: var(--mud-palette-overlay-dark);

    /* Shadows — unified rgba(0,0,0,...) so they read in both modes (slightly
       softer than the previous light-only values, comparable to the dark set). */
    --sh-sm: 0 1px 3px rgba(0,0,0,0.10), 0 1px 2px rgba(0,0,0,0.06);
    --sh-md: 0 4px 12px rgba(0,0,0,0.14), 0 2px 4px rgba(0,0,0,0.08);
    --sh-lg: 0 12px 32px rgba(0,0,0,0.20), 0 4px 8px rgba(0,0,0,0.12);
    --sh-focus: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent);
    --sh-focus-danger: 0 0 0 3px color-mix(in srgb, var(--danger) 25%, transparent);

    /* Pearl shape tokens */
    --shape-xs: 4px;
    --shape-sm: 8px;
    --shape-md: 12px;
    --shape-lg: 16px;
    --shape-xl: 28px;
    --shape-full: 9999px;

    /* Pearl easing */
    --ease-emp: cubic-bezier(0.2, 0, 0, 1);
    --ease-decel: cubic-bezier(0.05, 0.7, 0.1, 1);
    --ease-accel: cubic-bezier(0.3, 0, 0.8, 0.15);

    /* Pearl font stacks (Design-Guidelines.md §3.1) */
    --pearl-font: "DM Sans", "Roboto", "Segoe UI", system-ui, sans-serif;
    --pearl-font-display: "DM Serif Display", Georgia, serif;
    --pearl-font-mono: "JetBrains Mono", Consolas, "Courier New", monospace;

    /* Legacy --epx-* aliases — kept until non-shell pages migrate to Pearl */
    --epx-surface-container-lowest: var(--surface);
    --epx-surface-container-low: var(--bg);
    --epx-surface-container: var(--surface);
    --epx-surface-container-high: var(--surface-2);
    --epx-surface-container-highest: var(--surface-3);
    --epx-primary-container: var(--accent-soft);
    --epx-on-primary-container: var(--accent-strong);
    --epx-tertiary: var(--accent-2);
    --epx-on-tertiary: #ffffff;
    --epx-tertiary-container: var(--success-soft);
    --epx-on-tertiary-container: var(--success);
    --epx-elevation-1: var(--sh-sm);
    --epx-elevation-2: var(--sh-md);
    --epx-elevation-3: var(--sh-lg);
    --epx-motion-fast: 150ms var(--ease-emp);
    --epx-motion-medium: 250ms var(--ease-emp);
}

/* ---------- Dark mode operational contract (Pearl Design-Guidelines §2.5) ----------
   MudBlazor's internal palette already maps DrawerBackground/TextPrimary to the
   dark Pearl values, but a few component defaults don't flip cleanly:
     1. Persistent left MudDrawer hosting <SideNav> renders its own background
        layer that doesn't always pick up --mud-palette-drawer-background.
     2. .epx-page-header__title and dialog/card titles are wrapped in MudText
        whose .mud-typography-* color rules can win specificity over our
        page-level rules. We pin them to var(--text) with !important so the
        theme token (light → #2A2520, dark → #EDE8E0) is authoritative.
   Keep this block close to the dark token definition so the contract is
   one search away. */
.mud-drawer.mud-drawer-left {
    background: var(--surface) !important;
    border-right: 1px solid var(--border) !important;
    color: var(--text);
}

.mud-dialog .mud-dialog-title,
.mud-dialog .mud-dialog-title .mud-typography {
    color: var(--text);
}

/* Layout & Utility */
.full-width {
    width: 100%;
}

/* ---------- Pearl utility classes ----------
   Small, single-purpose helpers used while migrating page-level views to Pearl.
   Prefer these over inline Style="" for things that appear in many places. */
.epx-mono {
    font-family: var(--pearl-font-mono);
}

.epx-display {
    font-family: var(--pearl-font-display);
}

.epx-pill {
    border-radius: var(--shape-full);
}

.epx-text-muted {
    color: var(--text-muted);
}

.epx-surface-alt {
    background: var(--surface-2);
}

/* ---------- Epoxy App Shell (Pearl) ---------- */
.epx-appbar {
    /* Solid bar (like the bottom nav) so scrolled content never shows through it. */
    background: var(--surface) !important;
    border-bottom: 1px solid var(--border) !important;
    box-shadow: var(--epx-elevation-1) !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    height: 52px !important;
    min-height: 52px !important;
}

/* Force the toolbar inside the appbar to honour Pearl's height + side padding,
   center actions vertically, and space them with a consistent gap. */
.epx-appbar.mud-appbar > .mud-toolbar,
.epx-appbar > .mud-toolbar {
    height: 52px;
    min-height: 52px;
    padding-left: 24px;
    padding-right: 24px;
    display: flex;
    align-items: center;
    gap: 8px;
}

@media (max-width: 599.98px) {
    /* Slimmer appbar on mobile — 48 px keeps it compact while leaving room
       for the wordmark. */
    .epx-appbar {
        height: 48px !important;
        min-height: 48px !important;
    }

    .epx-appbar.mud-appbar > .mud-toolbar,
    .epx-appbar > .mud-toolbar {
        height: 48px;
        min-height: 48px;
        padding-left: 12px;
        padding-right: 12px;
        gap: 4px;
    }

    /* Compact mark-only on tight mobile widths. The wordmark still shows but
       a touch smaller so it doesn't crowd out the right-side icons. */
    .epx-appbar .epx-brand-mark--sidebar {
        width: 32px;
        height: 32px;
    }

    .epx-appbar .epx-brand-title {
        font-size: 14px;
    }

    .epx-appbar .epx-brand-tagline {
        display: none;
    }
}

/* Main-content container: tighten the gap between the appbar and the page
   hero/greeting (was 16 px top padding plus the LoadingProgressBar's reserved
   margin band — now 8 px and the progress bar only renders while loading). */
.epx-main-container {
    max-width: none !important;
    padding-top: 8px !important;
}

@media (max-width: 599.98px) {
    .epx-main-container {
        padding-top: 4px !important;
    }
}

/* Trim padding on icon-buttons inside the appbar so the 36×36 hit area sits
   neatly at 52px appbar height (the prototype gives them no extra padding). */
.epx-appbar .mud-icon-button {
    width: 36px;
    height: 36px;
    padding: 6px;
}

.epx-brand-wrap {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
    text-decoration: none;
}

/* Pearl bicromatic mark "EJM" — base, sized via modifiers */
.epx-brand-mark {
    width: 40px;
    height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.epx-brand-mark svg {
    width: 100%;
    height: 100%;
    display: block;
}

.epx-brand-mark--sidebar {
    width: 32px;
    height: 32px;
    padding-top: 7px;
}

.epx-brand-mark--sidebar .epx-brand-mark__e {
    font-size: 16px;
}

.epx-brand-mark--sidebar .epx-brand-mark__jm {
    font-size: 10px;
}

.epx-brand-mark--auth {
    width: 48px;
    height: 48px;
    padding-top: 11px;
}

.epx-brand-mark--auth .epx-brand-mark__e {
    font-size: 22px;
}

.epx-brand-mark--auth .epx-brand-mark__jm {
    font-size: 13px;
}

.epx-brand-mark__e {
    font-family: "DM Sans", sans-serif;
    font-weight: 700;
    color: var(--accent);
    line-height: 1;
}

.epx-brand-mark__jm {
    font-family: "DM Sans", sans-serif;
    font-weight: 600;
    color: var(--on-primary);
    opacity: 0.85;
    line-height: 1;
}

.epx-brand-text {
    display: flex;
    flex-direction: column;
    justify-content: center;
    line-height: 1.15;
    min-width: 0;
}

.epx-brand-title {
    font-family: "DM Sans", sans-serif;
    font-weight: 500;
    font-size: 14px;
    line-height: 20px;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Two-tone wordmark — 'Epoxy Job' descriptive (muted), 'Manager' active (emphasised).
   Both route through theme tokens so dark mode flips them automatically. */
.epx-brand-title__name {
    color: var(--text-muted);
    font-weight: 500;
}

.epx-brand-title__role {
    color: var(--text);
    font-weight: 600;
}

.epx-brand-tagline {
    font-family: "DM Sans", sans-serif;
    font-weight: 500;
    font-size: 11px;
    line-height: 16px;
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

@media (max-width: 599px) {
    .epx-brand-tagline {
        display: none;
    }
}

/* Top-bar visual search mock (desktop only) */
.epx-search-mock {
    display: flex;
    align-items: center;
    gap: 8px;
    height: 36px;
    padding: 0 12px;
    width: 200px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--shape-full);
    color: var(--text-muted);
    font: 400 12px/16px "DM Sans", sans-serif;
    flex-shrink: 0;
}

.epx-search-mock__icon {
    display: flex;
    align-items: center;
    color: var(--text-muted);
    flex-shrink: 0;
}

/* DEPRECATED: Top navigation (legacy desktop horizontal nav). Pearl moves
   primary nav to the left sidebar. Classes preserved as no-op aliases until
   any non-shell page that referenced them is migrated. */
.epx-top-nav {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-left: 16px;
}

.epx-top-nav__item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 12px;
    border-radius: var(--shape-full);
    font-size: 14px;
    font-weight: 500;
    color: var(--text-muted);
    text-decoration: none;
    line-height: 1;
    transition: background 0.15s var(--ease-emp), color 0.15s var(--ease-emp);
}

.epx-top-nav__item:hover {
    background: var(--surface-2);
    color: var(--text);
}

.epx-top-nav__item.active {
    background: var(--accent-soft);
    color: var(--accent-strong);
}

/* ---------- Pearl Sidebar (220px, persistent on desktop ≥ 960px) ---------- */
.epx-sidebar {
    width: 220px;
    height: 100%;
    background: var(--surface);
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    padding: 20px 12px;
    gap: 4px;
    overflow-y: auto;
    box-sizing: border-box;
}

.epx-sidebar__brand {
    padding: 4px 12px 20px;
    display: flex;
    align-items: center;
    gap: 10px;
    color: inherit;
    text-decoration: none;
}

.epx-sidebar__section-label {
    font: 500 11px/16px "DM Sans", sans-serif;
    color: var(--text-muted);
    padding: 8px 12px 4px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.epx-sidebar__section-label--spaced {
    padding-top: 12px;
}

.epx-sidebar__item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0 12px;
    height: 44px;
    border-radius: var(--shape-full);
    border: none;
    cursor: pointer;
    background: transparent;
    color: var(--text-muted);
    font: 500 14px/20px "DM Sans", sans-serif;
    text-align: left;
    width: 100%;
    text-decoration: none;
    transition: all 0.15s var(--ease-emp);
}

.epx-sidebar__item:hover {
    background: var(--surface-2);
    color: var(--text);
}

.epx-sidebar__item.active,
.epx-sidebar__item--active {
    background: var(--accent-soft);
    color: var(--accent-strong);
}

.epx-sidebar__item-icon {
    width: 24px;
    height: 24px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.epx-sidebar__group-toggle {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0 12px;
    height: 44px;
    border-radius: var(--shape-full);
    border: none;
    cursor: pointer;
    background: transparent;
    color: var(--text-muted);
    font: 500 14px/20px "DM Sans", sans-serif;
    text-align: left;
    width: 100%;
    transition: all 0.15s var(--ease-emp);
}

.epx-sidebar__group-toggle:hover,
.epx-sidebar__group-toggle--open {
    background: var(--surface-2);
    color: var(--text);
}

.epx-sidebar__group-toggle__label {
    flex: 1;
}

.epx-sidebar__group-toggle__chevron {
    font-size: 10px;
    transition: transform 0.25s var(--ease-emp);
    color: var(--text-muted);
}

.epx-sidebar__group-toggle--open .epx-sidebar__group-toggle__chevron {
    transform: rotate(180deg);
}

.epx-sidebar__subitem {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0 12px 0 46px;
    height: 40px;
    border-radius: var(--shape-full);
    border: none;
    cursor: pointer;
    background: transparent;
    color: var(--text-muted);
    font: 500 12px/16px "DM Sans", sans-serif;
    text-align: left;
    width: 100%;
    text-decoration: none;
    transition: all 0.15s var(--ease-emp);
}

.epx-sidebar__subitem:hover {
    background: var(--surface-2);
    color: var(--text);
}

.epx-sidebar__subitem.active,
.epx-sidebar__subitem--active {
    background: var(--accent-soft);
    color: var(--accent-strong);
}

.epx-sidebar__spacer {
    flex: 1;
}

.epx-sidebar__footer {
    border-top: 1px solid var(--border);
    padding-top: 12px;
    margin-top: 8px;
}

.epx-sidebar__footer-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
}

.epx-sidebar__footer-avatar {
    width: 32px;
    height: 32px;
    border-radius: var(--shape-full);
    background: var(--accent);
    color: var(--on-primary);
    font: 500 12px/16px "DM Sans", sans-serif;
    display: grid;
    place-items: center;
    flex-shrink: 0;
}

.epx-sidebar__footer-name {
    font: 500 12px/16px "DM Sans", sans-serif;
    color: var(--text);
}

.epx-sidebar__footer-role {
    font: 500 11px/16px "DM Sans", sans-serif;
    color: var(--text-muted);
}


/* ---------- Pearl Bottom Navigation v2 (mobile) — primary row + Tools/Billing drop-ups + pull-up drawer ---------- */
.epx-bnav {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1100;
    background: var(--surface);
    border-top: 1px solid var(--border);
    box-shadow: var(--epx-elevation-2);
}

/* One fixed 5-column grid. Collapsed = just the first row (the 5 primary icons). Expanded =
   the bar grows upward and the remaining icons fill the rows below, keeping the 5 columns
   (last row left partial). The primary 5 always occupy the TOP row. */
.epx-bnav__grid {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    grid-auto-rows: 72px;
    align-items: stretch;
    padding: 0 4px;
    padding-bottom: env(safe-area-inset-bottom, 0px);
}

/* Tools/Billing drop-up wrappers are grid cells too — stretch their button to fill the cell. */
.epx-bnav__dropup-wrap {
    display: flex;
    justify-content: center;
}

.epx-bnav__dropup-wrap > .epx-bnav__item {
    flex: 1;
}

/* Center pull handle on the bar's top edge — rides upward with the bar as it grows. */
.epx-bnav__handle {
    position: absolute;
    left: 50%;
    top: -22px;
    transform: translateX(-50%);
    width: 60px;
    height: 22px;
    border: 1px solid var(--border);
    border-bottom: none;
    border-radius: 14px 14px 0 0;
    background: var(--surface);
    display: grid;
    place-items: center;
    cursor: pointer;
    z-index: 1101;
}

.epx-bnav__grip {
    width: 28px;
    height: 4px;
    border-radius: var(--shape-full);
    background: var(--text-muted);
    transition: background 0.15s var(--ease-emp);
}

.epx-bnav__handle.open .epx-bnav__grip { background: var(--accent); }

.epx-bnav__item {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    padding: 4px 0;
    min-width: 48px;
    min-height: 48px;
    background: transparent;
    border: none;
    cursor: pointer;
    color: var(--text-muted);
    text-decoration: none;
    transition: color 0.15s var(--ease-emp);
}

.epx-bnav__item:hover { color: var(--text); }
.epx-bnav__item.active { color: var(--accent); }

.epx-bnav__pill {
    width: 40px;
    height: 28px;
    border-radius: var(--shape-full);
    display: grid;
    place-items: center;
    background: transparent;
    color: inherit;
    transition: all 0.25s var(--ease-emp);
}

.epx-bnav__item.active .epx-bnav__pill { width: 56px; background: var(--accent-soft); }

.epx-bnav__label {
    font: 500 11px/16px "DM Sans", sans-serif;
    letter-spacing: 0.01em;
}

/* Drop-up (Tools / Billing) — menu above the slot. */
.epx-bnav__dropup-wrap { position: relative; }

.epx-bnav__dropup {
    position: absolute;
    bottom: calc(100% + 10px);
    left: 50%;
    transform: translateX(-50%);
    min-width: 168px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 14px;
    box-shadow: var(--epx-elevation-2);
    padding: 6px;
    z-index: 1102;
}

/* Rightmost slot (Billing): anchor the drop-up to its right edge so it opens inward
   and never spills off-screen. */
.epx-bnav__dropup--end {
    left: auto;
    right: 4px;
    transform: none;
}

.epx-bnav__dropup-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border-radius: 10px;
    color: var(--text);
    text-decoration: none;
    white-space: nowrap;
    font: 500 14px/1 "DM Sans", sans-serif;
}

.epx-bnav__dropup-item:hover { background: var(--accent-soft); color: var(--accent); }
.epx-bnav__dropup-item.active { color: var(--accent); }

.epx-bnav__scrim {
    position: fixed;
    inset: 0;
    background: transparent;
    z-index: 1099;
}

/* ---------- Settings mosaic (/settings) — icon tiles ---------- */
.epx-settings-mosaic {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 12px;
    margin-top: 8px;
}

.epx-settings-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 22px 12px;
    min-height: 124px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 16px;
    cursor: pointer;
    color: var(--text);
    transition: transform 0.15s var(--ease-emp), box-shadow 0.2s var(--ease-emp), border-color 0.15s var(--ease-emp);
}

.epx-settings-tile:hover {
    transform: translateY(-2px);
    box-shadow: var(--epx-elevation-2);
    border-color: var(--accent);
}

.epx-settings-tile__icon {
    width: 52px;
    height: 52px;
    border-radius: var(--shape-full);
    display: grid;
    place-items: center;
    background: var(--accent-soft);
    color: var(--accent);
}

.epx-settings-tile__label {
    font: 600 13px/1.25 "DM Sans", sans-serif;
    text-align: center;
}

@media (max-width: 599.98px) {
    .epx-settings-mosaic { grid-template-columns: repeat(2, 1fr); gap: 10px; }
    .epx-settings-tile { min-height: 108px; padding: 18px 8px; }
}

/* Summary-KPI grid removed from the top of every list page (Customers, Estimates, Invoices,
   Expenses, Salaries, Teams, Users, Roles, Reports, Tenants). The dashboard KPIs use a separate
   class (.epx-kpi-card) and are unaffected. */
.epx-stats-grid { display: none !important; }

/* ---------- Pearl Bottom Navigation (mobile, ≤ 960px) ---------- */
.epx-bottom-nav {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1100;
    height: 72px;
    display: flex;
    justify-content: space-around;
    align-items: center;
    padding: 0 4px calc(0px + env(safe-area-inset-bottom, 0px));
    background: var(--surface);
    border-top: 1px solid var(--border);
}

.epx-bottom-nav__item {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    padding: 4px 0;
    min-width: 48px;
    min-height: 48px;
    background: transparent;
    border: none;
    cursor: pointer;
    color: var(--text-muted);
    text-decoration: none;
    transition: color 0.15s var(--ease-emp);
}

.epx-bottom-nav__item:hover {
    color: var(--text);
}

.epx-bottom-nav__item.active,
.epx-bottom-nav__item--active {
    color: var(--accent);
}

/* Pearl pill — 40×28 inactive, 56×28 active, accent-soft background when active */
.epx-bottom-nav__icon-pill {
    width: 40px;
    height: 28px;
    border-radius: var(--shape-full);
    display: grid;
    place-items: center;
    background: transparent;
    transition: all 0.25s var(--ease-emp);
}

.epx-bottom-nav__item.active .epx-bottom-nav__icon-pill,
.epx-bottom-nav__item--active .epx-bottom-nav__icon-pill {
    width: 56px;
    background: var(--accent-soft);
}

.epx-bottom-nav__icon {
    transition: color 0.15s var(--ease-emp);
}

.epx-bottom-nav__item.active .epx-bottom-nav__icon,
.epx-bottom-nav__item--active .epx-bottom-nav__icon {
    color: var(--accent);
}

.epx-bottom-nav__label {
    font: 500 11px/16px "DM Sans", sans-serif;
    letter-spacing: 0.01em;
}

/* "Más" overflow dropdown that expands UPWARD from the bottom nav */
.epx-bottom-nav__more-wrap {
    position: relative;
}

.epx-bottom-nav__more-menu {
    position: absolute;
    bottom: calc(100% + 12px);
    right: -16px;
    width: 220px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--shape-lg);
    box-shadow: var(--sh-lg);
    z-index: 50;
    overflow: hidden;
    animation: epx-drop-up 0.2s var(--ease-decel);
}

.epx-bottom-nav__more-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0 16px;
    height: 44px;
    width: 100%;
    font: 500 14px/20px "DM Sans", sans-serif;
    text-align: left;
    border: none;
    cursor: pointer;
    background: transparent;
    color: var(--text);
    text-decoration: none;
    transition: background 0.1s var(--ease-emp);
}

.epx-bottom-nav__more-item:hover {
    background: var(--surface-2);
}

.epx-bottom-nav__more-item.active,
.epx-bottom-nav__more-item--active {
    background: var(--accent-soft);
    color: var(--accent-strong);
}

.epx-bottom-nav__more-divider {
    height: 1px;
    background: var(--border);
    margin: 4px 0;
}

.epx-bottom-nav__more-section-label {
    font: 500 11px/16px "DM Sans", sans-serif;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 6px 16px 2px;
}

.epx-bottom-nav__more-subitem {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0 16px 0 24px;
    height: 40px;
    width: 100%;
    font: 500 12px/16px "DM Sans", sans-serif;
    text-align: left;
    border: none;
    cursor: pointer;
    background: transparent;
    color: var(--text-muted);
    text-decoration: none;
    transition: background 0.1s var(--ease-emp);
}

.epx-bottom-nav__more-subitem:hover {
    background: var(--surface-2);
    color: var(--text);
}

.epx-bottom-nav__more-subitem.active,
.epx-bottom-nav__more-subitem--active {
    background: var(--accent-soft);
    color: var(--accent-strong);
}

@keyframes epx-drop-up {
    from { opacity: 0; transform: translateY(12px) scale(0.97); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* Content padding when bottom nav is visible (md and below — MudBlazor md breakpoint = 960px) */
@media (max-width: 959.98px) {
    .epx-has-bottom-nav .mud-main-content {
        padding-bottom: 96px;
    }
}

/* Shopify settings — discover handles panel */
.epx-shopify-discover {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-top: 12px;
    max-height: 480px;
    overflow-y: auto;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 10px;
    padding: 8px;
}

.epx-shopify-discover__row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px;
    border-radius: 8px;
    transition: background 0.15s ease;
}

.epx-shopify-discover__row:hover {
    background: var(--mud-palette-action-default-hover);
}

.epx-shopify-discover__thumb {
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    border-radius: 6px;
    overflow: hidden;
    background: var(--mud-palette-background-gray);
    border: 1px solid var(--mud-palette-lines-default);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--mud-palette-text-secondary);
}

.epx-shopify-discover__thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.epx-shopify-discover__main {
    flex: 1 1 auto;
    min-width: 0;
}

.epx-shopify-discover__title {
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--mud-palette-text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.epx-shopify-discover__meta {
    font-size: 0.72rem;
    color: var(--mud-palette-text-secondary);
    margin-top: 2px;
}

/* Card wrapper shared by Calculator + list pages. `overflow: hidden` clips
   inner content (e.g. MudTable rows) to the rounded outer border so we don't
   see white triangle gaps at the corners. */
.epx-card {
    border-radius: 14px;
    border: 1px solid var(--mud-palette-lines-default);
    background: var(--mud-palette-surface);
    padding: 24px;
    box-shadow: var(--epx-elevation-1);
    transition: box-shadow var(--epx-motion-medium);
    overflow: hidden;
}

.epx-card__title {
    font-family: var(--pearl-font);
    font-weight: 700;
    font-size: 1.35rem;
    letter-spacing: -0.01em;
    color: var(--mud-palette-text-primary);
}

.epx-info-banner {
    border-radius: 10px;
    padding: 14px 16px;
    background: rgba(61, 90, 128, 0.08);
    border: 1px solid rgba(61, 90, 128, 0.18);
    font-size: 0.88rem;
    line-height: 1.5;
    color: var(--mud-palette-text-primary);
    display: flex;
    gap: 10px;
    align-items: flex-start;
}

.epx-info-banner code {
    font-family: "JetBrains Mono", "Fira Code", Consolas, monospace;
    font-size: 0.78rem;
    padding: 1px 4px;
    border-radius: 4px;
    background: rgba(0, 0, 0, 0.06);
}

/* ---------- Floor plan sketch ---------- */
.fps-root {
    display: flex;
    flex-direction: column;
}

.fps-svg-wrap {
    width: 100%;
    border-radius: 12px;
    border: 1px solid var(--mud-palette-lines-default);
    background: var(--mud-palette-background-gray);
    overflow: hidden;
}

.fps-svg {
    width: 100%;
    height: auto;
    display: block;
    touch-action: none;
    cursor: crosshair;
}

.fps-grid-bg {
    fill: transparent;
}

.fps-dot {
    fill: var(--mud-palette-lines-default);
    opacity: 0.9;
}

/* Polygon outline — amber stroke + amber-tinted fill. High contrast against
   both the dotted background and the blue vertex markers. */
.fps-polyline {
    fill: rgba(161, 98, 7, 0.12);
    stroke: var(--mud-palette-secondary);
    stroke-width: 3;
    stroke-linejoin: round;
    stroke-linecap: round;
    pointer-events: none;
}

/* Vertex markers — solid dark fill with surface-toned ring so they pop in both modes. */
.fps-vertex {
    fill: var(--mud-palette-primary);
    stroke: var(--surface);
    stroke-width: 2.5;
    pointer-events: none;
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.35));
}

.fps-vertex--first {
    fill: var(--mud-palette-warning);
    stroke: var(--surface);
    stroke-width: 3;
    filter: drop-shadow(0 0 4px rgba(251, 191, 36, 0.7))
            drop-shadow(0 1px 2px rgba(0, 0, 0, 0.35));
}

/* Edge letter labels — paint-order halo for max readability on any surface. */
.fps-edge-label {
    fill: var(--mud-palette-primary);
    stroke: var(--surface);
    stroke-width: 3.5;
    paint-order: stroke fill;
    font-family: var(--pearl-font);
    font-size: 13px;
    font-weight: 800;
    letter-spacing: 0.02em;
    pointer-events: none;
    user-select: none;
}

.fps-lengths {
    margin-top: 12px;
}

.fps-lengths__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 8px;
}

.fps-lengths__row {
    display: flex;
    align-items: center;
    gap: 8px;
}

.fps-lengths__letter {
    font-weight: 700;
    color: var(--mud-palette-text-secondary);
    min-width: 18px;
    text-align: center;
}

/* ---------- Materials result list ---------- */
.epx-material-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.epx-material-line {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    padding: 14px 16px;
    border-radius: 10px;
    border: 1px solid var(--mud-palette-lines-default);
    background: var(--mud-palette-background-gray);
    transition: background 0.15s ease, border-color 0.15s ease;
}

.epx-material-line:hover {
    background: var(--mud-palette-action-default-hover);
    border-color: var(--mud-palette-lines-inputs);
}

.epx-material-line:nth-child(even) {
    background: var(--mud-palette-surface);
}

.epx-material-line:nth-child(even):hover {
    background: var(--mud-palette-action-default-hover);
}

.epx-material-line__thumb {
    flex: 0 0 auto;
    width: 56px;
    height: 56px;
    border-radius: 8px;
    overflow: hidden;
    background: var(--mud-palette-surface);
    border: 1px solid var(--mud-palette-lines-default);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--mud-palette-text-secondary);
}

.epx-material-line__thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.epx-material-line__main {
    flex: 1 1 auto;
    min-width: 0;
}

.epx-material-line__price {
    flex: 0 0 auto;
    text-align: end;
    white-space: nowrap;
}

/* Validation — Blazor's <ValidationMessage> renders <div class="validation-message">
   and <ValidationSummary> renders <ul class="validation-errors">. Pearl rule #12
   says we eliminate <ValidationSummary> in favour of inline per-field errors, but
   until every form migrates (Phases 3, 5, 7) we keep both styled red and token-
   driven so dark mode works. */
.validation-message {
    color: var(--mud-palette-error);
    font-size: .8rem;
    margin: 3px 0 0;
    text-align: start;
    font-weight: 500;
    line-height: 1.66;
    letter-spacing: .03333em;
}

.validation-errors {
    list-style: none;
    margin: 12px 0 0;
    padding: 12px 14px;
    background: var(--danger-soft);
    border: 1px solid var(--danger);
    border-radius: var(--shape-sm);
    color: var(--mud-palette-error);
    font-size: .8rem;
    line-height: 1.5;
}

.validation-errors li {
    padding-left: 16px;
    position: relative;
    color: var(--mud-palette-error);
}

.validation-errors li::before {
    content: "•";
    position: absolute;
    left: 4px;
    color: var(--mud-palette-error);
    font-weight: 700;
}

/* ---------- Pearl Form Inputs (minimal, native-first) ----------
   The previous monolithic override block (~340 lines) is gone. MudBlazor's
   native outlined / filled inputs render with their default look — we only
   nudge the typography stack + helper text colour + dropdown surface to stay
   on-palette. Date pickers, numeric fields, textareas and selects keep their
   stock MudBlazor chrome. See feedback_mudblazor_native_first.md (memory). */

.mud-input-control + .mud-input-control {
    margin-top: 8px;
}

/* Popover items (MudSelect / MudAutocomplete dropdowns) — Pearl tint on hover
   and selected items. Purely cosmetic — doesn't touch geometry. */
.mud-popover .mud-list-item:hover {
    background: var(--surface-2);
}

.mud-popover .mud-list-item.mud-selected-item,
.mud-popover .mud-list-item.mud-selected-item:hover {
    background: var(--accent-soft);
    color: var(--accent-strong);
}


/* (Pearl MudBlazor override block reverted 2026-05-14 — let MudBlazor render native chrome) */

/* ---------- Account layout (Login / Register / Forgot password / etc.) ----
   AccountLayout renders a FULL-BLEED two-column shell PINNED to the viewport.
   position:fixed + inset:0 guarantees the shell exactly fills the viewport so
   the brand-panel footer is always visible without scrolling — no stray top
   space from sibling components (LoadingProgressBar, MudLayout margins, etc.)
   can push it off the bottom.
   100dvh on mobile to handle Safari's URL-bar height change correctly. */
.epx-account-shell {
    position: fixed;
    inset: 0;
    display: grid;
    grid-template-columns: 1fr 1fr;
    height: 100vh;
    height: 100dvh;
    z-index: 1;
}

.epx-account-shell__brand {
    position: relative;
    display: grid;
    grid-template-rows: 1fr auto;
    justify-items: center;
    align-items: center;
    padding: 48px 40px 28px;
    background:
        radial-gradient(circle at 85% 15%, rgba(255, 255, 255, 0.10), transparent 50%),
        radial-gradient(circle at 15% 85%, rgba(0, 0, 0, 0.18), transparent 55%),
        linear-gradient(135deg,
            var(--mud-palette-primary) 0%,
            color-mix(in srgb, var(--mud-palette-primary) 65%, #000) 100%);
    color: #ffffff;
    overflow: hidden;
}

/* Slim highlight along the top edge — adds depth without distraction. */
.epx-account-shell__brand::after {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.35), transparent);
    pointer-events: none;
}

.epx-login-brand {
    display: flex;
    flex-direction: column;
    align-items: center;
    align-self: center;
    justify-self: center;
    gap: 14px;
    max-width: 400px;
    text-align: center;
}

/* Bottom-row attribution: copyright + 'A product of AchStack.com'.
   Muted white to match the welcome/description body copy — the footer
   reads as supporting text, not a competing dark band. */
.epx-login-brand-footer {
    align-self: end;
    justify-self: start;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    font-size: 0.8rem;
    color: rgba(255, 255, 255, 0.72);
    letter-spacing: 0.01em;
}

.epx-login-brand-footer__dot {
    opacity: 0.45;
}

.epx-login-brand-footer a {
    color: rgba(255, 255, 255, 0.94);
    font-weight: 600;
    text-decoration: none;
    border-bottom: 1px solid rgba(255, 255, 255, 0.32);
    transition: color 150ms ease, border-bottom-color 150ms ease;
}

.epx-login-brand-footer a:hover,
.epx-login-brand-footer a:focus-visible {
    color: #ffffff;
    border-bottom-color: rgba(255, 255, 255, 0.78);
}

/* Cream-tile favicon used as the brand mark on the auth panel — has its own
   integrated outline (the cream square contrasts against the amber panel),
   plus dark trowel and dark meniscus inside. Subtle shadow for depth. */
.epx-login-brand__mark-img {
    width: clamp(84px, 10vmin, 108px);
    height: clamp(84px, 10vmin, 108px);
    border-radius: clamp(16px, 2vmin, 22px);
    filter: drop-shadow(0 10px 24px rgba(0, 0, 0, 0.28));
    margin-bottom: 18px;
}

/* Wordmark — deep ink to anchor the brand identity at the top of the hierarchy
   against the amber panel. Two-tone ("Epoxy" lighter, "Job" heavier). */
.epx-login-brand__title {
    color: #1A1612 !important;
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.02;
    margin-bottom: 2px;
    font-size: clamp(2.5rem, 5vmin, 3.5rem) !important;
}

/* Mixed-tone title: "Epoxy" in white (light) + "Job" in deep ink (dark).
   The pairing layers light/dark within the wordmark and pulls the brand-
   defining noun ("Job") forward against the amber panel. */
.epx-login-brand__title__name {
    color: rgba(255, 255, 255, 0.92);
    font-weight: 500;
    text-shadow: 0 1px 1px rgba(0, 0, 0, 0.18);
}

.epx-login-brand__title__role {
    color: #1A1612;
    font-weight: 800;
}

/* Editorial accent — slim white rule under the title bridges the dark wordmark
   to the white copy below; centered to match the centered brand block. */
.epx-login-brand__rule {
    width: 56px;
    height: 2px;
    background: rgba(255, 255, 255, 0.65);
    border-radius: 2px;
    margin: 14px auto 10px;
}

/* Feature bullet list — replaces the description paragraph with four
   centered checkmark + text rows, reading more like a product feature
   strip on a marketing page. */
.epx-login-brand__features {
    list-style: none;
    padding: 0;
    margin: 12px 0 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
    width: 100%;
    max-width: 320px;
}

.epx-login-brand__feature {
    display: flex;
    align-items: center;
    gap: 12px;
    color: rgba(255, 255, 255, 0.92);
    font-size: clamp(0.95rem, 1.45vmin, 1.05rem);
    font-weight: 500;
    line-height: 1.35;
    text-align: left;
}

.epx-login-brand__feature-check {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.18);
    border: 1px solid rgba(255, 255, 255, 0.42);
    color: #ffffff;
    font-size: 0.75rem;
    font-weight: 700;
    line-height: 1;
}

/* Welcome subtitle: DARK ink — pairs with the dark "Job" in the title
   above and creates a deliberate light → dark → dark → light layering
   ("Epoxy" white, "Job" dark, welcome dark, description white). */
.epx-login-brand__welcome {
    color: rgba(26, 22, 18, 0.92) !important;
    font-weight: 600;
    letter-spacing: 0.005em;
    line-height: 1.35;
    margin-top: 4px;
    font-size: clamp(1.1rem, 1.8vmin, 1.3rem) !important;
}

.epx-login-brand__description {
    color: rgba(255, 255, 255, 0.86) !important;
    line-height: 1.6;
    margin-top: 8px;
    font-size: clamp(0.95rem, 1.5vmin, 1.08rem) !important;
}

.epx-account-shell__form {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 48px 32px;
    background: var(--bg, var(--mud-palette-background));
}

/* Bottom-right cluster: dark-mode toggle + language switcher. Absolute so it
   doesn't push form content; sits in the corner. */
.epx-account-shell__form-controls {
    position: absolute;
    bottom: 16px;
    right: 20px;
    display: flex;
    align-items: center;
    gap: 4px;
    z-index: 2;
}

/* Constrain the form content so even on ultra-wide screens it stays readable
   (~440px is the standard auth form width for desktop). */
.epx-account-shell__form-inner {
    width: 100%;
    max-width: 440px;
}

/* Account form internals — used by Login, Register, ForgotPassword, ResetPassword,
   ConfirmEmail, etc. All inherit from AccountLayout so styling once cascades. */
.epx-account-form-header {
    margin-bottom: 28px;
}

.epx-account-form-header__title {
    margin: 0 0 6px !important;
    color: var(--mud-palette-text-primary);
}

.epx-account-form-header__lede {
    color: var(--mud-palette-text-secondary);
    margin: 0 !important;
}

.epx-account-form-header__lede a {
    font-weight: 600;
}

.epx-account-links {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    margin: 8px 0 24px;
    font-size: 0.875rem;
}

/* Single-link variant: only the "Forgot password" link remains after the
   register-flow removal. Right-aligned so the eye lands on it after
   reading the password field. */
.epx-account-links--single {
    justify-content: flex-end;
}

.epx-account-links a {
    font-weight: 500;
}

.epx-account-submit {
    margin-top: 4px;
    height: 48px;
    font-weight: 600;
    letter-spacing: 0.01em;
}

/* ---------- Google sign-in button (Google identity brand guidelines) ----
   White surface in light mode, dark gray (#131314) in dark mode, with the
   official 4-color "G" logo at 18 px on the left. Hover gives subtle bg
   shift + shadow per Google's recommended interaction states. */
.epx-google-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    width: 100%;
    height: 44px;
    background: #ffffff;
    color: #1f1f1f;
    border: 1px solid #dadce0;
    border-radius: 8px;
    text-decoration: none;
    font-weight: 500;
    font-size: 0.95rem;
    letter-spacing: 0.005em;
    cursor: pointer;
    transition: background-color 150ms ease, border-color 150ms ease, box-shadow 150ms ease;
}

.epx-google-btn:hover,
.epx-google-btn:focus-visible {
    background: #f8f9fa;
    border-color: #d2d3d6;
    box-shadow: 0 1px 3px rgba(60, 64, 67, 0.10), 0 1px 2px rgba(60, 64, 67, 0.06);
    text-decoration: none;
}

.epx-google-btn:active {
    background: #f1f3f4;
}

.epx-google-btn__logo svg {
    width: 18px;
    height: 18px;
    display: block;
}

.epx-google-btn__text {
    line-height: 1;
}

/* Dark-mode variant — Google's official dark theme spec. */
.mud-theme-dark .epx-google-btn,
[data-mud-theme="dark"] .epx-google-btn {
    background: #131314;
    color: #e3e3e3;
    border-color: #8e918f;
}

.mud-theme-dark .epx-google-btn:hover,
.mud-theme-dark .epx-google-btn:focus-visible,
[data-mud-theme="dark"] .epx-google-btn:hover,
[data-mud-theme="dark"] .epx-google-btn:focus-visible {
    background: #1f1f1f;
    border-color: #a8aba8;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}

/* Generic fallback for other future external providers. */
.epx-external-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 44px;
    background: var(--mud-palette-surface, #ffffff);
    color: var(--mud-palette-text-primary, #1f1f1f);
    border: 1px solid var(--mud-palette-divider, rgba(0, 0, 0, 0.12));
    border-radius: 8px;
    text-decoration: none;
    font-weight: 500;
    font-size: 0.95rem;
    cursor: pointer;
    transition: background-color 150ms ease;
}

.epx-external-btn:hover {
    background: var(--mud-palette-action-default-hover, rgba(0, 0, 0, 0.04));
    text-decoration: none;
}

/* "O continúa con" divider — thin rules on either side of the centered label. */
.epx-divider-text {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 24px 0 16px;
    color: var(--mud-palette-text-secondary);
    font-size: 0.8125rem;
    text-transform: lowercase;
    letter-spacing: 0.04em;
}

.epx-divider-text::before,
.epx-divider-text::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--mud-palette-divider, rgba(0, 0, 0, 0.12));
}

.epx-divider-text span {
    display: inline-block;
    white-space: nowrap;
}

/* Mobile (< 900 px): collapse to a single column. The amber brand panel
   becomes a thin HEADER strip at the top (logo + wordmark side-by-side,
   welcome and description hidden to save vertical space). The form takes
   the remaining height. The brand-panel footer (© + AchStack link)
   detaches via position:fixed and pins to the bottom of the viewport so
   the attribution is always visible without scrolling. */
@media (max-width: 899.98px) {
    .epx-account-shell {
        display: flex;
        flex-direction: column;
    }

    /* Brand panel keeps amber gradient but becomes a short header. */
    .epx-account-shell__brand {
        display: flex;
        flex-direction: row;
        align-items: center;
        padding: 14px 18px;
        flex-shrink: 0;
        height: auto;
        min-height: auto;
        max-height: 64px;
    }

    /* Logo + wordmark in a horizontal row on mobile. */
    .epx-login-brand {
        flex-direction: row;
        align-items: center;
        gap: 10px;
        padding-top: 0;
        max-width: none;
    }

    /* Hide welcome / description / accent rule / feature bullets — only the
       brand header (logo + wordmark) stays on mobile. */
    .epx-login-brand__welcome,
    .epx-login-brand__description,
    .epx-login-brand__features,
    .epx-login-brand__rule {
        display: none;
    }

    /* Compact logo for the header strip. */
    .epx-login-brand__mark-img {
        width: 36px;
        height: 36px;
        border-radius: 9px;
        margin-bottom: 0;
        filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.18));
    }

    /* Wordmark sized to fit beside the small logo. */
    .epx-login-brand__title {
        font-size: 1.4rem !important;
        margin-bottom: 0;
        line-height: 1;
    }

    /* Footer detaches and pins to the bottom of the viewport — same
       attribution visible without scrolling, regardless of form height. */
    .epx-login-brand-footer {
        position: fixed;
        bottom: 14px;
        left: 50%;
        transform: translateX(-50%);
        z-index: 5;
        font-size: 0.7rem;
        max-width: calc(100vw - 32px);
        justify-content: center;
        padding: 6px 12px;
        border-radius: 999px;
        background: rgba(245, 240, 230, 0.78);
        backdrop-filter: blur(8px);
        -webkit-backdrop-filter: blur(8px);
        color: rgba(26, 22, 18, 0.78);
        white-space: nowrap;
    }

    .epx-login-brand-footer a {
        color: rgba(26, 22, 18, 0.96);
        border-bottom-color: rgba(26, 22, 18, 0.32);
    }

    .epx-login-brand-footer a:hover,
    .epx-login-brand-footer a:focus-visible {
        color: #1A1612;
        border-bottom-color: rgba(26, 22, 18, 0.70);
    }

    /* Form panel takes the remaining height; bottom-padding leaves room for
       the fixed footer pill so the bottom of the form isn't covered. */
    .epx-account-shell__form {
        padding: 32px 20px 64px;
        flex: 1;
    }

    /* Form-controls cluster shifts up slightly so it doesn't overlap the
       fixed footer pill. */
    .epx-account-shell__form-controls {
        bottom: 56px;
    }
}

/* ---------- Public layout (magic-link views like PublicEstimate) ----------
   No sidebar, no auth chrome — transparent surface header with the EJM logo,
   plus the page content centered with a comfortable max-width. Tenant-specific
   branding (custom logo / tenant name) wires in during the PublicEstimate
   migration (Phase 8). Light mode only for now (Phase 8 decision). */
.epx-public-shell {
    min-height: 100vh;
    background: var(--bg);
    color: var(--text);
    display: flex;
    flex-direction: column;
}

.epx-public-shell__header {
    height: 60px;
    display: flex;
    align-items: center;
    padding: 0 24px;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}

.epx-public-shell__content {
    flex: 1;
    width: 100%;
    max-width: 920px;
    margin-inline: auto;
    padding: 24px;
}

@media (max-width: 599.98px) {
    .epx-public-shell__header {
        padding: 0 12px;
        height: 52px;
    }

    .epx-public-shell__content {
        padding: 16px 8px;
    }
}

/* Header Version Info */
.header-version-info {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 5px 20px;
    margin-left: 10px;
    box-shadow: 0 0 10px 2px rgba(176, 38, 255, 0.3);
}

    .header-version-info:hover {
        box-shadow: 0 0 20px 4px rgba(176, 38, 255, 0.7);
    }

.version-number {
    color: #b626ff;
    font-family: 'Orbitron', Consolas, monospace;
    font-size: 0.875rem;
    font-weight: 600;
    letter-spacing: 1.5px;
    line-height: 1.2;
    text-transform: none;
}

.framework-version {
    color: #b626ff;
    font-family: 'Orbitron', Consolas, monospace;
    font-size: 0.8rem;
    letter-spacing: 1px;
    opacity: 0.85;
    line-height: 1.2;
    text-transform: none;
}

.header-version-info:hover .version-number,
.header-version-info:hover .framework-version {
    text-shadow: 0 0 20px rgba(57, 255, 20, 1) !important;
}

/* ---------- Notifications bell popover ---------- */
.epx-notifications-popover {
    min-width: 340px;
    max-width: 400px;
}

/* Bell badge positioning. MudBlazor 9.2.0 default rule for top-right + overlap
   is `inset: auto auto calc(100% - 12px) calc(100% - 12px)` — that resolves
   to a negative top (badge floats outside the icon's top edge) and gets
   clipped by the AppBar/viewport boundary on a 64 px header.
   We override with `inset: 8px 8px auto auto` so the badge sits 8 px inside
   from the icon's top-right corner (fully contained inside the icon button),
   plus `scale(0.7)` for a smaller, less obtrusive bubble. The selector mirrors
   MudBlazor's full default selector to guarantee the cascade overrides it. */
.epx-bell-badge .mud-badge.mud-badge-top.right.mud-badge-overlap,
.epx-bell-badge .mud-badge.mud-badge-overlap,
.epx-bell-badge .mud-badge {
    inset: 8px 8px auto auto !important;
    transform: scale(0.7) !important;
    transform-origin: top right !important;
}

.epx-notifications-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 14px 8px;
}

.epx-notifications-header__actions {
    display: inline-flex;
    align-items: center;
    gap: 2px;
}

.epx-notifications-empty {
    padding: 18px 14px;
    text-align: center;
}

.epx-notifications-list {
    max-height: 420px;
    overflow-y: auto;
    padding: 0;
}

.epx-notification-row {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    padding: 2px 0;
    width: 100%;
}

.epx-notification-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    flex: 1 1 auto;
}

.epx-notification-title {
    font-weight: 600;
}

.epx-notification-body {
    color: var(--mud-palette-text-secondary);
    line-height: 1.35;
}

.epx-notification-row__action {
    flex-shrink: 0;
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 2px;
}

.epx-notification-unread {
    background: color-mix(in srgb, var(--mud-palette-primary) 6%, transparent);
}

/* ---------- Dashboard KPI cards ----------
   Reference style: spacious surface, small all-caps tracked label, dominant
   numeric value, optional muted caption. No avatar/icon — the typography
   rhythm carries the card. */
.epx-kpi-card {
    padding: 1.25rem;
    border-radius: 14px;
    box-shadow: var(--epx-elevation-1);
    transition: transform var(--epx-motion-fast), box-shadow var(--epx-motion-medium);
}

.epx-kpi-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--epx-elevation-2);
}

.epx-kpi-card__label {
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
    line-height: 1.2;
    margin-bottom: 0.5rem;
}

.epx-kpi-card__value {
    font-size: 2rem;
    font-weight: 700;
    line-height: 1.1;
    color: var(--mud-palette-text-primary);
    font-variant-numeric: tabular-nums;
}

.epx-kpi-card__caption {
    margin-top: 0.5rem;
    font-size: 0.72rem;
    color: var(--mud-palette-text-secondary);
    line-height: 1.3;
}

/* Mobile (xs, <600px): the 4 dashboard KPIs sit 2x2 (MudItem xs=6). Shrink the cards so two fit a
   narrow phone without overflowing money values. */
@media (max-width: 599.98px) {
    .epx-kpi-card {
        padding: 0.85rem;
        border-radius: 12px;
    }

    .epx-kpi-card__label {
        font-size: 0.6rem;
        letter-spacing: 0.06em;
        margin-bottom: 0.3rem;
    }

    .epx-kpi-card__value {
        font-size: 1.4rem;
    }

    .epx-kpi-card__caption {
        margin-top: 0.3rem;
        font-size: 0.6rem;
    }
}

/* ---------- Dashboard greeting hero ----------
   Borrowed pattern from the reference dashboard: small tracked eyebrow date,
   prominent salutation, muted subhead with the actionable count. Stays in the
   current Pearl palette — accent token already lives in --mud-palette-primary. */
.epx-dash-hero__eyebrow {
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
    line-height: 1.2;
}

.epx-dash-hero__headline {
    font-size: 2.25rem;
    font-weight: 700;
    line-height: 1.15;
    color: var(--mud-palette-text-primary);
    margin-top: 0.25rem;
}

.epx-dash-hero__subhead {
    font-size: 0.95rem;
    color: var(--mud-palette-text-secondary);
    margin-top: 0.5rem;
}

@media (max-width: 600px) {
    .epx-dash-hero__headline {
        font-size: 1.75rem;
    }

    /* Mobile pattern mirrors the calendar page header (Pearl §8.2): hero stacks
       vertically — eyebrow + greeting + subhead on row 1, range toggle on row 2
       at full width. MudStack with Row="true" applies the utility class .flex-row
       which sets flex-direction: row !important, so we must counter with
       !important here. .epx-dash-hero.mud-stack also bumps specificity for
       margin/gap overrides over MudStack's gap-* utility classes. */
    .epx-dash-hero.mud-stack,
    .epx-dash-hero {
        flex-direction: column !important;
        align-items: stretch !important;
        gap: 12px !important;
    }

    .epx-dash-hero > .mud-toggle-group {
        width: 100%;
    }

    .epx-dash-hero > .mud-toggle-group > .mud-toggle-item {
        flex: 1 1 0;
        min-width: 0;
    }
}

/* Section title used by the dashboard's "Active estimates" block — same eyebrow
   typography as the hero but at heading scale. */
.epx-dash-section__title {
    font-size: 1.05rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    color: var(--mud-palette-text-primary);
}

/* Estimate cards on the dashboard. Same lift-on-hover affordance as KPI cards
   since both are click-through surfaces. */
.epx-estimate-card {
    border-radius: 14px;
    box-shadow: var(--epx-elevation-1);
    transition: transform var(--epx-motion-fast), box-shadow var(--epx-motion-medium);
}

.epx-estimate-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--epx-elevation-2);
}

/* 3-column mini-grid inside each estimate card — AREA / TARIFA / TIPO.
   Pulled out of MudStack because the mini-label/value pair wants tight vertical
   stacking with controlled letter-spacing, and Mud's flex defaults fight that. */
.epx-estimate-card__grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.5rem 0.75rem;
    padding: 0.6rem 0.75rem;
    border-radius: 10px;
    background: color-mix(in srgb, var(--mud-palette-text-primary) 4%, transparent);
}

.epx-estimate-card__minilabel {
    font-size: 0.62rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
    line-height: 1.2;
    margin-bottom: 0.2rem;
}

.epx-estimate-card__minivalue {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--mud-palette-text-primary);
    line-height: 1.25;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Accent the user's first name in the greeting headline — matches the reference's
   "Good morning, Alex" pattern where the name picks up the dashboard accent. */
.epx-dash-hero__name {
    color: var(--mud-palette-primary);
}

/* Shared tracked-caps eyebrow / label utility. Use on any "section title at small
   size" — Mañana/Tarde/Noche, Próximo/Último, form-section breaks, etc. Larger
   eyebrows (page header, dashboard hero) live in their own classes with looser
   tracking; this one targets ~0.72rem in-card labels. */
.epx-eyebrow {
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
    line-height: 1.2;
}

/* Tertiary-accent variant — opt-in modifier for KPI cards or status chips */
.epx-accent-tertiary {
    border-left: 3px solid var(--epx-tertiary);
}


/* (Pearl MudBlazor override block reverted 2026-05-14 — let MudBlazor render native chrome) */

/* ---------- Form action row ----------
   Standard layout for the submit/cancel pair at the bottom of edit forms.
   Desktop: right-aligned in a single row.
   Mobile (< 600px): full-width column, content left-aligned. */
.epx-form-actions {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 8px;
    padding: 16px;
}

@media (max-width: 600px) {
    .epx-form-actions {
        flex-direction: column;
        align-items: stretch;
        gap: 8px;
        padding: 12px;
    }

    .epx-form-actions > .mud-button-root {
        width: 100%;
        justify-content: flex-start;
    }
}

/* ---------- Mobile FAB primary ----------
   Floating action button for the primary action of a page on phone-size
   viewports only. Pinned to the bottom-right, sitting above the bottom-nav
   strip with safe-area padding for notched phones.
   Pages render this inside a <MudHidden Breakpoint="Breakpoint.SmAndUp"/>. */
.epx-fab-primary,
.epx-fab-primary.mud-fab {
    position: fixed !important;
    right: 16px !important;
    bottom: calc(64px + 16px + env(safe-area-inset-bottom, 0px)) !important;
    z-index: 1050;
    box-shadow: var(--epx-elevation-2) !important;
}


/* (Pearl MudBlazor override block reverted 2026-05-14 — let MudBlazor render native chrome) */

/* ---------- Pick row alignment ----------
   Generic flex row that pairs a MudTextField (Margin.Dense) with an action
   button on its right. Keeps both elements bottom-aligned with the input
   baseline (not the field's outer bottom — accounts for the label height). */
.epx-pick-row {
    align-items: flex-end !important;
}

.epx-pick-row .mud-button-root {
    height: 40px;
    margin-bottom: 0;
}

/* ---------- Editor toolbar ----------
   Header action row for editor pages (EstimateEditor, InvoiceEditor) that
   carry multiple primary/secondary actions (Save, Send, Approve, Reject,
   etc.). Desktop: inline row with wrap. Mobile (< 600 px): each button
   takes its own row, full-width, content left-aligned. */
@media (max-width: 600px) {
    .epx-editor-toolbar > .mud-button-root {
        flex: 1 1 100%;
        justify-content: flex-start;
    }
}

/* ---------- Empty state ---------- */
.epx-empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 48px 24px;
    text-align: center;
    gap: 8px;
    color: var(--mud-palette-text-secondary);
    animation: epx-fade-in var(--epx-motion-medium);
}

.epx-empty-state__icon.mud-icon-root {
    color: var(--mud-palette-text-disabled);
    font-size: 56px !important;
    height: 56px;
    width: 56px;
    margin-bottom: 8px;
}

.epx-empty-state__title {
    color: var(--mud-palette-text-primary);
    font-weight: 600;
    margin-bottom: 4px;
}

.epx-empty-state__description {
    color: var(--mud-palette-text-secondary);
    max-width: 360px;
    line-height: 1.5;
}

.epx-empty-state__action {
    margin-top: 16px;
}

@media (max-width: 600px) {
    .epx-empty-state {
        padding: 32px 16px;
    }
    .epx-empty-state__icon.mud-icon-root {
        font-size: 48px !important;
        height: 48px;
        width: 48px;
    }
}

/* ---------- Microinteractions ---------- */
@keyframes epx-fade-in {
    from {
        opacity: 0;
        transform: translateY(8px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* Focus ring polish — visible but not overwhelming. M3-style 2 px ring with
   2 px offset, primary color. Applied only on keyboard focus (focus-visible)
   so mouse clicks don't show the ring. */
.epx-card .mud-button-root:focus-visible,
.epx-card .mud-icon-button:focus-visible,
.epx-fab-primary:focus-visible,
.mud-tab:focus-visible {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: 2px;
    border-radius: inherit;
}

/* Table row hover — smooth bg transition (MudBlazor's default is instant) */
.epx-card .mud-table-row:not(.mud-table-no-records) {
    transition: background-color var(--epx-motion-fast);
}

/* ---------- Settings shell (sidebar + content) ---------- */
.epx-settings-shell {
    display: grid;
    grid-template-columns: 260px minmax(0, 1fr);
    gap: 16px;
    padding: 16px;
}

.epx-settings-shell__aside {
    position: sticky;
    top: 88px;
    align-self: start;
}

.epx-settings-shell__content {
    min-width: 0;
}

.epx-settings-sidenav {
    padding: 12px;
    border-radius: 12px;
    border: 1px solid var(--mud-palette-lines-default);
}

.epx-settings-sidenav__title {
    display: block;
    padding: 4px 8px 8px;
    color: var(--mud-palette-text-secondary);
    letter-spacing: 1px;
}

@media (max-width: 960px) {
    .epx-settings-shell {
        grid-template-columns: 1fr;
        padding: 8px;
    }

    .epx-settings-shell__aside {
        position: static;
    }
}

/* ---------- Page header (Pearl) — title + actions, on page background ----------
   Pearl spec: lives directly on --bg (no card wrapper), title in title-lg
   weight 500, optional subtitle in body-sm muted, thin divider below, 24px
   gap before content. Icon parameter is no longer rendered (component still
   accepts it for backwards compatibility but ignores it). */
.epx-page-header {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 0;
    margin: 0 0 12px 0;
    width: 100%;
    box-sizing: border-box;
}

.epx-page-header__text {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-width: 0;
    line-height: 1.2;
    gap: 4px;
}

/* Optional eyebrow above the title — same anatomy as .epx-dash-hero__eyebrow so
   index pages can pick up the dashboard's hero rhythm when the consumer opts in. */
.epx-page-header__eyebrow {
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-muted);
    line-height: 1.2;
    margin: 0 0 2px 0;
}

.epx-page-header__title {
    font: 700 28px/34px "DM Sans", sans-serif !important;
    color: var(--text) !important;
    letter-spacing: -0.01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin: 0;
}

.epx-page-header__subtitle {
    font: 400 14px/20px "DM Sans", sans-serif !important;
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin: 0;
}

.epx-page-header__actions {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
}

.epx-page-header__actions .mud-button-root {
    text-transform: none;
}

/* Mobile (< 600px): wrap to 2 rows, actions stack as a full-width column. */
@media (max-width: 600px) {
    .epx-page-header {
        flex-wrap: wrap;
        row-gap: 12px;
        padding: 0;
        margin: 0 0 8px 0;
    }

    .epx-page-header__title {
        font: 700 22px/28px "DM Sans", sans-serif !important;
    }

    .epx-page-header__subtitle {
        white-space: normal;
    }

    .epx-page-header__actions {
        flex: 1 1 100%;
        flex-direction: column;
        align-items: stretch;
        gap: 8px;
    }

    .epx-page-header__actions > .mud-button-root,
    .epx-page-header__actions > .mud-icon-button {
        width: 100%;
        justify-content: flex-start;
    }

    /* MudToggleGroup in actions stacks full-width on mobile, with its items
       splitting the width equally — same row of pills, just stretched. Scoped
       to .epx-page-header__actions so it doesn't bleed into other pages. */
    .epx-page-header__actions > .mud-toggle-group {
        width: 100%;
    }

    .epx-page-header__actions > .mud-toggle-group > .mud-toggle-item {
        flex: 1 1 0;
    }
}

/* ---------- Responsive table toolbars ---------- */
/* Tablet & smaller: toolbar children wrap so they don't crowd horizontally. */
@media (max-width: 960px) {
    .epx-card .mud-table-toolbar {
        flex-wrap: wrap;
        gap: 8px;
        padding-top: 12px;
        padding-bottom: 12px;
        height: auto !important;
        min-height: auto !important;
    }
}

/* Phone: each toolbar child takes its own row so search/filter never overlap the data
   area. Inline max-widths from the markup are overridden so fields fill the available
   width comfortably for thumb input. */
@media (max-width: 600px) {
    .epx-card .mud-table-toolbar > * {
        flex: 1 1 100%;
        max-width: 100% !important;
        width: 100%;
    }

    /* FixedHeader can leak over the first row when the toolbar wraps to multiple lines.
       Anchor it to its natural place instead of sticky positioning on small screens. */
    .epx-card .mud-table-root .mud-table-head {
        position: static !important;
    }
}


/* (Pearl MudBlazor override block reverted 2026-05-14 — let MudBlazor render native chrome) */

/* ---------- Pearl Notification Panel ---------- */
.epx-notifications-popover {
    border-radius: var(--shape-lg) !important;
    border: 1px solid var(--border) !important;
    background: var(--surface) !important;
    box-shadow: var(--sh-lg) !important;
    width: 360px;
    max-width: 92vw;
    overflow: hidden;
    padding: 0 !important;
}

.epx-notifications-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 14px 16px 10px;
    gap: 8px;
}

.epx-notifications-title {
    font: 500 14px/20px "DM Sans", sans-serif;
    color: var(--text);
}

.epx-notifications-action-link {
    font: 500 11px/16px "DM Sans", sans-serif;
    color: var(--accent);
    cursor: pointer;
    background: none;
    border: none;
    padding: 0;
}

.epx-notifications-list {
    max-height: 280px;
    overflow-y: auto;
}

.epx-notif-row {
    display: flex;
    gap: 12px;
    padding: 12px 16px;
    border-top: 1px solid var(--border);
    cursor: pointer;
    transition: background 0.1s var(--ease-emp);
}

.epx-notif-row--unread {
    background: var(--accent-soft);
}

.epx-notif-row:hover {
    background: var(--surface-2);
}

.epx-notif-row--unread:hover {
    background: var(--accent-soft);
    filter: brightness(1.02);
}

.epx-notif-avatar {
    width: 36px;
    height: 36px;
    border-radius: var(--shape-full);
    display: grid;
    place-items: center;
    flex-shrink: 0;
    color: #fff;
    font: 500 12px/16px "DM Sans", sans-serif;
}

.epx-notif-avatar--read {
    background: var(--surface-2);
    color: var(--text-muted);
}

.epx-notif-meta {
    flex: 1;
    min-width: 0;
}

.epx-notif-title {
    font: 500 12px/16px "DM Sans", sans-serif;
    color: var(--text);
    margin-bottom: 2px;
}

.epx-notif-body {
    font: 400 12px/16px "DM Sans", sans-serif;
    color: var(--text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}

.epx-notif-time {
    font: 500 11px/16px "DM Sans", sans-serif;
    color: var(--text-muted);
    margin-top: 4px;
}

.epx-notif-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--accent);
    flex-shrink: 0;
    margin-top: 6px;
}

.epx-notifications-footer {
    padding: 12px;
    border-top: 1px solid var(--border);
    text-align: center;
}

.epx-notifications-footer__link {
    font: 500 14px/20px "DM Sans", sans-serif;
    color: var(--accent);
    cursor: pointer;
    background: none;
    border: none;
}

.epx-notifications-empty {
    padding: 48px 24px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    color: var(--text-muted);
    text-align: center;
}

@media (max-width: 599.98px) {
    .epx-notifications-popover {
        width: 340px;
    }
}

/* ---------- Pearl Language Drawer ---------- */
.epx-lang-popover {
    border-radius: var(--shape-lg) !important;
    border: 1px solid var(--border) !important;
    background: var(--surface) !important;
    box-shadow: var(--sh-lg) !important;
    width: 240px;
    overflow: hidden;
    padding: 0 !important;
}

.epx-lang-header {
    padding: 12px 16px 8px;
    font: 500 12px/16px "DM Sans", sans-serif;
    color: var(--text-muted);
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.epx-lang-list {
    max-height: 320px;
    overflow-y: auto;
}

.epx-lang-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 16px;
    width: 100%;
    font: 400 14px/20px "DM Sans", sans-serif;
    color: var(--text);
    background: transparent;
    border: none;
    cursor: pointer;
    text-align: left;
    transition: background 0.1s var(--ease-emp);
}

.epx-lang-row:hover {
    background: var(--surface-2);
}

.epx-lang-row--selected {
    background: var(--accent-soft);
    color: var(--accent-strong);
}

.epx-lang-row--selected:hover {
    background: var(--accent-soft);
}

.epx-lang-flag {
    font-size: 18px;
    line-height: 1;
    flex-shrink: 0;
}

.epx-lang-name {
    flex: 1;
}

.epx-lang-check {
    color: var(--accent);
    font-size: 14px;
    font-weight: 600;
}

/* ---------- Pearl User Menu ---------- */
.epx-user-menu {
    border-radius: var(--shape-md) !important;
    border: 1px solid var(--border) !important;
    background: var(--surface) !important;
    box-shadow: var(--sh-lg) !important;
    width: 240px;
    overflow: hidden;
    padding: 0 !important;
}

.epx-user-menu__header {
    padding: 16px;
    border-bottom: 1px solid var(--border);
    display: flex;
    gap: 12px;
    align-items: center;
}

.epx-user-menu__avatar {
    width: 40px;
    height: 40px;
    border-radius: var(--shape-full);
    background: var(--accent);
    color: var(--on-primary);
    font: 500 14px/20px "DM Sans", sans-serif;
    display: grid;
    place-items: center;
    flex-shrink: 0;
    overflow: hidden;
}

.epx-user-menu__avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.epx-user-menu__name {
    font: 500 14px/20px "DM Sans", sans-serif;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.epx-user-menu__sub {
    font: 400 12px/16px "DM Sans", sans-serif;
    color: var(--text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.epx-user-menu__item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 16px;
    width: 100%;
    font: 400 14px/20px "DM Sans", sans-serif;
    color: var(--text);
    background: none;
    border: none;
    cursor: pointer;
    text-align: left;
    text-decoration: none;
    transition: background 0.1s var(--ease-emp);
}

.epx-user-menu__item:hover {
    background: var(--surface-2);
}

.epx-user-menu__item-icon {
    color: var(--text-muted);
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
}

.epx-user-menu__divider {
    border-top: 1px solid var(--border);
}

.epx-user-menu__item--danger {
    color: var(--danger);
}

.epx-user-menu__item--danger:hover {
    background: var(--danger-soft);
}

.epx-user-menu__item--danger .epx-user-menu__item-icon {
    color: var(--danger);
}

/* User-menu activator (avatar circle in top bar) */
.epx-user-avatar-btn {
    width: 32px;
    height: 32px;
    padding: 0;
    border: 2px solid transparent;
    border-radius: var(--shape-full);
    background: var(--accent);
    color: var(--on-primary);
    cursor: pointer;
    display: grid;
    place-items: center;
    font: 500 12px/16px "DM Sans", sans-serif;
    overflow: hidden;
    transition: border 0.15s var(--ease-emp);
}

.epx-user-avatar-btn:hover,
.epx-user-avatar-btn--open {
    border-color: var(--accent);
}

.epx-user-avatar-btn img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: var(--shape-full);
}

/* ============================================================
   ============   PEARL COMPONENT MIGRATION — F2-F9   =========
   ============================================================
   Each block below targets a MudBlazor component group. CSS-only
   overrides — pages don't need markup changes. Tokens from Pearl
   §7 in docs/Design-Guidelines.md. */

/* ---------- Pearl Selection Controls — DEFERRED ----------
   MudCheckBox, MudRadio and MudSwitch keep MudBlazor's default rendering
   for now (they pick up the accent colour through Color="Color.Primary"
   and the theme palette). The Pearl-spec rebuild was reverted after the
   first attempt clipped the rendered control: it requires deeper DOM
   inspection of MudBlazor v7's switch/checkbox markup. We'll revisit
   them in a dedicated pass. */

/* ---------- Pearl Date / Time Pickers (native-first) ----------
   The previous monolithic override block (~120 lines on .mud-picker-* selectors)
   broke the calendar header, day buttons, time clock and toolbar after the
   surrounding form-input rebuild was stripped. We now let MudDatePicker /
   MudTimePicker render with their native chrome. The accent palette propagates
   automatically via PaletteLight/Dark in EjmAdminDashboardTheme.cs. See
   feedback_mudblazor_native_first.md (memory). */


/* (Pearl MudBlazor override block reverted 2026-05-14 — let MudBlazor render native chrome) */

/* ---------- Pearl Error Page (Design-Guidelines §8.3) ----------
   Centered single-column layout for 401 / 404 / generic errors. Circular hero
   icon at the top (warning-tinted), big mono code, headline-md title, body-lg
   description, action button row centered. */
.epx-error-page {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 64px 16px;
    gap: 12px;
}

.epx-error-page__icon {
    width: 96px;
    height: 96px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--accent-soft);
    color: var(--accent-strong);
    margin-bottom: 8px;
}

.epx-error-page__icon--warning {
    background: var(--warning-soft);
    color: var(--warning);
}

.epx-error-page__icon--danger {
    background: var(--danger-soft);
    color: var(--danger);
}

.epx-error-page__icon .mud-icon-root {
    font-size: 40px !important;
    width: 40px !important;
    height: 40px !important;
}

.epx-error-page__code {
    font-size: 36px;
    font-weight: 700;
    color: var(--text);
    line-height: 1.1;
    letter-spacing: 0.02em;
}

.epx-error-page__title {
    color: var(--text);
    margin-top: 4px;
}

.epx-error-page__description {
    color: var(--text-muted);
    max-width: 480px;
}

.epx-error-page__actions {
    display: flex;
    gap: 8px;
    margin-top: 16px;
    justify-content: center;
    flex-wrap: wrap;
}

/* ---------- Pearl Data Table primitives (prototype "Datos Financieros") ----------
   Used by list pages (Estimates pilot, then propagated). Stats grid above table,
   filter chips toolbar, bulk actions bar, status pills with dots. */

.epx-stats-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 16px;
    margin-bottom: 20px;
}

.epx-stat-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--shape-lg);
    padding: 18px 20px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    transition: border-color 0.15s var(--ease-emp), transform 0.15s var(--ease-emp);
}

.epx-stat-card:hover {
    border-color: var(--accent);
    transform: translateY(-1px);
}

.epx-stat-card__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.epx-stat-card__label {
    font-size: 12px;
    color: var(--text-muted);
    font-weight: 500;
}

.epx-stat-card__icon {
    width: 32px;
    height: 32px;
    border-radius: var(--shape-md);
    display: flex;
    align-items: center;
    justify-content: center;
}

.epx-stat-card__icon .mud-icon-root {
    font-size: 18px !important;
    width: 18px !important;
    height: 18px !important;
}

.epx-stat-card__icon--primary { background: var(--accent-soft); color: var(--accent); }
.epx-stat-card__icon--success { background: var(--success-soft); color: var(--success); }
.epx-stat-card__icon--warning { background: var(--warning-soft); color: var(--warning); }
.epx-stat-card__icon--info { background: var(--accent-soft); color: var(--accent-strong); }

.epx-stat-card__value {
    font-size: 24px;
    font-weight: 700;
    color: var(--text);
    line-height: 1.2;
}

.epx-stat-card__caption {
    font-size: 11px;
    color: var(--text-muted);
}

/* Toolbar with search left + filter chips + icon actions right */
.epx-table-toolbar {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 20px;
    border-bottom: 1px solid var(--border-light);
    flex-wrap: wrap;
}

.epx-table-toolbar__left {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 1;
    min-width: 0;
    flex-wrap: wrap;
}

.epx-table-toolbar__right {
    display: flex;
    align-items: center;
    gap: 6px;
}

/* Filter chips (Todos / Active / Pending / etc.) */
.epx-filter-chips {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}

.epx-filter-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 5px 12px;
    border: 1px solid var(--border);
    border-radius: var(--shape-full);
    font-size: 12px;
    font-weight: 500;
    color: var(--text-muted);
    background: var(--surface);
    cursor: pointer;
    transition: all 0.15s var(--ease-emp);
    user-select: none;
    white-space: nowrap;
}

.epx-filter-chip:hover {
    border-color: var(--accent);
    color: var(--accent);
}

.epx-filter-chip.active {
    background: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent-strong);
    font-weight: 600;
}

.epx-filter-chip__dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    display: inline-block;
    flex-shrink: 0;
}

.epx-filter-chip__dot--default { background: var(--text-muted); }
.epx-filter-chip__dot--info { background: var(--accent); }
.epx-filter-chip__dot--primary { background: var(--accent); }
.epx-filter-chip__dot--success { background: var(--success); }
.epx-filter-chip__dot--warning { background: var(--warning); }
.epx-filter-chip__dot--error { background: var(--danger); }
.epx-filter-chip__dot--dark { background: var(--text); }

/* Bulk action bar — appears above table when rows are selected */
.epx-bulk-bar {
    padding: 10px 20px;
    background: var(--accent-soft);
    border-bottom: 1px solid var(--border-light);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
}

/* Compact ledger totals — a thin summary strip (NOT the big KPI stat cards). */
.epx-ledger-summary {
    display: flex;
    gap: 28px;
    flex-wrap: wrap;
    padding: 10px 20px;
    border-bottom: 1px solid var(--border-light);
    background: var(--surface);
}

.epx-ledger-summary__item {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.epx-ledger-summary__label {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.epx-ledger-summary__value {
    font-size: 16px;
    font-weight: 700;
}

.epx-bulk-bar__count {
    font-size: 13px;
    font-weight: 600;
    color: var(--accent-strong);
}

.epx-bulk-bar__actions {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}

@media (max-width: 599.98px) {
    .epx-table-toolbar {
        padding: 12px;
    }
    .epx-stats-grid {
        grid-template-columns: 1fr 1fr;
        gap: 10px;
    }
    .epx-stat-card {
        padding: 14px;
    }
    .epx-stat-card__value {
        font-size: 18px;
    }
}

/* ---------- Pearl Dialog hero icons (Design-Guidelines §11.2) ----------
   Circular hero icon centered above the body copy of a danger/success/info
   modal. Used by DeleteConfirmationDialog, RemoveConfirmationDialog,
   SaveConfirmationDialog and any page-level dialog wanting the same hierarchy. */
.epx-dialog-hero-icon {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 16px;
}

.epx-dialog-hero-icon--danger {
    background: var(--danger-soft);
    color: var(--danger);
}

.epx-dialog-hero-icon--success {
    background: var(--success-soft);
    color: var(--success);
}

.epx-dialog-hero-icon--info {
    background: var(--accent-soft);
    color: var(--accent-strong);
}

.epx-dialog-hero-icon .mud-icon-root {
    font-size: 28px !important;
    width: 28px !important;
    height: 28px !important;
}

.epx-dialog-center {
    text-align: center;
}

/* All dialog action rows sit 24px from the bottom-right corner of the dialog
   frame. Applies globally to every <DialogActions> across the app. */
.mud-dialog-actions {
    padding-right: 24px !important;
    padding-bottom: 24px !important;
}

/* Audit-trail style key/value rows used by AuditTrailDialog. Each row is a
   label (label-md uppercase) + value pair separated by a thin divider. */
.epx-audit-row {
    display: grid;
    grid-template-columns: 140px 1fr;
    gap: 10px;
    padding: 10px 0;
    border-bottom: 1px solid var(--border-light);
}

.epx-audit-row:last-child {
    border-bottom: none;
}

.epx-audit-row__label {
    font-size: 11px;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    line-height: 20px;
}

.epx-audit-row__value {
    font-size: 14px;
    color: var(--text);
    line-height: 20px;
}

@media (max-width: 599.98px) {
    .epx-audit-row {
        grid-template-columns: 1fr;
        gap: 2px;
        padding: 8px 0;
    }
}


/* (Pearl MudBlazor override block reverted 2026-05-14 — let MudBlazor render native chrome) */

/* ---------- Mobile padding reclamation ---------- */
/* Tighten the lateral padding stack on phones (container gutters + page-level
   px-4 helpers + settings shell) to recover ~64 px of usable width. Desktop
   intentionally untouched. */
@media (max-width: 599.98px) {
    .mud-container--gutters {
        padding-left: 8px;
        padding-right: 8px;
    }

    .mud-container.px-4 {
        padding-left: 0;
        padding-right: 0;
    }

    .epx-settings-shell {
        padding: 8px 0;
    }
}

/* ============================================================
   Pearl v2.1 — Data Table row patterns
   Patterns for the canonical "Datos Financieros" listing layout
   (see docs/Design-Guidelines.md §8.4 + docs/pearl-design-system.html).
   ============================================================ */

/* ---------- Customer cell — avatar (30×30) + name + sub-line ----------
   Apply on a wrapper <div class="epx-cell-user"> inside an MudTd. The avatar
   is a static <div> (pure decoration — no interaction needed) per the §0
   "MudBlazor always" exception. */
.epx-cell-user {
    display: flex;
    align-items: center;
    gap: 10px;
}

.epx-cell-user__avatar {
    width: 30px;
    height: 30px;
    border-radius: var(--shape-full);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 11px;
    color: #fff;
    flex-shrink: 0;
}

.epx-cell-user__info {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.epx-cell-user__name {
    font-weight: 600;
    font-size: var(--mud-typography-body1-size, 14px);
    color: var(--text);
    line-height: 1.3;
}

.epx-cell-user__sub {
    font-size: 11px;
    color: var(--text-tertiary);
    line-height: 1.3;
    font-family: var(--pearl-font-mono);
}

/* ---------- Avatar color variants — warm Pearl palette ----------
   Use one per row in a deterministic way (hash of initials or id). The
   gradient variants give a tactile depth to the strip without dominating
   the row. */
.epx-av-amber { background: var(--accent); }
.epx-av-green { background: var(--success); }
.epx-av-teal { background: linear-gradient(135deg, #2BA87A, var(--accent-2)); }
.epx-av-red { background: var(--danger); }
.epx-av-orange { background: linear-gradient(135deg, #CB8B3E, var(--accent)); }
.epx-av-pink { background: linear-gradient(135deg, #C46B5A, var(--danger)); }
.epx-av-gray { background: var(--text-muted); }

/* ---------- Status cell — dot + plain text (no chip) ----------
   Replaces the legacy "<MudChip Filled>" pattern in the Status column. The
   chip filled rendering is still valid for Risk / severity columns (see §8.4
   rule 6), but Status (Active/Suspended/Review) uses this dot indicator. */
.epx-status-cell {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: var(--mud-typography-body2-size, 14px);
    color: var(--text);
    white-space: nowrap;
}

.epx-status-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    display: inline-block;
    flex-shrink: 0;
}

.epx-status-dot--default { background: var(--text-muted); }
.epx-status-dot--info { background: var(--accent); }
.epx-status-dot--primary { background: var(--accent); }
.epx-status-dot--success { background: var(--success); }
.epx-status-dot--warning { background: var(--warning); }
.epx-status-dot--error { background: var(--danger); }
.epx-status-dot--danger { background: var(--danger); }
.epx-status-dot--dark { background: var(--text); }

/* ---------- Ghost row action — minimal tint, native MudBlazor geometry ----------
   Apply Class="epx-row-action" on a MudIconButton (default Variant, no Color)
   to tint the icon "ghost" (text-tertiary) so it reads as a low-emphasis
   secondary action in list rows. Size, hover ring shape and hit area are left
   to MudBlazor's native chrome — no width/height/border-radius overrides. */
.epx-row-action.mud-icon-button {
    color: var(--text-tertiary);
}

.epx-row-action.mud-icon-button:hover:not(:disabled) {
    color: var(--text);
}

