/* Obelus — the site.
   One stylesheet, no build step.

   Drawn to omarchy's web rules (`huacnlee/omarchy-style`, references/
   web-design.md), which are deliberately not omarchy's shell rules: the
   shell is dense, foreground-tinted and fill-averse, and the website is a
   themed surface with its own type pairing, its own button recipe and a
   solid accent fill. So this page no longer draws itself the way Obelus
   draws itself -- the round frames, the key caps with a lip under them and
   the shade behind a raised thing are gone. What is kept from there is the
   palette, which is Obelus's own `dark` and `light`, the values in
   `obelus-theme`'s `builtin.rs`: a page in another program's colours would
   leave the screenshots sitting on it rather than in it.

   What that style asks for, in the order the reference asks it:

     · two layers of colour -- `--t-*` is the theme and nothing else
       changes between themes, and the components name a semantic token and
       never a hex value
     · monospace is the voice of the page, and the sans-serif exists so the
       headings do not shout in a typewriter face. Not the other way round
     · every radius is zero, and it is zero centrally, so nothing opts out
       by accident
     · elevation is a hairline ring rather than a shadow (a light theme is
       the exception, and may add a soft one under the ring)
     · a link in prose is the body's colour with a border-coloured
       underline, and only the underline changes on hover -- the geometry
       is reserved at rest, so nothing moves under the pointer
     · 150ms ease-out, on colour, border, shadow and transform, and no
       page-level animation beyond that
     · focus is always visible and always the accent, 2px offset by 2px

   Two of its rules are omarchy's own brand and are not transplantable: the
   pixel lattice the homepage measures itself in is their 81x19 wordmark
   bitmap, and the five-band ramp is their brand gradient. Obelus's mark is
   a division sign, and the ramp it wears is the welcome screen's own -- the
   theme's keyword colour running to its function colour. It is still, not
   moving, because of the animation budget above. */

/* ── the theme ──────────────────────────────────────────────────────── */

:root {
  color-scheme: light;

  /* `LIGHT` */
  --t-bg:            #fafafa;
  --t-bg-deep:       #f4f4f5;
  --t-surface:       #f4f4f5;
  --t-surface-2:     #e4e4e7;

  --t-border-subtle: #e4e4e7;
  --t-border-strong: #a1a1aa;

  --t-text:          #18181b;
  --t-text-secondary:#3f3f46;
  --t-text-muted:    #71717a;

  --t-brand:         #1d4ed8;
  --t-brand-ink:     #fafafa;
  --t-mark:          #7e22ce;

  --t-selection:     #e0e7ff;

  /* A ring, not a shadow. The light theme is the one that may add a soft
     drop under it. */
  --t-ring:          0 0 0 1px oklch(0 0 0 / .09), 0 1px 2px oklch(0 0 0 / .05);
}

:root[data-theme="dark"] {
  color-scheme: dark;

  /* `DARK` */
  --t-bg:            #18181b;
  --t-bg-deep:       #0f0f11;
  --t-surface:       #1f1f23;
  --t-surface-2:     #27272a;

  --t-border-subtle: #27272a;
  --t-border-strong: #52525b;

  --t-text:          #e4e4e7;
  --t-text-secondary:#a1a1aa;
  --t-text-muted:    #8b8b93;

  --t-brand:         #60a5fa;
  --t-brand-ink:     #0f0f11;
  --t-mark:          #c084fc;

  --t-selection:     #312e81;

  --t-ring:          0 0 0 1px oklch(1 0 0 / .07);
}

:root {
  /* Monospace is the page's voice; the sans is for headings only. The Nerd
     Font names sit behind the web font rather than in front of it: they are
     there for a glyph JetBrains Mono does not carry, not for the Latin. */
  --font-mono: "JetBrains Mono", "JetBrainsMono Nerd Font", "FiraCode Nerd Font",
               "Hack Nerd Font", ui-monospace, "SF Mono", Menlo, Consolas,
               "Noto Sans Mono CJK SC", "Sarasa Mono SC", monospace;
  --font-sans: "Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
               "PingFang SC", "Noto Sans CJK SC", "Microsoft YaHei", sans-serif;

  /* The measures the reference gives: the bar, the content column, and the
     prose measure, which is applied per block so a structural layout keeps
     the full width. */
  --nav-h: 3.5rem;
  --column: 90rem;
  --measure: 54rem;
  --gutter-width: 1rem;

  /* Square is enforced here, once. */
  --round: 0px;

  /* nav 100, dropdown 200, modal 300, tooltip 400, and nothing arbitrary
     anywhere else. */
  --z-nav: 100;
}

@media (min-width: 40rem) {
  :root { --gutter-width: 1.5rem; }
}

*, *::before, *::after { box-sizing: border-box; }

/* A theme swap must not tween: every colour would move independently and
   the page would smear. `main.js` puts this on the root for one frame. */
:root.swapping, :root.swapping *, :root.swapping *::before, :root.swapping *::after {
  transition: none !important;
}

html { scroll-behavior: smooth; }
[id] { scroll-margin-top: calc(var(--nav-h) + 1rem); }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--t-bg);
  color: var(--t-text-secondary);
  font-family: var(--font-mono);
  font-size: 17px;
  line-height: 1.65;
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
}

/* Chinese sets its own measure: denser glyphs want a little more air, and
   the mono fallback for them is wider again. */
html[lang="zh-Hans"] body { line-height: 1.8; }

::selection { background: var(--t-selection); color: var(--t-text); }

/* 8px, the thumb in the accent -- and a neutral one in a code block, which
   is the reference's own exception. */
* { scrollbar-width: thin; scrollbar-color: var(--t-brand) transparent; }
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: var(--t-brand); }
*::-webkit-scrollbar-thumb:hover { background: color-mix(in srgb, var(--t-brand) 80%, #fff); }
pre { scrollbar-color: var(--t-border-strong) transparent; }
pre::-webkit-scrollbar-thumb { background: var(--t-border-strong); }

/* Always visible, always the accent, and inset where a scroll container
   would clip it. */
:focus-visible { outline: 2px solid var(--t-brand); outline-offset: 2px; }
.table-wrap :focus-visible, pre :focus-visible { outline-offset: -2px; }

img { max-width: 100%; }
[hidden] { display: none !important; }

/* An image takes an inset outline rather than a border: it never changes
   the layout box. */
.shot img { outline: 1px solid oklch(0.5 0 0 / .18); outline-offset: -1px; }

/* ── type ───────────────────────────────────────────────────────────── */

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-sans);
  color: var(--t-text);
  text-wrap: balance;
}

p { max-width: var(--measure); margin: 0 0 1rem; }
p + p { margin-top: 0; }

strong { color: var(--t-text); font-weight: 600; }
em { color: var(--t-text); }

.quiet { color: var(--t-text-muted); }
.small { font-size: 0.88em; }
.mono { font-family: var(--font-mono); }

/* ── links ──────────────────────────────────────────────────────────── */

/* The body's colour with a border-coloured underline, and only the
   underline changes. Reserved at rest, so hovering moves nothing. */
a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--t-border-strong);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-skip-ink: auto;
  transition: color 150ms ease-out, text-decoration-color 150ms ease-out;
  touch-action: manipulation;
}
a:hover { text-decoration-color: var(--t-brand); }

/* The furniture is not prose: a control carries its own chrome and takes
   no underline. */
.top a, .contents a, .button, .switch, .beats .where, .wordmark {
  text-decoration: none;
}

/* ── the bar ────────────────────────────────────────────────────────── */

.top {
  position: sticky;
  top: 0;
  z-index: var(--z-nav);
  display: flex;
  align-items: center;
  gap: 0.5rem;
  height: calc(var(--nav-h) + env(safe-area-inset-top));
  padding: env(safe-area-inset-top) var(--gutter-width) 0;
  background: var(--t-bg);
  border-bottom: 1px solid var(--t-border-subtle);
}

.top .wordmark {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  color: var(--t-text);
  font-weight: 500;
}
.top .wordmark .obelus { font-size: 1.15rem; }

/* The subtitle under a wordmark is the brand's display device: uppercase,
   wide tracking, the accent. The left padding is the tracking back again,
   so the trailing letter-space does not push the line off its centre. */
.top .wordmark .tag {
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.18em;
  padding-left: 0.18em;
  text-transform: uppercase;
  color: var(--t-brand);
}
@media (max-width: 720px) { .top .wordmark .tag { display: none; } }

.top .spacer { flex: 1; }

/* ── controls ───────────────────────────────────────────────────────── */

/* The website button, at the reference's four heights. `.switch` is the
   extra-small one and `.button` the default; `.primary` is the solid fill.
   The fill is opaque on purpose. */
.button, .switch {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font-family: var(--font-mono);
  font-weight: 500;
  color: var(--t-text);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--round);
  cursor: pointer;
  white-space: nowrap;
  touch-action: manipulation;
  transition: background-color 150ms ease-out, border-color 150ms ease-out,
              color 150ms ease-out, transform 150ms ease-out;
}
.button:active, .switch:active { transform: scale(0.96); }
.button[disabled], .switch[disabled] { opacity: 0.5; pointer-events: none; }

/* xs: 32 tall, 10 of padding, 12px text. No chrome until it is hovered,
   which is what a bar wants. */
.switch {
  height: 32px;
  padding: 0 10px;
  font-size: 14px;
}
.switch:hover { background: var(--t-surface-2); }

/* default: 40 tall, 16 of padding, 15px text. Outline unless it is the
   page's primary action. */
.button {
  height: 40px;
  padding: 0 16px;
  font-size: 15px;
  background: var(--t-surface);
  border-color: var(--t-border-strong);
}
.button:hover { background: var(--t-surface-2); }

.button.primary {
  color: var(--t-brand-ink);
  background: var(--t-brand);
  border-color: var(--t-brand);
}
.button.primary:hover {
  background: color-mix(in srgb, var(--t-brand) 86%, #fff);
  border-color: color-mix(in srgb, var(--t-brand) 86%, #fff);
}

.buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 2.4rem; }

/* A command is there to be run, so it is there to be taken away. The button
   is a sibling of the <pre> rather than inside it: a <pre> scrolls, and
   anything positioned within one walks off sideways with the text. It sits
   on the frame's top edge rather than inside the box, because an install
   line is wider than the box on most screens -- over the text, the button
   covers the end of the very command it is offering. */
.block { position: relative; }
.block > .copy {
  position: absolute;
  top: -16px;
  right: 10px;
  background: var(--t-bg);
  border-color: var(--t-border-strong);
}
.copy.done { color: var(--t-brand); border-color: var(--t-brand); }

/* ── the frame ──────────────────────────────────────────────────────── */

.frame {
  display: grid;
  grid-template-columns: 13rem minmax(0, 1fr);
  gap: clamp(1.5rem, 5vw, 4rem);
  max-width: var(--column);
  margin: 0 auto;
  padding: 0 var(--gutter-width) 6rem;
}

.contents {
  position: sticky;
  top: calc(var(--nav-h) + 1rem);
  align-self: start;
  max-height: calc(100vh - var(--nav-h) - 3rem);
  overflow-y: auto;
  padding-top: 3.2rem;
  font-size: 14px;
}
.contents ol { list-style: none; margin: 0; padding: 0; }
.contents li { margin: 0; }
.contents a {
  display: block;
  padding: 0.25rem 0.6rem;
  color: var(--t-text-muted);
  border-left: 2px solid transparent;
  transition: color 150ms ease-out, background-color 150ms ease-out,
              border-color 150ms ease-out;
}
.contents a:hover { color: var(--t-text); background: var(--t-surface); }
.contents a.here {
  color: var(--t-text);
  background: var(--t-surface);
  border-left-color: var(--t-brand);
}

@media (max-width: 860px) {
  .frame { grid-template-columns: minmax(0, 1fr); }
  .contents {
    position: static;
    max-height: none;
    padding: 1.2rem 0 0;
    margin-bottom: -1rem;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .contents::-webkit-scrollbar { display: none; }
  .contents ol { display: flex; gap: 0.2rem; }
  .contents a { white-space: nowrap; border-left: 0; border-bottom: 2px solid transparent; }
  .contents a.here { border-bottom-color: var(--t-brand); }
}

main { min-width: 0; }

/* ── the hero ───────────────────────────────────────────────────────── */

.hero { padding: 3.6rem 0 1rem; }

/* The front page's hero stands outside the frame, centred over the whole
   column: it is the one thing on the page that is not a section, and its
   screen is read at the size it was photographed at rather than squeezed
   into the prose measure beside the contents. */
.hero.wide {
  max-width: var(--column);
  margin: 0 auto;
  padding: 4.5rem var(--gutter-width) 1rem;
  text-align: center;
}
.hero.wide h1 { margin-left: auto; margin-right: auto; }
.hero.wide p { margin-left: auto; margin-right: auto; }
.hero.wide .sub { max-width: 46rem; }
.hero.wide .buttons { justify-content: center; }
/* The main screens, as a stack: the one being shown in front, and the next
   two showing behind it, smaller, fainter and turned a little, the way a
   desktop stacks a folder of pictures. The frames share one cell of a
   grid, so the stack takes the height of one picture and nothing below it
   moves when the front one changes. `main.js` says how deep each one is,
   and walks them on a clock until a visitor picks one. */
/* Smaller than the screens were photographed at, never larger: they are
   twice the width they are shown at, so a page this size only ever shrinks
   them, and shrinking keeps a letter sharp where stretching blurs it. At
   1050px -- one pixel to one of a 2x screen's -- the stack filled a whole
   screen and pushed the sentence it illustrates out of view. */
.screens { max-width: 680px; margin: 2.2rem auto 0; }
.screens .tabs { display: flex; justify-content: center; flex-wrap: wrap; gap: 6px; margin-bottom: 1rem; }
.screens .tabs .switch[aria-selected="true"] {
  background: var(--t-surface-2);
  color: var(--t-text);
  box-shadow: inset 0 -2px 0 var(--t-brand);
}
.screens .frames { display: grid; text-align: left; padding-top: 3.2rem; }
.screens .frames > .shot {
  grid-area: 1 / 1;
  margin: 0;
  transform-origin: 50% 0;
  transition: transform 600ms cubic-bezier(.2, .7, .2, 1), opacity 600ms ease;
  opacity: 0;
  visibility: hidden;
  z-index: 1;
}
.screens .frames > .shot img { box-shadow: 0 14px 40px rgba(0, 0, 0, .22); }
.screens .frames > .shot[data-depth="0"] { opacity: 1; visibility: visible; z-index: 5; transform: none; }
.screens .frames > .shot[data-depth="1"] {
  opacity: .55; visibility: visible; z-index: 4; cursor: pointer;
  transform: translateY(-1.7rem) scale(.95) rotate(-1.6deg);
}
.screens .frames > .shot[data-depth="2"] {
  opacity: .3; visibility: visible; z-index: 3; cursor: pointer;
  transform: translateY(-3.1rem) scale(.9) rotate(1.4deg);
}
.screens .frames > .shot:not([data-depth="0"]) .caption { visibility: hidden; }
.screens .frames .caption { text-align: center; max-width: 46rem; margin: 1rem auto 0; }
@media (prefers-reduced-motion: reduce) {
  .screens .frames > .shot { transition: none; }
}


/* The mark and the name wear the welcome screen's ramp. Brand artwork, and
   the only place a gradient belongs. */
.hero .mark, .hero h1 {
  background: linear-gradient(135deg, var(--t-mark), var(--t-brand));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.hero .mark {
  font-family: var(--font-mono);
  font-size: 3.4rem;
  line-height: 1;
  margin-bottom: 0.8rem;
  display: inline-block;
}

.hero h1 {
  font-weight: 600;
  font-size: clamp(2.2rem, 6vw, 3rem);
  letter-spacing: -0.02em;
  margin: 0 0 0.8rem;
  display: table;
}

/* The one sentence the page is for, so it is set as a heading rather than
   as the first line of the paragraph under it. */
.hero .lede {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: clamp(1.5rem, 4vw, 2.1rem);
  letter-spacing: -0.01em;
  line-height: 1.25;
  color: var(--t-text);
  margin: 0 0 1rem;
}
/* The half of it that is the reader's, in the brand colour: the sentence is
   already the page's heaviest, so weight cannot be what picks it out. */
.hero .lede strong { color: var(--t-brand); }
.hero .sub { color: var(--t-text-muted); margin: 0 0 1.8rem; }

/* One screen, photographed. Two of them, because the page has a theme
   switch and a dark screenshot on a light page is a hole in it. */
.shot { margin: 0 0 0.9rem; }
.shot img { display: block; width: 100%; height: auto; }
:root[data-theme="dark"] .shot .light,
:root[data-theme="light"] .shot .dark { display: none; }
.shot .caption { margin: 0.6rem 0 0; }

.caption {
  font-size: 14px;
  color: var(--t-text-muted);
  margin: 0 0 1rem;
  max-width: var(--measure);
}

/* ── sections ───────────────────────────────────────────────────────── */

section { padding-top: 3.2rem; }

section > h2 {
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  margin: 0 0 0.8rem;
  padding-bottom: 0.7rem;
  border-bottom: 1px solid var(--t-border-subtle);
}
@media (min-width: 40rem) { section > h2 { font-size: 1.75rem; } }

/* The number stays in the mono face: it is a line number, and the gutter's
   ink is where a line number is drawn. */
section > h2 .num {
  font-family: var(--font-mono);
  font-size: 0.72em;
  font-weight: 400;
  color: var(--t-text-muted);
  margin-right: 0.8rem;
}

h3 {
  font-size: 1.25rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.4;
  margin: 2.2rem 0 0.6rem;
}
h4 {
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 1.8rem 0 0.4rem;
}

section > p, section > ul, section > ol { max-width: var(--measure); }

/* A subsection beside its picture, the two swapping sides down the page so
   the eye has somewhere to go besides straight down. The picture gets the
   larger share because it is a screen, and opens at full size on a click.
   One column again where two would make either unreadable. */
.feature {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
  gap: 2rem;
  align-items: center;
  margin: 2.6rem 0;
}
.feature.flip { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); }
.feature.flip > .text { order: 2; }
.feature > .text > h3:first-child { margin-top: 0; }
.feature > .text > :last-child { margin-bottom: 0; }
.feature .shot { margin: 0; }
.feature .shot a { display: block; }
@media (max-width: 1100px) {
  .feature, .feature.flip { grid-template-columns: minmax(0, 1fr); gap: 1.2rem; }
  .feature.flip > .text { order: 0; }
}

/* ── prose ──────────────────────────────────────────────────────────── */

ul { list-style: square; }
ul, ol { padding-left: 1.4rem; }
li { margin-bottom: 0.4rem; }
li::marker { color: var(--t-text-muted); }
li > p { margin-bottom: 0.5rem; }

hr { border: 0; border-top: 1px solid var(--t-border-subtle); margin: 2em 0; }

blockquote {
  margin: 1.6rem 0;
  padding: 0.1rem 0 0.1rem 1rem;
  border-left: 2px solid var(--t-brand);
  color: var(--t-text-muted);
  max-width: var(--measure);
}
blockquote p:last-child { margin-bottom: 0; }

/* Inline code and a key sit on the secondary surface, with no radius. The
   key is no longer a cap with a lip under it: that is the shell's shape,
   and this page is not the shell. */
code, kbd {
  font-family: var(--font-mono);
  background: var(--t-surface-2);
  padding: 0.15em 0.4em;
  border-radius: var(--round);
}
code { font-size: 0.86em; word-break: break-word; }
kbd {
  font-size: 0.82em;
  color: var(--t-text);
  white-space: nowrap;
}

/* A code block sits on the deepest ground, with the ring for its edge. */
pre {
  margin: 1.4rem 0;
  padding: 1em 1.25em;
  background: var(--t-bg-deep);
  box-shadow: var(--t-ring);
  border-radius: var(--round);
  overflow-x: auto;
  font-size: 14px;
  line-height: 1.6;
  color: var(--t-text);
}
pre code { background: none; padding: 0; font-size: inherit; }

/* ── the principles ─────────────────────────────────────────────────── */

.tenets { list-style: none; padding: 0; margin: 1.4rem 0 0; max-width: var(--measure); }
.tenets > li {
  display: grid;
  grid-template-columns: 2.4rem minmax(0, 1fr);
  gap: 0.2rem 0.8rem;
  padding: 0.8rem 0.7rem;
  margin: 0;
  border-left: 2px solid transparent;
  transition: background-color 150ms ease-out, border-color 150ms ease-out;
}
.tenets > li:hover { background: var(--t-surface); border-left-color: var(--t-brand); }
.tenets .no {
  font-size: 14px;
  color: var(--t-text-muted);
  text-align: right;
  padding-top: 0.15rem;
}
.tenets .claim { color: var(--t-text); font-weight: 600; margin: 0 0 0.3rem; max-width: none; }
.tenets .why { color: var(--t-text-muted); margin: 0; max-width: none; }

/* The highlights: a row each, and where it is explained on the right. */
.beats { list-style: none; padding: 0; margin: 1.4rem 0 0; max-width: var(--measure); }
.beats li {
  display: flex;
  gap: 1.2rem;
  align-items: baseline;
  justify-content: space-between;
  padding: 0.5rem 0.7rem;
  margin: 0;
  border-left: 2px solid transparent;
  transition: background-color 150ms ease-out, border-color 150ms ease-out;
}
.beats li:hover { background: var(--t-surface); border-left-color: var(--t-brand); }
.beats .where {
  flex: none;
  font-size: 13px;
  color: var(--t-text-muted);
  white-space: nowrap;
  transition: color 150ms ease-out;
}
.beats .where:hover { color: var(--t-brand); }
@media (max-width: 560px) {
  .beats li { flex-direction: column; gap: 0.25rem; }
}

/* ── cards, tables, asides ──────────────────────────────────────────── */

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1rem;
  margin: 1.6rem 0;
}
.card {
  background: var(--t-surface);
  box-shadow: var(--t-ring);
  padding: 1rem 1.15rem;
  transition: background-color 150ms ease-out;
}
.card:hover { background: var(--t-surface-2); }
.card h4 { margin: 0 0 0.5rem; font-size: 1rem; }
.card p { margin: 0; font-size: 0.93em; color: var(--t-text-muted); max-width: none; }
.card ul { margin: 0.4rem 0 0; padding-left: 1.1rem; font-size: 0.93em; color: var(--t-text-muted); }
.card li { margin-bottom: 0.25rem; }

/* What a feature is reached by -- its key, its command and the settings that
   change it -- in one quiet line under what it does. The labels are muted so
   the names are what the eye lands on. */
.how {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.35rem 0.4rem;
  font-size: 0.88em;
  margin-top: -0.2rem;
}
.how > span { color: var(--t-text-muted); }
.how > span:not(:first-child) { margin-left: 0.8rem; }

/* Tables are lists: a rule under the heading and none between rows, and
   the row the pointer is on marked the way a list's selection is. */
.table-wrap { overflow-x: auto; margin: 1.4rem 0; }
table { border-collapse: collapse; width: 100%; font-size: 0.93em; }
th, td {
  text-align: left;
  padding: 0.45rem 0.8rem 0.45rem 0.5rem;
  vertical-align: top;
}
th {
  font-size: 13px;
  color: var(--t-text-muted);
  font-weight: 600;
  white-space: nowrap;
  border-bottom: 1px solid var(--t-border-strong);
}
td:first-child { white-space: nowrap; }
td code { font-size: 0.86em; white-space: nowrap; }
td code + code { margin-left: 0.25em; }
tbody tr { transition: background-color 150ms ease-out; }
tbody tr:hover { background: var(--t-surface); }

.aside {
  margin: 1.6rem 0;
  padding: 0.9rem 1.15rem;
  background: var(--t-surface);
  box-shadow: var(--t-ring);
  font-size: 0.93em;
  max-width: var(--measure);
}
.aside p { margin: 0; max-width: none; }
.aside p + p { margin-top: 0.6rem; }
.aside strong { color: var(--t-brand); }

/* ── the foot ───────────────────────────────────────────────────────── */

footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.4rem 1.5rem;
  border-top: 1px solid var(--t-border-subtle);
  margin-top: 4rem;
  padding: 1rem var(--gutter-width) 2.5rem;
  font-size: 13px;
  color: var(--t-text-muted);
}
footer p { max-width: none; margin: 0; }
