/*
    Account pages. Self-contained: no CDN, nothing that reaches off the origin,
    because this is where people type their password. The brand font and logo
    are static files served from this origin — same trust boundary as this
    stylesheet.

    The palette and type mirror the marknote.md site (marknote-blazor-site:
    Styles/tailwind.css + tailwind.config.js) so signing up feels like the same
    product: ink surface tokens, the app's #EE0000 accent, and the accent-prose
    pair (#A70000 light / #FA8F8F dark) for any accent-coloured text, which is
    what keeps links and focus rings at AAA contrast on both themes.
*/

/* Same face the site and the desktop app use; one variable file covers the
   300–900 weight axis. font-display: swap so the form renders immediately in
   the system fallback while it loads. */
@font-face {
    font-family: "Red Hat Display";
    font-style: normal;
    font-weight: 300 900;
    font-display: swap;
    src: url("../fonts/red-hat-display-variable.woff2") format("woff2");
}

:root {
    color-scheme: light dark;

    --bg: #fafafb;            /* ink-base */
    --surface: #ffffff;       /* ink-card */
    --text: #18181b;          /* ink-text */
    --muted: #52525b;         /* ink-dim */
    --line: #e5e7eb;          /* ink-line */
    --accent: #ee0000;        /* accent-600 — backgrounds only, never text */
    /* Interaction DARKENS the button; it used to lighten it.

       With white text that is not a style choice. Hover was accent-500
       (#f42b2b), lighter than rest, which drops white to 4.02:1 — below AA,
       and precisely while the pointer is on the control. Darkening instead
       keeps every state above it: 4.53:1 at rest, 5.44:1 hovered, 6.58:1
       pressed. Measured, not estimated. */
    --accent-hover: #d60000;  /* accent-700 */
    --accent-active: #be0000; /* accent-800 */
    --accent-prose: #a70000;  /* accent-900 — accent TEXT on the page bg */
    --error-bg: #fef2f2;
    --error-text: #a70000;
    --success-bg: #e6f6ec;
    --success-text: #1c5b33;
    --card-shadow: 0 8px 32px rgba(0, 0, 0, 0.06);
}

@media (prefers-color-scheme: dark) {
    :root {
        --bg: #0e0f12;
        --surface: #1c1f24;
        --text: #e7e9ee;
        --muted: #9ea3ae;
        --line: #2a2d33;
        --accent-prose: #fa8f8f; /* accent-300 — pure red can't reach AAA on dark */
        --error-bg: #3a1d1d;
        --error-text: #fa8f8f;
        --success-bg: #16301f;
        --success-text: #8fd6a8;
        --card-shadow: 0 8px 32px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.06);
    }
}

* { box-sizing: border-box; }

body {
    margin: 0;
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    /* The site's dot grid, quiet enough to sit behind a form. */
    background:
        radial-gradient(circle, rgba(238, 0, 0, 0.13) 1px, transparent 1.5px) 0 0 / 24px 24px,
        var(--bg);
    color: var(--text);
    font: 15px/1.5 "Red Hat Display", "Segoe UI", system-ui, -apple-system, sans-serif;
}

/* Accent-tinted selection, mirroring the site and the app's editor. */
::selection { background: rgba(238, 0, 0, 0.3); }

/* Keyboard focus only; mouse clicks stay quiet — same rule as the site. */
:focus {
    outline: 2px solid var(--accent-prose);
    outline-offset: 2px;
    border-radius: 6px;
}
:focus:not(:focus-visible) { outline: none; }

.card {
    width: 100%;
    max-width: 400px;
    padding: 32px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 12px;
    box-shadow: var(--card-shadow);
}

.brand {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0 0 6px;
    font-size: 20px;
    font-weight: 700;
    letter-spacing: -0.01em;
}

.brand img { display: block; }

h2 {
    margin: 0 0 20px;
    font-size: 17px;
    font-weight: 600;
}

label {
    display: block;
    margin-bottom: 6px;
    font-size: 13px;
    color: var(--muted);
}

input[type="email"],
input[type="password"],
input[type="text"] {
    width: 100%;
    padding: 10px 12px;
    margin-bottom: 16px;
    background: var(--bg);
    color: var(--text);
    border: 1px solid var(--line);
    border-radius: 10px;
    font: inherit;
}

input:focus-visible { outline-offset: 1px; }

button {
    width: 100%;
    padding: 11px;
    border: 0;
    border-radius: 10px;
    background: var(--accent);
    /* White on the accent, and fixed rather than theme-aware.

       This used to be the site's btn-primary pairing, dark text on red. It
       was changed on the owner's call (2026-09-01) for contrast: white
       measures 4.53:1 against #ee0000 and the dark pairing 4.23:1, so white
       is the only one of the two that clears the 4.5:1 text this size is
       held to — though only just, which is why the hover and active shades
       darken rather than lighten. It also ends a
       split inside this very stylesheet, where the plan and danger-zone
       buttons below were already white on the same red, and brings the
       consumer pages into line with the admin doors and with account mail. */
    color: #ffffff;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
    box-shadow: 0 0 0 1px rgba(238, 0, 0, 0.35), 0 8px 32px rgba(238, 0, 0, 0.15);
    transition: background 150ms ease, transform 100ms ease;
}

button:hover { background: var(--accent-hover); }
button:active { background: var(--accent-active); transform: scale(0.98); }

button.secondary {
    background: transparent;
    color: var(--text);
    border: 1px solid var(--line);
    font-weight: 500;
    margin-top: 10px;
    box-shadow: none;
}

button.secondary:hover { background: var(--bg); }
button.secondary:active { background: var(--bg); }

@media (prefers-reduced-motion: reduce) {
    button { transition: none; }
    button:active { transform: none; }
}

.checkbox {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 16px;
    font-size: 14px;
    color: var(--muted);
}

.checkbox input { margin: 0; accent-color: var(--accent); }

.error {
    padding: 10px 12px;
    margin-bottom: 16px;
    background: var(--error-bg);
    color: var(--error-text);
    border-radius: 6px;
    font-size: 14px;
}

.success {
    padding: 10px 12px;
    margin-bottom: 16px;
    background: var(--success-bg);
    color: var(--success-text);
    border-radius: 6px;
    font-size: 14px;
}

.note {
    margin-top: 20px;
    padding-top: 16px;
    border-top: 1px solid var(--line);
    font-size: 13px;
    color: var(--muted);
}

a {
    color: var(--accent-prose);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.divider {
    margin: 18px 0;
    text-align: center;
    font-size: 12px;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

/* ---- passkey list ---- */

/* The card is deliberately narrow for the sign-in forms; the table needs more
   room than that, so this page widens it. */
.card.wide { max-width: 620px; }

/* Four columns will not fit a phone. Scrolling the table rather than the page
   keeps the rest of the card readable. */
.table-scroll { overflow-x: auto; }

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

table.keys th {
    text-align: left;
    padding: 0 8px 8px 0;
    font-size: 12px;
    font-weight: 600;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    white-space: nowrap;
}

table.keys td {
    padding: 10px 8px 10px 0;
    border-top: 1px solid var(--line);
    vertical-align: middle;
    white-space: nowrap;
}

table.keys td:first-child { white-space: normal; }

/* The name doubles as its own edit field: no separate mode, no dialog. The
   button only earns its space once the row is hovered or focused. */
form.rename {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    width: auto;
    margin: 0;
}

form.rename input[type="text"] {
    width: 26ch;
    margin: 0;
    padding: 5px 8px;
    font-size: 14px;
    background: transparent;
    border-color: transparent;
}

form.rename input[type="text"]:hover { border-color: var(--line); }

form.rename input[type="text"]:focus-visible {
    background: var(--bg);
    border-color: var(--line);
}

button.link {
    width: auto;
    margin: 0;
    padding: 4px 6px;
    background: none;
    border: 0;
    color: var(--muted);
    font-size: 13px;
    font-weight: 500;
    text-decoration: underline;
    text-underline-offset: 2px;
    box-shadow: none;
    opacity: 0;
}

/* Keyboard users must be able to reach it, so focus reveals it too — opacity
   alone would leave it invisible but tabbable, which is worse than hidden. */
tr:hover button.link,
button.link:focus-visible { opacity: 1; }

button.link:hover { background: none; color: var(--text); }
button.link:active { background: none; transform: none; }
button.link.danger:hover { color: var(--accent-prose); }

.tag {
    margin-left: 6px;
    padding: 2px 6px;
    border-radius: 4px;
    background: var(--bg);
    border: 1px solid var(--line);
    font-size: 11px;
    color: var(--muted);
}

/* The beta mark beside the wordmark: brand-tinted rather than grey, because
   it is a statement about the product, not metadata about a row. The accent
   stays background-tint + accent-prose text, per the palette rules. */
.brand .tag.beta {
    margin-left: 2px;
    background: rgba(238, 0, 0, 0.12);
    border-color: transparent;
    color: var(--accent-prose);
    font-weight: 700;
    font-size: 10px;
    letter-spacing: 0.06em;
    vertical-align: 2px;
}

/* The plan you are on, among the plans on offer. */
.stat.current { border-color: var(--accent-prose); }

/* Shown only for authenticators we could not name — deliberately quiet, but
   selectable, because its whole purpose is to be copied and looked up. */
.aaguid {
    margin-top: 2px;
    font-family: "Cascadia Mono", Consolas, ui-monospace, monospace;
    font-size: 11px;
    color: var(--muted);
    user-select: all;
}

/* ---- the doors: sign in / register as a split card ---- */

.card.split {
    max-width: 880px;
    padding: 0;
    display: flex;
    overflow: hidden;   /* the hero art bleeds past the corner radius on purpose */
}

.hero {
    flex: 1;
    min-width: 0;
    position: relative;
    display: flex;
    flex-direction: column;
    padding: 36px 40px;
    border-right: 1px solid var(--line);
    background:
        /* a faint drafting grid, fading out toward the top right */
        linear-gradient(var(--line) 1px, transparent 1px) 0 0 / 48px 48px,
        linear-gradient(90deg, var(--line) 1px, transparent 1px) 0 0 / 48px 48px,
        var(--bg);
}

.hero::before {
    /* wash the grid back so it reads as texture, not graph paper: solid
       surface up top where the words are, grid ghosting in toward the art */
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(to bottom left, var(--bg) 35%, transparent 90%);
    pointer-events: none;
}

.hero > * { position: relative; }

.hero-copy { margin: 48px 0 auto; max-width: 36ch; }

.hero-copy h2 {
    margin: 0 0 12px;
    font-size: 32px;
    line-height: 1.15;
    font-weight: 800;
    letter-spacing: -0.02em;
}

.hero-copy p {
    margin: 0;
    font-size: 15px;
    color: var(--muted);
}

/* Abstract shapes in the brand red, drawn entirely in CSS — the account pages
   load nothing, so the art has to come from the stylesheet. Translucent so
   both themes tint them correctly. */
.hero-art {
    position: absolute;
    inset: auto auto 0 0;
    width: 100%;
    height: 220px;
    pointer-events: none;
}

.art-disc {
    /* a tall capsule rising from the bottom edge */
    position: absolute;
    bottom: -34px;
    left: 118px;
    width: 110px;
    height: 190px;
    border-radius: 55px 55px 0 0;
    background: rgba(238, 0, 0, 0.13);
}

.art-ring {
    /* a wide arc, cropped by the card's bottom edge */
    position: absolute;
    bottom: -110px;
    left: 205px;
    width: 210px;
    height: 210px;
    border-radius: 50%;
    border: 30px solid rgba(238, 0, 0, 0.09);
}

.art-leaf {
    position: absolute;
    bottom: -26px;
    left: -30px;
    width: 140px;
    height: 140px;
    background: rgba(238, 0, 0, 0.20);
    border-radius: 50% 50% 0 50%;   /* petal: three round corners, one sharp */
    transform: rotate(-15deg);
}

.pane {
    width: 400px;
    flex-shrink: 0;
    padding: 40px 36px;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

input::placeholder { color: var(--muted); opacity: 0.65; }

.center-link {
    margin: 14px 0 0;
    text-align: center;
    font-size: 13px;
}

/* Phones and narrow windows: the hero shrinks to a masthead — headline and
   sentence, no art — and the form follows underneath. */
@media (max-width: 760px) {
    .card.split { flex-direction: column; }

    .hero {
        border-right: 0;
        border-bottom: 1px solid var(--line);
        padding: 24px 28px 22px;
        background: var(--bg);   /* no grid behind a masthead this small */
    }

    .hero-copy { margin: 16px 0 0; }
    .hero-copy h2 { font-size: 24px; }
    .hero-art { display: none; }

    .pane { width: auto; padding: 28px 24px; }
}

/* ---- signed-in shell: the same rounded card, widened around a sidebar ---- */

.card.shell {
    max-width: 1600px;
    /* A FIXED height, not a minimum — the user's requirement is that every
       page presents the identical panel, so the tall pages scroll inside the
       content pane instead of stretching the card. Viewport-capped so laptops
       aren't asked for more than they have. */
    height: min(1000px, calc(100vh - 48px));
    padding: 0;
    display: flex;
    overflow: hidden;   /* the sidebar's tinted panel must not poke past the radius */
}

.sidenav {
    flex-shrink: 0;
    width: 290px;
    display: flex;
    flex-direction: column;
    padding: 32px 18px 24px;
    background: var(--bg);
    border-right: 1px solid var(--line);
}

.sidenav .brand {
    font-size: 17px;
    margin: 0 12px 20px;
}

.sidenav ul {
    list-style: none;
    margin: 0;
    padding: 0;
    flex: 1;
}

.sidenav li + li { margin-top: 2px; }

.sidenav a {
    display: block;
    padding: 10px 12px;
    border-radius: 6px;
    color: var(--muted);
    font-size: 14px;
    font-weight: 500;
    text-decoration: none;
}

.sidenav a:hover {
    color: var(--text);
    background: var(--surface);
}

/* The active page: the accent as a quiet left mark, not a filled bar —
   accent-600 stays backgrounds-only per the palette rules, and a 3px sliver
   next to AAA text is the compromise that keeps both. */
.sidenav a[aria-current="page"] {
    color: var(--text);
    font-weight: 600;
    background: var(--surface);
    box-shadow: inset 3px 0 0 var(--accent);
}

/* ---- the identity block: picture, name, email, above the way out ---- */

.sidenav .who {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 16px 12px 0;
    min-width: 0;
}

.who-lines { min-width: 0; }

/* The name is a link to the profile: plain text until hovered, so the block
   still reads as "who you are" rather than a menu. */
/* Overrides the sidebar's nav-link rule (.sidenav a: block, padded, tinted)
   which would otherwise indent the name away from the email under it. */
.sidenav .who-name a {
    display: inline;
    padding: 0;
    border-radius: 0;
    background: none;
    color: inherit;
    font-size: inherit;
    font-weight: inherit;
    text-decoration: none;
    border-bottom: 1px solid transparent;
}

.sidenav .who-name a:hover { background: none; color: inherit; border-bottom-color: var(--muted); }

/* ---- the picture's flyout: a <details> that opens above the block ---- */

.sidenav .who { position: relative; }

.avatar-menu { position: static; }

.avatar-menu > summary {
    list-style: none;
    cursor: pointer;
    display: inline-flex;
    border-radius: 50%;
    outline-offset: 3px;
}

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

.avatar-menu > summary:hover .avatar { border-color: var(--muted); }

.avatar-menu[open] > summary .avatar { box-shadow: 0 0 0 2px var(--accent); }

.avatar-menu .flyout {
    position: absolute;
    left: 0;
    bottom: calc(100% + 10px);
    z-index: 5;
    width: 250px;
    padding: 14px 14px 12px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 10px;
    box-shadow: var(--card-shadow);
}

.flyout-title {
    margin: 0 0 10px;
    font-size: 13px;
    font-weight: 600;
}

.flyout .avatar-upload { flex-direction: column; align-items: stretch; gap: 8px; max-width: none; }

.flyout .avatar-upload button { width: 100%; margin: 0; }

.flyout .link.inline { padding: 8px 0 0; }

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

.who-name {
    font-size: 13px;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The email is the account — it identifies which one you are signed into, so
   it must be legible in full. It wraps rather than truncates; the sidebar is
   sized so most addresses fit one line anyway. */
.who-email {
    font-size: 12px;
    color: var(--muted);
    overflow-wrap: anywhere;
}

/* The picture is displayed cropped to a circle whatever its shape — the
   upload is stored as sent, so the crop is presentation, not data. */
.avatar {
    width: 36px;
    height: 36px;
    flex-shrink: 0;
    border-radius: 50%;
    object-fit: cover;
    border: 1px solid var(--line);
}

.avatar.placeholder {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: rgba(238, 0, 0, 0.12);
    color: var(--accent-prose);
    font-weight: 700;
    font-size: 15px;
}

.avatar.large {
    width: 72px;
    height: 72px;
}

.avatar.large.placeholder { font-size: 28px; }

/* ---- the profile page's picture row ---- */

.avatar-row {
    display: flex;
    align-items: center;
    gap: 18px;
}

.avatar-actions { min-width: 0; }

form.avatar-upload {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

input[type="file"] {
    font: inherit;
    font-size: 13px;
    color: var(--muted);
    max-width: 100%;
}

input[type="file"]::file-selector-button {
    padding: 7px 12px;
    margin-right: 10px;
    background: var(--bg);
    color: var(--text);
    border: 1px solid var(--line);
    border-radius: 6px;
    font: inherit;
    font-size: 13px;
    cursor: pointer;
}

/* A link-button that is always visible — the table variant hides until the
   row is hovered, which makes no sense outside a table. */
button.link.inline {
    width: auto;
    opacity: 1;
    padding: 6px 0 0;
}

.account-email {
    color: var(--muted);
    font-size: 14px;
    margin-top: 0;
}

.sidenav .signout { margin: 12px 12px 0; }

/* The build stamp under the sign-out button: a small rounded rectangle,
   centred, quiet. Same shape as the page's other pills. */
.sidenav .build {
    display: flex;
    justify-content: center;
    margin: 12px 12px 0;
}

.build-pill {
    display: inline-flex;
    align-items: center;
    height: 22px;
    padding: 0 9px;
    border: 1px solid var(--line);
    border-radius: 6px;
    background: var(--surface);
    color: var(--muted);
    font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
    font-size: 11px;
    letter-spacing: 0.02em;
    white-space: nowrap;
}

.sidenav .signout button {
    width: 100%;
    margin: 0;
    font-size: 13px;
    padding: 8px;
}

.shell .content {
    flex: 1;
    min-width: 0;      /* lets the table-scroll shrink instead of the card growing */
    padding: 40px 44px;
    overflow-y: auto;  /* the card's height is fixed; long pages scroll here */
}

/* More room earns slightly more voice: the page title and body text scale up
   a step inside the shell, where the narrow card's compact sizes read lost. */
.shell .content h2 { font-size: 20px; }
.shell .content { font-size: 15px; }

/* The room is for tables and lists, not for stretching a text field across
   the whole pane — fields keep a form's width. Inline forms (rename, the
   table's revoke buttons) size to their content anyway and don't care. */
.shell .content form { max-width: 420px; }
.shell .content > button { max-width: 420px; }

/* ---- the white-on-red action language ---- */

/* Quiet buttons that turn decisive on hover: the sidebar's sign-out and the
   profile's save rest as outlines and commit to the brand red under the
   pointer. White text there by the owner's call. */
button.accent-hover:hover {
    background: var(--accent);
    color: #ffffff;
    border-color: transparent;
}

button.accent-hover:active { background: var(--accent-active); color: #ffffff; }

/* The inverse: a button that starts red-and-white and calms to the quiet
   grey outline state on hover — the add-passkey call to action. */
button.accent-invert {
    background: var(--accent);
    color: #ffffff;
}

button.accent-invert:hover {
    background: var(--bg);
    color: var(--text);
    box-shadow: inset 0 0 0 1px var(--line);
}

button.accent-invert:active {
    background: var(--bg);
    color: var(--text);
}

/* ---- the overview ---- */

/* Picture on the left, greeting and email beside it — the same identity the
   sidebar shows, at front-page scale. */
.greeting {
    display: flex;
    align-items: center;
    gap: 18px;
    margin-bottom: 28px;
}

.greeting h2 {
    margin: 0 0 4px;
    font-size: 28px;
    font-weight: 800;
    letter-spacing: -0.02em;
}

.greeting .email {
    margin: 0;
    font-size: 14px;
    color: var(--muted);
}

/* Plan, devices, passkeys as tiles that go somewhere — each is the front of
   its page, not just a number. */
.stat-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: 14px;
}

/* .stat is shared between the overview's links and the plan page's plain
   tiles — only the links move on hover, because only they go somewhere. */
.stat {
    display: block;
    padding: 18px 20px;
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: 10px;
    color: var(--text);
    text-decoration: none;
    transition: border-color 150ms ease, transform 100ms ease;
}

a.stat:hover {
    border-color: var(--accent-prose);
    transform: translateY(-1px);
}

.stat .label,
.stat .figure,
.stat .sub { display: block; }

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

.stat .figure {
    margin-top: 4px;
    font-size: 26px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    line-height: 1.15;
}

.stat .sub {
    margin-top: 6px;
    font-size: 12px;
    color: var(--muted);
}

@media (prefers-reduced-motion: reduce) {
    a.stat { transition: none; }
    a.stat:hover { transform: none; }
}

/* ---- icon buttons (the passkey rename pencil) ---- */

button.link.icon {
    padding: 4px;
    text-decoration: none;
}

button.link.icon svg { display: block; }

/* ---- the danger zone ---- */

.danger-zone {
    margin-top: 28px;
    padding: 18px 20px;
    border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
    border-radius: 10px;
}

.danger-zone h3 { color: var(--accent-prose); }

.danger-zone button[type="submit"] {
    background: var(--accent);
    color: #ffffff;
    width: auto;
    padding: 10px 18px;
}

.danger-zone button[type="submit"]:hover { background: var(--accent-hover); color: #ffffff; }

/* Phones: the sidebar becomes a nav row across the top of the card. Same
   markup, no script — the shell is one media query away from either shape. */
@media (max-width: 640px) {
    /* Stacked, the fixed height would crush the content pane; a phone page
       scrolls as a page. */
    .card.shell { flex-direction: column; height: auto; }
    .shell .content { overflow-y: visible; }

    .sidenav {
        width: auto;
        border-right: 0;
        border-bottom: 1px solid var(--line);
        padding: 20px 16px 12px;
    }

    .sidenav ul {
        display: flex;
        flex-wrap: wrap;
        gap: 2px;
    }

    .sidenav li + li { margin-top: 0; }

    .sidenav a { padding: 6px 10px; }

    /* The inset left bar reads as clutter on a horizontal row; underline the
       active item instead, like a tab. */
    .sidenav a[aria-current="page"] {
        box-shadow: inset 0 -2px 0 var(--accent);
        border-radius: 6px 6px 0 0;
    }

    .sidenav .who { margin: 12px 0 0; }
    .sidenav .signout { margin: 10px 0 0; }

    .shell .content { padding: 24px 20px; }

    /* nowrap cells set the card's INTRINSIC width — a scroll container does
       not reduce intrinsic size, so the phone's layout viewport expands to
       fit the table and the whole page side-scrolls. Wrapping the cells is
       the honest fix: the table genuinely fits, nothing scrolls. */
    table.keys td { white-space: normal; }
}

/* ---- account page sections ---- */

/* Legacy: a rule between blocks. Kept for any page still using it. */
.account-section {
    margin-top: 24px;
    padding-top: 20px;
    border-top: 1px solid var(--line);
}

.account-section h3,
.shell .content h3 {
    margin: 0 0 12px;
    font-size: 14px;
    font-weight: 600;
}

/* The settings pages (Profile, Security, Devices) are a stack of panels. Each
   panel is one concern: its name and a line of context on the left, the
   controls on the right, so the eye can find "Email address" without reading
   the form under "Display name" first. One column on narrow screens, where
   the head simply sits above the body. */
.section {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 14px 40px;
    margin-top: 16px;
    padding: 22px 24px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--surface);
}

@media (min-width: 960px) {
    .section { grid-template-columns: 220px minmax(0, 1fr); }
}

.section-head { min-width: 0; }

.section-head h3,
.shell .content .section-head h3 {
    margin: 0 0 6px;
    font-size: 15px;
    font-weight: 600;
}

.section-head .lead {
    margin: 0;
    font-size: 13px;
    line-height: 1.5;
    color: var(--muted);
}

.section-body { min-width: 0; }

.section-body > :first-child { margin-top: 0; }

/* The one panel that removes things: red edge, red title, red button. */
.section.danger { border-color: color-mix(in srgb, var(--accent) 40%, transparent); }

.section.danger .section-head h3,
.shell .content .section.danger .section-head h3 { color: var(--accent-prose); }

.section.danger button[type="submit"] {
    background: var(--accent);
    color: #ffffff;
    width: auto;
    padding: 10px 18px;
}

.section.danger button[type="submit"]:hover { background: var(--accent-hover); color: #ffffff; }

/* A panel whose body is a single button (sign out everywhere) shouldn't leave
   the button floating at the top of a tall left column. */
.section-body form.single { display: flex; align-items: flex-start; }

/* In-page links ("sign out everywhere", "change your password") land with the
   panel's top edge in view rather than its heading hard against the pane's
   top; the content pane is the scroll container, so scroll-margin does it. */
.section-head h3[id] { scroll-margin-top: 24px; }

/* Tiles inside a panel: a lone tile (the plan) keeps a tile's width instead
   of stretching across the whole body column. */
.section-body .stat-tiles.single { grid-template-columns: minmax(170px, 280px); }

/* A select styled like the text fields (the vault picker). */
select {
    display: block;
    width: 100%;
    margin-bottom: 14px;
    padding: 10px 12px;
    font: inherit;
    font-size: 14px;
    color: var(--text);
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: 6px;
}

select:focus-visible { outline-offset: 1px; }

.font-mono { font-family: ui-monospace, "Cascadia Mono", Consolas, monospace; font-size: 0.95em; }

/* The facts list is styled further down, next to the other list rules. */

/* Links inside a panel's prose — "manage", "sign out everywhere", "change
   your password" — are actions, and an underlined word in a sentence reads
   as a footnote. The same pill shape as the empty state, at text size, so
   they read as small buttons. Table actions and the overview's tiles have
   their own treatments and are left alone. */
.section :is(p, dd) a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 28px;
    /* 1px more on top than the bottom: Red Hat Display's tall ascenders make
       a mathematically centred line look high, and this puts the x-height
       where the eye expects a button label to be. */
    padding: 1px 11px 0;
    margin: 0 1px;
    border: 1px solid var(--line);
    border-radius: 6px;
    background: var(--bg);
    color: var(--text);
    font-size: 14px;
    font-weight: 600;
    line-height: 1;
    text-decoration: none;
    vertical-align: middle;
    position: relative;
    top: -1px;
    white-space: nowrap;
    transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
}

/* A sentence carrying pills needs taller lines, or two wrapped pills touch;
   the sentence's own height stays for prose without them. Punctuation right
   after a pill keeps the pill's small side padding rather than a gap. */
.section :is(p, dd):has(a) { line-height: 2.6; }

.section :is(p, dd) a:hover {
    background: var(--accent);
    border-color: transparent;
    color: #ffffff;
}

.section :is(p, dd) a:active { background: var(--accent-active); color: #ffffff; }

/* Empty states ("No devices yet…"): a pill rather than a bare line of grey
   text, so the absence of content is presented as a state of its own and
   not mistaken for a stray caption. Dashed edge says "nothing here yet". */
.empty {
    display: inline-flex;
    align-items: center;
    min-height: 40px;
    margin: 0;
    padding: 0 18px;
    border: 1px dashed var(--line);
    border-radius: 8px;
    background: var(--bg);
    color: var(--muted);
    font-size: 13px;
    line-height: 1.4;
}

/* Quiet explanatory text under a control — smaller than .note, no rule above,
   because these sit inside a section rather than closing the card. */
.hint {
    margin: 10px 0 0;
    font-size: 13px;
    color: var(--muted);
}

.optional {
    font-weight: 400;
    text-transform: uppercase;
    font-size: 10px;
    letter-spacing: 0.05em;
    margin-left: 4px;
}

/* Section-local actions: full-width buttons read like the page's one purpose,
   which none of these are. */
button.compact {
    width: auto;
    padding: 8px 16px;
    margin-top: 0;
}

/* Facts: label/value pairs (the account summary, the security summary). A
   definition list, not a table — there are no rows to compare — laid out as
   two columns so every label sits in one line down the left and every value
   starts at the same edge. Flex-wrapped pairs read as one run-on line. */
dl.facts {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr);
    gap: 10px 24px;
    align-items: baseline;
    margin: 0;
    font-size: 14px;
}

dl.facts dt {
    font-size: 12px;
    font-weight: 600;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    white-space: nowrap;
}

dl.facts dd {
    margin: 0;
    min-width: 0;
    overflow-wrap: anywhere;
}

@media (max-width: 640px) {
    dl.facts { grid-template-columns: minmax(0, 1fr); gap: 2px 0; }
    dl.facts dd { margin-bottom: 10px; }
}

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

/* The support code: a pill in the brand tint, monospace, so it reads as a
   thing to copy rather than a word in a sentence. Accent-prose text on a
   faint accent wash keeps it AAA in both themes; the wash is the same one
   the avatar placeholder uses. */
.code-pill {
    display: inline-flex;
    align-items: center;
    height: 26px;
    padding: 1px 10px 0;
    border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
    border-radius: 6px;
    background: rgba(238, 0, 0, 0.08);
    color: var(--accent-prose);
    font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.08em;
    vertical-align: middle;
    position: relative;
    top: -1px;
    user-select: all;
}
