html, body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", sans-serif;
}

a, .btn-link {
    color: #006bb7;
}

.btn-primary {
    color: #fff;
    background-color: #1b6ec2;
    border-color: #1861ac;
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
    box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

.content {
    padding-top: 1.1rem;
}

/* Keep dt/dd row heights consistent whether or not a value is present */
dl.row dd {
    min-height: 1.5em;
}

h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid #e50000;
}

.validation-message {
    color: #e50000;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}

.filter-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem;
    margin-bottom: 0.5rem;
}

.filter-bar label {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.data-grid tr {
    height: 1em;
}

.data-grid tbody tr:not([aria-rowindex]) {
    display: none;
}

.data-grid th {
    padding-left: 0;
}

.data-grid th button,
.data-grid th .col-header-content {
    padding-left: 0;
}

/* The count/link columns are right-aligned but not sortable. Force header and cells to share the
   same right padding, drop QuickGrid's themed col-gap on the header, and right-align the title text
   (its default row-reverse leaves a slot for a sort arrow these columns never show). These target
   the only right-aligned (col-justify-end) columns in the app. */
.data-grid th.col-justify-end,
.data-grid td.col-justify-end {
    /* !important beats QuickGrid's high-specificity themed cell padding so the header title and the
       numbers below it share exactly the same right edge. */
    padding-right: 1rem !important;
}

.data-grid th.col-justify-end .col-header-content {
    padding-right: 0;
}

/* Non-sortable only (QuickGrid renders a sortable title as a <button>, a plain one as a <div>).
   QuickGrid's own row-reverse reserves the leading slot for a sort arrow these columns never show,
   which would hold the title off the right edge — so lay them out as a plain row pushed right. */
.data-grid th.col-justify-end .col-title:not(button) {
    flex-direction: row;
    justify-content: flex-end;
    /* The theme gives col-title 0.4rem of horizontal padding; drop it on the right so the title
       text ends on the same edge as the numbers instead of ~half a character short. */
    padding-right: 0;
}

/* A sortable right-aligned column (reports grid, "Omsætning") keeps QuickGrid's row-reverse: it puts
   the sort arrow *before* the title, leaving the title text itself flush right. Forcing the plain-row
   layout above onto these would park the arrow to the right of the title and shove the text ~1.4rem
   (arrow + gap) clear of the numbers. Only the theme's right padding has to go. */
.data-grid th.col-justify-end button.col-title {
    padding-right: 0;
}

/* Centre the header title over a centred column. QuickGrid's col-title is a row-reverse flex that
   reserves a slot for the sort arrow, which would push the title off centre on the columns that
   never show one. */
.data-grid th.col-justify-center .col-title {
    flex-direction: row;
    justify-content: center;
    padding-left: 0;
    padding-right: 0;
}

/* Reserve room for the action-icon column so column widths stay stable when there are no rows. */
.data-grid th:last-child,
.data-grid td:last-child {
    min-width: 4.2rem;
    white-space: nowrap;
}

/* Highlight the row the user last acted on (an action icon or the property count), so it stands out
   when they return from the details/edit/... page. The current row renders a hidden .row-current
   marker in one cell; :has() lifts that to the whole row. */
.data-grid tbody tr:has(.row-current) > td {
    background-color: rgba(13, 110, 253, 0.14);
}

@media (prefers-color-scheme: dark) {
    .data-grid tbody tr:has(.row-current) > td {
        background-color: rgba(13, 110, 253, 0.30);
    }
}

/* Fixed layout keeps the Users grid's column widths identical whether or not rows are shown. */
.users-table {
    table-layout: fixed;
    width: 100%;
}

    .users-table th:nth-child(1),
    .users-table td:nth-child(1) {
        width: 25.5%; /* Email */
    }

    .users-table th:nth-child(2),
    .users-table td:nth-child(2) {
        width: 22%; /* Username */
    }

    .users-table th:nth-child(3),
    .users-table td:nth-child(3) {
        width: 26%; /* Member */
    }

    .users-table th:nth-child(4),
    .users-table td:nth-child(4) {
        width: 7.5rem; /* Confirmed */
    }

    .users-table th:nth-child(5),
    .users-table td:nth-child(5) {
        width: 9rem; /* Disabled */
    }

    .users-table th:nth-child(6),
    .users-table td:nth-child(6) {
        width: 6rem; /* Actions: details, edit, disable/enable, delete */
    }

    /* "Bekræftet" and "Deaktiveret" are long words over two narrow yes/no columns, and the theme
       spends 2.8rem of each header on everything but the text: a 1rem gap to the next column, the
       title's own 0.4rem of right padding, a 0.4rem gap to the sort arrow, and the arrow's 1rem
       slot. That is what puts them into an ellipsis. Reclaim the first two — the arrow and its gap
       have to stay — rather than widening the columns at Email's and Member's expense. A quarter of
       a rem is left so the two headers cannot end up touching. The cells below keep the theme's full
       gap, so the values still stand clear of the action icons. */
    .users-table th:nth-child(4) .col-header-content,
    .users-table th:nth-child(5) .col-header-content {
        padding-right: 0.25rem;
    }

    .users-table th:nth-child(4) .col-title,
    .users-table th:nth-child(5) .col-title {
        padding-right: 0;
    }

/* Fixed layout keeps the Associations grid's column widths identical whether or not rows are shown. */
.associations-table {
    table-layout: fixed;
    width: 100%;
}

    .associations-table th:nth-child(1),
    .associations-table td:nth-child(1) {
        width: 35%; /* Name */
    }

    .associations-table th:nth-child(2),
    .associations-table td:nth-child(2) {
        width: 6rem; /* Cvr */
    }

    .associations-table th:nth-child(3),
    .associations-table td:nth-child(3) {
        width: 25%; /* Postal code/City */
    }

    .associations-table th:nth-child(4),
    .associations-table td:nth-child(4) {
        width: 7.5rem; /* Defunct */
    }

    .associations-table th:nth-child(5),
    .associations-table td:nth-child(5) {
        width: 7.5rem; /* Actions: properties, details, edit, disable/enable, delete */
    }

.properties-table {
    table-layout: fixed;
    width: 100%;
}

    .properties-table th:nth-child(1),
    .properties-table td:nth-child(1) {
        width: 15ch; /* Number: max four characters, plus header and sort arrow */
    }

    .properties-table th:nth-child(2),
    .properties-table td:nth-child(2) {
        width: auto; /* Name flexes to fill remaining space */
    }

    .properties-table th:nth-child(3),
    .properties-table td:nth-child(3) {
        width: 14rem; /* Group: the property group's number and name, or a dash */
    }

    .properties-table th:nth-child(4),
    .properties-table td:nth-child(4) {
        width: 8.8rem; /* Members: count */
    }

    .properties-table th:nth-child(5),
    .properties-table td:nth-child(5) {
        width: 10rem; /* Defunct */
    }

    .properties-table th:nth-child(6),
    .properties-table td:nth-child(6) {
        width: 5rem; /* Actions: edit, disable/enable, delete */
    }

/* The property-group grid repeats the Properties layout, but its third column is the exclusivity
   flag and its count column is headed "Egenskaber" rather than "Medlemmer". */
.property-groups-table {
    table-layout: fixed;
    width: 100%;
}

    .property-groups-table th:nth-child(1),
    .property-groups-table td:nth-child(1) {
        width: 15ch; /* Number: matches the Properties grid's Number column */
    }

    .property-groups-table th:nth-child(2),
    .property-groups-table td:nth-child(2) {
        width: auto; /* Name flexes to fill remaining space */
    }

    .property-groups-table th:nth-child(3),
    .property-groups-table td:nth-child(3) {
        width: 9rem; /* Exclusive: yes/no, plus header and sort arrow */
    }

    .property-groups-table th:nth-child(4),
    .property-groups-table td:nth-child(4) {
        width: 10rem; /* Properties: count, headed by the longer word "Egenskaber" */
    }

    .property-groups-table th:nth-child(5),
    .property-groups-table td:nth-child(5) {
        width: 10rem; /* Defunct */
    }

    .property-groups-table th:nth-child(6),
    .property-groups-table td:nth-child(6) {
        width: 5rem; /* Actions: edit, disable/enable, delete */
    }

/* The reporting-period editor holds exactly three rows, one per report, so it is a plain input grid
   like the range editor rather than a QuickGrid. */
.report-periods-table {
    table-layout: fixed;
    width: 100%;
}

    .report-periods-table th:nth-child(1),
    .report-periods-table td:nth-child(1) {
        width: auto; /* Name flexes to fill remaining space */
    }

    .report-periods-table th:nth-child(2),
    .report-periods-table td:nth-child(2),
    .report-periods-table th:nth-child(3),
    .report-periods-table td:nth-child(3) {
        width: 12rem; /* Opens/Closes: a month name in the select, plus the header */
    }

    .report-periods-table th:nth-child(4),
    .report-periods-table td:nth-child(4) {
        width: 9rem; /* Disabled: checkbox under the longer word "Deaktiveret" */
    }

    .report-periods-table th:nth-child(5),
    .report-periods-table td:nth-child(5) {
        width: 8rem; /* Open now: yes/no */
    }

/* The postal-code range editor is a plain input grid rather than a QuickGrid, but it shares the
   fixed layout so the inputs keep their width as rows are added and removed. */
.ranges-table {
    table-layout: fixed;
    width: 100%;
}

    .ranges-table th:nth-child(1),
    .ranges-table td:nth-child(1) {
        width: auto; /* Property flexes to fill remaining space */
    }

    .ranges-table th:nth-child(2),
    .ranges-table td:nth-child(2),
    .ranges-table th:nth-child(3),
    .ranges-table td:nth-child(3) {
        width: 10rem; /* From/To: a four-digit code plus the header */
    }

    .ranges-table th:nth-child(4),
    .ranges-table td:nth-child(4) {
        width: 5rem; /* Actions: delete row */
    }

.categories-table {
    table-layout: fixed;
    width: 100%;
}

    .categories-table th:nth-child(1),
    .categories-table td:nth-child(1) {
        width: 15ch; /* Number: matches the Properties grid's Number column */
    }

    .categories-table th:nth-child(2),
    .categories-table td:nth-child(2) {
        width: auto; /* Name flexes to fill remaining space */
    }

    .categories-table th:nth-child(3),
    .categories-table td:nth-child(3) {
        width: 8.8rem; /* Members: count */
    }

    .categories-table th:nth-child(4),
    .categories-table td:nth-child(4) {
        width: 12rem; /* Reporting: the reports the category takes part in */
    }

    .categories-table th:nth-child(5),
    .categories-table td:nth-child(5) {
        width: 10rem; /* Defunct */
    }

    .categories-table th:nth-child(6),
    .categories-table td:nth-child(6) {
        width: 5rem; /* Actions: edit, disable/enable, delete */
    }

/* The contact grids repeat the Properties/Categories layouts, but their count column is headed
   "Kontaktpersoner" rather than "Medlemmer" and needs the extra width to spell it out. */
.contact-properties-table,
.contact-roles-table {
    table-layout: fixed;
    width: 100%;
}

    .contact-properties-table th:nth-child(1),
    .contact-properties-table td:nth-child(1),
    .contact-roles-table th:nth-child(1),
    .contact-roles-table td:nth-child(1) {
        width: 15ch; /* Number: matches the Properties grid's Number column */
    }

    .contact-properties-table th:nth-child(2),
    .contact-properties-table td:nth-child(2),
    .contact-roles-table th:nth-child(2),
    .contact-roles-table td:nth-child(2) {
        width: auto; /* Name flexes to fill remaining space */
    }

    .contact-properties-table th:nth-child(3),
    .contact-properties-table td:nth-child(3),
    .contact-roles-table th:nth-child(3),
    .contact-roles-table td:nth-child(3) {
        width: 14rem; /* Contacts: count, headed by the full word "Kontaktpersoner" */
    }

    .contact-properties-table th:nth-child(4),
    .contact-properties-table td:nth-child(4),
    .contact-roles-table th:nth-child(4),
    .contact-roles-table td:nth-child(4) {
        width: 10rem; /* Defunct */
    }

    .contact-properties-table th:nth-child(5),
    .contact-properties-table td:nth-child(5),
    .contact-roles-table th:nth-child(5),
    .contact-roles-table td:nth-child(5) {
        width: 5rem; /* Actions: edit, disable/enable, delete */
    }

/* The monthly staff groups: a name that flexes, then the two salary bounds and three short
   yes/no columns, all of which are sized to their headers rather than their contents. */
.staff-monthly-types-table {
    table-layout: fixed;
    width: 100%;
}

    .staff-monthly-types-table th:nth-child(1),
    .staff-monthly-types-table td:nth-child(1) {
        width: auto; /* Name flexes to fill remaining space */
    }

    .staff-monthly-types-table th:nth-child(2),
    .staff-monthly-types-table td:nth-child(2) {
        width: 8rem; /* Manager */
    }

    .staff-monthly-types-table th:nth-child(3),
    .staff-monthly-types-table td:nth-child(3),
    .staff-monthly-types-table th:nth-child(4),
    .staff-monthly-types-table td:nth-child(4) {
        width: 11rem; /* Minimum/maximum salary: a five-digit amount, its header and the sort arrow */
    }

    .staff-monthly-types-table th:nth-child(5),
    .staff-monthly-types-table td:nth-child(5) {
        width: 12rem; /* Education fund: headed by the full word */
    }

    .staff-monthly-types-table th:nth-child(6),
    .staff-monthly-types-table td:nth-child(6) {
        width: 10rem; /* Defunct */
    }

    .staff-monthly-types-table th:nth-child(7),
    .staff-monthly-types-table td:nth-child(7) {
        width: 5rem; /* Actions: edit, disable/enable, delete */
    }

/* The hourly staff types: the rate count and the two short columns beside it are sized to their
   headers, and the name takes the rest. */
.staff-hourly-types-table {
    table-layout: fixed;
    width: 100%;
}

    .staff-hourly-types-table th:nth-child(1),
    .staff-hourly-types-table td:nth-child(1) {
        width: auto; /* Name flexes to fill remaining space */
    }

    .staff-hourly-types-table th:nth-child(2),
    .staff-hourly-types-table td:nth-child(2) {
        width: 8rem; /* Rates: count, linking to the rate editor */
    }

    .staff-hourly-types-table th:nth-child(3),
    .staff-hourly-types-table td:nth-child(3) {
        width: 12rem; /* Education fund: headed by the full word */
    }

    .staff-hourly-types-table th:nth-child(4),
    .staff-hourly-types-table td:nth-child(4) {
        width: 10rem; /* Defunct */
    }

    .staff-hourly-types-table th:nth-child(5),
    .staff-hourly-types-table td:nth-child(5) {
        width: 5rem; /* Actions: edit, disable/enable, delete */
    }

/* The rate editor is a plain input grid rather than a QuickGrid, as the postal-code one is, but it
   shares the fixed layout so the inputs keep their width as rows are added and removed. */
.rates-table {
    table-layout: fixed;
    width: 100%;
}

    .rates-table th:nth-child(1),
    .rates-table td:nth-child(1) {
        width: auto; /* Name flexes to fill remaining space */
    }

    .rates-table th:nth-child(2),
    .rates-table td:nth-child(2),
    .rates-table th:nth-child(3),
    .rates-table td:nth-child(3) {
        width: 11rem; /* Minimum/maximum rate: an amount with two decimals, plus the header */
    }

    .rates-table th:nth-child(4),
    .rates-table td:nth-child(4) {
        width: 8rem; /* Defunct: a checkbox under the header */
    }

    .rates-table th:nth-child(5),
    .rates-table td:nth-child(5) {
        width: 5rem; /* Actions: delete row */
    }

/* Fixed layout keeps the Members grid's column widths identical whether or not rows are shown. */
.members-table {
    table-layout: fixed;
    width: 100%;
}

    .members-table th:nth-child(1),
    .members-table td:nth-child(1) {
        width: 13ch; /* Account: max six characters, plus room for the spelled-out header and sort arrow */
    }

    .members-table th:nth-child(2),
    .members-table td:nth-child(2) {
        width: 12rem; /* Member category */
    }

    .members-table th:nth-child(3),
    .members-table td:nth-child(3) {
        width: auto; /* Name flexes to fill remaining space */
    }

    .members-table th:nth-child(4),
    .members-table td:nth-child(4) {
        width: 7rem; /* Contacts: count, matches the Properties column */
    }

    .members-table th:nth-child(5),
    .members-table td:nth-child(5) {
        width: 7rem; /* Properties: count */
    }

    .members-table th:nth-child(6),
    .members-table td:nth-child(6) {
        width: 6rem; /* Actions: details, edit, disable/enable, delete */
    }

/* The company-wide report grids — turnover and wages — repeat the Members grid's leading columns,
   then the period's one figure. Both have the same six columns, so they share this. */
.reports-table {
    table-layout: fixed;
    width: 100%;
}

    .reports-table th:nth-child(1),
    .reports-table td:nth-child(1) {
        width: 13ch; /* Account: matches the Members grid */
    }

    .reports-table th:nth-child(2),
    .reports-table td:nth-child(2) {
        width: 12rem; /* Member category */
    }

    .reports-table th:nth-child(3),
    .reports-table td:nth-child(3) {
        width: auto; /* Name flexes to fill remaining space */
    }

    .reports-table th:nth-child(4),
    .reports-table td:nth-child(4) {
        width: 12rem; /* The figure — turnover or payroll: right-aligned, grouped to millions */
    }

    .reports-table th:nth-child(5),
    .reports-table td:nth-child(5) {
        width: 9rem; /* Confirmed: a check mark, under a header shorter than the date one it replaced */
    }

    .reports-table th:nth-child(6),
    .reports-table td:nth-child(6) {
        width: 3rem; /* Actions: edit only */
    }

/* The member's own report lists: one row per year, so they need none of the width the company-wide
   grids spend on account and name. Capped rather than stretched across the page. */
.member-report-table {
    table-layout: fixed;
    width: 100%;
    max-width: 34rem;
}

    .member-report-table th:nth-child(1),
    .member-report-table td:nth-child(1) {
        width: 7rem; /* Year */
    }

    .member-report-table th:nth-child(2),
    .member-report-table td:nth-child(2) {
        width: 12rem; /* The figure — turnover or payroll: right-aligned amount */
    }

    .member-report-table th:nth-child(3),
    .member-report-table td:nth-child(3) {
        width: 7rem; /* Confirmed: sized to its header, since the cell holds only a check mark */
    }

    .member-report-table th:nth-child(4),
    .member-report-table td:nth-child(4) {
        /* 4.2rem, not less: .data-grid td:last-child sets that as a min-width, so a smaller width
           here would simply be ignored. */
        width: 4.2rem; /* Actions: edit, and only on the open year */
    }

/* The wide grids push their action icons to the right edge; with only four narrow columns here that
   would strand the pencil far from the figures it belongs to. Left-align it in its column so it sits
   just past the "Bekræftet" header instead. */
.member-report-table .grid-action-bar {
    justify-content: flex-start;
    margin-right: 0;
}

/* Keeps the period selector's label on the control's baseline, as the rows-per-page selector does. */
.period-picker {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    white-space: nowrap;
}

/* Role (3rd) holds a short label; pin it so it neither stretches on a long role name nor collapses
   when the page happens to show none. */
.contacts-table th:nth-child(3),
.contacts-table td:nth-child(3) {
    width: 9rem;
    min-width: 9rem;
    max-width: 9rem;
}

/* The contacts grid's E-mail (4th), Direct phone (5th) and Mobile (6th) columns carry only a check
   mark, so pin them narrow and give the space back to Member and Name. E-mail keeps 6rem for its
   sort arrow; the other two need only their one-word headers ("Direkte", "Mobil"). */
.contacts-table th:nth-child(4),
.contacts-table td:nth-child(4) {
    width: 6rem;
    min-width: 6rem;
    max-width: 6rem;
}

.contacts-table th:nth-child(5),
.contacts-table td:nth-child(5),
.contacts-table th:nth-child(6),
.contacts-table td:nth-child(6) {
    width: 4.75rem;
    min-width: 4.75rem;
    max-width: 4.75rem;
}

/* Pin the contacts grid's Properties (7th) and User (8th) columns to a steady width so they don't
   resize as their content varies between "", counts, "Yes" and "Disabled" across filters and pages.
   In an auto-layout table a plain width is only a suggestion, so min = max = width removes the
   flexibility for just these two; the remaining columns keep their content-based sizing.
   Properties holds only a count, so it sits narrower than User's "Deaktiveret". */
.contacts-table th:nth-child(7),
.contacts-table td:nth-child(7) {
    width: 6.4rem;
    min-width: 6.4rem;
    max-width: 6.4rem;
    white-space: nowrap;
}

.contacts-table th:nth-child(8),
.contacts-table td:nth-child(8) {
    width: 8rem;
    min-width: 8rem;
    max-width: 8rem;
    white-space: nowrap;
}

/* These four columns are sized to their (bold) headers, and three layers of padding sit between the
   column edge and the title text: Bootstrap's 0.5rem-a-side cell padding, the default theme's
   --col-gap on .col-header-content, and another 0.4rem a side on .col-title. Together that is well
   over a rem of a ~5rem column — enough that QuickGrid's .col-title-text ellipsizes "Direkte" and
   "Egenskaber" while the row still has room to spare. Strip all three back to the gap the columns
   actually need. !important beats .table > :not(caption) > * > *; the .data-grid prefix outranks
   both the theme and the col-justify-end padding set further up. */
.data-grid .contacts-table th:nth-child(4),
.data-grid .contacts-table td:nth-child(4),
.data-grid .contacts-table th:nth-child(5),
.data-grid .contacts-table td:nth-child(5),
.data-grid .contacts-table th:nth-child(6),
.data-grid .contacts-table td:nth-child(6) {
    padding-left: 0.2rem !important;
    padding-right: 0.2rem !important;
}

/* Properties is right-aligned, so it keeps a wider right gap to hold the count off the next column. */
.data-grid .contacts-table th:nth-child(7),
.data-grid .contacts-table td:nth-child(7) {
    padding-left: 0.2rem !important;
    padding-right: 0.5rem !important;
}

.data-grid .contacts-table th:nth-child(4) .col-header-content,
.data-grid .contacts-table th:nth-child(5) .col-header-content,
.data-grid .contacts-table th:nth-child(6) .col-header-content,
.data-grid .contacts-table th:nth-child(7) .col-header-content {
    padding-right: 0;
}

.data-grid .contacts-table th:nth-child(4) .col-title,
.data-grid .contacts-table th:nth-child(5) .col-title,
.data-grid .contacts-table th:nth-child(6) .col-title,
.data-grid .contacts-table th:nth-child(7) .col-title {
    padding-left: 0;
    padding-right: 0;
}

/* The action-icon column (9th, last) is otherwise only min-width-bounded, so auto-layout lets it
   absorb slack and drift — pin it too (three icons ≈ 4.2rem, so 5rem holds them). */
.contacts-table th:nth-child(9),
.contacts-table td:nth-child(9) {
    width: 5rem;
    min-width: 5rem;
    max-width: 5rem;
}

/* Check mark for the columns that only report whether a value is stored (see StoredMark.razor).
   Same green as the enable action, so "present" reads the same way across the grid. */
.grid-check {
    display: inline-block;
    width: 1rem;
    height: 1rem;
    background-size: contain;
    background-repeat: no-repeat;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%23198754' viewBox='0 0 16 16'%3E%3Cpath d='M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z'/%3E%3C/svg%3E");
}

/* Render the property count as a plain link-styled number, without button chrome or underline. */
.property-count {
    text-decoration: none;
    vertical-align: baseline;
    border: 0;
}

.grid-action-bar {
    display: flex;
    justify-content: flex-end;
    margin-right: -1.7rem; /* fine-tuned shift to align icon block with row separators */
}

.grid-action {
    display: inline-block;
    width: 1rem;
    height: 1rem;
    margin-right: 0.4rem;
    background-size: contain;
    background-repeat: no-repeat;
    opacity: 0.6;
}

.grid-action:hover {
    opacity: 1;
}

.grid-action-details {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%23212529' viewBox='0 0 16 16'%3E%3Cpath d='M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.133 13.133 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.133 13.133 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5c-2.12 0-3.879-1.168-5.168-2.457A13.134 13.134 0 0 1 1.172 8z'/%3E%3Cpath d='M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z'/%3E%3C/svg%3E");
}

.grid-action-edit {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%23212529' viewBox='0 0 16 16'%3E%3Cpath d='M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z'/%3E%3C/svg%3E");
}

.grid-action-delete {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%23dc3545' viewBox='0 0 16 16'%3E%3Cpath d='M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z'/%3E%3Cpath fill-rule='evenodd' d='M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H5.5l1-1h3l1 1H14a1 1 0 0 1 1 1v1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z'/%3E%3C/svg%3E");
}

.grid-action-disable {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%23dc3545' viewBox='0 0 16 16'%3E%3Cpath d='M8 15A7 7 0 1 0 8 1a7 7 0 0 0 0 14zm0 1A8 8 0 1 1 8 0a8 8 0 0 1 0 16z'/%3E%3Cpath d='M11.354 4.646a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708l6-6a.5.5 0 0 1 .708 0z'/%3E%3C/svg%3E");
}

.grid-action-enable {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%23198754' viewBox='0 0 16 16'%3E%3Cpath d='M8 15A7 7 0 1 0 8 1a7 7 0 0 0 0 14zm0 1A8 8 0 1 1 8 0a8 8 0 0 1 0 16z'/%3E%3Cpath d='M10.97 4.97a.235.235 0 0 1 .02-.022.75.75 0 0 1 1.079 1.04l-.007.007-4.5 5.5a.75.75 0 0 1-1.06.05L4.324 9.384a.75.75 0 1 1 1.06-1.06l1.598 1.598 4-4.89a.798.798 0 0 1-.01-.062z'/%3E%3C/svg%3E");
}

.grid-action-reinvite {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%231a56a0' viewBox='0 0 16 16'%3E%3Cpath d='M0 4a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V4zm2-1a1 1 0 0 0-1 1v.217l7 4.2 7-4.2V4a1 1 0 0 0-1-1H2zm13 2.383-4.708 2.825L15 11.105V5.383zm-.034 6.876-5.64-3.471L8 9.583l-1.326-.795-5.64 3.47A1 1 0 0 0 2 13h12a1 1 0 0 0 .966-.741zM1 11.105l4.708-2.897L1 5.383v5.722z'/%3E%3C/svg%3E");
}

.grid-action-properties {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%23212529' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M5 11.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5z'/%3E%3Cpath d='M2.854 4.646a.5.5 0 0 1-.708 0l-.5-.5a.5.5 0 1 1 .708-.708l.146.147.646-.647a.5.5 0 1 1 .708.708l-1 1zm0 4a.5.5 0 0 1-.708 0l-.5-.5a.5.5 0 1 1 .708-.708l.146.147.646-.647a.5.5 0 1 1 .708.708l-1 1zm0 4a.5.5 0 0 1-.708 0l-.5-.5a.5.5 0 0 1 .708-.708l.146.147.646-.647a.5.5 0 0 1 .708.708l-1 1z'/%3E%3C/svg%3E");
}

/* Shared key display for authenticator setup */
.shared-key {
    font-family: "Cascadia Code", Consolas, "Courier New", monospace;
    font-size: 1.125rem; /* slightly larger than surrounding text */
    margin: 0.25rem 0;
    padding: 0.125rem 0;
    display: block;
}

    .shared-key kbd {
        /* Make the key visible against any page background while remaining copyable */
        background: #f8f9fa; /* light neutral background */
        color: #212529; /* readable foreground */
        border: 1px solid #ced4da;
        padding: 0.125rem 0.5rem;
        /*border-radius: 0.25rem;*/
        border-radius: 0.00rem;
        font-size: inherit;
    }

/* QR scaling */
img[src*="/Account/Manage/AuthenticatorQr"] {
    width: 50%;
    height: auto;
}

/* Recovery codes styling */
.recovery-box {
    background: #fff3cd;
    border: 1px solid #ffeeba;
    padding: 1rem;
    border-radius: 0.25rem;
}
.recovery-code {
    color: #c7254e;
    font-family: "Cascadia Code", Consolas, "Courier New", monospace;
    font-size: 1.05rem;
    display: block;
    margin: 0.25rem 0;
}

/* Home page */
.home-logo {
    width: 180px;
    height: auto;
    margin-bottom: 1rem;
}

.home-header h1 {
    font-family: 'Comfortaa', sans-serif;
    font-weight: 400;
    font-size: 1.75rem;
    margin-bottom: 0.2rem;
}

.home-header h2 {
    font-family: 'Comfortaa', sans-serif;
    font-weight: 400;
    font-size: 1.2rem;
    color: #555;
    margin-bottom: 1.5rem;
}

.home-body {
    max-width: 700px;
}

/* ------------------------------------------------------------------------------------------------
   Staff reporting

   The two entry lists are hand-written tables rather than QuickGrids, because a row turns into
   inputs where it stands and QuickGrid has no notion of that. They therefore sit outside .data-grid
   — that wrapper hides any row without an aria-rowindex, which only QuickGrid stamps — and carry
   their own fixed layout so the inputs do not resize the columns as rows open and close.
   ------------------------------------------------------------------------------------------------ */
.staff-table {
    table-layout: fixed;
    width: 100%;
    /* The fixed columns below come to some 55rem, and everything left over goes to the function -
       which holds a select, so it cannot be squeezed to nothing. Below this the table scrolls inside
       its .table-responsive wrapper instead of crushing that one flexible column. */
    min-width: 65rem;
}

    /* Monthly: number, function, gender, age, seniority, hours, salary, car, done, actions.
       Adding the hours column cost 6.5rem, which came from the three columns after the salary
       rather than from the function: car holds the word "Bil" and was nearly all slack, and both
       "Færdig" and the two action icons had more room than their contents need. Gender is
       deliberately untouched — see the note on it below. */
    .staff-table th:nth-child(1),
    .staff-table td:nth-child(1) {
        width: 8rem; /* Number: ten characters, and often initials rather than digits */
    }

    .staff-table th:nth-child(2),
    .staff-table td:nth-child(2) {
        width: auto; /* Function flexes to fill remaining space */
    }

    .staff-table th:nth-child(3),
    .staff-table td:nth-child(3) {
        /* Gender: "Uoplyst" plus the select's own arrow and padding, which together take more room
           than the word suggests — below this the longest option is clipped. */
        width: 9rem;
    }

    .staff-table th:nth-child(4),
    .staff-table td:nth-child(4) {
        width: 4.5rem; /* Age: two digits under "Alder" */
    }

    .staff-table th:nth-child(5),
    .staff-table td:nth-child(5) {
        /* Seniority: two digits, but the header "Anciennitet" is the widest thing in the column and
           has to fit whole. */
        width: 7rem;
    }

    .staff-table th:nth-child(6),
    .staff-table td:nth-child(6) {
        /* Hours: "160,33" under "Timer/måned", which is the wider of the two and what sets this. */
        width: 6.5rem;
    }

    .staff-table th:nth-child(7),
    .staff-table td:nth-child(7) {
        width: 6.5rem; /* Salary: five digits and a separator, under "Månedsløn" */
    }

    .staff-table th:nth-child(8),
    .staff-table td:nth-child(8) {
        width: 3.25rem; /* Car: a checkbox under "Bil" */
    }

    .staff-table th:nth-child(9),
    .staff-table td:nth-child(9) {
        /* Done: a check mark or "Fratrådt", right-aligned so it sits against the icons beside it
           rather than adrift at the far side of its own column. */
        width: 5.5rem;
    }

    .staff-table th:nth-child(10),
    .staff-table td:nth-child(10) {
        width: 5rem; /* Actions: two icons, and Save/Cancel on the row being edited */
    }

/* Hourly reports neither seniority nor gender - gender is asked of monthly staff only - so it runs
   two columns shorter and everything from the third on shifts left: number, function, age, hours,
   rate, subsistence, done, actions. Nothing from the third column on lines up with the monthly
   widths above any more, so all of them are restated rather than inherited by accident. */
/* Twelve rem lighter than the monthly table, having neither gender nor seniority, so it starts
   scrolling that much later. */
.staff-table-hourly {
    min-width: 53rem;
}

.staff-table-hourly th:nth-child(3),
.staff-table-hourly td:nth-child(3) {
    width: 4.5rem; /* Age: two digits under "Alder" */
}

.staff-table-hourly th:nth-child(4),
.staff-table-hourly td:nth-child(4) {
    /* Hours: as on the monthly page, and there is room to spare here - this table carries fourteen
       fewer rem of fixed columns, so the function keeps its width even with this added. */
    width: 6.5rem;
}

.staff-table-hourly th:nth-child(5),
.staff-table-hourly td:nth-child(5) {
    width: 6.5rem; /* Rate: to two decimals, under "Timeløn" */
}

.staff-table-hourly th:nth-child(6),
.staff-table-hourly td:nth-child(6) {
    width: 7rem; /* Allowance: a checkbox under "Udetillæg", which is what sets the width */
}

.staff-table-hourly th:nth-child(7),
.staff-table-hourly td:nth-child(7) {
    width: 5.5rem; /* Done */
}

.staff-table-hourly th:nth-child(8),
.staff-table-hourly td:nth-child(8) {
    width: 5rem; /* Actions */
}

/* Last year's figures, standing in for figures nobody has entered yet. Greyed and italic because
   they are a suggestion and not a report: nothing here is stored until the row is saved, and the
   list must not read as complete when it is not. */
.staff-proposal {
    color: #6c757d;
    font-style: italic;
}

.staff-dismissed td {
    color: #6c757d;
}

/* The row being worked on, lifted off the list so the eye keeps its place in a hundred rows. */
.staff-editing > td {
    background-color: #f2f7fd;
    vertical-align: middle;
}

/* The number boxes need only as much room as the figure, so they are capped rather than stretched
   across their column. Pushed to the right edge, under their right-aligned headers: a column has to
   be as wide as its header — "Anciennitet" by some way the widest — and letting the boxes fill that
   width left the three figures adrift with gaps between them. Text inputs only, so the car-scheme
   and subsistence checkboxes keep their place. */
.staff-table .staff-editing td:nth-child(4) input[type="text"],
.staff-table .staff-editing td:nth-child(5) input[type="text"],
.staff-table .staff-editing td:nth-child(6) input[type="text"],
.staff-table .staff-editing td:nth-child(7) input[type="text"] {
    display: block;
    margin-left: auto;
    max-width: 4rem;
}

/* Wider than the two year counts beside them, and stated after the rule above so they win on equal
   specificity. */
.staff-table .staff-editing td:nth-child(6) input[type="text"] {
    max-width: 5rem; /* Hours: "160,33" */
}

.staff-table .staff-editing td:nth-child(7) input[type="text"] {
    max-width: 6rem; /* Salary */
}

/* Age has shifted out from under the monthly rule above, and neither the hours nor the rate fits
   the width the two year counts share. */
.staff-table-hourly .staff-editing td:nth-child(3) input[type="text"] {
    display: block;
    margin-left: auto;
    max-width: 4rem; /* Age */
}

.staff-table-hourly .staff-editing td:nth-child(4) input[type="text"] {
    display: block;
    margin-left: auto;
    max-width: 5rem; /* Hours */
}

.staff-table-hourly .staff-editing td:nth-child(5) input[type="text"] {
    display: block;
    margin-left: auto;
    max-width: 6rem; /* Rate */
}

.staff-row-actions {
    display: flex;
    gap: 0.75rem;
    align-items: center;
}

/* The read-only row's actions. No gap of its own — .grid-action already carries a right margin, and
   the icons are what keep these rows shorter than the text links they replaced. */
.staff-row-icons {
    display: flex;
    align-items: center;
}

/* An action icon that runs a handler instead of navigating. The grids use links, which need no
   reset; a button brings its own chrome, so it is stripped back to the icon inside it. */
.grid-action-button {
    padding: 0;
    border: 0;
    background: none;
    line-height: 1;
}

/* Validation for the row being edited, in a row of its own directly beneath it. It keeps the
   background so the two read as one block, and drops the border between them. */
.staff-messages > td {
    border-top: 0;
    padding-top: 0;
}

/* Both sit under the row they belong to rather than in the page's alert box at the top: they are
   about one row, and in a list of a hundred the top of the page is nowhere near it. */
.staff-error {
    color: #dc3545;
    font-size: 0.875rem;
    margin-top: 0.25rem;
}

.staff-warning {
    color: #997404;
    font-size: 0.875rem;
    margin-top: 0.25rem;
}

/* The reminder dialog: a checkbox, a name, a telephone number and a date. Fixed layout so the
   column of dates lines up however long the names are. */
.remind-table {
    table-layout: fixed;
    width: 100%;
}

    .remind-table th:nth-child(1),
    .remind-table td:nth-child(1) {
        width: 2.5rem; /* The checkbox, or nothing for somebody who cannot be written to */
    }

    .remind-table th:nth-child(2),
    .remind-table td:nth-child(2) {
        width: auto; /* Name flexes, and carries the reason underneath when there is one */
    }

    .remind-table th:nth-child(3),
    .remind-table td:nth-child(3) {
        width: 9rem; /* Telephone */
    }

    .remind-table th:nth-child(4),
    .remind-table td:nth-child(4) {
        width: 10rem; /* Last reminded */
    }

.staff-progress {
    white-space: nowrap;
    font-weight: 600;
}

/* The administrator's status list is an ordinary QuickGrid: account, category, name, reported,
   outstanding, confirmed, actions. */
.staff-status-table {
    table-layout: fixed;
    width: 100%;
}

    .staff-status-table th:nth-child(1),
    .staff-status-table td:nth-child(1) {
        width: 13ch; /* Account: matches the Members grid */
    }

    .staff-status-table th:nth-child(2),
    .staff-status-table td:nth-child(2) {
        width: 12rem; /* Member category */
    }

    .staff-status-table th:nth-child(3),
    .staff-status-table td:nth-child(3) {
        width: auto; /* Name flexes to fill remaining space */
    }

    .staff-status-table th:nth-child(4),
    .staff-status-table td:nth-child(4),
    .staff-status-table th:nth-child(5),
    .staff-status-table td:nth-child(5) {
        width: 9rem; /* Reported and outstanding: counts under a header word */
    }

    .staff-status-table th:nth-child(6),
    .staff-status-table td:nth-child(6) {
        width: 9rem; /* Confirmed: a check mark */
    }

    .staff-status-table th:nth-child(7),
    .staff-status-table td:nth-child(7) {
        width: 3rem; /* Actions: open only */
    }

/* The member's own landing page: two rows, one per pay form, so it needs none of the width the
   company-wide grid spends on account and name. */
.staff-summary-table {
    table-layout: fixed;
    width: 100%;
    max-width: 46rem;
}

    .staff-summary-table th:nth-child(1),
    .staff-summary-table td:nth-child(1) {
        width: auto; /* Pay form flexes to fill remaining space */
    }

    .staff-summary-table th:nth-child(2),
    .staff-summary-table td:nth-child(2) {
        width: 7rem; /* Year */
    }

    .staff-summary-table th:nth-child(3),
    .staff-summary-table td:nth-child(3),
    .staff-summary-table th:nth-child(4),
    .staff-summary-table td:nth-child(4) {
        width: 8rem; /* Reported and outstanding */
    }

    .staff-summary-table th:nth-child(5),
    .staff-summary-table td:nth-child(5) {
        width: 8rem; /* Confirmed */
    }

    .staff-summary-table th:nth-child(6),
    .staff-summary-table td:nth-child(6) {
        width: 9rem; /* The button through to the list */
    }