/* The internal tools' own rules — Timeregistrering and Sager — on top
   of styles.css: the page head, the cards, the tables, the dialogs, the
   development notice and the print form. Linked by both pages after
   styles.css. */

/* ============================================================
   Timeregistrering — page rules
   Loaded after styles.css, only by /timer/. Component classes
   live in components.css; only this page's layout and its print
   form live here. The record is the page: one card, one toolbar,
   the table.
   ============================================================ */

/* The front page's navy band is the tenant's shortcut and stays there;
   its echo here is a thin brand strip on the header's lower edge —
   family resemblance without faking the band's purpose. Same 3px as
   the site's other rules. */
.site-header {
    border-bottom: 3px solid var(--surface-brand);
}

/* The heading, and under it the summary card at its own width — at
   every width; it fills the line only in the toolbar's final step. */
.page-top {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-5);
    margin-bottom: var(--space-6);
}

/* ========== the periods card ========== */
/* Shaped like the entries card under it: a toolbar with the standing
   figures on the left and Vis perioder on the right, and under it the
   periods table — the same frameless table as the entries, so the two
   read as one system — unfolded by the checkbox. */
.periods-card {
    margin-bottom: var(--space-5);
}

/* The toolbar's margin belongs to the table below it, which is not
   always there. */
.periods-card .toolbar {
    margin-bottom: 0;
}

.periods-card .table-periods {
    margin-top: var(--space-5);
}

/* Label, then the figure, on one line, at the table's size — plain
   text, a sentence rather than a heading. */
.summary-figures {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3) var(--space-6);
}

.stat {
    display: flex;
    align-items: baseline;
    gap: var(--space-3);
    margin: 0;
}

.stat-value {
    color: var(--text-strong);
}

/* Timer, second in this table, is right-aligned like every figure. */
.table-periods th:nth-child(2),
.table-periods td:nth-child(2) {
    text-align: right;
}

/* The word column: narrow and right-aligned, so Afslut and Genåbn stand
   under each other with the pencil column outside them. */
.table-periods .col-word {
    width: 1%;
    white-space: nowrap;
    text-align: right;
}

.table-periods .row-action.is-armed {
    color: var(--color-danger);
}

/* ========== the toolbar ========== */
/* The filter row under the card's head: Fra, Til and Vis alle
   registreringer, bottom-aligned so the checkbox sits on the inputs'
   baseline. Tilføj and the burger live in the head above. */
.toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--space-4);
    margin-bottom: var(--space-5);
}

.toolbar-period {
    display: flex;
    align-items: flex-end;
    gap: var(--space-3);
}

.toolbar-period .field {
    min-width: 0;
}

/* Vis alle sits on the same baseline as the inputs it rests. */
.toolbar-period .check {
    padding-bottom: 0.6rem;
}

/* The card's head: the title centred on the button beside it, and a
   little more room under it than the front page's heads take, so the
   filter row and the rows below breathe. */
.list-card .card-head {
    align-items: center;
    margin-bottom: var(--space-5);
}

/* The title and, on a phone, the status filter beside it. */
.card-head-title {
    display: flex;
    align-items: center;
    gap: var(--space-4);
}

.status-filter-slot {
    display: inline-flex;
}

.status-filter-slot:empty {
    display: none;
}

/* Tilføj, the one button, at the right-hand end of the card's head; the
   rest of the tools sit behind the header's burger. */
.toolbar-actions {
    display: flex;
    align-items: center;
    gap: var(--space-3);
}

.toolbar-actions .btn {
    min-width: 7rem;
}

/* ========== the table ========== */
/* The card is the frame, so the table drops its own: no border, no
   sunken header band, and the first and last columns run flush with the
   card's content edge — DATO lines up under FRA, and the row actions
   under the toolbar's right edge. */
.table-hours {
    border: 0;
    border-radius: 0;
    background: transparent;
}

.table-hours th {
    background: transparent;
}

.table-hours th:first-child,
.table-hours td:first-child {
    padding-left: 0;
}

.table-hours th:last-child,
.table-hours td:last-child {
    padding-right: 0;
}

/* The entries table: Nr, Dato and Kategori hug their content on the
   left, the description owns the middle, and the row ends on its figure:
   Timer right-aligned just before the row actions. Auto layout would
   otherwise scatter the columns across the row with dead space between.
   The periods table, which shares .table-hours, has columns of its own
   and its own rules above. */
.table-entries th:nth-child(-n + 3),
.table-entries td:nth-child(-n + 3),
.table-entries th:nth-child(5),
.table-entries td:nth-child(5) {
    width: 1%;
    white-space: nowrap;
}

.table-entries td:nth-child(5),
.table-entries th:nth-child(5) {
    text-align: right;
}

/* Air between the fact cluster and the description. */
.table-entries th:nth-child(3),
.table-entries td:nth-child(3) {
    padding-right: var(--space-8);
}

.table-periods th:nth-child(-n + 2),
.table-periods td:nth-child(-n + 2) {
    width: 1%;
    white-space: nowrap;
}

/* A description keeps its own line breaks and wraps; it never widens
   the table. */
.table-hours .cell-description {
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.table-hours .col-actions {
    width: 1%;
    white-space: nowrap;
    text-align: right;
}

/* A settled row's lock: the pencil's footprint and size, in grey, and
   not a control — there is nothing to press. */
.row-lock {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-3);
    margin: calc(var(--space-3) * -1);
    vertical-align: middle;
    color: var(--text-muted);
}

.row-lock svg {
    display: block;
    width: 1rem;
    height: 1rem;
}

/* Gem on the left; Slet — or, in the categories dialog, the reason there
   is none — alone on the right, as far from Gem as the dialog allows. */
.dialog-actions .btn-danger,
.dialog-actions .category-in-use {
    margin-left: auto;
}

/* ========== the dialogs ========== */
/* The entry form is the page's main gesture; it gets a little more
   room than the frame's default. */
.entry-dialog {
    width: min(28rem, calc(100vw - var(--gutter) * 2));
}

/* Dato and Timer share a row — a date and a figure, not two sentences. */
.entry-when {
    display: grid;
    grid-template-columns: 1.4fr 1fr;
    gap: var(--space-4);
}

.category-hint {
    margin: 0 0 var(--space-4);
}

/* ========== the categories dialog ========== */
/* Shared by both tools (js/categories.js): two columns under the hint —
   the list on the left, a checkbox and a pencil on each line, the flats
   stepped in under the building, scrolling on its own when it outgrows
   the dialog; the form on the right, standing still, in the update
   dialog's pattern. The list is narrow and grows a line per flat, the
   form is two fields and a button: side by side neither waits on the
   other. */
.category-dialog {
    width: min(40rem, calc(100vw - var(--gutter) * 2));
}

.category-body {
    display: grid;
    grid-template-columns: minmax(10rem, max-content) 1fr;
    gap: var(--space-8);
    align-items: start;
}

/* The two columns are two permanent regions, so a hairline where they
   meet, with air on both sides of it; the list column hugs its longest
   name, so the pencils stand close to the names rather than at a far
   edge. */
.category-side {
    align-self: stretch;
    padding-right: var(--space-6);
    border-right: 1px solid var(--border-subtle);
}

/* A fixed height, so folding and unfolding change nothing around the
   list; a long one scrolls downward inside it. The padding holds the
   pencils' hit area, which reaches beyond each line, so a short list
   shows no scrollbar. */
.category-list {
    list-style: none;
    margin: 0 0 var(--space-3);
    padding: var(--space-3) var(--space-3) var(--space-3) 0;
    display: grid;
    align-content: start;
    gap: var(--space-2);
    height: min(16rem, 50vh);
    overflow-y: auto;
    overflow-x: hidden;
}

/* Under the list, Tilføj starts where the top-level lines' checkboxes
   do: past the fold slot and its gap, less the button's own padding. */
.category-side .dialog-fresh {
    margin-left: calc(1rem + var(--space-3) - var(--space-2));
}

/* The form column stands as tall as the list column, and its actions
   sit at the bottom, the frame's own distance from the edge — as in
   every other dialog. */
.category-main {
    align-self: stretch;
    display: flex;
    flex-direction: column;
}

.category-main .dialog-form {
    display: flex;
    flex-direction: column;
    flex: 1;
}

.category-main .dialog-actions {
    margin-top: auto;
}

/* Out of sight but not out of the layout: the space stays, so nothing
   around it moves when it comes and goes. */
.is-invisible {
    visibility: hidden;
}

/* The fold control leads a top-level line, a blank of the same width
   leads every other, so the checkboxes stand under each other. The
   chevron points right when the children are folded away, down when
   they are shown. */
.category-fold {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1rem;
    height: 1.5rem;
    padding: 0;
    margin: 0;
}

.category-fold svg {
    display: block;
    width: 1rem;
    height: 1rem;
    transition: transform var(--dur-fast) var(--ease);
}

.category-fold[aria-expanded="true"] svg {
    transform: rotate(90deg);
}

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

.category-item {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    font-size: var(--text-sm);
}

.category-item .check {
    flex: 1;
    min-width: 0;
}

.category-item.is-child {
    padding-left: var(--space-6);
}

/* Hidden reads hidden: the name steps back with its unticked box. */
.category-item.is-hidden .check {
    color: var(--text-muted);
}

/* The line the form holds: its pencil fills in teal — hollow for a
   tool, filled for the thing chosen — so the marker adds nothing to the
   line and nothing needs its space reserved. The update dialog marks
   with a teal rule instead, since its form sits below the list. */
.category-item.is-editing .row-action.is-icon {
    color: var(--color-accent);
}

.category-item.is-editing .row-action.is-icon svg {
    fill: currentColor;
}

.category-item.is-editing .check {
    color: var(--text-strong);
}

/* Beside the list, the form's title needs no rule above it: the column
   is the separation. */
.category-main .dialog-form-title {
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
}

.category-in-use {
    align-self: center;
    margin: 0;
    text-align: right;
}

/* ========== the inbox ========== */
/* A thought dropped before it is a case: one line to type in, the
   notes under it. The card sits above the register, shaped like it. */
.inbox-card {
    margin-bottom: var(--space-5);
}

.inbox-form {
    display: grid;
    gap: var(--space-2);
}

.inbox-line {
    display: flex;
    gap: var(--space-3);
}

.inbox-line .input {
    flex: 1;
    min-width: 0;
}

/* Tilføj takes the toolbar's button width, and the notes' actions
   column below takes the same, so Opret's left edge lines up with it. */
.inbox-line .btn,
.inbox-actions {
    width: 7rem;
    flex: none;
}

.inbox-actions {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
}

.inbox-list {
    list-style: none;
    margin: var(--space-4) 0 0;
    padding: 0;
    display: grid;
    gap: var(--space-2);
}

.inbox-list:empty {
    margin: 0;
}

.inbox-item {
    display: flex;
    align-items: baseline;
    gap: var(--space-3);
    font-size: var(--text-sm);
}

.inbox-date {
    flex: none;
}

.inbox-item-text {
    flex: 1;
    min-width: 0;
    overflow-wrap: anywhere;
}

.inbox-item .row-action {
    flex: none;
}

.inbox-item .row-action.is-armed {
    color: var(--color-danger);
}

/* Opret's own padding is pulled back so its text starts on the column's
   edge, where Tilføj's box starts. */
.inbox-actions .row-action:first-child {
    margin-left: calc(var(--space-2) * -1);
}

/* ========== Sager ========== */
/* The register's table — Sagsnr, Kategori, Dato, Beskrivelse, Ansvar,
   Frist, the pencil: every column but Beskrivelse hugs its content,
   and Beskrivelse owns the middle. Written against tbody and thead so it
   outranks the entries table's column rules, which this table inherits
   through .table-hours and which right-align its fourth column. */
.table-cases thead th:nth-child(-n + 3),
.table-cases tbody td:nth-child(-n + 3),
.table-cases thead th:nth-child(5),
.table-cases tbody td:nth-child(5),
.table-cases thead th:nth-child(6),
.table-cases tbody td:nth-child(6),
.table-cases thead th:nth-child(7),
.table-cases tbody td:nth-child(7) {
    width: 1%;
    white-space: nowrap;
}

.table-cases thead th:nth-child(4),
.table-cases tbody td:nth-child(4) {
    width: auto;
    white-space: normal;
    text-align: left;
}

/* The timer pads its second column to put air before the description;
   here Dato stands between them, so Kategori hugs its tags and the
   width goes to Beskrivelse. */
.table-cases thead th:nth-child(2),
.table-cases tbody td:nth-child(2) {
    padding-right: var(--space-4);
}

/* The title keeps a floor under its width, so on a phone the table
   scrolls sideways instead of squeezing the words into syllables. */
.table-cases .cell-description {
    min-width: 14rem;
}

/* A case and its updates are one block: no rules inside it, one rule
   under it where the next case begins. The date and initials lead an
   update, the words follow. */
.table-cases tbody td {
    border-bottom: 0;
}

.table-cases .row-case td {
    padding-bottom: var(--space-2);
}

.table-cases .row-update td {
    padding-top: 0;
}

.table-cases tbody tr:last-child td,
.table-cases tbody tr:has(+ .row-case) td {
    border-bottom: 1px solid var(--border-subtle);
}

.table-cases .cell-update {
    min-width: 14rem;
    color: var(--text-body);
    overflow-wrap: anywhere;
}

/* An update's date and who wrote it: the regular weight, like the words
   beside them, in the faint colour — colour steps them back, not weight.
   A light 300 was tried and dropped: it existed nowhere else on the site
   and made the medium figures above it read as bold. */
.table-cases .update-stamp {
    font-weight: var(--weight-regular);
    color: var(--text-faint);
}

.table-cases .update-by {
    text-align: center;
}

/* Ansvar: two or three letters, centred under their heading — on the
   case line and the update lines alike. */
.table-cases thead th:nth-child(5),
.table-cases tbody td:nth-child(5) {
    text-align: center;
}

/* A passed Frist on an open case: the date in the danger red, nothing
   more — the row order already puts it on top. På hold stands in the
   Status column as a plain word, muted. */
.table-cases tr.is-overdue .cell-when {
    color: var(--color-danger);
}

/* The status filter hangs from its column heading: the heading is a
   button drawn exactly like the other headings, with a funnel, and it
   opens the same flat panel the burger does, holding three checkboxes.
   Teal while the filter is not the resting one, so a narrowed list can
   be seen to be narrowed. */
.th-filter .menu {
    display: inline-flex;
}

.th-filter-button {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: 0;
    border: 0;
    background: none;
    font: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    color: inherit;
    cursor: pointer;
    transition: color var(--dur-fast) var(--ease);
}

.th-filter-button:hover,
.th-filter-button:focus-visible,
.th-filter-button[aria-expanded="true"],
.th-filter-button.is-filtering {
    color: var(--color-accent);
}

.th-filter-icon {
    width: 0.85rem;
    height: 0.85rem;
    margin-left: var(--space-1);
}

.th-filter .menu-panel {
    left: 0;
    right: auto;
    min-width: 9rem;
    gap: var(--space-2);
    text-transform: none;
    letter-spacing: normal;
    font: var(--font-body);
    font-size: var(--text-sm);
}

.table-cases .cell-status {
    white-space: nowrap;
}

/* The empty list's one line, in the hint's voice. */
.table-cases .cell-empty {
    padding-top: var(--space-4);
    color: var(--text-muted);
    white-space: normal;
}

/* A closed case steps back: the settled rows should not compete with
   the open ones when Afsluttet is ticked. */
.table-cases tr.is-closed td {
    color: var(--text-muted);
}

/* A case number leading a time entry's words: the same tag as the
   category, so the row reads as one set of facts. */
.tag-case {
    margin-right: var(--space-1);
}

/* The case dialog is a little wider than the entry's: three date-sized
   fields on one row. */
.case-dialog {
    width: min(34rem, calc(100vw - var(--gutter) * 2));
}

/* The update dialog: the case's updates as a list, a pencil on each,
   then the form. Wider than the frame's default, since a list of words
   needs room to be read. */
.update-dialog {
    width: min(34rem, calc(100vw - var(--gutter) * 2));
}

/* The case the dialog is about, standing out under the title: the
   section weight in ink, the number first. */
.update-case {
    margin: 0 0 var(--space-4);
    font: var(--font-h3);
    color: var(--text-strong);
}

.update-case .num {
    margin-right: var(--space-2);
    font-weight: var(--weight-semibold);
}

.update-list {
    list-style: none;
    margin: 0 0 var(--space-3);
    padding: 0;
    display: grid;
    gap: var(--space-2);
}

.update-item {
    display: flex;
    align-items: baseline;
    gap: var(--space-3);
    font-size: var(--text-sm);
}

.update-item .update-stamp {
    flex: none;
    color: var(--text-faint);
}

.update-item-text {
    flex: 1;
    min-width: 0;
    overflow-wrap: anywhere;
}

.update-item .row-action {
    flex: none;
}

/* The line the form holds: the teal rule, the site's marker for the
   thing in focus, and the words in ink. The negative margin keeps the
   text where it was; the padding takes its place inside the rule. */
.update-item.is-editing {
    margin-left: calc(var(--space-3) * -1);
    padding-left: calc(var(--space-3) - 3px);
    border-left: 3px solid var(--color-accent);
}

.update-item.is-editing .update-item-text {
    color: var(--text-strong);
}

.update-list-empty {
    margin: 0 0 var(--space-3);
}

/* Tilføj, under a dialog's list, only while the form holds an old item. */
.dialog-fresh {
    margin: 0 0 var(--space-3) calc(var(--space-2) * -1);
}

/* A dialog form's own heading, under the list it follows: which job the
   form is doing. */
.dialog-form-title {
    margin: var(--space-3) 0 var(--space-3);
    padding-top: var(--space-4);
    border-top: 1px solid var(--border-subtle);
    font: var(--font-h3);
    color: var(--text-strong);
}

/* The case line's two glyphs sit together at the row's end, a gap
   between them so they read as two. */
.table-cases .row-case .col-actions {
    white-space: nowrap;
}

.table-cases .row-case .col-actions .row-action + .row-action {
    margin-left: var(--space-2);
}

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

.case-who {
    display: grid;
    grid-template-columns: 1.4fr 0.8fr 1fr;
    gap: var(--space-4);
}

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

/* ========== development notice ========== */
/* Only ever visible on localhost. Loud, so a faked session cannot be
   mistaken for a real one. */
.dev-notice {
    margin: 0;
    padding: var(--space-2) var(--gutter);
    background: var(--color-accent-soft);
    color: var(--text-strong);
    font: var(--font-label);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    text-align: center;
}

/* ========== responsive ========== */
@media (max-width: 600px) {
    /* Phone width: Fra and Til stay side by side; Vis alle registreringer
       takes its own line under them. */
    .toolbar,
    .page-top {
        align-items: stretch;
    }

    .toolbar-period {
        flex-wrap: wrap;
    }

    .toolbar-period .field {
        flex: 1 1 8rem;
    }

    .toolbar-period .check {
        flex-basis: 100%;
        padding-bottom: 0;
    }

}

@media (max-width: 880px) {
    .entry-when,
    .case-facts,
    .case-who,
    .update-when {
        grid-template-columns: 1fr;
    }

    /* On a phone the dialog's two columns stack back to list, then form,
       and the form's title takes its rule again. */
    .category-body {
        grid-template-columns: 1fr;
    }

    .category-side {
        padding-right: 0;
        border-right: 0;
    }

    .category-list {
        height: auto;
        max-height: 50vh;
    }

    .category-main .dialog-form-title {
        margin-top: var(--space-3);
        padding-top: var(--space-4);
        border-top: 1px solid var(--border-subtle);
    }

    .table {
        display: block;
        overflow-x: auto;
    }
}

/* ========== phone: the lists as stacks ========== */
/* The desktop tables stay as they are; at phone width the stylesheet
   lays each row out as a stack instead — a caption line (the number
   left, the controls right, ruled under), then one line per fact with
   the heading the table lost on the left and the value on the right,
   and air before the next entry. One table, one set of rules, no second
   markup. Tried first and dropped: a white card per entry with a row of
   headings over a row of values and the description in a grey box —
   too many frames and too many headings on a small screen. */
@media (max-width: 600px) {
    /* The summary figures as lines: label left, figure right. */
    .summary-figures {
        flex-basis: 100%;
        display: grid;
        gap: var(--space-2);
    }

    .stat {
        justify-content: space-between;
    }

    /* ---- shared shape ---- */
    .table-entries,
    .table-cases {
        display: block;
        overflow: visible;
    }

    .table-entries tbody,
    .table-cases tbody {
        display: block;
    }

    .table-entries thead {
        display: none;
    }

    /* An entry or a case: a grid of one column, the caption line's two
       cells sharing the first row. :nth-child(n) only lifts the rules
       over the desktop column rules and their 1% widths. */
    .table-entries tr,
    .table-cases .row-case {
        display: grid;
        grid-template-columns: auto 1fr auto;
        margin-top: var(--space-6);
    }

    .table-entries tbody tr:first-child,
    .table-cases tbody tr:first-child {
        margin-top: 0;
    }

    .table-entries td:nth-child(n),
    .table-cases .row-case td:nth-child(n) {
        display: grid;
        grid-template-columns: 7rem 1fr;
        grid-column: 1 / -1;
        align-items: baseline;
        justify-items: end;
        padding: var(--space-2) 0 0;
        border: 0;
        width: auto;
        white-space: nowrap;
        text-align: right;
    }

    /* The heading the table lost, on the line's left, in its own voice. */
    .table-entries td::before,
    .table-cases .row-case td::before {
        display: block;
        justify-self: start;
        font: var(--font-label);
        letter-spacing: var(--tracking-label);
        text-transform: uppercase;
        color: var(--text-muted);
        text-align: left;
    }

    /* The description: its heading on a line of its own — with the case
       tag at the line's far end when the entry is booked to one — and
       under it the words across the whole width in a box with a subtle
       outline, so several lines hold together instead of floating in
       the stack. */
    .table-entries td.cell-description,
    .table-cases .row-case td.cell-description {
        grid-template-columns: 1fr auto;
        justify-items: stretch;
        align-items: center;
        text-align: left;
        white-space: pre-wrap;
        min-width: 0;
    }

    .table-entries td.cell-description .tag-case {
        justify-self: end;
        margin: 0;
    }

    .table-entries td.cell-description .cell-text,
    .table-cases .row-case td.cell-description .cell-text {
        display: block;
        grid-column: 1 / -1;
        margin-top: var(--space-2);
        padding: var(--space-2) var(--space-3);
        border: 1px solid var(--border-subtle);
        border-radius: var(--radius-sm);
        overflow-wrap: anywhere;
    }

    /* The caption line: number and tag on the left, the controls on the
       right, one line under all of it — the inputs' stronger hairline,
       so where one entry ends and the next begins can be seen at a
       glance. */
    /* Written against tr as well, to outweigh the table's own rule that
       the last row carries no line. */
    .table-entries tr td.col-actions,
    .table-cases tr.row-case td.col-actions {
        display: flex;
        justify-content: flex-end;
        gap: var(--space-2);
        grid-column: 3;
        padding: 0 0 var(--space-2);
        border-bottom: 1px solid var(--border-input);
    }

    /* ---- the timer: T26-012, the tag and the pencil; Dato, Timer,
       Beskrivelse ---- */
    .table-entries tr td:nth-child(1),
    .table-entries tr td:nth-child(3) {
        display: flex;
        align-items: center;
        grid-row: 1;
        padding: 0 0 var(--space-2);
        border-bottom: 1px solid var(--border-input);
        text-align: left;
    }

    .table-entries tr td:nth-child(1) {
        grid-column: 1;
        color: var(--text-strong);
    }

    .table-entries tr td:nth-child(3) {
        grid-column: 2;
        padding-left: var(--space-3);
    }

    .table-entries td:nth-child(6) {
        grid-row: 1;
    }

    .table-entries td:nth-child(2) {
        grid-row: 2;
    }

    .table-entries td:nth-child(2)::before {
        content: "Dato";
    }

    .table-entries td:nth-child(5) {
        grid-row: 3;
    }

    .table-entries td:nth-child(5)::before {
        content: "Timer";
    }

    .table-entries td:nth-child(4) {
        grid-row: 4;
    }

    .table-entries td:nth-child(4)::before {
        content: "Beskrivelse";
    }

    /* ---- the register: S26-001, the tag and the two glyphs; Dato,
       Ansvar, Frist, Status, Beskrivelse; then the updates ---- */
    .table-cases thead {
        display: none;
    }

    /* The status filter beside the card's title, where js/cases.js puts
       it at this width: the heading's own voice, since it is no longer
       inside a heading to inherit it from. */
    .status-filter-slot .th-filter-button {
        font: var(--font-label);
        letter-spacing: var(--tracking-label);
        text-transform: uppercase;
        color: var(--text-muted);
    }

    .status-filter-slot .menu-panel {
        left: 0;
        right: auto;
        min-width: 9rem;
        gap: var(--space-2);
        text-transform: none;
        letter-spacing: normal;
        font: var(--font-body);
        font-size: var(--text-sm);
    }

    /* The number, then the tag beside it, on the caption line, the two
       centred on each other. */
    .table-cases tr.row-case td:nth-child(1),
    .table-cases tr.row-case td:nth-child(2) {
        display: flex;
        align-items: center;
        grid-row: 1;
        padding: 0 0 var(--space-2);
        border-bottom: 1px solid var(--border-input);
        text-align: left;
    }

    .table-cases .row-case td:nth-child(1) {
        grid-column: 1;
        color: var(--text-strong);
    }

    .table-cases tr.row-case td:nth-child(2) {
        grid-column: 2;
        padding-left: var(--space-3);
    }

    .table-cases .row-case td:nth-child(8) {
        grid-row: 1;
    }

    .table-cases .row-case td:nth-child(3) {
        grid-row: 2;
    }

    .table-cases .row-case td:nth-child(3)::before {
        content: "Dato";
    }

    .table-cases .row-case td:nth-child(5) {
        grid-row: 3;
    }

    .table-cases .row-case td:nth-child(5)::before {
        content: "Ansvar";
    }

    .table-cases .row-case td:nth-child(6) {
        grid-row: 4;
    }

    .table-cases .row-case td:nth-child(6)::before {
        content: "Frist";
    }

    /* No Frist, no line: an empty value would only say what is absent. */
    .table-cases .row-case td:nth-child(6):empty {
        display: none;
    }

    .table-cases .row-case td:nth-child(7) {
        grid-row: 5;
    }

    .table-cases .row-case td:nth-child(7)::before {
        content: "Status";
    }

    .table-cases .row-case td:nth-child(4) {
        grid-row: 6;
    }

    .table-cases .row-case td:nth-child(4)::before {
        content: "Beskrivelse";
    }

    /* An update in the inbox note's shape: its date left and who wrote
       it right on one line, faint, and the words under them in the same
       box across the width. */
    .table-cases .row-update {
        display: grid;
        grid-template-columns: 1fr auto;
        row-gap: var(--space-2);
        align-items: center;
        padding-top: var(--space-3);
    }

    .table-cases .row-update td:nth-child(n) {
        display: none;
        padding: 0;
        border: 0;
    }

    .table-cases .row-update td:nth-child(3),
    .table-cases .row-update td:nth-child(4),
    .table-cases .row-update td:nth-child(5) {
        display: block;
    }

    /* The date and the initials in the body colour here, not the faint
       one the table uses: the update's own line and box already step it
       back, and faint beside the strong dates above read as disabled. */
    .table-cases .row-update td:nth-child(3) {
        grid-area: 1 / 1;
        color: var(--text-body);
    }

    .table-cases .row-update td:nth-child(5) {
        grid-area: 1 / 2;
        text-align: right;
        color: var(--text-body);
    }

    .table-cases .row-update td.cell-update {
        grid-area: 2 / 1 / 3 / 3;
        min-width: 0;
        padding: var(--space-2) var(--space-3);
        border: 1px solid var(--border-subtle);
        border-radius: var(--radius-sm);
        white-space: normal;
    }

    /* An inbox note: the date and the actions on one line, centred on
       each other, and the words under them in the same box the
       descriptions get, across the card. */
    .inbox-list {
        gap: var(--space-4);
    }

    .inbox-item {
        display: grid;
        grid-template-columns: auto 1fr;
        align-items: center;
        row-gap: var(--space-2);
    }

    .inbox-item .inbox-date {
        grid-area: 1 / 1;
    }

    .inbox-item .inbox-actions {
        grid-area: 1 / 2;
        justify-self: end;
        align-items: center;
        width: auto;
        gap: var(--space-3);
    }

    .inbox-item .inbox-item-text {
        grid-area: 2 / 1 / 3 / 3;
        padding: var(--space-2) var(--space-3);
        border: 1px solid var(--border-subtle);
        border-radius: var(--radius-sm);
    }

    /* The empty list's one line, as plain words. */
    .table-cases .cell-empty {
        display: block;
        padding: var(--space-3) 0;
        border: 0;
    }
}

/* ========== print ========== */
/* Udskriv prints the filtered list as a clean sheet: the heading, the
   period, the sums and the table. Everything for *doing* — the toolbar,
   the header, the banners — stays on screen. */
.print-head {
    display: none;
}

@media print {
    .site-header,
    .dev-notice,
    .page-head,
    .periods-card,
    .inbox-card,
    .toolbar,
    .banner,
    #loading-note,
    .table-hours .col-actions,
    .th-filter-icon,
    .menu-panel {
        display: none !important;
    }

    body {
        background: #fff;
    }

    .list-card {
        border: 0;
        padding: 0;
    }

    .print-head {
        display: block;
        margin-bottom: var(--space-4);
    }

    .print-title {
        margin: 0 0 var(--space-1);
        font: var(--font-h2);
        color: var(--text-strong);
    }

    .print-period {
        margin: 0;
        font: var(--font-label);
        letter-spacing: var(--tracking-label);
        text-transform: uppercase;
        color: var(--text-body);
    }
}
