/* Global concerns not covered by component CSS isolation. Everything else
   (shell layout, screens, primitives) lives in scoped .razor.css files and
   references tokens.css variables only — see frontend-blazor.md §6/§8. */

.not-found {
    padding: 40px;
    color: var(--faint);
    font-size: 0.8125rem;
}

/* NavMenu's sidebar links — kept here, not in NavMenu.razor.css, because
   NavLink (Microsoft.AspNetCore.Components.Routing) is a built-in
   component: Blazor's CSS isolation never stamps a scope attribute onto a
   child component's own root element, only onto elements authored directly
   in the parent .razor file. A scoped rule here would silently never match. */
.nav-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: var(--nav-pad);
    border-radius: var(--radius-sm);
    color: var(--dim);
    /* Sidebar nav reads larger than page body by design — pinned to 1.3x the
       base size regardless of density, so it scales with the font-scale
       control (rem) without picking up density's own type-scale changes. */
    font-size: calc(0.78125rem * 1.3);
    font-weight: 500;
    text-decoration: none;
}

.nav-item:hover {
    color: var(--text);
    text-decoration: none;
}

.nav-item.active {
    background: var(--accent-soft);
    color: var(--accent);
    font-weight: 600;
}

/* ----- drawer detail vocabulary --------------------------------------------
   Global for the same reason the buttons below are: a detail panel is rendered
   into another component's slot (Drawer's ChildContent), so a scoped rule in
   the panel's own .razor.css reaches its markup but a rule in the page that
   opened the drawer does not — and every one of these was previously declared
   per page. ProfileDetailPanel declared none of them, which is why its section
   labels ran into their help text on one line.

   Scoped rules still win, so a page that styles its own copies is unaffected;
   these are the floor, not an override. */

.detail-section {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--border);
}

.detail-section:first-child {
    margin-top: 0;
    padding-top: 0;
    border-top: none;
}

.detail-head-text {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}

.detail-title {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--text);
}

.detail-sub {
    font-family: var(--mono);
    font-size: 0.6875rem;
    color: var(--faint);
}

.field-value {
    font-size: 0.8125rem;
    color: var(--text);
    line-height: 1.5;
}

.field-hint {
    font-size: 0.71875rem;
    color: var(--faint);
}

#blazor-error-ui {
    display: none;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 1000;
    background: var(--red);
    color: oklch(0.99 0 0);
    padding: 10px 16px;
    font-size: 0.78125rem;
}

#blazor-error-ui .reload {
    color: inherit;
    font-weight: 600;
    text-decoration: underline;
    margin-left: 8px;
}

#blazor-error-ui .dismiss {
    float: right;
    cursor: pointer;
}

/* ----- buttons -------------------------------------------------------------
   Global on purpose. These were previously re-declared in each page's scoped
   .razor.css, so a page that forgot one rendered a bare browser button — which
   is exactly what happened to Mailgun's "Domain anlegen" and its drawer delete.
   Scoped rules still win (isolation adds an attribute selector, which is more
   specific), so pages that style their own buttons are unaffected; these are
   the floor, not an override.

   A button rendered into another component's slot — a Drawer footer, a Modal
   footer — belongs to the parent page's scope, so a global default is the only
   thing that reliably reaches it. */

.btn-primary,
.btn-danger,
.btn-warn,
.btn-ghost {
    border-radius: var(--radius);
    padding: 0.35rem 0.9rem;
    font: inherit;
    font-size: var(--fs-small);
    cursor: pointer;
    white-space: nowrap;
    transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}

.btn-primary {
    background: var(--accent, var(--blue));
    border: 1px solid transparent;
    color: var(--bg);
    font-weight: 600;
}

.btn-primary:hover:not(:disabled) {
    filter: brightness(1.08);
}

/* Destructive and irreversible. */
.btn-danger {
    background: transparent;
    border: 1px solid var(--red);
    color: var(--red);
}

.btn-danger:hover:not(:disabled) {
    background: color-mix(in oklch, var(--red) 12%, transparent);
}

/* Changes something real but is recoverable — a retry, a re-publish. Amber
   sits deliberately between the neutral ghost and the red danger button. */
.btn-warn {
    background: transparent;
    border: 1px solid var(--amber);
    color: var(--amber);
}

.btn-warn:hover:not(:disabled) {
    background: color-mix(in oklch, var(--amber) 14%, transparent);
}

.btn-ghost {
    background: transparent;
    border: 1px solid var(--border);
    color: var(--text);
}

.btn-ghost:hover:not(:disabled) {
    border-color: var(--border-2);
    background: var(--surface-2);
}

.btn-primary:disabled,
.btn-danger:disabled,
.btn-warn:disabled,
.btn-ghost:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}
