/*
 * SurfHost Panel. Flat and square: no rounded corners, no gradients, no
 * shadows. Content uses the width of a Full HD screen (1920 px minus a
 * scrollbar) and stays centred on wider screens. No inline styles: the
 * CSP only allows this file.
 */

:root {
    --page-width: 1903px;
    --gutter: 24px;
    --tile-width: 128px;

    /* SurfHost green, as on surfhost.nl */
    --bg: #f3f7f1;
    --surface: #ffffff;
    --surface-alt: #f8faf7;
    --text: #182b1f;
    --muted: #5a6b5e;
    --faint: #8a9b8d;
    --line: #e4e9e2;
    --border: #d3dcd1;

    --brand: #12351f;
    --brand-text: #ffffff;
    --brand-muted: #b9cdbb;
    --brand-mark: #8cc63e;

    --accent: #4e8a1e;
    --accent-hover: #3e6e16;
    --accent-soft: #f0f7e7;
    --accent-line: #cfe5b0;

    --action: #8cc63e;
    --action-hover: #a5d65e;
    --action-text: #12351f;

    --ok: #3e6e16;
    --ok-bg: #f0f7e7;
    --ok-line: #8cc63e;
    --error: #b42318;
    --error-bg: #fef3f2;
    --info: #24492f;
    --info-bg: #eef3ec;
    /* Corners: subtly rounded. */
    --radius: 4px;
    --radius-sm: 3px;
    /* One size for every field, select and button on every page: forms,
       filter bars, fields and buttons in a table row. */
    --control-height: 32px;
    --control-font: 14px;

    color-scheme: light;
}

*,
*::before,
*::after {
    box-sizing: border-box;
    border-radius: 0;
}

html {
    -webkit-text-size-adjust: 100%;
}

body {
    margin: 0;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    background: var(--bg);
    color: var(--text);
    font: 14px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

a {
    color: var(--accent);
}

a:hover {
    color: var(--accent-hover);
}

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

code {
    font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", monospace;
    font-size: 0.92em;
}

.icon {
    width: 16px;
    height: 16px;
    vertical-align: -3px;
    flex: none;
}

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

/* Width container shared by top bar, page and footer */

.bar {
    display: flex;
    align-items: center;
    gap: 24px;
    width: 100%;
    max-width: var(--page-width);
    margin: 0 auto;
    padding: 0 var(--gutter);
}

/* Top bar */

.topbar {
    background: var(--brand);
    color: var(--brand-text);
}

.topbar .bar {
    height: 48px;
}

.topbar :focus-visible {
    outline-color: var(--brand-text);
}

.brand {
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--brand-text);
    font-size: 15px;
    text-decoration: none;
    white-space: nowrap;
}

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

.brand-icon {
    width: 22px;
    height: 22px;
    color: var(--brand-mark);
}

.levels {
    display: flex;
    align-self: stretch;
    margin-left: auto;
}

.level {
    display: flex;
    align-items: center;
    padding: 0 14px;
    border-top: 2px solid transparent;
    border-bottom: 2px solid transparent;
    color: var(--brand-muted);
    text-decoration: none;
    white-space: nowrap;
}

.level:hover {
    color: var(--brand-text);
}

/* Webmail in the top bar: an app beside the levels, not a level. */
/* Every item between two lines has 14px on both sides. */
.level-app {
    gap: 6px;
    border-left: 1px solid rgba(255, 255, 255, 0.2);
}

.level-app .icon {
    width: 18px;
    height: 18px;
}

/* A medium screen (tablet, phone with large text): the apps show only
   their icons, so the account menu stays inside the bar. */
@media (min-width: 721px) and (max-width: 960px) {
    .level {
        padding: 0 10px;
    }

    .level-app,
    .level-apps button.level-app {
        font-size: 0;
    }

    .level-app .icon {
        width: 20px;
        height: 20px;
    }
}

/* phpMyAdmin in the top bar posts (single sign-on): a button that looks
   like the links beside it. */
.level-form {
    display: flex;
    margin: 0;
}

button.level {
    border-right: 0;
    background: none;
    font: inherit;
    cursor: pointer;
}

/* A button that cannot be used now (Databases without any). */
.button.is-disabled {
    opacity: 0.55;
    cursor: default;
    pointer-events: none;
}

.level.is-active {
    border-bottom-color: var(--brand-mark);
    color: var(--brand-text);
    font-weight: 600;
}

/* Bell, then the user menu: each part after a line, like the apps. */
.account {
    display: flex;
    align-self: stretch;
    align-items: center;
    color: var(--brand-muted);
    white-space: nowrap;
}

/* The levels (Admin, Reseller, Gebruiker) right beside the name, a line
   before them. */
.level-main {
    margin-left: 0;
    border-left: 1px solid rgba(255, 255, 255, 0.2);
}

.account-user {
    display: flex;
    align-self: stretch;
    align-items: center;
    padding: 0 14px;
    border-left: 1px solid rgba(255, 255, 255, 0.2);
}

.account-name {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--brand-text);
}

/* Account menu under the user name: a <details>, so it works without
   inline script; menu.js only closes it on Escape or a click elsewhere. */
.account-menu {
    position: relative;
}

.account-menu > summary {
    height: 48px;
    padding: 0 4px;
    cursor: pointer;
    list-style: none;
}

.account-menu > summary::-webkit-details-marker {
    display: none;
}

.account-menu > summary:hover,
.account-menu[open] > summary {
    color: #ffffff;
}

.account-caret {
    width: 14px;
    height: 14px;
}

.account-menu-items {
    position: absolute;
    top: 100%;
    right: 0;
    z-index: 20;
    display: flex;
    flex-direction: column;
    min-width: 220px;
    padding: 4px 0;
    background: var(--surface);
    border: 1px solid var(--border);
    box-shadow: 0 6px 18px rgb(0 0 0 / 12%);
}

.account-menu-items a {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 14px;
    color: var(--text);
    text-decoration: none;
}

.account-menu-items a:hover,
.account-menu-items a:focus-visible {
    background: var(--surface-alt);
    color: var(--text);
}

/* The bell (admin): plain, or with an exclamation mark and a count while a
   notice is open; it opens a list like the account menu. */
/* The bell: an item like Webmail and phpMyAdmin, a line before it and
   the word Alerts after the icon. */
.account-menu > summary.alert-bell {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 0 14px;
    border-left: 1px solid rgba(255, 255, 255, 0.2);
    color: var(--brand-muted);
}

.alert-bell .icon {
    width: 18px;
    height: 18px;
}

/* Right against Bestanden, like the apps (the bar keeps 24px between
   its parts). */
.account > .alert-menu {
    margin-left: -24px;
}

.alert-bell:hover {
    color: var(--brand-text);
}

.alert-menu.has-open .alert-bell {
    color: #ffb4a8;
}

.alert-count {
    min-width: 18px;
    padding: 0 5px;
    border-radius: 9px;
    background: var(--error);
    color: #ffffff;
    font-size: 11px;
    font-weight: 700;
    line-height: 18px;
    text-align: center;
}

/* Opens under the bell and the user menu, against the right edge of the
   bar (so it never leaves the screen). */
.account {
    position: relative;
}

.account > .alert-menu {
    position: static;
}

.alert-items {
    left: auto;
    right: 0;
    width: 360px;
    max-width: calc(100vw - 2 * var(--gutter));
    padding: 0;
    white-space: normal;
}

.alert-heading {
    margin: 0;
    padding: 12px 16px;
    border-bottom: 1px solid var(--border);
    color: var(--text);
    font-weight: 700;
}

.alert-empty {
    display: flex;
    gap: 10px;
    align-items: center;
    margin: 0;
    padding: 14px 16px;
    color: var(--text);
}

.alert-empty .icon {
    color: var(--accent, #3e6e16);
}

.alert-item {
    display: flex;
    gap: 12px;
    padding: 12px 16px;
    border-bottom: 1px solid var(--border);
    color: var(--text);
}

.alert-icon {
    flex: none;
    width: 20px;
    height: 20px;
    color: var(--error);
}

.alert-item p {
    margin: 0 0 4px;
}

.alert-detail {
    color: var(--muted);
    font-size: 13px;
}

.alert-item.is-dismissed {
    color: var(--muted);
}

.alert-item.is-dismissed .alert-icon {
    color: var(--muted);
}

/* Links in the list: plain links, not the account menu's rows. */
.account-menu-items.alert-items a {
    display: inline;
    padding: 0;
    color: var(--accent);
    text-decoration: underline;
}

.account-menu-items.alert-items a:hover {
    background: none;
    color: var(--accent-hover);
}

.alert-item .link-button,
.alert-all .link-button {
    color: var(--accent);
    font-size: 13px;
    text-decoration: underline;
}

.alert-all .link-button {
    font-weight: 600;
    text-decoration: none;
}

/* On the white list a hover stays readable (the top bar's hover is white). */
.alert-item .link-button:hover,
.alert-item .link-button:focus-visible,
.alert-all .link-button:hover,
.alert-all .link-button:focus-visible {
    color: var(--accent-hover);
    text-decoration: underline;
}

.alert-item.is-dismissed .alert-title a {
    color: var(--muted);
}

.alert-all {
    margin: 0;
    padding: 10px 16px;
    text-align: center;
}

/* Section header with a title and a menu of actions on the right (three
   dots), e.g. Bewerken / Blokkeren / Verwijderen on an account. */
.section-head {
    display: flex;
    align-items: center;
    background: var(--surface-alt);
    border-bottom: 1px solid var(--line);
}

/* The head has the border line, so its title is 1px lower. */
.section-head > .section-title {
    flex: 1;
    min-height: 36px;
    border-bottom: 0;
}

.action-menu {
    position: relative;
    margin-right: 6px;
}

.action-menu > summary {
    display: flex;
    align-items: center;
    padding: 4px;
    border-radius: 4px;
    color: var(--muted);
    cursor: pointer;
    list-style: none;
}

.action-menu > summary::-webkit-details-marker {
    display: none;
}

.action-menu > summary:hover,
.action-menu[open] > summary {
    background: var(--surface);
    color: var(--text);
}

.action-menu-items {
    position: absolute;
    top: 100%;
    right: 0;
    z-index: 20;
    display: flex;
    flex-direction: column;
    min-width: 220px;
    padding: 4px 0;
    background: var(--surface);
    border: 1px solid var(--border);
    box-shadow: 0 6px 18px rgb(0 0 0 / 12%);
}

.action-menu-items a,
.action-menu-items button {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 9px 14px;
    border: 0;
    background: none;
    color: var(--text);
    font: inherit;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}

.action-menu-items .danger {
    color: var(--error);
}

.action-menu-items a:hover,
.action-menu-items a:focus-visible,
.action-menu-items button:hover,
.action-menu-items button:focus-visible {
    background: var(--error-bg);
}

.inline-form {
    margin: 0;
}

.link-button {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 0;
    border: 0;
    background: none;
    color: var(--brand-muted);
    font: inherit;
    cursor: pointer;
}

.link-button:hover {
    color: var(--brand-text);
}

/* Page */

.page {
    flex: 1;
    width: 100%;
    max-width: var(--page-width);
    margin: 0 auto;
    padding: 24px var(--gutter) 48px;
}

.page-title {
    margin: 0 0 16px;
    font-size: 20px;
    font-weight: 600;
}

.breadcrumb {
    margin-bottom: 4px;
    color: var(--muted);
    font-size: 13px;
}

.breadcrumb a {
    color: var(--muted);
    text-decoration: none;
}

.breadcrumb a:hover {
    color: var(--accent);
    text-decoration: underline;
}

.footer {
    border-top: 1px solid var(--line);
    color: var(--faint);
    font-size: 12px;
}

.footer .bar {
    height: 40px;
}

/* Sections */

.section-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(440px, 1fr));
    gap: 20px;
    align-items: start;
}

.panel-section {
    margin-bottom: 20px;
    background: var(--surface);
    border: 1px solid var(--border);
}

.section-grid .panel-section {
    margin-bottom: 0;
}

/* Always two halves, also with one section in it. */
.section-grid.section-halves {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* A block grid (BlockGrid): two columns, each a stack, so a block starts
   right under the one above it whatever the other column holds. */
.section-grid.block-columns {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* A WordPress site: details, changed files and the narrow administrators
   side by side; two columns on a medium screen. */
.section-grid.wp-top {
    grid-template-columns: minmax(0, 2fr) minmax(0, 2fr) minmax(0, 1fr);
}

/* Narrower: the details across the whole width, the other two under it. */
@media (max-width: 1400px) {
    .section-grid.wp-top {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .section-grid.wp-top > :first-child {
        grid-column: 1 / -1;
    }
}

/* Plugins and themes side by side only where both tables fit. */
@media (max-width: 1100px) {
    .section-grid.section-halves.wp-pair {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* A value keeps room for itself; a long label wraps instead. */
.wp-top .details {
    grid-template-columns: minmax(0, max-content) minmax(10em, 1fr);
}

.wp-setting {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 12px;
}

.wp-setting-note {
    color: var(--muted);
    font-size: 12px;
}

/* An on/off switch that posts the other state (WordPress settings). */
.switch {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 2px 0;
    border: 0;
    background: none;
    color: var(--muted);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.switch-track {
    position: relative;
    flex: none;
    width: 34px;
    height: 20px;
    border-radius: 10px;
    background: var(--border);
    transition: background-color 0.15s;
}

.switch-track::after {
    content: "";
    position: absolute;
    top: 2px;
    left: 2px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: #ffffff;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
    transition: left 0.15s;
}

.switch:hover .switch-track {
    background: var(--faint);
}

.switch[aria-checked="true"] {
    color: var(--text);
}

.switch[aria-checked="true"] .switch-track {
    background: var(--accent);
}

.switch[aria-checked="true"] .switch-track::after {
    left: 16px;
}

.switch[aria-checked="mixed"] .switch-track {
    background: var(--accent-line);
}

.switch[aria-checked="mixed"] .switch-track::after {
    left: 9px;
}

/* Maintenance mode on: the site is closed to visitors. */
.switch.switch-warn[aria-checked="true"] .switch-track {
    background: #c2410c;
}

.count-badge {
    display: inline-block;
    min-width: 18px;
    padding: 0 5px;
    border-radius: 9px;
    background: var(--action);
    color: var(--action-text);
    font-size: 11px;
    line-height: 18px;
    text-align: center;
}

.wp-admins {
    margin: 0;
    padding: 0;
    list-style: none;
}

.wp-admins li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 10px 16px;
    border-bottom: 1px solid var(--line);
}

.wp-admins li:last-child {
    border-bottom: 0;
}

.wp-admin-name {
    min-width: 0;
    overflow-wrap: anywhere;
}

.block-column {
    display: flex;
    flex-direction: column;
    gap: 20px;
    min-width: 0;
}

.panel-section-narrow {
    max-width: 560px;
}

/* One height for every section title, also with a badge or a period
   switch in it. */
.section-title {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 6px;
    box-sizing: border-box;
    min-height: 37px;
    margin: 0;
    padding: 9px 16px;
    background: var(--surface-alt);
    border-bottom: 1px solid var(--line);
    color: var(--muted);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.section-title .badge {
    line-height: 13px;
}

.section-body {
    padding: 16px;
}

.section-intro {
    margin: 0;
    padding: 12px 16px;
    border-bottom: 1px solid var(--line);
}

/* Fail2ban: the count with the filter field that also releases. */
.jail-filter {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 16px;
}

.jail-filter-form {
    display: flex;
    gap: 8px;
    margin-left: auto;
}

.jail-filter-form .input {
    width: 16em;
    max-width: 100%;
    height: var(--control-height);
    padding: 0 10px;
    border: 1px solid var(--border);
    border-radius: 0;
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-size: var(--control-font);
}

.jail-filter-form .input:focus {
    border-color: var(--accent);
    outline: none;
    box-shadow: inset 0 0 0 1px var(--accent);
}

@media (max-width: 720px) {
    .jail-filter-form {
        flex: 1 1 100%;
        margin-left: 0;
    }

    .jail-filter-form .input {
        flex: 1;
        width: auto;
    }
}

/* Inside the body of a block the intro is plain text: no line under it. */
.section-body .section-intro {
    padding: 0;
    border-bottom: 0;
    margin-bottom: 8px;
}

/* Icon grid: a section holds subsections, small groups of related tiles
   side by side, each under a quiet label when a section has more than one. */

.subsections {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 12px;
    padding: 8px;
}

.subsection {
    flex: 0 1 auto;
    min-width: 0;
}

.subsection-title {
    margin: 4px 8px 0;
    padding-bottom: 3px;
    border-bottom: 1px solid var(--line);
    color: var(--muted);
    font-size: 10px;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.icon-grid {
    display: flex;
    flex-wrap: wrap;
    margin: 0;
    padding: 0;
    list-style: none;
}

.icon-grid > li {
    width: var(--tile-width);
}

/* Dashboard: each block as wide as its tiles need (--cols, worked out by
   DashboardLayout::columns), sharing the row by that number; the tiles
   then fill their block exactly, so no block has room left at its side. */
@media (min-width: 961px) {
    .section-grid.dashboard-grid {
        display: flex;
        flex-wrap: wrap;
    }

    /* At least 100px a tile; a block alone on its row stops at 170px a
       tile, so its tiles do not drift apart. */
    .dashboard-grid > .panel-section {
        flex: var(--cols, 4) 1 calc(var(--cols, 4) * 100px + 18px);
        min-width: 0;
        max-width: calc(var(--cols, 4) * 170px + 18px);
    }

    .dashboard-grid .subsections {
        container-type: inline-size;
        column-gap: 0;
    }

    .dashboard-grid .icon-grid > li {
        width: calc(100cqw / var(--cols, 4));
    }

    /* A class, not a style attribute: the CSP allows no inline styles. */
    .dashboard-grid > .cols-3 { --cols: 3; }
    .dashboard-grid > .cols-4 { --cols: 4; }
    .dashboard-grid > .cols-5 { --cols: 5; }
}

.tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    height: 100%;
    padding: 16px 8px 14px;
    border: 1px solid transparent;
    color: var(--text);
    text-align: center;
    text-decoration: none;
}

/* A tile that posts (phpMyAdmin): a button that looks like a link tile. */
.tile-form {
    height: 100%;
    margin: 0;
}

button.tile {
    width: 100%;
    background: none;
    font: inherit;
    cursor: pointer;
}

button.tile:hover,
a.tile:hover {
    background: var(--accent-soft);
    border-color: var(--accent-line);
    color: var(--text);
}

.tile-icon {
    width: 32px;
    height: 32px;
    color: var(--accent);
    stroke-width: 1.5;
}

.tile-label {
    font-size: 13px;
    line-height: 1.3;
}

.tile.is-disabled {
    color: var(--muted);
    cursor: default;
}

.tile.is-disabled .tile-icon {
    color: var(--faint);
}

.tile-note {
    color: var(--faint);
    font-size: 10px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* Login and other small boxes */

.auth-box {
    max-width: 380px;
    margin: 64px auto;
    padding: 28px;
    background: var(--surface);
    border: 1px solid var(--border);
}

.auth-box-wide {
    max-width: 520px;
}

/* Inloggen and Tweestapsverificatie: one box of the same size, the
   intro of the code on one line; the last link stands at the bottom. */
.auth-box-login {
    display: flex;
    flex-direction: column;
    max-width: 400px;
    min-height: 360px;
}

.auth-box-login > form {
    margin-bottom: auto;
}

.auth-box h1 {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0 0 16px;
    font-size: 18px;
    font-weight: 600;
}

.auth-icon {
    width: 22px;
    height: 22px;
    color: var(--accent);
}

/* Forms */

.form {
    display: grid;
    gap: 6px;
}

.form label {
    margin-top: 10px;
    font-size: 13px;
    font-weight: 600;
}

.form input {
    width: 100%;
    height: var(--control-height);
    padding: 0 10px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-size: var(--control-font);
}

.form input:focus {
    border-color: var(--accent);
    outline: none;
    box-shadow: inset 0 0 0 1px var(--accent);
}

.form input[readonly] {
    background: var(--surface-alt);
    color: var(--muted);
}

.hint {
    margin: 0;
    color: var(--muted);
    font-size: 12px;
}

/* A note about the whole page, above its blocks (Firewall: when it was
   applied): plain text, with room before the blocks. */
.page-note {
    margin-bottom: 16px;
}

/* Fields that show only for some choices (Product: the extension). */
.form-sub {
    display: grid;
    gap: 6px;
}

.form-sub[hidden] {
    display: none;
}

/* Two fields side by side, half each (Product: Soort and Eenheid). */
.form-pair {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
}

@media (max-width: 640px) {
    .form-pair {
        grid-template-columns: 1fr;
    }
}

/* A group of fields inside a form, under a line (Product: prices per plan). */
.form-fieldset {
    display: grid;
    gap: 6px;
    min-width: 0;
    margin: 16px 0 0;
    padding: 14px 0 0;
    border: 0;
    border-top: 1px solid var(--line);
}

.form-fieldset > legend {
    padding: 0;
    font-weight: 600;
}

.form-actions {
    display: flex;
    gap: 8px;
    margin-top: 18px;
}

.form > .button {
    margin-top: 18px;
}

.button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: var(--control-height);
    padding: 0 14px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-size: var(--control-font);
    font-weight: 600;
    text-decoration: none;
    vertical-align: middle;
    cursor: pointer;
}

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

.button.primary {
    background: var(--action);
    border-color: var(--action);
    color: var(--action-text);
}

.button.primary:hover {
    background: var(--action-hover);
    border-color: var(--action-hover);
    color: var(--action-text);
}

/* Two-factor setup */

.totp-setup {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 16px;
    margin: 8px 0 4px;
}

.qr {
    width: 200px;
    height: 200px;
    border: 1px solid var(--border);
    image-rendering: pixelated;
}

.secret {
    display: inline-block;
    padding: 6px 8px;
    background: var(--bg);
    letter-spacing: 0.05em;
    word-break: break-all;
}

/* Messages */

.flash {
    margin: 0 0 16px;
    padding: 10px 14px;
    border-left: 3px solid var(--info);
    background: var(--info-bg);
    color: var(--info);
}

.flash-success {
    border-left-color: var(--ok);
    background: var(--ok-bg);
    color: var(--ok);
}

.flash-error {
    border-left-color: var(--error);
    background: var(--error-bg);
    color: var(--error);
}

/* A notice with its action on the right (DNS not managed here). */
.flash-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 8px 16px;
    padding-top: 8px;
    padding-bottom: 8px;
}

/* Tables */

.table-wrap {
    overflow-x: auto;
}

.table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}

/* One row height on every page: 6px above and below, 12px between the
   columns and 16px at the edges, in line with the section titles. */
.table th,
.table td {
    padding: 6px 12px;
    border-bottom: 1px solid var(--line);
    text-align: left;
    vertical-align: middle;
}

.table th:first-child,
.table td:first-child {
    padding-left: 16px;
}

.table th:last-child,
.table td:last-child {
    padding-right: 16px;
}

/* Every row of one line is as high as a row with a control in it,
   whatever is in it: text, a badge, a select or buttons. A table cell's
   height counts its padding (2 x 6px) and its line (1px). */
.table td {
    height: calc(var(--control-height) + 13px);
    line-height: 20px;
}

.table th {
    background: var(--surface-alt);
    color: var(--muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    white-space: nowrap;
}

/* A checkbox in a column head (select all) keeps the head one line high. */
.table th input[type="checkbox"] {
    display: block;
    margin: 0;
}

/* DNS: long values (DKIM, SPF) break instead of widening the page. */
.dns-table td {
    overflow-wrap: anywhere;
}

/* A long status ("Staat bij Openprovider, nog niet zichtbaar") wraps
   inside its column instead of making the table scroll. */
.dns-table .badge {
    white-space: normal;
    max-width: 100%;
}

/* The queue on the DNS page (dns-queue.js): a set button goes when done. */
.dns-table [data-dns-result][hidden],
.dns-table form[data-dns-set][hidden] {
    display: none;
}

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

/* A badge is one word or two on one line, also in a narrow cell, and no
   higher than a line of text. */
.badge {
    display: inline-block;
    padding: 1px 6px;
    border: 1px solid var(--border);
    color: var(--muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.04em;
    line-height: 15px;
    text-transform: uppercase;
    vertical-align: middle;
    white-space: nowrap;
    overflow-wrap: normal;
}

.badge-on,
.badge-active,
.badge-done {
    border-color: var(--ok-line);
    background: var(--ok-bg);
    color: var(--ok);
}

.badge-provisioning,
.badge-partial,
.badge-pending,
.badge-queued,
.badge-running {
    border-color: #e8c66a;
    background: #fdf7e3;
    color: #7a5a00;
}

.badge-failed,
.badge-expired,
.badge-cancelled,
.badge-suspended,
.badge-removing {
    border-color: #f1b5ae;
    background: var(--error-bg);
    color: var(--error);
}

/* Page heading with an action on the right */

.page-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 8px 16px;
    margin-bottom: 16px;
}

.page-head .page-title {
    margin: 0;
}

/* A running backup or restore: its step and how far (backups table). */
.run-progress {
    display: grid;
    gap: 4px;
    margin-top: 4px;
    font-size: 12px;
}

.run-progress progress {
    width: 100%;
    max-width: 220px;
    height: 6px;
    accent-color: var(--accent);
}

/* Buttons next to each other in the head of a page. */
.page-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.page-lead {
    margin: -8px 0 16px;
}

.invoice-delete {
    margin-top: 16px;
}

.section-spaced {
    margin-top: 20px;
}

/* Detail lists */

.details {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 8px 24px;
    margin: 0;
    padding: 16px;
}

.details dt {
    color: var(--muted);
}

.details dd {
    margin: 0;
}

/* More form controls */

.form select {
    width: 100%;
    height: var(--control-height);
    padding: 0 8px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-size: var(--control-font);
}

.form select:focus {
    border-color: var(--accent);
    outline: none;
    box-shadow: inset 0 0 0 1px var(--accent);
}

.form .checkbox {
    display: flex;
    align-items: center;
    gap: 8px;
    font-weight: 400;
}

.form .checkbox input {
    width: 16px;
    height: 16px;
    margin: 0;
    accent-color: var(--accent);
}

.field-error {
    margin: 0;
    color: var(--error);
    font-size: 12px;
}

/* As high as every other control; only less room and smaller text. */
.button.small {
    padding: 0 10px;
    font-size: 13px;
}

/* A button with only its icon (the rows of Bestanden): square, the
   text in title and aria-label. */
.button.icon-only {
    width: var(--control-height);
    padding: 0;
}

.button.icon-slot {
    visibility: hidden;
}

.actions-cell,
.table td.actions-cell {
    /* .table td is left-aligned; the buttons always stand right. */
    text-align: right;
    white-space: nowrap;
}

/* Buttons that post (toggle, retry) stay on the row with the links. */
.actions-cell .inline-form {
    display: inline;
}

/* Several buttons in one cell: they wrap, aligned right, with a gap. */
.cell-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 6px;
}

.cell-actions .inline-form {
    display: inline-flex;
    margin: 0;
}

.error-cell {
    max-width: 480px;
    color: var(--error);
    font-size: 12px;
    word-break: break-word;
}

/* Job log: what a step was for, and its error on a row of its own */

.job-subject {
    font-weight: 600;
}

.job-table tr.has-detail td {
    border-bottom: 0;
}

.job-table .job-detail td {
    padding-top: 0;
    font-size: 12px;
}

.job-error {
    max-height: 240px;
    margin: 4px 0 0;
    padding: 6px 8px;
    overflow: auto;
    border: 1px solid var(--border);
    background: var(--surface-alt);
    color: var(--error);
    font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", monospace;
    font-size: 12px;
    white-space: pre-wrap;
    word-break: break-word;
}

/* Account actions: one row per action, label left, controls right */

.action-row {
    display: grid;
    grid-template-columns: 130px 1fr;
    align-items: start;
    gap: 6px 16px;
    margin: 0;
    padding: 12px 16px;
    border-top: 1px solid var(--line);
}

.section-title + .action-row {
    border-top: 0;
}

.action-row > label,
.action-label {
    padding-top: 9px;
    font-size: 13px;
    font-weight: 600;
}

.action-row .hint {
    margin: 6px 0 0;
}

.inline-controls {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}

.inline-controls input[type="text"],
.inline-controls select {
    flex: 1 1 120px;
    min-width: 0;
    height: var(--control-height);
    padding: 0 10px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-size: var(--control-font);
}

.inline-controls input[type="text"]:focus,
.inline-controls select:focus {
    border-color: var(--accent);
    outline: none;
    box-shadow: inset 0 0 0 1px var(--accent);
}

/* A box next to a field (Product: Actief beside the name). */
.form .inline-controls > label {
    margin-top: 0;
}

.checkbox-inline {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
}

/* Mail and SSL of a new website, hidden for a pointer (domain-pointer.js). */
[data-own-site][hidden] {
    display: none;
}

.checkbox-inline input {
    width: 16px;
    height: 16px;
    margin: 0;
    accent-color: var(--accent);
}

.button.danger {
    border-color: #f1b5ae;
    color: var(--error);
}

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

.button.danger-solid {
    border-color: var(--error);
    background: var(--error);
    color: #ffffff;
}

.button.danger-solid:hover {
    border-color: #912018;
    background: #912018;
    color: #ffffff;
}

/* "Log in as": always visible, never mistaken for the normal view */

.login-as-bar {
    background: #fdf7e3;
    border-bottom: 1px solid #e8c66a;
    color: #7a5a00;
}

.login-as-bar .bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding-top: 8px;
    padding-bottom: 8px;
    font-weight: 600;
}

.login-as-text {
    min-width: 0;
    overflow-wrap: anywhere;
}

/* The way back: on one line, in the bar's own colours. */
.login-as-bar .inline-form {
    flex: none;
}

.button.login-as-back {
    gap: 6px;
    border-color: #e8c66a;
    background: #fffdf5;
    color: #7a5a00;
    white-space: nowrap;
}

.button.login-as-back:hover {
    border-color: #c9a33f;
    background: #fff6d8;
    color: #5c4300;
}

/* Domain pointers (aliases), listed under their domain */

.pointer-row td:first-child {
    padding-left: 32px;
}

.pointer-name::before {
    content: "\21B3\00A0";
    color: var(--faint);
}

/* An input with a fixed prefix, e.g. account_ before a database name */

.input-prefix {
    display: flex;
    align-items: stretch;
}

.input-prefix span {
    display: inline-flex;
    align-items: center;
    padding: 0 10px;
    border: 1px solid var(--border);
    border-right: 0;
    background: var(--surface-alt);
    color: var(--muted);
    font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
}

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

/* Mail: an input with a fixed suffix (@domain) and multi-line fields */

.input-suffix {
    display: flex;
    align-items: stretch;
}

.input-suffix span {
    display: inline-flex;
    align-items: center;
    padding: 0 10px;
    border: 1px solid var(--border);
    border-left: 0;
    background: var(--surface-alt);
    color: var(--muted);
    font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
}

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

.form textarea {
    width: 100%;
    min-height: 90px;
    padding: 6px 10px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-size: var(--control-font);
    resize: vertical;
}

.form textarea:focus {
    border-color: var(--accent);
    outline: none;
    box-shadow: inset 0 0 0 1px var(--accent);
}

/* Bestanden: the same column widths on every folder. The name takes what
   is left; size, date, owner and rights have a short, fixed length; the
   buttons stand right. On a phone the rows become cards. */
@media (min-width: 721px) {
    .file-table {
        table-layout: fixed;
    }

    .file-table .col-check { width: 44px; }
    .file-table .col-size { width: 90px; }
    .file-table .col-modified { width: 150px; }
    .file-table .col-owner { width: 170px; }
    .file-table .col-mode { width: 64px; }
    .file-table .col-actions { width: 240px; }

    .file-table td {
        overflow-wrap: anywhere;
    }

    .file-table td.actions-cell {
        overflow-wrap: normal;
    }
}

/* Server status */

/* At a glance (admin home, Servers): one line when all is well, else what
   needs attention. */
.overview {
    margin-bottom: 20px;
}

/* The admin's server cards, under Accountbeheer and Serverbeheer. */
.overview-stats {
    margin-top: 20px;
}

/* Servers side by side (three on a wide screen), each a table of facts. */
.node-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 20px;
    align-items: start;
}

@media (max-width: 1400px) {
    .node-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 900px) {
    .node-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* The buttons under a server: on one line while they fit. */
.node-actions {
    gap: 6px;
}

.node-grid > .panel-section {
    margin: 0;
}

/* Under a server: the load chart and the services side by side. */
.node-panels {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(420px, 1fr));
    gap: 20px;
    align-items: start;
    margin: 20px 0;
}

.service-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 6px 16px;
    margin: 12px 0;
    padding: 0;
    list-style: none;
}

.service-list li {
    display: flex;
    gap: 8px;
    align-items: center;
}

.service-dot {
    flex: none;
    width: 8px;
    height: 8px;
    border-radius: 50%;
}

.service-dot.is-ok {
    background: var(--ok-line);
}

.service-dot.is-down {
    background: var(--error);
}

.node-status {
    display: grid;
    gap: 16px;
    margin-top: 16px;
}

.health {
    position: relative;
    display: grid;
    gap: 6px;
    padding: 12px 16px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
}

.health-row {
    display: flex;
    gap: 10px;
    align-items: center;
    min-height: 24px;
}

.health-text {
    flex: 1;
    min-width: 0;
}

.health-icon {
    flex: none;
    width: 20px;
    height: 20px;
}

.health-problem .health-icon {
    color: var(--error);
}

/* The cross sits top right of its line. */
.health-close {
    align-self: flex-start;
    margin: 0;
}

.health-dismiss {
    display: inline-flex;
    padding: 2px;
    border: 0;
    background: none;
    color: var(--muted);
    cursor: pointer;
}

.health-dismiss:hover {
    color: var(--text);
}

.health-dismiss .icon {
    width: 16px;
    height: 16px;
}


/* auto-fit: the cards fill the whole width, as wide as the blocks below. */
.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 20px;
}

.stat-value {
    margin: 0 0 6px;
    font-size: 18px;
    font-weight: 600;
}

.stat .section-body p:last-child {
    margin-bottom: 0;
}

/* How full something is (mailbox, disk, memory): a native <meter>, whose
   value needs no inline style (the CSP blocks those); flat, amber from 80 %,
   red from 95 %. */

.usage-meter {
    display: inline-block;
    width: 80px;
    height: 6px;
    margin: 0 0 0 8px;
    vertical-align: middle;
    appearance: none;
    background: var(--surface-alt);
    border: 1px solid var(--border);
}

.usage-meter.wide {
    display: block;
    width: 100%;
    margin: 0 0 6px;
}

td:has(> .usage-meter) {
    white-space: nowrap;
}

.usage-meter::-webkit-meter-bar {
    height: 6px;
    background: var(--surface-alt);
    border: 0;
    border-radius: 0;
}

.usage-meter::-webkit-meter-optimum-value {
    background: var(--accent);
}

.usage-meter::-webkit-meter-suboptimum-value {
    background: #c98a00;
}

.usage-meter::-webkit-meter-even-less-good-value {
    background: var(--error);
}

.usage-meter::-moz-meter-bar {
    background: var(--accent);
}

.usage-meter:-moz-meter-sub-optimum::-moz-meter-bar {
    background: #c98a00;
}

.usage-meter:-moz-meter-sub-sub-optimum::-moz-meter-bar {
    background: var(--error);
}

.table .num {
    text-align: right;
}

.table tfoot td {
    border-top: 1px solid var(--border);
    border-bottom: 0;
    font-weight: 600;
}

/* Subdomain: label . domain on one line */

.subdomain-input {
    display: flex;
    align-items: center;
    gap: 6px;
}

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

.subdomain-input select {
    flex: 1;
    width: auto;
}

/* Cron jobs */

.cron-fields {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 0 8px;
    margin: 10px 0 0;
    padding: 0;
    border: 0;
}

.cron-fields legend {
    padding: 0;
    font-size: 13px;
    font-weight: 600;
}

.cron-fields label {
    margin-top: 4px;
    font-weight: 400;
    color: var(--muted);
}

.cron-fields input,
.form input.mono {
    font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", monospace;
}

.cron-command code,
code.wrap {
    word-break: break-all;
}

.nowrap {
    white-space: nowrap;
}

.row-off td {
    color: var(--muted);
}

.cron-log {
    max-height: 480px;
    margin: 8px 0 0;
    padding: 10px;
    overflow: auto;
    border: 1px solid var(--border);
    background: var(--surface-alt);
    font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", monospace;
    font-size: 12px;
    white-space: pre-wrap;
    word-break: break-all;
}

@media (max-width: 640px) {
    .cron-fields {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

/* DNS-beheer: one zone record on one row (name, type, value, prio, TTL) */

.dns-fields {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 5fr) minmax(0, 1fr) minmax(0, 1fr);
    gap: 0 8px;
}

.dns-fields label {
    display: block;
    margin: 4px 0 4px;
}

@media (max-width: 640px) {
    .dns-fields {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .dns-fields .dns-value {
        grid-column: 1 / -1;
    }
}

/* File manager */

.file-path {
    font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
    font-size: 18px;
    word-break: break-all;
}

.file-path a {
    color: var(--text);
    text-decoration: none;
}

.file-path a:hover {
    color: var(--accent);
    text-decoration: underline;
}

.file-toolbar {
    display: flex;
    flex-wrap: wrap;
    gap: 12px 24px;
    padding: 12px 16px;
    border-bottom: 1px solid var(--line);
    background: var(--surface-alt);
}

.file-toolbar .inline-controls {
    flex: 1 1 320px;
    margin: 0;
}

.file-bulk {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 12px;
    padding: 8px 16px;
    border-bottom: 1px solid var(--line);
}

.file-bulk .action-label {
    padding-top: 0;
}

/* On a phone the table has no head, so "select all" stands in the bar. */
/* What was copied or cut, with Paste: between the actions and the list. */
.file-clipboard {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    padding: 10px 16px;
    border-bottom: 1px solid var(--border);
    background: var(--surface-alt);
}

.file-clipboard > span:first-child {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-right: auto;
}

.file-select-all {
    display: none;
    align-items: center;
    gap: 6px;
    margin: 0;
    font-size: 14px;
}

.file-bulk .inline-controls {
    flex: 1 1 360px;
}

.file-hidden-toggle {
    margin: 0;
    font-size: 13px;
}

.page-head-main,
.page-head-side {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 12px;
    min-width: 0;
}

/* A protected folder (module htpasswd): a badge that opens its page. */

.badge-lock {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-left: 8px;
    text-decoration: none;
    vertical-align: 1px;
}

.page-head-main .badge-lock {
    margin-left: 0;
}

.badge-lock .icon {
    width: 12px;
    height: 12px;
    vertical-align: 0;
}

a.badge-lock:hover {
    text-decoration: underline;
}

.check-cell {
    width: 32px;
    padding-right: 0;
}

.check-cell input {
    width: 16px;
    height: 16px;
    margin: 0;
    accent-color: var(--accent);
}

.file-name {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--text);
}

a.file-name:hover {
    color: var(--accent);
}

.file-name .icon {
    flex: none;
    color: var(--accent);
}

.file-editor textarea {
    display: block;
    width: 100%;
    min-height: 65vh;
    padding: 12px 16px;
    border: 0;
    border-bottom: 1px solid var(--line);
    background: var(--surface);
    color: var(--text);
    font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
    font-size: 13px;
    line-height: 1.5;
    tab-size: 4;
    resize: vertical;
}

.file-editor textarea:focus {
    outline: none;
    box-shadow: inset 0 0 0 1px var(--accent);
}

.file-editor-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    padding: 12px 16px;
}

/* Certificate details under the HTTPS badge */

.cert-detail {
    display: block;
    margin-top: 3px;
    color: var(--muted);
    font-size: 12px;
}

/* Domains: one line per domain, the details beside the name. */
@media (min-width: 761px) {
    .domains-table td > .cert-detail {
        display: inline;
        margin: 0 0 0 10px;
    }
}

/* A row of buttons under a section's details */

.section-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 12px 16px;
    border-top: 1px solid var(--line);
}

/* Two rows: where to go (grey), what changes the account (red). */
.section-actions.stacked {
    flex-direction: column;
    align-items: flex-start;
}

.button-row {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.section-note {
    margin: 0;
    padding: 12px 16px;
    color: var(--muted);
    font-size: 12px;
}

/* A value with a small "Wijzigen" that opens its form in place. */
.edit-inline > summary {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    list-style: none;
}

.edit-inline > summary::-webkit-details-marker {
    display: none;
}

.edit-inline-link {
    color: var(--accent);
    font-size: 12px;
}

.edit-inline[open] .edit-inline-link {
    display: none;
}

.edit-inline > form {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-top: 6px;
}

/* Its field: the same control as elsewhere, as wide as an IPv6 address. */
.edit-inline > form input[type="text"] {
    box-sizing: border-box;
    width: 26ch;
    max-width: 100%;
    height: var(--control-height);
    padding: 0 10px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", monospace;
    font-size: var(--control-font);
}

.edit-inline > form input[type="text"]:focus {
    border-color: var(--accent);
    outline: none;
    box-shadow: inset 0 0 0 1px var(--accent);
}

.edit-inline > form .button {
    height: var(--control-height);
}

.details-inline {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}

.badges {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 6px;
}

.plain-list {
    margin: 0 0 12px;
    padding-left: 18px;
}

@media (max-width: 720px) {
    .action-row {
        grid-template-columns: 1fr;
    }

    .action-row > label,
    .action-label {
        padding-top: 0;
    }

    :root {
        --gutter: 16px;
        --tile-width: 108px;
    }

    /* Two rows: the name, the levels and the user menu; under them the
       apps with the bell at the right. */
    .topbar .bar {
        position: relative;
        flex-wrap: wrap;
        height: auto;
        gap: 0 8px;
    }

    .topbar .bar::after {
        content: "";
        order: 3;
        flex-basis: 100%;
    }

    .account {
        display: contents;
    }

    .account-user {
        order: 2;
        min-width: 0;
        margin-left: auto;
        padding: 0 0 0 10px;
    }

    /* A long user name ends in dots, so the first row never wraps. */
    .account-user > summary {
        display: flex;
        align-items: center;
        min-width: 0;
        max-width: 160px;
    }

    .account-user .account-name {
        overflow: hidden;
        text-overflow: ellipsis;
    }

    /* Only the mark on a phone: the name is there for screen readers. */
    .brand > span {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }

    .level-apps {
        order: 4;
        margin-left: 0;
    }

    .account > .alert-menu {
        order: 5;
        margin-left: auto;
    }

    .account-menu > summary {
        height: 44px;
    }

    .account-menu > summary.alert-bell {
        padding: 0 0 0 10px;
    }

    .level {
        height: 44px;
        padding: 0 10px;
    }

    .level-app {
        gap: 5px;
        padding: 0 8px;
    }

    .level-apps > .level-app:first-child,
    .level-apps > .level-form:first-child .level-app {
        padding-left: 0;
        border-left: 0;
    }

    /* The list of notices opens under the bar, within the gutter. */
    .alert-items {
        right: var(--gutter);
    }
}

/* A small phone: the apps show only their icons, so the bell stays on
   the second row (the names are still read out). */
@media (max-width: 379px) {
    .level-app {
        font-size: 0;
    }

    .level-app .icon {
        width: 20px;
        height: 20px;
    }

    .auth-box {
        margin: 24px auto;
        padding: 20px 16px;
    }
}

/* A label above a group of radio buttons (spam settings). */
.form .group-label {
    margin: 10px 0 0;
    font-size: 13px;
    font-weight: 600;
}

/* Arranging a dashboard in place (admin, dashboard-layout.js). Arrange
   mode keeps the page as it is: headings become fields, a cross shows on
   the tile under the pointer, drop places only show while dragging. */
.dashboard:not(.is-arranging) .arrange-only {
    display: none !important;
}

.dashboard.is-arranging .arrange-only {
    display: revert;
}

.dashboard.is-arranging .arrange-off-only {
    display: none;
}

.arrange-toolbar,
.dashboard.is-arranging .arrange-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.dashboard.is-arranging .section-title:has(+ .arrange-head),
.dashboard.is-arranging .subsection-title:has(+ .arrange-head) {
    display: none;
}

.dashboard.is-arranging .arrange-head {
    display: flex;
    align-items: center;
    gap: 2px;
}

.dashboard.is-arranging .panel-section > .arrange-head {
    padding: 3px 6px 3px 4px;
    background: var(--surface-alt);
    border-bottom: 1px solid var(--line);
}

.dashboard.is-arranging .subsection > .arrange-head {
    border-bottom: 1px solid var(--line);
}

.arrange-title {
    flex: 1;
    min-width: 0;
    padding: 3px 4px;
    border: 1px solid transparent;
    border-radius: 3px;
    background: transparent;
    color: var(--muted);
    font: inherit;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.arrange-section-title {
    font-size: 12px;
}

.arrange-title::placeholder {
    color: var(--faint);
    font-weight: 400;
    text-transform: none;
    letter-spacing: 0;
}

.arrange-title:hover,
.arrange-title:focus {
    border-color: var(--border);
    background: var(--surface);
    color: var(--text);
    outline: none;
}

.arrange-handle {
    display: flex;
    color: var(--faint);
    cursor: grab;
}

.arrange-handle .icon {
    width: 14px;
    height: 14px;
}

.arrange-remove,
.arrange-hide,
.arrange-show {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2px;
    border: 0;
    border-radius: 3px;
    background: none;
    color: var(--faint);
    cursor: pointer;
}

.arrange-remove .icon {
    width: 14px;
    height: 14px;
}

/* The cross of a group or section only when the pointer is on its head. */
.dashboard.is-arranging .arrange-remove {
    opacity: 0;
}

.dashboard.is-arranging .arrange-head:hover .arrange-remove,
.dashboard.is-arranging .arrange-remove:focus-visible {
    opacity: 1;
}

.arrange-remove:hover,
.arrange-hide:hover {
    background: var(--error-bg);
    color: var(--error);
}

.arrange-tile {
    position: relative;
}

.dashboard.is-arranging .arrange-tile {
    cursor: grab;
}

.dashboard.is-arranging .arrange-tile .tile {
    pointer-events: none;
}

.dashboard.is-arranging .arrange-tile:hover .tile {
    background: var(--accent-soft);
    border-color: var(--accent-line);
}

.dashboard.is-arranging .arrange-hide,
.dashboard.is-arranging .arrange-show {
    position: absolute;
    top: 4px;
    right: 10px;
    width: 20px;
    height: 20px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 50%;
    opacity: 0;
}

.dashboard.is-arranging .arrange-hide .icon,
.dashboard.is-arranging .arrange-show .icon {
    display: block;
    width: 12px;
    height: 12px;
}

/* .arrange-only resets display in arrange mode; these stay centred. */
.dashboard.is-arranging .arrange-tile .arrange-hide {
    display: flex;
    padding: 0;
}

.dashboard.is-arranging .arrange-hidden .arrange-tile .arrange-show {
    display: flex;
    padding: 0;
}

.dashboard.is-arranging .arrange-tile:hover .arrange-hide,
.dashboard.is-arranging .arrange-tile:hover .arrange-show,
.dashboard.is-arranging .arrange-hide:focus-visible,
.dashboard.is-arranging .arrange-show:focus-visible {
    opacity: 1;
}

.dashboard.is-arranging .arrange-show,
.dashboard.is-arranging .arrange-hidden .arrange-tile .arrange-hide {
    display: none;
}

.dashboard.is-arranging .arrange-hidden .arrange-show {
    display: flex;
}

.arrange-show:hover {
    background: var(--accent-soft);
    color: var(--accent);
}

/* An empty group or Verborgen says what it is for. */
.dashboard.is-arranging [data-drop="tile"]:not(:has(li))::after {
    content: attr(data-empty);
    display: block;
    width: 100%;
    padding: 18px 12px;
    border: 1px dashed var(--border);
    color: var(--faint);
    font-size: 12px;
    text-align: center;
}

/* While dragging, every place a tile can go is marked. */
.dashboard.is-dragging-tile .subsection > [data-drop="tile"],
.dashboard.is-dragging-tile .arrange-hidden [data-drop="tile"] {
    min-height: 60px;
    outline: 1px dashed var(--accent-line);
    outline-offset: -1px;
}

.dashboard.is-arranging .subsections {
    min-height: 40px;
}

.arrange-intro {
    margin: 0 0 12px;
    color: var(--muted);
}

/* Verborgen comes after the sections, so arrange mode moves nothing. */
.dashboard.is-arranging {
    display: flex;
    flex-direction: column;
}

.dashboard.is-arranging .arrange-hidden {
    order: 2;
    margin: 20px 0 0;
}

.arrange-hidden .hidden-title {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 9px 16px;
    color: var(--muted);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.arrange-hidden .icon-grid {
    margin: 10px 16px;
}

.arrange-add {
    padding: 0 16px 12px;
}

.is-dragging {
    opacity: 0.4;
}

.is-over {
    outline: 2px dashed var(--accent) !important;
    outline-offset: -2px;
}

/* Arranging the blocks of a page in place (admin, blocks.js, BlockGrid),
   like the dashboard: the toolbar sits above the first grid, handles show
   in the block titles only in arrange mode. */
.blocks-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: 6px;
    margin-bottom: 12px;
}

.blocks-toolbar-head {
    margin-bottom: 0;
}

.blocks-intro {
    flex: 1 1 260px;
    color: var(--muted);
    font-size: 13px;
}

.page:not(.is-arranging-blocks) .blocks-toolbar .arrange-only,
.page:not(.is-arranging-blocks) .blocks-handle,
.page.is-arranging-blocks .blocks-toolbar .arrange-off-only {
    display: none;
}

.page.is-arranging-blocks .blocks-toolbar .arrange-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.blocks-handle {
    display: inline-flex;
    align-items: center;
    margin: 0 2px 0 -6px;
    padding: 2px;
    border: 0;
    border-radius: 3px;
    background: transparent;
    color: var(--faint);
    cursor: grab;
}

.blocks-handle .icon {
    width: 14px;
    height: 14px;
}

.blocks-handle:hover,
.blocks-handle:focus-visible {
    color: var(--text);
    background: var(--surface);
}

.page.is-arranging-blocks [data-column] > [data-block] {
    outline: 1px dashed var(--border);
    outline-offset: 2px;
}

/* An empty column stays a place to drop a block. */
.page.is-arranging-blocks [data-grid] > [data-column] {
    min-height: 120px;
}

.page.is-arranging-blocks [data-grid] > [data-column]:not(:has([data-block])) {
    border: 1px dashed var(--border);
    border-radius: 4px;
}

.button[disabled] {
    opacity: 0.5;
    cursor: not-allowed;
}

.break {
    word-break: break-all;
}

/* A select in a row (PHP version per website): the same control, only
   as wide as its choices. */
.table select,
.panel-section dd .inline-form select {
    box-sizing: border-box;
    width: auto;
    min-width: 0;
    height: var(--control-height);
    padding: 0 8px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-size: var(--control-font);
}

/* Compact tables: forms in a row. */

.table-compact .inline-form {
    display: inline-block;
    margin: 0 0 0 4px;
    vertical-align: middle;
}

.table-compact td:nth-child(3) .inline-form {
    margin-left: 0;
}

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

/* Serverstatus: the server name with its restart button. */
.stat-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 6px;
}

.stat-head .stat-value {
    margin: 0;
}

/* Language choice at the bottom of the account menu. */
.account-menu-language {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0;
    padding: 9px 14px;
    border-top: 1px solid var(--line);
}

.account-menu-language .link-button {
    padding: 0;
    color: var(--text);
}

.account-menu-language .link-button[aria-current="true"] {
    font-weight: 600;
    cursor: default;
    opacity: 1;
}

/* Filters above a log (Audit log): one bar in the panel's own style. */
.filter-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 0 0 12px;
    padding: 10px 12px;
    border: 1px solid var(--border);
    background: var(--surface);
}

.filter-bar input,
.filter-bar select {
    height: var(--control-height);
    padding: 0 10px;
    border: 1px solid var(--border);
    border-radius: 0;
    background: var(--surface);
    color: var(--text);
    font: inherit;
    /* The same size as the fields of every other form. */
    font-size: var(--control-font);
}

.filter-bar select {
    flex: 0 0 160px;
    padding: 0 6px;
}

.filter-bar input {
    flex: 1 1 140px;
    min-width: 0;
}

.filter-bar input[type="search"] {
    flex: 2 1 220px;
}

.filter-bar input:focus,
.filter-bar select:focus {
    border-color: var(--accent);
    outline: none;
    box-shadow: inset 0 0 0 1px var(--accent);
}

.audit-details > span {
    display: block;
    font-size: 12px;
    word-break: break-word;
}

/* Spamfilter (ADR 0026): one compact line per message; Details opens a
   row below it with the facts, the reasons and the allow/block form. */
.spam-table td {
    white-space: nowrap;
}

.spam-table td.clip {
    max-width: 260px;
    overflow: hidden;
    text-overflow: ellipsis;
}

.spam-table .num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* A row that a "Details" link opens (Spamfilter, Audit-log). */
.detail-row {
    display: none;
}

.detail-row:target,
.detail-row.open {
    display: table-row;
}

.detail-row > td {
    white-space: normal;
    background: var(--surface-alt);
}

.spam-detail > td {
    white-space: normal;
    background: var(--surface-alt);
}

.spam-detail-body {
    display: grid;
    grid-template-columns: minmax(220px, 1fr) 2fr;
    gap: 8px 24px;
    font-size: 13px;
}

.spam-facts {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 2px 12px;
    margin: 0;
}

.spam-facts dt {
    color: var(--muted);
}

.spam-facts dd {
    margin: 0;
}

.spam-reasons {
    margin: 0 0 6px;
    padding: 0;
    list-style: none;
}

.spam-reasons li {
    margin: 2px 0;
}

.spam-plus,
.spam-minus {
    display: inline-block;
    min-width: 3.5em;
    font-variant-numeric: tabular-nums;
}

.spam-plus {
    color: var(--error);
}

.spam-minus {
    color: var(--ok);
}

.spam-action {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin-top: 6px;
}

.spam-action select {
    width: auto;
}

.spam-action .checkbox {
    margin: 0;
}

.spam-buttons {
    display: inline-flex;
    gap: 4px;
}

@media (max-width: 760px) {
    .spam-detail-body {
        grid-template-columns: 1fr;
    }
}

/* Below a long list: rows shown, page links, rows per page (partials/pager). */
.pager {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 8px 16px;
    padding: 10px 12px;
    border-top: 1px solid var(--line);
    font-size: 13px;
}

.pager-info .muted {
    margin-left: 4px;
}

.pager-pages {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px;
}

.pager-current {
    border-color: var(--accent);
    background: var(--accent-soft);
    font-weight: 600;
    cursor: default;
}

.pager-gap {
    padding: 0 4px;
    color: var(--muted);
}

.pager-size {
    margin: 0;
}

.pager-size label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 0;
    font-weight: normal;
}

.pager-size select {
    box-sizing: border-box;
    width: auto;
    min-width: 0;
    height: var(--control-height);
    padding: 0 8px;
    font-size: var(--control-font);
}

/* Log viewer (ADR 0027): one log line per row, newest first. */
.log-lines {
    margin: 0;
    padding: 6px 12px;
    list-style: none;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 12px;
    line-height: 1.5;
}

.log-lines li {
    padding: 1px 0;
    border-bottom: 1px solid var(--line);
    white-space: pre-wrap;
    word-break: break-all;
}

.log-lines li:last-child {
    border-bottom: 0;
}

/* Monitoring (ADR 0028): one line per check, its threshold to the right. */
.monitor-checks {
    margin: 12px 0 0;
    padding: 0;
    border: 0;
}

.monitor-checks legend {
    margin-bottom: 6px;
    font-weight: 600;
}

.monitor-check {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 4px 12px;
    padding: 4px 0;
    border-bottom: 1px solid var(--line);
}

.monitor-check .checkbox {
    margin: 0;
}

.monitor-threshold {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
    font-size: 13px;
}

.input-number {
    width: 6.5em;
}

.monitor-problems {
    margin: 0 0 12px;
    padding: 0;
    list-style: none;
}

.monitor-problems li {
    margin: 6px 0;
}

/* Wijzigingen: the changelog, one block per version. */
.changelog-version {
    padding: 12px 16px;
    border-top: 1px solid var(--line);
}

.changelog-title {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 6px;
    font-size: 15px;
    font-variant-numeric: tabular-nums;
}

.changelog-body p,
.changelog-body ul,
.changelog-intro p {
    margin: 4px 0;
}

.changelog-body ul {
    padding-left: 20px;
}

.changelog-body li {
    margin: 3px 0;
}

.footer .bar a {
    color: inherit;
}

/* A row the page was asked to point out (Mailboxen from Gebruikers). */
tr.is-highlight > td {
    background: var(--accent-soft);
}

tr.is-highlight:target > td:first-child {
    box-shadow: inset 3px 0 0 var(--accent);
}

/* Audit-log: the details of an entry, under Details. */
.audit-detail-list {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 2px 12px;
    margin: 0;
    font-size: 13px;
}

.audit-detail-list dt {
    color: var(--muted);
}

.audit-detail-list dd {
    margin: 0;
    word-break: break-word;
}

/* Load chart on Serverstatus (an SVG the panel draws). */
.section-title-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding-top: 4px;
    padding-bottom: 4px;
}

.section-title-row h2 {
    margin: 0;
    font: inherit;
}

.segmented {
    display: inline-flex;
    border: 1px solid var(--border);
}

.segmented a {
    display: inline-block;
    padding: 3px 10px;
    color: var(--muted);
    font-size: 13px;
    line-height: 20px;
    font-weight: normal;
    text-decoration: none;
}

.segmented a + a {
    border-left: 1px solid var(--border);
}

.segmented a.is-active {
    background: var(--accent-soft);
    color: var(--text);
    font-weight: 600;
}

.load-chart {
    margin: 0;
}

.load-chart svg {
    display: block;
    width: 100%;
    height: auto;
}

.load-chart .grid {
    stroke: var(--line);
    stroke-width: 1;
}

.load-chart .grid-v {
    stroke-dasharray: 2 4;
}

.load-chart .axis {
    fill: var(--muted);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
}

.load-chart .line {
    fill: none;
    stroke-width: 2;
    stroke-linejoin: round;
    stroke-linecap: round;
}

.load-chart .line-1 {
    stroke: #d64545;
    stroke-width: 1.5;
}

.load-chart .line-5 {
    stroke: #d99a1e;
}

.load-chart .line-15 {
    stroke: #2f7fd1;
    stroke-width: 2.5;
}

.load-chart .area {
    fill: #d64545;
    opacity: 0.08;
}

.load-chart .capacity {
    stroke: var(--muted);
    stroke-width: 1;
    stroke-dasharray: 6 4;
}

.load-chart .capacity-label {
    fill: var(--muted);
    font-size: 11px;
}

.load-chart .hover rect {
    fill: transparent;
}

.load-chart .hover rect:hover {
    fill: var(--accent);
    opacity: 0.12;
}

.load-legend {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 6px 18px;
    margin-top: 6px;
    color: var(--muted);
    font-size: 13px;
}

.load-legend span {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.load-legend .swatch {
    display: inline-block;
    width: 18px;
    height: 3px;
    border-radius: 2px;
}

.load-legend .swatch.line-1 {
    background: #d64545;
}

.load-legend .swatch.line-5 {
    background: #d99a1e;
}

.load-legend .swatch.line-15 {
    background: #2f7fd1;
}

.load-legend .swatch.capacity {
    background: repeating-linear-gradient(90deg, var(--muted) 0 6px, transparent 6px 10px);
}

/* Statistieken (ADR 0032), GoAccess style: hits as a light bar, visitors
   as a dark bar inside it; the top lists two by two. */
.stats-bar .inline-form {
    display: inline-flex;
}

.stats-totals {
    margin-bottom: 0;
}

.stats-chart {
    margin: 0;
}

.stats-chart svg {
    display: block;
    width: 100%;
    height: auto;
}

.stats-chart .grid {
    stroke: var(--line);
    stroke-width: 1;
}

.stats-chart .axis {
    fill: var(--muted);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
}

.stats-chart .hit-bar,
.load-legend .swatch.hit-bar {
    fill: var(--accent-line);
    background: var(--accent-line);
}

.stats-chart .visitor-bar,
.load-legend .swatch.visitor-bar {
    fill: var(--accent);
    background: var(--accent);
}

.stats-chart .bar:hover .hit-bar {
    fill: var(--action);
}

.load-legend .swatch.hit-bar,
.load-legend .swatch.visitor-bar {
    height: 10px;
    width: 10px;
}

.stats-charts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(420px, 1fr));
    gap: 20px;
    align-items: start;
}

.stats-donut {
    display: flex;
    align-items: center;
    gap: 20px;
    margin: 0;
}

.stats-donut svg {
    flex: 0 0 auto;
    width: 110px;
    height: 110px;
}

.stats-donut circle {
    fill: none;
    stroke-width: 22;
}

.stats-donut .donut-track {
    stroke: var(--line);
}

.stats-donut-legend {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
    font-size: 13px;
}

.stats-donut-legend > span {
    display: flex;
    align-items: center;
    gap: 6px;
    overflow-wrap: anywhere;
}

.stats-donut-legend .swatch {
    flex: 0 0 auto;
    width: 10px;
    height: 10px;
    border-radius: 2px;
}

.stats-donut .donut-0 { stroke: #4e8a1e; }
.stats-donut .donut-1 { stroke: #8cc63e; }
.stats-donut .donut-2 { stroke: #2f7fd1; }
.stats-donut .donut-3 { stroke: #d99a1e; }
.stats-donut .donut-4 { stroke: #8a6fd1; }
.stats-donut .donut-5 { stroke: #b8c2ba; }
.stats-donut-legend .donut-0 { background: #4e8a1e; }
.stats-donut-legend .donut-1 { background: #8cc63e; }
.stats-donut-legend .donut-2 { background: #2f7fd1; }
.stats-donut-legend .donut-3 { background: #d99a1e; }
.stats-donut-legend .donut-4 { background: #8a6fd1; }
.stats-donut-legend .donut-5 { background: #b8c2ba; }

.stats-donut-body {
    border-bottom: 1px solid var(--line);
}

.stats-lists {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(380px, 1fr));
    gap: 20px;
    align-items: start;
}

.stats-top td {
    vertical-align: middle;
}

.stats-top .stats-name {
    overflow-wrap: anywhere;
}

.stats-top .stats-meter {
    width: 110px;
}

.stats-top meter {
    display: block;
    width: 100%;
    height: 6px;
}

.stats-top .num {
    width: 80px;
}

/* The rest of a top list, behind "Alle 25 tonen". */
.stats-more > summary {
    padding: 10px 16px;
    color: var(--accent);
    cursor: pointer;
}

.stats-more[open] > summary {
    border-bottom: 1px solid var(--border);
}

@media (max-width: 520px) {
    .stats-lists,
    .stats-charts {
        grid-template-columns: 1fr;
    }

    .stats-top .stats-meter {
        width: 60px;
    }
}

/* Modules: per module one table (service, version, status ...), links below. */
.module-title {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 10px;
}

.module-dep {
    color: var(--muted);
    font-size: 12px;
    font-weight: normal;
    text-transform: none;
    letter-spacing: 0;
}

.module-services .software-row td {
    color: var(--muted);
}

.module-links {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    padding: 8px 12px 12px;
}

.module-block.is-off .module-title {
    opacity: 0.7;
}

/* Every module's table has the same columns in the same place. */
.module-services {
    table-layout: fixed;
}

/* Fixed widths, the name takes the rest; the button column holds the
   widest set (Stoppen, Herstarten, Herladen) so nothing sticks out. */
.module-services th:nth-child(2) { width: 120px; }
.module-services th:nth-child(3) { width: 110px; }
.module-services th:nth-child(4) { width: 140px; }
.module-services th:nth-child(5) { width: 100px; }
.module-services th:nth-child(6) { width: 80px; }
.module-services th:nth-child(7) { width: 290px; }

.module-services td {
    overflow-wrap: anywhere;
}

/* Subtly rounded corners (the reset above makes everything square first). */
.panel-section,
.tile,
.flash,
.filter-bar,
.auth-box,
.account-menu-items,
.action-menu-items,
.load-chart svg {
    border-radius: var(--radius);
}

.panel-section > .section-title:first-child,
.panel-section > .section-title-row:first-child,
.panel-section > h2:first-child {
    border-radius: var(--radius) var(--radius) 0 0;
}

.button,
.badge,
.segmented,
input,
select,
textarea,
.filter-bar input,
.filter-bar select,
code {
    border-radius: var(--radius-sm);
}

.segmented a:first-child {
    border-radius: var(--radius-sm) 0 0 var(--radius-sm);
}

.segmented a:last-child {
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}

input[type="checkbox"] {
    border-radius: 2px;
}

input[type="radio"] {
    border-radius: 50%;
}

/* Tiles line up in columns: groups side by side have no gap of their own,
   so a group of one tile takes exactly one column. */
.subsections {
    gap: 4px 0;
}

.subsection-title {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.section-head > .section-title {
    min-width: 0;
    overflow-wrap: anywhere;
}

/* Phones: three tile columns over the full width, and table rows as cards
   (menu.js gives each cell its column's name as data-label). */
@media (max-width: 720px) {
    :root {
        /* page gutters, the section's border and the grid's padding */
        --tile-width: calc((100vw - 2 * var(--gutter) - 2px - 16px) / 3);
    }

    .table-wrap:has(> .table:not(.table-keep)) {
        overflow-x: visible;
    }

    .table:not(.table-keep),
    .table:not(.table-keep) tbody,
    .table:not(.table-keep) tfoot {
        display: block;
        width: 100%;
    }

    .table:not(.table-keep) thead {
        display: none;
    }

    .file-select-all {
        display: inline-flex;
    }

    .table:not(.table-keep) tr:not(.detail-row) {
        display: block;
        padding: 8px 16px;
        border-bottom: 1px solid var(--line);
    }

    .table:not(.table-keep) tbody tr:last-child {
        border-bottom: 0;
    }

    .table:not(.table-keep) tr.detail-row:target,
    .table:not(.table-keep) tr.detail-row.open {
        display: block;
    }

    .table:not(.table-keep) tr[hidden] {
        display: none;
    }

    .table:not(.table-keep) td,
    .table:not(.table-keep) th {
        height: auto;
        display: flex;
        align-items: baseline;
        justify-content: space-between;
        gap: 4px 16px;
        padding: 3px 0;
        border-bottom: 0;
        text-align: right;
        white-space: normal;
        overflow-wrap: anywhere;
    }

    .table:not(.table-keep) td::before {
        content: attr(data-label);
        flex: none;
        max-width: 45%;
        color: var(--muted);
        font-size: 11px;
        letter-spacing: 0.04em;
        text-align: left;
        text-transform: uppercase;
    }

    /* The first cell names the row: a title without a label. */
    .table:not(.table-keep) tr > td:first-child {
        justify-content: flex-start;
        font-weight: 600;
        text-align: left;
    }

    .table:not(.table-keep) tr > td:first-child::before,
    .table:not(.table-keep) td:not([data-label])::before {
        content: none;
    }

    .table:not(.table-keep) td[colspan] {
        display: block;
        text-align: left;
    }

    .table:not(.table-keep) td.actions-cell {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        justify-content: flex-start;
        gap: 6px;
        padding-top: 6px;
    }

    /* Buttons and the forms around them line up as equals. */
    .table:not(.table-keep) td.actions-cell > *,
    .table:not(.table-keep) td.actions-cell .inline-form {
        display: inline-flex;
        margin: 0;
    }

    .table:not(.table-keep) td.actions-cell::before {
        content: none;
    }

    .table:not(.table-keep) td.actions-cell .cell-actions {
        justify-content: flex-start;
    }

    /* Cards on a phone line nothing up: no empty slots. */
    .table:not(.table-keep) td.actions-cell .icon-slot {
        display: none;
    }

    .table:not(.table-keep) td:empty {
        display: none;
    }

    .table:not(.table-keep) td > .badge {
        flex: none;
    }

    /* DNS: the explanation under the status, not squeezed beside it. */
    .table.dns-table:not(.table-keep) td {
        flex-wrap: wrap;
    }

    .table.dns-table:not(.table-keep) td > .cert-detail {
        flex-basis: 100%;
    }

    .table:not(.table-keep) .num,
    .spam-table td.clip,
    .error-cell {
        max-width: none;
    }

    .detail-row > td {
        margin: 6px -16px -8px;
        padding: 8px 16px;
    }
}

/* A long value (an address, a key) wraps instead of widening the page. */
.details {
    grid-template-columns: minmax(0, max-content) minmax(0, 1fr);
}

.details dd {
    min-width: 0;
    overflow-wrap: anywhere;
}

@media (max-width: 720px) {
    .details {
        gap: 6px 16px;
        padding: 12px 16px;
    }
}

/* Unlimited in an overview. */
/* A second heading on a page (Openprovider on Instellingen). */
.page-subtitle {
    margin: 28px 0 12px;
    font-size: 18px;
    font-weight: 600;
    scroll-margin-top: 16px;
}

/* A page's introduction under its title: always the same distance to the
   first section. */
main > .hint {
    max-width: 960px;
    margin: 0 0 16px;
    font-size: 13px;
}

/* Uitloggen: the last item of the account menu, like its links. */
.account-menu-logout {
    margin: 0;
    border-top: 1px solid var(--line);
}

.account-menu-logout button {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 9px 14px;
    border: 0;
    background: none;
    color: var(--text);
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.account-menu-logout button:hover,
.account-menu-logout button:focus-visible {
    background: var(--surface-alt);
}

/* PHP versions in the block of module web on Modules. */
.php-versions {
    border-top: 1px solid var(--line);
}

.subsection-heading {
    margin: 0;
    padding: 10px 16px 6px;
    color: var(--muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* Arrange mode keeps every group as wide as its tiles: the title field
   (an input, about 20 characters wide by itself) and its buttons never
   widen a group, so no tile moves to another row. */
.dashboard.is-arranging .subsection > .arrange-head {
    contain: inline-size;
}

.arrange-title {
    width: 0;
}

/* Spamfilter: the lists for the whole server side by side. */
.spam-lists-fields {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 0 16px;
}

/* Restoring: the options of overwriting only matter when it is chosen. */
.restore-overwrite {
    margin: 4px 0 0 24px;
}

.form:has(input[name="mode"][value="copy"]:checked) .restore-overwrite {
    display: none;
}

/* The customer's Back-ups: one choice per line, its list beside it; the
   archive itself is never unpacked, so "how" does not apply. */
.restore-choices {
    display: grid;
    gap: 8px;
}

.restore-choices .inline-controls .checkbox-inline {
    flex: 0 0 150px;
}

.form:has(input[name="what"][value="archive"]:checked) .restore-how {
    display: none;
}

/* A role next to a name (Reseller in the list of customers): small, calm,
   in a colour of its own so it never reads as a state. */
.badge-role {
    margin-left: 6px;
    padding: 0 6px;
    border-color: #c7d7ec;
    border-radius: 999px;
    background: #eef4fb;
    color: #2f5b8f;
    font-size: 10px;
    line-height: 16px;
    vertical-align: 1px;
}

/* A new password with the button that generates one (menu.js). */
.password-field {
    display: flex;
    gap: 8px;
    align-items: stretch;
}

.password-field input {
    flex: 1;
    min-width: 0;
}

.password-field .password-generate {
    flex: none;
    white-space: nowrap;
}

.password-note {
    margin: 6px 0 0;
    padding: 6px 10px;
    border-left: 3px solid var(--ok-line);
    background: var(--ok-bg);
    font-size: 13px;
}

.password-note code {
    font-weight: 600;
    user-select: all;
}

.password-note .link-button {
    padding: 0;
    border: 0;
    background: none;
    color: var(--accent);
    font: inherit;
    text-decoration: underline;
    cursor: pointer;
}

/* Customer details (ADR 0030): private or business, postcode beside city. */
.radio-group {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 20px;
    margin: 10px 0 0;
    padding: 0;
    border: 0;
}

.radio-group legend {
    width: 100%;
    margin-bottom: 4px;
    font-size: 13px;
    font-weight: 600;
}

.form-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
    gap: 12px;
}

.form-row > div {
    display: grid;
    gap: 6px;
    align-content: start;
}

.form-row-even {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}

@media (max-width: 520px) {
    .form-row,
    .form-row-even {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* Labels beside their fields, like a table (Instellingen > Algemeen):
   the label on the line of the field, the hint under the field. Short
   fields stay short. One column on a narrow screen. */
.form.form-aligned {
    grid-template-columns: minmax(0, 13em) minmax(0, 1fr);
    gap: 12px 16px;
    align-items: start;
}

/* The name of a row, as in a table (Maildoelen): 13px, bold, on the
   line of the field. */
.form.form-aligned > label {
    margin-top: 0;
    padding-top: 7px;
    font-size: 13px;
    font-weight: 700;
}

.form.form-aligned .form-field {
    display: grid;
    gap: 4px;
    min-width: 0;
}

.form.form-aligned input[type="number"] {
    max-width: 8em;
}

.form.form-aligned select {
    max-width: 16em;
}

.form.form-aligned > .form-actions {
    grid-column: 1 / -1;
    margin-top: 4px;
}

@media (max-width: 520px) {
    .form.form-aligned {
        grid-template-columns: minmax(0, 1fr);
        gap: 6px;
    }
}

/* A heading between groups of fields in a long form. */
.form-heading {
    margin: 22px 0 0;
    padding-top: 14px;
    border-top: 1px solid var(--line);
    font-size: 14px;
}

/* File fields (database restore): the browser's grey button gets the
   panel's button look, the field a dashed drop-zone border. */
.form input[type="file"] {
    height: auto;
    padding: 6px;
    border-style: dashed;
    color: var(--muted);
    cursor: pointer;
}

/* The same field in the file manager's toolbar (Uploaden). */
.inline-controls input[type="file"] {
    flex: 1 1 220px;
    min-width: 0;
    padding: 4px;
    border: 1px dashed var(--border);
    background: var(--surface);
    color: var(--muted);
    font: inherit;
    font-size: var(--control-font);
    cursor: pointer;
}

.inline-controls input[type="file"]::file-selector-button {
    height: 28px;
    margin-right: 10px;
    padding: 0 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface-alt);
    color: var(--text);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.inline-controls input[type="file"]:hover::file-selector-button {
    border-color: var(--accent);
}

/* Rechten: read, write and run for owner, group and others. */
.permission-grid {
    width: auto;
    margin-bottom: 4px;
}

.permission-grid th,
.permission-grid td {
    padding-right: 28px;
}

.permission-grid td {
    text-align: center;
}

/* The small green checkboxes of the rest of the panel, not a form field. */
.form .permission-grid input[type="checkbox"] {
    width: 16px;
    height: 16px;
    margin: 0;
    vertical-align: middle;
    accent-color: var(--accent);
}

.form input[type="file"]::file-selector-button {
    height: 30px;
    margin-right: 12px;
    padding: 0 14px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface-alt);
    color: var(--text);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.form input[type="file"]:hover::file-selector-button {
    border-color: var(--accent);
}

/* A time or number next to its choice (backup schedule "Dagelijks om"),
   and the small numbers of Monitoring, keep their own width in a form. */
.inline-controls input[type="time"],
.inline-controls input[type="number"] {
    flex: 0 0 auto;
    width: auto;
}

.form .input-number {
    width: 6.5em;
}

/* Usage of the package next to a page title (partials/usage): one block
   as high as the button beside it. */
.usage-pill {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: var(--control-height);
    padding: 0 14px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    font-size: 13px;
    white-space: nowrap;
}

.usage-pill-label {
    color: var(--muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.usage-pill .usage-meter {
    width: 60px;
    margin: 0;
}

.usage-pill-full {
    border-color: #c98a00;
}

.page-head .badges {
    align-items: center;
}

/* Tables with the same column widths on every page (.table-fixed): the
   first column without a width class takes what is left, the buttons
   stand right. On a phone the rows become cards, as everywhere. */
@media (min-width: 721px) {
    .table-fixed {
        table-layout: fixed;
    }

    .table-fixed td {
        overflow-wrap: anywhere;
    }

    .table-fixed td.actions-cell {
        overflow-wrap: normal;
    }

    .table-fixed .w-xs { width: 100px; }
    .table-fixed .w-s { width: 130px; }
    .table-fixed .w-m { width: 170px; }
    .table-fixed .w-l { width: 210px; }
    .table-fixed .w-xl { width: 300px; }
    .table-fixed .w-icon { width: 64px; }
    /* DNS: room for a status with its explanation below it. */
    .table-fixed .w-dns-status { width: 250px; }
    /* Room for 2, 3 or 4 small buttons of 13px text (Databases needs 513px). */
    .table-fixed .w-actions-2 { width: 280px; }
    .table-fixed .w-actions-3 { width: 400px; }
    .table-fixed .w-actions-4 { width: 540px; }

    /* Firewall: Fail2ban and the two lists as blocks, each half the page. */
    .firewall-blocks .table-fixed .w-l { width: 26%; }
    .firewall-blocks .table-fixed .w-m { width: 17%; }
    .firewall-blocks .table-fixed .w-s { width: 14%; }
    .firewall-blocks .table-fixed .w-icon { width: 56px; }
}

/* In a table with fixed columns a long header may wrap. */
@media (min-width: 721px) {
    .table-fixed th {
        white-space: normal;
    }
}

/* Modules without services of their own, a row each: several buttons may
   wrap, and stay right. A module that is off is greyed. */
.module-light td.actions-cell {
    white-space: normal;
}

.module-light td.actions-cell .button {
    margin: 2px 0 2px 4px;
}

.module-light tr.is-off td {
    color: var(--muted);
}

/* Pakketten: the name has a fixed width, the other columns share the rest
   and are centred under their header. */
@media (min-width: 721px) {
    .package-table {
        min-width: 1100px;
    }

    .package-table th,
    .package-table td {
        text-align: center;
        white-space: nowrap;
    }

    .package-table th:first-child,
    .package-table td:first-child {
        text-align: left;
    }

    .package-table td.actions-cell {
        text-align: right;
    }
}

/* A part within a block (Vrijgegeven domeinen under the Openprovider login). */
.section-subtitle {
    margin: 0;
    padding: 12px 16px 8px;
    border-top: 1px solid var(--line);
    color: var(--muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* DNS for the server's mail, half a page: the DKIM value wraps. */
#server-mail td {
    overflow-wrap: anywhere;
}

/* Klanten (admin): many fixed columns; the names keep room, a narrow window
   scrolls this table instead of squeezing them away. */
@media (min-width: 721px) {
    .wide-table {
        min-width: 1650px;
    }

    .table-fixed th.nowrap {
        white-space: nowrap;
    }
}

/* Instellingen > Maildoelen: a name and the MX records per destination,
   the same controls as every form. */
.destinations-table input,
.destinations-table textarea {
    box-sizing: border-box;
    width: 100%;
    padding: 6px 10px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-size: var(--control-font);
}

.destinations-table input {
    height: var(--control-height);
    padding: 0 10px;
}

/* Half the page wide: the name columns share the room with the MX records. */
@media (min-width: 721px) {
    .table-fixed.destinations-table .w-l { width: 27%; }
}

.destinations-table textarea {
    font-family: var(--mono, monospace);
    font-size: 13px;
    resize: vertical;
}

/* Domeinnamen (admin): many columns; the names keep room. */
@media (min-width: 721px) {
    .wide-domains {
        min-width: 1250px;
    }
}

/* Holds the place of a button a row lacks (Domeinnamen), so the same
   buttons line up; on a phone the row just wraps without it. */
.button-gap {
    visibility: hidden;
}

@media (max-width: 720px) {
    .table td.actions-cell > .button-gap {
        display: none;
    }
}

/* PHP-instellingen of a website (admin): each choice with its name above. */
.php-settings {
    align-items: flex-end;
}

.php-setting {
    display: grid;
    gap: 2px;
    font-size: 12px;
}

.php-setting select {
    flex: none;
}

/* Facturen: the lines of a concept, each field in its own cell. */
.invoice-lines input,
.invoice-lines select {
    width: 100%;
    min-width: 0;
    height: var(--control-height);
    padding: 0 8px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-size: var(--control-font);
}

.invoice-lines input.num {
    text-align: right;
}

.invoice-lines input:focus,
.invoice-lines select:focus {
    border-color: var(--accent);
    outline: none;
    box-shadow: inset 0 0 0 1px var(--accent);
}

.table tfoot th {
    text-transform: none;
    letter-spacing: 0;
    font-size: inherit;
    color: var(--text);
}

.invoice-lines .invoice-new-line select {
    margin-bottom: 6px;
}

.invoice-lines tfoot th,
.invoice-lines tfoot td,
.table tfoot th,
.table tfoot td {
    border-bottom: 0;
    font-weight: 400;
}

.table tfoot .invoice-total th,
.table tfoot .invoice-total td {
    border-top: 1px solid var(--border);
    font-weight: 600;
}

/* Mail with local delivery off: the blocks managed elsewhere, greyed out. */
.locked-fieldset {
    min-width: 0;
    margin: 0;
    padding: 0;
    border: 0;
    opacity: .5;
}

.locked-fieldset a {
    pointer-events: none;
}

.locked-note {
    margin: 12px 16px 0;
}

/* Radio buttons under a heading, without a line (Mailprovider). */
.radio-group {
    display: grid;
    gap: 6px;
    min-width: 0;
    margin: 16px 0 0;
    padding: 0;
    border: 0;
}

.radio-group > legend {
    padding: 0;
    margin-bottom: 4px;
    font-weight: 600;
}

/* HTTPS on the account page: the end date, green while valid, red near its end. */
.cert-date {
    font-weight: 600;
    white-space: nowrap;
}

.cert-valid {
    color: var(--ok);
}

.cert-ending {
    color: var(--error);
}

/* A part of a section folded away under its summary, such as the
   monitoring settings on Instellingen. */
.section-fold {
    border-top: 1px solid var(--line);
}

.section-fold > summary {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 10px 16px;
    font-weight: 600;
    cursor: pointer;
}

.section-fold > summary:hover {
    background: var(--surface);
}

/* A chevron that turns when the fold opens; display: flex/grid on a
   summary drops the browser's own marker. */
.section-fold > summary::-webkit-details-marker,
summary.jail-row::-webkit-details-marker {
    display: none;
}

.section-fold > summary::before,
summary.jail-row > span:first-child::before {
    content: "";
    display: inline-block;
    width: 6px;
    height: 6px;
    margin-right: 8px;
    border-right: 2px solid var(--muted);
    border-bottom: 2px solid var(--muted);
    transform: rotate(-45deg);
    transition: transform 0.15s;
}

.section-fold[open] > summary::before,
.jail[open] > summary.jail-row > span:first-child::before {
    transform: rotate(45deg);
}

/* Firewall: fail2ban's jails, one line each, that fold open to the
   banned addresses. */
.jail-row {
    display: grid;
    /* --grid-cols: widths set by hand (table-resize.js). */
    grid-template-columns: var(--grid-cols, minmax(0, 1fr) repeat(4, 110px));
    gap: 12px;
    align-items: center;
    padding: 6px 16px;
    border-bottom: 1px solid var(--line);
    min-height: calc(var(--control-height) + 13px);
}

.jail-row .num {
    text-align: right;
}

.jail-head {
    background: var(--surface-alt);
    color: var(--muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    min-height: 0;
}

summary.jail-row {
    cursor: pointer;
}

summary.jail-row:hover,
.jail[open] > summary.jail-row {
    background: var(--surface);
}

.jail-body {
    border-bottom: 1px solid var(--line);
}

.jail-body > .hint,
.jail-body > .muted {
    margin: 0;
    padding: 8px 16px;
}

@media (max-width: 640px) {
    .jail-row {
        grid-template-columns: minmax(0, 1fr) repeat(4, 56px);
        gap: 6px;
    }
}

/* Column widths you set yourself (table-resize.js): a grip on the right
   edge of each header, only where the rows are a table. */
.col-grip {
    display: none;
}

@media (min-width: 721px) {
    .table thead th,
    [data-resize-head] > * {
        position: relative;
    }

    /* In a grid of rows the grip sits in the middle of the gap. */
    [data-resize-head] .col-grip {
        right: -10px;
    }

    .col-grip {
        display: block;
        position: absolute;
        top: 0;
        right: -4px;
        bottom: 0;
        z-index: 1;
        width: 8px;
        cursor: col-resize;
        touch-action: none;
    }

    .col-grip::after {
        content: "";
        position: absolute;
        top: 25%;
        bottom: 25%;
        left: 3px;
        width: 2px;
        border-radius: 1px;
        background: var(--line);
        opacity: 0;
        transition: opacity 0.15s;
    }

    .table thead:hover .col-grip::after,
    [data-resize-head]:hover .col-grip::after,
    .is-resizing .col-grip::after {
        opacity: 1;
    }

    .col-grip:hover::after,
    .is-resizing .col-grip:active::after {
        background: var(--accent);
    }

    .table.is-resized td {
        overflow-wrap: anywhere;
    }

    .table.is-resized td.actions-cell {
        overflow-wrap: normal;
    }

    .is-resizing {
        cursor: col-resize;
        user-select: none;
    }
}

/* Facturatie > Sjablonen (ADR 0034): every editor the same, the fields
   beside a preview with example values. */
.template-editor-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 24px;
    align-items: start;
}

.template-editor-fields textarea {
    font-family: inherit;
}

.template-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 12px 0 4px;
}

.chip {
    padding: 2px 8px;
    border: 1px solid var(--accent-line);
    background: var(--accent-soft);
    color: var(--accent);
    font: 12px/18px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    cursor: pointer;
}

.chip:hover,
.chip:focus-visible {
    border-color: var(--accent);
}

.template-preview {
    padding: 12px 16px;
    border: 1px solid var(--line);
    background: var(--surface-alt);
}

.template-preview .subsection-title {
    margin-top: 0;
}

.template-preview-field + .template-preview-field {
    margin-top: 12px;
}

.template-preview-label {
    display: block;
    color: var(--muted);
    font-size: 12px;
}

.template-preview-text {
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.template-preview-type-line .template-preview-text {
    font-weight: 600;
}

.template-preview-text.is-empty::before {
    content: "-";
    color: var(--faint);
}

.company-logo {
    max-width: 240px;
    max-height: 96px;
}

@media (max-width: 900px) {
    .template-editor-grid {
        grid-template-columns: 1fr;
    }
}

/* The payment page of an invoice (ADR 0035). */
.pay-text {
    white-space: pre-line;
}

.pay-box .details {
    margin: 16px 0;
}

.form-row-three {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr);
}

.invoice-mails {
    margin-top: 12px;
}

.invoice-mails li + li {
    margin-top: 4px;
}

@media (max-width: 520px) {
    .form-row-three {
        grid-template-columns: 1fr;
    }
}

/* Inkoop (phase 6). */
.plain-fieldset {
    margin: 0;
    padding: 0;
    border: 0;
    min-width: 0;
}

.purchase-amounts input {
    max-width: 160px;
}

.vat-return td .muted {
    font-size: 12px;
}

.vat-return tbody th {
    text-transform: none;
    letter-spacing: 0;
}

/* Inkoop, PDF uitlezen: what was read, under the upload, and the row of
   PDFs still to do. Plain lines with a small icon, no coloured box. */
.read-result {
    display: grid;
    gap: 14px;
    margin-top: 20px;
    padding-top: 16px;
    border-top: 1px solid var(--line);
}

.read-queue {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 8px 16px;
    font-weight: 600;
}

.read-lines {
    display: grid;
    gap: 8px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.read-lines li {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    line-height: 1.45;
}

.read-lines .icon {
    flex: none;
    width: 18px;
    height: 18px;
    margin-top: 1px;
}

.read-lines .is-found .icon {
    color: var(--accent);
}

.read-lines .is-missing {
    color: var(--muted);
}

.read-lines .is-missing .icon {
    color: var(--faint);
}

.read-lines .is-check {
    color: var(--error);
}

/* A phone (also one that reports up to 960px, like the top bar's medium
   width): blocks always under each other, never two side by side. Last in
   the file, so it wins over every grid above. */
@media (max-width: 960px) {
    .section-grid,
    .section-grid.section-halves,
    .section-grid.section-halves.wp-pair,
    .section-grid.block-columns,
    .section-grid.wp-top,
    .node-grid,
    .node-panels,
    .stats-charts,
    .stats-lists,
    .template-editor-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    .section-grid.wp-top > :first-child {
        grid-column: auto;
    }
}
