.button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-height: var(--tap-target);
    padding: var(--space-2) var(--space-4);
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--text);
    font-family: var(--font-body);
    font-size: var(--text-base);
    font-weight: 500;
    line-height: var(--leading-body);
    text-decoration: none;
    cursor: pointer;
    transition: background var(--duration-fast) var(--easing), border-color var(--duration-fast) var(--easing),
        transform var(--duration-fast) var(--easing);
}

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

/* 5.48:1 contrast ratio. */
.button--primary {
    background: var(--accent);
    color: var(--accent-text);
}

.button--primary:hover {
    background: var(--accent-hover);
}

.button--secondary {
    background: var(--surface);
    border-color: var(--border-input);
}

.button--secondary:hover {
    background: var(--surface-sunken);
}

.button--danger {
    background: var(--danger);
    color: var(--surface);
}

.button--danger:hover {
    background: var(--danger-hover);
}

/* A destructive action that is not the page's job: text weight, danger colour, no fill. The
   confirm dialog it opens carries the solid `.button--danger` instead. */
.button--quiet-danger {
    border-color: transparent;
    background: transparent;
    color: var(--danger);
}

.button--quiet-danger:hover {
    background: var(--danger-soft);
    color: var(--danger);
}

.button--ghost {
    background: transparent;
    color: var(--muted);
    padding: var(--space-2);
    min-width: var(--tap-target);
}

.button--ghost:hover {
    background: var(--surface-sunken);
    color: var(--text);
}

.button[disabled],
.button[aria-disabled="true"] {
    opacity: 0.5;
    cursor: not-allowed;
}

.button[aria-pressed="true"] {
    background: var(--accent-soft);
    border-color: var(--text);
    box-shadow: inset 0 0 0 1px var(--text);
}

.button--js-only {
    display: none;
}

.js .button--js-only {
    display: inline-flex;
}

.js .button--nojs-only {
    display: none;
}

.button-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    align-items: center;
}

.form-grid + .button-row {
    margin-top: var(--space-5);
}

.badge {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: 2px var(--space-2);
    border-radius: var(--radius-pill);
    border: 1px solid var(--border-strong);
    background: var(--surface-sunken);
    color: var(--text);
    font-size: var(--text-xs);
    font-weight: 500;
    line-height: 1.4;
    white-space: nowrap;
}

.badge--accent {
    background: var(--accent-soft);
    border-color: var(--accent);
}

.badge--muted {
    background: transparent;
    color: var(--muted);
}

.badge--warning {
    background: var(--warning-soft);
    border-color: transparent;
}

.badge-list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
}

.field {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    margin-bottom: var(--space-4);
}

.field__label {
    font-weight: 500;
    font-size: var(--text-sm);
}

.field__required {
    color: var(--danger);
    margin-left: 2px;
}

.field__help {
    color: var(--muted);
    font-size: var(--text-sm);
}

/*
 * The hint input_filter.js shows for a refused character: the help line's type in a bubble, never red, faded over
 * --duration-fast. It is a manual popover, so it sits in the top layer: it takes no room (nothing below the field moves),
 * no container clips it, and it never enters the error slot, so the field never gets the invalid border. input_filter.js
 * sets its inset and width from the field it belongs to.
 */
.field__hint {
    position: fixed;
    inset: auto;
    margin: 0;
    padding: var(--space-2) var(--space-3);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface);
    box-shadow: var(--shadow-md);
    overflow: visible;
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--duration-fast) var(--easing);
}

.field__hint--shown {
    opacity: 1;
}

/* A browser without popovers has the announcer alone; the bubble would sit in the flow and push the page down. */
@supports not selector(:popover-open) {
    .field__hint {
        display: none;
    }
}

.field__error-slot:empty {
    display: none;
}

.field__errors {
    list-style: none;
    margin: 0;
    padding: 0;
    color: var(--danger);
    font-size: var(--text-sm);
}

/* A live check reveals an error line over --duration-reveal; live_validation.js sets --reveal-height from the line. */
.field__errors--reveal {
    overflow: hidden;
    animation: error-reveal var(--duration-reveal) var(--easing);
}

@keyframes error-reveal {
    from {
        height: 0;
        opacity: 0;
    }

    to {
        height: var(--reveal-height);
        opacity: 1;
    }
}

/* A refused Save nudges the first invalid field: three swings of --nudge-distance within --duration-nudge. */
.field--nudge :is(input, select, textarea) {
    animation: field-nudge var(--duration-nudge) var(--easing);
}

@keyframes field-nudge {
    0%,
    100% {
        transform: translateX(0);
    }

    12.5%,
    37.5%,
    62.5% {
        transform: translateX(calc(var(--nudge-distance) * -1));
    }

    25%,
    50%,
    75% {
        transform: translateX(var(--nudge-distance));
    }
}

/* Exclusion-based: listing types silently drops new ones. :where() keeps specificity at 0. */
.field input:where(:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="file"])),
.field select,
.field textarea {
    width: 100%;
    min-height: var(--tap-target);
    padding: var(--space-2) var(--space-3);
    border: 1px solid var(--border-input);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--text);
    font-family: var(--font-body);
    font-size: var(--text-base);
    line-height: var(--leading-body);
    transition: border-color var(--duration-fast) var(--easing);
}

.field input:hover,
.field select:hover,
.field textarea:hover {
    border-color: var(--text);
}

.field textarea {
    min-height: 96px;
    resize: vertical;
}

.field :is(input, select, textarea):disabled {
    background: var(--surface-sunken);
    border-style: dashed;
    color: var(--muted);
    cursor: not-allowed;
}

.field--invalid input,
.field--invalid select,
.field--invalid textarea,
.field:has(.field__error-slot:not(:empty)) input,
.field:has(.field__error-slot:not(:empty)) select,
.field:has(.field__error-slot:not(:empty)) textarea {
    border-color: var(--danger);
}

.field--checkbox {
    flex-direction: row;
    align-items: center;
    gap: var(--space-2);
    min-height: var(--tap-target);
}

.field--checkbox > div {
    flex: 1;
    min-width: 0;
}

/* The label is the touch target: as wide as the row and one tap target tall, its margins taking back the extra
   height so the row keeps the height of its text. */
.field--checkbox .field__label {
    display: flex;
    align-items: center;
    min-height: var(--tap-target);
    margin-block: calc((1lh - var(--tap-target)) / 2);
    cursor: pointer;
}

.field--checkbox input[type="checkbox"],
.field__choices input[type="checkbox"] {
    flex-shrink: 0;
    width: var(--checkbox-size);
    height: var(--checkbox-size);
    accent-color: var(--accent);
}

.data-table__numeric,
.pagination__status {
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}

.form-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0 var(--space-4);
}

.form-grid > .field:last-child,
.form-grid > :last-child .field {
    margin-bottom: 0;
}

.form-grid__row-3 {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0 var(--space-4);
}

/* Two short fields side by side at every width (a datetime pair stays stacked instead). */
.form-grid__pair {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 var(--space-4);
    max-width: 26rem;
}

/* Every decimal, money and whole-number input (the kinds the number widget renders in data-filter): right-aligned with
   tabular figures so values line up. :where() keeps specificity at 0, so a control that centres its own value (a
   stepper) says so with a plain class. Identifiers typed on the numeric keyboard (data-filter="digits") are not here. */
:where(input[data-filter="decimal"], input[data-filter="whole"]) {
    font-variant-numeric: tabular-nums;
    text-align: right;
}

/* A value with a unit suffix (kr., min): tabular, right-aligned, the unit overlaid at the end. */
.input-unit {
    position: relative;
    display: flex;
    align-items: center;
    max-width: 12rem;
}

.field .input-unit input {
    padding-inline-end: calc(var(--space-4) * 3);
    font-variant-numeric: tabular-nums;
    text-align: right;
}

.input-unit__suffix {
    position: absolute;
    inset-inline-end: var(--space-3);
    color: var(--muted);
    pointer-events: none;
}

/* The form's save row stays in reach on a long form. */
.form-footer {
    position: sticky;
    inset-block-end: 0;
    z-index: var(--z-raised);
    margin-inline: calc(var(--space-4) * -1);
    padding: var(--space-3) var(--space-4);
    background: var(--bg);
    box-shadow: 0 -1px 0 var(--border);
}

@media (min-width: 768px) {
    .form-footer {
        margin-inline: 0;
        padding-inline: 0;
    }
}

.form-errors {
    margin: 0 0 var(--space-4);
    padding: var(--space-3);
    border-radius: var(--radius-md);
    border: 1px solid var(--danger);
    background: var(--danger-soft);
    color: var(--danger);
    list-style: none;
}

@media (min-width: 768px) {
    .form-grid {
        grid-template-columns: 1fr 1fr;
    }

    .form-grid__full {
        grid-column: 1 / -1;
    }

    .form-grid__row-3 {
        grid-template-columns: repeat(3, 1fr);
    }
}

.field--choices {
    border: 1px solid var(--border-input);
    border-radius: var(--radius-md);
    padding: var(--space-3);
    margin-bottom: var(--space-4);
}

.field--group {
    min-inline-size: 0;
    margin: 0;
    padding: 0;
    border: 0;
}

.field__choices > div {
    margin-top: var(--space-2);
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: var(--space-1);
}

.field__choices label {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    min-height: var(--tap-target);
    font-size: var(--text-sm);
}

.data-table-wrap {
    position: relative;
    overflow-x: auto;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
}

.data-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--text-base);
}

.data-table th,
.data-table td {
    padding: var(--space-3);
    text-align: left;
    vertical-align: middle;
    overflow-wrap: anywhere;
}

.data-table thead th {
    font-family: var(--font-display);
    font-weight: 500;
    font-size: var(--text-sm);
    letter-spacing: var(--display-tracking);
    color: var(--muted);
    border-bottom: 1px solid var(--border-strong);
    white-space: nowrap;
    vertical-align: middle;
}

.data-table tbody tr {
    border-bottom: 1px solid var(--border);
    transition: background var(--duration-fast) var(--easing);
}

.data-table tbody tr:last-child {
    border-bottom: 0;
}

/* No fill — the fill belongs to the "just saved" row mark and hover; two meanings must not share it. */
.data-table tbody tr.data-table__row--inactive {
    background: var(--surface);
}

.data-table tbody tr:hover,
.data-table tbody tr.data-table__row--inactive:hover {
    background: var(--accent-soft);
}

.data-table__name {
    font-family: var(--font-display);
    font-weight: 700;
    letter-spacing: var(--display-tracking);
}

a.data-table__name {
    display: inline-flex;
    align-items: center;
    min-height: var(--tap-target);
    color: inherit;
    text-decoration: none;
}

.data-table__count {
    display: inline-flex;
    align-items: center;
    min-height: var(--tap-target);
    padding-inline: var(--space-2);
}

a.data-table__name:hover,
a.data-table__name:focus-visible {
    text-decoration: underline;
}

.data-table__row--linked {
    position: relative;
    cursor: pointer;
}

.data-table__row-link::after {
    content: "";
    position: absolute;
    inset: 0;
}

.data-table__row--linked :is(a, button, input, select, textarea, label):not(.data-table__row-link) {
    position: relative;
    z-index: var(--z-raised);
}

.data-table tbody tr.data-table__row--linked:focus-within {
    background: var(--accent-soft);
}

.data-table__row--linked:hover .data-table__row-link {
    text-decoration: underline;
}

.data-table__row-link:focus-visible {
    outline: none;
}

.data-table__row-link:focus-visible::after {
    outline: var(--focus-ring);
    outline-offset: var(--focus-inset-offset);
}

@media (max-width: 1249.98px) {
    .data-table__row-link::after {
        border-radius: var(--radius-lg);
    }
}

.data-table__meta {
    color: var(--muted);
    font-size: var(--text-sm);
}

.data-table__numeric {
    white-space: nowrap;
}

@media (min-width: 1250px) {
    .data-table th.data-table__numeric,
    .data-table td.data-table__numeric {
        text-align: right;
    }
}

.data-table__actions {
    display: flex;
    gap: var(--space-2);
    flex-wrap: wrap;
}

.data-table__actions--split > :last-child {
    margin-inline-start: var(--space-3);
}

@media (min-width: 1250px) {
    .data-table__actions {
        flex-wrap: nowrap;
    }
}

.data-table__row--inactive td,
.data-table__row--inactive .data-table__name {
    color: var(--muted);
}

@media (max-width: 1249.98px) {
    .data-table-wrap {
        overflow-x: visible;
        border: 0;
        background: transparent;
        box-shadow: none;
    }

    .data-table,
    .data-table tbody,
    .data-table tr,
    .data-table th,
    .data-table td {
        display: block;
    }

    .data-table thead {
        display: none;
    }

    .data-table tbody tr {
        display: flex;
        flex-direction: column;
        background: var(--surface);
        border: 1px solid var(--border);
        border-radius: var(--radius-lg);
        box-shadow: var(--shadow-sm);
        padding: var(--space-3);
        margin-bottom: var(--space-3);
    }

    .data-table tbody td {
        display: flex;
        flex-wrap: wrap;
        gap: var(--space-1);
        padding: var(--space-1) 0;
        border: 0;
    }

    .data-table tbody td::before {
        content: attr(data-label);
        margin-right: auto;
        color: var(--muted);
        font-size: var(--text-xs);
        font-weight: 400;
        flex: none;
    }

    .data-table tbody td[data-label=""]::before {
        content: none;
    }

    .data-table tbody td.data-table__cell--headline {
        display: block;
        padding-bottom: var(--space-2);
        order: -1;
    }

    .data-table__cell--headline .data-table__name {
        font-size: var(--text-lg);
        display: block;
    }
}

@media (min-width: 768px) and (max-width: 1249.98px) {
    .data-table tbody {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(var(--card-min-width), 1fr));
        gap: var(--space-3);
    }

    .data-table tbody tr {
        margin-bottom: 0;
    }
}

@media (min-width: 1250px) {
    .data-table td .button {
        white-space: nowrap;
    }

    .data-table td.data-table__cell--headline > .field input {
        min-width: 6rem;
    }

    .data-table .field {
        overflow-wrap: normal;
    }

    .data-table .field__errors {
        overflow-wrap: anywhere;
    }

    .data-table .field--checkbox {
        display: grid;
        grid-template-columns: auto minmax(0, 1fr);
        row-gap: var(--space-1);
    }

    .data-table .field--checkbox > div {
        display: contents;
    }

    .data-table .field--checkbox :is(.field__help, .field__error-slot) {
        grid-column: 1 / -1;
    }
}

/* Same weight as the base cell rule, so the checkbox column's own padding still wins. */
@media (min-width: 1250px) and (max-width: 1439.98px) {
    .data-table :is(th, td) {
        padding-inline: var(--space-2);
    }

    .data-table td.data-table__cell--headline {
        min-width: 8rem;
        overflow-wrap: break-word;
    }

    .data-table:has(td > .data-table__actions > :nth-child(3)) td:has(> .data-table__actions) {
        width: calc(3 * var(--tap-target) + 4 * var(--space-2));
    }

    .data-table:has(td > .data-table__actions > :nth-child(3)) .data-table__actions,
    .data-table tr:has(> td > .data-table__actions > .button--primary) .data-table__actions {
        flex-wrap: wrap;
    }

    .data-table:has(td > .data-table__actions > :nth-child(3)) .data-table__actions {
        min-width: calc(2 * var(--tap-target) + var(--space-2));
    }
}

.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--space-3);
    padding: var(--space-7) var(--space-4);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
}

.empty-state__mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 72px;
    height: 72px;
    border-radius: var(--radius-pill);
    background: var(--brand-gradient);
    color: var(--text);
}

.empty-state__text {
    color: var(--muted);
    max-width: 46ch;
}

/* Inside a card that already has its own frame: no second frame, no mark, a heading one level down. */
.empty-state--compact {
    padding-block: var(--space-3);
    background: none;
    border: 0;
    border-radius: 0;
}

.empty-state--compact .empty-state__mark {
    display: none;
}

.pagination {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    margin-top: var(--space-4);
}

.pagination__status {
    color: var(--muted);
    font-size: var(--text-sm);
}

.modal {
    width: 100%;
    max-width: 560px;
    padding: var(--space-4);
    border: 0;
    background: transparent;
}

.modal::backdrop {
    background: var(--scrim);
}

.modal__panel {
    width: 100%;
    max-width: 520px;
    max-height: 90dvh;
    overflow: auto;
    background: var(--surface);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: var(--space-5);
}

.modal__header {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-4);
}

.modal__header h2 {
    flex: 1;
    min-width: 0;
}

.modal__body {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.confirm__mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border-radius: var(--radius-pill);
    background: var(--accent-soft);
    color: var(--text);
    flex: none;
}

.confirm__text {
    max-width: 72ch;
    color: var(--muted);
    margin-bottom: var(--space-4);
}

.confirm__label {
    margin: 0 0 var(--space-1);
    font-size: var(--text-sm);
    font-weight: 600;
}

.confirm__list {
    margin: 0 0 var(--space-4);
    padding-left: var(--space-5);
    color: var(--muted);
}

.confirm .confirm__blockers {
    margin: 0 0 var(--space-4);
}

.confirm__blockers a {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    min-height: var(--tap-target);
    padding-inline: var(--space-2);
}

.confirm__counts {
    font-variant-numeric: tabular-nums;
}

.confirm__blockers .confirm__counts {
    flex: none;
    white-space: nowrap;
}

.delete-page {
    max-width: var(--form-measure);
}

.confirm__blockers a:focus-visible {
    outline-offset: var(--focus-inset-offset);
}

.confirm__note {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: var(--space-4);
    color: var(--muted);
    font-size: var(--text-sm);
}

.confirm__armed > .confirm__note {
    grid-column: 1 / -1;
    margin-bottom: 0;
}

.confirm__note--warning {
    color: var(--danger);
}

.confirm__armed {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
    gap: var(--space-2);
}

.confirm__armed .button {
    white-space: nowrap;
}

.confirm__question {
    grid-column: 1 / -1;
    margin: 0 0 var(--space-1);
    font-weight: 600;
}

.messages {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.messages:not(:empty) {
    margin-block-end: var(--space-4);
}

.message {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    padding: var(--space-3);
    border-radius: var(--radius-md);
    border: 1px solid var(--border-strong);
    background: var(--surface);
}

.message--success {
    background: var(--success-wash);
    border-color: var(--success);
    color: var(--success);
}

.message--error {
    background: var(--danger-soft);
    border-color: var(--danger);
    color: var(--danger);
}

/* Must come after .message: at equal specificity, source order decides the fill colour. */
.message--warning {
    background: var(--warning-soft);
    border-color: var(--border-strong);
    color: var(--text);
}

.message--compact {
    padding: var(--space-2) var(--space-3);
    font-size: var(--text-sm);
}

.message__list {
    max-height: min(16rem, 40dvh);
    overflow-y: auto;
    overscroll-behavior: contain;
}

@media print {
    .message__list {
        max-height: none;
        overflow: visible;
    }
}

.message__list {
    margin: var(--space-2) 0 0;
    padding-left: var(--space-4);
}

.card__title {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    min-width: 0;
}

.card__title-note {
    color: var(--muted);
    font-weight: 400;
}

.advanced__summary {
    min-height: var(--tap-target);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-2) var(--space-3);

    margin-block: calc(var(--space-2) * -1);
    margin-inline: calc(var(--space-3) * -1);
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: background var(--duration-fast) var(--easing);
}

.advanced__summary::-webkit-details-marker {
    display: none;
}

.advanced__summary:hover,
.advanced__summary:focus-visible {
    background: var(--accent-soft);
}

.page-header__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    margin: var(--space-1) 0 0;
    font-size: var(--text-sm);
}

/* A single-column page (a standalone form, a no-JS fallback) reads best at a narrow measure
   instead of stretching to the viewport. */
.page--narrow {
    max-width: 46rem;
}

.segmented {
    display: flex;
    width: max-content;
    max-width: 100%;
    padding: 0;
    margin: 0 0 var(--space-4);
    border: 1px solid var(--border-input);
    border-radius: var(--radius-md);
    overflow: hidden;
}

.segmented__option {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: var(--tap-target);
    padding: 0 var(--space-4);
    font-size: var(--text-sm);
    font-weight: 500;
    white-space: nowrap;
    color: var(--text);
    text-decoration: none;
    cursor: pointer;
}

.segmented__option[aria-current],
.segmented__option:has(:checked),
.segmented__option--on {
    background: var(--accent-soft);
    font-weight: 700;
    box-shadow: inset 0 var(--selection-bar-inset) 0 currentColor;
}

@media (forced-colors: active) {
    .segmented__option[aria-current],
    .segmented__option:has(:checked),
    .segmented__option--on,
    .button[aria-pressed="true"] {
        text-decoration: underline;
        text-underline-offset: var(--selection-underline-offset);
    }
}

.segmented__option:focus-visible,
.segmented__option:has(:focus-visible) {
    outline: var(--focus-ring);
    outline-offset: var(--focus-inset-offset);
}

.segmented--fill {
    width: 100%;
    max-width: 20rem;
    margin: 0;
    border: 0;
    background: var(--surface);
}

.segmented--fill .segmented__option {
    flex: 1 0 auto;
    min-width: 0;
    border: 1px solid var(--border-input);
    transition: background-color var(--duration-fast) var(--easing), box-shadow var(--duration-fast) var(--easing);
}

.segmented--fill .segmented__option:not([hidden]) ~ .segmented__option:not([hidden]) {
    margin-left: -1px;
}

.segmented--fill .segmented__option:not([hidden]):not(.segmented__option:not([hidden]) ~ *) {
    border-start-start-radius: var(--radius-md);
    border-end-start-radius: var(--radius-md);
}

.segmented--fill .segmented__option:not([hidden]):not(:has(~ .segmented__option:not([hidden]))) {
    border-start-end-radius: var(--radius-md);
    border-end-end-radius: var(--radius-md);
}

.segmented--fill .segmented__option:has(:checked) {
    border-bottom-color: currentColor;
}

@supports (anchor-scope: all) {
    .segmented--fill:not(.segmented--multi) {
        position: relative;
        anchor-scope: --segmented-picked;
    }

    .segmented--fill .segmented__option {
        position: relative;
        z-index: var(--z-raised);
    }

    .segmented--fill:not(.segmented--multi) .segmented__option:has(:checked) {
        anchor-name: --segmented-picked;
        background: none;
        box-shadow: none;
    }

    .segmented--fill:not(.segmented--multi):has(:checked)::before {
        content: "";
        position: absolute;
        position-anchor: --segmented-picked;
        inset: anchor(top) anchor(right) anchor(bottom) anchor(left);
        background: var(--accent-soft);
        box-shadow: inset 0 var(--selection-bar-inset) 0 currentColor;
        transition: left var(--duration-slow) var(--easing), right var(--duration-slow) var(--easing);
    }
}

.segmented__option[hidden] {
    display: none;
}

.segmented__option:has(:disabled) {
    pointer-events: none;
}

.segmented__option:has(:disabled:not(:checked)) {
    opacity: 0.45;
}

.advanced__chevron,
.disclosure__chevron {
    transition: transform var(--duration-fast) var(--easing);
}

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

.advanced[open] .advanced__chevron,
.disclosure--open .disclosure__chevron {
    transform: rotate(180deg);
}

.advanced:not([open]) {
    row-gap: 0;
}

@supports (interpolate-size: allow-keywords) {
    .advanced {
        transition: row-gap var(--duration-slow) var(--easing);
    }

    .advanced::details-content {
        min-block-size: 0;
        block-size: 0;
        opacity: 0;
        overflow: clip;
        overflow-clip-margin: var(--space-2);
        transition:
            block-size var(--duration-slow) var(--easing),
            opacity var(--duration-slow) var(--easing),
            content-visibility var(--duration-slow) var(--easing) allow-discrete;
    }

    .advanced[open]::details-content {
        block-size: auto;
        opacity: 1;
    }

    .advanced--overflowing::details-content {
        transition-property: block-size, opacity, content-visibility, overflow;
        transition-duration: var(--duration-slow), var(--duration-slow), var(--duration-slow), 0s;
        transition-timing-function: var(--easing);
        transition-delay: 0s, 0s, 0s, 0s;
        transition-behavior: allow-discrete;
    }

    .advanced--overflowing[open]::details-content {
        overflow: visible;
        transition-delay: 0s, 0s, 0s, var(--duration-slow);
    }
}

.disclosure__panel {
    --collapse-shift: calc(var(--space-2) * -1);
    transition:
        opacity var(--duration-slow) var(--easing),
        translate var(--duration-slow) var(--easing);
}

.js .disclosure__panel--collapsed {
    display: none;
    opacity: 0;
    translate: 0 var(--collapse-shift);
}

@starting-style {
    [data-motion] .disclosure__panel {
        opacity: 0;
        translate: 0 var(--collapse-shift);
    }
}

@keyframes row-mark {
    0%,
    40% {
        background: var(--accent-soft);
    }

    100% {
        background: transparent;
    }
}

.data-table tbody tr:target,
.related__row:target,
.card--saved {
    animation: row-mark var(--row-mark-duration) ease-out;

    scroll-margin-block: var(--space-6);
}

/* Override base.css's reduced-motion 0.01ms: the mark must still appear, just without animation. */
@media (prefers-reduced-motion: reduce) {
    .field__hint {
        transition: none;
    }

    .data-table tbody tr:target,
    .related__row:target,
    .card--saved {
        animation-duration: var(--row-mark-duration) !important;
        animation-timing-function: steps(1, end) !important;
    }
}

.segmented-field > legend,
.choice-chips > legend {
    margin-bottom: var(--space-1);
}

@media (min-width: 768px) {
    .form-grid__row-3:has(> .segmented-field) {
        grid-template-columns: minmax(0, 1fr) fit-content(20rem) minmax(0, 1fr);
    }
}

/* ------------------------------------------------------------------ */
/* Menu (shared action menu: ⋯ menus, profile menu items)             */
/* ------------------------------------------------------------------ */

.menu__panel {
    display: flex;
    flex-direction: column;
    width: min(18rem, calc(100vw - 2 * var(--space-4)));
    padding: var(--space-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface);
    box-shadow: var(--shadow-md);
    color: var(--text);
    font-size: var(--text-base);
    text-align: start;
}

.js .menu__panel {
    position: absolute;
    top: calc(100% + var(--space-1));
    inset-inline-end: 0;
    z-index: var(--z-dropdown);
}

.menu__item {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    min-height: var(--tap-target);
    padding: var(--space-2) var(--space-3);
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text);
    font: inherit;
    text-align: start;
    text-decoration: none;
    cursor: pointer;
    transition: background var(--duration-fast) var(--easing);
}

.menu__item:hover {
    background: var(--surface-sunken);
}

.menu__item--danger {
    color: var(--danger);
    border-top: 1px solid var(--border);
}

/* ------------------------------------------------------------------ */
/* Password input (eye toggle beside a password field)                */
/* ------------------------------------------------------------------ */

/* The eye beside every password field (partials/password_input.html), linked only by the screens that draw
   one: sign-in, a new password and the account page. It sits inside the input's right edge as a full 44px target.
   Without scripting it is never painted and the input keeps its own padding, so the field is a plain
   password input. */
.password-input {
    position: relative;
}

.js .password-input input {
    padding-inline-end: var(--tap-target);
}

.password-input__toggle {
    display: none;
    position: absolute;
    inset-block: 0;
    inset-inline-end: 0;
    width: var(--tap-target);
    place-items: center;
    padding: 0;
    border: 0;
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--muted);
    cursor: pointer;
    touch-action: manipulation;
}

.js .password-input__toggle {
    display: grid;
}

.password-input__toggle:hover {
    color: var(--text);
}

/* Both eyes are painted in one cell and crossfade, so the pressed state never moves the box. */
.password-input__icon {
    grid-area: 1 / 1;
    transition: opacity var(--duration-fast) var(--easing);
}

.password-input__icon--hide,
.password-input__toggle[aria-pressed="true"] .password-input__icon--show {
    opacity: 0;
}

.password-input__toggle[aria-pressed="true"] .password-input__icon--hide {
    opacity: 1;
}

/* ------------------------------------------------------------------ */
/* Availability input (spinner and tick inside a field with a check)  */
/* ------------------------------------------------------------------ */

/* partials/availability_input.html wraps only the fields that declare an availability check. The icon room is
   always reserved as padding, so the input's box is the same in every state (neutral, pending, free, taken,
   unavailable); only the icon inside it changes. Both icons share one cell and `data-state` shows one. */
.availability-input {
    position: relative;
}

.availability-note:empty {
    display: none;
}

.availability-input input {
    padding-inline-end: calc(var(--space-3) + var(--icon-size) + var(--space-2));
}

.availability-status {
    position: absolute;
    inset-block: 0;
    inset-inline-end: var(--space-3);
    display: grid;
    place-items: center;
    width: var(--icon-size);
    pointer-events: none;
}

.availability-status__icon {
    grid-area: 1 / 1;
    display: none;
}

.availability-status[data-state="pending"] .availability-status__pending {
    display: block;
    color: var(--muted);
}

.availability-status[data-state="free"] .availability-status__free {
    display: block;
    color: var(--success);
}

/* A submit in flight: disabled, its icon swaps for a spinner in the same grid cell, so the button
   keeps its width and the tap is acknowledged where the finger is. */
.button__icons {
    display: inline-grid;
}

.button__icons > .icon {
    grid-area: 1 / 1;
    transition: opacity var(--duration-fast) var(--easing);
}

.button__icons > .button__spinner,
.button[aria-busy="true"] .button__icons > .icon:not(.button__spinner) {
    opacity: 0;
}

.button[aria-busy="true"] .button__icons > .button__spinner {
    opacity: 1;
}

.button[aria-busy="true"] {
    cursor: progress;
}

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

/* A real checkbox with role="switch"; its state is carried by the knob's position and the fill,
   never colour alone. The label is the 44px target; the track is drawn inside it. */
.switch {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: var(--tap-target);
    min-height: var(--tap-target);
    cursor: pointer;
    touch-action: manipulation;
}

.switch input[type="checkbox"] {
    position: absolute;
    inset: 0;
    margin: 0;
    opacity: 0;
    cursor: pointer;
}

.switch__track {
    position: relative;
    display: block;
    width: var(--tap-target);
    height: var(--space-5);
    border: 1px solid var(--border-input);
    border-radius: var(--radius-pill);
    background: var(--surface-sunken);
    transition:
        background-color var(--duration-fast) var(--easing),
        border-color var(--duration-fast) var(--easing);
}

.switch__track::after {
    content: "";
    position: absolute;
    inset-block-start: calc(var(--space-1) - 1px);
    inset-inline-start: calc(var(--space-1) - 1px);
    width: var(--space-4);
    height: var(--space-4);
    border-radius: var(--radius-pill);
    background: var(--surface);
    box-shadow: var(--shadow-sm), 0 0 0 1px var(--border-input);
    transition: transform var(--duration-fast) var(--easing);
}

.switch input[type="checkbox"]:checked + .switch__track {
    border-color: var(--accent);
    background: var(--accent-soft);
}

/* On is the normal state, so it stays quiet: a soft fill and the knob at the far end. */
.switch input[type="checkbox"]:checked + .switch__track::after {
    transform: translateX(calc(var(--tap-target) - var(--space-4) - var(--space-2)));
    background: var(--accent);
    box-shadow: none;
}

.switch input[type="checkbox"]:focus-visible + .switch__track {
    outline: var(--focus-ring);
    outline-offset: 2px;
}

.switch input[type="checkbox"]:disabled + .switch__track {
    opacity: 0.5;
}

/* A switch with a visible label, for a field inside an ordinary form (never auto-submitting). */
.field.field--switch {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: var(--space-3);
}

.field--switch .field__label {
    margin: 0;
    cursor: pointer;
}

@media (forced-colors: active) {
    .switch__track {
        border-color: CanvasText;
    }

    .switch input[type="checkbox"]:checked + .switch__track {
        background: Highlight;
    }
}

@media (prefers-reduced-motion: reduce) {
    .switch__track,
    .switch__track::after {
        transition: none;
    }
}

.progress {
    height: var(--progress-height);
    border-radius: var(--radius-pill);
    background: var(--surface-sunken);
    overflow: hidden;
}

.progress__bar {
    height: 100%;
    border-radius: var(--radius-pill);
    background: var(--accent);
    transition: width var(--duration-slow) var(--easing);
}

/* The quiet bar: text-coloured on a stronger track, for a count that is read, not a job being watched. */
.progress--quiet {
    background: var(--border-strong);
}

.progress--quiet .progress__bar {
    background: var(--text);
}

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

/* A narrow numeric table that stays a table at every width instead of folding into one card per row below 1250 px.
   The wrap is part of the selectors: the card layout's own rules name it too and would win otherwise. */
.data-table-wrap:has(.data-table--compact) {
    overflow-x: auto;
    border: 1px solid var(--border);
    background: var(--surface);
    box-shadow: var(--shadow-sm);
}

.data-table-wrap .data-table.data-table--compact {
    display: table;
}

.data-table-wrap .data-table.data-table--compact thead {
    display: table-header-group;
}

.data-table-wrap .data-table.data-table--compact tbody {
    display: table-row-group;
}

.data-table-wrap .data-table.data-table--compact tfoot {
    display: table-footer-group;
}

.data-table-wrap .data-table.data-table--compact tr {
    display: table-row;
}

.data-table-wrap .data-table.data-table--compact th,
.data-table-wrap .data-table.data-table--compact td {
    display: table-cell;
    height: var(--tap-target);
    padding: var(--space-2) var(--space-3);
}

.data-table-wrap .data-table.data-table--compact tbody tr {
    margin: 0;
    padding: 0;
    border: 0;
    border-bottom: 1px solid var(--border);
    border-radius: 0;
    background: none;
    box-shadow: none;
}

.data-table-wrap .data-table.data-table--compact tbody tr:last-child {
    border-bottom: 0;
}

.data-table-wrap .data-table.data-table--compact tbody td::before {
    content: none;
}

.data-table-wrap .data-table.data-table--compact .data-table__numeric {
    text-align: right;
}
