html, body {
    font-family: 'Inter Tight', 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

/* Neurom typeface app-wide — every MudText carries the mud-typography base class,
   so one rule retargets all headings and body text (Inter Tight 400-700). */
.mud-typography {
    font-family: 'Inter Tight', 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

a, .btn-link {
    color: var(--mud-palette-primary);
}

.btn-primary {
    color: #fff;
    background-color: #1b6ec2;
    border-color: #1861ac;
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

.content {
    padding-top: 1.1rem;
}

h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid #e50000;
}

.validation-message {
    color: #e50000;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}

/* Global fix: MudBlazor tab panel content sits hard against the panel edges.
   Active panels render display:contents, so padding must go on the panels container. */
.mud-tabs-panels {
    padding: 24px;
}

/* Input heights reverted to MudBlazor defaults (2026-09-19, founder request) —
   the "compact inputs" override block that forced dense vertical metrics
   app-wide was removed; fields now use Mud's standard sizing everywhere. */

/* ============================================================
   Scheduling timeline (TimelineView) — resource rows x day
   columns with absolutely positioned, HTML5-draggable bars.
   ============================================================ */
.sched {
    border: 1px solid var(--mud-palette-lines-default, rgba(0, 0, 0, 0.12));
    border-radius: 8px;
    overflow-x: auto;
    background: var(--mud-palette-surface, #fff);
}
.sched-header, .sched-row { display: flex; align-items: stretch; }
.sched-header {
    background: var(--mud-palette-action-default-hover, rgba(0, 0, 0, 0.05));
    font-weight: 500;
}
.sched-label {
    width: 190px; min-width: 190px;
    padding: 6px 10px;
    display: flex; align-items: center; gap: 6px;
    border-right: 1px solid var(--mud-palette-lines-default, rgba(0, 0, 0, 0.12));
    border-bottom: 1px solid var(--mud-palette-lines-default, rgba(0, 0, 0, 0.12));
    overflow: hidden;
}
.sched-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sched-days { flex: 1; display: flex; position: relative; }
.sched-day {
    flex: 1 1 0; min-width: 34px;
    text-align: center; padding: 4px 2px;
    border-left: 1px solid var(--mud-palette-lines-inputs, rgba(0, 0, 0, 0.08));
    border-bottom: 1px solid var(--mud-palette-lines-default, rgba(0, 0, 0, 0.12));
    font-size: 0.75rem;
}
.sched-dow { color: var(--mud-palette-text-secondary, rgba(0, 0, 0, 0.54)); }
.sched-lane { flex: 1; display: flex; position: relative; min-height: 44px; }
.sched-cell {
    flex: 1 1 0; min-width: 34px;
    border-left: 1px solid var(--mud-palette-lines-inputs, rgba(0, 0, 0, 0.08));
    border-bottom: 1px solid var(--mud-palette-lines-default, rgba(0, 0, 0, 0.12));
    cursor: pointer;
}
.sched-weekend { background: var(--mud-palette-action-default-hover, rgba(0, 0, 0, 0.045)); }
.sched-today { background: var(--mud-palette-primary, #1976d2); opacity: 1; }
.sched-day.sched-today, .sched-cell.sched-today { background: rgba(25, 118, 210, 0.10); }
.sched-dragover { outline: 2px dashed var(--mud-palette-primary, #1976d2); outline-offset: -2px; background: rgba(25, 118, 210, 0.12) !important; }
.sched-bar {
    position: absolute; top: 5px; bottom: 5px;
    border-radius: 6px; z-index: 2;
    color: #fff; font-size: 0.72rem;
    padding: 2px 8px;
    display: flex; align-items: center;
    overflow: hidden; white-space: nowrap;
    cursor: grab; user-select: none;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
}
.sched-bar-text { position: relative; z-index: 1; }
.sched-fill {
    position: absolute; left: 0; top: 0; bottom: 0;
    background: rgba(255, 255, 255, 0.38);
    border-radius: 6px 0 0 6px;
}
.sched-empty { flex: 1; display: flex; align-items: center; justify-content: center; color: var(--mud-palette-text-secondary, rgba(0, 0, 0, 0.54)); padding: 12px; font-size: 0.85rem; }

/* Platform settings — true masonry: cards flow top-down per column and the browser
   balances the column heights, so a short card no longer strands a gap under its
   row (flex-wrap aligned every row's tops — ragged bottoms). Drag reorder is
   unaffected: MudBlazor resolves the drop index via elementsFromPoint — the card
   under the pointer, not row math — and CardDropped inserts at that index. */
.settings-flex {
    columns: 2;                /* base (960–1599px): two columns */
    column-gap: 16px;
}
/* Cards are drag-reorderable: each card sits in a .mud-drop-item wrapper, so the
   column rules target the wrapper; the paper inside fills it. */
.settings-flex > .mud-drop-item,
.settings-flex > .mud-dropitem-placeholder {   /* dashed slot shown during a drag */
    break-inside: avoid;       /* a card never splits across a column break */
    -webkit-column-break-inside: avoid;
    page-break-inside: avoid;
    width: 100%;
    margin-bottom: 16px;      /* vertical rhythm — CSS columns have no row gap */
    box-sizing: border-box;
}
.settings-flex > .mud-drop-item > .mud-paper { width: 100%; box-sizing: border-box; }
/* mud-drop-item disables text selection globally — keep inputs selectable so
   values can still be copied while cards are drag-reorderable. */
.settings-flex .mud-drop-item input,
.settings-flex .mud-drop-item textarea { user-select: text; }
@media (min-width: 1600px) {   /* wide screens — three columns */
    .settings-flex { columns: 3; }
}
@media (max-width: 959.95px) {   /* matches MudBlazor's md breakpoint — single column */
    .settings-flex { columns: 1; }
}

/* Founder rule: no up/down spin buttons on numeric fields — anywhere, ever.
   MudBlazor wraps them in .mud-input-numeric-spin (only used by numeric inputs),
   so this one rule covers every existing and future MudNumericField. */
.mud-input-numeric-spin {
    display: none !important;
}

/* Settings vertical tabs — nav-like strip: MudTabs default colouring keeps only
   the selected tab highlighted; labels align left like the sidebar nav links. */
.settings-tabs .mud-tab {
    justify-content: flex-start;
    text-align: left;
}

/* MudBlazor 9.10 vertical-tabs quirks:
   1. The active panel renders display:contents inside a flex-ROW panels
      container, so panel content with several root elements (headers, forms,
      toolbars, grids) lays out side-by-side and squashes into a narrow row.
      Stack panel content vertically, full width instead.
   2. MudTabs' PanelClass never renders in 9.10 (panels had no padding), so the
      panel padding is applied here. */
.settings-tabs .mud-tabs-panels.mud-tabs-vertical {
    flex-direction: column;
    padding: 24px;
}

/* Table action cells — the "d-flex justify-end" CellClass flips the td from
   display:table-cell to display:flex (!important in MudBlazor), detaching it
   from the row height: the action cell hugs its icons and renders shorter
   than every other cell in the row. Keep it a real table cell so it stretches
   with the row, right-align and vertically center the buttons. */
.mud-table-cell.d-flex {
    display: table-cell !important;   /* beats .d-flex's display:flex !important */
    text-align: end;                  /* replaces the now-dead justify-end */
    vertical-align: middle;           /* center within the row */
}

.mud-table-cell.d-flex .mud-icon-button {
    vertical-align: middle;           /* icons center, not baseline-aligned */
}

/* Settings panels — root-level buttons (Xero connect/disconnect, invoice save)
   were stretching to the full panel width by the flex column's default stretch.
   Size them to their text like every other button. */
.settings-tabs .mud-tabs-panels.mud-tabs-vertical > .mud-tab-panel-active > .mud-button-root {
    align-self: flex-start;
}

/* Dark-mode fills — the palette keeps BRIGHT accent colours (nav links and icons
   use them as text colour), so filled chips/buttons would render white-on-light
   text after the contrast-text revert. Scoped to the html.omni-dark marker
   (toggled by setTheme) these darken ONLY the backgrounds; text stays white.
   Light mode is completely untouched. Outlined AND Text chips keep their
   transparent backgrounds — a Text chip's font colour IS the bright palette
   colour, so painting a #0b3bf0 bg on a #0b3bf0-text chip made it invisible
   (hub widget stat chips). */
html.omni-dark .mud-chip-color-primary:not(.mud-chip-outlined):not(.mud-chip-text)   { background-color: var(--mud-palette-primary); }
html.omni-dark .mud-chip-color-secondary:not(.mud-chip-outlined):not(.mud-chip-text) { background-color: #16455a; }
html.omni-dark .mud-chip-color-success:not(.mud-chip-outlined):not(.mud-chip-text)   { background-color: #15803d; }
html.omni-dark .mud-chip-color-warning:not(.mud-chip-outlined):not(.mud-chip-text)   { background-color: #b45309; }
html.omni-dark .mud-chip-color-info:not(.mud-chip-outlined):not(.mud-chip-text)      { background-color: #0369a1; }

/* Same treatment for filled buttons — their colour classes are fill-variant-only,
   so outlined/text buttons are never touched. */
html.omni-dark .mud-button-filled-primary   { background-color: var(--mud-palette-primary); }
html.omni-dark .mud-button-filled-secondary { background-color: #16455a; }
html.omni-dark .mud-button-filled-success   { background-color: #15803d; }
html.omni-dark .mud-button-filled-warning   { background-color: #b45309; }
html.omni-dark .mud-button-filled-info      { background-color: #0369a1; }

/* Primary-filled surfaces (chat bubbles, portal balance headers). Light mode:
   palette primary + white. Dark mode: deeper blue + white. */
.oc-primary-fill {
    background-color: var(--mud-palette-primary);
    color: var(--mud-palette-primary-text);
}
html.omni-dark .oc-primary-fill {
    background-color: var(--mud-palette-primary);
    color: #ffffff;
}

/* ============================================================
   Neurom brand utilities (2026-09-29 rebrand) — glass panels,
   cyan burner glow lines and hover-glow, used by marketing pages
   and app accents alike. Tokens extracted from the template.
   ============================================================ */

/* Glassy translucent panel — Neurom bg-light (#ffffff30-family) tuned
   for legibility on the #030614 app background. */
.oc-glass {
    background: rgba(255, 255, 255, 0.055);
    border: 1px solid rgba(255, 255, 255, 0.12);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border-radius: 16px;
}

/* Signature burner line — 1px vertical bar with a cyan glow
   (gradient transparent -> #27bbff, the Neurom hero divider). */
.oc-burner {
    width: 1px;
    height: 150px;
    background: linear-gradient(#18709900, #27bbff);
    border: none;
    flex: 0 0 auto;
}
.oc-burner-h {
    height: 1px;
    width: 100%;
    background: linear-gradient(90deg, #18709900, #27bbff, #18709900);
    border: none;
}

/* Glow-on-hover card — the template's card lift: cyan-tinted shadow. */
.oc-glow-hover {
    transition: box-shadow 0.4s ease, transform 0.4s ease, border-color 0.4s ease;
}
.oc-glow-hover:hover {
    box-shadow: 0 0 34px rgba(39, 187, 255, 0.22), 0 8px 28px rgba(0, 0, 0, 0.45);
    transform: translateY(-3px);
    border-color: rgba(39, 187, 255, 0.45);
}

/* Electric-blue text glow for hero titles (use sparingly). */
.oc-hero-glow {
    text-shadow: 0 0 42px rgba(11, 59, 240, 0.55);
}

/* MudStack rows (utility flex rows with gap classes) reflow on narrow screens
   instead of squashing titles and buttons together. flex-wrap only engages when
   content overflows, so desktop layouts are unchanged. */
.d-flex.flex-row[class*="gap-"] {
    flex-wrap: wrap;
}

/* Table action cells never wrap: the rule above turns stacked icon rows in
   narrow grid columns vertical (one icon per line, rows balloon). Icon rows
   in tables are always one horizontal line — columns carry explicit Widths. */
.mud-table-cell .d-flex.flex-row[class*="gap-"] {
    flex-wrap: nowrap;
}

/* ============================================================
   Zenko appbar — public-site top-section look (navy gradient +
   blue glow + cyan hairline) with the neuron brand mark.
   Fixed dark surface in both themes, mirroring the public header.
   ============================================================ */
.zen-appbar {
    background:
        radial-gradient(480px 110px at 16% 0%, rgba(11, 59, 240, 0.42), transparent 72%),
        radial-gradient(340px 90px at 82% 100%, rgba(122, 251, 252, 0.10), transparent 72%),
        linear-gradient(180deg, #0a0e24 0%, #030614 100%) !important;
    color: #fff !important;
    position: relative;
}
.zen-appbar::after {
    content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
    background: linear-gradient(90deg, transparent 4%, rgba(11, 59, 240, 0.9) 30%, #7afbfc 50%, rgba(11, 59, 240, 0.9) 70%, transparent 96%);
    pointer-events: none;
}
.zen-appbar .mud-icon-root { color: #fff; }
.zen-brand { display: inline-flex; align-items: center; gap: 10px; text-decoration: none; cursor: pointer; }
.zen-brand:hover .zen-brand-name { color: #7afbfc; }
.zen-brand-icon { color: #0b3bf0; filter: drop-shadow(0 0 10px rgba(11, 59, 240, 0.8)); flex-shrink: 0; }
.zen-brand-name { color: #fff; font-weight: 700; font-size: 1.08rem; letter-spacing: 0.09em; text-transform: uppercase; white-space: nowrap; }
/* Tenant logo in the appbar (tenant branding) — replaces the tenant-name text. */
.zen-tenant-logo { height: 34px; max-width: 170px; width: auto; border-radius: 6px; object-fit: contain; display: block; }

/* ============================================================
   Billing module cards — the public Pricing banner head on the
   subscription card. The illustration banner is a dark panel on
   purpose (same asset as the shop); the body follows the app theme.
   ============================================================ */
.bill-card { display: flex; flex-direction: column; height: 100%; border-radius: 16px; overflow: hidden; transition: border-color 0.3s, box-shadow 0.3s; }
.bill-card-active { border-color: var(--mud-palette-primary) !important; box-shadow: 0 0 0 1px var(--mud-palette-primary), 0 10px 30px color-mix(in srgb, var(--mud-palette-primary) 18%, transparent); }
.bill-banner { position: relative; overflow: hidden; background: linear-gradient(135deg, var(--mud-palette-primary) 0%, var(--mud-palette-primary-darken) 100%); }
.bill-banner img { width: 100%; display: block; }
.bill-chip {
    position: absolute; top: 12px; right: 12px;
    font-size: 0.72rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
    padding: 3px 10px; border-radius: 999px;
    background: rgba(3, 6, 20, 0.72); color: #9b9da7; border: 1px solid rgba(128, 128, 128, 0.4);
    backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
.bill-chip-active { background: rgba(24, 154, 97, 0.92); border-color: transparent; color: #fff; }
.bill-chip-other { background: rgba(245, 158, 11, 0.92); border-color: transparent; color: #30230a; }
.bill-body { display: flex; flex-direction: column; flex-grow: 1; padding: 16px 20px 12px; }
.bill-foot { padding: 10px 16px 14px; border-top: 1px solid var(--mud-palette-lines-default); }

/* AI Assistant flyout — a MudMenu popover hosting the whole mini window.
   MudMenu wraps ChildContent in a list; strip its list styling so the
   flyout looks like a dialog panel, not a menu. */
.ai-flyout-popover { overflow: hidden; border-radius: 14px; }
.ai-flyout-popover .mud-list { background: transparent; box-shadow: none; }

/* ============================================================
   Module hub dashboards — KPI strip, chart grid, month labels.
   Theme-safe: fixed accents over Mud theme variables.
   ============================================================ */
.zen-kpi-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
    gap: 12px;
}
.zen-hub-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(330px, 1fr));
    gap: 16px;
    /* stretch: every chart card in a row shares the tallest height, so
       side-by-side cards read as one even band (David's "even the sizes"). */
    align-items: stretch;
}
.zen-kpi {
    padding: 16px 18px !important;
    display: flex;
    flex-direction: column;
    gap: 4px;
    position: relative;
    overflow: hidden;
}
.zen-kpi::before {
    content: '';
    position: absolute; inset: 0;
    background: radial-gradient(200px 100px at 88% -10%, rgba(11, 59, 240, 0.10), transparent 70%);
    pointer-events: none;
}
.zen-kpi > * { position: relative; }
.zen-kpi-label {
    font-size: .74rem; text-transform: uppercase; letter-spacing: .09em;
    color: var(--mud-palette-text-secondary); font-weight: 600;
}
.zen-kpi-value { font-size: 1.65rem; font-weight: 700; letter-spacing: -0.5px; line-height: 1.1; }
.zen-kpi-sub { font-size: .8rem; color: var(--mud-palette-text-secondary); }
.zen-month-labels {
    display: flex; justify-content: space-between;
    font-size: .7rem; color: var(--mud-palette-text-secondary);
    text-transform: uppercase; letter-spacing: .05em;
}
