html, body {
    font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

h1:focus {
    outline: none;
}

a, .btn-link {
    color: #0071c1;
}

.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;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid red;
}

.validation-message {
    color: red;
}

/* Document-builder BT-XX code chip — renders the EN 16931 / HR-CIUS
   business-term identifier in a slightly muted monospace face so it
   reads as a structured cross-reference, not body text. Used by
   Components/BtChip.razor for standalone section-header chips. */
.bt-code-chip {
    font-family: 'JetBrains Mono', 'Consolas', 'Menlo', monospace;
    font-size: 0.7rem;
    letter-spacing: 0.02em;
}

/* BT-pin overlay — used by Components/BtField.razor. The chip floats
   in the top-right corner of the wrapped input (rather than stacking
   above), matching the eRacun.bixi wizard's input pattern. Click the
   pin to open the BT help dialog. */
.mud-bt-wrap {
    position: relative;
}
.mud-bt-pin {
    position: absolute;
    top: -7px;
    right: 12px;
    z-index: 3;
    display: inline-flex;
    align-items: center;
    font-family: 'JetBrains Mono', 'Consolas', 'Menlo', monospace;
    font-size: 0.6rem;
    font-weight: 700;
    letter-spacing: 0.3px;
    line-height: 1.5;
    white-space: nowrap;
    padding: 1px 7px;
    border-radius: 10px;
    border: 1px solid #bbdefb;
    background: #fff;
    color: #1565c0;
    cursor: help;
    transition: color 0.15s, background-color 0.15s, border-color 0.15s, transform 0.1s;
}
.mud-bt-pin:hover {
    background: #e3f2fd;
    border-color: #64b5f6;
    color: #0d47a1;
    transform: translateY(-1px);
}
.mud-bt-pin:focus-visible {
    outline: 2px solid #0EA5E9;
    outline-offset: 1px;
}
.mud-bt-wrap:focus-within .mud-bt-pin {
    color: #0d47a1;
    background: #bbdefb;
    border-color: #90caf9;
}

/* Always-shrunk floating label on every input inside .mud-bt-wrap.
   MudBlazor's outlined inputs centre the label inside the field as a fake
   placeholder when empty + unfocused — which makes TextField inputs (empty,
   centered label) look visually different from MudSelect / MudDatePicker
   (default value present, label shrunk top-left). The pin in the top-right
   corner is the same in both cases, but the label-position difference makes
   the pin "feel" misaligned across input types. Forcing the label always
   into the top-left shrunk position normalises the visual frame so every
   field's pin sits the same way relative to a consistent top border. */
.mud-bt-wrap .mud-input-control .mud-input-label,
.mud-bt-wrap .mud-input-control .mud-input-label-outlined {
    transform: translate(12px, -7px) scale(0.75) !important;
    transform-origin: top left !important;
    background: var(--mud-palette-surface, #FFFFFF);
    padding: 0 4px !important;
    pointer-events: none;
    /* Hint-grey so an empty input's label reads as a placeholder, not a
       prefilled value. The text-secondary palette colour matches what
       MudBlazor uses for its non-focused floating label by default. */
    color: var(--mud-palette-text-secondary, #9e9e9e) !important;
}

/* The outlined-border <fieldset>'s <legend> punches a gap in the top
   border where the label sits. Force it open so the border doesn't draw
   through the always-shrunk label text. The legend's inner span keeps
   the label's width-reservation but stays invisible (the label element
   above does the actual rendering). */
.mud-bt-wrap .mud-input-outlined-border legend {
    max-width: 100% !important;
}
.mud-bt-wrap .mud-input-outlined-border legend > span {
    padding: 0 4px !important;
    display: inline-block !important;
    visibility: hidden;
}

/* The "placeholder-style label colour" rule that used to live here has moved
   to css/mud-overrides.css, which is linked AFTER MudBlazor and therefore
   needs no !important.

   It was not merely untidy. The guard was :not(.mud-input-label-shrink), but
   MudBlazor 9 marks the INPUT with .mud-shrink and never puts that class on
   the label — so the guard matched nothing, and !important then beat
   MudBlazor's own shrink rule. Every label in the app was hint-grey,
   including the ones sitting over filled fields: measured on /company, "Ulica"
   and "Grad" both held values and both rendered at rgba(0,0,0,.38), leaving a
   field's own heading as the faintest text in the form.

   BtField keeps its own always-shrunk label colour from the .mud-bt-wrap rule
   higher up in this file, which is more specific and unaffected. */

#blazor-error-ui {
    color-scheme: light only;
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }

.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."
    }

.loading-progress {
    position: absolute;
    display: block;
    width: 8rem;
    height: 8rem;
    inset: 20vh 0 auto 0;
    margin: 0 auto 0 auto;
}

    .loading-progress circle {
        fill: none;
        stroke: #e0e0e0;
        stroke-width: 0.6rem;
        transform-origin: 50% 50%;
        transform: rotate(-90deg);
    }

        .loading-progress circle:last-child {
            stroke: #1b6ec2;
            stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
            transition: stroke-dasharray 0.05s ease-in-out;
        }

.loading-progress-text {
    position: absolute;
    text-align: center;
    font-weight: bold;
    inset: calc(20vh + 3.25rem) 0 auto 0.2rem;
}

    .loading-progress-text:after {
        content: var(--blazor-load-percentage-text, "Loading");
    }

code {
    color: #c02d76;
}

.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;
}
/* ─────────────────────────────────────────────────────────────────
   KPD/CPA classification picker (BT-158)
   Drill-down dropdown with search + breadcrumb navigation. Used by
   Components/CpaPicker.razor; data + index live in /js/kpd.js
   fetching from /data/kpd.json.
   ───────────────────────────────────────────────────────────────── */
.cpa-backdrop {
    position: fixed;
    top: 0; left: 0; right: 0; bottom: 0;
    z-index: 999;
}
.cpa-dropdown {
    position: absolute;
    top: 100%;
    left: 0; right: 0;
    z-index: 1000;
    background: #fff;
    border: 1px solid #bdbdbd;
    border-radius: 4px;
    box-shadow: 0 4px 12px rgba(0,0,0,0.15);
    max-height: 350px;
    display: flex;
    flex-direction: column;
    min-width: 320px;
}
.cpa-search-box {
    padding: 8px;
    border-bottom: 1px solid #e0e0e0;
    display: flex;
    gap: 6px;
    align-items: center;
}
.cpa-search-box input {
    flex: 1;
    border: 1px solid #bdbdbd;
    border-radius: 4px;
    padding: 6px 10px;
    font-size: 0.85rem;
    outline: none;
}
.cpa-search-box input:focus {
    border-color: #1976d2;
}
.cpa-clear-link {
    font-size: 0.75rem;
    white-space: nowrap;
    color: #dc3545;
}
.cpa-results {
    overflow-y: auto;
    flex: 1;
}
.cpa-item {
    padding: 6px 10px;
    cursor: pointer;
    font-size: 0.82rem;
    border-bottom: 1px solid #f5f5f5;
    display: flex;
    align-items: baseline;
    gap: 6px;
}
.cpa-item:hover {
    background: #e3f2fd;
}
.cpa-item.active {
    background: #bbdefb;
    font-weight: 600;
}
.cpa-item.cpa-section {
    font-weight: 500;
}
.cpa-code-tag {
    background: #e8eaf6;
    color: #283593;
    padding: 1px 5px;
    border-radius: 3px;
    font-family: 'JetBrains Mono', 'Consolas', monospace;
    font-size: 0.78rem;
    white-space: nowrap;
    flex-shrink: 0;
}
.cpa-empty {
    padding: 16px;
    text-align: center;
    color: #999;
    font-size: 0.85rem;
}
.cpa-breadcrumb {
    padding: 5px 10px;
    border-bottom: 1px solid #e0e0e0;
    font-size: 0.78rem;
    background: #fafafa;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 2px;
}
.cpa-breadcrumb a {
    color: #1976d2;
    text-decoration: none;
    cursor: pointer;
}
.cpa-breadcrumb a:hover {
    text-decoration: underline;
}
.cpa-sep {
    color: #999;
    margin: 0 2px;
}
.cpa-chevron {
    margin-left: auto;
    font-size: 0.7rem;
    color: #999;
}

/* Language switcher trigger — circular icon-button hover so the bare flag
   image still reads as an interactive AppBar control. A real MudIconButton
   here intercepts the click before MudMenu can open. */
.lang-flag-trigger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    cursor: pointer;
    transition: background-color 120ms ease;
    user-select: none;
}
.lang-flag-trigger:hover,
.lang-flag-trigger:focus-visible {
    background-color: rgba(0, 0, 0, 0.05);
    outline: none;
}

/* Validator error panels: MudBlazor's MudAlert + MudExpansionPanel chain
   inherits user-select:none on some children (MudListItem, panel title),
   blocking text copy. Validator messages contain rule IDs ("BR-CO-25" /
   "HR-BR-13") users want to paste into a search or our support chat —
   force selection on anything inside an error-severity alert. */
.mud-alert-filled-error,
.mud-alert-outlined-error,
.mud-alert-text-error {
    user-select: text;
    -webkit-user-select: text;
}
.mud-alert-filled-error *,
.mud-alert-outlined-error *,
.mud-alert-text-error * {
    user-select: text;
    -webkit-user-select: text;
}

/* Clickable BT-XX / HR-BT-XX references inside validator error messages.
   Stand out as a small underlined chip the user can click to jump to
   the matching wizard input. Hover bumps the colour so the affordance
   is obvious. */
.bt-link {
    color: var(--mud-palette-primary);
    cursor: pointer;
    text-decoration: underline dotted;
    text-underline-offset: 2px;
    font-weight: 600;
    background: rgba(25, 118, 210, 0.06);
    padding: 0 4px;
    border-radius: 3px;
}
.bt-link:hover {
    background: rgba(25, 118, 210, 0.15);
    text-decoration: underline solid;
}

/* Quick flash highlight when the validator panel navigates the user to
   a BtField. Removes itself when the animation finishes — no JS cleanup
   needed. The scroll-to-bt.js helper re-adds the class on a second
   click via a reflow trick. */
@keyframes bt-target-flash {
    0%   { box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.0); background-color: rgba(245, 158, 11, 0.0); }
    25%  { box-shadow: 0 0 0 4px rgba(245, 158, 11, 0.35); background-color: rgba(245, 158, 11, 0.15); }
    100% { box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.0); background-color: rgba(245, 158, 11, 0.0); }
}
.bt-target-flash {
    animation: bt-target-flash 1.6s ease-out;
    border-radius: 4px;
}

/* OIB registry-lookup spinner — rotates the end-adornment icon of the OIB
   input while the external company lookup is in flight. Applied via the
   `oib-spin` class the registration forms add only while loading. */
@keyframes oib-spin-rotate {
    to { transform: rotate(360deg); }
}
.oib-spin .mud-input-adornment-end svg {
    animation: oib-spin-rotate 0.9s linear infinite;
}

/* MudDivider — MudBlazor default is ~12% black, barely visible on a
   white surface. Bump to ~35% so section separators read across the app.
   Applies everywhere; remove the scoped override in Company.razor. */
.mud-divider {
    border-color: rgba(0, 0, 0, 0.35) !important;
}

/* Inline API-key cell on the /company list — monospace + selectable
   so the user can copy a part of it manually if needed. Width-bounded
   so the row doesn't expand uncontrollably on a long key. */
.api-key-cell {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 13px;
    letter-spacing: 0.02em;
    user-select: all;
    word-break: break-all;
}


/* ─────────────────────────────────────────────────────────────────
   Unified design tokens — empty-state, placeholder card, settings rail.
   Mirrored verbatim in Admin.Client/wwwroot/css/app.css so the two WASM
   bundles render the same surface. Every visual rule that should look
   the same across customer + admin shells lives in THIS block.
   ───────────────────────────────────────────────────────────────── */

/* Empty-state surface for tables that have no rows YET but the user
   can act to fill them ("Add account", "Invite member"). Soft dashed
   border + tinted background reads as a slot waiting for content, not
   as an alert. Used by Web.Client/Company.razor + Admin.Client tables. */
.empty-state {
    background: var(--mud-palette-action-default-hover);
    border: 1px dashed var(--mud-palette-divider);
    border-radius: 8px;
    padding: 24px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    text-align: center;
}
.empty-state__icon { opacity: .4; }

/* Coming-soon placeholder card — section-level "this is not built yet"
   surface. Backed by the shared PlaceholderHint component. Quieter than
   an Info-alert so it doesn't fight for attention; the dashed border +
   construction icon read as "future content" at a glance. */
.placeholder-card {
    background: var(--mud-palette-action-default-hover);
    border: 1px dashed var(--mud-palette-divider);
    border-radius: 12px;
    min-height: 240px;
    padding: 40px 24px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
}
.placeholder-card__icon { margin-bottom: 8px; }
.placeholder-card__title { margin-bottom: 4px; }
.placeholder-card__body { max-width: 520px; line-height: 1.55; }
.placeholder-card__action { margin-top: 16px; }
.placeholder-card--warning {
    border-color: var(--mud-palette-warning);
    background: rgba(255, 152, 0, 0.04);
}
.placeholder-card--error {
    border-color: var(--mud-palette-error);
    background: rgba(244, 67, 54, 0.04);
}

/* Dashboard readiness notice (AMS/MPS). A loud brand-red banner — these are
   blocking states the user must act on (account not activated / not
   registered to receive eRačune), so it leans on the brand red (#e23d3a)
   rather than the muted warning palette. */
.registry-notice {
    border: 1px solid var(--mud-palette-divider);
    border-radius: 12px;
}
.registry-notice--danger {
    border: none;
    background: linear-gradient(135deg, #e64541 0%, #c92f2b 100%);
    color: #fff;
    box-shadow: 0 8px 24px rgba(226, 61, 58, 0.28);
}
.registry-notice__title { font-weight: 600; }
/* Solid-red danger notice — everything inside reads white. */
.registry-notice--danger .registry-notice__title,
.registry-notice--danger .mud-typography { color: #fff !important; }
.registry-notice--danger .mud-text-secondary { color: rgba(255, 255, 255, 0.85) !important; }
.registry-notice--danger .registry-notice__icon,
.registry-notice--danger .registry-notice__icon .mud-icon-root { color: #fff !important; }
.registry-notice--danger .registry-doc-link,
.registry-notice--danger .registry-doc-link:hover { color: #fff; }
/* Primary CTA flips to a white chip with red text so it pops on the red field. */
.registry-notice--danger .registry-danger-btn {
    background-color: #fff !important;
    color: #c92f2b !important;
}
.registry-notice--danger .registry-danger-btn:hover { background-color: #f0f0f0 !important; }
/* "Check again" text button → white. */
.registry-notice--danger .mud-button-text { color: #fff !important; }
.registry-notice__row {
    display: flex;
    gap: 1rem;
    align-items: flex-start;
}
.registry-notice__icon { flex: 0 0 auto; margin-top: 2px; }
.registry-notice__body { flex: 1 1 auto; min-width: 0; }
.registry-notice__actions {
    display: flex;
    align-items: center;
    gap: .75rem;
    flex-wrap: wrap;
}

/* The two help-document links sit side-by-side across the full width,
   each taking an equal share; they wrap to stacked rows when the notice
   is too narrow. */
.registry-notice__links {
    display: flex;
    width: 100%;
    gap: 1rem;
    flex-wrap: wrap;
}
.registry-doc-link {
    flex: 1 1 280px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: #e23d3a;
    text-decoration: underline;
    line-height: 1.4;
}
.registry-doc-link:hover { color: #c33330; }

/* The two guide links rendered as white CTA buttons (same white-on-red look as
   the Kreiraj button, via .registry-danger-btn). Left-aligned with a wrapping
   label so the long guide titles read on multiple lines; they share the row and
   wrap under each other on narrow screens. */
.registry-notice__links .registry-doc-btn {
    flex: 1 1 280px;
    justify-content: flex-start;
    text-align: left;
    text-transform: none;
    white-space: normal;
}
.registry-notice__links .registry-doc-btn .mud-button-label { white-space: normal; }

/* Brand-red CTA — MudButton's Error palette isn't the brand red, so we
   paint it explicitly to match the rest of the brand surfaces. */
.registry-danger-btn {
    background-color: #e23d3a !important;
    color: #fff !important;
}
.registry-danger-btn:hover { background-color: #c33330 !important; }

/* Same brand red, for the one irreversible action on a page full of harmless
   ones. Separate class from .registry-danger-btn on purpose: that one carries a
   contextual override (white-on-red inside .registry-notice--danger) which has
   nothing to do with a standalone CTA. Not Color.Error — that palette entry
   means "something went wrong", and this button is the happy path. */
.brand-cta-btn {
    background-color: #e23d3a !important;
    color: #fff !important;
}
.brand-cta-btn:hover { background-color: #c33330 !important; }
.brand-cta-btn:disabled,
.brand-cta-btn.mud-button-disabled { background-color: #e9a3a2 !important; }

/* The card holding it. The finish step offers four things; three are drafts and
   downloads you can repeat, one actually sends the invoice to the recipient and
   cannot be taken back. Tinted ground plus a red rule so the difference is
   visible before reading any label. */
.finish-send-card {
    background-color: rgba(226, 61, 58, 0.05);
    border-color: rgba(226, 61, 58, 0.45) !important;
}

/* On phones the icon column eats width the copy needs — stack it. */
@media (max-width: 599px) {
    .registry-notice__row { flex-direction: column; gap: .5rem; }
}

/* Settings-rail variant for left-positioned MudTabs (Company / settings
   surfaces). Replaces the chunky pill look with a quiet sidebar — flat,
   left-aligned, primary-coloured indicator strip on the active tab.
   Apply with: <MudTabs Class="settings-rail" Position="Position.Left"> */
.settings-rail .mud-tabs-tabbar-wrapper-vertical {
    min-width: 220px;
    max-width: 240px;
    background: transparent;
    border-right: 1px solid var(--mud-palette-divider);
}
.settings-rail .mud-tab {
    justify-content: flex-start;
    text-transform: none;
    font-weight: 500;
    border-radius: 0 !important;
    padding-left: 16px;
    padding-right: 12px;
    min-height: 44px;
    color: var(--mud-palette-text-secondary);
}
.settings-rail .mud-tab:hover {
    background: var(--mud-palette-action-default-hover);
}
.settings-rail .mud-tab.mud-tab-active {
    background: var(--mud-palette-action-default-hover);
    color: var(--mud-palette-primary);
    border-left: 3px solid var(--mud-palette-primary);
    padding-left: 13px;
    font-weight: 600;
}
.settings-rail .mud-tab .mud-icon-root {
    font-size: 18px !important;
    width: 18px !important;
    height: 18px !important;
    margin-right: 12px;
}
.settings-rail .mud-tabs-tabbar-inner .mud-tab-slider {
    display: none;
}
.settings-rail .mud-tabs-panels {
    padding: 24px 28px 32px;
}
.settings-rail .mud-tabs-panels .pa-4 {
    padding: 0 !important;
}
.settings-rail code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.85em;
    padding: 1px 5px;
    border-radius: 4px;
    background: rgba(0, 0, 0, 0.05);
}

/* Section header L1 inside a settings panel — slightly tighter than a
   page-level h6 and pairs with subtle uppercase L2 subsections below. */
.section-l1 {
    font-weight: 600;
    margin-bottom: 8px;
}
.section-l2 {
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
    margin-bottom: 8px;
    margin-top: 8px;
}

/* Save-row pattern — left-aligned Save + Discard + "Unsaved changes"
   hint. Same shape across every multi-field form so users build muscle
   memory; toggles still auto-save without showing this row. */
.save-row {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 12px;
    flex-wrap: wrap;
}
.save-row__hint {
    color: var(--mud-palette-warning);
    font-size: 0.78rem;
    font-weight: 500;
}

/* ──────── End unified design tokens ──────── */


/* Impersonation banner — persistent top bar shown while a superadmin
   is acting as another user. Strong red so it never blends with the
   chrome; the deliberate visual contrast is the point.

   position:fixed + z-index above the MudBlazor appbar
   (--mud-zindex-appbar = 1100) so the banner sits ON TOP of the appbar
   instead of behind it. The :has() rules further down push MudAppBar /
   MudDrawer / main content down by 40px while the banner is in the DOM
   so nothing is clipped. */
.impersonation-banner {
    background: #c62828;
    color: #ffffff;
    padding: 8px 16px;
    font-size: 13px;
    line-height: 1.4;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 40px;
    box-sizing: border-box;
    z-index: 1400;
    border-bottom: 1px solid rgba(0, 0, 0, 0.2);
}

/* When the banner is in the DOM, push every MudBlazor chrome element
   that pins to top:0 down by the banner's height. CSS :has() is
   supported on every modern browser we target (Chrome 105+,
   Firefox 121+, Safari 15.4+). */
body:has(.impersonation-banner) .mud-appbar {
    top: 40px !important;
}
/* margin-top (additive) — NOT top — so the drawer keeps MudBlazor's
   AppBar-height offset and the banner height is added on top; `top` would
   replace the offset and pull the first nav item under the AppBar. */
body:has(.impersonation-banner) .mud-drawer {
    margin-top: 40px !important;
}
body:has(.impersonation-banner) .mud-main-content {
    padding-top: 40px;
}

.impersonation-banner__content {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    max-width: 100%;
}

.impersonation-banner__icon {
    display: inline-flex;
    align-items: center;
}

.impersonation-banner__text {
    flex: 1 1 auto;
    min-width: 0;
}

.impersonation-banner__sep {
    margin: 0 6px;
    opacity: 0.7;
}

.impersonation-banner__expiry {
    opacity: 0.85;
    font-variant-numeric: tabular-nums;
}

/* O9 session-mode pill ("Samo pregled" / "Puni pristup") — white outline on
   the red banner so the mode reads at a glance without adding a second
   colour to the alert surface. */
.impersonation-banner__mode {
    display: inline-block;
    margin-left: 8px;
    padding: 1px 8px;
    border: 1px solid rgba(255, 255, 255, 0.75);
    border-radius: 10px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    white-space: nowrap;
    vertical-align: middle;
}

.impersonation-banner__actor {
    opacity: 0.85;
    font-size: 12px;
    white-space: nowrap;
}

.impersonation-banner__exit {
    border-color: rgba(255, 255, 255, 0.7) !important;
    color: #ffffff !important;
}

.impersonation-banner__exit:hover {
    background: rgba(255, 255, 255, 0.12) !important;
    border-color: #ffffff !important;
}

/* Mobile: stack the metadata so the Exit button stays reachable. */
@media (max-width: 600px) {
    .impersonation-banner__actor {
        flex-basis: 100%;
        font-size: 11px;
    }
}

/* ── Webhooks page ─────────────────────────────────────────────────────── */
.webhook-url {
    font-size: 13px;
    word-break: break-all;
    background: var(--mud-palette-background-grey);
    padding: 2px 8px;
    border-radius: 6px;
}

.webhook-secret {
    font-size: 13px;
    word-break: break-all;
    flex: 1 1 auto;
}

.webhook-stat-label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--mud-palette-text-secondary);
}

.webhook-stat-value {
    font-size: 14px;
    font-weight: 500;
}

/* Event checklist in the create/edit dialog */
.webhook-events {
    display: flex;
    flex-direction: column;
    gap: 4px;
    border: 1px solid var(--mud-palette-lines-inputs);
    border-radius: 8px;
    padding: 8px 10px;
}

.webhook-event-row {
    display: flex;
    align-items: flex-start;
    gap: 6px;
}

.webhook-event-text {
    display: flex;
    flex-direction: column;
    padding-top: 6px;
}

.webhook-event-name {
    font-size: 13px;
    font-weight: 600;
}


/* ── Locked party block (copy re-issue) ───────────────────────────────
   PartyFormSection wraps itself in a <fieldset> so one `disabled` locks
   every descendant control natively. A fieldset carries a default border,
   margin, padding and min-width:min-content — the last one is the nasty
   part: it stops the grid inside from ever shrinking below its content and
   breaks the mobile layout. Reset all four. */
.party-fieldset {
    border: 0;
    margin: 0;
    padding: 0;
    min-width: 0;
}

/* ── The "frozen field" look, for the copy re-issue flow ──────────────
   A locked field gets there two different ways and NEITHER styles itself:

     • <fieldset disabled> (both party blocks, the allowances/charges block) —
       HTML makes every descendant inert, but MudBlazor never sees it and so
       never applies its own per-component disabled look;
     • MudBlazor ReadOnly (number, dates, currency, line figures, VAT rate,
       due date, delivery date) — stops typing and changes nothing on screen.

   Either way the input sits there looking exactly like the editable one beside
   it and only reveals itself when a click does nothing, which reads as a broken
   page. These rules cover both routes.

   Values keep FULL CONTRAST on purpose: the entire point of a frozen step is
   that it can be read back against the original invoice. It is the chrome —
   fill, dashed edge, cursor, dead adornments — that says "not yours to change". */

.doc-copy-locked input[readonly],
.doc-copy-locked textarea[readonly],
.doc-copy-locked fieldset[disabled] .mud-input-slot,
.doc-copy-locked fieldset[disabled] .mud-input-root {
    cursor: not-allowed;
}

/* :has() puts the treatment on the WRAPPER, which is what carries the outline
   and the fill — the readonly attribute lives on the inner <input>. */
.doc-copy-locked .mud-input-control:has(> .mud-input input[readonly]),
.doc-copy-locked .mud-input-control:has(> .mud-input textarea[readonly]),
.doc-copy-locked fieldset[disabled] .mud-input-control {
    --locked-field: 1;
}

.doc-copy-locked .mud-input-control:has(> .mud-input input[readonly]) > .mud-input,
.doc-copy-locked .mud-input-control:has(> .mud-input textarea[readonly]) > .mud-input,
.doc-copy-locked fieldset[disabled] .mud-input-control > .mud-input {
    background-color: rgba(0, 0, 0, 0.03);
    border-radius: var(--mud-default-borderradius);
}

.doc-copy-locked .mud-input-control:has(> .mud-input input[readonly]) .mud-input-outlined-border,
.doc-copy-locked .mud-input-control:has(> .mud-input textarea[readonly]) .mud-input-outlined-border,
.doc-copy-locked fieldset[disabled] .mud-input-outlined-border {
    border-style: dashed;
}

/* Clear "x", dropdown chevrons and the date / time picker buttons are inert on a
   locked field; at full strength they invite a click that does nothing. */
.doc-copy-locked .mud-input-control:has(> .mud-input input[readonly]) .mud-input-adornment,
.doc-copy-locked fieldset[disabled] .mud-input-adornment,
.doc-copy-locked fieldset[disabled] .mud-select-input .mud-icon-button {
    opacity: 0.4;
    pointer-events: none;
}


/* ── Attachment drop zone ─────────────────────────────────────────────
   Replaces a full-width filled button that shouted louder than anything else
   on an optional step, and only advertised half of what the browser can do.
   Click and drop both land here; MudFileUpload's DragAndDrop puts the native
   input over this element to capture the drop (Blazor's own DragEventArgs
   cannot read dropped files, only their names). */
.upload-dropzone {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
    padding: 1.35rem 1rem;
    border: 2px dashed var(--mud-palette-lines-default, rgba(0, 0, 0, 0.18));
    border-radius: var(--mud-default-borderradius);
    background-color: var(--mud-palette-background-gray, rgba(0, 0, 0, 0.02));
    cursor: pointer;
    text-align: center;
    transition: border-color .15s ease, background-color .15s ease;
}

.upload-dropzone:hover,
.upload-dropzone:focus-visible {
    border-color: var(--mud-palette-primary);
    background-color: rgba(var(--mud-palette-primary-rgb), 0.06);
}

/* Drag is in progress over the zone — the strongest state, because the user is
   holding a file and needs to know this is where to let go. */
.upload-dropzone--over {
    border-color: var(--mud-palette-primary);
    border-style: solid;
    background-color: rgba(var(--mud-palette-primary-rgb), 0.1);
}

.upload-dropzone--full {
    cursor: not-allowed;
    opacity: 0.6;
}

.upload-dropzone--full:hover {
    border-color: var(--mud-palette-lines-default, rgba(0, 0, 0, 0.18));
    background-color: var(--mud-palette-background-gray, rgba(0, 0, 0, 0.02));
}

.upload-dropzone__icon {
    color: var(--mud-palette-text-secondary);
}

.upload-dropzone--over .upload-dropzone__icon,
.upload-dropzone:hover .upload-dropzone__icon {
    color: var(--mud-palette-primary);
}
