/* Backups admin page ([[M-680c]]). Presentation only — every string is in Blade, and the page's one
   behaviour (re-asking the server while a run is in flight) is in backup_refresh_controller.js
   (coding-standards §4). Token-driven so it re-skins with the theme and reads on any surface (§12): every
   colour and every space comes from a design token, nothing hard-coded. Scoped under
   .platform-system-backups so nothing here leaks to another page. */

/* ── The action card ([[M-696]]) ───────────────────────────────────────────────────────────────────
   The two things an operator comes here to DO, side by side and first: the state and the backup trigger
   left, the upload right. Presentation only; the order and the supersession of M-683's "list first" are
   argued in index.blade.php, where the order lives.

   THE SWITCH IS A CONTAINER QUERY, NOT A VIEWPORT ONE, and on this page that is not a preference. The admin
   shell opens its side nav at a 768px viewport and takes 359px off the row from there up, so this card is
   NARROWER at 768px than at 767px — a `min-width` media query would hand two columns to the narrower box.
   (Measured on this card: 767px yields `323px 323px`, 768px yields one 359px pane.) The 768–968px stacked
   band is therefore a DECISION, not an oversight.

   38rem is COPIED, NOT RE-DERIVED, from `.platform-storage-config` (admin.css) — same page, same box (a card,
   a two-track grid inside `.platform-card__body`), so the same threshold buys the same 268px panes. The
   arithmetic is worked once, for all three container queries on this page, in the table in
   `docs/modules/platform.md` ("The order of the page, and two layouts that were wrong") — including the fact
   that the 38rem is coupled BY HAND to `--platform-space-lg`, because a container query cannot take a
   `var()`. Re-theming that token means recomputing all three; that is where they are listed. AND THIS IS THE
   SECOND COPY OF THE 38rem TWO-UP, WHICH IS THE LAST ONE THAT GETS ITS OWN BLOCK: the docs say a third is
   factored into a shared `.platform-two-up` on an unnamed container query instead of a fourth prose
   derivation of 268px. */
.platform-system-backups__action {
    /* Named, so the query below cannot be silently re-pointed at some future ancestor that becomes a
       container. `inline-size` containment makes this card a containing block for `position: fixed`
       descendants and a stacking context (the D-056/M-259 trap) — safe here because both overlays in the
       card are native `<dialog>`s opened with `showModal()`, which live in the browser's TOP LAYER and are
       laid out against the viewport rather than against any ancestor. That is not assumed, it is MEASURED
       (`bin/dev computed --click`, M-696): the open dialog is 608px wide at x=328.5 y=54.81 on a 1280px
       viewport — `margin: 54.8125px 328.5px`, i.e. centred on the viewport minus its scrollbar, not on this
       919px card — and removing this very line and measuring again gives byte-identical geometry. (What DID
       pin it to the top was an author rule of ours reaching the dialog through the DOM; see the pane block
       below. Top layer is where an element paints, not where a selector finds it.) Drop in anything that
       renders a `position: fixed` overlay INTO the DOM instead — an enhanced select's menu, a tooltip — and
       this line has to be revisited. Deliberately NOT phrased as "a popover": the Popover API is top-layer too and escapes this
       exactly as `showModal()` does, so naming it would teach the wrong test. The test is whether the
       overlay is laid out against an ancestor or against the viewport. */
    container: platform-backup-action / inline-size;
}

.platform-system-backups__action-panes {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--platform-space-lg);
}

@container platform-backup-action (min-width: 38rem) {
    .platform-system-backups__action-panes {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* One pane. A flex column so the pane owns the rhythm between its blocks in ONE place... */
.platform-system-backups__pane {
    display: flex;
    flex-direction: column;
    gap: var(--platform-space-md);
    min-width: 0;
}

/* ...which is also why the top margins those blocks carry for a prose flow are dropped here: a notice with
   its own `margin-top` inside a gapped column spaces itself twice. Scoped through the page class purely for
   SPECIFICITY: the blocks it overrides are single classes defined further down this file, and a rule that
   only worked because of where it happens to sit is a rule the next edit breaks.

   `:not(dialog)` IS THE BUG FIX, NOT TIDINESS (QA, M-696). Each pane also contains an
   `<x-platform::modal>`, i.e. a real `<dialog>` child — a modal is promoted to the browser's TOP LAYER for
   PAINT, but it never leaves the DOM, so a child combinator still matches it. `dialog:modal { margin: auto }`
   is what centres an open modal, and it is a UA rule: this author rule beat it, zeroed the top margin alone,
   and the dialog opened pinned to `y = 0` with all the free space below it (`margin: 0px … 109.6px`). With
   the exclusion it is `margin: 54.8125px 328.5px` — symmetric, on the same page, at the same width.

   The general form, for the next pane-like block: a `> *` inside a container that can host an overlay
   element reaches that overlay. Today this is the only `> *` in the app whose SUBJECT is the universal
   selector (calendars.css has `> * + .platform-card`, whose subject is a card), so there is nothing else to
   correct — but the trap is written here because the next such rule will be written by somebody who did not
   watch a modal jump to the top of the screen.

   The exclusion names BOTH of HTML's top-layer mechanisms, not just the one that bit us. `[popover]` centred
   the ordinary way (`inset: 0; margin: auto`) breaks identically, on this page, one element name along — and
   the block above deliberately declines to name "popover" as the hazard, so a guard covering only `dialog`
   would have contradicted its own warning. If a third top-layer mechanism ever appears, invert this to a
   positive list of the four blocks that actually carry a top margin (`__notice`, `__alert`, `__running`,
   `__upload`): that form cannot reach an overlay at all, and its failure mode is visible double-spacing
   rather than a silently mispositioned dialog. */
.platform-system-backups .platform-system-backups__pane > *:not(dialog, [popover]) {
    margin-top: 0;
}

/* The pane's heading and its "explain this" button, on one line, the button pushed to the trailing edge. */
.platform-system-backups__pane-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--platform-space-sm);
}

/* The shared subhead, minus its bottom margin: in the pane the flex gap does that spacing. */
.platform-system-backups__pane-head .platform-system-backups__subhead {
    margin-bottom: 0;
}

/* State panel — label above value, always. It used to be a `max-content 1fr` pair that stacked under 40rem;
   since M-696 it lives in a pane that is 268px at the two-column switch and about 570px at a 1600px
   viewport, so the two-track version would only ever have applied to a window wider than any we lay out for
   — and at 268px it gave "Backups are stored on" the label column and the location name ~90px.

   SO THE TWO SYSTEM PAGES NOW DIFFER, DELIBERATELY: the self-updater's `.platform-system-update__meta`
   (system-update.css) is still `max-content 1fr`, stacking only under 40rem, and that is right there — its
   state list is a full-width card body, not a 268px pane. Same content shape, different available width,
   therefore different layout. If the action card ever stops being two-up, this is the block to revisit. */
.platform-system-backups__meta {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    margin: 0;
}

.platform-system-backups__meta dt {
    font-weight: 600;
    color: var(--platform-color-text-muted);
}

.platform-system-backups__meta dd {
    margin: 0 0 var(--platform-space-sm);
    word-break: break-word;
}

.platform-system-backups__meta dd:last-child {
    margin-bottom: 0;
}

/* Status chip inside the state list. */
.platform-system-backups__flag {
    display: inline-block;
    padding: 0.1rem var(--platform-space-sm);
    border-radius: var(--platform-radius-pill);
    font-size: 0.85em;
    font-weight: 600;
}

.platform-system-backups__flag--ok {
    color: var(--platform-color-ok);
    background: var(--platform-color-accent-surface);
}

.platform-system-backups__flag--error {
    color: var(--platform-color-error-text);
    background: var(--platform-color-error-surface);
}

/* A state-list value that is a SENTENCE rather than a one-word answer — "no off-server copies", "no backup
   yet". Deliberately NOT a chip: the two above are single words, and a pill that wraps onto two lines reads
   as a badge that has outgrown itself. Amber and semibold, so it is noticed without shouting; the words
   carry the meaning either way, so colour is never the only cue. */
.platform-system-backups__absent {
    color: var(--platform-color-warning);
    font-weight: 600;
}

/* Scoped alert boxes (page-local — not a shared component), in the three tones this page needs: a refusal,
   a caution, and a plain confirmation. */
.platform-system-backups__alert {
    margin-top: var(--platform-space-md);
    padding: var(--platform-space-md);
    border-radius: var(--platform-radius-md);
    border: 1px solid transparent;
}

.platform-system-backups__alert--danger {
    color: var(--platform-color-error-text);
    background: var(--platform-color-error-surface);
    border-color: var(--platform-color-error);
}

/* A caution, and it must not read as a routine flash: the foreign-restore and shared-Location warnings say
   something an operator has to act on. `--platform-color-warning-surface` is a real token in every theme
   (M-680c) — before it existed this fell back to surface-muted, i.e. to exactly the informational
   background below, leaving one border pixel to carry the difference. */
.platform-system-backups__alert--warn {
    background: var(--platform-color-warning-surface);
    border-color: var(--platform-color-warning);
}

.platform-system-backups__alert--info {
    background: var(--platform-color-surface-muted);
    border-color: var(--platform-color-border);
}

.platform-system-backups__alert-title {
    margin: 0 0 var(--platform-space-xs);
    font-weight: 700;
}

.platform-system-backups__alert p:last-child {
    margin-bottom: 0;
}

.platform-system-backups__notice {
    margin: var(--platform-space-md) 0 0;
    color: var(--platform-color-text-muted);
}

/* The in-flight run panel. Accent-toned rather than amber: a running backup is a good thing happening, not
   a caution — the page re-asks the server while this is on screen and the panel disappears with the run. */
.platform-system-backups__running {
    margin-top: var(--platform-space-md);
    padding: var(--platform-space-md);
    border-radius: var(--platform-radius-md);
    border: 1px solid var(--platform-color-accent);
    background: var(--platform-color-accent-surface);
}

.platform-system-backups__running p {
    margin: 0;
}

.platform-system-backups__running-title {
    font-weight: 700;
    margin-bottom: var(--platform-space-xs);
}

/* One trigger per registered backup type. A row that wraps rather than a fixed pair of columns: this build
   has one type, the next has two, and nothing here should have to be edited for the third. */
.platform-system-backups__triggers {
    display: flex;
    flex-wrap: wrap;
    gap: var(--platform-space-sm);
    margin-top: var(--platform-space-lg);
}

.platform-system-backups__trigger {
    margin: 0;
}

/* "What a backup contains" — two lists side by side on a wide screen, stacked on a phone. `1fr` columns
   with an `auto-fit` minimum rather than a media query, so the break happens when the CONTENT needs it. */
.platform-system-backups__contents {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
    gap: var(--platform-space-lg);
}

.platform-system-backups__subhead {
    margin: 0 0 var(--platform-space-sm);
    font-size: 1rem;
    font-weight: 700;
}

.platform-system-backups__list {
    margin: 0;
    padding-left: var(--platform-space-lg);
}

.platform-system-backups__list li + li {
    margin-top: var(--platform-space-xs);
}

/* The two lists answer opposite questions, so their markers do too: a tick for what IS in the artifact, a
   cross for what is NOT. Colour is a second cue, never the only one — the words carry the meaning. */
.platform-system-backups__list--in,
.platform-system-backups__list--out {
    list-style: none;
    padding-left: var(--platform-space-md);
}

.platform-system-backups__list--in li::before,
.platform-system-backups__list--out li::before {
    display: inline-block;
    width: var(--platform-space-md);
    margin-left: calc(-1 * var(--platform-space-md));
    font-weight: 700;
}

.platform-system-backups__list--in li::before {
    content: "✓";
    color: var(--platform-color-ok);
}

.platform-system-backups__list--out li::before {
    content: "✕";
    color: var(--platform-color-error-text);
}

/* Retention ([[M-680d]], re-laid out in M-683). The three numbers are ONE question asked three times — how
   far back the daily, weekly and monthly steps reach — so they belong on one row, and the row is stated
   rather than negotiated: EXACTLY three tracks, or exactly one. Never two.

   They were `repeat(auto-fit, minmax(14rem, 1fr))`, which never reached three at ANY viewport width: this
   grid lives inside a `.platform-form`, capped at the 40rem reading measure, so auto-fit divided 640px into
   `308px 308px` and dropped Months onto a second row on its own (measured at 1600px). Shrinking the minimum
   until three tracks happen to fit would leave the accident in place from the other side — the count would
   still be emergent, and the next longer hint string would take it back to two. The difference that matters
   is not the number, it is that `repeat(3, …)` can only ever produce three-or-stacked; two-and-an-orphan is
   no longer a state this grid has.

   Keyed off the FORM's width, not the viewport's, for the same reason the grid footer is (M-082, table.css):
   the form is 640px wide on a 1600px viewport and 359px wide on a 768px one, where the side nav opens and
   takes the space — so it is NARROWER on the wider viewport (both measured with `bin/dev computed`). Key a
   media query at 768px and you get three ~104px tracks at 768 and one full-width track at 767, which is the
   inversion, on purpose, in CSS.

   ## The threshold, and what it is measured against
   The container is the `<form>` itself, and `.platform-form` has no padding, so 30rem is 480px of the form's
   own box and the whole 480px reaches this grid. Three tracks with two `--platform-space-lg` gaps:
   (480 − 2 × 24px) / 3 = **144px per track** — a two-digit number field with room to spare and a hint that
   wraps to three lines rather than five. Measured at the switch: a 889px viewport gives a 480px form and
   exactly `144px 144px 144px`; 888px gives one 479px track.

   **The 24px gap is a design token, and this number is coupled to it by hand.** A container query cannot take
   a `var()`, so a host that re-themes `--platform-space-lg` changes what 30rem buys here — same hazard the
   dashboard-tile thresholds document in admin.css. If that token changes, recompute.

   Below the threshold — a phone, and the 768–888px band the open side nav creates, where the form is 359px
   and three tracks would be ~104px each — it stacks. That band is a DECISION, not an oversight: at 768 the
   form is genuinely narrower than at 767, so any rule that gave it three tracks would be shipping the
   inversion above.

   `minmax(0, 1fr)` so a long hint cannot push a track past its share (a bare `1fr` floors at min-content).
   Each field keeps its own hint under it, so the three still read as three separate questions rather than as
   one row of boxes. */
.platform-system-backups__retention-form {
    /* Named, so the query below cannot be silently re-pointed at some future ancestor that becomes a
       container: an unnamed @container resolves against the NEAREST containing ancestor, whichever that
       turns out to be.

       `inline-size` containment is SAFE ON THIS ELEMENT, which is not something to assume anywhere else:
       `container-type` implies `contain: layout style inline-size`, making this form a containing block for
       `position: fixed` descendants and a stacking context — the trap D-056/M-259 burned four QA rounds on,
       and the reason card.css refuses to give every card a `position: relative`. It is safe HERE because the
       form's whole content is three native `<input type="number">` fields and a submit: nothing inside it
       escapes its box (a number spinner is drawn by the OS, not the document). Anything that renders an
       overlay INTO the DOM — an enhanced select, a popover, a date picker, a tooltip — would be re-anchored
       to this form and trapped in its stacking context the moment it is dropped in here, and its overflow
       would stop contributing to any ancestor's scrollable region. It would NOT be clipped: none of the
       three computed containments clips painting — only `contain: paint` does, and `container-type` does not
       imply it. Drop one in and this line has to be revisited. */
    container: platform-retention-form / inline-size;
}

.platform-system-backups__retention-fields {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
    gap: var(--platform-space-md) var(--platform-space-lg);
}

@container platform-retention-form (min-width: 30rem) {
    .platform-system-backups__retention-fields {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

/* A number field never needs the full width of a card: at 1fr it draws a 400px box for a two-digit number,
   which reads as an invitation to type a sentence. Capped rather than given a flex basis, so it still
   shrinks to fit a 390px phone — a max-width yields, a flex-basis would not. */
.platform-system-backups__retention-fields .platform-form__input {
    max-width: 10rem;
}

/* The policy's non-numeric rules. Same tick list as "in the backup" above — these are things the code
   guarantees, and they read as guarantees. Slightly quieter than body text: they are reference, not news. */
.platform-system-backups__rules {
    margin-top: var(--platform-space-lg);
    color: var(--platform-color-text-muted);
}

/* The dry run's "why" column is prose and wraps, opting out of the one-line row rule (coding-standards
   §15's stated exception): a truncated reason is exactly what somebody opened this table to read. The rule
   it overrides is `:where()`d to specificity 0, so this bare class is enough. */
.platform-system-backups__reason {
    white-space: normal;
    min-width: 14rem;
}

/* ── Restore checks ([[M-680e]]) ──────────────────────────────────────────────────────────────────
   The drill's results, under the list. Presentation only — every string is in Blade and the panel has no
   behaviour of its own (the page's single poller lives on the section). Token-driven and mobile-first like
   the rest of this file: no fixed pixel widths anywhere, so it reads at 390px and at a desktop alike. */
.platform-restore-checks {
    list-style: none;
    display: grid;
    gap: var(--platform-space-md);
    margin: var(--platform-space-md) 0 0;
    padding: 0;
}

/* Each check is a block, not a table row: it carries a sentence, a verdict and a list of findings, and a
   row would either truncate them or grow a second line (coding-standards §15 applies to LISTS; this is
   deliberately not one). The leading rule ties the block together without drawing a box inside a card. */
.platform-restore-checks__run {
    /* Belt and braces against a grid item's automatic minimum size being its MIN-CONTENT: this block carries
       hash-tailed filenames and sentences full of them. It is NOT a measured fix — removing this declaration
       leaves the rendered geometry byte-identical at 390x844, because the `overflow-wrap: anywhere` on the
       message and the findings already gives every long token a break opportunity. It stays as the guard for
       a future child that has none; anyone claiming it does more should measure again. */
    min-width: 0;
    border-inline-start: 3px solid var(--platform-color-border);
    padding-inline-start: var(--platform-space-md);
}

/* The head wraps rather than overflowing: on a phone the file name takes the line and the pill, the verdict
   and the timestamp fall under it. `baseline` so the pill sits on the same line as the text beside it. */
.platform-restore-checks__head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--platform-space-xs) var(--platform-space-sm);
}

/* The artifact's filename is an identifier an operator compares character by character against the list
   above, so it is set in the monospace stack and allowed to break — a truncated hash-tailed filename is
   exactly the thing that cannot be compared. */
.platform-restore-checks__file {
    /* Same belt-and-braces as the block above, for a flex item this time; `word-break` below is what
       actually keeps a hash-tailed filename inside a 343px card. */
    min-width: 0;
    font-family: var(--platform-font-mono, ui-monospace, monospace);
    font-size: var(--platform-font-size-sm);
    word-break: break-all;
}

.platform-restore-checks__verdict {
    color: var(--platform-color-text-muted);
    font-weight: 600;
}

/* Pushed to the trailing edge where there is room, and simply next in the wrap where there is not:
   `margin-inline-start: auto` does both, with no breakpoint to keep in step with anything. */
.platform-restore-checks__when {
    margin-inline-start: auto;
    color: var(--platform-color-text-muted);
    font-size: var(--platform-font-size-sm);
}

.platform-restore-checks__message {
    margin: var(--platform-space-xs) 0 0;
    overflow-wrap: anywhere;
}

/* The battery. One column on a phone — a label above its finding reads; a two-track grid at 390px would
   give the finding about 200px and hyphenate a role name. Two tracks from 40rem, where the label column
   can take its natural width. */
.platform-restore-checks__battery {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--platform-space-xs) var(--platform-space-md);
    margin: var(--platform-space-sm) 0 0;
}

@media (min-width: 40rem) {
    .platform-restore-checks__battery {
        grid-template-columns: max-content minmax(0, 1fr);
    }
}

.platform-restore-checks__check {
    display: flex;
    align-items: baseline;
    gap: var(--platform-space-xs);
    font-weight: 600;
}

/* `anywhere`, not `break-word`: only the former contributes to min-content sizing, and these findings quote
   filenames and role names that have no break opportunity in them at all. */
.platform-restore-checks__battery dd {
    margin: 0;
    color: var(--platform-color-text-muted);
    overflow-wrap: anywhere;
}

/* A throwaway copy the run could not delete. Warning-toned because it is the ONE trace a restore check can
   leave on the server — and quiet, because the sweep on the next page load is already retrying it. */
.platform-restore-checks__leftover {
    margin: var(--platform-space-xs) 0 0;
    color: var(--platform-color-warning);
    font-size: var(--platform-font-size-sm);
}

/* Upload an artifact from another installation ([[M-687]]). The panel is a drop target AND holds the plain
   file input, so the picker and the drop end in the same control and it works with no JS at all — there is
   no hidden fallback here to keep in step with an enhanced twin.

   THE DROP TARGET ITSELF IS NOT STYLED HERE. It wears `.platform-dropzone`, the shared primitive in
   forms.css (M-696) that the contracts uploader wears too — this page used to carry a second copy of
   that block under its own prefix, which is the duplication M-696 closed. What is left below is only what is
   this form's own: how the drop target sits inside it. */
.platform-system-backups__upload {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--platform-space-md);
    margin-top: var(--platform-space-md);
}

/* The panel is the drop target, so it takes the pane's whole width — a target the size of its own text is
   one a dragged file misses. The form aligns its items to the start so the submit button hugs its own label,
   so the exception is asked for here rather than by loosening the form. */
.platform-system-backups__upload > .platform-dropzone {
    align-self: stretch;
}

/* The native file control. It is the one element here whose width the browser picks for itself (and picks
   differently per browser, from the filename it is showing), so it is capped to its container rather than
   trusted — §12: the page never scrolls sideways. */
.platform-system-backups__file {
    max-width: 100%;
}

/* What is about to be uploaded, and the browser's own refusal. Both carry a filename with no break
   opportunity in it, so `anywhere` — only that value contributes to min-content sizing. */
.platform-system-backups__upload-selected,
.platform-system-backups__upload-error {
    margin: 0;
    overflow-wrap: anywhere;
}

.platform-system-backups__upload-selected {
    font-weight: 600;
}

.platform-system-backups__upload-error {
    color: var(--platform-color-error-text);
    font-weight: 600;
}

/* ── Replacing the live database ([[M-680f]]) ─────────────────────────────────────────────────────────────
   The swap panel on the list page and the confirmation page share this block, because they are the same
   three things said twice: what a restore does, what it leaves behind, and the exact name of the leftover.
   Nothing here is a new visual language — the panel reuses `.platform-system-backups__meta`, `__alert` and
   `__running` from above; what follows is only the parts those do not have. */

/* The phase a running swap is on. Larger and unmuted, because during the one minute anybody reads this
   panel it is the only line that changes. */
.platform-restore-swap__phase {
    margin: var(--platform-space-xs) 0 0;
    font-weight: 600;
}

/* The step line inside that phase, in the running process's own words. Muted: it is detail under the
   heading above it, not a second heading. */
.platform-restore-swap__detail,
.platform-restore-swap__message {
    margin: var(--platform-space-xs) 0 0;
    color: var(--platform-color-text-muted);
    overflow-wrap: anywhere;
}

.platform-restore-swap__leftover {
    margin-top: var(--platform-space-md);
}

/* The undo, as one statement to select and paste. `pre` keeps it verbatim — a database name with an
   underscore run through a proportional paragraph is a name somebody retypes wrong — and the wrapping is
   what stops a 90-character statement scrolling the page sideways on a phone (§12). */
.platform-restore-swap__sql {
    margin: var(--platform-space-xs) 0 0;
    padding: var(--platform-space-sm);
    border: 1px solid var(--platform-color-border);
    border-radius: var(--platform-radius-sm);
    background: var(--platform-color-surface-muted);
    color: var(--platform-color-text);
    font-family: var(--platform-font-mono, ui-monospace, monospace);
    font-size: var(--platform-font-size-sm);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.platform-restore-swap__reopen {
    margin-top: var(--platform-space-md);
}

/* The confirmation page's own two. The file name is the thing being confirmed, so it is set in the same
   face the operator will type it in — a proportional font makes `l` and `1` in a generated name the same
   shape, which is exactly the mistake this field exists to catch. */
.platform-restore-swap__filename {
    font-family: var(--platform-font-mono, ui-monospace, monospace);
    overflow-wrap: anywhere;
}

/* The numbered account of what a restore does. A list, not prose: an operator reads it once, in order, and
   a paragraph would hide the step that undoes the swap. */
.platform-restore-swap__steps {
    margin: 0 0 var(--platform-space-md);
    padding-left: var(--platform-space-lg);
    display: grid;
    gap: var(--platform-space-xs);
}

/* The typed confirmation, in the face the name above it is set in, so the two can be compared by eye. */
.platform-restore-swap__confirm .platform-form__input {
    font-family: var(--platform-font-mono, ui-monospace, monospace);
}
