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;
}

/* ── Contextual page help (PageHelpDialog) ─────────────────────────────────── */
/* .nx-page-help is gone with the inline card — the help now opens in a dialog from the breadcrumb
   toolbar, and MudDialog brings its own surface. The block and step styles below are still used by
   the dialog body. */
.nx-help-block {
    min-width: 0;
}

ol.nx-help-steps {
    margin: 0;
    padding-left: 1.25rem;
}

ol.nx-help-steps > li {
    margin-bottom: 0.25rem;
}
/* A count badge on a full-size (48px) icon button. MudBadge anchors 8px outside the BUTTON's corner,
   and a default icon button wraps its 24px glyph in 12px of padding — so the badge lands ~10px clear of
   the icon and reads as floating next to it rather than belonging to it. The small buttons elsewhere
   (the thread header's notes badge) have only 3px of padding, which is why those look right untouched.
   MudBadge positions an overlapping badge with bottom/left — `calc(100% - 12px)` against the button box,
   with top/right forced to auto — so those are the properties to move; setting top/right does nothing.
   12px → 21px pulls it in by 9, landing it on the glyph's corner the way the notes badge sits. The
   number assumes the default 48px icon button holding a 24px glyph, which is what this class is for.
   The full selector is needed to outrank MudBlazor's own four-class rule. */
.nx-badge-on-icon .mud-badge.mud-badge-top.right.mud-badge-overlap {
    bottom: calc(100% - 21px);
    left: calc(100% - 21px);
}

/* Inbox: a quoted reply is a jump link to the message it answers (nxScrollToMessage). The flash is
   what makes the landing obvious — without it a smooth scroll leaves you guessing which bubble. */
.nx-quote:hover {
    background: rgba(0, 0, 0, .08) !important;
}

@keyframes nx-quote-flash {
    0%   { background-color: rgba(7, 94, 84, .28); }
    100% { background-color: transparent; }
}

.nx-quote-flash {
    animation: nx-quote-flash 1.4s ease-out 1;
    border-radius: 8px;
}

/* A count badge on a MudTabs tab (the platform WhatsApp "Conversations" tab, and anything else that grows
   one). MudBadge anchors the badge 16px right of the badge-root, which sits immediately after the tab's
   label — so on a tab with 12px of right padding the 20px badge ends up 4px past the tab's own box, and
   `.mud-tab` is `overflow: hidden` for its ripple, which slices the badge's right edge off.
   Widening the padding rather than unhiding the overflow is deliberate: the hidden overflow is what keeps
   the ripple inside the tab, and letting it out to fix a badge would trade one visual bug for another.
   28px = the default 12px plus 16px: the measured 4px shortfall plus air, so the badge reads as clear
   of the label instead of touching it. Measured after: 12px clear on the right, 8px top, 20px bottom. Scoped with :has() so tabs WITHOUT a badge keep their normal width and the tab row does
   not shift the day a badge appears or disappears. */
.mud-tab:has(.mud-tab-badge) {
    padding-right: 28px;
}

/* Dialog forms on a narrow screen.

   Every form dialog in Sales and Tech Support pinned its content to a fixed min-width (460–560px) and
   laid paired fields out in `d-flex` rows that never wrap. On a 375px phone that meant the dialog fitted
   the viewport but its content did not: measured 568px of content inside a 375px dialog, so "Company
   name", "Email", "Country" and "Estimated MRR" all sat off the right edge and the form had to be
   scrolled sideways to be filled in.

   Two rules, because there were two causes. The width floor becomes a ceiling as well — the dialog keeps
   its comfortable desktop width and gives it up when there is no room. Each dialog passes its own width
   through --nx-form-w so widening one does not mean editing this file. `100vw - 48px` leaves the dialog
   its margins; a percentage cannot be used here because the dialog is sized *by* this content, so a
   percentage min-width would resolve against a containing block that does not have a width yet.

   Then the rows wrap. `flex: 1 1 200px` lets two fields share a line while there is room for both and
   drops the second onto its own line when there is not, instead of squeezing both into something too
   narrow to read. `min-width: 0` is what actually permits the shrink — flex items default to
   `min-width: auto`, which refuses to go below the input's intrinsic width and is the usual reason a
   wrap rule looks like it did nothing. */
.nx-form-stack {
    min-width: min(var(--nx-form-w, 520px), calc(100vw - 48px));
}

.nx-form-stack .d-flex {
    flex-wrap: wrap;
}

.nx-form-stack .d-flex > * {
    flex: 1 1 200px;
    min-width: 0;
}

/* Page header row: title on the left, actions pushed right by a MudSpacer.

   These were plain `d-flex`, which cannot wrap, so on a narrow screen the actions ran off the right
   edge and took the page with them — /support/sessions measured 417px of document in a 375px viewport
   because its header carries a title, an "All agents" switch and a refresh button. Wrapping costs
   nothing on a wide screen, where the row never reaches its limit.

   The MudSpacer keeps working: on one line it still pushes the actions right, and once the row wraps it
   collapses to zero and the actions start the next line. */
.nx-page-header {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
}

/* ── MudSelect with a leading icon keeps its dropdown arrow ────────────────── */
/* MudSelect has one adornment slot, and it spends it on the dropdown arrow. Passing
   `Adornment="Adornment.Start"` to put a leading icon on the field therefore does not *add* an
   adornment, it *moves* the only one — the arrow disappears and the select renders as something
   indistinguishable from a MudTextField. That is what /workspace/create, /{slug}/settings/company and
   the template library all looked like: five fields the user had no reason to think were selectable.

   The arrow is the affordance and the leading icon is the design, so this draws the arrow back rather
   than giving up either. `.mud-input` is an inline-flex row, so an ::after is a flex item after the
   input slot — it takes real space instead of overlapping the value, which matters for the long
   timezone labels that already ellipsize at the field edge.

   The geometry reproduces MudBlazor's own arrow so a select with a leading icon lines up with one
   without: a 24px glyph centred in the 48px box a default MudIconButton occupies (12px padding each
   side), plus the 14px `.mud-input-outlined.mud-input-adorned-end` would have added. Outlined is the
   only variant these selects use; a filled one would want 12px there.

   The guards keep it to the case that is actually broken: `.mud-input-adorned-end` means MudBlazor is
   still drawing its own arrow, and MudAutocomplete shares `.mud-select-input` but manages its end
   adornment itself (clear button, progress ring). */
.mud-select-input.mud-input-adorned-start:not(.mud-input-adorned-end, .mud-autocomplete *)::after {
    content: "";
    flex: 0 0 auto;
    width: 48px;
    height: 24px;
    margin-inline-end: 14px;
    background-color: var(--mud-palette-action-default);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7 10l5 5 5-5z'/%3E%3C/svg%3E") no-repeat center / 24px 24px;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7 10l5 5 5-5z'/%3E%3C/svg%3E") no-repeat center / 24px 24px;
    pointer-events: none;
}

.mud-input.mud-disabled.mud-select-input.mud-input-adorned-start:not(.mud-input-adorned-end, .mud-autocomplete *)::after {
    background-color: var(--mud-palette-text-disabled);
}

/* MCP-S10: copyable connect snippets on the API keys page. Wraps long commands instead of
   pushing the card sideways, and uses the theme surface so it reads in light and dark. */
.mcp-snippet {
    margin: 0;
    padding: 12px 14px;
    border-radius: var(--mud-default-borderradius);
    background-color: var(--mud-palette-background-gray);
    border: 1px solid var(--mud-palette-lines-default);
    font-size: 0.8125rem;
    line-height: 1.6;
    white-space: pre-wrap;
    word-break: break-word;
    overflow-x: auto;
}
