SchOS/docs/Website/style.css
Nexoniarz c0ed23cc56 freeze: one register for everything half-built, and the corners cleared
The failure this is against is not scope creep. It is abandonment by promotion:
a thing gets built to the point where it works, the next thing becomes more
interesting, and the first is left in a corner -- in the tree, not finished, not
deleted, and not in any list. Enough of those and the tree stops matching its
own documentation.

docs/plan/1.0.md now holds the register, and it is the only place anything
half-built is listed. Four sections, because the kinds are genuinely different:
built and connected to nothing (the text layer, a font from disk, socket
activation, wait_vblank); started and stopped part-way (foundations 2-5, hybrid
H2, Schcom v0, a released PCI device that nothing brings back); named in a "what
it does not do" and still true; and frozen -- scoped, unstarted, not to be
started. The rule is that nothing enters except by being finished or deleted,
and that adding a row requires closing one.

1.0.md already said "two things in flight, never three". It was right and it was
not being followed.

Then the corners themselves, because a register written over a tree full of them
is just a longer list:

  - cmd/init is deleted. Nothing had execed /bin/init since initcode.S changed
    to /bin/schinit; it was built and installed on every image as an unreachable
    fallback, and an unreachable fallback rots rather than saves.
  - projects/schwm/ and projects/schde/ are deleted. Both said "to be deleted"
    in their own first paragraph, which proves only that a directory marked for
    deletion is not deleted by being marked. README-only, no code lost, and the
    arguments each made are moved into wayland.md where they are still true.
  - projects/schcom/schcom and schcom-demo were tracked binaries. Untracked, and
    .gitignore'd.

Three code comments and one document described a boot that has not happened
since 7d44eb7. cons_serial_only starts set, but kmain clears it on its first
lines now, so the splash does not survive the boot and the kernel log is on
screen from the start. That reversal was earned by a Chromebox with no serial
port freezing at boot showing nothing at all, and the comments still argued the
losing side of it.

The site:

  - a download page. One ISO, what it has actually been run on -- one machine,
    under test -- Ventoy and dd, what the first boot looks like step by step,
    and the build if you would rather. The support table names one Chromebox
    rather than listing hardware, because one Chromebox is the entire bare-metal
    record and a list would be fiction.
  - Assets/usb.svg, drawn to the same rule as the other marks: two tones,
    geometry only, the accent spent in one place, and that place is the activity
    light because it is the part that tells you something is happening.
  - Download is in both navs and is the hero's primary action; a closing band
    ends the front page on it.
  - the uberblock-slots and drivers-outside-the-kernel figures are gone. Three
    numbers left, including the fastfetch one, which stays because it is funny.

Two things caught by rendering the pages instead of assuming: .hero p was
beating .filemeta on specificity and the file line was coming out at body size,
and the dd command was one line long enough that the card clipped it at `conv=`
-- a destructive command that can scroll half of itself out of view is a good
way to take somebody's disk. It is two lines now.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ7Qx8E1q1M1bbCq8QLHS2
2026-09-13 20:28:05 +02:00

692 lines
20 KiB
CSS

/* SPDX-License-Identifier: Apache-2.0
*
* The palette is not chosen here. It is include/theme.h, transcribed, because
* a site that describes an operating system should look like the operating
* system. That includes the rule theme.h enforces:
*
* normal states are calm and dark; only failure is loud.
*
* PSOGM purple (--psogm) therefore appears exactly once on this page, in the
* crash-screen section. If it ever appears anywhere else, delete it there.
*/
:root {
/* include/theme.h */
--bg: #0C0E13; /* SCH_BG */
--fg: #E6E8EC; /* SCH_FG */
--dim: #707784; /* SCH_DIM */
--accent: #7C5CFF; /* SCH_ACCENT */
--accent-dim: #2A2440; /* SCH_ACCENT_DIM */
--ok: #4ADE80; /* SCH_OK */
--warn: #FBBF24; /* SCH_WARN */
--psogm: #4B1D9A; /* PSOGM_BG — failure, and nothing else */
/* Surfaces lifted off the ground, keeping its blue bias rather than
sliding toward neutral grey. */
--surface: #12151C;
--surface-2: #171B24;
--line: #212632;
--sans: "Roboto", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
--mono: "JetBrains Mono", ui-monospace, SFMono-Regular, "Cascadia Code",
Menlo, Consolas, monospace;
--measure: 66ch;
--gap: clamp(1rem, 2.5vw, 1.75rem);
--section: clamp(4rem, 10vw, 7.5rem);
}
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
html { scroll-behavior: auto; }
}
body {
margin: 0;
background: var(--bg);
color: var(--fg);
font-family: var(--sans);
font-size: clamp(1rem, 0.95rem + 0.2vw, 1.0625rem);
line-height: 1.65;
-webkit-font-smoothing: antialiased;
}
/* ---- shared shells ------------------------------------------------- */
.wrap {
width: min(100% - 2.5rem, 68rem);
margin-inline: auto;
}
section { padding-block: var(--section); }
.eyebrow {
font-family: var(--mono);
font-size: 0.75rem;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--accent);
margin: 0 0 0.75rem;
}
h1, h2, h3 { text-wrap: balance; line-height: 1.15; margin: 0; }
h2 {
font-size: clamp(1.75rem, 1.3rem + 2vw, 2.75rem);
font-weight: 700;
letter-spacing: -0.02em;
}
.lede {
max-width: var(--measure);
color: var(--dim);
font-size: clamp(1.05rem, 1rem + 0.35vw, 1.2rem);
margin: 1.25rem 0 0;
}
p { max-width: var(--measure); }
a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--fg); }
a:focus-visible,
button:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 3px;
border-radius: 2px;
}
code, .mono { font-family: var(--mono); font-size: 0.9em; }
code { color: var(--fg); background: var(--surface-2); padding: 0.1em 0.4em; border-radius: 3px; }
/* ---- header -------------------------------------------------------- */
header.top {
position: sticky;
top: 0;
z-index: 10;
background: color-mix(in srgb, var(--bg) 88%, transparent);
backdrop-filter: blur(8px);
border-bottom: 1px solid var(--line);
}
.top .wrap {
display: flex;
align-items: center;
gap: 1.5rem;
padding-block: 0.85rem;
}
.brand {
display: flex; align-items: center; gap: 0.6rem;
font-weight: 700; letter-spacing: -0.01em;
color: inherit; text-decoration: none;
}
.brand img { width: 26px; height: 26px; display: block; }
.top nav { margin-left: auto; display: flex; gap: 1.5rem; font-size: 0.9rem; }
.top nav a { color: var(--dim); text-decoration: none; }
.top nav a:hover { color: var(--fg); }
@media (max-width: 46rem) { .top nav { display: none; } }
/* ---- hero ---------------------------------------------------------- */
.hero { padding-block: clamp(3.5rem, 9vw, 6.5rem) var(--section); }
.hero .wrap {
display: grid;
grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
gap: clamp(2rem, 5vw, 4rem);
align-items: center;
}
@media (max-width: 56rem) {
.hero .wrap { grid-template-columns: 1fr; }
}
.hero h1 {
font-size: clamp(2.75rem, 1.8rem + 4.2vw, 4.75rem);
font-weight: 700;
letter-spacing: -0.035em;
}
.hero h1 .mark {
display: inline-block;
width: 0.95em;
height: 0.95em;
vertical-align: -0.08em;
margin-right: 0.22em;
}
.hero p { color: var(--dim); font-size: clamp(1.05rem, 1rem + 0.4vw, 1.25rem); margin-top: 1.25rem; }
.hero .cta { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 2rem; }
.btn {
display: inline-block;
padding: 0.65rem 1.25rem;
border-radius: 4px;
font-size: 0.925rem;
font-weight: 500;
text-decoration: none;
border: 1px solid var(--line);
color: var(--fg);
background: var(--surface);
}
.btn:hover { border-color: var(--accent); color: var(--fg); }
.btn.primary { background: var(--accent); border-color: var(--accent); color: #0B0714; font-weight: 700; }
.btn.primary:hover { background: #8F73FF; border-color: #8F73FF; color: #0B0714; }
/* ---- console ------------------------------------------------------- */
.console {
background: #090B0F;
border: 1px solid var(--line);
border-radius: 6px;
overflow: hidden;
box-shadow: 0 24px 60px -30px #000;
}
.console-bar {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.55rem 0.85rem;
border-bottom: 1px solid var(--line);
background: var(--surface);
font-family: var(--mono);
font-size: 0.72rem;
color: var(--dim);
letter-spacing: 0.06em;
}
.console-bar .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--line); }
.console-bar .dot.live { background: var(--ok); }
.console-bar span { margin-left: auto; }
.console pre {
margin: 0;
padding: 1rem 1.1rem 1.4rem;
font-family: var(--mono);
font-size: clamp(0.72rem, 0.62rem + 0.35vw, 0.82rem);
line-height: 1.85;
color: var(--fg);
overflow-x: auto;
}
/* The hero's console reserves its height so the typing animation does not
push the page around as it fills. A static transcript sizes to its own
content instead, which is why this is not on .console pre. */
.hero .console pre { min-height: 16.5rem; }
.console.transcript { margin-top: 3rem; }
.console .t { color: var(--dim); }
.console .k { color: var(--accent); }
.console .g { color: var(--ok); }
.console .cursor {
display: inline-block;
width: 0.55em;
height: 1.05em;
background: var(--accent);
vertical-align: -0.18em;
animation: blink 1.1s step-end infinite;
}
@keyframes blink { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .console .cursor { animation: none; } }
/* ---- origin timeline ----------------------------------------------- */
.origin-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
gap: var(--gap);
margin-top: 3rem;
}
.step {
border-left: 2px solid var(--accent-dim);
padding-left: 1.1rem;
}
.step h3 { font-size: 1.05rem; font-weight: 700; margin-bottom: 0.4rem; }
.step .when { font-family: var(--mono); font-size: 0.72rem; color: var(--accent); letter-spacing: 0.08em; text-transform: uppercase; display: block; margin-bottom: 0.5rem; }
.step p { color: var(--dim); font-size: 0.925rem; margin: 0; }
/* ---- the stack ----------------------------------------------------- */
.stack { display: flex; flex-direction: column; gap: 3px; margin-top: 3rem; }
.layer {
display: grid;
grid-template-columns: 10.5rem 1fr;
gap: 1.25rem;
align-items: baseline;
padding: 0.95rem 1.15rem;
background: var(--surface);
border: 1px solid transparent;
border-radius: 3px;
}
.layer:hover { border-color: var(--accent-dim); background: var(--surface-2); }
.layer .name { font-family: var(--mono); font-size: 0.8rem; color: var(--accent); letter-spacing: 0.04em; }
.layer .what { color: var(--dim); font-size: 0.9rem; }
.layer.seam { background: var(--accent-dim); }
.layer.seam .name { color: var(--fg); }
.layer.seam .what { color: #C9BEEC; }
@media (max-width: 42rem) {
.layer { grid-template-columns: 1fr; gap: 0.3rem; }
}
.seam-note { margin-top: 1.5rem; color: var(--dim); font-size: 0.9rem; }
/* ---- features ------------------------------------------------------ */
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
gap: var(--gap);
margin-top: 3rem;
}
.card {
background: var(--surface);
border: 1px solid var(--line);
border-radius: 5px;
padding: 1.4rem;
display: flex;
flex-direction: column;
gap: 0.6rem;
}
.card h3 { font-size: 1.05rem; font-weight: 700; }
.card p { color: var(--dim); font-size: 0.925rem; margin: 0; max-width: none; }
.tag {
align-self: flex-start;
font-family: var(--mono);
font-size: 0.68rem;
letter-spacing: 0.1em;
text-transform: uppercase;
padding: 0.2rem 0.5rem;
border-radius: 3px;
border: 1px solid var(--line);
color: var(--dim);
}
.tag.runs { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 35%, transparent); }
.tag.partial{ color: var(--warn); border-color: color-mix(in srgb, var(--warn) 35%, transparent); }
.tag.planned{ color: var(--dim); }
/* ---- numbers ------------------------------------------------------- */
.figures {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
gap: var(--gap);
margin-top: 3rem;
}
.figure { border-top: 1px solid var(--line); padding-top: 1rem; }
.figure b {
display: block;
font-family: var(--mono);
font-size: clamp(1.6rem, 1.2rem + 1.6vw, 2.25rem);
font-weight: 700;
font-variant-numeric: tabular-nums;
letter-spacing: -0.02em;
}
.figure span { color: var(--dim); font-size: 0.85rem; }
/* ---- the crash screen: the one loud thing --------------------------- */
.crash { background: var(--psogm); color: #fff; }
.crash .wrap {
display: grid;
grid-template-columns: 8rem minmax(0, 1fr);
gap: clamp(1.5rem, 4vw, 3rem);
align-items: start;
}
@media (max-width: 44rem) { .crash .wrap { grid-template-columns: 1fr; } }
.crash img { width: 100%; max-width: 8rem; height: auto; }
.crash .eyebrow { color: #C3AEEC; }
.crash h2 { color: #fff; }
.crash p { color: #DBCEF5; }
.crash code { background: rgba(0, 0, 0, 0.28); color: #fff; }
/* ---- closing links -------------------------------------------------- */
.links { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: var(--gap); margin-top: 2.5rem; }
.link-card {
display: block;
padding: 1.2rem;
border: 1px solid var(--line);
border-radius: 5px;
text-decoration: none;
color: var(--fg);
background: var(--surface);
}
.link-card:hover { border-color: var(--accent); color: var(--fg); }
.link-card b { display: block; margin-bottom: 0.3rem; }
.link-card span { color: var(--dim); font-size: 0.875rem; }
footer {
border-top: 1px solid var(--line);
padding-block: 2.5rem 3.5rem;
color: var(--dim);
font-size: 0.85rem;
}
footer .wrap { display: flex; flex-wrap: wrap; gap: 1rem 2rem; align-items: center; }
footer .mono { font-size: 0.78rem; }
/* ---- reveal on scroll ---------------------------------------------- */
.reveal { opacity: 0; transform: translateY(12px); transition: opacity .5s ease, transform .5s ease; }
.reveal.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
.reveal { opacity: 1; transform: none; transition: none; }
}
/* The SchFS mark, set beside its own card heading. Baseline-aligned rather
than centred: it sits next to a word, so it follows the word. */
.card h3 .cardmark {
width: 1.15em;
height: 1.15em;
vertical-align: -0.22em;
margin-right: 0.4em;
}
/* =====================================================================
The pride mark
---------------------------------------------------------------------
Small, and permanent. It is in the top bar in November the same way it
is in June, which is the only version of this that means anything --
support with an end date is marketing.
Deliberately not bigger than this. The site is about an operating
system; the flag is a statement, not a subject.
===================================================================== */
.pride {
display: inline-flex;
align-items: center;
line-height: 0;
border-radius: 2px;
text-decoration: none;
}
.pride img {
width: 26px;
height: auto;
display: block;
border-radius: 2px;
/* Sits down slightly against the dark ground so it reads as part of the
bar rather than as a sticker on top of it; full colour on hover. */
opacity: 0.85;
transition: opacity .18s ease, transform .18s ease;
}
.pride:hover img { opacity: 1; transform: translateY(-1px); }
@media (prefers-reduced-motion: reduce) {
.pride img { transition: none; }
.pride:hover img { transform: none; }
}
.pride-note {
display: flex;
align-items: center;
gap: 0.6rem;
flex-basis: 100%;
color: var(--dim);
font-size: 0.82rem;
}
.pride-note img { width: 20px; height: auto; border-radius: 2px; flex: none; }
/* =====================================================================
The documentation reader
===================================================================== */
body.reading { display: flex; flex-direction: column; min-height: 100vh; }
body.reading footer { margin-top: auto; }
.docshell {
width: min(100% - 2.5rem, 84rem);
margin-inline: auto;
display: grid;
grid-template-columns: 15rem minmax(0, 1fr) 13rem;
gap: clamp(1.5rem, 3vw, 3rem);
align-items: start;
padding-block: 2.5rem 4rem;
}
@media (max-width: 72rem) { .docshell { grid-template-columns: 14rem minmax(0, 1fr); } .rail { display: none; } }
@media (max-width: 54rem) { .docshell { grid-template-columns: 1fr; } .sidebar .sticky { position: static; max-height: none; } }
.sticky {
position: sticky;
top: 4.5rem;
max-height: calc(100vh - 6rem);
overflow-y: auto;
scrollbar-width: thin;
}
.navgroup {
font-family: var(--mono);
font-size: 0.68rem;
letter-spacing: 0.13em;
text-transform: uppercase;
color: var(--dim);
margin: 1.6rem 0 0.5rem;
}
.navgroup:first-child { margin-top: 0; }
#docnav ul, #toc ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
#docnav a, #toc a {
display: block;
padding: 0.28rem 0.6rem;
margin-left: -0.6rem;
border-radius: 3px;
color: var(--dim);
text-decoration: none;
font-size: 0.875rem;
line-height: 1.45;
}
#docnav a:hover, #toc a:hover { color: var(--fg); background: var(--surface); }
#docnav a.on {
color: var(--fg);
background: var(--accent-dim);
box-shadow: inset 2px 0 0 var(--accent);
}
#toc .lvl3 a { padding-left: 1.5rem; font-size: 0.8rem; }
/* ---- prose ---------------------------------------------------------- */
.prose { max-width: 46rem; }
.prose .loading { color: var(--dim); font-family: var(--mono); font-size: 0.85rem; }
.prose h1 {
font-size: clamp(1.9rem, 1.4rem + 2.2vw, 2.6rem);
font-weight: 700;
letter-spacing: -0.025em;
margin: 0 0 1.25rem;
}
.prose h2 {
font-size: clamp(1.3rem, 1.1rem + 1vw, 1.65rem);
font-weight: 700;
letter-spacing: -0.015em;
margin: 2.75rem 0 0.9rem;
padding-top: 1.6rem;
border-top: 1px solid var(--line);
}
.prose h3 { font-size: 1.1rem; font-weight: 700; margin: 2rem 0 0.6rem; }
.prose h4, .prose h5, .prose h6 { font-size: 0.95rem; font-weight: 700; margin: 1.5rem 0 0.5rem; color: var(--dim); }
.prose p, .prose li { color: #C6CAD3; }
.prose p { margin: 0 0 1.1rem; max-width: none; }
.prose strong { color: var(--fg); }
.prose a { color: var(--accent); }
.prose ul, .prose ol { margin: 0 0 1.2rem; padding-left: 1.35rem; display: flex; flex-direction: column; gap: 0.4rem; }
.prose li { line-height: 1.6; }
.prose li::marker { color: var(--accent); }
.prose hr { border: 0; border-top: 1px solid var(--line); margin: 2.25rem 0; }
.prose blockquote {
margin: 1.4rem 0;
padding: 0.2rem 0 0.2rem 1.1rem;
border-left: 2px solid var(--accent);
color: var(--dim);
}
.prose blockquote p:last-child { margin-bottom: 0; }
.prose pre.code {
background: #090B0F;
border: 1px solid var(--line);
border-radius: 5px;
padding: 0.95rem 1.1rem;
overflow-x: auto;
margin: 0 0 1.3rem;
position: relative;
}
.prose pre.code code {
font-family: var(--mono);
font-size: 0.815rem;
line-height: 1.7;
color: #CBD1DC;
background: none;
padding: 0;
white-space: pre;
}
.prose pre.code[data-lang]::after {
content: attr(data-lang);
position: absolute;
top: 0.5rem;
right: 0.7rem;
font-family: var(--mono);
font-size: 0.62rem;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--dim);
}
.prose :not(pre) > code {
font-family: var(--mono);
font-size: 0.85em;
background: var(--surface-2);
border: 1px solid var(--line);
color: #D8DCE4;
padding: 0.08em 0.36em;
border-radius: 3px;
}
.tablewrap { overflow-x: auto; margin: 0 0 1.4rem; }
.prose table { border-collapse: collapse; width: 100%; font-size: 0.9rem; }
.prose th, .prose td {
text-align: left;
padding: 0.55rem 0.85rem;
border-bottom: 1px solid var(--line);
vertical-align: top;
}
.prose th {
font-family: var(--mono);
font-size: 0.72rem;
letter-spacing: 0.07em;
text-transform: uppercase;
color: var(--accent);
border-bottom-color: var(--accent-dim);
white-space: nowrap;
}
.prose td { color: #C6CAD3; }
.prose tbody tr:hover td { background: var(--surface); }
.prose img { max-width: 100%; height: auto; }
.top nav a.on { color: var(--fg); }
.readerlink { margin-top: 2rem; }
/* A footer note that is a paragraph rather than a credit line. Same width
discipline as body text: these are read, not scanned. */
footer .note {
flex-basis: 100%;
max-width: 54rem;
color: var(--dim);
font-size: 0.82rem;
line-height: 1.7;
}
footer .note b { color: var(--fg); font-weight: 700; }
footer .note a { color: var(--accent); }
/* The two notes sit below the identity line, not beside it. */
footer .wrap { row-gap: 1.5rem; }
/* ---- the download page --------------------------------------------- */
/*
* Same components as the front page, arranged for a page with one job. The
* hero here is a two-column split rather than a pitch: the action on the left,
* and immediately beside it the thing a download page usually buries, which is
* what this has actually been run on.
*/
.getit .wrap { align-items: start; }
.getit h1 { font-size: clamp(2rem, 1.5rem + 2.4vw, 3.1rem); }
.getit p { color: var(--dim); }
h2.small {
font-size: clamp(1.15rem, 1rem + 0.6vw, 1.4rem);
letter-spacing: -0.01em;
margin: 0;
}
.getpanel {
background: var(--surface);
border: 1px solid var(--line);
border-radius: 6px;
padding: clamp(1.25rem, 3vw, 1.75rem);
}
.getpanel p { font-size: 0.92rem; margin: 0.85rem 0 0; }
/* Not a data table -- a two-column list of claims, where the claim on the
right is the whole content and should line up down the page. */
.support {
width: 100%;
border-collapse: collapse;
margin-top: 1.25rem;
font-size: 0.9rem;
}
.support td { padding: 0.55rem 0; border-top: 1px solid var(--line); }
.support tr:first-child td { border-top: 0; }
.support td:last-child { text-align: right; white-space: nowrap; }
.dimtext { color: var(--dim); }
.getit .filemeta {
margin-top: 1.25rem;
font-family: var(--mono);
font-size: 0.78rem;
color: var(--dim);
}
.fineprint, .getpanel .fineprint, .card .fineprint {
color: var(--dim);
font-size: 0.82rem;
line-height: 1.65;
}
/* Two columns rather than as-many-as-fit: these two are a pair to be compared,
and a three-up row would put the destructive one somewhere it reads as an
equal option. */
.cards.two { grid-template-columns: repeat(auto-fit, minmax(21rem, 1fr)); }
/* A command you are meant to type, as opposed to output you are meant to read
-- which is what .console is for. The prompt is dim because it is not part
of what you type, and the part to substitute is the accent, because that is
the only decision in the line. */
.cmd {
margin: 1.1rem 0 0;
padding: 0.8rem 0.9rem;
background: #090B0F;
border: 1px solid var(--line);
border-radius: 4px;
font-family: var(--mono);
font-size: 0.78rem;
line-height: 1.8;
color: var(--fg);
overflow-x: auto;
}
.cmd.block { margin-top: 2.5rem; font-size: 0.82rem; padding: 1.1rem 1.2rem; }
.cmd .p { color: var(--dim); user-select: none; }
.cmd .v { color: var(--accent); }
.cmd .c { color: var(--dim); }
/* The closing band on the front page. Same two-column shape as the crash
section, so the page ends the way it turns: a mark on the left, the thing to
do on the right. */
.getband { border-top: 1px solid var(--line); }
.getband .wrap {
display: grid;
grid-template-columns: clamp(5rem, 10vw, 8rem) minmax(0, 1fr);
gap: clamp(1.5rem, 4vw, 3rem);
align-items: center;
}
.getband img { width: 100%; height: auto; display: block; }
.getband .readerlink { display: flex; flex-wrap: wrap; gap: 0.75rem; }
@media (max-width: 40rem) {
.getband .wrap { grid-template-columns: 1fr; }
.getband img { width: 5rem; }
}