body {
    background: var(--bg-page);
    color: var(--text-primary);
    margin: 0;
}

.panel,
.card,
.hero {
    background: var(--bg-panel);
    border: var(--border-width) solid var(--border-color);
    border-radius: var(--border-radius-lg);
    min-width: 0;
}

.panel {
    box-shadow: var(--elevation-1);
}

.panel--secondary {
    background: var(--bg-panel-secondary);
    border: var(--border-width) solid var(--border-color);
    border-radius: var(--border-radius-md);
}

/* Danger-zone panel: hosts an irreversible platform action (release
   clear-down). The error tokens mark the whole card — border and heading — so
   the area reads as dangerous before any control is reached. */
.panel--danger {
    border-color: var(--border-error);
    border-left: 4px solid var(--border-error);
}

.panel--danger > .workspace-section-label {
    color: var(--text-error);
}

.role-pill,
.eyebrow {
    display: inline-flex;
    align-items: center;
    font-size: var(--font-size-xs);
    background: var(--role-pill-bg, var(--role-icon-bg));
    color: var(--role-pill-text, var(--role-icon-text));
    border: 1px solid transparent;
    border-color: var(--role-pill-border, var(--role-icon-bg));
    box-shadow: var(--role-pill-shadow, none);
    padding: 3px 8px;
    border-radius: var(--border-radius-sm);
    margin-bottom: 6px;
}

/* Role colours are part of the Criterium visual design language for subtle area identification. */
.role-pill--admin,
.role-pill--platform_operator,
.role-pill--platform_security,
.role-pill--platform_engineer,
.role-pill--organisation_admin,
.role-pill--content_author,
.role-pill--content_reviewer,
.role-pill--marker,
.role-pill--invigilator,
.role-pill--analyst,
.role-pill--psychometrician,
.role-pill--results_viewer,
.role-pill--candidate {
    --role-pill-text: var(--text-primary);
    --role-pill-bg: color-mix(in srgb, var(--role-pill-color) 12%, var(--bg-panel-secondary) 88%);
    --role-pill-border: color-mix(in srgb, var(--role-pill-color) 28%, var(--border-color) 72%);
    --role-pill-shadow: inset 3px 0 0 0 var(--role-pill-color);
}

.role-pill--admin {
    --role-pill-color: var(--role-admin);
}

.role-pill--platform_operator,
.role-pill--platform_security,
.role-pill--platform_engineer,
.role-pill--organisation_admin {
    --role-pill-color: var(--role-admin);
}

.role-pill--content_author {
    --role-pill-color: var(--role-content-author);
}

.role-pill--content_reviewer {
    --role-pill-color: var(--role-content-reviewer);
}

.role-pill--marker {
    --role-pill-color: var(--role-marker);
}

.role-pill--invigilator {
    --role-pill-color: var(--role-invigilator);
}

.role-pill--analyst,
.role-pill--psychometrician,
.role-pill--results_viewer {
    --role-pill-color: var(--role-content-reviewer);
}

.role-pill--candidate {
    --role-pill-color: var(--role-candidate);
}

.button.primary,
button.primary,
.button,
button,
input[type="submit"],
input[type="button"] {
    background: var(--btn-primary-bg);
    color: var(--btn-primary-text);
    border: var(--btn-primary-border, none);
    border-radius: var(--border-radius-sm);
    padding: 8px 16px;
    font-family: inherit;
    font-size: inherit;
    font-weight: 700;
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease-standard), border-color var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard), transform var(--duration-fast) var(--ease-standard);
}

.button.primary:hover,
button.primary:hover,
.button:hover,
button:hover,
input[type="submit"]:hover,
input[type="button"]:hover {
    background: var(--accent-hover);
}

.button.secondary,
button.secondary {
    background: var(--btn-secondary-bg);
    color: var(--btn-secondary-text);
    border: var(--btn-secondary-border);
    border-radius: var(--border-radius-sm);
    padding: 8px 14px;
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease-standard), border-color var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard), transform var(--duration-fast) var(--ease-standard);
}

.button.secondary:hover,
button.secondary:hover {
    background: var(--accent-subtle);
    color: var(--text-primary);
    border-color: var(--border-color-emphasis);
}

.button.primary:focus-visible,
button.primary:focus-visible,
.button:focus-visible,
button:focus-visible,
input[type="submit"]:focus-visible,
input[type="button"]:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.button.primary:active,
button.primary:active,
.button:active,
button:active,
input[type="submit"]:active,
input[type="button"]:active {
    transform: translateY(1px);
}

.button.secondary:active,
button.secondary:active {
    background: var(--accent-subtle);
    border-color: var(--border-color-emphasis);
}

.button.danger,
button.danger {
    background: var(--bg-error);
    color: var(--text-error);
    border: var(--border-width) solid var(--border-error);
    border-radius: var(--border-radius-sm);
    padding: 8px 14px;
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease-standard), border-color var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard), transform var(--duration-fast) var(--ease-standard);
}

.button.danger:hover,
button.danger:hover {
    background: var(--border-error);
    color: var(--text-error);
}

.button.danger:active,
button.danger:active {
    transform: translateY(1px);
}

input,
textarea,
select {
    background: var(--bg-input);
    border: var(--border-width) solid var(--border-color);
    border-radius: var(--border-radius-sm);
    color: var(--text-primary);
    padding: 6px 10px;
    width: 100%;
    box-sizing: border-box;
    font: inherit;
}

input:focus,
textarea:focus,
select:focus {
    outline: none;
    border-color: var(--accent);
}

.answer-option,
.choice-item {
    display: flex;
    align-items: center;
    gap: 10px;
    border: var(--border-width) solid var(--border-color);
    border-radius: var(--border-radius-md);
    padding: 10px 12px;
    cursor: pointer;
    background: var(--bg-panel-secondary);
    color: var(--text-secondary);
    transition: border-color var(--duration-base);
}

.answer-option:hover,
.choice-item:hover {
    border-color: var(--border-color-emphasis);
}

.answer-option.is-selected {
    border: var(--border-width-emphasis) solid var(--border-color-emphasis);
    background: var(--bg-radio-selected);
    color: var(--text-primary);
}

.choice-item:has(input:checked) {
    border: var(--border-width-emphasis) solid var(--border-color-emphasis);
    background: var(--bg-radio-selected);
    color: var(--text-primary);
}

.radio-dot {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    border: 1.5px solid var(--border-color);
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

.answer-option.is-selected .radio-dot {
    border-color: var(--accent);
}

.answer-option.is-selected .radio-dot::after {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--accent);
    display: block;
}

.progress-track {
    background: var(--progress-track);
    height: 4px;
    border-radius: var(--border-radius-pill);
    overflow: hidden;
}

.progress-fill {
    background: var(--progress-fill);
    height: 4px;
    border-radius: var(--border-radius-pill);
    transition: width 0.3s ease;
    width: 0%;
}

.badge--draft {
    background: var(--bg-badge-draft);
    color: var(--text-badge-draft);
    font-size: var(--font-size-xs);
    padding: 2px 6px;
    border-radius: var(--border-radius-sm);
    border: 1px solid var(--border-color);
}

.badge--warning {
    display: inline-flex;
    align-items: center;
    width: fit-content;
    background: var(--warning-bg);
    color: var(--warning-text);
    font-size: var(--font-size-xs);
    font-weight: 700;
    padding: 2px 6px;
    border-radius: var(--border-radius-sm);
    border: 1px solid color-mix(in srgb, var(--warning-text) 30%, transparent);
}

.muted {
    color: var(--text-muted);
}

.sidebar .notice {
    background: var(--bg-panel-secondary);
    color: var(--text-primary);
    border-color: var(--border-color);
}

.candidate-table,
table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--font-size-base);
    line-height: 1.45;
}

.candidate-table thead tr,
table thead tr {
    background: var(--bg-table-header);
}

.candidate-table thead th,
table thead th {
    color: var(--text-on-accent);
    text-align: left;
    padding: 0.65rem 0.85rem;
    font-weight: 700;
}

.candidate-table tbody td,
table tbody td {
    padding: 0.72rem 0.85rem;
    color: var(--text-primary);
    border-bottom: 1px solid var(--border-color);
}

/*
 * Wide-table scroll region.
 *
 * Wrap any data table that can exceed its panel width:
 *
 *   <div class="table-scroll" role="region" aria-label="…" tabindex="0">
 *       <table class="candidate-table">…</table>
 *   </div>
 *
 * The wrapper scrolls horizontally instead of the page; scrolling edge
 * shadows (background-attachment: local) appear only while content is
 * clipped, giving a visible affordance that more columns exist. tabindex +
 * role="region" + aria-label make the region keyboard-focusable and named,
 * so keyboard-only users can scroll it with the arrow keys. Print resets the
 * overflow so the full table is printed.
 */
.table-scroll {
    overflow-x: auto;
    background:
        linear-gradient(to right, var(--bg-panel) 30%, transparent) left center,
        linear-gradient(to left, var(--bg-panel) 30%, transparent) right center,
        radial-gradient(farthest-side at 0 50%, color-mix(in srgb, var(--text-primary) 30%, transparent), transparent) left center,
        radial-gradient(farthest-side at 100% 50%, color-mix(in srgb, var(--text-primary) 30%, transparent), transparent) right center;
    background-repeat: no-repeat;
    background-size: 48px 100%, 48px 100%, 14px 100%, 14px 100%;
    background-attachment: local, local, scroll, scroll;
}

.table-scroll:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

@media print {
    .table-scroll {
        overflow-x: visible;
        background: none;
    }
}

[data-theme="amber-ledger"] h1,
[data-theme="amber-ledger"] h2 {
    font-family: var(--heading-font, var(--font-serif));
}

[data-theme="amber-ledger"] .sidebar {
    background: var(--sidebar-bg);
    color: var(--sidebar-text);
    --bg-panel: var(--sidebar-card-bg);
    --bg-panel-secondary: var(--sidebar-card-bg);
    --bg-input: var(--sidebar-card-bg);
    --border-color: var(--sidebar-card-border);
    --text-primary: var(--sidebar-card-text);
    --text-secondary: var(--sidebar-card-label);
    --text-muted: var(--sidebar-card-label);
}

[data-theme="forest-authority"] .sidebar {
    background: var(--sidebar-bg);
    color: var(--sidebar-text);
    --bg-panel: var(--sidebar-card-bg);
    --bg-panel-secondary: var(--sidebar-card-bg);
    --bg-input: var(--sidebar-card-bg);
    --border-color: var(--sidebar-card-border);
    --text-primary: var(--sidebar-card-text);
    --text-secondary: var(--sidebar-card-label);
    --text-muted: var(--sidebar-card-label);
}

[data-theme="civic-clear"] .sidebar {
    background: var(--sidebar-bg);
    color: var(--sidebar-text);
    --bg-panel: var(--sidebar-card-bg);
    --bg-panel-secondary: var(--sidebar-card-bg);
    --bg-input: var(--sidebar-card-bg);
    --border-color: var(--sidebar-card-border);
    --text-primary: var(--sidebar-card-text);
    --text-secondary: var(--sidebar-card-label);
    --text-muted: var(--sidebar-card-label);
}

[data-theme="forest-authority"] .candidate-table thead th {
    color: var(--text-on-accent);
}

[data-theme="obsidian-edge"] .sidebar {
    background: var(--sidebar-bg);
    color: var(--sidebar-text);
    border-right: 1px solid var(--accent);
}

[data-theme="obsidian-edge"] .radio-dot {
    border-radius: 0;
}

[data-theme="obsidian-edge"] .answer-option.is-selected .radio-dot::after {
    border-radius: 0;
}

[data-theme="obsidian-edge"] .candidate-table thead tr {
    background: var(--bg-table-header);
}

[data-theme="obsidian-edge"] .candidate-table thead th {
    color: var(--text-muted);
    font-size: var(--font-size-xs);
    letter-spacing: 1.5px;
}

.th-sortable {
    cursor: pointer;
    -webkit-user-select: none;
    user-select: none;
    white-space: nowrap;
}

.th-sortable:hover {
    opacity: 0.8;
}

.sort-indicator {
    display: inline-block;
    margin-left: 0.2rem;
    font-size: 0.8em;
    opacity: 0.75;
}

/* Preview panel spacing and layout for assessment source previews */
.preview-root {
    margin: 0;
}
.preview-meta {
    margin: 0 0 0.75rem 0;
}
.preview-notices {
    margin: 0 0 0.75rem 1rem;
    padding-left: 0.5rem;
    color: var(--text-secondary);
}
.instance-group {
    background: var(--bg-panel-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius-md);
    padding: 0.9rem 1rem;
    margin: 0 0 1rem 0;
}
.instance-group-heading h3 {
    margin: 0 0 0.6rem 0;
    font-size: 1.05rem;
}
.preview-section-instructions {
    margin: 0 0 0.75rem 0;
    color: var(--text-secondary);
}
.preview-question-list {
    list-style: none;
    padding: 0;
    margin: 0;
}
.preview-question-item {
    padding: 0.9rem 0;
    border-bottom: 1px solid var(--border-color);
}
.preview-question-item:last-child {
    border-bottom: none;
}
.preview-question-num {
    display: inline-block;
    width: 2.2rem;
    margin-right: 0.6rem;
    color: var(--text-muted);
}
.preview-question-body {
    display: block;
}
.preview-question-prompt {
    display: block;
    font-weight: 600;
    margin-bottom: var(--space-1);
}
.preview-question-meta {
    font-size: var(--font-size-md);
    color: var(--text-muted);
    display: flex;
    gap: var(--space-4);
    align-items: center;
}

/* Section rule pill next to section titles */
.section-rule-pill {
    display: inline-block;
    margin-left: 0.6rem;
    background: var(--bg-panel-secondary);
    color: var(--text-secondary);
    border: 1px solid var(--border-color);
    padding: 3px 8px;
    border-radius: var(--border-radius-pill);
    font-size: var(--font-size-sm);
    vertical-align: middle;
}

.section-total-marks {
    display: inline-block;
    color: var(--text-muted);
    font-size: var(--font-size-xs);
    margin-left: 10px;
}

.preview-template-title {
    color: var(--text-secondary);
    font-size: var(--font-size-base);
    margin-top: var(--space-1);
}

/* Tighter, inline-styled notices for table rows to avoid overflow/clip issues */
.content-table .notice {
    display: inline-block;
    padding: 0.35rem 0.6rem;
    border-radius: var(--border-radius-sm);
    margin-left: 0.5rem;
    white-space: normal;
    max-width: 100%;
    box-sizing: border-box;
    font-size: var(--font-size-sm);
}

/* ------------------------------------------------------------------ */
/* Progressive-disclosure governed components.
   Sole sanctioned implementations of accordion, modal, tabs, and empty
   state. Backed by deploy/src/ui_components.php — do not introduce ad
   hoc <details>, <dialog>, or bespoke tab markup elsewhere.             */
/* ------------------------------------------------------------------ */

/* Accordion */
.accordion-section {
    background: var(--bg-panel);
    border: var(--border-width) solid var(--border-color);
    border-radius: var(--border-radius-md);
    margin: 0 0 0.75rem 0;
    overflow: hidden;
}

/* Give the disclosure breathing room when it sits directly beneath its
   intro text (section label or helper paragraph). Panels lay out children
   by margin, not gap, and those text elements carry margin:0, so without
   this the accordion butts straight up against the copy above it. Scoped to
   the adjacency so it does not over-space accordions used in other layouts. */
.workspace-section-label + .accordion-section,
.admin-helper + .accordion-section {
    margin-top: var(--space-3);
}

.accordion-section-summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: 0.65rem 0.9rem;
    cursor: pointer;
    list-style: none;
    font-weight: 600;
    color: var(--text-primary);
}

.accordion-section-summary::-webkit-details-marker {
    display: none;
}

.accordion-section-summary:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
}

.accordion-section-summary:hover {
    background: var(--bg-panel-secondary);
}

.accordion-section-title-group {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-width: 0;
}

.accordion-section-title {
    overflow: hidden;
    text-overflow: ellipsis;
}

.accordion-section-meta {
    color: var(--text-muted);
    font-weight: 400;
    font-size: var(--font-size-md);
}

.accordion-section-chevron {
    transition: transform var(--duration-base) ease;
    color: var(--text-secondary);
    flex-shrink: 0;
}

.accordion-section[open] > .accordion-section-summary .accordion-section-chevron {
    transform: rotate(180deg);
}

.accordion-section-body {
    padding: 0.9rem;
    border-top: var(--border-width) solid var(--border-color);
    background: var(--bg-panel);
}

.accordion-section--compact .accordion-section-summary {
    padding: 0.45rem 0.7rem;
    font-size: var(--font-size-base);
}

.accordion-section--compact .accordion-section-body {
    padding: 0.6rem 0.7rem;
}

@media (prefers-reduced-motion: reduce) {
    .accordion-section-chevron {
        transition: none;
    }
}

/* Modal dialog (also covers the existing confirm-dialog uses) */
.modal-dialog,
.confirm-dialog {
    border: var(--border-width) solid var(--border-color);
    border-radius: var(--border-radius-lg);
    background: var(--bg-panel);
    color: var(--text-primary);
    padding: 0;
    max-width: min(560px, 92vw);
    width: 100%;
    box-shadow: 0 18px 40px rgba(0, 0, 0, 0.18);
}

.modal-dialog--wide {
    max-width: min(900px, 94vw);
}

.modal-dialog::backdrop,
.confirm-dialog::backdrop {
    background: rgba(15, 23, 42, 0.45);
}

.modal-dialog-inner,
.confirm-dialog-inner {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    padding: 1.1rem 1.2rem 1rem 1.2rem;
}

.modal-dialog-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-3);
}

.modal-dialog-title-group {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-width: 0;
}

.modal-dialog-title {
    margin: 0;
    font-size: 1.05rem;
    line-height: 1.3;
}

.modal-dialog-body {
    color: var(--text-secondary);
    font-size: var(--font-size-base);
    line-height: 1.5;
}

.modal-dialog-body p {
    margin: 0 0 0.6rem 0;
}

.modal-dialog-body p:last-child {
    margin-bottom: 0;
}

.modal-dialog-actions,
.confirm-dialog-actions {
    display: flex;
    justify-content: flex-end;
    gap: var(--space-2);
}

.modal-dialog-close {
    padding: 4px 8px;
    line-height: 1;
}

/*
 * Provenance drawer — a governed read-only evidence panel. It reuses
 * the native <dialog> primitive (focus trap, Escape / backdrop dismiss, focus
 * return via modal-dialog.js), restyled to dock to the right edge as a side
 * drawer rather than a centred modal. No state-changing control lives inside.
 */
.modal-dialog--drawer {
    max-width: min(440px, 96vw);
    width: 100%;
    max-height: 100vh;
    height: 100vh;
    margin: 0 0 0 auto;          /* dock to the right edge */
    border-radius: 0;
    border-top: 0;
    border-right: 0;
    border-bottom: 0;
    box-shadow: -18px 0 40px rgba(0, 0, 0, 0.18);
    transform: translateX(2%);
    opacity: 0;
    transition: transform 0.18s ease, opacity 0.18s ease;
}

.modal-dialog--drawer[open] {
    transform: translateX(0);
    opacity: 1;
}

.modal-dialog--drawer .modal-dialog-inner {
    height: 100%;
    overflow-y: auto;
}

@media (prefers-reduced-motion: reduce) {
    .modal-dialog--drawer {
        transition: none;
        transform: none;
    }
}

.provenance-lead {
    color: var(--text-secondary);
    font-size: var(--font-size-md);
}

.provenance-section {
    margin-top: var(--space-4);
}

.provenance-section-heading {
    margin: 0 0 var(--space-2) 0;
    font-size: var(--font-size-sm);
    font-weight: 700;
    letter-spacing: 0.02em;
    color: var(--text-secondary);
}

.provenance-timeline,
.provenance-decisions {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.provenance-event,
.provenance-decision {
    border-left: 2px solid var(--border-color);
    padding-left: var(--space-3);
}

.provenance-event-title,
.provenance-decision-title {
    margin: 0;
    font-weight: 600;
    color: var(--text-primary);
}

.provenance-event-meta {
    margin: 0.15rem 0 0 0;
    font-size: var(--font-size-xs);
    color: var(--text-secondary);
}

.provenance-event-detail,
.provenance-decision-reason {
    margin: 0.25rem 0 0 0;
    font-size: var(--font-size-md);
    color: var(--text-secondary);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.provenance-decisions-section .provenance-decision {
    border-left-color: var(--accent-color, var(--border-color));
}

.provenance-audit-link {
    margin-top: var(--space-4);
}

.provenance-trigger {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}

/* Tabbed panel */
.tabbed-panel {
    margin: 0 0 1rem 0;
}

.tabbed-panel-tablist {
    display: flex;
    gap: var(--space-1);
    border-bottom: var(--border-width) solid var(--border-color);
    flex-wrap: wrap;
}

.tabbed-panel-tab {
    background: transparent;
    color: var(--text-secondary);
    border: var(--border-width) solid transparent;
    border-bottom: none;
    border-top-left-radius: var(--border-radius-sm);
    border-top-right-radius: var(--border-radius-sm);
    padding: 0.5rem 0.85rem;
    font-weight: 600;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    position: relative;
    top: 1px;
}

.tabbed-panel-tab:hover {
    color: var(--text-primary);
    background: var(--bg-panel-secondary);
}

.tabbed-panel-tab[aria-selected="true"] {
    background: var(--bg-panel);
    color: var(--text-primary);
    border-color: var(--border-color);
    border-bottom-color: var(--bg-panel);
}

.tabbed-panel-tab:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
}

.tabbed-panel-tab-meta {
    color: var(--text-muted);
    font-weight: 400;
    font-size: var(--font-size-sm);
}

.tabbed-panel-panel {
    padding: 1rem 0;
}

.tabbed-panel-panel:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* Empty state */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--space-2);
    padding: 1.6rem 1rem;
    border: var(--border-width) dashed var(--border-color);
    border-radius: var(--border-radius-md);
    background: var(--bg-panel-secondary);
    color: var(--text-secondary);
}

.empty-state-icon {
    color: var(--text-muted);
    margin-bottom: var(--space-1);
}

.empty-state-heading {
    margin: 0;
    color: var(--text-primary);
    font-weight: 600;
}

.empty-state-message {
    margin: 0;
    max-width: 48ch;
    font-size: var(--font-size-base);
}

.empty-state-actions {
    margin-top: var(--space-2);
    display: inline-flex;
    gap: var(--space-2);
    flex-wrap: wrap;
    justify-content: center;
}

.empty-state--warning {
    border-color: color-mix(in srgb, var(--warning-text) 30%, transparent);
    background: color-mix(in srgb, var(--warning-bg) 70%, var(--bg-panel-secondary));
}

.empty-state--success {
    border-color: color-mix(in srgb, var(--accent) 30%, transparent);
}

/* Organisation branding governed components.
 *
 * Subtle organisation branding for candidate-facing and organisation-admin
 * surfaces. The brand band is the only place the configured primary colour is
 * applied, and only as a thin accent border — brand colours never replace
 * semantic system colours (success/warning/error/destructive).
 */

.organisation-brand-band {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: 0.65rem 1rem;
    background: var(--bg-panel-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius-md);
    border-left-width: 4px;
    border-left-color: var(--brand-primary, var(--accent));
    margin-bottom: var(--space-4);
}

.branding-preview-panel .organisation-brand-band {
    margin-top: var(--space-3);
}

/* Platform-mode Owner-column brand swatch: a small round dot in the owning
   organisation's primary brand colour, before the org name, so platform
   operators can scan owners at a glance across interleaved cross-org lists.
   The dot's colour is set per organisation by a nonce'd <style> rule
   (renderOwnerColumnSwatch() in includes/page.php); orgs with no brand colour
   render no swatch at all. Decorative — aria-hidden — the name is the label. */
.owner-swatch {
    display: inline-block;
    width: 0.65rem;
    height: 0.65rem;
    border-radius: 50%;
    margin-right: 0.45rem;
    vertical-align: baseline;
    border: 1px solid color-mix(in srgb, var(--border-color) 70%, transparent);
}

.organisation-brand-logo {
    height: 32px;
    width: auto;
    max-width: 160px;
    object-fit: contain;
}

.candidate-info-brand {
    display: flex;
    align-items: center;
    justify-self: start;
    min-height: 2.25rem;
    padding: var(--space-1) var(--space-2);
    border: var(--border-width) solid var(--sidebar-card-border, var(--border-color));
    border-radius: var(--border-radius-sm);
    background: var(--sidebar-card-bg, var(--bg-panel-secondary));
}

.candidate-info-brand-logo {
    display: block;
    width: auto;
    height: 1.75rem;
    max-width: 6rem;
    object-fit: contain;
    object-position: left center;
}

.organisation-brand-name {
    font-weight: 600;
    color: var(--text-primary);
    font-size: var(--font-size-base);
}

.organisation-brand-support {
    margin: 0.75rem 0 0;
    padding: 0.75rem 1rem;
    background: var(--bg-panel);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius-md);
    font-size: var(--font-size-md);
    color: var(--text-secondary);
}

.organisation-brand-help {
    margin: 0 0 0.5rem;
    color: var(--text-primary);
}

.organisation-brand-support-list {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 1rem;
}

.organisation-brand-footer {
    margin: 1rem 0 0;
    padding-top: 0.5rem;
    border-top: 1px solid var(--border-color);
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    text-align: center;
}

.branding-colour-preview {
    display: inline-block;
    width: 1.25rem;
    height: 1.25rem;
    border-radius: 0.25rem;
    border: 1px solid var(--border-color);
    vertical-align: middle;
    margin-right: 0.4rem;
}

.branding-field-errors {
    color: var(--error-text);
    margin: 0.25rem 0 0;
    font-size: var(--font-size-sm);
}

/* ─── Active organisation switcher ─────────────────────────────────────────── */

.page-nav-org {
    display: inline-flex;
    align-items: center;
    min-height: 2.5rem;
    padding: 0.55rem 0.9rem;
    border-radius: var(--border-radius-sm);
    background: var(--accent-subtle);
    font-size: var(--font-size-sm);
    font-weight: 600;
    color: var(--text-secondary);
    white-space: nowrap;
}

.page-nav-org-switcher {
    display: inline-flex;
    align-items: center;
}

.page-nav-org-switcher select {
    min-height: 2.5rem;
    max-width: 14rem;
    padding: 0 0.6rem;
    font-size: var(--font-size-sm);
}

.page-nav-org-logo {
    height: 1.4rem;
    width: auto;
    max-width: 2.4rem;
    object-fit: contain;
    margin-right: 0.4rem;
    vertical-align: middle;
}

/* Report charts: accessible, dependency-free SVG charts rendered by
   report_charts.js ALONGSIDE each report table (never replacing it —
   ARCH-COHORT-REPORTING). All colour comes from theme tokens so light/dark
   mode and theme switching work for free; there is no hard-coded colour here
   or in the JS. Charts are PART of the printed report: the @media print rules
   below switch to opaque high-contrast fills and suppress the tooltip and
   entrance transition, while the tables remain the exact-value reading. */
.report-chart {
    margin: var(--space-3) 0 var(--space-2);
    max-width: 640px;
}

.report-chart[data-chart-full-width="true"] {
    max-width: none;
    width: 100%;
}

/* Optional visible title/subtitle, emitted only where the surrounding panel
   does not already carry an equivalent heading (no duplicated card chrome —
   the report panel supplies the boundary). */
.report-chart-title {
    margin: 0 0 var(--space-1);
    color: var(--text-primary);
    font-weight: 600;
}

.report-chart-subtitle {
    margin: 0 0 var(--space-2);
    color: var(--text-secondary);
    font-size: var(--font-size-sm);
}

/* The plot wrapper is the chart's single keyboard interaction surface
   (tabindex + arrow keys, see report_charts.js) and the positioning context
   for the shared tooltip. */
.report-chart-plot {
    position: relative;
}

.report-chart-plot:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.report-chart-svg {
    display: block;
    width: 100%;
    /* Cap the rendered height so a sparse chart (one or two bars) never towers;
       the viewBox reserves space for labels, so no overflow is needed. */
    height: auto;
    max-height: 240px;
}

/* Brief decorative entrance only when the user has not asked for reduced
   motion; print gets the final frame immediately (see @media print below). */
@media (prefers-reduced-motion: no-preference) {
    .report-chart-svg {
        animation: report-chart-in var(--duration-base) var(--ease-standard);
    }
}

@keyframes report-chart-in {
    from { opacity: 0; }
    to { opacity: 1; }
}

/* Bars and the line/points take their colour from theme tokens: a translucent
   fill with a solid border for bars, outlined markers on the line. The neutral
   series uses --accent; pass/fail reinforces the table's pass/fail colours
   (never as the sole signal — the bars carry their own axis labels). */
.report-chart-bar {
    fill: color-mix(in srgb, var(--accent) 30%, transparent);
    stroke: var(--accent);
    stroke-width: 1.5;
}

.report-chart-track {
    fill: var(--bg-panel-secondary);
}

.report-chart-bar--pass {
    fill: color-mix(in srgb, var(--success-text) 30%, transparent);
    stroke: var(--success-text);
}

.report-chart-bar--fail {
    fill: color-mix(in srgb, var(--text-error) 30%, transparent);
    stroke: var(--text-error);
}

/* Stacked proportion track: the segments carry the SAME translucent fill and
   solid border as the bars, so the reporting surface reads as one chart
   family. Each segment's own border is what separates it from its neighbour,
   so no extra seam is needed. Share percentages are drawn inside wide-enough
   segments and every segment is named in the legend beneath the track, so no
   part is ever colour-only. */
.report-chart-segment {
    fill: color-mix(in srgb, var(--accent) 30%, transparent);
    stroke: var(--accent);
    stroke-width: 1.5;
}

.report-chart-segment.report-chart-bar--pass {
    fill: color-mix(in srgb, var(--success-text) 30%, transparent);
    stroke: var(--success-text);
}

.report-chart-segment.report-chart-bar--fail {
    fill: color-mix(in srgb, var(--text-error) 30%, transparent);
    stroke: var(--text-error);
}

/* The share sits on the same translucent fill the bars use, so it takes the
   ordinary body text colour like every other chart value label. */
.report-chart-segment-label {
    fill: var(--text-primary);
    font-size: var(--font-size-xs);
    font-weight: 600;
    font-family: inherit;
}

.report-chart-legend-swatch {
    fill: color-mix(in srgb, var(--accent) 30%, transparent);
    stroke: var(--accent);
    stroke-width: 1;
}

.report-chart-legend-swatch.report-chart-bar--pass {
    fill: color-mix(in srgb, var(--success-text) 30%, transparent);
    stroke: var(--success-text);
}

.report-chart-legend-swatch.report-chart-bar--fail {
    fill: color-mix(in srgb, var(--text-error) 30%, transparent);
    stroke: var(--text-error);
}

.report-chart-mark--active .report-chart-segment {
    stroke: var(--text-primary);
    stroke-width: 2.5;
}

.report-chart-line {
    fill: none;
    stroke: var(--accent);
    stroke-width: 2.5;
    stroke-linejoin: round;
    stroke-linecap: round;
}

.report-chart-point {
    fill: var(--bg-panel);
    stroke: var(--accent);
    stroke-width: 2;
}

/* Exact zero values have no bar height. An outlined baseline marker makes
   them intentional and keeps them visually distinct from missing data. */
.report-chart-zero-marker {
    fill: var(--bg-panel);
    stroke: var(--accent);
    stroke-width: 2;
}

/* Keyboard/hover highlight: a stronger border on the active mark. Meaning is
   never colour-only — the tooltip and live region carry the label and value. */
.report-chart-mark--active .report-chart-bar,
.report-chart-mark--active .report-chart-point,
.report-chart-mark--active .report-chart-zero-marker {
    stroke-width: 3;
}

.report-chart-axis {
    stroke: var(--text-muted);
    stroke-width: 1;
}

.report-chart-axis-tick {
    stroke: var(--text-muted);
    stroke-width: 1;
}

.report-chart-grid-line {
    stroke: var(--border-color);
    stroke-width: 1;
}

.report-chart-y-axis-label {
    fill: var(--text-secondary);
    font-family: inherit;
    font-size: var(--font-size-xs);
}

.report-chart-axis-label {
    fill: var(--text-secondary);
    font-size: var(--font-size-xs);
    font-family: inherit;
}

/* The one shared tooltip per chart: absolutely positioned inside the plot (no
   layout movement), pointer-events off so it never traps the pointer. The same
   content is announced by the chart's live region on keyboard movement. */
.report-chart-tooltip {
    position: absolute;
    z-index: 5;
    max-width: 16rem;
    padding: var(--space-1) var(--space-2);
    border: var(--border-width) solid var(--border-color);
    border-radius: var(--border-radius-sm);
    background: var(--bg-panel);
    color: var(--text-primary);
    font-size: var(--font-size-sm);
    box-shadow: var(--elevation-2);
    pointer-events: none;
    white-space: nowrap;
}

.question-performance-number,
.question-performance-text {
    display: block;
}

.question-performance-number {
    margin-bottom: 0.2rem;
    color: var(--text-muted);
    font-size: var(--font-size-xs);
    font-weight: 600;
}

.question-performance-text {
    color: var(--text-primary);
    font-weight: 400;
    line-height: 1.4;
}

/* On-bar / on-point value annotation so the chart reads without the table. */
.report-chart-value-label {
    fill: var(--text-primary);
    font-size: var(--font-size-xs);
    font-weight: 600;
    font-family: inherit;
}

/* Printed charts (both report pages): keep each chart together and within the
   page width, drop the tooltip/interaction affordances and the entrance
   transition, and switch to opaque high-contrast fills so colour and
   monochrome printouts both stay legible (solid fill + dark border; bar vs
   line geometry and the axis labels carry the series identity without
   colour). The adjacent tables remain the exact-value reading. */
@media print {
    .report-chart {
        display: block;
        width: 100%;
        max-width: none;
        break-inside: avoid;
        page-break-inside: avoid;
    }

    .report-chart-svg {
        width: 100%;
        height: auto;
        max-height: 190pt;
        animation: none;
    }

    .report-chart-tooltip {
        display: none !important;
    }

    .report-chart-plot:focus-visible {
        outline: none;
    }

    .report-chart-bar {
        fill: var(--accent);
        stroke: var(--text-primary);
        stroke-width: 1;
    }

    .report-chart-bar--pass {
        fill: var(--success-text);
        stroke: var(--text-primary);
    }

    .report-chart-bar--fail {
        fill: var(--text-error);
        stroke: var(--text-primary);
    }

    /* Print goes opaque for paper contrast (the pass/fail rules above already
       supply the fill); the ink-coloured border is what keeps two adjacent
       shares distinguishable where hue may not survive a greyscale printer. */
    .report-chart-segment {
        stroke: var(--text-primary);
        stroke-width: 1;
    }

    /* On the opaque print fills the share sits on a saturated colour. */
    .report-chart-segment-label {
        fill: var(--text-on-accent);
    }

    .report-chart-point {
        stroke: var(--text-primary);
    }

    .report-chart-zero-marker {
        fill: var(--bg-panel);
        stroke: var(--text-primary);
    }

    .report-chart-line {
        stroke: var(--text-primary);
    }
}

/* Session-report print layout: constrain the wide tables to the page. */
@media print {
    .page-main.session-report-view {
        display: block;
        width: 100%;
        max-width: none;
        margin: 0;
        padding: 0;
    }

    .session-report-view .report-layout {
        display: block;
        width: 100%;
    }

    .session-report-view .candidate-shell-card {
        width: 100%;
        margin: 0 0 10pt;
        padding: 10pt;
    }

    .session-report-view .admin-table-wrap {
        overflow: visible;
    }

    .session-report-view .candidate-table {
        width: 100%;
        min-width: 0;
        max-width: 100%;
        table-layout: fixed;
        /* Compact print tables: 0.8em is the smallest permitted relative size
           (typography scale — px/pt font sizes are banned in stylesheets). */
        font-size: 0.8em;
        line-height: 1.25;
    }

    .session-report-view .candidate-table th,
    .session-report-view .candidate-table td {
        box-sizing: border-box;
        padding: 4pt;
        overflow-wrap: anywhere;
        word-break: normal;
    }

    .session-report-view .candidate-table thead th {
        white-space: normal;
        hyphens: auto;
        line-height: 1.15;
    }

    .session-report-view .candidate-table thead {
        display: table-header-group;
    }

    .session-report-view .candidate-table tr {
        break-inside: avoid;
        page-break-inside: avoid;
    }

    .session-report-view .question-performance-table th:first-child,
    .session-report-view .question-performance-table td:first-child {
        width: 42%;
    }

    .session-report-view .question-performance-table th:not(:first-child),
    .session-report-view .question-performance-table td:not(:first-child) {
        /* Six result/detail columns share the 58% left after Question. */
        width: calc(58% / 6);
    }

    .session-report-view .category-performance-table th:first-child,
    .session-report-view .category-performance-table td:first-child {
        width: 34%;
    }

    .session-report-view .category-performance-table th:not(:first-child),
    .session-report-view .category-performance-table td:not(:first-child) {
        /* Six numeric/detail columns share the 66% left after Category. */
        width: 11%;
    }

    .session-report-view .question-performance-text {
        /* Compact print text: 0.8em is the smallest permitted relative size
           (typography scale — px/pt font sizes are banned in stylesheets). */
        font-size: 0.8em;
        line-height: 1.3;
    }

    .session-report-view .report-stats-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 8pt;
    }
}
