/* Concordance module styling.

   Everything here is expressed in Fluent design tokens rather than fixed colours, so the
   report follows the theme the user picked — including dark mode — without a second
   palette to keep in step. The agreement bands are mixed from the Fluent status colours
   for the same reason.

   Text sizes come from four aliases rather than from the ramp directly. Reaching for
   --type-ramp-* at each call site is how the app ended up with tables at three different
   sizes; changing a role here changes every place that plays that role. */

:root {
    --qch-text-heading: var(--type-ramp-plus-2-font-size);
    --qch-text-subheading: var(--type-ramp-plus-1-font-size);
    --qch-text-body: var(--type-ramp-base-font-size);
    --qch-text-support: var(--type-ramp-minus-1-font-size);
    --qch-text-micro: var(--type-ramp-minus-2-font-size);

    /* The one deliberately oversized role: a figure meant to be read across the room. */
    --qch-text-display: var(--type-ramp-plus-3-font-size);
}

.concordance,
.home {
    max-width: 1500px;
}

.lead {
    color: var(--neutral-foreground-hint);
    font-size: var(--qch-text-body);
}

.page-header {
    margin-bottom: 1rem;
}

/* Screen-reader-only text. It is taken out of flow, so it must also be pinned: left to its
   static position it sits wherever it happens to fall, and inside a tall scrolling pane that
   was far enough down the page to give the whole document a second scrollbar.
   `clip-path` is the current spelling; `clip` stays for older engines. */
.visually-hidden {
    position: absolute;
    top: 0;
    left: 0;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
}

.plain-list {
    margin: 0;
    padding-left: 1.1rem;
}

.hint,
.status {
    color: var(--neutral-foreground-hint);
    font-size: var(--qch-text-support);
    margin: 0;
}

.empty-note {
    color: var(--neutral-foreground-hint);
    font-style: italic;
}

/* ---- Home ------------------------------------------------------------------ */

.module-cards {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
    gap: 1rem;
    margin: 1.5rem 0;
}

.module-card {
    padding: 0;
}

.module-link {
    display: grid;
    gap: 0.3rem;
    padding: 1.25rem;
    text-decoration: none;
    color: inherit;
}

.module-name {
    font-size: var(--qch-text-subheading);
    font-weight: 600;
}

.module-description {
    color: var(--neutral-foreground-hint);
    font-size: var(--qch-text-support);
}

/* ---- Panels ---------------------------------------------------------------- */

.upload-panel,
.archive-bar,
.options-card,
.dashboard-panel,
.trend-card,
.individual-headline {
    padding: 1.25rem;
}

.upload-panel {
    margin: 1.25rem 0;
    display: grid;
    gap: 1rem;
}

/* The round kind sits above the dropzone because it changes what the uploaded files mean.
   Native radios rather than Fluent ones: the group has to work as a group, and the Fluent
   radio group only manages radios that are its own direct children. */
.round-kind {
    display: grid;
    gap: 0.5rem;
    margin: 0;
    padding: 0.75rem 1rem;
    border: calc(var(--stroke-width) * 1px) solid var(--neutral-stroke-divider-rest);
    border-radius: calc(var(--control-corner-radius) * 1px);
}

.round-kind legend {
    padding: 0 0.35rem;
    font-size: var(--qch-text-support);
    color: var(--neutral-foreground-hint);
}

.round-kind label {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.5rem;
    align-items: start;
    cursor: pointer;
}

.round-kind label span {
    display: grid;
    gap: 0.1rem;
    font-size: var(--qch-text-support);
    color: var(--neutral-foreground-hint);
}

.round-kind label strong {
    font-size: var(--qch-text-body);
    color: var(--neutral-foreground-rest);
}

.round-kind input {
    margin-top: 0.25rem;
}

.round-kind-badge {
    margin-left: 0.4rem;
    vertical-align: middle;
}

.dropzone {
    display: block;
}

.dropzone-text {
    display: grid;
    gap: 0.2rem;
    margin-top: 0.4rem;
    color: var(--neutral-foreground-hint);
    font-size: var(--qch-text-support);
}

.file-table .name-input {
    min-width: 11rem;
    width: 100%;
}

.file-table .file-name {
    color: var(--neutral-foreground-hint);
    font-size: var(--qch-text-support);
}

.file-table tr.is-gold th,
.file-table tr.is-gold td {
    background: color-mix(in srgb, var(--warning) 10%, transparent);
}

.actions {
    margin-top: 0.5rem;
}

/* ---- Settings -------------------------------------------------------------- */

.options-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
    gap: 1rem;
    padding: 0.5rem 0 1rem;
}

.options-card h4 {
    margin: 0 0 0.75rem;
    font-size: var(--qch-text-support);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--neutral-foreground-hint);
}

.options-card > .fluent-select,
.options-card > fluent-number-field,
.options-card > fluent-text-field,
.options-card > fluent-checkbox,
.options-card .field-pair,
.options-card .check-list {
    margin-bottom: 0.85rem;
    width: 100%;
}

.field-pair {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.75rem;
}

.check-list {
    display: grid;
    gap: 0.3rem;
}

.field-note,
.section-note,
.row-note,
.matrix-caption {
    color: var(--neutral-foreground-hint);
    font-size: var(--qch-text-support);
    font-weight: 400;
    line-height: 1.45;
}

.field-note {
    margin: 0 0 0.9rem;
}

.section-note {
    margin-bottom: 1rem;
}

.options-actions {
    padding: 0.5rem 0 0.25rem;
}

.inline-select {
    min-width: 13rem;
}

/* Only the native selects — the ones in the People table, which are plain elements so their
   popup escapes that table's scroll container. The Fluent selects elsewhere share the class
   for its width but bring their own appearance, and must not be restyled here. */
select.inline-select {
    /* Sized for a dense table row, not for a form: these sit beside single lines of text. */
    height: 1.75rem;
    padding: 0 0.4rem;
    font-family: inherit;
    font-size: var(--qch-text-body);
    color: var(--neutral-foreground-rest);
    background-color: var(--neutral-fill-input-rest);
    border: calc(var(--stroke-width) * 1px) solid var(--neutral-stroke-input-rest);
    border-radius: calc(var(--control-corner-radius) * 1px);
}

select.inline-select:hover:not(:disabled) {
    border-color: var(--neutral-stroke-input-hover);
}

select.inline-select:focus-visible {
    outline: calc(var(--focus-stroke-width) * 1px) solid var(--accent-fill-rest);
    outline-offset: -1px;
}

select.inline-select:disabled {
    opacity: var(--disabled-opacity);
    cursor: not-allowed;
}

/* The options themselves are painted by the operating system, which does not read our
   tokens — so the popup needs explicit colours or it renders light in a dark theme. */
select.inline-select option {
    color: var(--neutral-foreground-rest);
    background-color: var(--neutral-layer-1);
}

.trend-controls {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;
    max-width: none;
}

/* ---- Report ---------------------------------------------------------------- */

.report-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1rem;
    flex-wrap: wrap;
    margin-top: 1.5rem;
    padding-bottom: 0.75rem;
    border-bottom: calc(var(--stroke-width) * 2px) solid var(--neutral-stroke-divider-rest);
}

.report-meta {
    color: var(--neutral-foreground-hint);
    font-size: var(--qch-text-support);
    margin: 0.35rem 0 0;
}

.archive-bar {
    display: flex;
    align-items: flex-end;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin-top: 1rem;
}

.archive-bar .round-name {
    min-width: 16rem;
}

.archive-note {
    color: var(--neutral-foreground-hint);
    font-size: var(--qch-text-support);
    padding-bottom: 0.4rem;
}

.report-tabs {
    margin-top: 1.25rem;
}

.report-section {
    margin: 2rem 0;
    break-inside: avoid;
}

.report-section h3 {
    font-size: var(--qch-text-heading);
    border-bottom: calc(var(--stroke-width) * 1px) solid var(--neutral-stroke-divider-rest);
    padding-bottom: 0.35rem;
}

.report-section h4 {
    font-size: var(--qch-text-subheading);
    margin-top: 1.5rem;
    margin-bottom: 0.5rem;
    color: var(--neutral-foreground-hint);
}

.report-section h5 {
    font-size: var(--qch-text-body);
    margin-top: 1rem;
    margin-bottom: 0.35rem;
}

.detail-block {
    margin-top: 1.25rem;
}

/* ---- Tables ---------------------------------------------------------------- */

.table-scroll {
    overflow-x: auto;
    max-width: 100%;
}

/* Hand-built rather than a data grid: the report tables carry multi-level headers,
   spanned cells and a square agreement matrix, none of which a column-based grid
   expresses. They take their colours from the same tokens as the Fluent components. */
.report-table {
    width: 100%;
    /* Never narrower than its contents. A dozen scorers is two columns each, and without
       this the browser crushes the columns to fit rather than letting the wrapper scroll. */
    min-width: max-content;
    border-collapse: collapse;
    font-size: var(--qch-text-support);
    color: var(--neutral-foreground-rest);
}

.report-table th,
.report-table td {
    padding: 0.4rem 0.6rem;
    border: calc(var(--stroke-width) * 1px) solid var(--neutral-stroke-divider-rest);
    text-align: left;
    /* Centred, not top-aligned: rows mix plain text with text fields, buttons and badges of
       different heights, and top alignment left the short ones floating above the controls. */
    vertical-align: middle;
}

.report-table thead th {
    background: var(--neutral-layer-3);
    font-weight: 600;
    white-space: nowrap;
    /* Cells that span both header rows would otherwise sit at the top of a hollow box,
       out of line with the sub-headers next to them. */
    vertical-align: middle;
}

.report-table .numeric {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.report-table .strong {
    font-weight: 700;
}

.report-table .reference-row th,
.report-table .reference-row td {
    background: color-mix(in srgb, var(--warning) 10%, transparent);
    color: var(--neutral-foreground-hint);
}

.report-table .total-row th,
.report-table .total-row td {
    border-top: calc(var(--stroke-width) * 2px) solid var(--neutral-stroke-strong-rest);
    font-weight: 600;
}

.report-table .detection-row th,
.report-table .detection-row td {
    background: var(--neutral-layer-2);
    font-weight: 400;
}

.report-table .scorer-group {
    text-align: center;
    border-bottom: none;
}

/* The reference column is grouped like a scorer but tinted like the GOLD rows. */
.report-table .reference-group {
    background: color-mix(in srgb, var(--warning) 14%, var(--neutral-layer-3));
}

.report-table .rank {
    color: var(--neutral-foreground-hint);
    width: 2rem;
}

.row-note {
    display: block;
    font-weight: 400;
}

.row-actions {
    white-space: nowrap;
}

.report-table .row-actions {
    vertical-align: middle;
}

/* The flex sits on a wrapper inside the cell, not on the cell itself: a flex <td> stops
   being a table cell and no longer stretches with the row. */
.action-group {
    display: flex;
    align-items: center;
    gap: 0.25rem;
}

.delta {
    display: inline-block;
    margin-left: 0.35rem;
    color: var(--neutral-foreground-hint);
    font-size: var(--qch-text-micro);
}

.settings-cell {
    font-size: var(--qch-text-support);
    color: var(--neutral-foreground-hint);
    max-width: 24rem;
}

/* Agreement bands, mixed from the Fluent status colours so they read in either theme. */
.band-high { background: color-mix(in srgb, var(--success) 22%, transparent); }
.band-good { background: color-mix(in srgb, var(--success) 12%, transparent); }
.band-fair { background: color-mix(in srgb, var(--warning) 18%, transparent); }
.band-low  { background: color-mix(in srgb, var(--error) 18%, transparent); }
.band-none { color: var(--neutral-foreground-hint); }

.matrix-table {
    width: auto;
    min-width: 22rem;
}

.matrix-caption {
    caption-side: top;
    text-align: left;
    padding-bottom: 0.35rem;
}

.matrix-table .cell-agree {
    background: color-mix(in srgb, var(--success) 16%, transparent);
    font-weight: 600;
}

.matrix-table .cell-disagree-slight { background: color-mix(in srgb, var(--error) 7%, transparent); }
.matrix-table .cell-disagree { background: color-mix(in srgb, var(--error) 16%, transparent); }
.matrix-table .cell-disagree-strong { background: color-mix(in srgb, var(--error) 30%, transparent); }
.matrix-table .cell-empty { color: var(--neutral-stroke-divider-rest); }

.matrix-table .matrix-total td,
.matrix-table .matrix-total th {
    background: var(--neutral-layer-3);
}

/* ---- Scorer labels and legend ---------------------------------------------- */

.scorer-label {
    cursor: help;
    border-bottom: 1px dotted var(--neutral-stroke-rest);
}

.heading-initials {
    display: inline-block;
    padding: 0.05rem 0.4rem;
    border: calc(var(--stroke-width) * 1px) solid var(--neutral-stroke-divider-rest);
    border-radius: calc(var(--control-corner-radius) * 1px);
    background: var(--neutral-layer-3);
    font-size: var(--qch-text-micro);
    font-weight: 600;
    color: var(--neutral-foreground-hint);
}

.scorer-chips {
    display: flex;
    gap: 0.2rem;
    flex-wrap: wrap;
}

.scorer-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 1.1rem;
    font-size: var(--qch-text-support);
    margin: 0 0 1.25rem;
    padding: 0.6rem 0.9rem;
    border: calc(var(--stroke-width) * 1px) solid var(--neutral-stroke-divider-rest);
    border-radius: calc(var(--layer-corner-radius) * 1px);
    background: var(--neutral-layer-2);
}

.legend-entry {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
}

.legend-entry dt {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.legend-entry dd {
    margin: 0;
    color: var(--neutral-foreground-hint);
}

.legend-gold dd {
    color: var(--warning);
}

.legend-role {
    font-size: var(--qch-text-micro);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

/* ---- Hypnogram ------------------------------------------------------------- */

.hypnogram {
    margin-bottom: 1.25rem;
    break-inside: avoid;
}

.hypnogram-heading {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    margin-bottom: 0.2rem;
}

.hypnogram-title {
    font-weight: 600;
    font-size: var(--qch-text-support);
}

.hypnogram-subtitle {
    color: var(--neutral-foreground-hint);
    font-size: var(--qch-text-micro);
}

.hypnogram-body {
    display: flex;
    align-items: stretch;
    gap: 0.5rem;
}

.hypnogram-axis {
    display: flex;
    flex-direction: column;
    width: 2.6rem;
    flex: none;
    font-size: var(--qch-text-micro);
    color: var(--neutral-foreground-hint);
}

.hypnogram-axis > span {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: flex-end;
}

.hypnogram-axis-strip {
    height: 10px;
}

.hypnogram-plot,
.hypnogram-strip,
.trend-chart {
    flex: 1;
    min-width: 0;
    border: calc(var(--stroke-width) * 1px) solid var(--neutral-stroke-divider-rest);
    background: var(--neutral-layer-1);
}

.hypnogram-strip {
    height: 10px;
    border-top: none;
}

.hypnogram-gridline,
.trend-gridline {
    stroke: var(--neutral-stroke-divider-rest);
    stroke-width: 1;
    stroke-dasharray: 2 3;
}

.hypnogram-trace {
    fill: none;
    stroke: var(--neutral-foreground-rest);
    stroke-width: 1.5;
}

.hypnogram-rem {
    stroke: var(--error);
    stroke-width: 3;
}

.hypnogram-disagreement {
    fill: var(--error);
}

/* ---- Trends ----------------------------------------------------------------- */

.trend-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(23rem, 1fr));
    gap: 1rem;
}

.trend-card {
    break-inside: avoid;
}

.trend-card > header {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    margin-bottom: 0.6rem;
}

.trend-initials,
.individual-initials {
    padding: 0.1rem 0.45rem;
    border-radius: calc(var(--control-corner-radius) * 1px);
    /* Neutral, not the theme accent: scientists are blue, and an accent-blue chip for someone
       with no discipline set would read as a group they are not in. */
    background: var(--neutral-fill-strong-rest);
    color: var(--neutral-fill-inverse-rest);
    font-weight: 700;
}

/* Initials carry the scorer's discipline wherever they appear — the trend cards, the
   individual sheet, and the dashboard chips — so a reader can tell the groups apart without
   looking anyone up. Solid fills here, unlike the table tints, because these are small and
   sit on varied backgrounds.

   The dashboard chips are Fluent badges, which paint a pill inside a shadow root; colouring
   the host leaves that pill sitting on top in its own grey, so those go through ::part. */
/* Fluent's neutral badge draws a light outline meant to separate a pale pill from the page.
   Over a solid discipline colour it reads as a halo, so it comes off. */
.chip::part(control) {
    border: none;
    box-shadow: none;
    outline: none;
}

/* The badge host would otherwise pick up the flat discipline tint from the rule above and
   show it around the pill's rounded corners. Only the pill should carry colour here. */
.chip:is(.discipline-scientist, .discipline-doctor, .discipline-nursing) {
    background: transparent;
}

.trend-initials.discipline-scientist,
.individual-initials.discipline-scientist,
.chip.discipline-scientist::part(control) {
    background: var(--discipline-scientist-solid);
    color: #fff;
}

.trend-initials.discipline-doctor,
.individual-initials.discipline-doctor,
.chip.discipline-doctor::part(control) {
    background: var(--discipline-doctor-solid);
    color: #fff;
}

.trend-initials.discipline-nursing,
.individual-initials.discipline-nursing,
.chip.discipline-nursing::part(control) {
    background: var(--discipline-nursing-solid);
    color: #fff;
}

.trend-initials {
    font-size: var(--qch-text-micro);
}

.trend-name {
    font-weight: 600;
}

.trend-rounds {
    margin-left: auto;
    color: var(--neutral-foreground-hint);
    font-size: var(--qch-text-micro);
}

.trend-body {
    display: flex;
    gap: 0.4rem;
}

.trend-axis {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    width: 2.4rem;
    flex: none;
    font-size: var(--qch-text-micro);
    color: var(--neutral-foreground-hint);
    text-align: right;
}

.trend-line {
    fill: none;
    stroke: var(--accent-fill-rest);
    stroke-width: 1.5;
}

.trend-point {
    fill: var(--accent-fill-rest);
    stroke: var(--neutral-layer-1);
    stroke-width: 1;
}

.trend-empty {
    color: var(--neutral-foreground-hint);
    font-size: var(--qch-text-support);
    font-style: italic;
}

.trend-figures {
    display: flex;
    gap: 1.25rem;
    margin: 0.7rem 0 0;
}

.trend-figures div {
    display: grid;
    gap: 0.1rem;
}

.trend-figures dt {
    font-size: var(--qch-text-micro);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--neutral-foreground-hint);
}

.trend-figures dd {
    margin: 0;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    padding: 0 0.25rem;
    border-radius: calc(var(--control-corner-radius) * 1px);
}

.change-up { color: var(--success); }
.change-down { color: var(--error); }
.change-none { color: var(--neutral-foreground-hint); }

/* ---- Individual report ------------------------------------------------------ */

.individual-headline {
    margin-bottom: 1.5rem;
}

.individual-identity {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 1rem;
}

.individual-identity h3 {
    margin: 0;
    font-size: var(--qch-text-heading);
}

.individual-initials {
    font-size: var(--qch-text-heading);
    padding: 0.25rem 0.6rem;
}

.individual-meta {
    color: var(--neutral-foreground-hint);
    font-size: var(--qch-text-support);
}

.individual-position {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin: 1rem 0 0;
    padding-top: 0.75rem;
    border-top: calc(var(--stroke-width) * 1px) solid var(--neutral-stroke-divider-rest);
    color: var(--neutral-foreground-hint);
    font-size: var(--qch-text-support);
}

/* ---- Dashboard --------------------------------------------------------------- */

.dashboard {
    margin-top: 2rem;
}

.dashboard-heading {
    display: flex;
    align-items: baseline;
    gap: 0.75rem;
    flex-wrap: wrap;
    border-bottom: calc(var(--stroke-width) * 2px) solid var(--neutral-stroke-divider-rest);
    padding-bottom: 0.4rem;
}

.dashboard-scope {
    color: var(--neutral-foreground-hint);
    font-size: var(--qch-text-support);
}

.dashboard-empty {
    margin-top: 2rem;
}

.stat-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    gap: 0.75rem;
    margin: 1.25rem 0;
}

.stat-tile {
    display: grid;
    gap: 0.2rem;
    padding: 0.9rem 1rem;
    align-content: start;
}

.stat-value {
    font-size: var(--qch-text-display);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    border-radius: calc(var(--control-corner-radius) * 1px);
    padding: 0 0.2rem;
    justify-self: start;
}

.stat-label {
    font-size: var(--qch-text-support);
    color: var(--neutral-foreground-hint);
    line-height: 1.3;
}

.stat-sub {
    font-size: var(--qch-text-micro);
    color: var(--neutral-foreground-hint);
}

.dashboard-columns {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(25rem, 1fr));
    gap: 1rem;
    align-items: start;
}

.dashboard-panel h3 {
    margin-top: 0;
    font-size: var(--qch-text-subheading);
}

.round-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.round-list li {
    padding: 0.55rem 0;
    border-top: calc(var(--stroke-width) * 1px) solid var(--neutral-stroke-divider-rest);
}

.round-list li:first-child {
    border-top: none;
}

.round-title {
    display: flex;
    justify-content: space-between;
    gap: 0.5rem;
    font-weight: 500;
}

.round-date {
    color: var(--neutral-foreground-hint);
    font-size: var(--qch-text-support);
    font-weight: 400;
}

.round-detail {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-top: 0.3rem;
}

.round-median {
    padding: 0.05rem 0.4rem;
    border-radius: calc(var(--control-corner-radius) * 1px);
    font-size: var(--qch-text-support);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.diagnostic-list {
    margin: 0.5rem 0 0;
    padding: 0;
    list-style: none;
    font-size: var(--qch-text-support);
}

.diagnostic-list li {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    padding: 0.35rem 0;
    border-top: calc(var(--stroke-width) * 1px) solid var(--neutral-stroke-divider-rest);
}

.diagnostic-source {
    min-width: 7rem;
    font-weight: 600;
    color: var(--neutral-foreground-hint);
}

.diagnostic-warning .diagnostic-message { color: var(--warning); }
.diagnostic-error .diagnostic-message { color: var(--error); }

/* ---- Print ----------------------------------------------------------------- */

@media print {
    .no-print,
    .upload-panel,
    .archive-bar {
        display: none !important;
    }

    /* Inner scroll boxes clip to their own height on paper, so they are released too. The
       detail tables in particular are tall by design and must be allowed to run over pages. */
    .table-scroll,
    .detail-scroll {
        max-height: none !important;
        overflow: visible !important;
    }

    .report-table {
        min-width: 0 !important;
    }

    /* A sticky header repeats over the viewport, not the page; the table header does the
       right thing on paper on its own. */
    .detail-table thead th {
        position: static !important;
    }

    /* Collapsed sections stay collapsed, but an opened one must print its contents. */
    fluent-accordion-item[expanded] {
        display: block !important;
    }

    /* Only the open tab is printed, so an individual's sheet prints on its own. */
    fluent-tab,
    fluent-tab-panel[hidden] {
        display: none !important;
    }

    .report-section,
    .hypnogram,
    .report-table,
    .trend-card,
    .individual-headline {
        break-inside: avoid;
    }

    .report-table th,
    .report-table td {
        border-color: #999;
    }

    a[href]::after {
        content: none;
    }
}

/* ---- Sign in ---------------------------------------------------------------- */

/* Fixed rather than a grid inside the normal flow: the sign-in page has no navigation, and
   the layout's other children (the theme element, the error banner) were taking part in the
   centring and pushing the card off to one side. */
.bare-layout {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--neutral-layer-2);
    padding: 2rem 1rem;
    overflow: auto;
}

/* The page wrapper stretches to the layout's full width, so it has to do the centring
   itself — the layout centring only positions this wrapper, not the card inside it. */
.login-page {
    display: flex;
    justify-content: center;
    width: 100%;
}

.login-card {
    width: min(26rem, 100%);
    padding: 2rem;
    display: grid;
    gap: 0.75rem;
}

.login-card h1 {
    margin: 0;
    font-size: var(--qch-text-display);
}

.login-form {
    display: grid;
    gap: 0.9rem;
    margin-top: 0.5rem;
}

.login-form label {
    display: grid;
    gap: 0.3rem;
    font-size: var(--qch-text-support);
    font-weight: 500;
}

.login-form input {
    padding: 0.5rem 0.6rem;
    border: calc(var(--stroke-width) * 1px) solid var(--neutral-stroke-rest);
    border-radius: calc(var(--control-corner-radius) * 1px);
    background: var(--neutral-fill-input-rest);
    color: var(--neutral-foreground-rest);
    font: inherit;
}

.login-form input:focus-visible {
    outline: calc(var(--focus-stroke-width) * 1px) solid var(--accent-fill-rest);
    outline-offset: 1px;
}

.login-submit,
.logout-button {
    font: inherit;
    cursor: pointer;
    border: none;
    border-radius: calc(var(--control-corner-radius) * 1px);
    background: var(--accent-fill-rest);
    color: var(--foreground-on-accent-rest);
    padding: 0.55rem 1rem;
}

.login-submit:hover,
.logout-button:hover {
    background: var(--accent-fill-hover);
}

.login-note {
    color: var(--neutral-foreground-hint);
    font-size: var(--qch-text-support);
    margin: 0.5rem 0 0;
}

/* ---- Identity in the header -------------------------------------------------- */

.signed-in-as {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: var(--qch-text-support);
}

.role-badge {
    margin-left: 0.2rem;
}

.logout-form {
    display: inline;
}

/* A button, not underlined text: signing out is an action and should look like the other
   controls in the header rather than like a link. */
.logout-button {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    background: var(--neutral-fill-stealth-rest);
    color: var(--neutral-foreground-rest);
    border: calc(var(--stroke-width) * 1px) solid var(--neutral-stroke-rest);
    padding: 0.3rem 0.75rem;
    font-size: var(--qch-text-support);
    text-decoration: none;
    white-space: nowrap;
}

.logout-button:hover {
    background: var(--neutral-fill-stealth-hover);
}

.narrow {
    max-width: 44rem;
}

.full-width {
    width: 100%;
    margin-bottom: 0.85rem;
}

.disabled-row th,
.disabled-row td {
    opacity: 0.55;
}

/* ---- Detail tables ----------------------------------------------------------- */

.detail-controls {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 0.75rem;
}

.detail-scroll {
    max-height: 32rem;
    overflow: auto;
    border: calc(var(--stroke-width) * 1px) solid var(--neutral-stroke-divider-rest);
    border-radius: calc(var(--layer-corner-radius) * 1px);
}

/* The same size as every other table: detail views were a step smaller, which made
   the report look like two applications stitched together. */
.detail-table {
    font-size: var(--qch-text-support);
}

/* The header has to stay put: these tables are read by scrolling to a time of night. */
.detail-table thead th {
    position: sticky;
    top: 0;
    z-index: 1;
}

.detail-table .stage-cell {
    text-align: center;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}

.detail-table .reference-cell {
    background: color-mix(in srgb, var(--warning) 10%, transparent);
    font-weight: 600;
}

.detail-table .not-scored {
    color: var(--neutral-foreground-hint);
}

.detail-table .empty-cell {
    text-align: center;
    color: var(--neutral-foreground-hint);
    font-style: italic;
    padding: 1rem;
}

.detail-table .addition-row .reference-cell {
    background: color-mix(in srgb, var(--error) 8%, transparent);
}

.detail-table .missed-row th,
.detail-table .missed-row td {
    background: color-mix(in srgb, var(--error) 6%, transparent);
}

/* The Fluent message bar keeps a light tinted background in both themes, so it needs a dark
   foreground of its own — the shell's inherited light text disappears against it. */
.fluent-messagebar,
.fluent-messagebar * {
    color: #1c2733;
}

.fluent-messagebar a,
.fluent-messagebar fluent-anchor::part(control) {
    color: #0f4c8c;
}

/* ---- Event bands ------------------------------------------------------------- */

.band-chart {
    margin: 0 0 1.5rem;
    break-inside: avoid;
}

.band-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem 1rem;
    margin-bottom: 0.5rem;
    font-size: var(--qch-text-micro);
    color: var(--neutral-foreground-hint);
}

.band-key {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
}

.band-swatch {
    width: 0.85rem;
    height: 0.65rem;
    border-radius: 2px;
    display: inline-block;
}

.band-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 2px;
}

.band-label {
    width: 3.4rem;
    flex: none;
    text-align: right;
    font-size: var(--qch-text-micro);
    font-weight: 600;
    color: var(--neutral-foreground-hint);
    cursor: help;
}

.band-row-reference .band-label {
    color: var(--warning);
}

.band-strip {
    flex: 1;
    min-width: 0;
    border: calc(var(--stroke-width) * 1px) solid var(--neutral-stroke-divider-rest);
    background: var(--neutral-layer-1);
}

.band-row-reference .band-strip {
    border-color: var(--neutral-stroke-strong-rest);
}

.band {
    shape-rendering: crispEdges;
}

.band-axis {
    display: flex;
    justify-content: space-between;
    margin-left: 3.9rem;
    margin-top: 0.15rem;
    font-size: var(--qch-text-micro);
    color: var(--neutral-foreground-hint);
    font-variant-numeric: tabular-nums;
}

/* ---- Performance query -------------------------------------------------------- */

.query-panel {
    display: grid;
    gap: 1rem;
    padding: 1.25rem;
    margin-bottom: 1.5rem;
}

.tag-group {
    display: grid;
    gap: 0.4rem;
}

.tag-group-label {
    font-size: var(--qch-text-support);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--neutral-foreground-hint);
}

.tag-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}

/* Toggles rather than a multi-select: the whole filter is visible at once, and turning one
   on or off is a single click with no menu to open. */
.tag {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font: inherit;
    font-size: var(--qch-text-support);
    cursor: pointer;
    padding: 0.25rem 0.7rem;
    border-radius: 1rem;
    border: calc(var(--stroke-width) * 1px) solid var(--neutral-stroke-rest);
    background: var(--neutral-fill-stealth-rest);
    color: var(--neutral-foreground-rest);
}

.tag:hover {
    background: var(--neutral-fill-stealth-hover);
}

.tag-on {
    background: var(--accent-fill-rest);
    border-color: var(--accent-fill-rest);
    color: var(--foreground-on-accent-rest);
}

.tag-swatch {
    width: 0.7rem;
    height: 0.7rem;
    border-radius: 2px;
    display: inline-block;
    flex: none;
}

.tag-row-shortcuts {
    margin-top: 0.15rem;
}

.tag-shortcut {
    border-style: dashed;
    color: var(--neutral-foreground-hint);
}

.query-summary {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding-top: 0.75rem;
    border-top: calc(var(--stroke-width) * 1px) solid var(--neutral-stroke-divider-rest);
    font-size: var(--qch-text-support);
    color: var(--neutral-foreground-hint);
}

.report-table thead .tag-swatch {
    margin-right: 0.25rem;
    vertical-align: middle;
}

/* A second figure on the round summaries: staging agreement alone reads as "how did this
   round go", and respiratory agreement is routinely much lower. */
.round-median-label {
    display: block;
    font-size: var(--qch-text-micro);
    font-weight: 400;
    opacity: 0.75;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.round-median {
    text-align: center;
    line-height: 1.2;
    padding: 0.15rem 0.45rem;
}

/* Pushed to its own line so the event figure is not mistaken for another staging one. */
.trend-figure-split {
    margin-left: auto;
    padding-left: 1rem;
    border-left: calc(var(--stroke-width) * 1px) solid var(--neutral-stroke-divider-rest);
}

/* ---- KPI scorecard ------------------------------------------------------------ */

.kpi-section {
    margin-top: 0;
}

.kpi-target {
    display: block;
    font-size: var(--qch-text-micro);
    font-weight: 400;
    color: var(--neutral-foreground-hint);
    text-transform: none;
    letter-spacing: 0;
}

.kpi-cell {
    white-space: nowrap;
}

.kpi-value {
    font-variant-numeric: tabular-nums;
}

.kpi-mark {
    display: inline-block;
    margin-left: 0.4rem;
    font-weight: 700;
}

/* Shape as well as colour: pass and fail must not depend on distinguishing green from red. */
.kpi-met {
    background: color-mix(in srgb, var(--success) 20%, transparent);
}

.kpi-met .kpi-mark {
    color: var(--success);
}

.kpi-missed {
    background: color-mix(in srgb, var(--error) 18%, transparent);
}

.kpi-missed .kpi-mark {
    color: var(--error);
}

.kpi-unassessed {
    color: var(--neutral-foreground-hint);
}

.kpi-summary {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Round titles in the recent list are links, but the list reads as a table of contents —
   an underline under every title makes it look ragged. Underline on hover instead. */
.round-title a {
    color: inherit;
    text-decoration: none;
}

.round-title a:hover,
.round-title a:focus-visible {
    text-decoration: underline;
}

/* ---- Disciplines --------------------------------------------------------------- */

/* Tints rather than solid fills: these sit behind text in tables and on chips, and have to
   stay legible in both themes. The hue carries the group; the text stays the theme's. */
/* One hue per group, defined once and referenced everywhere a discipline is shown — the
   table tints, the dropdown, and the initials chips all read from these. */
:root {
    --discipline-scientist: #42a5f5;
    --discipline-doctor: #4caf50;
    --discipline-nursing: #ef5350;

    /* Deeper shades for the initials chips, which are solid fills carrying white text. The
       tint hues above are too light to read against at any weight. */
    --discipline-scientist-solid: #1976d2;
    --discipline-doctor-solid: #2e7d32;
    --discipline-nursing-solid: #c62828;
}

.discipline-scientist {
    background: color-mix(in srgb, var(--discipline-scientist) 22%, transparent);
}

.discipline-doctor {
    background: color-mix(in srgb, var(--discipline-doctor) 22%, transparent);
}

.discipline-nursing {
    background: color-mix(in srgb, var(--discipline-nursing) 22%, transparent);
}

.discipline-none {
    background: transparent;
}

.discipline-chip {
    display: inline-block;
    padding: 0.05rem 0.45rem;
    border-radius: 1rem;
    border: calc(var(--stroke-width) * 1px) solid var(--neutral-stroke-divider-rest);
    font-size: var(--qch-text-micro);
    white-space: nowrap;
}

/* Rows only. This turns a discipline's tint into an edge marker so it does not fight the
   agreement shading, which is the primary signal in these tables — but it has to reach the
   row and nothing else. Applied to any descendant it also caught the swatches and the
   initials chips that sit inside these tables, replacing the colour they exist to show with
   a stripe in the current text colour. */
.report-table tr:is(.discipline-scientist, .discipline-doctor, .discipline-nursing) {
    box-shadow: inset 3px 0 0 0 currentColor;
    background: transparent;
}

select.discipline-scientist {
    background-color: color-mix(in srgb, var(--discipline-scientist) 22%, var(--neutral-fill-input-rest));
}

select.discipline-doctor {
    background-color: color-mix(in srgb, var(--discipline-doctor) 22%, var(--neutral-fill-input-rest));
}

select.discipline-nursing {
    background-color: color-mix(in srgb, var(--discipline-nursing) 22%, var(--neutral-fill-input-rest));
}

.discipline-swatch {
    display: inline-block;
    width: 0.7rem;
    height: 0.7rem;
    border-radius: 2px;
    margin-right: 0.35rem;
    vertical-align: middle;
}

.small-group-note {
    color: var(--neutral-foreground-hint);
    font-style: italic;
}

/* ---- Lab benchmark ------------------------------------------------------------- */

.delta-above {
    color: var(--success);
}

.delta-below {
    color: var(--error);
}

.benchmark-row th,
.benchmark-row td {
    background: var(--neutral-layer-3);
    font-style: italic;
}

.small-group-flag {
    display: inline-block;
    margin-left: 0.3rem;
    width: 1rem;
    height: 1rem;
    line-height: 1rem;
    text-align: center;
    border-radius: 50%;
    background: color-mix(in srgb, var(--warning) 35%, transparent);
    font-size: var(--qch-text-micro);
    font-weight: 700;
    cursor: help;
}

/* ---- Live rounds ------------------------------------------------------------ */

.round-cards {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
    gap: 1rem;
    margin: 1.25rem 0;
}

.live-round-card {
    padding: 1.25rem;
    display: grid;
    gap: 0.9rem;
    align-content: start;
}

/* An edge marker rather than a fill: the card carries figures, and a tinted panel behind
   them competes with the agreement shading those figures use. */
.live-round-card.status-open {
    box-shadow: inset 3px 0 0 0 var(--accent-fill-rest);
}

.live-round-card.status-closed {
    box-shadow: inset 3px 0 0 0 var(--warning);
}

.live-round-card.status-run {
    box-shadow: inset 3px 0 0 0 var(--neutral-stroke-divider-rest);
}

.live-round-header {
    display: flex;
    align-items: start;
    justify-content: space-between;
    gap: 0.6rem;
}

.live-round-name {
    font-size: var(--qch-text-subheading);
    font-weight: 600;
    text-decoration: none;
    display: block;
}

.live-round-facts {
    display: grid;
    gap: 0.45rem;
    margin: 0;
    font-size: var(--qch-text-support);
}

.live-round-facts > div {
    display: grid;
    grid-template-columns: 8rem 1fr;
    gap: 0.5rem;
}

.live-round-facts dt {
    color: var(--neutral-foreground-hint);
}

.live-round-facts dd {
    margin: 0;
}

/* The dashboard's live-round summary. Compact rows rather than the cards used on the live
   rounds page itself: here it sits above the archive and should not crowd it out. */
.live-summary {
    margin: 1.25rem 0;
    display: grid;
    gap: 0.75rem;
    align-content: start;
}

.live-summary-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 0.5rem;
}

.live-summary-item {
    display: grid;
    gap: 0.15rem;
    padding: 0.55rem 0.75rem;
    border-radius: calc(var(--control-corner-radius) * 1px);
    background: var(--neutral-layer-2);
}

.live-summary-item.status-open {
    box-shadow: inset 3px 0 0 0 var(--accent-fill-rest);
}

.live-summary-item.status-scheduled {
    box-shadow: inset 3px 0 0 0 var(--neutral-stroke-divider-rest);
}

.live-summary-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
}

.live-summary-head a {
    font-weight: 600;
    text-decoration: none;
}

.live-summary-detail {
    font-size: var(--qch-text-support);
    color: var(--neutral-foreground-hint);
}

/* Native inputs used where a Fluent component is unavailable or unreliable, styled to sit
   beside the Fluent fields without looking transplanted. */
.stacked-field {
    display: grid;
    gap: 0.25rem;
}

.stacked-field > span {
    font-size: var(--qch-text-support);
    color: var(--neutral-foreground-rest);
}

.inline-input {
    height: 1.75rem;
    padding: 0 0.4rem;
    font-family: inherit;
    font-size: var(--qch-text-body);
    color: var(--neutral-foreground-rest);
    background-color: var(--neutral-fill-input-rest);
    border: calc(var(--stroke-width) * 1px) solid var(--neutral-stroke-input-rest);
    border-radius: calc(var(--control-corner-radius) * 1px);
}

.inline-input:hover:not(:disabled) {
    border-color: var(--neutral-stroke-input-hover);
}

.inline-input:focus-visible {
    outline: calc(var(--focus-stroke-width) * 1px) solid var(--accent-fill-rest);
    outline-offset: -1px;
}

.inline-textarea {
    height: auto;
    padding: 0.4rem;
    resize: vertical;
    font-size: var(--qch-text-body);
}
