/**
 * Thermal Type — UI styles.
 *
 * Built on the ASTA design system (MIT, https://github.com/anton-io/asta):
 * a monospace framework where every element aligns to a character grid.
 * Tokens, form components, rhythm and the flat 2px-border language are
 * ASTA's; the app-shell layout and the canvas/slider/palette components
 * are additions for this tool.
 *
 * Two deliberate departures from the upstream framework:
 *
 *  1. ASTA lays documents out centred and capped at 80ch. This is a tool
 *     with a fixed control column beside a canvas, so the shell is a grid
 *     and only the panel's internals keep the character measure.
 *  2. ASTA applies `* + * { margin-top: var(--line-height) }` for document
 *     rhythm. In a dense control panel that fights every grid and stacks
 *     margins onto absolutely-positioned children, so spacing here is
 *     explicit and still quantised to the same line-height scale.
 *
 * On colour: an earlier pass kept the chrome strictly monochrome so the
 * artwork would be the only colour on screen. That read as undifferentiated
 * — with every control drawn in the same flat black-on-white, nothing told
 * you which mode was live, which palette was selected, or where one section
 * ended and the next began. A single accent is now reserved for exactly one
 * job: marking what is currently ON. Everything inert stays monochrome, so
 * the accent still means something at a glance and the canvas is still the
 * only place a second colour appears.
 */

/* ─── Fonts ─────────────────────────────────────────────────────────── */
@font-face {
  font-family: 'JetBrains Mono';
  src: url('fonts/JetBrainsMono-Medium.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'JetBrains Mono';
  src: url('fonts/JetBrainsMono-SemiBold.woff2') format('woff2');
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'JetBrains Mono';
  src: url('fonts/JetBrainsMono-ExtraBold.woff2') format('woff2');
  font-weight: 800; font-style: normal; font-display: swap;
}

/* ─── Design tokens ─────────────────────────────────────────────────── */
:root {
  --font-family: 'JetBrains Mono', ui-monospace, 'SFMono-Regular', Consolas, monospace;
  --line-height: 1.20rem;

  --border-thickness: 2px;
  --char-width: 1ch;

  --spacing-half: calc(var(--line-height) / 2);
  --spacing-1: var(--line-height);
  --spacing-1-5: calc(var(--line-height) * 1.5);
  --spacing-2: calc(var(--line-height) * 2);

  --text-color: #000;
  --text-color-alt: #5a5a5a;
  --background-color: #fff;
  --background-color-alt: #ededed;
  /* Header bands need to separate from the body without becoming a third
     surface colour; a hair darker than background-alt is enough. */
  --surface-band: #e0e0e0;
  /* Reserved for "this is on". Dark enough to carry white text at the
     small sizes this panel uses. */
  --accent: #b3350a;
  --accent-ink: #fff;

  --font-weight-normal: 500;
  --font-weight-medium: 600;
  --font-weight-bold: 800;

  font-family: var(--font-family);
  font-optical-sizing: auto;
  font-weight: var(--font-weight-normal);
  font-variant-numeric: tabular-nums lining-nums;
  font-size: 15px;

  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --text-color: #fff;
    --text-color-alt: #9a9a9a;
    --background-color: #000;
    --background-color-alt: #141414;
    --surface-band: #1e1e1e;
    --accent: #ff7a3c;
    --accent-ink: #000;
  }
}
:root[data-theme='dark'] {
  --text-color: #fff;
  --text-color-alt: #9a9a9a;
  --background-color: #000;
  --background-color-alt: #141414;
  --surface-band: #1e1e1e;
  --accent: #ff7a3c;
  --accent-ink: #000;
}
:root[data-theme='light'] {
  --text-color: #000;
  --text-color-alt: #5a5a5a;
  --background-color: #fff;
  --background-color-alt: #ededed;
  --surface-band: #e0e0e0;
  --accent: #b3350a;
  --accent-ink: #fff;
}

/* ─── Reset ─────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; min-width: 0; }
* { margin: 0; padding: 0; }

html, body { height: 100%; }

body {
  background: var(--background-color);
  color: var(--text-color);
  line-height: var(--line-height);
  overflow: hidden;
  display: grid;
  grid-template-columns: 46ch 1fr;
  -webkit-font-smoothing: antialiased;
}

button, input, select, textarea, output {
  font: inherit;
  font-variant-numeric: inherit;
  color: inherit;
}

/* ─── App shell: control panel ──────────────────────────────────────── */
.panel {
  height: 100vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--background-color);
  border-right: var(--border-thickness) solid var(--text-color);
}

.brand {
  display: flex;
  align-items: center;
  gap: 1ch;
  padding: var(--spacing-1) 2ch;
  border-bottom: var(--border-thickness) solid var(--text-color);
}
.brand-name { min-width: 0; }
.brand h1 {
  font-size: 1.2rem;
  font-weight: var(--font-weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.05ch;
  line-height: var(--line-height);
  white-space: nowrap;
}
.brand p {
  margin-top: calc(var(--line-height) / 4);
  color: var(--text-color-alt);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.12ch;
}
.brand-actions { display: flex; align-items: center; gap: 1ch; margin-left: auto; }

/* The three interaction modes are mutually exclusive and belong on one
   row; Pause and Advanced are separate switches and sit apart from them,
   because grouping all five made it look like a five-way choice. */
.mode-switch {
  padding: var(--spacing-1) 2ch;
  border-bottom: var(--border-thickness) solid var(--text-color);
  background: var(--background-color-alt);
}
.switch-label {
  display: block;
  font-size: 0.7rem;
  font-weight: var(--font-weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.14ch;
  color: var(--text-color-alt);
  margin-bottom: calc(var(--line-height) / 3);
}
.switch-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1ch; }
.switch-row.one { grid-template-columns: 1fr; margin-top: 1ch; }

/* ─── Advanced switch ───────────────────────────────────────────────────
   A full-width bar pinned under the scrolling controls. It is the only
   thing down there, so it cannot be mistaken for one of the mode buttons,
   and it states what it will do rather than relying on a lone number. */
.panel-footer {
  flex: none;
  padding: var(--spacing-1) 2ch;
  border-top: var(--border-thickness) solid var(--text-color);
  background: var(--background-color-alt);
}
#advancedToggle {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1ch;
  font-size: 0.76rem;
}
.toggle-sign {
  font-size: 1rem;
  font-weight: var(--font-weight-bold);
  line-height: 1;
}
.toggle-count {
  display: inline-grid;
  place-content: center;
  min-width: 2.5ch;
  padding: 0 0.4ch;
  background: var(--text-color);
  color: var(--background-color);
  font-size: 0.66rem;
  font-variant-numeric: tabular-nums;
}
.toggle-count[hidden] { display: none; }

/* ─── Advanced controls ─────────────────────────────────────────────────
   Hidden by default and revealed as a block. Kept in the DOM rather than
   built on demand so their values stay bound and exports are unaffected
   by whether the panel happens to be showing them. */
body:not([data-show-advanced='on']) [data-advanced] { display: none !important; }

.controls {
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-bottom: var(--spacing-2);
}

/* ─── Collapsible sections ──────────────────────────────────────────────
   A section has to be findable while scrolling a long panel. The header is
   a filled band with a boxed number, so the eye lands on a run of solid
   bars rather than on twenty identical rows of text; the open one carries
   an accent rule down its left edge so you can see where you are without
   reading anything. */
details { border-bottom: var(--border-thickness) solid var(--text-color); }

summary {
  display: flex;
  align-items: center;
  gap: 1.5ch;
  padding: calc(var(--line-height) * 0.75) 2ch;
  cursor: pointer;
  user-select: none;
  text-transform: uppercase;
  font-weight: var(--font-weight-bold);
  font-size: 0.9rem;
  letter-spacing: 0.08ch;
  background: var(--surface-band);
  border-left: 4px solid transparent;
  /* The upstream framework styles `summary::marker` directly. Safari does
     not honour `content` on `::marker`, so the disclosure glyph is drawn
     as a `::before` instead — same look, works everywhere. */
  list-style: none;
}
summary::-webkit-details-marker { display: none; }

/* Numbered chip. Boxed so it reads as a marker, not as part of the title. */
summary > span:first-of-type {
  display: inline-grid;
  place-content: center;
  min-width: 3ch;
  height: var(--line-height);
  padding: 0 0.5ch;
  background: var(--text-color);
  color: var(--background-color);
  font-size: 0.7rem;
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
}
summary::after {
  content: '+';
  margin-left: auto;
  font-size: 1rem;
  font-weight: var(--font-weight-bold);
  color: var(--text-color-alt);
}
details[open] > summary { border-left-color: var(--accent); }
details[open] > summary::after { content: '−'; }
details[open] > summary > span:first-of-type {
  background: var(--accent);
  color: var(--accent-ink);
}
summary:hover { background: var(--background-color-alt); }
summary:focus-visible { outline: var(--border-thickness) solid var(--accent); outline-offset: -2px; }

.section-body {
  padding: var(--spacing-1) 2ch var(--spacing-1-5);
  border-left: 4px solid transparent;
}

/* ─── Groups inside a section ───────────────────────────────────────── */
.group { margin-top: var(--spacing-1-5); }
.group:first-child { margin-top: var(--spacing-half); }
.group-title {
  font-size: 0.7rem;
  font-weight: var(--font-weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.14ch;
  color: var(--text-color-alt);
  padding-bottom: calc(var(--line-height) / 4);
  border-bottom: 1px solid var(--text-color-alt);
  margin-bottom: var(--spacing-half);
}

/* ─── Typography helpers ────────────────────────────────────────────── */
.hint {
  color: var(--text-color-alt);
  font-size: 0.78rem;
  margin-bottom: var(--spacing-1);
}
.file-status, .export-status {
  color: var(--text-color-alt);
  font-size: 0.75rem;
  min-height: var(--line-height);
  margin-top: var(--spacing-half);
  text-transform: uppercase;
  letter-spacing: 0.06ch;
}
.export-status.active { color: var(--text-color); font-weight: var(--font-weight-medium); }

/* ─── Form controls ─────────────────────────────────────────────────── */
button, select, textarea, input[type='color'], .upload {
  border: var(--border-thickness) solid var(--text-color);
  background: var(--background-color);
  color: var(--text-color);
  border-radius: 0;
  -webkit-appearance: none;
  appearance: none;
}

button, .upload {
  display: block;
  width: 100%;
  height: calc(var(--line-height) * 2);
  padding: 0 1ch;
  text-transform: uppercase;
  font-weight: var(--font-weight-medium);
  font-size: 0.78rem;
  letter-spacing: 0.06ch;
  cursor: pointer;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
button:hover, .upload:hover { background: var(--background-color-alt); }
/* ASTA's tactile press. Kept for buttons only — a file-input wrapper that
   shifts under the cursor makes the hit target slide away mid-click. */
button:active { transform: translate(2px, 2px); }
button:focus-visible, .upload:focus-within,
select:focus, textarea:focus, input:focus-visible {
  --border-thickness: 3px;
  outline: none;
}
/* The one job the accent has: showing what is currently on. */
button.active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
  font-weight: var(--font-weight-bold);
}
button.active:hover { background: var(--accent); filter: brightness(1.1); }
/* Export's primary action is emphasis, not state — inverted, not accented,
   so a live mode is never confused with a button that merely looks loud. */
button.accent {
  background: var(--text-color);
  color: var(--background-color);
  font-weight: var(--font-weight-bold);
}
button.accent:hover { background: var(--text-color); }
button:disabled { opacity: 0.35; cursor: wait; transform: none; }

.quiet {
  width: auto;
  padding: 0 1ch;
  font-size: 0.72rem;
}

.field { display: block; margin-top: var(--spacing-1); }
.field > span, .upload > span {
  display: block;
  color: var(--text-color-alt);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.1ch;
  margin-bottom: calc(var(--line-height) / 4);
  font-weight: var(--font-weight-medium);
}

select, textarea {
  width: 100%;
  padding: calc(var(--line-height) / 2 - var(--border-thickness)) calc(1ch - var(--border-thickness));
  font-size: 0.84rem;
}
select { height: calc(var(--line-height) * 2); cursor: pointer; }
textarea {
  resize: vertical;
  min-height: calc(var(--line-height) * 6);
  line-height: var(--line-height);
}

.field-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1ch; align-items: end; }
.field-grid.three { grid-template-columns: 1fr 1fr 6ch; }
.field-grid .field { margin-top: 0; }

/* File input: the native control is hidden behind a styled label. */
.upload { position: relative; display: grid; place-content: center; }
.upload > span { margin: 0; color: var(--text-color); }
.upload input { position: absolute; inset: 0; width: 100%; opacity: 0; cursor: pointer; }

input[type='color'] {
  width: 100%;
  height: calc(var(--line-height) * 2);
  padding: 2px;
  cursor: pointer;
}
input[type='color']::-webkit-color-swatch-wrapper { padding: 0; }
input[type='color']::-webkit-color-swatch { border: 0; }
input[type='color']::-moz-color-swatch { border: 0; }

/* ─── Range sliders ─────────────────────────────────────────────────── */
/* ASTA ships no range component. Drawn here in the same language: a rule
   one border-thickness tall, and a thumb that is a solid character cell. */
.slider { display: block; margin-top: var(--spacing-1); }
.slider-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1ch;
  color: var(--text-color);
  font-size: 0.78rem;
  letter-spacing: 0.04ch;
  font-weight: var(--font-weight-medium);
}
/* The readout is the thing you check while dragging, so it is boxed and
   set at full contrast — previously it was the same grey as its own label
   and the two blurred together down the column. */
.slider-output {
  color: var(--text-color);
  background: var(--background-color-alt);
  padding: 0 0.6ch;
  font-size: 0.74rem;
  font-weight: var(--font-weight-bold);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

input[type='range'] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: var(--line-height);
  background: transparent;
  cursor: ew-resize;
  border: 0;
  padding: 0;
}
input[type='range']::-webkit-slider-runnable-track {
  height: 4px;
  background: var(--background-color-alt);
  border: 1px solid var(--text-color-alt);
}
input[type='range']::-moz-range-track {
  height: 4px;
  background: var(--background-color-alt);
  border: 1px solid var(--text-color-alt);
}
input[type='range']::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 1.6ch;
  height: var(--line-height);
  background: var(--text-color);
  border: 2px solid var(--background-color);
  border-radius: 0;
  margin-top: calc((4px - var(--line-height)) / 2);
}
input[type='range']::-moz-range-thumb {
  width: 1.6ch;
  height: var(--line-height);
  background: var(--text-color);
  border: 2px solid var(--background-color);
  border-radius: 0;
}
input[type='range']:hover::-webkit-slider-thumb { background: var(--accent); }
input[type='range']:hover::-moz-range-thumb { background: var(--accent); }
input[type='range']:focus-visible::-webkit-slider-thumb { outline: var(--border-thickness) solid var(--text-color); outline-offset: 2px; }

/* ─── Grouped button rows ───────────────────────────────────────────── */
.wide { margin-top: var(--spacing-1); }
.preset-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1ch; margin-top: var(--spacing-1); }
.preset-grid button { font-size: 0.68rem; padding: 0 0.5ch; }
.export-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1ch; margin-top: var(--spacing-1); }

.palette-bar {
  height: calc(var(--line-height) * 1.5);
  border: var(--border-thickness) solid var(--text-color);
  margin-top: var(--spacing-1);
}
.color-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1ch; margin-top: var(--spacing-1); }
.color-grid label {
  display: block;
  color: var(--text-color-alt);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.06ch;
  font-weight: var(--font-weight-medium);
}
.color-grid input { margin-top: calc(var(--line-height) / 4); }

.export-note { margin-top: var(--spacing-1); margin-bottom: 0; }

/* ─── Theme toggle ──────────────────────────────────────────────────── */
.theme-toggle {
  width: calc(var(--line-height) * 2);
  height: calc(var(--line-height) * 2);
  border: var(--border-thickness) solid var(--text-color);
  background: var(--background-color);
  display: grid;
  place-content: center;
  cursor: pointer;
  padding: 0;
  flex: none;
}
.theme-toggle:hover { background: var(--background-color-alt); }
.theme-toggle::before {
  content: '';
  width: var(--line-height);
  height: var(--line-height);
  background-color: var(--text-color);
  /* Sun and moon as masks rather than inline SVG fills, so the glyph
     recolours with the theme token instead of needing a second asset. */
  -webkit-mask: var(--theme-icon) center / contain no-repeat;
  mask: var(--theme-icon) center / contain no-repeat;
  --theme-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='4'/%3E%3Cline x1='12' y1='1' x2='12' y2='4'/%3E%3Cline x1='12' y1='20' x2='12' y2='23'/%3E%3Cline x1='4.22' y1='4.22' x2='6.34' y2='6.34'/%3E%3Cline x1='17.66' y1='17.66' x2='19.78' y2='19.78'/%3E%3Cline x1='1' y1='12' x2='4' y2='12'/%3E%3Cline x1='20' y1='12' x2='23' y2='12'/%3E%3Cline x1='4.22' y1='19.78' x2='6.34' y2='17.66'/%3E%3Cline x1='17.66' y1='6.34' x2='19.78' y2='4.22'/%3E%3C/svg%3E");
}
:root[data-theme='dark'] .theme-toggle::before,
:root:not([data-theme='light']) .theme-toggle::before {
  --theme-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z'/%3E%3C/svg%3E");
}
@media (prefers-color-scheme: light) {
  :root:not([data-theme='dark']) .theme-toggle::before {
    --theme-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='4'/%3E%3Cline x1='12' y1='1' x2='12' y2='4'/%3E%3Cline x1='12' y1='20' x2='12' y2='23'/%3E%3Cline x1='4.22' y1='4.22' x2='6.34' y2='6.34'/%3E%3Cline x1='17.66' y1='17.66' x2='19.78' y2='19.78'/%3E%3Cline x1='1' y1='12' x2='4' y2='12'/%3E%3Cline x1='20' y1='12' x2='23' y2='12'/%3E%3Cline x1='4.22' y1='19.78' x2='6.34' y2='17.66'/%3E%3Cline x1='17.66' y1='6.34' x2='19.78' y2='4.22'/%3E%3C/svg%3E");
  }
}

/* ─── Stage ─────────────────────────────────────────────────────────── */
.stage {
  position: relative;
  display: grid;
  place-items: center;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  background: var(--background-color-alt);
  padding: var(--spacing-2) 2ch calc(var(--line-height) * 3);
}
/* Character-cell graph paper, sized off the same rhythm as everything else. */
.stage::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(var(--text-color) 1px, transparent 1px),
    linear-gradient(90deg, var(--text-color) 1px, transparent 1px);
  background-size: 2ch var(--line-height);
  opacity: 0.07;
  pointer-events: none;
}

.canvas-shell {
  position: relative;
  display: grid;
  place-items: center;
  max-width: 100%;
  max-height: 100%;
  border: var(--border-thickness) solid var(--text-color);
  touch-action: none;
  cursor: none;
}
#art {
  display: block;
  max-width: 100%;
  max-height: calc(100vh - var(--line-height) * 7);
  width: auto;
  height: auto;
  background: #f4f2ec;
}

.cursor-ring {
  position: absolute;
  left: 0; top: 0;
  width: 80px; height: 80px;
  border: var(--border-thickness) solid #fff;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  pointer-events: none;
  opacity: 0;
  mix-blend-mode: difference;
  transition: opacity 0.12s;
}
.canvas-shell:hover .cursor-ring { opacity: 1; }

.stage-hud {
  position: absolute;
  left: 2ch; right: 2ch;
  bottom: var(--line-height);
  display: flex;
  justify-content: space-between;
  gap: 1ch;
  color: var(--text-color-alt);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.1ch;
  font-weight: var(--font-weight-medium);
  pointer-events: none;
}

.fatal {
  position: absolute;
  inset: 0;
  background: var(--background-color);
  display: grid;
  place-items: center;
  text-align: center;
  padding: var(--spacing-2) 2ch;
  border: var(--border-thickness) solid var(--text-color);
  z-index: 5;
}
.fatal[hidden] { display: none; }

/* ─── Scrollbars ────────────────────────────────────────────────────── */
.controls { scrollbar-width: thin; scrollbar-color: var(--text-color-alt) transparent; }
.controls::-webkit-scrollbar { width: 1ch; }
.controls::-webkit-scrollbar-thumb { background: var(--text-color-alt); }
.controls::-webkit-scrollbar-track { background: transparent; }

/* ─── Responsive ────────────────────────────────────────────────────── */
@media (max-width: 900px) {
  body { display: flex; flex-direction: column; overflow: auto; }
  .panel { display: contents; }
  .brand { order: 0; background: var(--background-color); }
  .mode-switch { order: 1; background: var(--background-color); }
  .stage { order: 2; height: 70vh; min-height: 460px; padding: var(--spacing-1) 2ch var(--spacing-2); }
  .controls {
    order: 3;
    overflow: visible;
    border-top: var(--border-thickness) solid var(--text-color);
  }
  /* `.panel { display: contents }` dissolves the column here, so the footer
     needs its own order or it would land above the stage. */
  .panel-footer { order: 4; }
  .canvas-shell { max-height: 100%; }
  #art { max-height: calc(70vh - var(--line-height) * 5); }
}

@media (max-width: 480px) {
  :root { font-size: 14px; }
  .field-grid, .field-grid.three { grid-template-columns: 1fr 1fr; }
  .field-grid.three .field:last-child { grid-column: 1 / -1; }
  .preset-grid { grid-template-columns: 1fr; }
  .color-grid { grid-template-columns: repeat(2, 1fr); }
  .brand { position: sticky; top: 0; z-index: 3; }
}

/* ─── About and licence ─────────────────────────────────────────────── */
/* Term and definition pairs, set with the same label treatment the form
   fields use so the section reads as part of the panel, not a bolt-on. */
.about { margin: 0; }
.about dt {
  color: var(--text-color-alt);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.1ch;
  font-weight: var(--font-weight-medium);
  margin-bottom: calc(var(--line-height) / 4);
}
.about dd {
  margin: 0 0 var(--spacing-half);
  font-size: 0.8rem;
}
.about dd:last-child { margin-bottom: 0; }
.about a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.about a:hover, .about a:focus-visible { color: var(--accent); }
