/* ==========================================================================
   Buache Systems — site styles

   Hand-edited. No build step, no preprocessor, no framework.

   Two things set the look, and they pull in the same direction. The brand
   (see brand/README.md at the root of this repository) supplies the marks,
   the two grounds and the amber. Slate, the widget kit the applications are
   built on, supplies the manners, restated here for a document:

     - Flat surfaces. Hairline rules carry the structure; nothing is elevated.
     - One accent, used sparingly. It marks the current page, focus, and links.
     - Tight line heights, generous space between blocks.
     - Corners are square. The 2px on code blocks and the 23% on the
       application icons are the only exceptions, and the second is the
       brand's own container radius.
     - Monospace for anything a reader will type or paste.

   Sections
     1. Fonts
     2. Colour
     3. Reset and base
     4. Layout
     5. Header and footer
     6. Typography
     7. Code blocks and the copy button
     8. Tables and keys
     9a. Application icons and downloads
     9b. Figures and definition lists
    10. Buttons and links
    11. Responsive
   ========================================================================== */


/* 1. Fonts ----------------------------------------------------------------
   Self-hosted. There is not a single third-party request on this site, and a
   webfont from someone else's CDN would be the first one — which also means
   no visitor's IP address is handed to a font host, which is the whole point.

   Inter for the name and the interface, IBM Plex Mono for the sub-line and
   anything machine-written: paths, versions, filenames, tabular data. Both
   are SIL OFL 1.1 — see Inter-LICENSE.txt and LICENSE.txt in assets/fonts/.

   Two weights per family and no italics. The unhinted `web/` build of Inter
   is used rather than the hinted one: 30 KB smaller per face, and hinting is
   ignored by every renderer this site is read on. */

@font-face {
  font-family: "Inter";
  src: url("fonts/Inter-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Inter";
  src: url("fonts/Inter-SemiBold.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Mono";
  src: url("fonts/IBMPlexMono-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Mono";
  src: url("fonts/IBMPlexMono-SemiBold.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}


/* 2. Colour ---------------------------------------------------------------
   Both themes come from one place. `light-dark()` reads the used colour
   scheme, so the manual toggle only has to set `color-scheme` on the root and
   every token follows.

   The neutrals are built around the two brand grounds, ink #1A1D1B and paper
   #F1F2EF. Both carry a slight green cast; the greys between them keep it
   rather than sliding to a pure neutral, or the page reads as two palettes.

   The amber is one colour in two values, and the brand is explicit that they
   are never mixed in one composition: #E8901F on dark grounds, #C77410 on
   light ones. A document has a stricter contrast floor than an application
   chrome does, so there is one deliberate exception:

     --accent-strong  #C77410 -> #98580C   in the light theme only

   #C77410 reaches 3.15:1 on paper and 2.89:1 on the panels, well under the
   4.5 a link or a filled button needs. #98580C is the same hue and the same
   saturation three lightness steps down: 5.00:1 on paper, 4.60:1 on a panel,
   and 5.62:1 under white button text. The undarkened amber stays as --accent
   for rules, borders and the current-page marker, where no text floor applies
   and the brand value should be the one on screen. In the dark theme there is
   no exception: #E8901F clears 7.31:1 on the page ground on its own. */

/* Fallback for browsers without light-dark(): the light theme. */
:root {
  --bg: #F1F2EF;
  --chrome: #E7E9E4;
  --panel: #E7E9E4;
  --popover: #FFFFFF;
  --border: #D2D5CD;
  --separator: #E0E2DB;
  --ink: #1A1D1B;
  --ink-dim: #5B615C;
  --accent: #C77410;
  --accent-strong: #98580C;
  --on-accent: #FFFFFF;
  --hover: #DFE2DA;
  --selected: #F7E9D6;
  --field: #FFFFFF;
  --field-border: #C9CDC3;
  --danger: #C0392B;
}

/* The real definition. Edit colours here. */
:root {
  color-scheme: light dark;

  --bg: light-dark(#F1F2EF, #141613);
  --chrome: light-dark(#E7E9E4, #1A1D1B);
  --panel: light-dark(#E7E9E4, #1A1D1B);
  --popover: light-dark(#FFFFFF, #1F2320);
  --border: light-dark(#D2D5CD, #2C302D);
  --separator: light-dark(#E0E2DB, #242724);
  --ink: light-dark(#1A1D1B, #F1F2EF);
  --ink-dim: light-dark(#5B615C, #969C97);
  --accent: light-dark(#C77410, #E8901F);
  --accent-strong: light-dark(#98580C, #E8901F);
  --on-accent: light-dark(#FFFFFF, #1A1D1B);
  --hover: light-dark(#DFE2DA, #232725);
  --selected: light-dark(#F7E9D6, #2C2519);
  --field: light-dark(#FFFFFF, #141613);
  --field-border: light-dark(#C9CDC3, #343833);
  --danger: light-dark(#C0392B, #E0574A);

  /* Type */
  --sans: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, "Cascadia Mono", "Consolas", monospace;

  /* Measure for running prose. Wider than this and the eye loses the line. */
  --measure: 68ch;

  /* The page gutter, and the width the content is capped at. */
  --gutter: 2rem;
  --width: 64rem;
}

/* The manual toggle. Setting the scheme is enough: light-dark() resolves
   against it, and so do form controls and scrollbars. */
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }


/* 3. Reset and base ------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.55;
  font-feature-settings: "kern", "liga";
  text-rendering: optimizeLegibility;
}

img,
svg {
  max-width: 100%;
  height: auto;
  display: block;
}

/* Controls that do nothing without JavaScript are not shown. A dead button is
   worse than no button. theme.js removes .no-js from <html> as its first act. */
.no-js .js-only {
  display: none !important;
}

/* Keyboard users must always be able to see where they are. */
:focus-visible {
  outline: 2px solid var(--accent-strong);
  outline-offset: 2px;
  border-radius: 1px;
}

/* Only for browsers without :focus-visible; the rule above wins where it is
   supported. */
:focus:not(:focus-visible) {
  outline: none;
}

/* Parked just above the viewport rather than at left: -9999px. A large
   negative offset is the older trick and it can widen the scrollable area;
   negative top overflow never does. */
.skip-link {
  position: absolute;
  top: -3rem;
  left: 0;
  z-index: 10;
  padding: 0.5rem 0.875rem;
  background: var(--accent-strong);
  color: var(--on-accent);
  font-size: 0.875rem;
  text-decoration: none;
  transition: top 100ms;
}

.skip-link:focus {
  top: 0;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}


/* 4. Layout --------------------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: var(--width);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

main {
  display: block;
  padding-block: 3.5rem 5rem;
}

/* A rule between major sections. Hairline, full measure, never a shadow. */
.section {
  padding-block-start: 3rem;
  margin-block-start: 3rem;
  border-block-start: 1px solid var(--separator);
}

.section:first-of-type {
  padding-block-start: 0;
  margin-block-start: 0;
  border-block-start: 0;
}


/* 5. Header and footer ---------------------------------------------------- */

.site-header {
  background: var(--chrome);
  border-block-end: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 5;
}

.site-header .wrap {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  min-height: 3.25rem;
}

/* The lockup, rebuilt in HTML. brand/logo/lockup.svg carries the same three
   pieces as live <text>, which is right for a file handed to someone else and
   wrong here: as markup the name is selectable, it is read aloud correctly,
   and it follows the theme. Keep the two in step if either changes. */
.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}

.wordmark svg {
  width: 22px;
  height: 22px;
  flex: none;
}

/* The mark, filled from the tokens rather than from presentation attributes,
   so it follows the theme like everything else. favicon.svg carries the same
   circles with literal colours and its own media query, because a file loaded
   as an icon has no stylesheet to inherit from. */
.mark-dots { fill: var(--ink); }
.mark-accent { fill: var(--accent); }

.wordmark-text {
  display: flex;
  flex-direction: column;
  line-height: 1;
}

.wordmark-name {
  font-size: 1.125rem;
  font-weight: 600;
  letter-spacing: -0.045em;
}

/* `systems`, set beneath the name in amber and in the mono face, exactly as
   the lockup does it. Optical alignment: the mono face carries more left
   sidebearing than Inter, so it is nudged back a hair to sit under the b. */
.wordmark-sub {
  margin-block-start: 0.1875rem;
  margin-inline-start: -0.03em;
  color: var(--accent-strong);
  font-family: var(--mono);
  font-size: 0.5rem;
  letter-spacing: 0.19em;
}


/* The navigation, and the Apps submenu ------------------------------------
   The submenu opens on hover and on :focus-within, which is what makes it
   work with no JavaScript at all: tabbing to the trigger reveals it, and the
   links inside keep it open because focus is still within the item. nav.js
   only adds what CSS cannot — the ARIA state, Escape, and closing on an
   outside click — and it adds the attributes itself, so nothing in the markup
   claims a behaviour that is not there when the script does not run. */

.site-nav {
  margin-inline-start: auto;
}

.site-nav > ul {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-nav li {
  margin: 0;
  max-width: none;
}

.site-nav a,
.nav-trigger {
  display: block;
  padding-block: 0.875rem;
  color: var(--ink-dim);
  font-size: 0.875rem;
  text-decoration: none;
  border-block-end: 2px solid transparent;
}

.site-nav a:hover,
.nav-trigger:hover {
  color: var(--ink);
}

.site-nav a[aria-current="page"] {
  color: var(--ink);
  border-block-end-color: var(--accent);
}

/* The trigger is a button, not a link: there is no /apps/ page for it to go
   to, and a link to nowhere is worse than a control that only opens a menu. */
.nav-trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.3125rem;
  padding-inline: 0;
  background: none;
  border-inline: 0;
  border-block-start: 0;
  font-family: inherit;
  cursor: pointer;
}

.nav-trigger svg {
  width: 9px;
  height: 9px;
  fill: currentColor;
}

.has-submenu {
  position: relative;
}

/* Marks the trigger while any page under it is the one being read. */
.has-submenu[data-section="current"] .nav-trigger {
  color: var(--ink);
  border-block-end-color: var(--accent);
}

.submenu {
  display: none;
  position: absolute;
  top: 100%;
  inset-inline-start: -0.875rem;
  min-width: 11rem;
  margin: 0;
  padding: 0.25rem 0;
  background: var(--popover);
  border: 1px solid var(--border);
  border-radius: 2px;
  list-style: none;
}

.has-submenu:hover .submenu,
.has-submenu:focus-within .submenu,
.has-submenu.is-open .submenu {
  display: block;
}

.submenu a {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.4375rem 0.875rem;
  border-block-end: 0;
}

.submenu a:hover {
  background: var(--hover);
}

.submenu a[aria-current="page"] {
  color: var(--ink);
  background: var(--selected);
}

.submenu img {
  width: 18px;
  height: 18px;
  flex: none;
  border-radius: 4px;
}

.theme-toggle {
  flex: none;
  display: inline-grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  padding: 0;
  background: transparent;
  color: var(--ink-dim);
  border: 1px solid var(--border);
  border-radius: 2px;
  cursor: pointer;
}

.theme-toggle:hover {
  background: var(--hover);
  color: var(--ink);
}

.theme-toggle svg {
  width: 16px;
  height: 16px;
}

/* One button, two glyphs; the scheme decides which is drawn. */
.theme-toggle .icon-dark { display: none; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .icon-light { display: none; }
  :root:not([data-theme="light"]) .theme-toggle .icon-dark { display: block; }
}

:root[data-theme="dark"] .theme-toggle .icon-light { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-dark { display: block; }
:root[data-theme="light"] .theme-toggle .icon-light { display: block; }
:root[data-theme="light"] .theme-toggle .icon-dark { display: none; }

.site-footer {
  background: var(--chrome);
  border-block-start: 1px solid var(--border);
  color: var(--ink-dim);
  font-size: 0.875rem;
}

.site-footer .wrap {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 2.5rem;
  padding-block: 2rem 2.5rem;
}

.site-footer h2 {
  margin: 0 0 0.5rem;
  color: var(--ink);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.site-footer ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-footer li + li {
  margin-block-start: 0.25rem;
}

.site-footer .colophon {
  margin-inline-start: auto;
  max-width: 26rem;
}

.site-footer p {
  margin: 0 0 0.5rem;
  font-size: 0.8125rem;
}


/* 6. Typography ----------------------------------------------------------- */

h1, h2, h3, h4 {
  margin: 0;
  color: var(--ink);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.005em;
}

h1 {
  font-size: 2rem;
  letter-spacing: -0.02em;
}

h2 {
  font-size: 1.25rem;
  margin-block-end: 1rem;
}

h3 {
  font-size: 1rem;
  margin-block-end: 0.5rem;
}

p, ul, ol, dl, figure, table, pre {
  margin-block: 0 1.25rem;
}

p, li {
  max-width: var(--measure);
}

:is(p, li) > code,
:is(td, th) > code {
  max-width: none;
}

li {
  margin-block-end: 0.375rem;
}

ul, ol {
  padding-inline-start: 1.25rem;
}

.lede {
  font-size: 1.0625rem;
  color: var(--ink);
}

.eyebrow {
  margin-block-end: 0.5rem;
  color: var(--ink-dim);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.tagline {
  margin-block: 0.5rem 1.5rem;
  max-width: var(--measure);
  color: var(--ink-dim);
  font-size: 1.0625rem;
}

.note {
  max-width: var(--measure);
  color: var(--ink-dim);
  font-size: 0.875rem;
}

/* An honest statement of where a tool actually is. Bordered, not coloured in:
   this is information, not a warning. */
.status {
  max-width: var(--measure);
  margin-block-end: 2rem;
  padding: 0.875rem 1rem;
  background: var(--panel);
  border: 1px solid var(--border);
  border-inline-start: 2px solid var(--accent);
  font-size: 0.9375rem;
}

.status p {
  margin: 0;
}

.status p + p {
  margin-block-start: 0.625rem;
}

.status strong {
  font-weight: 600;
}


/* 7. Code blocks and the copy button --------------------------------------- */

code, kbd, samp, pre {
  font-family: var(--mono);
  font-size: 0.875rem;
}

:not(pre) > code {
  padding: 0.1em 0.35em;
  background: var(--panel);
  border: 1px solid var(--separator);
  border-radius: 2px;
  font-size: 0.8125rem;
  /* Not nowrap. A path like ~/.local/share/… is longer than a 320px screen,
     and an unbreakable one pushes the whole page sideways. Short tokens never
     reach the edge of the line, so they never break. */
  overflow-wrap: anywhere;
}

.command {
  position: relative;
  margin-block-end: 1.25rem;
  background: var(--field);
  border: 1px solid var(--border);
  border-radius: 2px;
}

.command pre {
  margin: 0;
  padding: 0.875rem 1rem;
  padding-inline-end: 5.5rem;
  overflow-x: auto;
  line-height: 1.6;
  tab-size: 2;
}

.command pre code {
  padding: 0;
  background: none;
  border: 0;
  white-space: pre;
}

.copy-button {
  position: absolute;
  top: 0.5rem;
  inset-inline-end: 0.5rem;
  padding: 0.25rem 0.5rem;
  background: var(--panel);
  color: var(--ink-dim);
  border: 1px solid var(--border);
  border-radius: 2px;
  font-family: var(--sans);
  font-size: 0.75rem;
  line-height: 1.4;
  cursor: pointer;
}

.copy-button:hover {
  background: var(--hover);
  color: var(--ink);
}

.copy-button[data-copied="true"] {
  color: var(--accent-strong);
  border-color: var(--accent);
}

.command-caption {
  margin-block: -0.75rem 1.25rem;
  color: var(--ink-dim);
  font-size: 0.8125rem;
}


/* 8. Tables and keys ------------------------------------------------------- */

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9375rem;
}

caption {
  margin-block-end: 0.75rem;
  color: var(--ink-dim);
  font-size: 0.875rem;
  text-align: start;
}

th {
  padding: 0 0.75rem 0.5rem 0;
  color: var(--ink-dim);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  text-align: start;
  border-block-end: 1px solid var(--border);
}

td {
  padding: 0.5rem 0.75rem 0.5rem 0;
  border-block-end: 1px solid var(--separator);
  vertical-align: baseline;
}

tr > :last-child {
  padding-inline-end: 0;
}

/* The shortcut column: keep the keys together and let the description wrap. */
.shortcuts td:first-child {
  white-space: nowrap;
  width: 1%;
  padding-inline-end: 1.5rem;
}

.table-scroll {
  overflow-x: auto;
  margin-block-end: 1.25rem;
}

kbd {
  display: inline-block;
  padding: 0.05em 0.35em;
  background: var(--panel);
  color: var(--ink);
  border: 1px solid var(--field-border);
  border-radius: 2px;
  font-size: 0.8125rem;
  line-height: 1.5;
  white-space: nowrap;
}

kbd + kbd {
  margin-inline-start: 0.25rem;
}


/* 9a. Application icons and downloads --------------------------------------
   The five icons are one system: one container radius, one glyph stroke, one
   two-stop vertical gradient each. They carry their own ground, so they are
   the one place on the site where a colour is not a token — and the one place
   that needs no dark variant, because a filled tile reads the same on both. */

.app-icon {
  flex: none;
  border-radius: 23%;
}

/* Icon-led rather than screenshot-led: three tools, three icons, one row, and
   nothing standing in for a screenshot that does not exist. The real windows
   are on the tool pages, where there is room to show them properly. */
.tools {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.5rem;
  margin-block-end: 0;
  padding: 0;
  list-style: none;
}

.tool {
  position: relative;
  display: flex;
  flex-direction: column;
  max-width: none;
  margin: 0;
  padding: 1.25rem 1.25rem 1.375rem;
  background: var(--panel);
  border: 1px solid var(--border);
}

.tool .app-icon {
  width: 44px;
  height: 44px;
  margin-block-end: 0.875rem;
}

.tool h3 {
  font-size: 1.0625rem;
  margin-block-end: 0.375rem;
}

.tool h3 a {
  color: var(--ink);
  text-decoration: none;
}

/* The heading link covers the whole card, so the icon is a target too. One
   link per card: no second anchor to hide from assistive technology after. */
.tool h3 a::after {
  content: "";
  position: absolute;
  inset: 0;
}

.tool h3 a:hover {
  color: var(--accent-strong);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.tool p {
  margin-block-end: 0.875rem;
  max-width: none;
  font-size: 0.9375rem;
}

.tool-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem 0.75rem;
  margin-block: auto 0;
  color: var(--ink-dim);
  font-family: var(--mono);
  font-size: 0.75rem;
}

/* A download row: icon, what the file is, and the control. Hairline-separated
   rows rather than cards, because the interesting column is the filename and
   it should line up down the page. */
.downloads {
  margin-block-end: 2rem;
  padding: 0;
  list-style: none;
  border-block-start: 1px solid var(--separator);
}

.downloads li {
  display: flex;
  align-items: center;
  gap: 1rem;
  max-width: none;
  margin: 0;
  padding-block: 1rem;
  border-block-end: 1px solid var(--separator);
}

.downloads .app-icon {
  width: 36px;
  height: 36px;
}

.download-what {
  flex: 1 1 auto;
  min-width: 0;
}

.download-what h3 {
  font-size: 0.9375rem;
  margin-block-end: 0.125rem;
}

/* The name is ink, not a link colour. Three amber headings stacked above three
   amber filenames put the accent on everything, which is the same as putting
   it on nothing — and the row already has one amber thing worth looking at. */
.download-what h3 a {
  color: var(--ink);
  text-decoration: none;
}

.download-what h3 a:hover {
  color: var(--accent-strong);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* The filename and the size. Mono, dim, and allowed to wrap rather than push
   the row sideways on a narrow screen. */
.download-file {
  margin: 0;
  max-width: none;
  color: var(--ink-dim);
  font-family: var(--mono);
  font-size: 0.75rem;
  overflow-wrap: anywhere;
}

.download-get {
  flex: none;
}


/* 9b. Figures and definition lists ---------------------------------------- */

.shots {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.5rem;
  margin-block-end: 2rem;
}

figure {
  margin: 0;
}

figure img {
  width: 100%;
  border: 1px solid var(--border);
}

figcaption {
  margin-block-start: 0.5rem;
  color: var(--ink-dim);
  font-size: 0.8125rem;
}

/* Facts about a tool: version, licence, where the source is. Two columns of
   hairline-separated rows. */
.facts {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 0;
  max-width: var(--measure);
  margin-block-end: 2rem;
  border-block-start: 1px solid var(--separator);
}

.facts dt {
  padding: 0.5rem 1.5rem 0.5rem 0;
  color: var(--ink-dim);
  font-size: 0.8125rem;
  border-block-end: 1px solid var(--separator);
}

.facts dd {
  margin: 0;
  padding: 0.5rem 0;
  font-size: 0.875rem;
  border-block-end: 1px solid var(--separator);
}

/* Two columns of running prose, for the home page's why-it-exists block. */
.columns {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 3rem;
}

.columns p {
  max-width: 46ch;
}


/* The home page's three promises: a heading and one line each, no cards, so
   they read as statements and not as a second row of apps. */
.promises {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.5rem 3rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.promises li {
  margin: 0;
  max-width: none;
}

.promises h3 {
  font-size: 1.0625rem;
  margin-block-end: 0.375rem;
}

.promises p {
  margin: 0;
  color: var(--ink-dim);
}

.closing {
  max-width: var(--measure);
  margin-block-end: 0.75rem;
  color: var(--ink);
  font-size: 1.375rem;
  font-weight: 600;
  line-height: 1.3;
}


/* 10. Buttons and links ---------------------------------------------------- */

a {
  color: var(--accent-strong);
  text-decoration: underline;
  text-underline-offset: 0.15em;
  text-decoration-thickness: 1px;
}

a:hover {
  text-decoration-thickness: 2px;
}

main h1 a,
main h2 a,
main h3 a {
  text-decoration: none;
}

.links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  margin-block-end: 1.25rem;
  padding: 0;
  list-style: none;
}

.links li {
  margin: 0;
  max-width: none;
}

.button {
  display: inline-block;
  padding: 0.375rem 0.875rem;
  background: var(--accent-strong);
  color: var(--on-accent);
  border: 1px solid var(--accent-strong);
  border-radius: 2px;
  font-size: 0.875rem;
  text-decoration: none;
}

.button:hover {
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

.button-quiet {
  background: transparent;
  color: var(--ink);
  border-color: var(--border);
}

.button-quiet:hover {
  background: var(--hover);
}

/* A package that does not exist yet. A <span>, not a disabled <a>: there is
   no URL to put in it, and a link that goes nowhere is worse than a label
   that says so. Dotted rather than solid, so it reads as a gap in the row
   rather than as a control someone failed to click. */
.button-pending {
  display: inline-block;
  padding: 0.375rem 0.875rem;
  background: transparent;
  color: var(--ink-dim);
  border: 1px dashed var(--border);
  border-radius: 2px;
  font-size: 0.875rem;
  white-space: nowrap;
  cursor: default;
}


/* 11. Responsive ----------------------------------------------------------- */

@media (max-width: 60rem) {
  .columns {
    grid-template-columns: minmax(0, 1fr);
  }

  .columns p {
    max-width: var(--measure);
  }
}

@media (max-width: 48rem) {
  :root {
    --gutter: 1.25rem;
  }

  h1 {
    font-size: 1.625rem;
  }

  main {
    padding-block: 2.5rem 3.5rem;
  }

  .tools,
  .promises,
  .shots {
    grid-template-columns: minmax(0, 1fr);
  }

  .site-header {
    position: static;
  }

  .site-header .wrap {
    flex-wrap: wrap;
    gap: 0 1rem;
    padding-block: 0.625rem;
  }

  .site-nav {
    order: 3;
    width: 100%;
    margin-inline-start: 0;
    border-block-start: 1px solid var(--border);
  }

  .site-nav ul {
    flex-wrap: wrap;
    gap: 0 1rem;
  }

  .site-nav a {
    padding-block: 0.5rem;
  }

  /* The submenu stops being a submenu. It exists to keep five items off a
     crowded header bar, and down here the header bar is its own row with
     nothing to be crowded by — so the trigger goes and the three apps join
     the others as one wrapping list. `display: contents` hoists them into the
     nav's flex row without touching the markup, which stays a nested list for
     anything that reads structure rather than layout.

     It also gets the header back under a third of a 320px screen; stacked,
     the same six links took more than half of it. */
  .nav-trigger {
    display: none;
  }

  .has-submenu,
  .submenu {
    display: contents;
  }

  .submenu a {
    gap: 0.375rem;
    padding: 0.5rem 0;
    background: none;
  }

  .submenu img {
    width: 16px;
    height: 16px;
  }

  .downloads li {
    flex-wrap: wrap;
  }

  .download-what {
    flex-basis: 60%;
  }

  /* The nav has dropped to its own row, so the toggle is alone on the first
     one with the wordmark and has the whole gap to itself. */
  .theme-toggle {
    margin-inline-start: auto;
  }

  .site-footer .wrap {
    flex-direction: column;
    gap: 1.5rem;
  }

  .site-footer .colophon {
    margin-inline-start: 0;
  }
}

/* 320px. The command blocks scroll rather than the page. */
@media (max-width: 26rem) {
  :root {
    --gutter: 1rem;
  }

  h1 {
    font-size: 1.5rem;
  }

  .command pre {
    padding-inline-end: 1rem;
    padding-block-start: 2.5rem;
  }

  .facts {
    grid-template-columns: minmax(0, 1fr);
  }

  .facts dt {
    padding-block-end: 0;
    border-block-end: 0;
  }
}
