Files
bench/site/static/site.css
T
istos 26e6bb333d site: point the landing page at the reader's problem, not the mechanics
The hero explained the architecture before saying why anyone would care:
'task files in stage directories', 'stdlib-only', 'narrates' are words
that mean something once you already use bench. Every line now maps to
something the audience has actually hit — agents outrunning the person
supposed to be tracking them.

- Hero: 'Run a team of coding agents. Stay in control.' The old headline
  keeps its job as the brand line, in the footer of every layout.
- A new section between hero and doors: three sentences a reader has
  said out loud, each answered by a mechanism rather than a promise.
  Deliberately unboxed — the doors below are the page's one grid of
  cards, and repeating that shape would make the eye work twice.
- The six doors lead with the outcome and keep one mechanism as the
  evidence for it, which is the inversion of what they did before.
- Title and description follow, since a pasted url is the same pitch in
  another form.

Two lines that were quietly false are fixed too: the strip's comment
still said this site counts nothing (Fathom counts pageviews now), and
'no per-seat pricing' would have tripped the fiction guard in
tests/test_site_landing.py, which forbids the word outright.
2026-07-31 16:04:03 +02:00

540 lines
23 KiB
CSS

/* ── Bench docs: the Daylight register of the board's own system ───────
The four state tokens are named exactly as manager/core/board.html
names them — --accent (surf), --calm (pine), --alarm (terracotta),
--idle (driftwood) — because the site and the board are one system,
and colour in both only ever means state. Their values are the board's
light theme; the neutrals are the docs design's paper register.
Fonts are self-hosted: reading bench's docs must not require a request
to anyone else. site/static/fonts/README.md says which files these
@font-face rules want and how to fetch them.
------------------------------------------------------------------- */
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:400;font-display:swap;src:url("/static/fonts/IBMPlexSans-Regular.woff2") format("woff2")}
@font-face{font-family:'IBM Plex Sans';font-style:italic;font-weight:400;font-display:swap;src:url("/static/fonts/IBMPlexSans-Italic.woff2") format("woff2")}
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:500;font-display:swap;src:url("/static/fonts/IBMPlexSans-Medium.woff2") format("woff2")}
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:600;font-display:swap;src:url("/static/fonts/IBMPlexSans-SemiBold.woff2") format("woff2")}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:400;font-display:swap;src:url("/static/fonts/IBMPlexMono-Regular.woff2") format("woff2")}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:500;font-display:swap;src:url("/static/fonts/IBMPlexMono-Medium.woff2") format("woff2")}
@font-face{font-family:'Zilla Slab';font-style:normal;font-weight:600;font-display:swap;src:url("/static/fonts/ZillaSlab-SemiBold.woff2") format("woff2")}
:root{
/* paper */
--bg:#c9dde1; --canvas:#eaf3f4; --surface:#ffffff; --sunken:#e0eef1;
--border:#c5d7db; --border-soft:#d9e6e9;
--text:#12323b; --muted:#4d6e77; --dim:#87a1a8;
/* state — the same four the board carries */
--accent:#0d6e8c; --calm:#5f7f33; --alarm:#b1543a; --idle:#93a8ac;
--on-accent:#ffffff;
/* dark ink: code, terminals, chrome */
--ink:#0c1a20; --ink-deep:#0a161b; --ink-line:#1c343a;
--ink-text:#e9f3f3; --ink-muted:#95afb4; --ink-dim:#62828a;
--ink-accent:#56c2d8; --ink-calm:#a6c96f; --ink-alarm:#e08a63;
/* tinted callouts, both state colours */
--calm-wash:#f4f8e6; --calm-edge:#d6e2a8; --calm-ink:#4a6329;
--alarm-wash:#fbf1ec; --alarm-edge:#ecc9b8; --alarm-ink:#7a3c2a;
--sans:'IBM Plex Sans',system-ui,-apple-system,sans-serif;
--mono:'IBM Plex Mono',ui-monospace,SFMono-Regular,Menlo,monospace;
--display:'Zilla Slab',Georgia,'Times New Roman',serif;
/* type scale, straight off the design */
--t-hero:52px; --t-title:40px; --t-h2:23px; --t-h3:17px;
--t-lede:17px; --t-body:15px; --t-ui:13.5px; --t-code:12.5px;
--t-micro:10.5px;
--radius:11px; --shadow:0 20px 50px -34px rgba(18,50,59,.55);
--shadow-ink:0 18px 40px -30px rgba(12,26,32,.9);
/* The smallest thing a finger is asked to hit. It is a token rather
than a number typed seven times because it is one decision, and the
narrow steps below are where it is spent. */
--tap:44px;
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
background:var(--canvas); color:var(--text);
font:var(--t-body)/1.68 var(--sans);
-webkit-font-smoothing:antialiased;
}
a{color:var(--accent);text-decoration:none}
a:hover{color:var(--text);text-decoration:underline}
::selection{background:var(--accent);color:var(--on-accent)}
.mono{font-family:var(--mono)}
.dim{color:var(--dim)}
.spacer{flex:1}
.rule{height:1px;background:var(--border-soft);margin:12px 0}
@media (prefers-reduced-motion: reduce){
*,*::before,*::after{animation:none !important;transition:none !important}
}
/* ── chrome ── */
.topbar{
display:flex;align-items:center;gap:10px;height:30px;padding:0 18px;
background:var(--text);color:#a9c4c9;
font:11px/1 var(--mono);
}
.topbar-org{color:var(--canvas);font-weight:500}
.topbar-sep{color:var(--muted)}
.topbar-repo{color:var(--ink-accent)}
.masthead{
display:flex;align-items:center;gap:20px;padding:14px 30px;
background:var(--surface);border-bottom:1px solid var(--border);
}
.masthead-flat{background:var(--canvas);border-bottom:0}
.wordmark{display:flex;align-items:baseline;gap:9px}
.wordmark:hover{text-decoration:none}
.wordmark-name{
font:600 21px/1 var(--display);letter-spacing:-.015em;color:var(--text);
}
.wordmark-tag{font:12px/1 var(--mono);color:var(--dim)}
.nav{display:flex;gap:18px;font-size:var(--t-ui)}
.nav-link{color:var(--muted);padding-bottom:2px;border-bottom:2px solid transparent}
.nav-link:hover{color:var(--text);text-decoration:none}
.nav-here{color:var(--text);font-weight:600;border-bottom-color:var(--accent)}
.button{
display:inline-block;padding:7px 13px;font:500 var(--t-ui)/1.4 var(--sans);
color:var(--text);background:transparent;
border:1px solid var(--border);border-radius:8px;
}
.button:hover{border-color:var(--accent);color:var(--accent);text-decoration:none}
.button-solid{background:var(--accent);color:var(--on-accent);border-color:var(--accent)}
.button-solid:hover{background:var(--text);border-color:var(--text);color:var(--on-accent)}
.button-lg{padding:11px 18px;font-size:14px}
.footer{
display:flex;align-items:flex-end;gap:26px;padding:22px 26px;
background:var(--text);color:#a9c4c9;margin-top:40px;
}
.footer-mark{margin:0;font:9.5px/1.25 var(--mono);color:var(--muted)}
.footer-id{display:flex;flex-direction:column;gap:4px}
.footer-name{font:600 15px/1 var(--display);color:var(--canvas)}
/* The line that used to be the h1. It says what bench is about in the
register the product speaks in; the h1 above now says what it does
for you. */
.footer-line{font-size:var(--t-ui);color:var(--ink-muted)}
.footer-id .mono,.footer-repo{font-size:11px}
.footer-repo{color:#a9c4c9}
/* ── article layout (1a Harbour) ── */
.shell{
display:grid;grid-template-columns:236px minmax(0,1fr) 208px;
background:var(--surface);
}
.side{
border-right:1px solid var(--border-soft);
padding:22px 16px 40px;display:flex;flex-direction:column;gap:22px;
}
.side-group{display:flex;flex-direction:column;gap:7px}
.side-label{
font:var(--t-micro)/1 var(--mono);letter-spacing:.1em;
text-transform:uppercase;color:var(--dim);padding-left:9px;
}
.side-link{font-size:var(--t-ui);color:var(--muted);padding:4px 9px;border-radius:0 6px 6px 0}
.side-link:hover{color:var(--text);text-decoration:none}
.side-here{
font-weight:600;color:var(--text);background:var(--sunken);
border-left:2px solid var(--accent);
}
.side-note{
display:flex;flex-direction:column;gap:5px;margin-top:6px;
padding:11px 12px;background:var(--canvas);
border:1px solid var(--border-soft);border-radius:10px;
font-size:12.5px;line-height:1.45;color:var(--muted);
}
.side-note .mono{font-size:var(--t-micro)}
.gutter{border-left:1px solid var(--border-soft);padding:30px 18px}
.toc{display:flex;flex-direction:column;gap:9px;position:sticky;top:20px}
.toc-label{
font:var(--t-micro)/1 var(--mono);letter-spacing:.1em;
text-transform:uppercase;color:var(--dim);margin-bottom:2px;
}
.toc-link{
font-size:12.5px;color:var(--muted);
border-left:2px solid var(--sunken);padding-left:9px;
}
.toc-link:hover{color:var(--accent);border-left-color:var(--accent);text-decoration:none}
.gutter-link{font-size:12.5px;line-height:1.5;color:var(--muted)}
.marginalia{
margin-top:36px;font:italic 11px/1.55 var(--mono);color:var(--alarm);
transform:rotate(-1.2deg);transform-origin:left top;
}
.marginalia .mono{font-size:11px}
.crumbs{
display:flex;align-items:center;gap:8px;margin-bottom:16px;
font:11.5px/1 var(--mono);color:var(--dim);
}
.crumb-here{color:var(--muted)}
/* ── generated prose ── */
.page-article .prose{padding:30px 40px 44px;min-width:0}
/* The lede is the article's own sentence; everything after it is the
slice. It reads wider and quieter than body copy, as in the design. */
.prose-lede{
margin:0 0 26px;max-width:60ch;
font-size:var(--t-lede);line-height:1.6;color:var(--muted);
text-wrap:pretty;
}
.prose h1{
font:600 var(--t-title)/1.1 var(--display);letter-spacing:-.02em;
margin:0 0 12px;
}
.prose h2{
font:600 var(--t-h2)/1.3 var(--display);letter-spacing:-.01em;
margin:34px 0 10px;scroll-margin-top:20px;
}
.prose h3{font:600 var(--t-h3)/1.4 var(--sans);margin:26px 0 8px}
/* The lede is the body's first paragraph. The collapsed contents strip
sits between it and the h1 — display:none at the design's width, but
still a sibling — so the adjacency has to name it too, or the lede
would quietly become an ordinary paragraph on desktop. */
.prose h1 + p,.prose .menu-contents + p,.prose > p:first-child{
font-size:var(--t-lede);line-height:1.6;color:var(--muted);max-width:60ch;
}
.prose p{margin:0 0 16px;color:var(--muted);max-width:64ch;text-wrap:pretty}
.prose strong{color:var(--text);font-weight:600}
.prose ul,.prose ol{margin:0 0 18px;padding-left:22px;max-width:64ch;color:var(--muted)}
.prose li{margin:0 0 7px}
.prose li > ul,.prose li > ol{margin:7px 0 0}
.prose hr{border:0;border-top:1px solid var(--border-soft);margin:30px 0}
.prose blockquote{
margin:0 0 20px;padding:14px 16px;background:var(--canvas);
border:1px solid var(--border-soft);border-left:3px solid var(--accent);
border-radius:0 10px 10px 0;color:var(--text);
}
.prose blockquote p:last-child{margin:0}
/* No page slices an image today. When one does, it is the only element
in generated markdown that arrives with its own intrinsic width, and
a 1200px screenshot on a 390px screen would widen the page itself. */
.prose img{max-width:100%;height:auto}
.prose code{
font:var(--t-code)/1.5 var(--mono);
background:var(--canvas);border-radius:4px;padding:1px 5px;
color:var(--text);
}
.prose pre{
margin:0 0 24px;padding:16px 18px;overflow-x:auto;
background:var(--ink);color:var(--ink-text);
font:var(--t-code)/1.75 var(--mono);
border-radius:var(--radius);box-shadow:var(--shadow-ink);
}
.prose pre code{background:transparent;padding:0;color:inherit;font-size:inherit}
.prose table{
border-collapse:separate;border-spacing:0;margin:0 0 26px;width:100%;
background:var(--surface);border:1px solid var(--border-soft);
border-radius:10px;overflow:hidden;font-size:var(--t-ui);
}
.prose th{
text-align:left;padding:9px 14px;background:var(--canvas);
border-bottom:1px solid var(--border-soft);
font:var(--t-micro)/1.4 var(--mono);letter-spacing:.08em;
text-transform:uppercase;color:var(--dim);
}
.prose td{padding:11px 14px;border-bottom:1px solid var(--canvas);color:var(--muted);vertical-align:top}
.prose tr:last-child td{border-bottom:0}
/* Prev/next along the same order the sidebar shows. An absent neighbour
leaves a .spacer in its slot, so `next →` stays right-hand on the first
page exactly as it does on every other. */
.flow{
display:flex;gap:14px;margin-top:44px;padding-top:22px;
border-top:1px solid var(--border-soft);
}
.flow-link{
display:flex;flex-direction:column;gap:5px;flex:0 1 auto;max-width:46%;
padding:12px 16px;background:var(--surface);
border:1px solid var(--border-soft);border-radius:11px;color:var(--text);
}
.flow-link:hover{border-color:var(--accent);color:var(--text);text-decoration:none}
.flow-next{margin-left:auto;text-align:right}
.flow-dir{font-size:var(--t-micro);letter-spacing:.08em;color:var(--dim)}
.flow-title{font:600 15px/1.3 var(--display)}
/* ── home layout (1b Dockside) ── */
.hero{
display:grid;grid-template-columns:1.05fr .95fr;gap:44px;
padding:44px 44px 40px;align-items:center;
}
.hero-copy{display:flex;flex-direction:column;gap:20px}
.eyebrow{
font:11px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;
color:var(--accent);
}
.hero h1{
margin:0;font:600 var(--t-hero)/1.05 var(--display);
letter-spacing:-.025em;text-wrap:balance;
}
.lede{
margin:0;max-width:44ch;font-size:var(--t-lede);line-height:1.62;
color:var(--muted);text-wrap:pretty;
}
.hero-actions{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.aside-note{font-size:11.5px;font-style:italic;color:var(--dim)}
.terminal{border-radius:12px;overflow:hidden;box-shadow:0 24px 46px -30px rgba(12,26,32,.85)}
.terminal-bar{
display:flex;align-items:center;gap:8px;padding:9px 14px;
background:var(--ink-deep);
}
.dot{width:8px;height:8px;border-radius:99px}
.dot-alarm{background:var(--ink-alarm)}
.dot-calm{background:var(--ink-calm)}
.terminal-title{font-size:11px;color:var(--ink-dim);margin-left:6px}
/* The transcript below is real output with the long stretches cut, and
the bar is where it says so — a claim about the block, not decoration. */
.terminal-note{font-size:10.5px;color:var(--ink-dim);letter-spacing:.04em}
.terminal-body{
margin:0;padding:18px;background:var(--ink);color:var(--ink-text);
font:var(--t-code)/1.85 var(--mono);
/* The release url is 72 characters and has to wrap rather than clip;
`anywhere` breaks it, and breaks a word only when a word is what
does not fit — the transcript's prose lines wrap normally. */
white-space:pre-wrap;overflow-wrap:anywhere;
}
.t-calm{color:var(--ink-calm)}
.t-accent{color:var(--ink-accent)}
.t-muted{color:var(--ink-muted)}
.t-dim{color:var(--ink-dim)}
/* The three sentences between the hero and the doors. Quiet on purpose:
no cards, no borders, no colour — the doors below are the page's one
grid of boxes, and repeating that shape here would make the reader
look twice at the same thing. The said-out-loud line takes the
display face; its answer is body copy. */
.snags{padding:8px 44px 30px}
.snags-title{
margin:0 0 20px;font:600 var(--t-h2)/1.3 var(--display);
letter-spacing:-.01em;color:var(--text);
}
.snag-list{
display:grid;grid-template-columns:repeat(3,1fr);gap:22px;
}
.snag{display:flex;flex-direction:column;gap:6px}
.snag-said{
font:600 var(--t-h3)/1.4 var(--display);color:var(--text);
text-wrap:pretty;
}
.snag-answer{
font-size:var(--t-ui);line-height:1.6;color:var(--muted);
text-wrap:pretty;
}
/* Every door is a link to a page this site builds — the whole card is
the target, so the hover is the card's border rather than an
underline under three words of it. */
.doors{
display:grid;grid-template-columns:repeat(3,1fr);gap:14px;
padding:0 44px 34px;
}
.door{
display:flex;flex-direction:column;gap:8px;padding:20px;
background:var(--surface);border:1px solid var(--border-soft);
border-radius:12px;color:var(--text);
}
.door:hover{border-color:var(--accent);color:var(--text);text-decoration:none}
.door-dark{background:var(--text);border-color:var(--text);color:var(--canvas)}
.door-dark:hover{border-color:var(--accent);color:var(--canvas)}
.door-index{font-size:11px;color:var(--dim)}
.door-dark .door-index{color:#7fa0a8}
.door-title{font:600 19px/1.2 var(--display)}
.door-text{font-size:var(--t-ui);line-height:1.6;color:var(--muted)}
.door-dark .door-text{color:#a9c4c9}
.door .mono{font-size:var(--t-code)}
/* The strip at the foot of the landing page. It carries the version and
nothing else measurable, because the version is the only thing about
itself this site can measure. */
.strip{
display:flex;align-items:center;gap:14px;flex-wrap:wrap;
padding:18px 44px;background:var(--sunken);
border-top:1px solid var(--border-soft);
}
.strip-label{
font-size:var(--t-micro);letter-spacing:.1em;text-transform:uppercase;
color:var(--dim);
}
.strip-version{
font-size:var(--t-code);padding:4px 10px;background:var(--surface);
border:1px solid var(--border);border-radius:99px;color:var(--accent);
}
.strip-text{font-size:12.5px;line-height:1.55;color:var(--muted);max-width:64ch}
.strip-text .mono{font-size:var(--t-code)}
.strip-link{font-size:12px;color:var(--accent)}
/* ── 404 (layout "notfound") ── */
.lost{
display:flex;flex-direction:column;align-items:flex-start;gap:18px;
padding:76px 44px 96px;max-width:60ch;
}
.lost-code{
font-size:11px;letter-spacing:.14em;color:var(--alarm);
}
.lost h1{
margin:0;font:600 var(--t-hero)/1.05 var(--display);
letter-spacing:-.025em;text-wrap:balance;
}
/* ── the columns a narrow screen folds away ──
The article is drawn with three columns and a phone has room for one.
Both of the ones it loses come back as a <details> the page can open:
the section nav as a menu under the masthead, the contents as a strip
under the title. Each is display:none until the step that hides its
column shows it, so at the design's width none of this renders — and
because the strips are <details>, one menu that opens and closes cost
this site no script at all. */
.menu{display:none}
.menu-summary{
display:flex;align-items:center;gap:8px;min-height:var(--tap);
padding:9px 18px;cursor:pointer;list-style:none;
font:500 var(--t-ui)/1.4 var(--sans);color:var(--text);
background:var(--surface);border-bottom:1px solid var(--border-soft);
}
.menu-summary::-webkit-details-marker{display:none}
.menu-summary::after{content:"▾";margin-left:auto;font-size:11px;color:var(--dim)}
.menu[open] > .menu-summary::after{content:"▴"}
.menu-panel{
display:flex;flex-direction:column;gap:4px;
max-height:min(62vh,460px);overflow-y:auto;
padding:10px 14px 16px;background:var(--surface);
border-bottom:1px solid var(--border-soft);
}
.menu-panel .side-link,.menu-panel .toc-link{
display:flex;align-items:center;min-height:var(--tap);
}
.menu-panel .side-group{gap:2px}
/* The contents strip sits inside the prose, so it is a card rather than
a bar across the page — and it says "On this page" once: the summary
is the label, and $toc's own label folds away underneath it. */
.menu-contents{
margin:0 0 22px;border:1px solid var(--border-soft);
border-radius:10px;overflow:hidden;
}
.menu-contents .menu-summary{
background:var(--canvas);border-bottom:0;padding:9px 14px;
}
.menu-contents[open] .menu-summary{border-bottom:1px solid var(--border-soft)}
.menu-contents .menu-panel{border-bottom:0;padding:8px 14px 12px}
.menu-contents .toc-label{display:none}
/* A body with no h2s has no contents: render_contents gives the strip
nothing, and a summary over an empty panel is worse than no strip. */
.menu-contents:not(:has(a)){display:none}
/* ── narrow ──
The design is drawn at 1180px and everything below this comment is
what happens under it. Three steps, each giving up what no longer
fits and handing back a way to reach it: 1080 the contents gutter,
760 the section sidebar and the top of the type scale, 480 the last
of the desktop's padding. Every query is a max-width at or below
1080, so at the design's own width the sheet above is the whole
stylesheet. */
@media (max-width:1080px){
.shell{grid-template-columns:220px minmax(0,1fr)}
.gutter{display:none}
.menu-contents{display:block}
.hero{grid-template-columns:minmax(0,1fr);gap:28px;padding:32px 24px}
.doors{grid-template-columns:repeat(2,minmax(0,1fr));padding:0 24px 28px}
.snags{padding:8px 24px 26px}
.snag-list{grid-template-columns:repeat(2,minmax(0,1fr));gap:20px}
.strip{padding:18px 24px}
/* Only a code block or a table may scroll sideways, so a token that
cannot break — a url, a curl one-liner in running text — breaks
rather than making the page wider than the screen. Fenced code is
untouched: white-space:pre forbids wrapping, which is why `pre`
carries overflow-x:auto instead. */
.prose :not(pre) > code{overflow-wrap:anywhere}
.prose h1,.prose h2,.prose h3{overflow-wrap:break-word}
/* A table is the one block that cannot reflow — its columns are its
meaning — so it becomes its own scroller. display:block makes the
table element the scroll container; the two edge shadows are
painted on the box (scroll) and covered by a patch of surface
painted on the content (local), so each one appears only while
there really is more that way. The cost is that a table narrower
than the column no longer stretches to fill it: the inner table box
an unblocked <table> generates sizes to its own content. */
.prose table{
display:block;width:100%;max-width:100%;overflow-x:auto;
background-image:
linear-gradient(to right,var(--surface),rgba(255,255,255,0)),
linear-gradient(to left,var(--surface),rgba(255,255,255,0)),
linear-gradient(to right,rgba(18,50,59,.20),rgba(18,50,59,0)),
linear-gradient(to left,rgba(18,50,59,.20),rgba(18,50,59,0));
background-position:0 0,100% 0,0 0,100% 0;
background-size:26px 100%,26px 100%,13px 100%,13px 100%;
background-repeat:no-repeat;
background-attachment:local,local,scroll,scroll;
}
}
@media (max-width:760px){
:root{
/* The design's 52px hero and 40px title are drawn for a 1180px
frame. The step comes down; the voice does not — --display is
still Zilla Slab, here and at every width below. */
--t-hero:36px; --t-title:30px; --t-h2:21px; --t-h3:16.5px;
--t-lede:16.5px;
}
.shell{grid-template-columns:minmax(0,1fr)}
.side{display:none}
.menu{display:block}
.page-article .prose{padding:24px 20px 36px}
.doors{grid-template-columns:minmax(0,1fr)}
.snag-list{grid-template-columns:minmax(0,1fr);gap:18px}
.masthead{padding:12px 18px;gap:12px;flex-wrap:wrap}
.crumbs{flex-wrap:wrap}
.footer{flex-wrap:wrap;gap:16px 20px;padding:20px 18px}
/* A spacer holds one end of a row against the other. Once the row
wraps there are no two ends, and all it can still do is take a
line of its own — so it goes, and the footer stacks. */
.footer .spacer{display:none}
.lost{padding:48px 20px 64px}
/* Tap targets: everything a finger has to hit is at least --tap tall.
Links inside running prose are the exception, because a line of
text cannot be 44px without stopping being a line of text. */
.wordmark,.nav-link,.button,.side-link,.toc-link,.strip-link,
.footer-repo{
display:inline-flex;align-items:center;min-height:var(--tap);
}
.button{justify-content:center}
.nav{gap:4px;flex-wrap:wrap}
.nav-link{padding:0 8px}
.side-link{padding:0 9px}
.toc-link{padding:0 0 0 9px}
}
@media (max-width:480px){
:root{
--t-hero:31px; --t-title:26px; --t-h2:19px;
/* Body text goes the other way: 15px is a desktop reading distance
and a phone is held closer to nothing. The lede keeps its notch
above it, or it stops being a lede. */
--t-body:16px; --t-lede:17.5px;
}
.topbar{padding:0 14px}
.masthead{padding:10px 14px;gap:8px 12px}
/* As in the footer: with the button no longer held at a far edge,
the wordmark, the nav and it share the row until they cannot, and
then wrap. */
.masthead .spacer{display:none}
.hero{padding:26px 16px}
.hero-actions{gap:8px}
.hero-actions .button{width:100%}
.doors{padding:0 16px 24px}
.snags{padding:8px 16px 22px}
.strip{padding:16px}
.page-article .prose{padding:20px 16px 32px}
.menu-summary{padding:9px 14px}
.footer{padding:18px 14px}
.lost{padding:40px 16px 56px}
}