/* The book's stylesheet. Prose is a serif and every piece of furniture is a sans, so a bold
   lead-in inside a paragraph never reads as a heading. The palette is blue-grey with accents
   that each mean one thing, shared with the lab so an experiment sits on the page rather than
   on top of it. */

/* The book's monospace font travels with it (public/fonts, SIL Open Font License): a phone's own
   monospace font may lack the box-drawing characters DuckDB draws its plans with, and borrowing
   them from another font pulls the boxes apart. */
@font-face { font-family: "JetBrains Mono"; font-weight: 400; font-display: swap;
             src: url("public/fonts/JetBrainsMono-Regular.woff2") format("woff2"); }
@font-face { font-family: "JetBrains Mono"; font-weight: 700; font-display: swap;
             src: url("public/fonts/JetBrainsMono-Bold.woff2") format("woff2"); }
:root {
  color-scheme: light dark;
  --ink: #263238; --muted: #41555e; --faint: #5a707b;
  --edge: #dfe5e8; --rule: #c4d0d6;
  --bg: #fdfdfc; --panel: #f2f6f7; --code: #f0f4f6; --raise: rgba(38,50,56,.06);
  --accent: #35648f; --on-accent: #ffffff; --wash: rgba(53,100,143,.09);
  --warn: #c8791a; --stop: #b3413a; --go: #2e7d32;
  /* Syntax colours: quiet, and legible on --code in both themes. */
  --tok-comment: #6b7d86; --tok-string: #2e7d32; --tok-number: #9c4f96;
  --tok-keyword: #35648f; --tok-type: #8a5a14; --tok-attr: #6b7d86;
  --chrome: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --text: Charter, "Bitstream Charter", "Sitka Text", Cambria, Georgia, serif;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, "DejaVu Sans Mono", monospace;
  --top: 3.1rem;
  /* The unit the page's widths are laid out in: the reader's text size, but never less than
     16px. `rem` alone follows a browser's font setting down as well as up, while the prose is
     set in px and does not, so a reader with 10px text would get both rails, the column and
     the page's own cap at ten sixteenths of their size around a chapter that had not moved.
     Larger text still widens the layout, which is what the rails' px caps are for. */
  --u: max(1rem, 16px);
  /* Two widths, each what its content needs, centred on the same middle. The prose keeps its
     measure at every width. Anything that cannot fit in it (a panel, the workbench, and a block
     of code or a table only when it would be cut off at the measure, which the page measures)
     takes one wider column. One, not two: a chapter with three left edges reads as three
     columns stacked. 72 of them because the book's Rust is formatted to 100 columns and its
     Python to 110, which at the code's 13.5px is 850 and 930 pixels with the block's padding,
     and the byte map puts its tree beside a sixteen-byte hex dump. Whatever is still wider says
     so, and takes the window on a button. */
  --measure: calc(var(--u) * 46);
  --wide: calc(var(--u) * 72);
  --pad: clamp(1rem, 4vw, 2.6rem);
  /* The middle column is sized by the book, not by the window: the wide column and its padding,
     and never more. Past that, a wider window gives the rails its spare width before the
     margins get any. Two ramps rather than one step: the first starts where the middle column
     stops needing every pixel, about 1440px, which is where it still clears a hundred columns
     of code beside both rails (a rem later than the arithmetic says, because `100vw` counts a
     classic scrollbar the layout does not have). The chapter list takes four fifths of it,
     because its titles are the ones that wrap. Past that the column is at the wide width and
     has no use for another pixel until the window is wider still, so a second ramp gives the
     rails the rest before the margins get any, most of it to the outline, whose section titles
     are the longest entries on the page. */
  --rails: clamp(0px, (100vw - var(--u) * 91) * 0.8, var(--u) * 5);
  --spare: clamp(0px, 100vw - var(--u) * 97.25, var(--u) * 7.5);
  /* Capped in px, and the cap is what each rail reaches at default text on the widest window,
     so nothing moves for a reader on browser defaults. It bites when the reader's text is
     larger, and it has to: in a `@media` rule `rem` is 16px whatever the reader has set, so at
     24px text the layout would decide there was room for both rails at 72rem and then draw
     them half as wide again, over the chapter. */
  --nav: min(calc(var(--u) * 17 + var(--rails) * 0.8 + var(--spare) * 0.2), 360px);
  --toc: min(calc(var(--u) * 14 + var(--rails) * 0.2 + var(--spare) * 0.8), 336px);
}
/* Registered, so each is computed once, here, as pixels: the script that decides whether the
   outline has room reads them, and an unregistered property would hand it back its own text. */
@property --measure { syntax: "<length>"; inherits: true; initial-value: 736px; }
@property --wide { syntax: "<length>"; inherits: true; initial-value: 1152px; }
@property --pad { syntax: "<length>"; inherits: true; initial-value: 16px; }
@property --rails { syntax: "<length>"; inherits: true; initial-value: 0px; }
@property --spare { syntax: "<length>"; inherits: true; initial-value: 0px; }
@property --nav { syntax: "<length>"; inherits: true; initial-value: 272px; }
@property --toc { syntax: "<length>"; inherits: true; initial-value: 224px; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ink: #dde4e8; --muted: #a7b8c1; --faint: #83949d;
    --edge: #2b363c; --rule: #3d4b53;
    --bg: #14191c; --panel: #1b2327; --code: #1b2327; --raise: rgba(0,0,0,.4);
    --accent: #7fb2dd; --on-accent: #10171b; --wash: rgba(127,178,221,.14);
    --warn: #e0a34e; --stop: #e8756c; --go: #81c784;
    --tok-comment: #83949d; --tok-string: #9ccc9e; --tok-number: #d6a3d1;
    --tok-keyword: #8fbfe6; --tok-type: #e0b46e; --tok-attr: #83949d;
  }
}
:root[data-theme="dark"] {
  --ink: #dde4e8; --muted: #a7b8c1; --faint: #83949d;
  --edge: #2b363c; --rule: #3d4b53;
  --bg: #14191c; --panel: #1b2327; --code: #1b2327; --raise: rgba(0,0,0,.4);
  --accent: #7fb2dd; --on-accent: #10171b; --wash: rgba(127,178,221,.14);
  --warn: #e0a34e; --stop: #e8756c; --go: #81c784;
  --tok-comment: #83949d; --tok-string: #9ccc9e; --tok-number: #d6a3d1;
  --tok-keyword: #8fbfe6; --tok-type: #e0b46e; --tok-attr: #83949d;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: calc(var(--top) + 1rem); }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body { margin: 0; background: var(--bg); color: var(--ink);
       font: 18px/1.62 var(--text); text-rendering: optimizeLegibility;
       -webkit-font-smoothing: antialiased; }
a { color: var(--accent); text-decoration-thickness: from-font; text-underline-offset: 2px; }
a.xref { font-style: italic; text-decoration: none; }
a.xref:hover { text-decoration: underline; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 2px; }

/* The header */
.top { position: sticky; top: 0; z-index: 20; height: var(--top); display: flex;
       align-items: center; gap: .75rem; padding: 0 1rem; background: var(--bg);
       border-bottom: 1px solid var(--edge); font-family: var(--chrome); }
.brand { font-weight: 600; font-size: 15px; letter-spacing: -.01em; color: var(--ink);
         text-decoration: none; margin-right: auto; }
.brand span { color: var(--muted); font-weight: 400; }
.top button { font: 13.5px/1 var(--chrome); color: var(--muted); background: var(--panel);
              border: 1px solid var(--edge); border-radius: 6px; padding: .45rem .7rem;
              cursor: pointer; }
.top button:hover { border-color: var(--accent); color: var(--accent); }
/* Written `hidden` and shown by the script that makes it work: `display` on a class would beat
   the browser's own rule for the attribute. */
.top [hidden] { display: none; }

/* Three columns: chapters, the page, and the page's own outline. Each rail is hidden until
   there is room for it, and declared hidden before the rules that show it, so those win by order.
   Two steps, not one: the prose needs 58rem beside the chapter list and 72rem beside both, and
   one breakpoint at the larger would leave a 1024px tablet with no chapter list and a third of
   its width empty. Below the first, the Chapters button opens the list over the page. */
.layout { display: grid; grid-template-columns: minmax(0, calc(var(--wide) + 2 * var(--pad)));
          justify-content: center; }
.nav, .toc { display: none; position: sticky; top: var(--top); align-self: start;
             height: calc(100vh - var(--top)); overflow-y: auto; overscroll-behavior: contain;
             font: 14px/1.45 var(--chrome); padding: 1.4rem 1rem 3rem; }
@media (max-width: 57.99rem) {
  /* Stretched between the bar and the bottom of the screen, and scrolled within: a fixed box keeps
     the column's `align-self: start`, which would size it to the list and, once the list is taller
     than the screen, push its top under the bar. */
  .nav { position: fixed; inset: var(--top) 0 0 0; z-index: 15; height: auto; align-self: stretch;
         background: var(--bg); }
  body.nav-open .nav { display: block; }
}
/* The middle column is the widest thing a chapter holds, and the group of columns is what
   centres: `1fr` would make it whatever the window has left, a column sized by the screen
   rather than by the book. Each rail has a button of its own in the top bar, so a reader can
   give the chapter back 272px, 224px or both. The outline also goes by itself when showing it
   would leave the chapter narrower than its content needs (`toc-cramped`, set by the script,
   because a media query cannot see the reader's text size), and on a page with no sections. */
@media (min-width: 58rem) {
  .layout { grid-template-columns: var(--nav) minmax(0, calc(var(--wide) + 2 * var(--pad))); }
  .nav { display: block; }
  html.nav-closed .layout { grid-template-columns: minmax(0, calc(var(--wide) + 2 * var(--pad))); }
  html.nav-closed .nav { display: none; }
}
@media (min-width: 72rem) {
  .layout { grid-template-columns: var(--nav) minmax(0, calc(var(--wide) + 2 * var(--pad))) var(--toc); }
  html.nav-closed .layout { grid-template-columns: minmax(0, calc(var(--wide) + 2 * var(--pad))) var(--toc); }
  html:is(.toc-closed, .toc-cramped, .toc-none) .layout {
    grid-template-columns: var(--nav) minmax(0, calc(var(--wide) + 2 * var(--pad))); }
  html.nav-closed:is(.toc-closed, .toc-cramped, .toc-none) .layout {
    grid-template-columns: minmax(0, calc(var(--wide) + 2 * var(--pad))); }
  .toc { display: block; }
  html:is(.toc-closed, .toc-cramped, .toc-none) .toc { display: none; }
}
.nav { border-right: 1px solid var(--edge); }
.nav ol { list-style: none; margin: 0; padding: 0; }
.nav .part { margin: 1.1rem 0 .3rem; font-size: 11.5px; font-weight: 600; letter-spacing: .06em;
             text-transform: uppercase; color: var(--faint); }
.nav .part a { color: inherit; text-decoration: none; }
.nav .part span { display: block; padding: .22rem .5rem; border-left: 2px solid transparent; }
.nav a { display: block; color: var(--muted); text-decoration: none; padding: .22rem .5rem;
         border-left: 2px solid transparent; border-radius: 0 4px 4px 0; }
.nav a:hover { color: var(--accent); background: var(--wash); }
.nav a.here { color: var(--accent); font-weight: 600; border-left-color: var(--accent);
              background: var(--wash); }
.nav a.unwritten { color: var(--faint); }
.nav a.unwritten::after { content: "planned"; margin-left: .4rem; font-size: 10.5px; letter-spacing: .04em;
                          text-transform: uppercase; color: var(--faint); border: 1px solid var(--edge);
                          border-radius: 3px; padding: 0 .25rem; }
.nav .num { font-variant-numeric: tabular-nums; color: var(--faint); margin-right: .35rem; }
.toc { color: var(--muted); border-left: 1px solid var(--edge); }
.toc p { margin: 0 0 .5rem; font-size: 11.5px; font-weight: 600; letter-spacing: .06em;
         text-transform: uppercase; color: var(--faint); }
.toc ol { list-style: none; margin: 0; padding: 0; border-left: 1px solid var(--edge); }
.toc a { display: block; color: var(--muted); text-decoration: none; padding: .18rem .7rem; }
.toc a:hover { color: var(--accent); }
.toc .d3 a { padding-left: 1.4rem; font-size: 13px; }

main { min-width: 0; padding: 1rem var(--pad) 5rem; }
/* The measure belongs to each thing in the chapter rather than to the column holding them, so
   prose, headings and notes keep one line length and stay centred while what needs more room
   spreads into the wide column around them. Addressed through the id, because most children set
   their own horizontal margins and at equal specificity the later rule would win. */
#main > .page > * { max-width: var(--measure); margin-inline: auto; }
/* A picture sits in the column like a paragraph: a block, at the measure, centred with the text.
   Left inline, it hung from the column's left edge, outside the measure's centring. */
#main > .page > img { display: block; width: 100%; height: auto; }
#main > .page > :is(.lab, .workbench, .wide) { max-width: var(--wide); }
/* A table is as wide as its content, and starts at the prose's left edge; one wider than the
   prose runs on to the right, and moves left only as far as the wide column needs it to. The
   script sets `--need`, the table's width with nothing squeezing it. */
#main > .page > .wide.fits {
  width: min(100%, var(--need), var(--wide)); max-width: none; margin-right: auto;
  margin-left: max((100% - min(100%, var(--wide))) / 2,
                   min((100% - min(100%, var(--measure))) / 2,
                       (100% + min(100%, var(--wide))) / 2 - min(100%, var(--need), var(--wide)))); }

main :is(h1, h2, h3, h4) { font-family: var(--chrome); letter-spacing: -.012em; }
h1 { font-size: clamp(1.6rem, 5.4vw, 2.1rem); font-weight: 700; line-height: 1.18;
     margin: 1.6rem 0 .5rem; }
h1 .label { color: var(--faint); font-weight: 500; margin-right: .4rem; }
.builds { margin: 0 0 1.6rem; font: 14.5px/1.5 var(--chrome); color: var(--muted); }
.builds strong { color: var(--ink); font-weight: 600; }
.subtitle { margin: -.4rem 0 1.2rem; font: 500 1.05rem/1.4 var(--chrome); color: var(--muted); }
h2 { font-size: 1.35rem; font-weight: 650; line-height: 1.25; margin: 2.5rem 0 .9rem;
     padding-top: 1.1rem; border-top: 1px solid var(--edge); }
h3 { font-size: 1.15rem; font-weight: 700; line-height: 1.3; margin: 1.9rem 0 .6rem; }
h4 { font-size: .95rem; font-weight: 600; color: var(--muted); margin: 1.6rem 0 .4rem; }
.anchor { margin-left: .4rem; color: var(--rule); text-decoration: none; font-weight: 400;
          opacity: 0; }
:is(h2, h3, h4):hover .anchor { opacity: 1; }
p { margin: 0 0 1.05rem; }
ul, ol { padding-left: 1.4rem; }
li { margin-bottom: .35rem; }
blockquote { margin: 1.4rem 0; padding: .1rem 0 .1rem 1.1rem; border-left: 2px solid var(--rule);
             color: var(--muted); }
hr { border: 0; border-top: 1px solid var(--edge); margin: 2.4rem 0; }

/* Code */
code, pre, kbd { font-family: var(--mono); }
code { font-size: .84em; background: var(--code); padding: .08em .3em; border-radius: 3px;
       overflow-wrap: break-word; }
pre { font-size: 13.5px; line-height: 1.55; background: var(--code); color: var(--ink);
      padding: .85rem 1rem; border-radius: 6px; border: 1px solid var(--edge); margin: 1.3rem 0;
      white-space: pre; overflow-x: auto; }
pre code { background: none; padding: 0; font-size: inherit; }
/* A diagram drawn in text: lines close enough that the box-drawing characters join up. */
pre.diagram { line-height: 1.25; background: none; border: 0; padding: .25rem 0; }
@media (max-width: 30rem) { pre.diagram { font-size: 12px; } }
.tok-comment { color: var(--tok-comment); font-style: italic; }
.tok-string { color: var(--tok-string); }
.tok-number { color: var(--tok-number); }
.tok-keyword { color: var(--tok-keyword); font-weight: 600; }
.tok-type { color: var(--tok-type); }
.tok-attr, .tok-macro { color: var(--tok-attr); }
figure.quoted { margin: 1.3rem 0; }
figure.quoted pre { margin-top: 0; border-top-left-radius: 0; border-top-right-radius: 0; }
.source-bar { display: flex; gap: 1rem; align-items: baseline;
              font: 12px/1.4 var(--chrome); color: var(--faint); background: var(--panel);
              border: 1px solid var(--edge); border-bottom: 0; border-radius: 6px 6px 0 0;
              padding: .35rem 1rem; }
.source-bar .source-label { flex: none; }
.source-bar code { background: none; padding: 0; font-size: 12px; overflow-wrap: anywhere; }
/* The file a listing comes from, linked to it on GitHub: coloured and underlined as the page's
   other links are, with an arrow that says it leaves the book. */
.source-bar a { color: var(--accent); min-width: 0; margin-left: auto; text-decoration: underline;
                text-decoration-color: color-mix(in srgb, var(--accent) 45%, transparent);
                text-underline-offset: 3px; }
.source-bar a:hover { text-decoration-color: var(--accent); }
.source-bar a::after { content: " \2197"; font-size: 11px; }
/* On a phone the bar's buttons leave the path too little room, and it broke a letter to a line:
   there the bar wraps, the buttons stay on the first line, and the path takes a line of its own. */
.source-bar { flex-wrap: wrap; row-gap: .3rem; }
@media (max-width: 40rem) {
  .source-bar { column-gap: .5rem; }
  .source-bar a { order: 1; flex: 1 0 100%; margin-left: 0; }
  .source-bar :is(.edit-open, .expand) { padding: .25rem .4rem; }
  .source-bar :is(.edit-open, .expand) { margin-left: auto; }
  .source-bar .edit-open + .expand, .source-bar .edit-open ~ .expand { margin-left: 0; }
}
/* The same step in Python and in Rust. The head script sets <html data-code>; without it both
   panels show, one after the other, and the tab bar is hidden. */
.tab-set { margin: 1.3rem 0; }
.tab-set figure.quoted { margin: 0; }
.tab-bar { display: none; gap: .25rem; font: 12.5px/1 var(--chrome); }
html[data-code] .tab-bar { display: flex; }
.tab-bar button { font: inherit; color: var(--muted); background: none; cursor: pointer;
                  border: 1px solid transparent; border-bottom: 0; border-radius: 6px 6px 0 0;
                  padding: .45rem .9rem; }
.tab-bar button:hover { color: var(--accent); }
html[data-code="python"] .tab-bar button[data-code="python"],
html[data-code="rust"] .tab-bar button[data-code="rust"] {
  color: var(--ink); background: var(--panel); border-color: var(--edge); font-weight: 600; }
html[data-code] .tab-panel .source-bar { border-top-left-radius: 0; }
html[data-code="python"] .tab-panel[data-code="rust"],
html[data-code="rust"] .tab-panel[data-code="python"] { display: none; }
html:not([data-code]) .tab-panel + .tab-panel { margin-top: 1rem; }
/* The button that gives the window to something the column cannot hold: a line of code longer
   than the wide column, or a table wider than it. The script puts one on every block of code
   and every table and shows it only where the block is cut off, which only the page can know,
   having the fonts. A quoted file keeps it in its bar; anything else is wrapped in a
   `wide-block` with the button above it, right-aligned, where it covers nothing: over the
   corner it would sit on a table's last heading or a command's Run button. Opened, the same
   element is moved nowhere and reloaded never, so an edit in progress survives the trip. */
.expand { display: inline-flex; align-items: center; gap: .35rem; font: 12px/1 var(--chrome);
          color: var(--muted); background: var(--bg); border: 1px solid var(--edge);
          border-radius: 5px; padding: .3rem .5rem; cursor: pointer; }
.expand:hover { border-color: var(--accent); color: var(--accent); }
.expand[hidden] { display: none; }
.source-bar .expand { align-self: center; flex: none; margin: -.15rem 0; }
.wide-block { margin: 1.3rem 0; }
.wide-block > :is(pre, .table-wrap, .runnable) { margin-top: 0; }
.wide-block > pre:last-child, .wide-block > .table-wrap:last-child { margin-bottom: 0; }
.wide-block > .expand { display: flex; width: fit-content; margin: 0 0 .4rem auto; }
.wide-block > .expand[hidden] { display: none; }
/* Open, it fills the window, above the top bar, and scrolls in itself, because the page behind
   it cannot: `expand-open` stops the document scrolling, so anything that left the box would
   be out of reach rather than off screen. The button stays pinned to the window's corner. */
html.expand-open { overflow: hidden; }
html.expand-open #main .page .expanded {
  position: fixed; inset: 0; z-index: 40; margin: 0; width: auto; max-width: none;
  background: var(--bg); display: flex; flex-direction: column; padding: .6rem;
  overflow: auto; overscroll-behavior: contain; }
html.expand-open #main .expanded > .expand { position: fixed; top: .6rem; right: .6rem; z-index: 41;
                                             margin: 0; }
html.expand-open #main .expanded.wide-block { padding-top: 2.8rem; }
html.expand-open #main .expanded > :is(pre, .runnable) { flex: 1 1 auto; min-height: 0; margin: 0; }
html.expand-open #main .expanded > .runnable { display: flex; flex-direction: column; }
html.expand-open #main .expanded > .runnable > :is(pre, .code-area, .code-edit) { flex: 1 1 auto; min-height: 0;
                                                                       margin: 0; resize: none; }
html.expand-open #main .expanded :is(.code-edit) > textarea { height: 100%; resize: none; }
/* A listing being edited fills the window until it is run. Then it shares the window with its
   output: the output is as tall as what it printed, up to half the window, scrolling within
   itself beyond that, and the editor takes the rest. */
html.expand-open #main .expanded > .code-edit { flex: 1 1 auto; min-height: 8rem; }
html.expand-open #main .expanded > .edit-bar { flex: none; }
html.expand-open #main .expanded > .run-result { flex: 0 0 auto; max-height: 50%; overflow: auto; margin: .6rem 0 0; }
/* A table is as wide as its content and the box scrolls: left a scroll box of its own, the
   table would keep a swipe that started on it, and on a phone its last columns could not be
   reached. */
html.expand-open #main .expanded .table-wrap { overflow: visible; margin: 0; }
html.expand-open #main .expanded table { width: max-content; }
kbd { font-size: .8em; border: 1px solid var(--rule); border-bottom-width: 2px; border-radius: 4px;
      padding: .05em .35em; background: var(--panel); }

/* Tables are data, not prose: the furniture face and lining figures. */
.table-wrap { overflow-x: auto; margin: 1.3rem 0; }
/* The way back to the page the reader was on, at the top of the preface. */
.resume { margin: .2rem 0 1.4rem; font: 600 14.5px/1.4 var(--chrome); }
.resume a { display: inline-block; padding: .5rem .8rem; border-radius: 6px; background: var(--wash);
            color: var(--accent); text-decoration: none; }
table { border-collapse: collapse; font: 14.5px/1.45 var(--chrome);
        font-variant-numeric: tabular-nums; }
th, td { text-align: left; padding: .42rem .7rem; border-bottom: 1px solid var(--edge);
         vertical-align: top; }
th { font-size: 11.5px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
     color: var(--faint); border-bottom: 1px solid var(--rule); }
td.align-right, th.align-right { text-align: right; }
td.align-center, th.align-center { text-align: center; }
td code { font-size: 12.5px; }
/* Code in a table (a plan's expression, a column list) may be one long token, so on a phone it
   breaks anywhere rather than pushing the table wider than the screen. */
@media (max-width: 40rem) {
  td code { overflow-wrap: anywhere; }
  /* Narrower cells and smaller type let a four-column table of counts fit a phone without
     scrolling. */
  table { font-size: 13.5px; }
  th, td { padding-left: .4rem; padding-right: .4rem; }
  th { font-size: 11px; letter-spacing: .02em; }
}
/* On a phone, a wide table becomes one card per row, each value under its column's heading. */
@media (max-width: 40rem) {
  table.cards, table.cards tbody, table.cards tr, table.cards td { display: block; width: 100%; }
  table.cards thead { display: none; }
  table.cards tr { border-bottom: 1px solid var(--rule); padding: .45rem 0; }
  /* A value may be one long token (a logical type, a column's dotted path), so it breaks
     anywhere rather than pushing the card wider than the screen. */
  table.cards td { display: grid; grid-template-columns: minmax(6.5rem, 38%) minmax(0, 1fr); gap: .7rem;
                   border: 0; padding: .12rem 0; text-align: left; overflow-wrap: anywhere; }
  table.cards td::before { content: attr(data-label); font-size: 11px; font-weight: 600;
                           letter-spacing: .05em; text-transform: uppercase; color: var(--faint);
                           padding-top: .15em; }
}
.generated > p:last-child em { font: italic 13.5px/1.45 var(--chrome); color: var(--faint); }

/* Boxes */
.admonition, .definition, .takeaways, .unwritten-note {
  background: var(--panel); border: 1px solid var(--edge); border-left: 3px solid var(--accent);
  border-radius: 6px; padding: .8rem 1rem; margin: 1.5rem 0; font-size: .96em; }
.admonition > :last-child, .definition > :last-child, .takeaways > :last-child { margin-bottom: 0; }
.admonition-title { font: 600 12.5px/1.4 var(--chrome); letter-spacing: .05em;
                    text-transform: uppercase; color: var(--muted); margin: 0 0 .4rem; }
.admonition.warning, .admonition.important { border-left-color: var(--stop); }
.admonition.tip { border-left-color: var(--go); }
.takeaways ul { margin: 0; }
.unwritten-note { border-left-color: var(--warn); font-family: var(--chrome); font-size: 15px; }

.prevnext { display: flex; justify-content: space-between; gap: 1rem; margin-top: 3.5rem;
            padding-top: 1.2rem; border-top: 1px solid var(--edge); font: 14.5px/1.4 var(--chrome); }
.prevnext a { text-decoration: none; max-width: 48%; }
.prevnext small { display: block; color: var(--faint); font-size: 12px; text-transform: uppercase;
                  letter-spacing: .06em; }
.prevnext .next { margin-left: auto; text-align: right; }
.footnotes { margin-top: 3rem; font-size: .9em; color: var(--muted); border-top: 1px solid var(--edge); }
.stamp { margin-top: 2rem; font: 12.5px/1.4 var(--chrome); color: var(--faint); }

@media (max-width: 52rem) {
  .brand span { display: none; }
  main { padding-bottom: 4rem; }
  body { font-size: 17px; }
}

/* The foot of every page but the cover, which says the same itself: the author and the terms. */
.colophon { margin: 1.5rem 0 0; padding-top: 1rem; border-top: 1px solid var(--edge);
            font: 13px/1.5 var(--chrome); color: var(--muted); }
.colophon a { color: inherit; }
