/* The one stylesheet every Acie page draws from, loaded after brand.css by
   www/page.html. Tokens live in brand.css; nothing here types a color that
   brand.css already names. The plan behind it: /acie/docs/ui.md. */

:root {
    color-scheme: dark;
    --content-width: 52rem;
    --gutter: 1.5rem;
}

/* Keyboard focus scrolled into view lands under the sticky top bar, and
   under the selection bar when a page has one. */
html {
    scroll-padding-top: 4.5rem;
}

html:has(.bar) {
    scroll-padding-top: 8.5rem;
}

body {
    margin: 0;
    min-height: 100vh;
    font-family: var(--font);
    font-size: 0.9375rem;
    line-height: 1.55;
    color: var(--text);
    background: var(--page-background) fixed;
    background-color: var(--ground);
    -webkit-font-smoothing: antialiased;
    /* Inherited, so every var(--mono) element gets it. The sans face has no
       stylistic sets, so it ignores them. */
    font-feature-settings: var(--mono-features);
}

/* The circuit picture over the gradient on every page: sharp enough to read
   as traces, faint enough that text on the panels above it stays easy to read. */
body::before {
    content: "";
    position: fixed;
    inset: -8px;
    background: url("brand/bg-pattern.1411f6644954.webp") center / cover;
    filter: blur(var(--circuit-blur));
    opacity: var(--circuit-opacity);
    pointer-events: none;
    z-index: -1;
}

/* A light type scale. Hierarchy comes from size and space; nothing on a
   page is bolder than 600, and headings are lighter than that. */
h1, h2, h3 {
    margin: 0;
    color: var(--text);
    text-wrap: balance;
}

h1 {
    font-size: 1.75rem;
    font-weight: 300;
    line-height: 1.2;
    letter-spacing: 0.005em;
}

h2 {
    font-size: 1.0625rem;
    font-weight: 500;
    line-height: 1.3;
}

h3 {
    font-size: 0.9375rem;
    font-weight: 500;
}

p {
    margin: 0 0 0.75rem;
}

a {
    color: var(--link);
    text-decoration-color: rgb(var(--magenta-rgb) / 0.45);
    text-underline-offset: 0.2em;
}

a:hover {
    color: var(--text);
    text-decoration-color: var(--magenta);
}

code,
pre,
.mono {
    font-family: var(--mono);
}

code {
    font-size: 0.85em;
}

pre {
    margin: 0 0 0.75rem;
    padding: 0.7rem 0.85rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: rgb(10 8 30 / 0.45);
    font-size: 0.8rem;
    color: var(--text-soft);
    overflow-x: auto;
}

/* ---- What every control shares ---- */

/* Cyan, the circuit's signal color: focus never looks like selection
   (violet) or the primary action (magenta). */
:focus-visible {
    outline: 2px solid var(--cyan);
    outline-offset: 2px;
}

:disabled {
    cursor: not-allowed;
}

/* A hidden element stays hidden whatever display a class gives it: a
   tr[hidden] otherwise keeps display: table-row and a row filter does
   nothing. */
[hidden] {
    display: none !important;
}

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.skip {
    position: absolute;
    top: 0.5rem;
    left: 0.5rem;
    z-index: 100;
    padding: 0.5rem 0.9rem;
    border-radius: var(--radius-sm);
    background: var(--accent-fill);
    color: var(--accent-ink);
    transform: translateY(-200%);
}

.skip:focus-visible {
    transform: none;
}

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        transition-duration: 0s !important;
        animation-duration: 0s !important;
        animation-iteration-count: 1 !important;
        scroll-behavior: auto !important;
    }
}

/* ---- The shell ---- */

/* The frame groups the top bar and main. It has no box of its own except on
   a narrow page, where it is the card. */
.frame {
    display: contents;
}

/* The bar's contents line up with the column under it, so the logo and the
   heading share a left edge at every width. */
.topbar {
    position: sticky;
    top: 0;
    z-index: 10;
    display: flex;
    align-items: center;
    gap: 1.25rem;
    min-height: 3.5rem;
    padding-inline: max(var(--gutter), calc((100% - var(--content-width)) / 2));
    background: rgb(20 18 50 / 0.55);
    backdrop-filter: var(--panel-blur);
    -webkit-backdrop-filter: var(--panel-blur);
}

/* The bar's bottom edge is the mark's trace, not a grey rule, as wide as
   the column so its ends fade out at the brand and the account button. */
.topbar::after {
    content: "";
    position: absolute;
    inset: auto max(var(--gutter), calc((100% - var(--content-width)) / 2)) -1px;
    height: 1px;
    background: var(--wire);
    pointer-events: none;
}

/* The wordmark is the one place the sans gives way to Monaspace at a light
   weight, set a little wide. */
.brand {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    min-width: 0;
    font-family: var(--mono);
    font-size: 0.9375rem;
    font-weight: 300;
    font-stretch: 112%;
    letter-spacing: 0.04em;
    color: var(--text);
    text-decoration: none;
}

/* The mark's outline is a thin magenta line that vanishes on a dark phone
   without a little light of its own. */
.brand img {
    flex-shrink: 0;
    width: 1.5rem;
    height: 1.5rem;
    filter: drop-shadow(0 0 3px rgb(var(--magenta-rgb) / 0.7));
}

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

/* The strip wraps onto as many rows as the links need, at every width, so
   no link is ever out of sight past the column's edge. A wrapping strip
   cannot shrink below one link, so the brand and the account button keep
   their room. */
.sections {
    display: flex;
    flex-wrap: wrap;
    align-self: stretch;
    gap: 0 1.25rem;
}

/* A page with no section links has no navigation landmark either. */
.sections:not(:has(a)) {
    display: none;
}

.sections a {
    display: inline-flex;
    align-items: center;
    font-size: 0.875rem;
    color: var(--text-muted);
    text-decoration: none;
    white-space: nowrap;
    box-shadow: inset 0 -2px 0 transparent;
}

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

.sections a[aria-current="page"] {
    color: var(--text);
    box-shadow: inset 0 -2px 0 var(--magenta);
}

.account {
    margin-left: auto;
    min-width: 0;
}

.account:empty {
    display: none;
}

main {
    display: block;
    position: relative;
    max-width: var(--content-width);
    margin: 0 auto;
    padding-block: 2.5rem 5rem;
    padding-inline: var(--gutter);
    box-sizing: content-box;
}

/* A ledger or any table of many columns: opted into per page with
   body.wide, and taken without asking by a page whose list has five
   columns or more, so no data-heavy page is squeezed into 52rem. */
body.wide,
body:not(.narrow, .doc):has(.list > thead th:nth-child(5)) {
    --content-width: 72rem;
}

.page-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1rem 1.5rem;
    margin-bottom: 1.75rem;
}

/* Nothing in it: a page whose heading lives in its content. */
.page-head:not(:has(> :not(:empty))),
.page-head > :empty {
    display: none;
}

.page-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

/* After the rule it undoes: the two are equally specific. */
.page-actions:not(:has(*)) {
    display: none;
}

/* A fact the heading does not carry: the account and closing balance under
   a statement. Never a sentence restating the heading. */
.lede {
    flex-basis: 100%;
    margin: -0.5rem 0 0;
    font-size: 0.875rem;
    color: var(--text-muted);
}

.section {
    margin-top: 3rem;
}

.section > h2 {
    margin-bottom: 0.75rem;
}

.section > .lede {
    margin: -0.4rem 0 0.9rem;
}

/* ---- The account menu ---- */

.menu-button {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    max-width: 18rem;
    min-height: 2.25rem;
    padding: 0.35rem 0.75rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: rgb(255 255 255 / 0.04);
    color: var(--text);
    font: inherit;
    font-size: 0.875rem;
    cursor: pointer;
}

.menu-button::after {
    content: "";
    flex-shrink: 0;
    width: 0.38rem;
    height: 0.38rem;
    border-right: 1.5px solid var(--text-muted);
    border-bottom: 1.5px solid var(--text-muted);
    transform: translateY(-0.1rem) rotate(45deg);
}

.menu-button:hover,
.menu-button:has(+ .menu-list:popover-open) {
    border-color: rgb(255 255 255 / 0.18);
    background: rgb(255 255 255 / 0.08);
}

.menu-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* A popover sits in the top layer, so it is placed against the viewport:
   under the top bar, at the right edge of the column. 100%, not 100vw,
   which counts the scrollbar the top bar's padding does not. */
.menu-list {
    position: fixed;
    inset: 3.75rem max(var(--gutter), calc((100% - var(--content-width)) / 2)) auto auto;
    margin: 0;
    min-width: 15rem;
    max-width: calc(100vw - 2rem);
    padding: 0.35rem;
    border: 0;
    border-radius: var(--float-radius);
    background: var(--panel-solid);
    backdrop-filter: var(--panel-blur);
    -webkit-backdrop-filter: var(--panel-blur);
    color: var(--text);
    box-shadow: var(--float-shadow);
}

.menu-list:popover-open {
    display: grid;
    gap: 1px;
}

.menu-list form {
    margin: 0;
}

/* A menu entry is a row of text with a hover, not a boxed button. */
.menu-list > .btn,
.menu-list > form > .btn,
.menu-list > a {
    display: flex;
    width: 100%;
    min-height: 2.25rem;
    justify-content: flex-start;
    padding: 0.45rem 0.7rem;
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    box-shadow: none;
    color: var(--text-soft);
    font-size: 0.875rem;
    font-weight: 400;
    text-decoration: none;
}

.menu-list > .btn:hover,
.menu-list > form > .btn:hover,
.menu-list > a:hover {
    background: var(--wash-hover);
    box-shadow: none;
    color: var(--text);
}

/* The links, then a rule, then Switch account and Sign out. */
.menu-list > form:first-of-type {
    margin-top: 0.3rem;
    padding-top: 0.3rem;
    border-top: 1px solid var(--line-soft);
}

.menu-list > .menu-fact + * {
    margin-top: 0.25rem;
}

.menu-fact {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin: 0;
    padding: 0.35rem 0.35rem 0.5rem 0.7rem;
    border-bottom: 1px solid var(--line-soft);
    font-size: 0.75rem;
    color: var(--text-faint);
}

/* ---- Messages ---- */

#messages {
    display: grid;
    gap: 0.5rem;
    margin-bottom: 1.5rem;
}

#messages:not(:has(*)) {
    display: none;
}

/* A panel strip with a leading mark in the message's color. */
.alert {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.75rem;
    padding: 0.65rem 0.9rem 0.65rem 2.1rem;
    position: relative;
    border-radius: var(--radius);
    background: var(--panel-strong);
    box-shadow: var(--panel-edge), 0 0 0 1px var(--panel-line);
    font-size: 0.9rem;
}

.alert::before {
    content: "";
    position: absolute;
    left: 0.9rem;
    top: 1.05rem;
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 1px;
    background: var(--text-muted);
    transform: rotate(45deg);
}

.alert.success::before {
    background: var(--ok);
}

.alert.info::before {
    background: var(--cyan);
}

.alert.warning::before {
    background: var(--warn);
}

.alert.error {
    background: rgb(var(--danger-rgb) / 0.1);
    box-shadow: var(--panel-edge), 0 0 0 1px rgb(var(--danger-rgb) / 0.35);
}

.alert.error::before {
    background: var(--danger);
}

/* Undo belongs inside the message about what it undoes. */
.alert form,
.alert .btn {
    margin: 0 0 0 auto;
}

/* ---- Buttons ---- */

/* A quiet button is a lit edge on a faint fill. No colored outline, no
   glow: color is kept for the one primary action. */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    min-height: 2.25rem;
    padding: 0.4rem 0.85rem;
    border: 1px solid rgb(255 255 255 / 0.13);
    border-radius: var(--radius-sm);
    background: rgb(255 255 255 / 0.05);
    box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.05);
    color: var(--text);
    font: inherit;
    font-size: 0.875rem;
    font-weight: 450;
    line-height: 1.2;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease;
}

.btn:hover {
    border-color: rgb(255 255 255 / 0.22);
    background: rgb(255 255 255 / 0.1);
    color: var(--text);
}

/* The logo's magenta, deepened until white on it is 5.52:1. */
.btn-primary {
    border-color: rgb(255 255 255 / 0.12);
    background: var(--accent-fill);
    box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.22), 0 2px 6px -2px rgb(4 2 16 / 0.6);
    color: var(--accent-ink);
    font-weight: 500;
}

.btn-primary:hover {
    border-color: rgb(255 255 255 / 0.2);
    background: var(--accent-hover);
    box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.28), 0 3px 8px -2px rgb(4 2 16 / 0.7);
    color: var(--accent-ink);
}

/* Red only inside a confirm dialog. In a bar the destructive action is a
   quiet .btn, so it is never the loudest control on the page. */
.btn-danger {
    border-color: transparent;
    background: var(--danger-fill);
    box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.18);
    color: #fff;
    font-weight: 500;
}

.btn-danger:hover {
    border-color: transparent;
    background: var(--danger-fill-hover);
    color: #fff;
}

.btn:disabled,
.btn:disabled:hover {
    border-color: var(--line-soft);
    background: transparent;
    box-shadow: none;
    color: var(--text-faint);
}

.btn-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    min-width: 2.25rem;
    min-height: 2.25rem;
    padding: 0.4rem;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    font: inherit;
    font-size: 0.875rem;
    cursor: pointer;
    background: transparent;
    box-shadow: none;
    color: var(--text-muted);
}

.btn-icon:hover {
    border-color: transparent;
    background: var(--wash-hover);
    box-shadow: none;
    color: var(--text);
}

.btn-icon svg {
    flex-shrink: 0;
}

.btn [data-count] {
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
}

/* A pressed button that is still working, the Pay button's shape. */
.btn[aria-busy="true"] {
    position: relative;
    color: transparent;
    pointer-events: none;
}

.btn[aria-busy="true"]::after {
    content: "";
    position: absolute;
    inset: 0;
    width: 1rem;
    height: 1rem;
    margin: auto;
    border: 2px solid var(--text);
    border-right-color: transparent;
    border-radius: 50%;
    animation: www-spin 0.7s linear infinite;
}

.btn-primary[aria-busy="true"]::after,
.btn-danger[aria-busy="true"]::after {
    border-color: #fff;
    border-right-color: transparent;
}

@keyframes www-spin {
    to {
        transform: rotate(360deg);
    }
}

.htmx-indicator {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    font-size: 0.85rem;
    color: var(--text-muted);
    opacity: 0;
    transition: opacity 150ms ease-in 150ms;
}

.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator {
    opacity: 1;
}

.copy .copied {
    display: none;
    color: var(--ok);
}

.copy.is-copied .copied {
    display: inline;
}

.copy.is-copied .to-copy {
    display: none;
}

/* ---- Forms ---- */

.form {
    display: grid;
    gap: 1.1rem;
    max-width: 32rem;
    margin: 0;
}

/* Space before the next form, so no page adds an <hr>. */
.form + .form,
.bar + .form,
.form + .panel {
    margin-top: 2rem;
}

/* A form of one field is one line: the box and its button side by side,
   one height, the button as wide as its words. The button drops to its
   own line only when the box would be under 10rem, so enlarged text
   spacing never cuts off the placeholder. A form holding anything else
   beside its field and buttons (a switch, a paragraph) is not one of
   these, whether or not that thing is wrapped in a .field. */
.form:has(> .field):not(:has(> .field ~ .field, > :not(.field, .actions, input[type="hidden"], [hidden]))) {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 0.5rem;
}

.form:has(> .field):not(:has(> .field ~ .field, > :not(.field, .actions, input[type="hidden"], [hidden]))) > .field {
    flex: 1 1 10rem;
}

.form:has(> .field):not(:has(> .field ~ .field, > :not(.field, .actions, input[type="hidden"], [hidden]))) > .actions {
    flex: 0 0 auto;
    padding-top: 0;
}

.form:has(> .field):not(:has(> .field ~ .field, > :not(.field, .actions, input[type="hidden"], [hidden]))) > .actions .btn,
.form:has(> .field):not(:has(> .field ~ .field, > :not(.field, .actions, input[type="hidden"], [hidden]))) input {
    height: var(--control-height);
    min-height: var(--control-height);
}

/* Under the list it adds to, it belongs to that list: closer to it than
   the heading is, with no rule between. */
.panel + .form,
.panel + .divider + .form {
    margin-top: 1rem;
}

.panel + .divider:has(+ .form) {
    display: none;
}

.field {
    display: grid;
    gap: 0.4rem;
    min-width: 0;
}

.field > label,
.field-label {
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--text-soft);
}

input:where([type="text"], [type="email"], [type="password"], [type="search"], [type="number"], [type="tel"], [type="url"], [type="date"], [type="file"], :not([type])),
select,
textarea {
    box-sizing: border-box;
    width: 100%;
    min-height: var(--control-height);
    padding: 0.45rem 0.75rem;
    border: 1px solid var(--input-border);
    border-radius: var(--input-radius);
    background: rgb(12 10 34 / 0.5);
    box-shadow: inset 0 1px 2px rgb(0 0 0 / 0.25);
    color: var(--text);
    font: inherit;
    font-size: 1rem;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

input:where([type="text"], [type="email"], [type="password"], [type="search"], [type="number"], [type="tel"], [type="url"], [type="date"], :not([type])):hover,
select:hover,
textarea:hover {
    border-color: var(--input-border-hover);
}

select option {
    background: var(--surface);
}

textarea {
    min-height: 5rem;
    resize: vertical;
}

::placeholder {
    color: var(--text-faint);
    opacity: 1;
}

/* Chromium puts focus inside a date input's own fields, where the input
   itself never matches :focus-visible. The outline is transparent, not
   none: forced colors drops the shadow and paints the outline. */
input:focus-visible,
input[type="date"]:focus-within,
select:focus-visible,
textarea:focus-visible {
    outline: 2px solid transparent;
    outline-offset: 0;
    border-color: var(--cyan);
    box-shadow: inset 0 1px 2px rgb(0 0 0 / 0.25), 0 0 0 3px rgb(var(--cyan-rgb) / 0.22);
}

[aria-invalid="true"] {
    border-color: var(--danger);
}

[aria-invalid="true"]:focus-visible {
    border-color: var(--danger);
    box-shadow: 0 0 0 3px rgb(var(--danger-rgb) / 0.25);
}

.hint {
    margin: 0;
    font-size: 0.8125rem;
    color: var(--text-faint);
}

/* A link in a hint is still a target a thumb has to hit. */
.hint a {
    display: inline-block;
    padding: 0.25rem 0;
}

/* Not .alert.error, a message, which keeps the message's own text. */
.error:not(.alert) {
    margin: 0;
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--danger);
}

.form-errors {
    display: grid;
    gap: 0.25rem;
}

.actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.form > .actions {
    padding-top: 0.25rem;
}

/* An input with its unit beside it: an amount with USD. */
.with-suffix {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.with-suffix input {
    max-width: 10rem;
}

.suffix {
    font-size: 0.875rem;
    color: var(--text-muted);
}

/* A checkbox or radio with its label, the whole row the target. */
.check {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    cursor: pointer;
}

.check input {
    flex-shrink: 0;
    width: 1.05rem;
    height: 1.05rem;
    margin: 0.2rem 0 0;
    accent-color: var(--violet);
    cursor: pointer;
}

fieldset {
    display: grid;
    gap: 0.5rem;
    min-width: 0;
    margin: 0;
    padding: 0;
    border: 0;
}

legend {
    margin-bottom: 0.35rem;
    padding: 0;
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--text-soft);
}

/* An on and off setting: a checkbox drawn as a track, the label wrapping it. */
.switch {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    min-height: 2.25rem;
    cursor: pointer;
}

.switch input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
}

.switch-track {
    position: relative;
    flex-shrink: 0;
    width: 2.2rem;
    height: 1.25rem;
    border: 1px solid var(--input-border);
    border-radius: 999px;
    background: rgb(12 10 34 / 0.5);
    transition: background 0.15s ease;
}

.switch-track::after {
    content: "";
    position: absolute;
    top: 2px;
    left: 2px;
    width: calc(1.25rem - 6px);
    height: calc(1.25rem - 6px);
    border-radius: 50%;
    background: var(--text-muted);
    transition: transform 0.15s ease;
}

.switch input:checked + .switch-track {
    border-color: transparent;
    background: var(--accent-fill);
}

.switch input:checked + .switch-track::after {
    transform: translateX(0.95rem);
    background: #fff;
}

.switch input:focus-visible + .switch-track {
    outline: 2px solid var(--cyan);
    outline-offset: 2px;
}

/* A creation form that opens on demand, above the list it adds to. Closed,
   its opener is the page's primary action; open, the form's own submit is,
   and the opener steps back to a quiet button. */
.create {
    margin-bottom: 1.25rem;
}

.create > summary {
    display: inline-flex;
    list-style: none;
}

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

.create[open] > summary {
    margin-bottom: 0.75rem;
}

.create[open] > summary.btn-primary {
    border-color: rgb(255 255 255 / 0.13);
    background: rgb(255 255 255 / 0.05);
    box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.05);
    font-weight: 450;
}

.create > .form,
.panel {
    border-radius: var(--panel-radius);
    background: var(--panel);
    backdrop-filter: var(--panel-blur);
    -webkit-backdrop-filter: var(--panel-blur);
    box-shadow: var(--panel-shadow-soft), 0 0 0 1px var(--panel-line);
}

.create > .form {
    padding: 1.25rem;
}

/* ---- Panels, the bar and lists ---- */

/* A panel over the page: a lavender tint lighter than the page, an edge lit
   from above, a ring of light for its border. One layer only: nothing
   inside a panel gets the panel background again. */
.panel {
    position: relative;
}

.panel + .panel {
    margin-top: 1.25rem;
}

.panel-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem 1rem;
    padding: 0.75rem 1.1rem;
    border-bottom: 1px solid var(--line-soft);
}

.panel-body {
    padding: 1.1rem;
}

/* An empty list is not a box holding one grey sentence: the sentence sits
   in the page, and the action beside or above it is the content. */
.panel:has(> .empty:only-child) {
    background: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    box-shadow: none;
}

.empty {
    padding: 1.1rem;
    color: var(--text-muted);
}

.panel > .empty:only-child {
    padding: 0.25rem 0;
}

.empty p {
    margin: 0;
}

/* One set of actions for the selected rows: the count, one picker, the
   buttons, sticky under the top bar while the list scrolls. */
.bar {
    position: sticky;
    top: 4rem;
    z-index: 5;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.6rem;
    margin-bottom: 0.75rem;
    padding: 0.55rem 0.7rem;
    border-radius: var(--panel-radius);
    background: var(--panel-strong);
    box-shadow: var(--panel-shadow-soft), 0 0 0 1px var(--panel-line);
}

.bar select {
    width: auto;
    max-width: 18rem;
    min-height: 2.25rem;
    font-size: 0.875rem;
}

.bar .grow {
    flex: 1;
}

.select-all {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin-right: 0.25rem;
    font-size: 0.875rem;
    color: var(--text-muted);
    white-space: nowrap;
    cursor: pointer;
}

.select-all input,
.list input[type="checkbox"],
.list input[type="radio"] {
    width: 1.05rem;
    height: 1.05rem;
    margin: 0;
    accent-color: var(--violet);
    cursor: pointer;
}

/* Rows split by hairlines inside the panel. The header is a quiet line of
   small mono labels, not a filled band. */
.list {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
}

.list th {
    padding: 0.7rem 1.1rem 0.55rem;
    border-bottom: 1px solid var(--line-soft);
    font-family: var(--mono);
    font-size: 0.6875rem;
    font-weight: 500;
    font-stretch: 112%;
    letter-spacing: 0.04em;
    color: var(--text-faint);
    text-align: left;
    white-space: nowrap;
}

/* A row with a menu button and a row without are the same height. */
.list td {
    height: 3.5rem;
    padding: 0.6rem 1.1rem;
    border-bottom: 1px solid var(--line-soft);
    vertical-align: middle;
}

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

.list tbody tr:last-child td:first-child {
    border-bottom-left-radius: var(--panel-radius);
}

.list tbody tr:last-child td:last-child {
    border-bottom-right-radius: var(--panel-radius);
}

.list tbody tr:hover > td {
    background: var(--wash);
}

.list tbody tr:has(> td > input:checked) > td {
    background: rgb(var(--violet-rgb) / 0.14);
}

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

/* Row spacing goes on the buttons, never display: flex on the cell: that
   drops the td out of the table layout and the column rules break. The
   actions column is as narrow as its buttons. */
.list .cell-actions {
    width: 1%;
    text-align: right;
    white-space: nowrap;
}

.list .cell-actions > * + * {
    margin-left: 0.5rem;
}

/* A column holding only a state is as wide as its word, so the state sits
   by the row's actions instead of halfway across the panel. */
.list td:has(> .badge:only-child) {
    width: 1%;
    white-space: nowrap;
}

/* Every state's word lines up with the column name: a marker, or a tag's
   box, hangs into the cell's padding. */
.list td > .badge:only-child {
    margin-left: -0.95rem;
}

.list td > .badge[data-state="warn"]:only-child {
    margin-left: -0.45rem;
}

/* A row menu left open closes to the eye once keyboard focus moves on,
   so it never covers the control focus went to. */
body:has(main :focus-visible) .menu-list:popover-open {
    visibility: hidden;
}

main:has(:focus-visible) .list .cell-actions details[open]:not(:focus-within) > :not(summary) {
    display: none;
}

/* A row's own menu opens over the rows below it, never pushing them. */
.list .cell-actions details {
    position: relative;
    display: inline-block;
}

.list .cell-actions details > summary {
    color: var(--text-muted);
}

.list .cell-actions details > summary:focus-visible {
    outline: 2px solid var(--cyan);
    outline-offset: 2px;
}

.list .cell-actions details > :not(summary) {
    position: absolute;
    top: calc(100% + 0.3rem);
    right: 0;
    z-index: 20;
    min-width: 11rem;
    margin: 0;
    padding: 0.3rem;
    border: 0;
    border-radius: var(--float-radius);
    background: var(--panel-solid);
    backdrop-filter: var(--panel-blur);
    -webkit-backdrop-filter: var(--panel-blur);
    box-shadow: var(--float-shadow);
    text-align: left;
}

.list .cell-actions details > :not(summary) .btn {
    width: 100%;
    justify-content: flex-start;
    border: 0;
    background: transparent;
    box-shadow: none;
    color: var(--text-soft);
    font-weight: 400;
}

.list .cell-actions details > :not(summary) .btn:hover {
    background: var(--wash-hover);
    color: var(--text);
}

.col-select {
    width: 2.5rem;
    padding-right: 0;
}

/* An amount or a count: right aligned, tabular, never wrapped. */
.num {
    text-align: right;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.list th.num {
    text-align: right;
}

.mono {
    font-size: 0.8125rem;
    font-variant-numeric: tabular-nums;
    color: var(--text-soft);
}

time.mono,
.list td.date {
    white-space: nowrap;
}

/* An identifier, an address or a subject id: its own line when it must
   break, and it breaks at a <wbr> the breakable_email filter placed. */
.id {
    overflow-wrap: break-word;
    word-break: normal;
}

code.id {
    font-size: 0.8125rem;
    color: var(--text-soft);
    overflow-wrap: anywhere;
}

.sub {
    display: block;
    font-size: 0.8125rem;
    color: var(--text-faint);
}

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

/* Label and value, one per row: a detail page's facts. Labels are the
   quiet column, values carry the weight. */
.facts {
    display: grid;
    grid-template-columns: minmax(8rem, 30%) 1fr;
    gap: 0;
    margin: 0;
}

.facts dt,
.facts dd {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    min-width: 0;
    min-height: 3rem;
    margin: 0;
    padding: 0.55rem 1.1rem;
    border-top: 1px solid var(--line-soft);
}

.facts dt {
    font-size: 0.8125rem;
    color: var(--text-muted);
}

.facts dd > .id {
    min-width: 0;
}

/* A value and its copy button share a line; a form's parts in a value
   (a field, a hint, its buttons) each take their own. */
.facts dd {
    flex-wrap: wrap;
}

.facts dd > :is(.actions, .field, .hint, .error, .stored, form, p) {
    flex-basis: 100%;
}

.facts dt:first-of-type,
.facts dt:first-of-type + dd {
    border-top: 0;
}

/* ---- State ---- */

/* Five meanings, and each service names its own words for them:
   todo, a thing not started (Draft, Unsorted); warn, a thing wanting
   attention (Overdue, To sort); active, a thing in motion (Sent,
   Suggested); done (Paid, Recorded); off, a thing that is over (Void,
   Skipped).
   A state is a mono word led by a node from the circuit, with no box: a
   filled magenta node for done, a hollow cyan ring for active, a hollow
   grey ring for todo, a dash for off. Only warn is a filled tag, so the
   one state that needs attention is the one that shows. */
.badge {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    font-family: var(--mono);
    font-size: 0.75rem;
    font-weight: 400;
    line-height: 1.5;
    letter-spacing: 0.01em;
    color: var(--text-soft);
    white-space: nowrap;
    vertical-align: middle;
}

.badge::before {
    content: "";
    flex-shrink: 0;
    box-sizing: border-box;
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background: var(--text-muted);
}

.badge[data-state="todo"] {
    color: var(--text-muted);
}

.badge[data-state="todo"]::before {
    background: transparent;
    border: 1.5px solid var(--text-muted);
}

.badge[data-state="warn"] {
    padding: 0 0.45rem;
    border-radius: var(--radius-xs);
    background: rgb(var(--warn-rgb) / 0.14);
    box-shadow: inset 0 0 0 1px rgb(var(--warn-rgb) / 0.35);
    color: var(--warn);
}

.badge[data-state="warn"]::before {
    content: none;
}

.badge[data-state="active"] {
    color: var(--text-muted);
}

.badge[data-state="active"]::before {
    background: transparent;
    border: 1.5px solid var(--cyan);
}

.badge[data-state="done"] {
    color: var(--text);
}

.badge[data-state="done"]::before {
    background: var(--magenta);
}

.badge[data-state="off"] {
    color: var(--text-faint);
}

.badge[data-state="off"]::before {
    height: 1.5px;
    border-radius: 0;
    background: var(--text-faint);
}

/* Alive or not: a mark and a word. The words wrap, since a status can be a
   sentence; the mark stays level with the first line. */
.status {
    display: inline-flex;
    align-items: baseline;
    gap: 0.45rem;
    font-size: 0.875rem;
    color: var(--text-muted);
}

.status .dot {
    align-self: flex-start;
    margin-top: 0.5em;
}

.dot {
    flex-shrink: 0;
    width: 0.4rem;
    height: 0.4rem;
    border-radius: 1px;
    background: var(--text-faint);
}

.dot-live {
    background: var(--cyan);
    box-shadow: 0 0 6px rgb(var(--cyan-rgb) / 0.7);
}

/* ---- Tabs: a list filtered by state, with counts ---- */

/* Words on a hairline with the current one underlined in magenta, the way
   the section links are. A tab is never a filled button, even when a page
   marks it up as one. */
.tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 0 1.5rem;
    padding: 0;
    border: 0;
    box-shadow: inset 0 -1px 0 var(--line);
}

.tabs a,
.tabs a.btn,
.tabs a.btn-primary {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    min-height: 2.25rem;
    padding: 0.35rem 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: inset 0 -2px 0 transparent;
    font-size: 0.875rem;
    font-weight: 400;
    color: var(--text-muted);
    text-decoration: none;
}

.tabs a:hover,
.tabs a.btn:hover {
    border: 0;
    color: var(--text);
    background: transparent;
    box-shadow: inset 0 -2px 0 var(--line);
}

.tabs a[aria-current],
.tabs a[aria-current]:hover {
    color: var(--text);
    background: transparent;
    box-shadow: inset 0 -2px 0 var(--magenta);
}

.tabs .count {
    font-family: var(--mono);
    font-size: 0.75rem;
    font-variant-numeric: tabular-nums;
    color: var(--text-faint);
}

/* ---- A stored thing: a fact with Replace and Remove ---- */

.stored {
    display: grid;
    gap: 0.6rem;
}

.stored-fact {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem 0.75rem;
    margin: 0;
}

.stored .actions {
    align-items: flex-start;
}

.stored details > summary {
    list-style: none;
}

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

.stored details[open] {
    flex-basis: 100%;
}

.stored details[open] > summary {
    margin-bottom: 0.75rem;
}

/* ---- Shown once: a credential that will not be shown again ---- */

.reveal {
    margin-bottom: 1.5rem;
    border-radius: var(--panel-radius);
    background: linear-gradient(rgb(var(--warn-rgb) / 0.07), rgb(var(--warn-rgb) / 0.07)), var(--panel-strong);
    box-shadow: var(--panel-edge), 0 0 0 1px rgb(var(--warn-rgb) / 0.4);
    overflow: hidden;
}

.reveal > p {
    margin: 0;
    padding: 0.7rem 1.1rem;
    border-bottom: 1px solid rgb(var(--warn-rgb) / 0.2);
    font-size: 0.9rem;
}

.reveal-body {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    padding: 1.1rem;
}

.reveal-body pre {
    flex: 1;
    margin: 0;
    user-select: all;
}

/* ---- Confirm: a dialog the server renders into #dialog ---- */

.confirm {
    width: min(28rem, calc(100vw - 2rem));
    padding: 1.4rem;
    border: 0;
    border-radius: var(--card-radius);
    background: var(--panel-strong);
    backdrop-filter: var(--panel-blur);
    -webkit-backdrop-filter: var(--panel-blur);
    box-shadow: var(--float-shadow);
    color: var(--text);
}

.confirm::backdrop {
    background: rgb(8 6 24 / 0.6);
    backdrop-filter: blur(3px);
}

.confirm h2 {
    margin-bottom: 0.5rem;
    font-size: 1.125rem;
    overflow-wrap: anywhere;
}

.confirm p {
    color: var(--text-soft);
}

.confirm .actions {
    justify-content: flex-end;
    margin-top: 1.4rem;
}

.confirm form {
    margin: 0;
}

/* ---- The document: a page a stranger reads once and acts on once ---- */

body.doc {
    --content-width: 44rem;
}

.doc-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1.5rem;
}

.doc-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem 2.5rem;
    margin: 0 0 1.5rem;
    font-size: 0.9rem;
}

.doc-meta dt {
    margin-bottom: 0.15rem;
    font-size: 0.8125rem;
    color: var(--text-muted);
}

.doc-meta dd {
    margin: 0;
}

.doc-total {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.85rem 1.1rem;
    font-size: 1.125rem;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
}

/* ---- The narrow page: sign in, on one centered card ---- */

/* A panel with a faint violet halo, the thin wordmark beside the glowing
   mark. One left edge inside it. */
body.narrow {
    display: grid;
    place-items: center;
    padding-block: 2rem;
    padding-inline: 1rem;
}

body.narrow .frame {
    display: block;
    position: relative;
    box-sizing: border-box;
    width: 100%;
    max-width: 26rem;
    padding: 2.25rem 2.25rem 2rem;
    border-radius: var(--card-radius);
    background: var(--panel);
    backdrop-filter: var(--panel-blur);
    -webkit-backdrop-filter: var(--panel-blur);
    box-shadow: var(--panel-edge), 0 0 0 1px rgb(255 255 255 / 0.1), 0 0 48px -8px rgb(var(--violet-rgb) / 0.35), 0 24px 48px -16px rgb(4 2 16 / 0.6);
}

/* The mark's trace along the card's top edge, glowing. */
body.narrow .frame::before {
    content: "";
    position: absolute;
    inset: 0 1.25rem auto;
    height: 1px;
    background: var(--wire);
    pointer-events: none;
}

body.narrow .topbar {
    position: static;
    justify-content: flex-start;
    min-height: 0;
    margin-bottom: 2rem;
    padding: 0;
    border: 0;
    background: none;
    box-shadow: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

body.narrow .topbar::after {
    content: none;
}

body.narrow .brand {
    gap: 0.7rem;
    font-size: 1.0625rem;
}

body.narrow .brand img {
    width: 1.9rem;
    height: 1.9rem;
}

body.narrow main {
    max-width: none;
    padding: 0;
}

body.narrow h1 {
    margin-bottom: 1.5rem;
    font-size: 1.75rem;
    font-weight: 300;
    color: #fff;
}

body.narrow .page-head:has(h1) {
    margin-bottom: 1.5rem;
}

body.narrow .page-head h1 {
    margin-bottom: 0;
}

body.narrow main form,
body.narrow .form {
    display: grid;
    gap: 1rem;
    max-width: none;
    margin: 0;
}

body.narrow .form > .actions,
body.narrow main form > .actions {
    flex-direction: column;
    align-items: stretch;
    padding-top: 0.25rem;
}

body.narrow .btn {
    min-height: var(--tap);
    font-size: 1rem;
}

body.narrow input {
    min-height: var(--tap);
}

body.narrow main > .hint {
    margin-top: 1.5rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--line-soft);
    font-size: 0.875rem;
    color: var(--text-muted);
}

body.narrow main > .hint a {
    padding-block: 0.85rem;
    margin-block: -0.85rem;
}

body.narrow a:not(.btn, .brand) {
    color: var(--link);
}

/* Sign in with a provider: one full-width button each. */
.providers {
    display: grid;
    gap: 0.5rem;
}

/* The rule before the providers is theirs to draw, so an empty list of
   providers leaves no rule pointing at nothing. */
.divider:has(+ .providers) {
    display: none;
}

.providers:has(*) {
    margin-top: 2rem;
    padding-top: 2rem;
    border-top: 1px solid var(--line);
}

.providers form {
    margin: 0;
}

.btn-provider {
    width: 100%;
    gap: 0.6rem;
}

.provider-icon {
    flex-shrink: 0;
    width: 1.1rem;
    height: 1.1rem;
}

/* A button that is only a logo is a square, and a list of them a row, not
   a stack of full-width bars with nothing written on them. */
.providers:has(.btn-provider > svg:only-child) {
    display: flex;
    flex-wrap: wrap;
}

.btn-provider:has(> svg:only-child) {
    width: 3rem;
}

/* A rule that fades out at both ends: the card's top edge without the
   glow. */
hr,
.divider {
    height: 1px;
    margin: 2rem 0;
    border: 0;
    background: linear-gradient(90deg, transparent, var(--line) 15%, var(--line) 85%, transparent);
}

/* ---- The account hub: a page that is only a set of links ---- */

/* auth's home renders its destinations as a row of link buttons straight
   in main. Drawn as one panel of rows instead, each with a chevron. */
main > .actions:has(> a.btn:nth-of-type(2)):not(:has(> :not(a.btn))) {
    display: grid;
    gap: 0;
    border-radius: var(--panel-radius);
    background: var(--panel);
    backdrop-filter: var(--panel-blur);
    -webkit-backdrop-filter: var(--panel-blur);
    box-shadow: var(--panel-shadow-soft), 0 0 0 1px var(--panel-line);
}

main > .actions:has(> a.btn:nth-of-type(2)):not(:has(> :not(a.btn))) > a.btn {
    justify-content: space-between;
    min-height: 3.5rem;
    padding: 0.6rem 1.1rem;
    border: 0;
    border-top: 1px solid var(--line-soft);
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    font-size: 0.9375rem;
    font-weight: 400;
}

main > .actions:has(> a.btn:nth-of-type(2)):not(:has(> :not(a.btn))) > a.btn:first-child {
    border-top: 0;
    border-radius: var(--panel-radius) var(--panel-radius) 0 0;
}

main > .actions:has(> a.btn:nth-of-type(2)):not(:has(> :not(a.btn))) > a.btn:last-child {
    border-radius: 0 0 var(--panel-radius) var(--panel-radius);
}

main > .actions:has(> a.btn:nth-of-type(2)):not(:has(> :not(a.btn))) > a.btn::after {
    content: "";
    width: 0.4rem;
    height: 0.4rem;
    border-top: 1.5px solid var(--text-faint);
    border-right: 1.5px solid var(--text-faint);
    transform: rotate(45deg);
}

main > .actions:has(> a.btn:nth-of-type(2)):not(:has(> :not(a.btn))) > a.btn:hover {
    background: var(--wash-hover);
}

main > .actions:has(> a.btn:nth-of-type(2)):not(:has(> :not(a.btn))) > a.btn:hover::after {
    border-color: var(--magenta);
}

/* ---- Without backdrop-filter ---- */

/* A panel that cannot blur shows the circuit sharp under the text, so each
   panel becomes its measured composite, opaque. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .panel,
    .create > .form,
    main > .actions:has(> a.btn:nth-of-type(2)):not(:has(> :not(a.btn))),
    body.narrow .frame {
        background: var(--panel-fallback);
    }

    .topbar {
        background: var(--bar-fallback);
    }

    .menu-list,
    .list .cell-actions details > :not(summary),
    .confirm {
        background: var(--panel-solid);
    }
}

/* ---- A phone ---- */

@media (max-width: 45rem) {
    :root {
        --gutter: 1rem;
        --control-height: var(--tap);
    }

    /* Brand and account on the first row, the section links wrapping on
       the rows below, so none is cut off out of sight. The first row is a
       fixed height, so the account menu can open right under it. */
    .topbar {
        flex-wrap: wrap;
        gap: 0 0.75rem;
        min-height: 3.75rem;
        padding-block: 0.375rem;
    }

    .sections {
        order: 3;
        flex-basis: 100%;
    }

    .brand .brand-name {
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .account {
        max-width: 55%;
    }

    /* A 48px box around one short name is heavier than the brand beside
       it: the target stays, the outline goes, and the name lines up with
       the column's right edge. */
    .account:has(> .menu-button) {
        margin-right: -0.6rem;
    }

    .menu-button,
    .menu-button:hover,
    .menu-button:has(+ .menu-list:popover-open) {
        max-width: 100%;
        padding-inline: 0.6rem;
        border-color: transparent;
        background: transparent;
    }

    .menu-button:has(+ .menu-list:popover-open)::after {
        transform: translateY(0.1rem) rotate(225deg);
    }

    /* The account menu is a sheet across the phone under the bar: opaque,
       so no page text shows through it, with rows a thumb can hit. */
    .menu-list {
        inset: calc(3.75rem + 1px) 0 auto 0;
        width: auto;
        min-width: 0;
        max-width: none;
        padding: 0.35rem calc(var(--gutter) - 0.5rem) 0.6rem;
        border-radius: 0 0 var(--float-radius) var(--float-radius);
        background: var(--panel-solid);
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
    }

    /* The page under the sheet dims, so where the sheet ends is plain;
       the top bar above it stays lit. */
    .menu-list::backdrop {
        inset: calc(3.75rem + 1px) 0 0;
        background: rgb(8 6 24 / 0.6);
    }

    .menu-list > .btn,
    .menu-list > form > .btn,
    .menu-list > a {
        padding-inline: 0.5rem;
        font-size: 1rem;
    }

    .menu-list > form:first-of-type {
        margin-top: 0.35rem;
        padding-top: 0.35rem;
    }

    main {
        padding-block: 1.75rem 3rem;
    }

    h1 {
        font-size: 1.5rem;
    }

    .page-head {
        margin-bottom: 1.5rem;
    }

    /* A thumb, not a pointer. */
    .btn,
    .menu-button,
    .sections a,
    .tabs a,
    .tabs a.btn,
    .menu-list > .btn,
    .menu-list > form > .btn,
    .menu-list > a,
    .list .cell-actions details > summary,
    .list .cell-actions details > :not(summary) .btn {
        min-height: var(--tap);
    }

    .list .cell-actions details > summary {
        min-width: var(--tap);
    }

    .btn-icon {
        min-width: var(--tap);
        min-height: var(--tap);
    }

    input:where([type="text"], [type="email"], [type="password"], [type="search"], [type="number"], [type="tel"], [type="url"], [type="date"], :not([type])),
    select {
        min-height: var(--tap);
    }

    .bar {
        position: static;
    }

    .bar select {
        flex: 1 1 100%;
        max-width: none;
    }

    .bar .btn {
        flex: 1 1 auto;
    }

    .bar .grow {
        display: none;
    }

    .select-all {
        flex-basis: 100%;
    }

    /* The page's actions take their own row under the heading. */
    .page-actions {
        flex-basis: 100%;
    }

    .tabs {
        flex-basis: 100%;
    }

    .brand {
        min-height: var(--tap);
    }

    .facts {
        grid-template-columns: 1fr;
    }

    .facts dt {
        min-height: 0;
        padding-bottom: 0;
    }

    .facts dd {
        min-height: 0;
        padding-top: 0.15rem;
        border-top: 0;
    }

    body.narrow {
        padding: 1rem;
        place-items: start center;
    }

    /* The brand link's 48px box already pads the mark from the card's
       top, so the card's own top padding is smaller than its bottom. */
    body.narrow .frame {
        margin-top: 1.5rem;
        padding: 1rem 1.25rem 1.5rem;
    }
}

/* Below 40rem a list row becomes a record. The header row stays for
   screen readers, and each cell carries its column's name from data-th. */
@media (max-width: 40rem) {
    .list thead {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }

    .list,
    .list tbody,
    .list tfoot {
        display: block;
    }

    /* A row with a select box gets a column for it; one without starts
       at the panel's edge. */
    .list tr {
        display: grid;
        grid-template-columns: 1fr;
        gap: 0.35rem 0.75rem;
        padding: 0.85rem 1.1rem;
        border-bottom: 1px solid var(--line-soft);
    }

    .list tr:has(> td.col-select) {
        grid-template-columns: auto 1fr;
    }

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

    .list tbody tr:hover > td,
    .list tbody tr:has(> td > input:checked) > td {
        background: none;
    }

    .list tbody tr:has(> td > input:checked) {
        background: rgb(var(--violet-rgb) / 0.14);
    }

    /* A block with the label hung in its left padding, not a grid: in a
       grid every child element is its own item, and the <wbr>s
       breakable_email puts in an address would split it onto a line per
       segment. */
    .list td {
        display: block;
        position: relative;
        grid-column: -2;
        height: auto;
        min-width: 0;
        padding: 0 0 0 6.25rem;
        border: 0;
        text-align: left;
    }

    .list td::before {
        content: attr(data-th);
        position: absolute;
        top: 0.1rem;
        left: 0;
        width: 5.75rem;
        font-family: var(--font);
        font-size: 0.8125rem;
        color: var(--text-faint);
    }

    /* The label is out of the flow, so an empty cell still takes a line
       for it rather than letting it print over the next row's. */
    .list td[data-th] {
        min-height: 1.4rem;
    }

    .list td:has(> .badge:only-child) {
        width: auto;
    }

    /* A record's edge is too close to the panel's to hang a marker past,
       so the markers sit on it and the tag's box moves right instead,
       which still lines up every state's word. */
    .list td > .badge:only-child {
        margin-left: 0;
    }

    .list td > .badge[data-state="warn"]:only-child {
        margin-left: 0.5rem;
    }

    .list td:not([data-th]) {
        padding-left: 0;
    }

    .list td:not([data-th])::before {
        display: none;
    }

    .list td.col-select {
        grid-column: 1;
        grid-row: 1;
        width: auto;
        padding: 0;
    }

    .list .num {
        text-align: left;
    }

    /* A row's buttons end the record, on their own line under its facts.
       A row menu is one icon, so it sits at the record's top right instead
       and opens over the rows under it. */
    .list td.cell-actions {
        width: auto;
        padding: 0.35rem 0 0;
        text-align: left;
    }

    .list td.cell-actions:not(:has(*)) {
        display: none;
    }

    .list tr:has(> td.cell-actions > details) {
        position: relative;
        padding-right: 3.75rem;
    }

    /* The button's center on the center of the record's first line. */
    .list td.cell-actions:has(> details) {
        position: absolute;
        top: 0.0625rem;
        right: 0.5rem;
        padding: 0;
        text-align: right;
    }
}

/* Forced colors strips box-shadows, which is all that marks the current
   tab and section, and repaints the state markers white. Last in the
   file: .tabs a.btn-primary's text-decoration would win otherwise. */
@media (forced-colors: active) {
    .tabs a[aria-current],
    .sections a[aria-current] {
        text-decoration: underline 2px;
        text-underline-offset: 0.4em;
    }

    .badge::before {
        forced-color-adjust: none;
    }
}
