/* ==========================================================================
   thomasjstanbury.com

   One stylesheet, no build step. Organised as: tokens, reset, primitives,
   layout, components, then the two set pieces (the landing door and the
   admin panel).

   The landing page is always dark — it reads as a front door rather than a
   page. Everything behind the login follows the reader's own light or dark
   preference, because the people using it are reading phone numbers and
   addresses and legibility matters more than mood.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */

:root {
    --font-serif: ui-serif, Georgia, "Iowan Old Style", "Palatino Linotype", Palatino, serif;
    --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;

    --bg: #faf8f5;
    --surface: #ffffff;
    --surface-2: #f4f1eb;
    --surface-3: #ebe6dd;
    --line: #e2ddd3;
    --line-strong: #cfc8bb;
    --text: #1e1b17;
    --text-2: #4a443c;
    --muted: #6f665c;
    --accent: #8a6d2f;
    --accent-hover: #6f571f;
    --accent-bg: #f6efdc;
    --on-accent: #fff;
    --danger: #a3312a;
    --danger-bg: #fbeceb;
    --success: #2f6b47;
    --success-bg: #e9f4ed;
    --info: #2c5f8a;
    --info-bg: #e8f1f8;
    --warning: #8f4d0e;
    --warning-bg: #fbefdd;

    --radius: 10px;
    --radius-lg: 16px;
    --radius-sm: 6px;

    --shadow-sm: 0 1px 2px rgba(30, 27, 23, .05);
    --shadow: 0 1px 3px rgba(30, 27, 23, .07), 0 6px 16px -8px rgba(30, 27, 23, .12);
    --shadow-lg: 0 2px 6px rgba(30, 27, 23, .06), 0 20px 40px -20px rgba(30, 27, 23, .22);

    --measure: 68ch;
    --gutter: clamp(1.15rem, 4vw, 2.5rem);
}

@media (prefers-color-scheme: dark) {
    :root {
        --bg: #14120f;
        --surface: #1c1a16;
        --surface-2: #23201b;
        --surface-3: #2b2721;
        --line: #302b25;
        --line-strong: #423b32;
        --text: #ede8e0;
        --text-2: #c5bcaf;
        --muted: #9d9285;
        --accent: #d9b563;
        --accent-hover: #ecc87a;
        --accent-bg: #2a2317;
        --on-accent: #1a1611;
        --danger: #e8837c;
        --danger-bg: #2e1a19;
        --success: #7fc79b;
        --success-bg: #16281d;
        --info: #8ab8e0;
        --info-bg: #17232e;
        --warning: #e6a85c;
        --warning-bg: #2e2214;

        --shadow-sm: 0 1px 2px rgba(0, 0, 0, .3);
        --shadow: 0 1px 3px rgba(0, 0, 0, .35), 0 6px 16px -8px rgba(0, 0, 0, .5);
        --shadow-lg: 0 2px 6px rgba(0, 0, 0, .3), 0 20px 40px -20px rgba(0, 0, 0, .6);
    }
}

/* --------------------------------------------------------------------------
   2. Reset
   -------------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
    }
}

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: var(--font-sans);
    font-size: 16px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

h1, h2, h3, h4 {
    margin: 0;
    line-height: 1.2;
    font-weight: 600;
    letter-spacing: -0.011em;
}

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

a {
    color: var(--accent);
    text-decoration-color: color-mix(in srgb, var(--accent) 35%, transparent);
    text-underline-offset: 0.18em;
}

a:hover { color: var(--accent-hover); text-decoration-color: currentColor; }

img { max-width: 100%; height: auto; display: block; }

hr {
    border: 0;
    border-top: 1px solid var(--line);
    margin: 2rem 0;
}

/* Fieldsets are used purely to group radio inputs for assistive technology;
   the default border and inline-size floor get in the way of that. */
fieldset {
    border: 0;
    margin: 0;
    padding: 0;
    min-inline-size: 0;
}

legend { padding: 0; }

:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: 3px;
}

/* Visible only to screen readers, and to keyboard users when focused. */
.sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

.skip-link {
    position: absolute;
    left: 0.5rem;
    top: -3rem;
    z-index: 100;
    background: var(--surface);
    color: var(--text);
    padding: .6rem 1rem;
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow);
    transition: top .15s ease;
}
.skip-link:focus { top: .5rem; }

/* --------------------------------------------------------------------------
   3. Layout
   -------------------------------------------------------------------------- */

.wrap {
    width: 100%;
    max-width: 62rem;
    margin: 0 auto;
    padding-inline: var(--gutter);
}

.wrap--narrow { max-width: 44rem; }
.wrap--wide { max-width: 76rem; }

main { flex: 1 0 auto; }

.stack > * + * { margin-top: var(--stack-gap, 1rem); }

/* --------------------------------------------------------------------------
   4. Site header
   -------------------------------------------------------------------------- */

.masthead {
    border-bottom: 1px solid var(--line);
    background: color-mix(in srgb, var(--surface) 82%, transparent);
    backdrop-filter: saturate(180%) blur(12px);
    position: sticky;
    top: 0;
    z-index: 40;
}

.masthead__inner {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    min-height: 60px;
}

.wordmark {
    font-family: var(--font-serif);
    font-size: 1.15rem;
    font-weight: 500;
    letter-spacing: -0.01em;
    color: var(--text);
    text-decoration: none;
    white-space: nowrap;
}
.wordmark:hover { color: var(--text); }

.nav {
    display: flex;
    align-items: center;
    gap: .25rem;
    margin-left: auto;
    flex-wrap: wrap;
}

.nav a, .nav button {
    font: inherit;
    font-size: .875rem;
    color: var(--text-2);
    text-decoration: none;
    padding: .4rem .7rem;
    border-radius: var(--radius-sm);
    border: 0;
    background: none;
    cursor: pointer;
    white-space: nowrap;
    transition: background .12s ease, color .12s ease;
}

.nav a:hover, .nav button:hover { background: var(--surface-2); color: var(--text); }
.nav a[aria-current="page"] { color: var(--text); background: var(--surface-2); font-weight: 500; }

.nav__divider {
    width: 1px;
    height: 20px;
    background: var(--line);
    margin-inline: .35rem;
}

/* --------------------------------------------------------------------------
   5. Page furniture
   -------------------------------------------------------------------------- */

.page-head {
    padding-block: clamp(2rem, 6vw, 3.5rem) 1.5rem;
}

.page-head__eyebrow {
    font-size: .75rem;
    text-transform: uppercase;
    letter-spacing: .09em;
    color: var(--muted);
    font-weight: 600;
    margin-bottom: .6rem;
}

.page-head h1 {
    font-family: var(--font-serif);
    font-size: clamp(1.85rem, 5vw, 2.6rem);
    font-weight: 500;
    letter-spacing: -0.02em;
}

.page-head__lede {
    color: var(--muted);
    font-size: 1.0625rem;
    max-width: var(--measure);
    margin-top: .75rem;
}

.site-footer {
    margin-top: 4rem;
    padding-block: 2rem;
    border-top: 1px solid var(--line);
    color: var(--muted);
    font-size: .8125rem;
}

.site-footer__inner {
    display: flex;
    gap: 1rem;
    justify-content: space-between;
    flex-wrap: wrap;
}

/* --------------------------------------------------------------------------
   6. Cards and detail lists
   -------------------------------------------------------------------------- */

.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 20rem), 1fr));
    gap: 1.25rem;
    align-items: start;
}

.card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
    /* Detail rows respond to the width of their own card, not the viewport,
       so a narrow card in a wide grid still stacks its rows correctly. */
    container-type: inline-size;
}

.card__head {
    display: flex;
    align-items: flex-start;
    gap: .75rem;
    padding: 1.15rem 1.25rem .9rem;
    border-bottom: 1px solid var(--line);
}

.card__icon {
    flex: none;
    width: 34px;
    height: 34px;
    display: grid;
    place-items: center;
    border-radius: 9px;
    background: var(--accent-bg);
    color: var(--accent);
}

.card__icon svg { width: 18px; height: 18px; }

.card__title {
    font-size: 1rem;
    font-weight: 600;
    letter-spacing: -0.005em;
}

.card__subtitle {
    font-size: .8125rem;
    color: var(--muted);
    margin-top: .15rem;
    line-height: 1.45;
}

/* A row of detail: label above, value below, action on the right. */
.detail-list { list-style: none; margin: 0; padding: 0; }

.detail {
    display: flex;
    align-items: baseline;
    gap: 1rem;
    padding: .8rem 1.25rem;
    border-bottom: 1px solid var(--line);
}

.detail:last-child { border-bottom: 0; }

.detail__label {
    font-size: .8125rem;
    color: var(--muted);
    flex: none;
    width: 8.5rem;
    line-height: 1.5;
}

.detail__body { min-width: 0; flex: 1; }

.detail__value {
    font-size: .9375rem;
    /* break-word only as a last resort, so an email address is not split
       mid-word while there is still a sensible place to wrap. */
    overflow-wrap: break-word;
    line-height: 1.5;
}

.detail__value a { font-weight: 500; }

.detail__note {
    font-size: .8125rem;
    color: var(--muted);
    margin-top: .15rem;
}

.detail--private { background: color-mix(in srgb, var(--accent-bg) 45%, transparent); }

@container (max-width: 25rem) {
    .detail { display: block; padding-inline: 1.1rem; }
    .detail__label { width: auto; margin-bottom: .1rem; }
    .copy { margin-top: .35rem; }
}

/* Fallback for browsers without container queries. */
@supports not (container-type: inline-size) {
    .detail__label { width: 7rem; }
}

/* Copy-to-clipboard control on a detail row. */
.copy {
    flex: none;
    font: inherit;
    font-size: .75rem;
    color: var(--muted);
    background: none;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    padding: .2rem .5rem;
    cursor: pointer;
    opacity: 0;
    transition: opacity .12s ease, color .12s ease, border-color .12s ease;
}

.detail:hover .copy, .copy:focus-visible { opacity: 1; }
.copy:hover { color: var(--text); border-color: var(--line-strong); }
.copy[data-copied="true"] { color: var(--success); border-color: var(--success); opacity: 1; }

@media (hover: none) {
    .copy { opacity: 1; }
}

/* A section's dated history, listed under its plain details. Sits inside the
   same card, so it borrows the card's padding rather than setting its own. */
.log {
    border-top: 1px solid var(--line);
    padding: .85rem 1.25rem 1rem;
}

.log__heading {
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--muted);
    margin: 0 0 .6rem;
}

.log__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: .55rem;
}

.log__entry {
    display: flex;
    align-items: baseline;
    gap: 1rem;
    border-radius: var(--radius-sm);
}

/* The date column is fixed so the entries read as a column of dates with
   detail beside them, rather than a ragged left edge. */
.log__date {
    flex: none;
    width: 6.75rem;
    font-size: .75rem;
    font-variant-numeric: tabular-nums;
    color: var(--muted);
    line-height: 1.5;
}

.log__body { min-width: 0; flex: 1; }

.log__label {
    display: block;
    font-size: .875rem;
    line-height: 1.45;
}

.log__value {
    display: block;
    font-size: .875rem;
    color: var(--muted);
    overflow-wrap: break-word;
    line-height: 1.45;
}

.log__note {
    display: block;
    font-size: .75rem;
    color: var(--muted);
    margin-top: .1rem;
}

.log__entry--private {
    background: color-mix(in srgb, var(--accent-bg) 45%, transparent);
    padding: .35rem .5rem;
    margin: -.35rem -.5rem;
}

@container (max-width: 25rem) {
    .log { padding-inline: 1.1rem; }
    .log__entry { display: block; }
    .log__date { width: auto; margin-bottom: .1rem; }
}

@supports not (container-type: inline-size) {
    .log__date { width: 6rem; }
}

/* Things with an expiry date, soonest first. Overdue rows are marked with a
   colour and a rule rather than colour alone, so the distinction survives
   being read by someone who cannot separate the two hues. */
.renewal-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: .4rem;
}

.renewal {
    display: flex;
    align-items: baseline;
    gap: 1rem;
    padding: .7rem .9rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface);
}

.renewal__date {
    flex: none;
    width: 7rem;
    font-size: .8125rem;
    font-variant-numeric: tabular-nums;
    color: var(--muted);
    line-height: 1.5;
}

.renewal__body { min-width: 0; flex: 1; }

.renewal__label {
    display: block;
    font-size: .9375rem;
    line-height: 1.45;
}

.renewal__section,
.renewal__note {
    display: block;
    font-size: .8125rem;
    color: var(--muted);
    margin-top: .1rem;
}

.renewal--overdue {
    border-color: var(--danger);
    background: var(--danger-bg);
}

.renewal--overdue .renewal__date {
    color: var(--danger);
    font-weight: 600;
}

.renewal--private { border-left: 3px solid var(--accent); }

/* Unlike a detail row, a renewal is a page-level list item rather than
   something inside a card, so it has no container to query — it is as wide as
   the page. That makes the viewport the right axis here. */
@media (max-width: 34rem) {
    .renewal { display: block; }
    .renewal__date { width: auto; margin-bottom: .15rem; }
}

/* --------------------------------------------------------------------------
   7. Badges
   -------------------------------------------------------------------------- */

.badge {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .03em;
    text-transform: uppercase;
    padding: .18rem .45rem;
    border-radius: 5px;
    border: 1px solid var(--line-strong);
    color: var(--muted);
    background: var(--surface-2);
    white-space: nowrap;
    line-height: 1.5;
}

.badge--tier-2 { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 40%, transparent); background: var(--accent-bg); }
.badge--tier-0 { color: var(--muted); }
.badge--draft { color: var(--muted); border-style: dashed; }
.badge--warn { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 45%, transparent); background: var(--accent-bg); cursor: help; }
.badge--danger { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 40%, transparent); background: var(--danger-bg); }
.badge--success { color: var(--success); border-color: color-mix(in srgb, var(--success) 40%, transparent); background: var(--success-bg); }

/* --------------------------------------------------------------------------
   8. Buttons
   -------------------------------------------------------------------------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .45rem;
    font: inherit;
    font-size: .9375rem;
    font-weight: 500;
    line-height: 1.2;
    padding: .62rem 1.1rem;
    border-radius: var(--radius);
    border: 1px solid var(--line-strong);
    background: var(--surface);
    color: var(--text);
    text-decoration: none;
    cursor: pointer;
    transition: background .12s ease, border-color .12s ease, color .12s ease, transform .06s ease;
    white-space: nowrap;
}

.btn:hover { background: var(--surface-2); color: var(--text); border-color: var(--muted); }
.btn:active { transform: translateY(1px); }

.btn--primary {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}
.btn--primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); color: #fff; }

@media (prefers-color-scheme: dark) {
    .btn--primary { color: #1a1611; }
    .btn--primary:hover { color: #1a1611; }
}

.btn--ghost { background: none; border-color: transparent; color: var(--text-2); }
.btn--ghost:hover { background: var(--surface-2); border-color: transparent; }

.btn--danger { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 35%, transparent); }
.btn--danger:hover { background: var(--danger-bg); border-color: var(--danger); color: var(--danger); }

.btn--sm { font-size: .8125rem; padding: .38rem .7rem; border-radius: var(--radius-sm); }
.btn--block { width: 100%; }

.btn svg { width: 16px; height: 16px; }

.btn-row {
    display: flex;
    gap: .6rem;
    flex-wrap: wrap;
    align-items: center;
}

.btn-row--end { justify-content: flex-end; }

/* --------------------------------------------------------------------------
   9. Forms
   -------------------------------------------------------------------------- */

.form { --stack-gap: 1.15rem; }

/* Only the field's own label, never a component label nested inside it.
   `.field label` would out-specify `.checkbox` and `.tier-option` and force
   those flex layouts back to block. */
.field > label:not(.checkbox),
.field > .field__label {
    display: block;
    font-size: .875rem;
    font-weight: 500;
    margin-bottom: .35rem;
    color: var(--text);
}

.field__hint {
    font-size: .8125rem;
    color: var(--muted);
    margin-top: .3rem;
    line-height: 1.45;
}

/* Hints for each option of a select, where one line under the control cannot
   explain what the choices actually do. */
.field__hints {
    font-size: .8125rem;
    color: var(--muted);
    line-height: 1.45;
    margin: .4rem 0 0;
    padding-left: 1.1rem;
    display: grid;
    gap: .25rem;
}

.field__hints strong { color: var(--text); font-weight: 500; }

/* A multi-line example inside a hint, shown as typed. */
.field__example {
    display: block;
    margin: .25rem 0;
    padding: .4rem .6rem;
    white-space: pre;
    overflow-x: auto;
    color: var(--text);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
}

input[type="text"],
input[type="email"],
input[type="password"],
input[type="number"],
input[type="url"],
input[type="search"],
input[type="date"],
select,
textarea {
    width: 100%;
    font: inherit;
    font-size: .9375rem;
    color: var(--text);
    background: var(--surface);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    padding: .6rem .75rem;
    transition: border-color .12s ease, box-shadow .12s ease;
    appearance: none;
}

textarea {
    min-height: 9rem;
    resize: vertical;
    line-height: 1.6;
}

/* A date input keeps its native picker; only the indicator needs nudging so
   it does not sit as a dark glyph on a dark field. */
input[type="date"] { min-height: 2.6rem; }
input[type="date"]::-webkit-calendar-picker-indicator { opacity: .55; cursor: pointer; }
input[type="date"]:hover::-webkit-calendar-picker-indicator { opacity: 1; }

@media (prefers-color-scheme: dark) {
    input[type="date"]::-webkit-calendar-picker-indicator { filter: invert(1); }
}

textarea.textarea--tall { min-height: 32rem; font-family: var(--font-mono); font-size: .875rem; }

select {
    background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%),
                      linear-gradient(135deg, var(--muted) 50%, transparent 50%);
    background-position: calc(100% - 18px) 52%, calc(100% - 13px) 52%;
    background-size: 5px 5px, 5px 5px;
    background-repeat: no-repeat;
    padding-right: 2.25rem;
}

input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}

input[aria-invalid="true"], select[aria-invalid="true"], textarea[aria-invalid="true"] {
    border-color: var(--danger);
}

.field__error {
    display: block;
    font-size: .8125rem;
    color: var(--danger);
    margin-top: .35rem;
    font-weight: 500;
}

.checkbox {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
    cursor: pointer;
}

.checkbox input[type="checkbox"] {
    appearance: none;
    flex: none;
    width: 18px;
    height: 18px;
    margin-top: 2px;
    border: 1px solid var(--line-strong);
    border-radius: 4px;
    background: var(--surface);
    cursor: pointer;
    position: relative;
    transition: background .12s ease, border-color .12s ease;
}

.checkbox input[type="checkbox"]:checked {
    background: var(--accent);
    border-color: var(--accent);
}

.checkbox input[type="checkbox"]:checked::after {
    content: "";
    position: absolute;
    left: 5px; top: 1px;
    width: 5px; height: 10px;
    border: solid var(--on-accent);
    border-width: 0 2px 2px 0;
    transform: rotate(42deg);
}

.checkbox__text { display: block; font-size: .9rem; line-height: 1.45; }
.checkbox__text small { display: block; color: var(--muted); font-size: .8125rem; }

.field-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
    gap: 1.15rem;
}

/* Radio cards used for choosing an access tier. */
.tier-choice { display: grid; gap: .6rem; }

.tier-option {
    display: flex;
    align-items: flex-start;
    gap: .7rem;
    padding: .8rem .9rem;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    cursor: pointer;
    background: var(--surface);
    transition: border-color .12s ease, background .12s ease;
}

.tier-option:hover { border-color: var(--muted); }

.tier-option input {
    appearance: none;
    flex: none;
    width: 16px; height: 16px;
    margin-top: 4px;
    border: 1px solid var(--line-strong);
    border-radius: 50%;
    position: relative;
    cursor: pointer;
}

.tier-option input:checked {
    border-color: var(--accent);
    border-width: 5px;
}

.tier-option:has(input:checked) {
    border-color: var(--accent);
    background: color-mix(in srgb, var(--accent-bg) 55%, var(--surface));
}

.tier-option__name { display: block; font-weight: 600; font-size: .9rem; }
.tier-option__desc { display: block; font-size: .8125rem; color: var(--muted); line-height: 1.45; }

/* --------------------------------------------------------------------------
   10. Notices
   -------------------------------------------------------------------------- */

.notice {
    display: flex;
    align-items: flex-start;
    gap: .7rem;
    padding: .85rem 1rem;
    border-radius: var(--radius);
    border: 1px solid var(--line-strong);
    background: var(--surface-2);
    font-size: .9rem;
    line-height: 1.5;
}

.notice svg { flex: none; width: 18px; height: 18px; margin-top: 2px; }

.notice--success { color: var(--success); background: var(--success-bg); border-color: color-mix(in srgb, var(--success) 30%, transparent); }
.notice--error { color: var(--danger); background: var(--danger-bg); border-color: color-mix(in srgb, var(--danger) 30%, transparent); }
.notice--accent { color: var(--accent); background: var(--accent-bg); border-color: color-mix(in srgb, var(--accent) 30%, transparent); }

.notice a { color: inherit; }

.flash-stack { --stack-gap: .6rem; margin-block: 1.25rem; }

/* Panel showing a freshly generated invite link. */
.invite-panel {
    border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
    background: var(--accent-bg);
    border-radius: var(--radius-lg);
    padding: 1.15rem 1.25rem;
    margin-block: 1.25rem;
}

.invite-panel__title { font-weight: 600; font-size: .95rem; margin-bottom: .3rem; }
.invite-panel__hint { font-size: .85rem; color: var(--text-2); margin-bottom: .8rem; }

.invite-link {
    display: flex;
    gap: .5rem;
    align-items: stretch;
}

.invite-link input {
    font-family: var(--font-mono);
    font-size: .8125rem;
    background: var(--surface);
}

/* --------------------------------------------------------------------------
   11. Tables
   -------------------------------------------------------------------------- */

.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

.table {
    width: 100%;
    border-collapse: collapse;
    font-size: .9rem;
}

.table th {
    text-align: left;
    font-size: .75rem;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--muted);
    font-weight: 600;
    padding: .6rem .8rem;
    border-bottom: 1px solid var(--line-strong);
    white-space: nowrap;
}

.table td {
    padding: .8rem;
    border-bottom: 1px solid var(--line);
    vertical-align: middle;
}

.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr:hover { background: var(--surface-2); }

.table__name { font-weight: 600; }
.table__sub { font-size: .8125rem; color: var(--muted); }
.table__actions { text-align: right; white-space: nowrap; }

.table--inset {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

.table--inset th { background: var(--surface-2); }

/* --------------------------------------------------------------------------
   12. Empty states
   -------------------------------------------------------------------------- */

.empty {
    text-align: center;
    padding: 3rem 1.5rem;
    border: 1px dashed var(--line-strong);
    border-radius: var(--radius-lg);
    color: var(--muted);
    background: var(--surface);
}

.empty h3 { font-size: 1.05rem; color: var(--text); margin-bottom: .4rem; font-weight: 600; }
.empty p { max-width: 34rem; margin-inline: auto; font-size: .9rem; }
.empty .btn { margin-top: 1.15rem; }

/* --------------------------------------------------------------------------
   13. The landing door
   -------------------------------------------------------------------------- */

.door {
    min-height: 100vh;
    min-height: 100dvh;
    display: grid;
    place-items: center;
    padding: 2rem var(--gutter);
    background: #100e0c;
    color: #ece6db;
    position: relative;
    isolation: isolate;
}

/* A slow warm wash behind the name, so the page is not a flat black slab. */
.door::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background:
        radial-gradient(58rem 30rem at 50% -8%, rgba(201, 162, 74, .11), transparent 68%),
        radial-gradient(40rem 26rem at 88% 104%, rgba(120, 132, 168, .09), transparent 70%);
}

.door__inner {
    width: 100%;
    max-width: 24rem;
    text-align: center;
}

.door__name {
    font-family: var(--font-serif);
    font-size: clamp(2rem, 8vw, 3rem);
    font-weight: 400;
    letter-spacing: -0.025em;
    line-height: 1.1;
    color: #f4efe5;
}

.door__rule {
    width: 2.5rem;
    height: 1px;
    background: rgba(216, 181, 99, .55);
    margin: 1.5rem auto;
    border: 0;
}

.door__tagline {
    color: #9c9285;
    font-size: .9375rem;
    line-height: 1.6;
    margin-bottom: 2.25rem;
}

.door__form { text-align: left; --stack-gap: 1rem; }

.door__form label {
    color: #cfc6b8;
    font-size: .8125rem;
    font-weight: 500;
}

.door__form input[type="text"],
.door__form input[type="email"],
.door__form input[type="password"] {
    background: rgba(255, 255, 255, .045);
    border-color: rgba(255, 255, 255, .13);
    color: #f0ebe2;
    padding: .7rem .85rem;
}

.door__form input::placeholder { color: #6d655b; }

.door__form input:focus {
    border-color: rgba(216, 181, 99, .75);
    box-shadow: 0 0 0 3px rgba(216, 181, 99, .16);
    background: rgba(255, 255, 255, .06);
}

.door__form .btn--primary {
    background: #d8b563;
    border-color: #d8b563;
    color: #17140f;
    padding: .7rem 1.1rem;
    font-weight: 600;
}

.door__form .btn--primary:hover { background: #e8c779; border-color: #e8c779; color: #17140f; }

.door__form .checkbox__text { color: #b3aa9c; font-size: .85rem; }

.door__form .checkbox input[type="checkbox"] {
    background: rgba(255, 255, 255, .05);
    border-color: rgba(255, 255, 255, .18);
}

.door__form .checkbox input[type="checkbox"]:checked { background: #d8b563; border-color: #d8b563; }
.door__form .checkbox input[type="checkbox"]:checked::after { border-color: #17140f; }

.door .notice {
    background: rgba(255, 255, 255, .05);
    border-color: rgba(255, 255, 255, .12);
    color: #cfc6b8;
    text-align: left;
}

.door .notice--error {
    color: #f0a49c;
    background: rgba(163, 49, 42, .14);
    border-color: rgba(232, 131, 124, .3);
}

.door .field__error { color: #f0a49c; }

.door__foot {
    margin-top: 2.25rem;
    font-size: .8125rem;
    color: #6d655b;
    line-height: 1.6;
}

.door__foot a { color: #9c9285; }
.door__foot a:hover { color: #cfc6b8; }

/* The door is also used for the setup, invite and error pages, which need a
   wider column than a bare login form. */
.door__inner--wide { max-width: 34rem; text-align: left; }
.door__inner--wide .door__rule { margin-inline: 0; }

/* --------------------------------------------------------------------------
   14. Admin
   -------------------------------------------------------------------------- */

.admin-nav {
    display: flex;
    gap: .25rem;
    border-bottom: 1px solid var(--line);
    margin-bottom: 2rem;
    overflow-x: auto;
    scrollbar-width: none;
}

.admin-nav::-webkit-scrollbar { display: none; }

.admin-nav a {
    font-size: .9rem;
    color: var(--muted);
    text-decoration: none;
    padding: .65rem .85rem;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    white-space: nowrap;
    transition: color .12s ease, border-color .12s ease;
}

.admin-nav a:hover { color: var(--text); }

.admin-nav a[aria-current="page"] {
    color: var(--text);
    border-bottom-color: var(--accent);
    font-weight: 500;
}

.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr));
    gap: 1rem;
}

.stat {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: 1.1rem 1.2rem;
}

.stat__value {
    font-family: var(--font-serif);
    font-size: 2rem;
    line-height: 1;
    font-weight: 500;
    letter-spacing: -0.02em;
}

.stat__label {
    font-size: .8125rem;
    color: var(--muted);
    margin-top: .45rem;
}

.stat--alert .stat__value { color: var(--danger); }

.section-block {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    overflow: hidden;
    scroll-margin-top: 5rem;
}

.section-block__head {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: .9rem 1.15rem;
    background: var(--surface-2);
    border-bottom: 1px solid var(--line);
    flex-wrap: wrap;
}

.section-block__title { font-weight: 600; font-size: .95rem; }
.section-block__meta { margin-left: auto; display: flex; gap: .4rem; align-items: center; flex-wrap: wrap; }

.section-block--hidden { opacity: .62; }

.admin-item {
    display: flex;
    align-items: center;
    gap: .85rem;
    padding: .7rem 1.15rem;
    border-bottom: 1px solid var(--line);
    flex-wrap: wrap;
}

.admin-item:last-child { border-bottom: 0; }
.admin-item__label { font-weight: 500; font-size: .9rem; min-width: 8rem; }
.admin-item__value { color: var(--muted); font-size: .875rem; flex: 1; min-width: 0; word-break: break-word; }
.admin-item__value em { color: var(--line-strong); font-style: normal; }
.admin-item__actions { margin-left: auto; display: flex; gap: .35rem; align-items: center; }

.admin-item--draft .admin-item__label { color: var(--muted); font-weight: 400; }

.section-block__foot {
    padding: .7rem 1.15rem;
    background: var(--surface-2);
    border-top: 1px solid var(--line);
}

.form-panel {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: clamp(1.25rem, 4vw, 2rem);
    box-shadow: var(--shadow-sm);
}

.form-panel + .form-panel { margin-top: 1.5rem; }

.form-panel__title {
    font-size: 1.05rem;
    font-weight: 600;
    margin-bottom: .35rem;
}

.form-panel__desc {
    font-size: .875rem;
    color: var(--muted);
    margin-bottom: 1.5rem;
}

.form-actions {
    display: flex;
    gap: .6rem;
    align-items: center;
    flex-wrap: wrap;
    margin-top: 1.75rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--line);
}

.form-actions__spacer { margin-left: auto; }

/* Inline single-button forms, used for the destructive row actions. */
.inline-form { display: inline; }

.activity-row td { font-size: .875rem; }
.activity-row--security td:nth-child(2) { color: var(--danger); font-weight: 500; }

.pagination {
    display: flex;
    gap: .5rem;
    align-items: center;
    justify-content: center;
    margin-top: 1.5rem;
    font-size: .875rem;
    color: var(--muted);
}

/* --------------------------------------------------------------------------
   15. Prose
   -------------------------------------------------------------------------- */

.prose {
    max-width: var(--measure);
    font-size: 1.0625rem;
    line-height: 1.7;
    color: var(--text-2);
}

.prose h2 {
    font-family: var(--font-serif);
    font-size: 1.4rem;
    font-weight: 500;
    color: var(--text);
    margin: 2.25rem 0 .75rem;
    letter-spacing: -0.015em;
}

.prose h2:first-child { margin-top: 0; }
.prose p { margin-bottom: 1.15em; }
.prose a { font-weight: 500; }

.prose ul { padding-left: 1.25rem; margin: 0 0 1.15em; }
.prose li { margin-bottom: .35em; }

/* Quotations and callouts. A callout is a tinted panel whose kind is stated
   by its label, so the colour only repeats what the words already say. */
.prose blockquote {
    margin: 0 0 1.15em;
    padding: .1rem 0 .1rem 1.1rem;
    border-left: 3px solid var(--line-strong);
    color: var(--muted);
}

.prose .callout {
    margin: 0 0 1.15em;
    padding: .85rem 1.1rem;
    border-left: 5px solid var(--callout);
    border-radius: var(--radius-sm);
    background: var(--callout-bg);
    color: var(--text);
}

.prose blockquote > :last-child,
.prose .callout > :last-child { margin-bottom: 0; }

.prose .callout__label {
    margin-bottom: .3rem;
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--callout);
}

.callout--info { --callout: var(--info); --callout-bg: var(--info-bg); }
.callout--success { --callout: var(--success); --callout-bg: var(--success-bg); }
.callout--warning { --callout: var(--warning); --callout-bg: var(--warning-bg); }
.callout--danger { --callout: var(--danger); --callout-bg: var(--danger-bg); }

/* Numbered lists, nested lists and checklists. */
.prose ol { padding-left: 1.5rem; margin: 0 0 1.15em; }
.prose li > ul,
.prose li > ol { margin: .35em 0 0; }

/* A checklist swaps the bullet for the box, so the box sits where the bullet
   was. The direct-child selectors keep a plain list nested inside an entry
   looking like a plain list. */
.prose .checklist { list-style: none; padding-left: 0; }
.prose .checklist > li > label { display: block; position: relative; padding-left: calc(18px + .6rem); }
.prose .checklist > li > ul,
.prose .checklist > li > ol { margin-left: calc(18px + .6rem); }

/* An ordinary item among the boxes keeps a bullet, with its text in line
   with theirs. */
.prose .checklist > .checklist__plain { list-style: disc; margin-left: calc(18px + .6rem); }

/* Drawn by hand, as the form checkbox is, because a browser greys a disabled
   native box and ignores the accent colour on it. */
.prose .checklist input[type="checkbox"] {
    appearance: none;
    position: absolute;
    left: 0;
    top: .3em;
    width: 18px;
    height: 18px;
    margin: 0;
    border: 1px solid var(--line-strong);
    border-radius: 4px;
    background: var(--surface);
}

.prose .checklist input[type="checkbox"]:checked {
    background: var(--accent);
    border-color: var(--accent);
}

.prose .checklist input[type="checkbox"]:checked::after {
    content: "";
    position: absolute;
    left: 5px; top: 1px;
    width: 5px; height: 10px;
    border: solid var(--on-accent);
    border-width: 0 2px 2px 0;
    transform: rotate(42deg);
}

/* Headings below the first level, text styles, code and rules. The sizes
   step down from the h2 above, and the last two levels change face as well
   as size so they still read as headings at body size. */
.prose h3 {
    font-family: var(--font-serif);
    font-size: 1.2rem;
    font-weight: 500;
    color: var(--text);
    margin: 1.9rem 0 .6rem;
    letter-spacing: -0.01em;
}

.prose h4 {
    font-size: 1.0625rem;
    font-weight: 600;
    color: var(--text);
    margin: 1.6rem 0 .5rem;
}

.prose h5 {
    font-size: .8125rem;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--muted);
    margin: 1.4rem 0 .45rem;
}

.prose h3:first-child,
.prose h4:first-child,
.prose h5:first-child { margin-top: 0; }

.prose s { color: var(--muted); }

.prose code {
    font-family: var(--font-mono);
    font-size: .875em;
    color: var(--text);
    background: var(--surface-2);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    padding: .1em .35em;
    /* A long reference number wraps instead of widening the page. */
    overflow-wrap: anywhere;
}

/* A long line scrolls inside the block, so the page never grows sideways. */
.prose pre {
    margin: 0 0 1.15em;
    padding: .9rem 1.1rem;
    background: var(--surface-2);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    font-size: .875rem;
    line-height: 1.55;
    overflow-x: auto;
    /* Without this the scrollbar is the browser's light one in dark mode. */
    scrollbar-color: var(--line-strong) transparent;
    tab-size: 4;
}

.prose pre code {
    font-size: inherit;
    background: none;
    border: 0;
    border-radius: 0;
    padding: 0;
    overflow-wrap: normal;
}

.prose hr { margin: 2.25rem 0; }

/* Tables. The box scrolls sideways so a wide table never widens the page. */
.prose-table {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    margin: 0 0 1.15em;
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
}

.prose-table table {
    width: 100%;
    border-collapse: collapse;
    font-size: .9375rem;
    line-height: 1.5;
}

.prose-table th,
.prose-table td {
    padding: .6rem .8rem;
    text-align: left;
    vertical-align: top;
    border-bottom: 1px solid var(--line);
}

.prose-table th {
    background: var(--surface-2);
    color: var(--text);
    font-weight: 600;
    border-bottom-color: var(--line-strong);
}

.prose-table tbody tr:last-child td { border-bottom: 0; }

.prose-table .align-left { text-align: left; }
.prose-table .align-center { text-align: center; }
.prose-table .align-right { text-align: right; }

/* The Prose template's page layout and its "On this page" list.

   The body is capped at a line length whether or not there is a list, so a
   page with no list has no second column and no gap where one would be. The
   list comes first in the markup, which is where a phone shows it. */
.prose-page .prose { max-width: 85ch; }

/* A link to a heading must not land it under the sticky masthead. */
.prose [id] { scroll-margin-top: 5rem; }

.prose-contents {
    margin-bottom: 1.75rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    font-size: .9375rem;
}

.prose-contents summary {
    padding: .7rem 1rem;
    font-weight: 600;
    color: var(--text);
    cursor: pointer;
}

.prose-contents ul {
    list-style: none;
    margin: 0;
    padding: 0 1rem .8rem;
}

.prose-contents li { margin-top: .4rem; }
.prose-contents .prose-contents__level-2 { padding-left: 1rem; }

.prose-contents a {
    color: var(--text-2);
    text-decoration: none;
    overflow-wrap: anywhere;
}

.prose-contents a:hover { color: var(--accent); text-decoration: underline; }

/* Wide enough for two columns. site.js opens and closes the list at this
   same width, so change the two together. */
@media (min-width: 64rem) {
    .prose-page--contents {
        display: grid;
        /* The first column takes what is left and the body caps itself
           inside it. A cap written here would be measured in this element's
           smaller type and come out short. */
        grid-template-columns: minmax(0, 1fr) 16rem;
        align-items: start;
        column-gap: 3rem;
    }

    .prose-contents {
        grid-column: 2;
        grid-row: 1;
        position: sticky;
        top: 5rem;
        max-height: calc(100vh - 6.5rem);
        overflow-y: auto;
        margin-bottom: 0;
        border-width: 0 0 0 1px;
        border-radius: 0;
        background: none;
    }

    .prose-page .prose { grid-column: 1; grid-row: 1; }

    /* Here the summary is the sidebar's title and no longer a control,
       because a sidebar that folds away has nothing to fold into. */
    .prose-contents summary {
        padding-block: 0 .35rem;
        list-style: none;
        pointer-events: none;
        font-size: .75rem;
        text-transform: uppercase;
        letter-spacing: .09em;
        color: var(--muted);
    }

    .prose-contents summary::-webkit-details-marker { display: none; }
    .prose-contents ul { padding-bottom: 0; }
}

/* --------------------------------------------------------------------------
   16. Utilities

   A deliberately tiny set. The content security policy forbids inline style
   attributes, so the handful of one-off spacing adjustments the templates
   need live here as classes.
   -------------------------------------------------------------------------- */

.mt-0 { margin-top: 0; }
.mt-sm { margin-top: .75rem; }
.mt { margin-top: 1.25rem; }
.mt-lg { margin-top: 2rem; }
.mb-sm { margin-bottom: .75rem; }
.mb { margin-bottom: 1.25rem; }
.mb-lg { margin-bottom: 2rem; }
.mb-xl { margin-bottom: 3rem; }

.text-muted { color: var(--muted); }
.text-sm { font-size: .875rem; }
.text-center { text-align: center; }
.font-mono { font-family: var(--font-mono); }

.section-gap { padding-bottom: clamp(2.5rem, 6vw, 4rem); }
