/* ===============================================================
   HOUSE — "JOB SITE"
   ---------------------------------------------------------------
   Same lineage as cars' WORKSHOP WEB (Tom Sachs / Van Neistat):
   square corners, hard 2px rules, block shadows, stencil + mono,
   mechanical motion, label everything, no gradients or glass.

   Different TRADE, so a different material palette. cars is the
   workbench — birch, plywood, warm paper. house is the job site —
   concrete, asphalt, hi-vis, safety orange.

   The palette is also a functional choice: this app is used
   outdoors, one-handed, in daylight. Hi-vis yellow-green on
   asphalt is the highest-legibility pairing in existence and it is
   spent on exactly one thing — the capture button.

   80 / 15 / 5:
     80%  concrete + slab (ground and surfaces)
     15%  asphalt (rules, type, structure)
      5%  paint (hi-vis / orange / caution / red) — EARNED by
          actions and problems only. A healthy row wears no color.
   =============================================================== */

:root {
    /* materials */
    --concrete: #C9C6BE;   /* page ground — poured slab */
    --slab: #E2DFD8;       /* raised surface — cards, sheets */
    --asphalt: #1C1C1A;    /* ink + structure (never pure #000) */
    /* Was #6E6C66 — measured 3.95:1 on slab for .field-label / .row-meta,
       which are small uppercase text. This clears 4.5:1 on all three light
       grounds (concrete, slab, chalk) and still reads as clearly secondary
       against asphalt ink. */
    --steel: #545249;      /* muted / secondary type ON LIGHT surfaces */
    /* Muted type on ASPHALT needs its own value: --steel measures 3.25:1
       there, under the 4.5 minimum, and these are small uppercase labels read
       outdoors. This clears 6:1 while still reading as "not the active one". */
    --steel-lt: #9C9A92;
    --chalk: #F2F0EB;      /* the lightest surface (never pure #FFF) */

    /* paint — the 5% */
    --hivis: #D8F000;      /* PRIMARY ACTION. Safety vest. One job: capture. */
    --orange: #FF6A00;     /* safety orange — high priority, links */
    --caution: #F2C230;    /* hazard yellow — due soon, queued work */
    /* Darkened from #D92B1F: chalk-on-red measured 4.27:1, under the 4.5
       minimum. This clears it at 4.8:1 without reading as a different red. */
    --red: #CE2418;        /* overdue, destructive */

    /* geometry */
    --border: 2px solid var(--asphalt);
    --rule: 2px;
    --radius: 0;
    --unit: 8px;
    --shadow-block: 4px 4px 0 var(--asphalt);
    --shadow-block-sm: 3px 3px 0 var(--asphalt);

    /* type */
    --font-display: 'Oswald', 'Archivo Narrow', system-ui, sans-serif;
    --font-body: 'IBM Plex Mono', 'Courier Prime', ui-monospace, monospace;
    --font-note: 'Permanent Marker', cursive; /* max 2 uses per screen */

    /* motion — a relay clicking, never a glide */
    --snap: 110ms linear;

    /* Large density: read at arm's length, tapped possibly in gloves.
       Not a taste call — the app is used outdoors. */
    --row-min: 68px;
    --tap-min: 48px;
}

/* ===============================================================
   Pico v2 overrides — flip the classless base onto this system
   =============================================================== */
:root {
    --pico-background-color: var(--concrete);
    --pico-color: var(--asphalt);
    --pico-h1-color: var(--asphalt);
    --pico-h2-color: var(--asphalt);
    --pico-h3-color: var(--asphalt);
    --pico-h4-color: var(--asphalt);
    --pico-muted-color: var(--steel);
    --pico-card-background-color: var(--slab);
    --pico-card-sectioning-background-color: var(--slab);
    --pico-form-element-background-color: var(--chalk);
    --pico-form-element-color: var(--asphalt);
    --pico-form-element-border-color: var(--asphalt);
    --pico-form-element-placeholder-color: var(--steel);
    --pico-muted-border-color: var(--asphalt);

    --pico-primary: var(--asphalt);
    --pico-primary-hover: var(--asphalt);
    --pico-primary-background: var(--hivis);
    --pico-primary-border: var(--asphalt);
    --pico-primary-inverse: var(--asphalt);
    --pico-secondary: var(--asphalt);
    --pico-secondary-background: var(--slab);
    --pico-del-color: var(--red);

    --pico-border-radius: 0;
    --pico-border-width: 2px;
    --pico-border-color: var(--asphalt);
    --pico-outline-width: 2px;
    --pico-box-shadow: var(--shadow-block);
    --pico-card-box-shadow: var(--shadow-block);

    --pico-font-family: var(--font-body);
    --pico-font-family-sans-serif: var(--font-body);
    --pico-font-family-monospace: var(--font-body);
    --pico-line-height: 1.45;
    --pico-spacing: calc(var(--unit) * 2);
    --pico-primary-focus: var(--orange);
}

[x-cloak] { display: none !important; }

* { border-radius: 0 !important; }

/* The ground must cover the viewport, not just the content box — a short
   list otherwise leaves a white slab below the last row. */
html {
    background: var(--concrete);
    min-height: 100%;
}

body {
    background: var(--concrete);
    min-height: 100vh;
    color: var(--asphalt);
    font-family: var(--font-body);
    /* Room for the fixed capture bar; iOS safe area included. */
    padding-bottom: calc(96px + env(safe-area-inset-bottom, 0px));
}

h1, h2, h3, h4, .display {
    font-family: var(--font-display);
    text-transform: uppercase;
    letter-spacing: 0.02em;
    font-weight: 600;
}

/* ===============================================================
   SITE PLATE — top bar
   The stamped identification plate. Wordmark bracketed, sync lamp
   at the right.
   =============================================================== */
.site-plate {
    position: sticky;
    top: 0;
    z-index: 40;
    display: flex;
    align-items: center;
    gap: var(--unit);
    padding: calc(var(--unit) * 1.25) var(--unit);
    padding-top: calc(var(--unit) * 1.25 + env(safe-area-inset-top, 0px));
    background: var(--asphalt);
    color: var(--chalk);
    border-bottom: var(--rule) solid var(--asphalt);
}

.site-plate .wordmark {
    font-family: var(--font-display);
    text-transform: uppercase;
    font-size: 1.15rem;
    letter-spacing: 0.08em;
    font-weight: 700;
}
.site-plate .wordmark::before { content: '['; color: var(--hivis); margin-right: 2px; }
.site-plate .wordmark::after  { content: ']'; color: var(--hivis); margin-left: 2px; }

.site-plate .spacer { flex: 1; }

.site-plate .plate-meta {
    font-size: 0.62rem;
    letter-spacing: 0.1em;
    color: var(--steel-lt);
    text-transform: uppercase;
}

.sync-lamp {
    width: 12px;
    height: 12px;
    border: 2px solid var(--chalk);
    background: var(--steel);
    flex: none;
}
.sync-lamp.is-active { background: var(--hivis); }
.sync-lamp.is-offline { background: var(--red); }
.sync-lamp.is-queued { background: var(--caution); }

/* ===============================================================
   CAUTION STRIP — offline / queued writes
   Hard-stop 45° stripes. No gradient anywhere in this app; this is
   a repeating pattern, which is a different thing.
   =============================================================== */
.caution-strip {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--unit);
    padding: 6px var(--unit);
    font-size: 0.68rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    font-weight: 600;
    color: var(--asphalt);
    border-bottom: var(--border);
    background-image: repeating-linear-gradient(
        45deg,
        var(--caution) 0, var(--caution) 12px,
        var(--asphalt) 12px, var(--asphalt) 24px
    );
}
/* Text needs a flat plate to sit on or the stripes eat it. */
.caution-strip span,
.caution-strip button {
    background: var(--caution);
    padding: 2px 6px;
    border: 2px solid var(--asphalt);
}
.caution-strip button {
    font-family: var(--font-body);
    font-size: 0.68rem;
    font-weight: 700;
    cursor: pointer;
    margin: 0;
    width: auto;
}

/* ===============================================================
   ZONE FILTER — chips across the top
   =============================================================== */
.zone-bar {
    display: flex;
    gap: 6px;
    overflow-x: auto;
    padding: var(--unit);
    background: var(--concrete);
    border-bottom: var(--border);
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}
.zone-bar::-webkit-scrollbar { display: none; }

.zone-chip {
    flex: none;
    font-family: var(--font-body);
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    padding: 8px 12px;
    min-height: var(--tap-min);
    background: var(--slab);
    color: var(--asphalt);
    border: var(--border);
    cursor: pointer;
    width: auto;
    margin: 0;
    box-shadow: none;
}
.zone-chip.is-on {
    background: var(--asphalt);
    color: var(--chalk);
}

/* ===============================================================
   FEED — the priority list. The reason the app is opened.
   =============================================================== */
.feed { padding: var(--unit); display: flex; flex-direction: column; gap: var(--unit); }

.row {
    display: flex;
    align-items: stretch;
    gap: 0;
    min-height: var(--row-min);
    background: var(--slab);
    border: var(--border);
    box-shadow: var(--shadow-block-sm);
}

/* The checkbox is a physical switch you slap — full-height hit area,
   not a 20px target you miss with a gloved thumb. */
.row-check {
    flex: none;
    width: 56px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--chalk);
    border-right: var(--border);
    cursor: pointer;
}
.row-check .box {
    width: 26px;
    height: 26px;
    border: var(--border);
    background: var(--chalk);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.1rem;
    line-height: 1;
    font-weight: 700;
}
.row.is-done .row-check { background: var(--hivis); }
.row.is-done .row-check .box { background: var(--hivis); }

.row-thumb {
    flex: none;
    width: 64px;
    background: var(--concrete);
    border-right: var(--border);
    background-size: cover;
    background-position: center;
}
.row-thumb.is-empty::after {
    content: '—';
    display: flex;
    height: 100%;
    align-items: center;
    justify-content: center;
    color: var(--steel);
}

.row-body {
    flex: 1;
    min-width: 0;
    padding: 10px 12px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    cursor: pointer;
}

.row-title {
    font-size: 1rem;
    line-height: 1.3;
    font-weight: 500;
    overflow-wrap: anywhere;
}
.row.is-done .row-title {
    text-decoration: line-through;
    text-decoration-thickness: 2px;
    color: var(--steel);
}

.row-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    font-size: 0.66rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--steel);
}

/* ===============================================================
   STAMPS — only PROBLEMS get paint. A healthy row wears none.
   =============================================================== */
.stamp {
    display: inline-block;
    font-family: var(--font-body);
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 2px 6px;
    border: 2px solid var(--asphalt);
    background: transparent;
    color: var(--asphalt);
    white-space: nowrap;
}
.stamp-overdue { background: var(--red); color: var(--chalk); }
.stamp-due-soon { background: var(--caution); }
/* Safety orange is BRIGHT (luminance .32) — light text on it measured 2.52:1.
   Ink on orange is 6:1 and is what real signage does. */
.stamp-high { background: var(--orange); color: var(--asphalt); }
.stamp-zone { background: var(--concrete); }
.stamp-recurring { background: var(--asphalt); color: var(--hivis); }
.stamp-quiet { border-color: var(--steel); color: var(--steel); }

/* ===============================================================
   CAPTURE BAR — the whole reason the app exists.
   Fixed, thumb-reachable, hi-vis. Two taps from cold app to camera:
   this button IS tap one.
   =============================================================== */
.capture-bar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 50;
    display: flex;
    gap: 0;
    border-top: 3px solid var(--asphalt);
    padding-bottom: env(safe-area-inset-bottom, 0px);
    background: var(--asphalt);
}

.capture-btn {
    flex: 1;
    font-family: var(--font-display);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    font-size: 1.1rem;
    font-weight: 700;
    min-height: 64px;
    background: var(--hivis);
    color: var(--asphalt);
    border: none;
    border-right: 3px solid var(--asphalt);
    cursor: pointer;
    margin: 0;
    box-shadow: none;
    transition: transform var(--snap);
}
.capture-btn:active { transform: translateY(2px); }

/* NOTE — the no-camera entry point. Deliberately NOT hi-vis: SNAP is the
   primary act and must stay the only thing wearing paint down here. Slab on
   asphalt still reads instantly in daylight. */
.note-btn {
    flex: none;
    width: 66px;
    font-family: var(--font-display);
    text-transform: uppercase;
    /* 66px + Oswald tracking wrapped this to "NOT / E". */
    white-space: nowrap;
    font-size: 0.82rem;
    letter-spacing: 0.08em;
    font-weight: 700;
    min-height: 64px;
    background: var(--slab);
    color: var(--asphalt);
    border: none;
    border-right: 3px solid var(--asphalt);
    cursor: pointer;
    margin: 0;
    box-shadow: none;
    transition: transform var(--snap);
}
.note-btn:active { transform: translateY(2px); }

.nav-btn {
    flex: none;
    /* Four nav buttons + NOTE must not starve SNAP: 4x56 + 66 = 290px of the
       414px reference phone, leaving SNAP ~124px — still the widest control
       and the only hi-vis one. */
    width: 56px;
    font-family: var(--font-body);
    font-size: 0.58rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    background: var(--asphalt);
    color: var(--steel-lt);
    border: none;
    border-left: 2px solid var(--steel);
    cursor: pointer;
    margin: 0;
    box-shadow: none;
    padding: 4px 2px;
}

/* Zone name, editable in place. Looks like text until you touch it — a
   settings row should not read as a form. */
.zone-rename {
    flex: 1;
    min-height: 40px;
    background: transparent;
    border: 2px solid transparent;
    padding: 4px 6px;
    font-size: 0.85rem;
    color: var(--asphalt);
}
.zone-rename:focus {
    background: var(--chalk);
    border-color: var(--asphalt);
}
.nav-btn.is-on { color: var(--hivis); }

/* ===============================================================
   SCREENS — capture + edit.

   NOT popups. A centered, shadowed, max-width dialog is a desktop
   idiom; on a phone it reads as a browser artifact sitting on top of
   the app. These are full-viewport pushed views: they own the screen
   edge to edge, the header is a fixed bar with the escape hatch in
   the top-left where a thumb expects Back, and only the body
   scrolls.

   The elements stay <dialog> because that is what the markup already
   uses and it carries the right semantics, but every visual trace of
   dialog-ness is removed. They are opened by the `open` ATTRIBUTE,
   not showModal(), so there is no ::backdrop and no top-layer.
   =============================================================== */
dialog {
    position: fixed;
    inset: 0;
    z-index: 200;
    width: 100%;
    max-width: none;
    height: 100%;
    max-height: none;
    margin: 0;
    padding: 0;
    border: none;
    background: var(--slab);
    color: var(--asphalt);
}
/* 100dvh where supported: the mobile URL bar collapsing must not clip the
   save button off the bottom of the screen. */
@supports (height: 100dvh) {
    dialog { height: 100dvh; }
}
dialog:not([open]) { display: none; }

dialog article {
    background: var(--slab);
    border: none;
    box-shadow: none;
    padding: 0;
    margin: 0;
    max-width: none;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
}

.sheet-head {
    flex: none;
    display: flex;
    align-items: center;
    gap: var(--unit);
    background: var(--asphalt);
    color: var(--chalk);
    padding: 12px;
    padding-top: calc(12px + env(safe-area-inset-top, 0px));
    font-family: var(--font-display);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-size: 0.95rem;
    /* Back sits LEFT, title after it — phone convention. The markup order is
       title-then-button, so flip it visually rather than churn every sheet. */
    flex-direction: row-reverse;
    justify-content: flex-end;
}
.sheet-head button {
    width: auto;
    margin: 0;
    padding: 8px 12px;
    min-height: 40px;
    background: transparent;
    color: var(--chalk);
    border: 2px solid var(--steel-lt);
    font-family: var(--font-body);
    font-weight: 700;
    font-size: 0.72rem;
    cursor: pointer;
    box-shadow: none;
}

/* Only the body scrolls; the header stays put. Bottom padding clears the
   home indicator so the last control is never under it. */
.sheet-body {
    flex: 1;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: var(--unit);
    padding-bottom: calc(var(--unit) * 4 + env(safe-area-inset-bottom, 0px));
    display: flex;
    flex-direction: column;
    gap: var(--unit);
}

.field-label {
    font-size: 0.64rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    font-weight: 700;
    color: var(--steel);
    margin-bottom: 4px;
    display: block;
}

input, textarea, select {
    font-family: var(--font-body) !important;
    min-height: var(--tap-min);
    margin-bottom: 0 !important;
}
textarea { min-height: 88px; }

/* The one input that matters. Big, because it is typed outdoors. */
.capture-input {
    font-size: 1.05rem !important;
    min-height: 56px;
    border-width: 3px !important;
}

.btn-row { display: flex; gap: var(--unit); flex-wrap: wrap; }

button, [role="button"] {
    font-family: var(--font-body);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    border: var(--border);
    box-shadow: var(--shadow-block-sm);
    cursor: pointer;
    /* Pico's default button text is WHITE. Any button here that sets a light
       background without also setting a color inherits it and renders
       invisible — the .opt chips measured 1.14:1. Default to ink; the paint
       modifiers below opt back into light text explicitly. */
    color: var(--asphalt);
    transition: transform var(--snap), box-shadow var(--snap);
}
button:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 var(--asphalt); }

.btn-primary { background: var(--hivis); color: var(--asphalt); }
.btn-plain { background: var(--slab); color: var(--asphalt); }
.btn-danger { background: var(--red); color: var(--chalk); }
.btn-small { min-height: 36px; font-size: 0.7rem; padding: 4px 10px; width: auto; }

/* Chip-style option pickers (priority, zone, category). */
.opt-row { display: flex; gap: 6px; flex-wrap: wrap; }
.opt {
    font-size: 0.72rem;
    padding: 8px 12px;
    min-height: 44px;
    background: var(--chalk);
    border: var(--border);
    box-shadow: none;
    width: auto;
    margin: 0;
}
.opt.is-on { background: var(--asphalt); color: var(--chalk); }
.opt.is-on.opt-high { background: var(--orange); color: var(--asphalt); }

/* ===============================================================
   SUBTASKS — a flat checklist. Not a workflow engine: no nesting,
   no dates, no assignees.
   =============================================================== */
.subtask {
    display: flex;
    align-items: center;
    gap: var(--unit);
    padding: 6px 0;
    border-bottom: 1px dashed var(--steel);
}
.subtask:last-of-type { border-bottom: none; }
.subtask .box {
    flex: none;
    width: 24px;
    height: 24px;
    border: var(--border);
    background: var(--chalk);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    cursor: pointer;
}
.subtask.is-done .box { background: var(--hivis); }
.subtask.is-done .subtask-title { text-decoration: line-through; color: var(--steel); }
.subtask-title { flex: 1; font-size: 0.9rem; overflow-wrap: anywhere; }

/* ===============================================================
   PHOTOS — documentary, never decorative. Every one is framed and
   labeled like a filed figure.
   =============================================================== */
.photo-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
    gap: var(--unit);
}
.photo-cell {
    position: relative;
    aspect-ratio: 1;
    border: var(--border);
    background: var(--concrete) center/cover no-repeat;
}
.photo-cell .fig {
    position: absolute;
    left: -2px;
    bottom: -2px;
    background: var(--asphalt);
    color: var(--chalk);
    font-size: 0.55rem;
    letter-spacing: 0.08em;
    padding: 1px 4px;
}

/* ===============================================================
   EMPTY STATE — a taped-off area awaiting work, not a sad face.
   =============================================================== */
.empty {
    margin: var(--unit);
    border: 3px dashed var(--asphalt);
    padding: calc(var(--unit) * 3) var(--unit);
    text-align: center;
    color: var(--steel);
    font-size: 0.8rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}
.empty strong {
    display: block;
    font-family: var(--font-display);
    font-size: 1.1rem;
    color: var(--asphalt);
    margin-bottom: 6px;
}

/* A rare hand annotation. Max 1–2 per screen, margins only. */
.marker-note {
    font-family: var(--font-note);
    font-size: 0.85rem;
    color: var(--steel);
    transform: rotate(-1deg);
    text-transform: none;
    letter-spacing: 0;
}

/* ===============================================================
   SECTION RULE — numbered, like a drawing sheet
   =============================================================== */
.section-head {
    display: flex;
    align-items: baseline;
    gap: var(--unit);
    padding: var(--unit) var(--unit) 4px;
    font-family: var(--font-display);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-size: 0.85rem;
}
.section-head .num {
    font-family: var(--font-body);
    font-size: 0.65rem;
    background: var(--asphalt);
    color: var(--chalk);
    padding: 1px 5px;
}
.section-head .rule {
    flex: 1;
    height: 0;
    border-top: var(--rule) solid var(--asphalt);
}

/* Data plate — tiny stamped facts at the foot of Settings. */
.data-plate {
    margin: var(--unit);
    border: var(--border);
    background: var(--concrete);
    padding: var(--unit);
    font-size: 0.62rem;
    letter-spacing: 0.06em;
    color: var(--steel);
    text-transform: uppercase;
    overflow-wrap: anywhere;
}

.ledger-row {
    display: flex;
    justify-content: space-between;
    gap: var(--unit);
    padding: 8px 0;
    border-bottom: 1px solid var(--steel);
    font-size: 0.8rem;
}
.ledger-row .amt { font-weight: 700; white-space: nowrap; }

a { color: var(--orange); text-decoration-thickness: 3px; text-underline-offset: 3px; }

/* ===============================================================
   Login overlay — we own the backdrop and the nui-* tokens only.
   =============================================================== */
#nostr-login-overlay {
    position: fixed;
    inset: 0;
    z-index: 100;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--unit);
    background: var(--concrete);
    background-image: repeating-linear-gradient(
        45deg, transparent 0 22px, rgba(28, 28, 26, 0.05) 22px 44px
    );
}
:root {
    --nui-card: var(--slab);
    --nui-card-hover: var(--chalk);
    --nui-bg: var(--slab);
    --nui-text: var(--asphalt);
    --nui-muted: var(--steel);
    /* The vendored card uses --nui-primary as a TEXT colour (the "LOGIN WITH
       NOSTR" heading, accents) as well as a button fill. Hi-vis is a fill
       colour only — as text on the light card it measured ~1.05:1, i.e. an
       invisible heading on the very first screen. Accent = ink; the primary
       button gets its hi-vis fill back explicitly below. */
    --nui-primary: var(--asphalt);
    --nui-primary-hover: var(--asphalt);
    --nui-border: var(--asphalt);
    --nui-error: var(--red);
    --nui-success: var(--asphalt);
}
#nostr-login-card { border: 3px solid var(--asphalt); box-shadow: var(--shadow-block); }
/* Restore the hi-vis FILL on the one real call-to-action, with ink on top.
   The lib hardcodes light text there, which under our palette was
   white-on-hi-vis at 1.28:1. */
#nostr-login-card .nui-btn-primary {
    background: var(--hivis);
    border-color: var(--asphalt);
    color: var(--asphalt);
}

.boot {
    padding: calc(var(--unit) * 6) var(--unit);
    text-align: center;
    font-family: var(--font-display);
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--steel);
}

.fatal {
    margin: var(--unit);
    border: 3px solid var(--red);
    background: var(--slab);
    padding: var(--unit);
    font-size: 0.8rem;
    overflow-wrap: anywhere;
}

/* ===============================================================
   MANDATORY — motion is a courtesy, not a requirement
   =============================================================== */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
    }
}
