/* ==========================================================================
   AkademIQ Design System — Components (v0.17.0)
   New reusable component classes for pages authored/refreshed in the
   v0.17.0-rc1 redesign (.btn, .status-badge, .card, .alert, .data-table,
   .pagination, .empty-state, .skeleton, .stat-card, .tabs, .dropdown-menu,
   .filter-bar, .form-field, .breadcrumb). Legacy per-module classes
   (.researchers-*, .researcher-detail__*, .login-card__*, ...) keep their
   old selectors for compatibility with every page that already uses them,
   but are redefined on top of the same tokens in app.css so the whole app
   reads as one system. See docs/ui/design-system.md.
   ========================================================================== */

/* ---- Buttons ------------------------------------------------------------ */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2xs);
    /* v0.33 Stage C (C1): min-height instead of a fixed height, and the label may wrap - at 320 px (400 % zoom) a long label used to push the button out
       of the window. On normal widths a button still renders on one line at exactly the control height. */
    min-height: var(--control-h-md);
    max-width: 100%;
    padding: 0.3rem var(--space-md);
    border: var(--border-width) solid transparent;
    border-radius: var(--radius-md);
    background: var(--color-primary);
    color: var(--color-on-primary);
    font-family: inherit;
    font-weight: 600;
    font-size: 0.9rem;
    line-height: 1.2;
    text-align: center;
    text-decoration: none;
    white-space: normal;
    overflow-wrap: anywhere;
    cursor: pointer;
    transition: background-color var(--motion-fast) var(--motion-ease),
        border-color var(--motion-fast) var(--motion-ease),
        transform var(--motion-fast) var(--motion-ease),
        box-shadow var(--motion-fast) var(--motion-ease);
}

.btn:hover {
    background: var(--color-primary-hover);
}

.btn:active {
    background: var(--color-primary-active);
    transform: translateY(1px);
}

.btn:disabled,
.btn[aria-disabled="true"] {
    background: var(--color-border-strong);
    /* v0.33 Stage C (C3): a disabled button keeps a readable label (5.0:1 on its grey); "disabled" is shown by the grey fill and the cursor, not by
       making the text illegible (was the decorative token, ~1.6:1). */
    color: var(--color-text-secondary);
    cursor: not-allowed;
    transform: none;
}

.btn--secondary {
    background: var(--color-surface);
    border-color: var(--color-border-strong);
    color: var(--color-text-primary);
}

.btn--secondary:hover {
    background: var(--color-surface-sunken);
}

.btn--ghost {
    background: transparent;
    color: var(--color-text-secondary);
}

.btn--ghost:hover {
    background: var(--color-surface-sunken);
    color: var(--color-text-primary);
}

.btn--danger {
    background: var(--color-surface);
    border-color: var(--color-danger-border);
    color: var(--color-danger-text);
}

.btn--danger:hover {
    background: var(--color-danger-bg);
}

.btn--danger-solid {
    background: var(--color-danger-solid);
    color: #fff;
}

.btn--danger-solid:hover {
    background: #a8321f;
}

.btn--sm {
    min-height: var(--control-h-sm);
    padding: 0.2rem var(--space-sm);
    font-size: 0.82rem;
}

.btn--lg {
    min-height: var(--control-h-lg);
    padding: 0.4rem var(--space-lg);
    font-size: 1rem;
}

.btn--icon {
    width: var(--control-h-md);
    height: var(--control-h-md);
    padding: 0;
}

.btn--full {
    width: 100%;
}

/* ---- Status badges --------------------------------------------------------
   One generic component for every status vocabulary in the app (publication
   lifecycle, scoring, integration health, affiliation state, active/inactive
   toggles). Color + text + optional icon - meaning never depends on color
   alone (WCAG 1.4.1). */

.status-badge {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3xs);
    padding: 0.22rem 0.6rem;
    border-radius: var(--radius-full);
    font-size: 0.75rem;
    font-weight: 700;
    line-height: 1.3;
    white-space: nowrap;
}

.status-badge .icon { width: 0.85rem; height: 0.85rem; }

.status-badge--neutral { background: var(--color-neutral-bg); color: var(--color-neutral-text); }
.status-badge--info { background: var(--color-info-bg); color: var(--color-info-text); }
.status-badge--success { background: var(--color-success-bg); color: var(--color-success-text); }
.status-badge--warning { background: var(--color-warning-bg); color: var(--color-warning-text); }
.status-badge--danger { background: var(--color-danger-bg); color: var(--color-danger-text); }

/* Simple colored dot variant, for compact table cells where a full pill
   would crowd the row (density: G1). */
.status-dot {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2xs);
    font-size: var(--text-compact-size);
    font-weight: 600;
}

.status-dot::before {
    content: "";
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background: currentColor;
    flex-shrink: 0;
}

.status-dot--neutral { color: var(--color-text-faint); }
.status-dot--info { color: var(--color-primary); }
.status-dot--success { color: var(--color-success-solid); }
.status-dot--warning { color: var(--color-warning-solid); }
.status-dot--danger { color: var(--color-danger-solid); }

/* ---- Cards ---------------------------------------------------------------- */

.card {
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: var(--space-lg);
    box-shadow: var(--shadow-xs);
}

.card--interactive {
    text-decoration: none;
    color: inherit;
    display: block;
    transition: border-color var(--motion-fast) var(--motion-ease),
        box-shadow var(--motion-fast) var(--motion-ease),
        transform var(--motion-fast) var(--motion-ease);
}

.card--interactive:hover {
    border-color: var(--color-primary);
    box-shadow: var(--shadow-sm);
    transform: translateY(-1px);
}

/* KPI / dashboard summary card. */
.stat-card {
    display: flex;
    flex-direction: column;
    gap: var(--space-2xs);
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: var(--space-md) var(--space-lg);
    box-shadow: var(--shadow-xs);
}

.stat-card__label {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2xs);
    font-size: var(--text-caption-size);
    font-weight: var(--text-caption-weight);
    text-transform: uppercase;
    letter-spacing: var(--text-caption-tracking);
    color: var(--color-text-muted);
}

.stat-card__value {
    font-size: 1.65rem;
    font-weight: 700;
    color: var(--color-text-primary);
    font-variant-numeric: tabular-nums;
}

.stat-card__hint {
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

.stat-card--accent { border-color: var(--color-primary-subtle-strong); background: var(--color-primary-subtle); }
.stat-card--warning { border-color: var(--color-warning-border); background: var(--color-warning-bg); }

/* ---- Alerts (success / error / warning / info banners + inline validation) */

.alert {
    display: flex;
    align-items: flex-start;
    gap: var(--space-xs);
    margin-bottom: var(--space-md);
    padding: 0.7rem 0.9rem;
    border: var(--border-width) solid;
    border-radius: var(--radius-md);
    font-size: 0.9rem;
    line-height: 1.45;
}

.alert .icon { margin-top: 0.15rem; }

.alert--success { background: var(--color-success-bg); border-color: var(--color-success-border); color: var(--color-success-text); }
.alert--danger { background: var(--color-danger-bg); border-color: var(--color-danger-border); color: var(--color-danger-text); }
.alert--warning { background: var(--color-warning-bg); border-color: var(--color-warning-border); color: var(--color-warning-text); }
.alert--info { background: var(--color-info-bg); border-color: var(--color-info-border); color: var(--color-info-text); }

.alert ul {
    margin: var(--space-2xs) 0 0;
    padding-left: 1.1rem;
}

/* ---- Toast (transient feedback, top-right) -------------------------------- */

.toast-region {
    position: fixed;
    top: var(--space-lg);
    right: var(--space-lg);
    z-index: var(--z-error-banner);
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
    max-width: 22rem;
}

.toast {
    display: flex;
    align-items: flex-start;
    gap: var(--space-xs);
    padding: var(--space-sm) var(--space-md);
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-left: 3px solid var(--color-primary);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    font-size: 0.88rem;
    animation: toast-in var(--motion-slow) var(--motion-ease);
}

.toast--success { border-left-color: var(--color-success-solid); }
.toast--danger { border-left-color: var(--color-danger-solid); }
.toast--warning { border-left-color: var(--color-warning-solid); }

@keyframes toast-in {
    from { opacity: 0; transform: translateY(-0.5rem); }
    to { opacity: 1; transform: translateY(0); }
}

/* ---- Empty states ----------------------------------------------------------- */

.empty-state {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-sm);
    background: var(--color-surface);
    border: 1px dashed var(--color-border-strong);
    border-radius: var(--radius-lg);
    padding: var(--space-xl) var(--space-lg);
    max-width: 34rem;
}

.empty-state--centered {
    align-items: center;
    text-align: center;
    max-width: none;
}

.empty-state__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: var(--radius-full);
    background: var(--color-primary-subtle);
    color: var(--color-primary-text);
}

.empty-state__title {
    margin: 0;
    font-size: 1rem;
    font-weight: 700;
    color: var(--color-text-primary);
}

.empty-state__body {
    margin: 0;
    color: var(--color-text-muted);
    font-size: 0.9rem;
}

/* ---- Skeleton loading -------------------------------------------------------- */

.skeleton {
    display: block;
    border-radius: var(--radius-sm);
    background: linear-gradient(90deg, var(--color-border) 25%, var(--color-surface-sunken) 37%, var(--color-border) 63%);
    background-size: 400% 100%;
    animation: skeleton-shimmer 1.4s ease infinite;
}

@keyframes skeleton-shimmer {
    from { background-position: 100% 50%; }
    to { background-position: 0 50%; }
}

.skeleton--text { height: 0.9em; margin-bottom: var(--space-2xs); }
.skeleton--title { height: 1.4rem; width: 40%; margin-bottom: var(--space-sm); }
.skeleton--card { height: 5.5rem; border-radius: var(--radius-lg); }
.skeleton--row { height: 2.75rem; border-radius: var(--radius-sm); margin-bottom: var(--space-2xs); }

@media (prefers-reduced-motion: reduce) {
    .skeleton { animation: none; background: var(--color-border); }
}

/* ---- Data table ------------------------------------------------------------- */

.data-table-wrap {
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    overflow-x: auto;
    box-shadow: var(--shadow-xs);
}

.data-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--text-compact-size);
}

.data-table th,
.data-table td {
    padding: 0.7rem 1rem;
    text-align: left;
    border-bottom: var(--border-width) solid var(--color-border);
    vertical-align: middle;
}

/* table-layout stays auto (columns size to content), so an outlier-long
   value in the identity column (title/name) would otherwise get squeezed
   to near-nothing while short badge/date columns keep their natural
   width - min-width floors it at a readable width and lets .data-table-wrap's
   overflow-x:auto take over instead of wrapping one word per line. */
.data-table th:first-child,
.data-table td:first-child {
    min-width: 14rem;
    overflow-wrap: break-word;
}

.data-table th {
    background: var(--color-surface-sunken);
    color: var(--color-text-muted);
    font-weight: 700;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    position: sticky;
    top: 0;
}

/* v0.23.0-rc3: a row header (<th scope="row">) inside tbody is CONTENT (a title), not a column header - it must not
   inherit the uppercase/muted/sticky column-header styling. */
.data-table tbody th[scope="row"] {
    text-transform: none;
    letter-spacing: normal;
    font-size: inherit;
    font-weight: 600;
    color: var(--color-text-primary);
    background: transparent;
    position: static;
}

.data-table tbody tr {
    transition: background-color var(--motion-fast) var(--motion-ease);
}

.data-table tbody tr:hover {
    background: var(--color-surface-sunken);
}

.data-table tbody tr:last-child td {
    border-bottom: none;
}

.data-table td.is-numeric,
.data-table th.is-numeric {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* v0.23.0-rc3 (manual PROD acceptance, Dorobek at 375px): a wide table that simply overflows hid the columns that matter
   (type/status/year) behind an unexplained horizontal scroll. .data-table--priority keeps the identity column (title)
   sticky and narrow, hides the SECONDARY columns (.col-secondary) on small screens while the same facts stay available
   inline in the title cell (.only-narrow), and .data-table-wrap--scrollable draws edge shadows that show there is more
   to the side. Wide screens are unchanged. Reuses the existing table tokens - no separate redesign. */
.data-table-wrap--scrollable {
    background:
        linear-gradient(to right, var(--color-surface) 30%, rgba(255, 255, 255, 0)) left center / 2.5rem 100% no-repeat local,
        linear-gradient(to left, var(--color-surface) 30%, rgba(255, 255, 255, 0)) right center / 2.5rem 100% no-repeat local,
        radial-gradient(farthest-side at 0 50%, rgba(20, 33, 61, 0.22), rgba(20, 33, 61, 0)) left center / 0.9rem 100% no-repeat scroll,
        radial-gradient(farthest-side at 100% 50%, rgba(20, 33, 61, 0.22), rgba(20, 33, 61, 0)) right center / 0.9rem 100% no-repeat scroll,
        var(--color-surface);
}

.table-scroll-hint {
    display: none;
    margin: var(--space-xs) 0 0;
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

.data-table--priority .only-narrow { display: none; }

@media (max-width: 640px) {
    .data-table--priority th,
    .data-table--priority td { padding: 0.6rem 0.6rem; }

    .data-table--priority th:first-child,
    .data-table--priority td:first-child {
        min-width: 8rem;
        max-width: 9.5rem;
        /* table cells default to nowrap in this design system - the title MUST wrap here or it runs over the next column */
        white-space: normal;
        overflow-wrap: anywhere;
        position: sticky;
        left: 0;
        z-index: 2;
        background: var(--color-surface);
        box-shadow: 1px 0 0 var(--color-border);
    }

    .data-table--priority thead th:first-child { background: var(--color-surface-sunken); z-index: 3; }
    .data-table--priority .col-secondary { display: none; }
    .data-table--priority .only-narrow { display: block; font-size: 0.78rem; color: var(--color-text-muted); }
    .table-scroll-hint { display: block; }
}

.summary-list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs) var(--space-lg);
    list-style: none;
    padding: 0;
    margin: var(--space-md) 0;
}

.row-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-2xs);
}

/* ---- Pagination -------------------------------------------------------------- */

.pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-md);
    padding: var(--space-sm) var(--space-md);
    flex-wrap: wrap;
}

.pagination__status {
    font-size: 0.82rem;
    color: var(--color-text-muted);
}

.pagination__controls {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
}

/* ---- Tabs (module local nav) -------------------------------------------------- */

.tabs {
    display: flex;
    gap: var(--space-2xs);
    overflow-x: auto;
    margin-bottom: var(--space-lg);
    padding-bottom: 1px;
    border-bottom: var(--border-width) solid var(--color-border);
}

.tabs__link {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2xs);
    padding: 0.6rem 0.9rem;
    border-radius: var(--radius-sm) var(--radius-sm) 0 0;
    color: var(--color-text-secondary);
    text-decoration: none;
    font-size: 0.9rem;
    font-weight: 600;
    white-space: nowrap;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    background: none;
    cursor: pointer;
    transition: color var(--motion-fast) var(--motion-ease), border-color var(--motion-fast) var(--motion-ease);
}

.tabs__link:hover {
    background: var(--color-surface-sunken);
    color: var(--color-text-primary);
}

.tabs__link.active,
.tabs__link[aria-current="page"],
.tabs__link[aria-selected="true"] {
    color: var(--color-primary-text);
    border-bottom-color: var(--color-primary);
}

/* ---- Dropdown / action menu -------------------------------------------------- */

.dropdown-menu {
    position: relative;
    display: inline-block;
}

.dropdown-menu__toggle {
    list-style: none;
}

.dropdown-menu__toggle::-webkit-details-marker {
    display: none;
}

.dropdown-menu__panel {
    position: absolute;
    right: 0;
    top: calc(100% + 0.35rem);
    z-index: var(--z-dropdown);
    display: flex;
    flex-direction: column;
    gap: var(--space-3xs);
    min-width: 13rem;
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--space-2xs);
    box-shadow: var(--shadow-md);
}

.dropdown-menu__panel a,
.dropdown-menu__panel button {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    width: 100%;
    padding: 0.5rem 0.6rem;
    border: none;
    border-radius: var(--radius-sm);
    background: none;
    color: var(--color-text-primary);
    font-size: 0.88rem;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}

.dropdown-menu__panel a:hover,
.dropdown-menu__panel button:hover {
    background: var(--color-surface-sunken);
}

.dropdown-menu__panel a.is-danger,
.dropdown-menu__panel button.is-danger {
    color: var(--color-danger-text);
}

/* ---- Filter bar / search -------------------------------------------------------- */

.filter-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--space-sm);
    margin-bottom: var(--space-md);
    padding: var(--space-md);
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
}

.filter-bar__field {
    display: flex;
    flex-direction: column;
    gap: var(--space-3xs);
    min-width: 9rem;
}

.filter-bar__field label {
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.filter-bar__actions {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    margin-left: auto;
}

.filter-chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2xs);
    margin-bottom: var(--space-md);
}

.filter-chip {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2xs);
    padding: 0.25rem 0.6rem;
    background: var(--color-primary-subtle);
    color: var(--color-primary-text);
    border-radius: var(--radius-full);
    font-size: 0.8rem;
    font-weight: 600;
}

.filter-chip button {
    display: inline-flex;
    border: none;
    background: none;
    color: inherit;
    cursor: pointer;
    padding: 0;
    line-height: 1;
}

.search-box {
    position: relative;
    display: flex;
    align-items: center;
    flex: 1;
    min-width: 12rem;
}

.search-box .icon {
    position: absolute;
    left: 0.75rem;
    color: var(--color-text-faint);
    pointer-events: none;
}

.search-box input[type="search"],
.search-box input[type="text"] {
    width: 100%;
    padding: 0 0.75rem 0 2.25rem;
    height: var(--control-h-md);
}

/* ---- Form fields --------------------------------------------------------------- */

input[type="text"],
input[type="search"],
input[type="email"],
input[type="password"],
input[type="number"],
input[type="date"],
input[type="url"],
input[type="tel"],
select,
textarea {
    font-family: inherit;
    font-size: 0.9rem;
    color: var(--color-text-primary);
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border-strong);
    border-radius: var(--radius-md);
    padding: 0 0.75rem;
    height: var(--control-h-md);
    transition: border-color var(--motion-fast) var(--motion-ease), box-shadow var(--motion-fast) var(--motion-ease);
    /* v0.33 Stage C (C1, AUDIT-UX-001/002): a control never decides how wide its container is. Without these two lines a <select> is as wide as its
       LONGEST option (a 146-character unit name pushed /struktura/nowa 673 px past a phone screen and past 1600 px desktops too), and every grid/flex
       parent with an automatic minimum size grew with it. The text of a long option is still fully readable in the opened list. */
    max-width: 100%;
    min-width: 0;
}

select {
    text-overflow: ellipsis;
}

textarea {
    height: auto;
    padding: 0.6rem 0.75rem;
    min-height: 6rem;
    resize: vertical;
}

input:hover:not(:disabled),
select:hover:not(:disabled),
textarea:hover:not(:disabled) {
    border-color: var(--color-text-faint);
}

input:focus,
select:focus,
textarea:focus {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-primary-subtle);
}

input:disabled,
select:disabled,
textarea:disabled {
    background: var(--color-surface-sunken);
    color: var(--color-text-muted);
    cursor: not-allowed;
}

.form-field {
    display: flex;
    flex-direction: column;
    gap: var(--space-3xs);
    /* v0.33 Stage C (C1): a field in a grid or flex row may shrink below its content's natural width (the control inside then fills it). */
    min-width: 0;
}

.form-field label {
    font-size: var(--text-label-size);
    font-weight: var(--text-label-weight);
    color: var(--color-text-primary);
}

.form-field__required {
    color: var(--color-danger-solid);
}

.form-field__help {
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

.form-field__error {
    display: flex;
    align-items: center;
    gap: var(--space-3xs);
    font-size: 0.8rem;
    color: var(--color-danger-solid);
    font-weight: 600;
}

.form-field.has-error input,
.form-field.has-error select,
.form-field.has-error textarea {
    border-color: var(--color-danger-solid);
}

/* v0.33 Stage C (C3): FormErrorSummary - the list of a form's errors (each a link to the message at its field). */
.form-error-summary ul {
    margin: var(--space-3xs) 0 0;
    padding-left: 1.1rem;
}

.form-error-summary a {
    color: inherit;
    text-decoration: underline;
}

.form-error-summary:focus {
    outline: 3px solid var(--color-danger-solid);
    outline-offset: 2px;
}

.form-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-md) var(--space-lg);
}

.form-grid--single {
    grid-template-columns: 1fr;
}

.form-actions {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    margin-top: var(--space-lg);
    padding-top: var(--space-md);
    border-top: var(--border-width) solid var(--color-border);
}

/* ---- Stat grid -------------------------------------------------------------------
   Responsive grid of .stat-card - global (not component-scoped .razor.css)
   on purpose: used by both Dashboard.razor and DorobekNaukowy.razor (and any
   future page). Blazor CSS isolation only scopes a rule to markup the
   *owning* component itself renders, so a rule left in Dashboard.razor.css
   would silently never apply to this same class name written in a sibling
   page - confirmed as a real bug during v0.17.0-rc1 release visual acceptance
   (DorobekNaukowy's summary cards rendered as display:block, one per row,
   at every viewport width, cause was exactly this isolation trap). */
.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr));
    gap: var(--space-md);
    margin-bottom: var(--space-md);
}

/* ---- Confirm panel (inline destructive-action confirmation) ---------------------
   Global (not scoped to ConfirmButton.razor.css) on purpose: found during
   v0.17.0-rc1 release visual acceptance that KlasyfikacjaDyscyplinAktywacja.razor
   hand-rolls this exact panel (a justification-gated activation flow that
   doesn't fit <ConfirmButton>'s own Text/ConfirmMessage/OnConfirmed shape) and
   was silently rendering unstyled - the same cross-component CSS-isolation
   trap documented elsewhere in this file. */
.confirm-panel {
    display: inline-flex;
    flex-direction: column;
    gap: var(--space-xs);
    padding: var(--space-sm) var(--space-md);
    background: var(--color-danger-bg);
    border: var(--border-width) solid var(--color-danger-border);
    border-radius: var(--radius-md);
}

.confirm-panel__message {
    margin: 0;
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--color-danger-text);
}

.confirm-panel__actions {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
}

/* v0.23.0-rc3: status-change confirmation (Submit / Withdraw) - informational, not destructive, so it uses the
   info palette instead of .confirm-panel's danger palette. */
.status-confirm {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
    max-width: 34rem;
    padding: var(--space-sm) var(--space-md);
    background: var(--color-info-bg);
    border: var(--border-width) solid var(--color-info-border);
    border-radius: var(--radius-md);
    color: var(--color-info-text);
}

.status-confirm__title { margin: 0; font-weight: 700; }
.status-confirm__transition { margin: 0; font-weight: 600; }
.status-confirm__from, .status-confirm__to { padding: 0 var(--space-2xs); border-radius: var(--radius-sm); background: var(--color-surface); }
.status-confirm__body { margin: 0; font-size: 0.9rem; }
.status-confirm__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-xs); }

/* v0.33.0-rc2 (D22-A11Y-CONFIRM-001): ConfirmButton and StatusChangeConfirm are native modal dialogs. Their display values above would override the
   browser's "dialog:not([open]) { display: none }", so a closed one is hidden explicitly; an open one sits centred over a dimmed, inert page like the
   session and unsaved-changes dialogs, never wider than the phone screen, and its buttons wrap. */
dialog.confirm-dialog:not([open]),
dialog.status-confirm--dialog:not([open]) {
    display: none;
}

dialog.confirm-dialog,
dialog.status-confirm--dialog {
    max-width: min(32rem, calc(100vw - 2rem));
    box-sizing: border-box;
    box-shadow: var(--shadow-lg, 0 10px 30px rgba(20, 33, 61, 0.25));
    overflow-wrap: break-word;
    /* Rendered inside a table cell (e.g. Dostęp PKA): the cell's nowrap / alignment must not reach the question, or it is cut off on a phone. */
    white-space: normal;
    text-align: start;
}

dialog.status-confirm--dialog {
    padding: var(--space-md) var(--space-lg);
    border: var(--border-width) solid var(--color-warning-border);
    border-radius: var(--radius-lg);
}

dialog.confirm-dialog .confirm-panel__actions {
    flex-wrap: wrap;
}

dialog.confirm-dialog::backdrop,
dialog.status-confirm--dialog::backdrop {
    background: rgba(20, 33, 61, 0.55);
}

/* ---- Review / work queues --------------------------------------------------------
   Used by decision queues (author-match confirmation, duplicate review,
   verification) - each candidate is its own card with context/evidence on
   the left and a clearly separated primary/secondary/danger decision
   cluster, never a raw data table (Part E/F of the redesign brief). */

.review-queue {
    margin-bottom: var(--space-xl);
}

.review-queue h3 {
    display: flex;
    align-items: center;
    gap: var(--space-2xs);
    margin: 0 0 var(--space-sm);
}

.review-queue__item {
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: var(--space-md) var(--space-lg);
    margin-bottom: var(--space-md);
    box-shadow: var(--shadow-xs);
}

.review-queue__actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--space-sm);
    margin-top: var(--space-md);
    padding-top: var(--space-sm);
    border-top: var(--border-width) solid var(--color-border);
}

.review-queue__decisions {
    display: flex;
    gap: var(--space-xs);
    flex-wrap: wrap;
    margin-left: auto;
}

/* v0.19.0-rc4: bulk selection bar above a review-queue's item list, and the
   per-item checkbox each article grows to carry - kept visually part of the
   existing card/queue pattern rather than a separate table, matching the
   surrounding non-tabular list style. */
.review-queue__bulk-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--space-sm);
    background: var(--color-surface-alt, var(--color-surface));
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: var(--space-sm) var(--space-lg);
    margin-bottom: var(--space-md);
}

.review-queue__bulk-select-all {
    display: flex;
    align-items: center;
    gap: var(--space-2xs);
    font-weight: 600;
}

.review-queue__item {
    position: relative;
}

.review-queue__item-select {
    position: absolute;
    top: var(--space-md);
    right: var(--space-lg);
}

/* ---- Entity header strip -------------------------------------------------------
   A compact row of key facts under a detail page's <PageHeader> (status badge
   + a handful of "label: value" chips) - used by ResearcherDetails,
   PublicationDetails and other entity detail pages so they share one
   "at a glance" pattern instead of each re-deriving its own. */

.entity-header-strip {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-sm);
    margin-bottom: var(--space-lg);
    padding-bottom: var(--space-md);
    border-bottom: var(--border-width) solid var(--color-border);
}

.entity-header-strip__item {
    font-size: 0.85rem;
    color: var(--color-text-secondary);
    /* v0.33 Stage C (C1): a long e-mail or identifier wraps instead of leaving the screen. */
    min-width: 0;
    max-width: 100%;
    overflow-wrap: anywhere;
}

.entity-header-strip__item::before {
    content: "•";
    margin-right: var(--space-sm);
    color: var(--color-border-strong);
}

/* ---- Breadcrumb (also used outside PageHeader.razor's own scope) --------------- */

.breadcrumb {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2xs);
    margin-bottom: var(--space-sm);
    font-size: 0.85rem;
    color: var(--color-text-muted);
}

.breadcrumb a {
    color: var(--color-text-muted);
    text-decoration: none;
}

.breadcrumb a:hover {
    color: var(--color-primary-text);
    text-decoration: underline;
}

.breadcrumb [aria-current="page"] {
    color: var(--color-text-primary);
    font-weight: 600;
}

@media (max-width: 860px) {
    .form-grid {
        grid-template-columns: 1fr;
    }

    .btn,
    .btn--secondary,
    .btn--danger,
    .dropdown-menu__toggle {
        min-height: var(--control-touch-min);
    }
}

/* ==========================================================================
   Access-mode banner (moved here from the scoped MainLayout stylesheet in v0.28.0-rc2: the banner is now an interactive island of its own, and scoped CSS does not cross components)
   ========================================================================== */
/* RC9: a persistent, clearly recognisable strip for the raised-privilege
   state - v0.17.0 keeps it always visible (never blending into ordinary
   chrome) but as a refined amber chip-style band rather than a shouting
   "alarm" banner (Part C2: elegant, not aggressive red). */
.access-mode-banner {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: var(--space-sm);
    padding: 0.6rem 2rem;
    font-size: 0.85rem;
    font-weight: 600;
}

.access-mode-banner--admin {
    background: linear-gradient(90deg, var(--color-warning-bg) 0%, #fff8ea 100%);
    color: var(--color-warning-text);
    border-bottom: var(--border-width) solid var(--color-warning-border);
}

.access-mode-banner--readonly {
    background: var(--color-info-bg);
    color: var(--color-info-text);
    border-bottom: var(--border-width) solid var(--color-border-strong);
}

.access-mode-banner__icon {
    display: inline-flex;
}

.access-mode-banner__form {
    margin: 0;
}

.access-mode-banner__disable {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2xs);
    padding: 0.3rem 0.75rem;
    border: var(--border-width) solid var(--color-warning-solid);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    color: var(--color-warning-text);
    font-size: 0.8rem;
    font-weight: 700;
    cursor: pointer;
    transition: background-color var(--motion-fast) var(--motion-ease);
}

.access-mode-banner__disable:hover {
    background: #fdecc4;
}

.access-mode-banner__enable {
    display: inline-flex;
    align-items: center;
    padding: 0.3rem 0.75rem;
    border: var(--border-width) solid var(--color-primary);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    color: var(--color-primary-text);
    font-size: 0.8rem;
    font-weight: 700;
    text-decoration: none;
    transition: background-color var(--motion-fast) var(--motion-ease);
}

.access-mode-banner__enable:hover {
    background: var(--color-primary-subtle);
}

@media (max-width: 860px) {
    .access-mode-banner {
        padding: 0.65rem 1rem;
    }
}

/* v0.28.0-rc2: the administrative mode ran out (30 minutes without administrative activity, or the 8-hour maximum) - the strip says so instead of claiming the mode is active. */
.access-mode-banner--expired {
    background: var(--color-danger-bg);
    color: var(--color-danger-text);
    border-bottom: var(--border-width) solid var(--color-danger-border);
}

.access-mode-banner__expiry {
    font-weight: 600;
}

/* ---- v0.33 Stage C (C2): session warnings (SessionKeeper) -------------------------------------------------- */
.session-banner {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    padding: 0.6rem 2rem;
    background: var(--color-warning-bg);
    color: var(--color-warning-text);
    border-bottom: var(--border-width) solid var(--color-warning-border);
    font-weight: 600;
}

.session-dialog {
    max-width: min(32rem, calc(100vw - 2rem));
    border: var(--border-width) solid var(--color-border-strong);
    border-radius: var(--radius-lg);
    padding: var(--space-lg);
    color: var(--color-text-primary);
    background: var(--color-surface);
    box-shadow: var(--shadow-lg, 0 10px 30px rgba(20, 33, 61, 0.25));
}

.session-dialog::backdrop {
    background: rgba(20, 33, 61, 0.55);
}

.session-dialog__title {
    margin: 0 0 var(--space-sm);
    font-size: var(--text-section-title-size);
}

.session-dialog__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-sm);
    margin-top: var(--space-md);
}

/* ---- v0.33 Stage C (C2): unsaved-changes confirmation (UnsavedChangesGuard) -------------------------------- */
.unsaved-dialog {
    max-width: min(32rem, calc(100vw - 2rem));
    border: var(--border-width) solid var(--color-border-strong);
    border-radius: var(--radius-lg);
    padding: var(--space-lg);
    color: var(--color-text-primary);
    background: var(--color-surface);
}

.unsaved-dialog::backdrop {
    background: rgba(20, 33, 61, 0.55);
}
