/* ===========================================================================
   Qoffee documentation stylesheet
   ---------------------------------------------------------------------------
   Neobrutalist. Thick black rules, hard offset shadows with no blur, flat
   saturated blocks, no border radius anywhere.

   Fonts load from Google Fonts in each page head. To self host, put the woff2
   files in assets/ and swap the link tag for @font-face here.

   Layout contract
   ---------------
   Above 940px  the shell is a two column grid: a sticky rail and a main
                column. The on-this-page table of contents is fixed to the
                right gutter. The quick links float over the bottom right.

   At or below  the rail becomes an off canvas drawer opened from a sticky
   940px        top bar, the table of contents becomes a collapsible panel in
                the flow, and the quick links move into a real page footer.
                Nothing overlaps the text.

   The desktop rendering is deliberately unchanged. Every mobile behaviour
   lives inside `@media (max-width: 940px)` in section 18. If you are changing
   desktop, you are in the wrong half of the file.

   Section index
   -------------
     1  tokens
     2  reset and base
     3  skip link
     4  entry page
     5  shell, rail, top bar
     6  page table of contents
     7  content typography
     8  code
     9  tables
    10  status vocabulary
    11  hero
    12  notification block
    13  timeline
    14  setup steps
    15  figures
    16  closer
    17  quick links and footer
    18  responsive
    19  debug helpers
   ======================================================================== */

/* -- 1. tokens ----------------------------------------------------------- */

:root {
  --paper: #e9e4f4;
  --card: #ffffff;
  --ink: #140f1e;

  --teal: #00d2a0;
  --purple: #9e0ffe;
  --amber: #ffc21f;
  --coral: #ff5a45;

  --bd: 3px;
  --sh: 6px 6px 0 var(--ink);
  --sh-sm: 4px 4px 0 var(--ink);
  --sh-lg: 9px 9px 0 var(--ink);

  --display: "Bricolage Grotesque", "Arial Black", Impact, sans-serif;
  --sans: "Space Grotesk", "Segoe UI", -apple-system, system-ui, sans-serif;
  --mono: "Space Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  --measure: 62ch;

  /* Height of the mobile top bar. Re-measured at runtime by assets/qoffee.js
     so anchor scrolling stays correct if the bar ever wraps. */
  --topbar-h: 61px;

  /* Grid ground, shared by body and by the mobile drawer so the drawer reads
     as the same surface rather than a floating panel. */
  --grid-line: rgba(20, 15, 30, 0.06);
  --grid-size: 32px;

  --drawer-w: min(320px, 88vw);
  --nav-ease: 200ms ease;
}

/* -- 2. reset and base --------------------------------------------------- */

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

html {
  background: var(--paper);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  background-color: var(--paper);
  background-image:
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: var(--grid-size) var(--grid-size);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.6;
  font-weight: 400;
  /* A long identifier in prose must not widen the page on a narrow screen. */
  overflow-wrap: break-word;
}

img,
svg,
video {
  max-width: 100%;
}

a {
  color: var(--ink);
  font-weight: 700;
  text-decoration: none;
  border-bottom: 3px solid var(--teal);
  padding-bottom: 1px;
}

a:hover {
  background: var(--teal);
}

:focus-visible {
  outline: 3px solid var(--purple);
  outline-offset: 3px;
}

/* -- 3. skip link -------------------------------------------------------- */

.skip {
  position: absolute;
  left: -9999px;
}

.skip:focus {
  left: 14px;
  top: 14px;
  z-index: 80;
  background: var(--amber);
  border: var(--bd) solid var(--ink);
  padding: 8px 14px;
}

/* -- 4. entry page ------------------------------------------------------- */

.entry-page {
  min-height: 100vh;
  min-height: 100dvh;
}

.entry-main {
  width: min(1120px, calc(100% - 56px));
  min-height: 100vh;
  min-height: 100dvh;
  margin: 0 auto;
  padding: 34px 0 28px;
}

.entry-header {
  max-width: 880px;
  margin-bottom: 30px;
}

.entry-header .motto {
  background: var(--amber);
  color: var(--ink);
  margin-bottom: 12px;
}

.entry-header h1 {
  margin: 0 0 12px;
  max-width: 14ch;
  font-size: clamp(42px, 6vw, 68px);
  line-height: 0.88;
}

.entry-lede {
  max-width: 56ch;
  margin: 0;
  font-size: 16px;
  line-height: 1.35;
}

.entry-options {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px;
  max-width: 1000px;
}

.entry-option {
  display: flex;
  flex-direction: column;
  min-height: 214px;
  padding: 16px 20px 14px;
  border: var(--bd) solid var(--ink);
  box-shadow: var(--sh-lg);
  transition: transform 140ms ease, box-shadow 140ms ease;
}

.entry-option:hover {
  transform: translate(-4px, -4px);
  box-shadow: 13px 13px 0 var(--ink);
}

.entry-option-use {
  background: var(--teal);
  transform: rotate(-1.2deg);
}

.entry-option-use:hover {
  background: var(--teal);
}

.entry-option-code {
  background: var(--amber);
  transform: rotate(1.2deg);
}

.entry-option-code:hover {
  background: var(--amber);
}

.entry-option-index {
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 700;
  margin-bottom: auto;
}

.entry-option-label {
  display: block;
  max-width: 10ch;
  margin: 22px 0 10px;
  font-family: var(--display);
  font-size: clamp(30px, 3.2vw, 42px);
  line-height: 0.94;
  font-weight: 800;
}

.entry-option-copy {
  display: block;
  max-width: 38ch;
  min-height: 48px;
  font-size: 13px;
  line-height: 1.35;
}

.entry-option-action {
  display: block;
  margin-top: 10px;
  padding-top: 8px;
  border-top: 2px solid var(--ink);
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.entry-foot {
  margin: 28px 0 0;
  font-family: var(--mono);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.entry-foot a {
  border-bottom-width: 2px;
}

/* -- 5. shell, rail, top bar --------------------------------------------- */

.shell {
  display: grid;
  grid-template-columns: 280px minmax(0, 1fr);
  max-width: 1240px;
  margin: 0 auto;
  min-height: 100vh;
  min-height: 100dvh;
}

.rail {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100dvh;
  overflow-y: scroll;
  scrollbar-width: thin;
  scrollbar-color: var(--ink) var(--paper);
  border-right: var(--bd) solid var(--ink);
  padding: 26px 22px 60px 22px;
}

.rail::-webkit-scrollbar {
  width: 12px;
}

.rail::-webkit-scrollbar-track {
  background: var(--paper);
  border-left: 2px solid var(--ink);
}

.rail::-webkit-scrollbar-thumb {
  background: var(--ink);
  border: 2px solid var(--paper);
}

.rail::-webkit-scrollbar-thumb:hover {
  background: var(--teal);
}

.rail-inner {
  position: static;
}

.rail nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.rail nav li {
  margin: 0 0 4px 0;
}

.rail nav a {
  display: block;
  padding: 5px 9px;
  font-size: 15px;
  font-weight: 500;
  line-height: 1.35;
  border: 2px solid transparent;
  border-bottom-width: 2px;
}

.rail nav a:hover {
  background: var(--teal);
  border-color: var(--ink);
}

.rail nav a[aria-current="page"] {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
  font-weight: 700;
}

.rail-boundary {
  margin: 20px 0 14px 0;
  border-top: var(--bd) dashed var(--ink);
  padding-top: 12px;
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.5;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.rail-foot {
  margin-top: 28px;
  border-top: var(--bd) solid var(--ink);
  padding-top: 12px;
  font-family: var(--mono);
  font-size: 12px;
  line-height: 2;
}

.rail-foot a {
  border-bottom-width: 2px;
}

/* The drawer header, the top bar and the scrim exist only in the mobile
   layout. They are in the markup on every documentation page and are switched
   on in section 18. */

.rail-head,
.topbar,
.rail-scrim {
  display: none;
}

/* -- 6. page table of contents ------------------------------------------- */

.page-toc {
  position: fixed;
  top: 34px;
  right: max(24px, calc((100vw - 1240px) / 2 + 24px));
  width: 210px;
  max-height: calc(100vh - 68px);
  overflow-y: auto;
  border-left: var(--bd) dashed var(--ink);
  padding-left: 12px;
}

.page-toc-title {
  margin: 0 0 8px;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  line-height: 1.4;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.page-toc ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.page-toc li {
  margin: 0 0 2px;
}

.page-toc a {
  display: block;
  padding: 3px 7px;
  border: 2px solid transparent;
  border-bottom-width: 2px;
  font-size: 12px;
  font-weight: 500;
  line-height: 1.3;
}

.page-toc a:hover {
  background: var(--teal);
  border-color: var(--ink);
}

.page-toc .toc-sub a {
  padding-left: 18px;
  font-size: 11px;
}

/* The collapse control is a mobile affordance only. */
.page-toc-toggle {
  display: none;
}

/* -- 7. content typography ----------------------------------------------- */

main {
  padding: 34px 46px 130px 46px;
  min-width: 0;
}

body.has-toc main#content,
body:has(.page-toc) main#content {
  position: relative;
  padding-right: 270px;
}

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

h1 {
  font-family: var(--display);
  font-size: clamp(38px, 5.4vw, 58px);
  line-height: 0.94;
  font-weight: 800;
  letter-spacing: -0.035em;
  margin: 4px 0 26px 0;
  max-width: 15ch;
}

h2 {
  font-family: var(--display);
  font-size: 27px;
  line-height: 1.08;
  font-weight: 800;
  letter-spacing: -0.025em;
  margin: 56px 0 16px 0;
  max-width: 22ch;
}

h2::after {
  content: "";
  display: block;
  width: 62px;
  height: 7px;
  background: var(--purple);
  border: 2px solid var(--ink);
  margin-top: 10px;
}

h3 {
  font-weight: 700;
  font-size: 19px;
  letter-spacing: -0.015em;
  margin: 34px 0 8px 0;
}

/* Anchors land clear of the sticky top bar rather than under it. On desktop
   there is no bar and this is a small comfortable offset. */
h1[id],
h2[id],
h3[id] {
  scroll-margin-top: 24px;
}

p {
  margin: 0 0 16px 0;
}

ul,
ol {
  padding-left: 22px;
  margin: 0 0 18px 0;
}

li {
  margin-bottom: 9px;
}

li::marker {
  font-weight: 700;
}

strong {
  font-weight: 700;
  background: var(--amber);
  box-shadow: 0 0 0 2px var(--amber);
}

.why-matters strong {
  background: var(--teal);
  box-shadow: 0 0 0 2px var(--teal);
}

.limits-intro {
  font-weight: 700;
  background-color: transparent !important;
  background-image: none !important;
  box-shadow: none !important;
}

.limits-list strong {
  background: none;
  box-shadow: none;
}

.note {
  background: var(--card);
  border: var(--bd) solid var(--ink);
  border-left-width: 12px;
  box-shadow: var(--sh-sm);
  padding: 14px 18px;
  margin: 24px 0;
  font-size: 16px;
  max-width: 660px;
}

/* -- 8. code ------------------------------------------------------------- */

code {
  font-family: var(--mono);
  font-size: 0.85em;
  background: var(--card);
  border: 2px solid var(--ink);
  padding: 0 4px;
}

pre {
  position: relative;
  background: var(--ink);
  border: var(--bd) solid var(--ink);
  box-shadow: var(--sh);
  padding: 20px;
  overflow-x: auto;
  margin: 0 0 26px 0;
  max-width: 720px;
}

pre code {
  background: none;
  border: 0;
  padding: 0;
  font-size: 13.5px;
  line-height: 1.75;
  color: #f0ecfa;
}

.copy {
  position: absolute;
  top: -3px;
  right: -3px;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--teal);
  border: var(--bd) solid var(--ink);
  padding: 4px 10px;
  cursor: pointer;
}

.copy:hover {
  background: var(--amber);
}

.copy[data-state="error"] {
  background: var(--coral);
}

/* -- 9. tables ----------------------------------------------------------- */

table {
  border-collapse: collapse;
  width: 100%;
  max-width: 720px;
  margin: 0 0 28px 0;
  font-size: 15px;
  background: var(--card);
  border: var(--bd) solid var(--ink);
  box-shadow: var(--sh);
}

/* Wrapper added by assets/qoffee.js. Inert on desktop: a plain block that
   changes no metric. It becomes the horizontal scroll container on narrow
   screens, which is the only way to keep a three column table legible on a
   phone without restyling it into something else. */

.table-wrap {
  max-width: 720px;
  margin: 0 0 28px 0;
}

.table-wrap > table {
  max-width: none;
  margin: 0;
}

th {
  text-align: left;
  font-family: var(--mono);
  font-weight: 700;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  background: var(--ink);
  color: var(--paper);
  padding: 8px 14px;
  border-right: 2px solid var(--paper);
}

th:last-child {
  border-right: 0;
}

td {
  padding: 11px 14px;
  border-top: 2px solid var(--ink);
  border-right: 2px solid var(--ink);
  vertical-align: top;
}

td:last-child {
  border-right: 0;
}

td:first-child {
  font-weight: 700;
  white-space: nowrap;
  background: #f4f1fb;
}

td.free {
  white-space: normal;
  font-weight: 400;
  background: none;
}

/* -- 10. status vocabulary ----------------------------------------------- */

.chip {
  display: inline-block;
  font-family: var(--mono);
  font-size: 11.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  padding: 1px 7px;
  border: 2px solid var(--ink);
  background: var(--card);
  white-space: nowrap;
}

.chip-active {
  background: var(--amber);
}

.chip-ok {
  background: var(--teal);
}

.chip-fail {
  background: var(--coral);
}

/* -- 11. hero ------------------------------------------------------------ */

.hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 330px;
  gap: 44px;
  align-items: start;
  margin-bottom: 20px;
}

.motto {
  display: inline-block;
  font-family: var(--display);
  font-size: 15px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  background: var(--amber);
  border: var(--bd) solid var(--ink);
  box-shadow: var(--sh-sm);
  padding: 6px 14px;
  margin: 0 0 24px 0;
  transform: rotate(-1.6deg);
}

.hero-lede {
  font-family: var(--display);
  font-size: clamp(30px, 4.1vw, 44px);
  line-height: 1.02;
  font-weight: 800;
  letter-spacing: -0.035em;
  margin: 0 0 22px 0;
  max-width: 17ch;
}

.hero-go {
  display: inline-block;
  font-family: var(--display);
  font-size: 19px;
  font-weight: 800;
  text-transform: uppercase;
  background: var(--teal);
  border: var(--bd) solid var(--ink);
  box-shadow: var(--sh);
  padding: 12px 26px;
  margin-top: 6px;
}

.hero-go:hover {
  background: var(--amber);
  box-shadow: var(--sh-lg);
}

.hero-go:active {
  box-shadow: 2px 2px 0 var(--ink);
  transform: translate(4px, 4px);
}

/* -- 12. notification block ---------------------------------------------- */

.notif {
  background: var(--card);
  border: var(--bd) solid var(--ink);
  box-shadow: var(--sh-lg);
  transform: rotate(1.2deg);
}

.notif-head {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--purple);
  border-bottom: var(--bd) solid var(--ink);
  padding: 9px 13px;
}

.notif-avatar {
  width: 24px;
  height: 24px;
  background: var(--teal);
  border: 2px solid var(--ink);
  flex: none;
}

.notif-name {
  font-family: var(--display);
  font-size: 15px;
  font-weight: 800;
  color: #fff;
  line-height: 1.1;
}

.notif-time {
  font-family: var(--mono);
  font-size: 11px;
  color: #fff;
}

.notif-body {
  padding: 14px 13px 15px 13px;
}

.notif-title {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-bottom: 3px solid var(--ink);
  padding-bottom: 8px;
  margin-bottom: 12px;
}

.notif-row {
  border: 2px solid var(--ink);
  margin-bottom: 9px;
  font-size: 13px;
}

.notif-row:last-child {
  margin-bottom: 0;
}

.notif-tag {
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 2px 8px;
  border-bottom: 2px solid var(--ink);
}

.t-active {
  background: var(--amber);
}

.t-ok {
  background: var(--teal);
}

.t-fail {
  background: var(--coral);
}

.notif-item {
  padding: 7px 9px;
  line-height: 1.4;
  font-weight: 500;
}

.notif-item code {
  font-size: 10.5px;
  border-width: 1px;
  padding: 0 3px;
}

.notif-err {
  font-family: var(--mono);
  font-size: 10.5px;
  background: var(--ink);
  color: #f0ecfa;
  padding: 5px 7px;
  margin-top: 6px;
  overflow-x: auto;
}

/* -- 13. timeline -------------------------------------------------------- */

.tl {
  margin: 26px 0 30px 0;
  max-width: 680px;
  border-left: var(--bd) solid var(--ink);
  padding-left: 26px;
}

.tl-row {
  position: relative;
  padding-bottom: 26px;
}

.tl-row::before {
  content: "";
  position: absolute;
  left: -34px;
  top: 6px;
  width: 14px;
  height: 14px;
  background: var(--paper);
  border: var(--bd) solid var(--ink);
}

.tl-row.speaks::before {
  background: var(--coral);
}

.tl-clock {
  display: inline-block;
  font-family: var(--mono);
  font-size: 11.5px;
  font-weight: 700;
  background: var(--ink);
  color: var(--paper);
  padding: 1px 7px;
  margin-bottom: 6px;
}

.tl-what {
  font-size: 16px;
}

.tl-msg {
  margin-top: 10px;
  background: var(--card);
  border: var(--bd) solid var(--ink);
  box-shadow: var(--sh-sm);
  padding: 11px 14px;
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.75;
  max-width: 420px;
}

.tl-msg b {
  display: block;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  border-bottom: 2px solid var(--ink);
  padding-bottom: 5px;
  margin-bottom: 6px;
}

/* -- 14. setup steps ----------------------------------------------------- */

.step {
  background: var(--card);
  border: var(--bd) solid var(--ink);
  box-shadow: var(--sh-lg);
  padding: 0 0 26px 0;
  margin: 0 0 34px 0;
  max-width: 740px;
}

.step-count {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  background: var(--ink);
  color: var(--paper);
  padding: 6px 16px;
}

.step-n {
  font-family: var(--display);
  font-size: 86px;
  line-height: 0.85;
  font-weight: 800;
  letter-spacing: -0.06em;
  background: var(--teal);
  border-bottom: var(--bd) solid var(--ink);
  padding: 16px 20px 12px 20px;
}

.calm .step-n {
  background: var(--purple);
  color: #fff;
}

.step h2,
.step p,
.step table,
.step .table-wrap,
.step pre,
.step figure,
.step .reassure,
.step ul {
  margin-left: 26px;
  margin-right: 26px;
}

.step h2 {
  font-size: 25px;
  margin-top: 22px;
  margin-bottom: 14px;
}

.step h2::after {
  display: none;
}

.step p:last-child {
  margin-bottom: 0;
}

.step table,
.step .table-wrap,
.step pre {
  max-width: calc(100% - 52px);
}

.step table,
.step pre {
  box-shadow: var(--sh-sm);
}

/* When a wrapper is present it owns the gutters and the child goes flush. */
.step .table-wrap > table {
  margin-left: 0;
  margin-right: 0;
  max-width: none;
}

.reassure {
  background: var(--amber);
  border: var(--bd) solid var(--ink);
  padding: 12px 16px;
  margin-bottom: 18px;
  font-size: 15.5px;
  line-height: 1.5;
  font-weight: 500;
}

/* -- 15. figures --------------------------------------------------------- */

figure {
  margin-bottom: 0;
}

figure img {
  display: block;
  width: 100%;
  height: auto;
  border: var(--bd) solid var(--ink);
}

figcaption {
  font-family: var(--mono);
  font-size: 12px;
  margin-top: 8px;
  line-height: 1.5;
}

.shot-todo {
  border: var(--bd) dashed var(--ink);
  background: #f4f1fb;
  padding: 32px 18px;
  text-align: center;
  font-family: var(--mono);
  font-size: 12.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* -- 16. closer ---------------------------------------------------------- */

.closer {
  font-family: var(--display);
  font-size: 22px;
  line-height: 1.25;
  font-weight: 700;
  letter-spacing: -0.02em;
  background: var(--card);
  border: var(--bd) solid var(--ink);
  box-shadow: var(--sh);
  padding: 20px 24px;
  margin: 52px 0 0 0;
  max-width: 720px;
}

.closer code {
  background: var(--amber);
  border: 0;
  padding: 0 2px;
}

/* -- 17. quick links and footer ------------------------------------------ */

/* `.site-foot` wraps the quick links. Both of its children are fixed
   positioned above 940px, so the wrapper has zero height and contributes
   nothing to the desktop layout. Below 940px it becomes a real footer and the
   children join the flow, which is what stops them covering the prose. */

.site-foot {
  margin: 0;
  padding: 0;
}

.floating-links {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 10;
  display: flex;
  gap: 8px;
}

.floating-link {
  position: relative;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border: 3px solid var(--ink);
  box-shadow: 4px 4px 0 var(--ink);
  color: var(--ink);
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  text-decoration: none;
  transition: transform 140ms ease, box-shadow 140ms ease;
}

.floating-link:hover {
  transform: translate(-2px, -2px);
  box-shadow: 6px 6px 0 var(--ink);
}

.floating-link::after {
  content: attr(data-label);
  position: absolute;
  right: 0;
  bottom: calc(100% + 42px);
  z-index: 12;
  width: max-content;
  max-width: 180px;
  padding: 5px 8px;
  background: #000;
  color: #fff;
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 700;
  line-height: 1.2;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  opacity: 0;
  pointer-events: none;
  transform: translateY(4px);
  transition: opacity 140ms ease, transform 140ms ease;
}

.floating-link:hover::after,
.floating-link:focus-visible::after {
  opacity: 1;
  transform: translateY(0);
}

.floating-link-repo {
  background: var(--teal);
}

.floating-link-repo:hover {
  background: var(--teal);
}

.floating-link-email {
  background: var(--amber);
}

.floating-link-email:hover {
  background: var(--amber);
}

.floating-link-wiki {
  background: var(--purple);
  color: #fff;
}

.floating-link-wiki:hover {
  background: var(--purple);
}

.ecosystem-note {
  position: fixed;
  right: 18px;
  bottom: 70px;
  z-index: 11;
  width: max-content;
  max-width: min(330px, calc(100vw - 36px));
  color: var(--ink);
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 700;
  line-height: 1.2;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.ecosystem-note a {
  color: var(--ink);
  border-bottom: 2px solid var(--teal);
}

.ecosystem-note a:hover {
  background: var(--teal);
  color: var(--ink);
}

/* A tooltip that needs hover is dead weight on a touch screen and it flashes
   on tap. The same text is already the link's accessible name. */
@media (hover: none) {
  .floating-link::after {
    content: none;
  }

  .floating-link:hover {
    transform: none;
    box-shadow: 4px 4px 0 var(--ink);
  }
}

/* ==========================================================================
   18. responsive
   Everything below this line is the narrow layout. Nothing here applies
   above 940px.
   ======================================================================== */

@media (max-width: 940px) {

  /* -- 18a. shell becomes a single column -------------------------------- */

  .shell {
    grid-template-columns: minmax(0, 1fr);
    min-height: calc(100vh - var(--topbar-h));
    min-height: calc(100dvh - var(--topbar-h));
  }

  main {
    padding: 24px 18px 44px 18px;
  }

  body.has-toc main#content,
  body:has(.page-toc) main#content {
    padding-right: 18px;
  }

  h1[id],
  h2[id],
  h3[id] {
    scroll-margin-top: calc(var(--topbar-h) + 14px);
  }

  /* -- 18b. sticky top bar ----------------------------------------------- */

  .topbar {
    position: sticky;
    top: 0;
    z-index: 40;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 14px;
    border-bottom: var(--bd) solid var(--ink);
    background: var(--paper);
  }

  .topbar-btn {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    flex: none;
    min-height: 42px;
    padding: 0 14px;
    background: var(--teal);
    color: var(--ink);
    border: var(--bd) solid var(--ink);
    box-shadow: var(--sh-sm);
    font-family: var(--mono);
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    line-height: 1;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
  }

  .topbar-btn:active {
    box-shadow: 1px 1px 0 var(--ink);
    transform: translate(3px, 3px);
  }

  .topbar-burger,
  .topbar-burger::before,
  .topbar-burger::after {
    display: block;
    width: 18px;
    height: 3px;
    background: var(--ink);
  }

  .topbar-burger {
    position: relative;
  }

  .topbar-burger::before,
  .topbar-burger::after {
    content: "";
    position: absolute;
    left: 0;
  }

  .topbar-burger::before {
    top: -6px;
  }

  .topbar-burger::after {
    top: 6px;
  }

  .topbar-here {
    flex: 1 1 auto;
    min-width: 0;
    font-family: var(--mono);
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    line-height: 1.25;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .topbar-home {
    display: none;
  }

  /* -- 18c. rail becomes an off canvas drawer ---------------------------- */

  .rail-scrim {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 50;
    background: rgba(20, 15, 30, 0.55);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--nav-ease);
  }

  .nav-open .rail-scrim {
    opacity: 1;
    pointer-events: auto;
  }

  .rail {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    z-index: 60;
    width: var(--drawer-w);
    height: 100vh;
    height: 100dvh;
    overflow-y: auto;
    overscroll-behavior: contain;
    border-right: var(--bd) solid var(--ink);
    border-bottom: 0;
    background-color: var(--paper);
    background-image:
      linear-gradient(var(--grid-line) 1px, transparent 1px),
      linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
    background-size: var(--grid-size) var(--grid-size);
    padding: 16px 16px 44px 16px;
    transform: translateX(-101%);
    visibility: hidden;
    transition:
      transform var(--nav-ease),
      visibility 0s linear 200ms;
  }

  .nav-open .rail {
    transform: translateX(0);
    visibility: visible;
    transition:
      transform var(--nav-ease),
      visibility 0s linear 0s;
  }

  .rail::-webkit-scrollbar {
    width: 8px;
  }

  .rail-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin: 0 0 14px 0;
    padding-bottom: 12px;
    border-bottom: var(--bd) solid var(--ink);
  }

  .rail-head-title {
    font-family: var(--mono);
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
  }

  .rail-close {
    display: grid;
    place-items: center;
    flex: none;
    width: 40px;
    height: 40px;
    padding: 0;
    background: var(--coral);
    color: var(--ink);
    border: var(--bd) solid var(--ink);
    box-shadow: var(--sh-sm);
    font-family: var(--mono);
    font-size: 15px;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
  }

  .rail-close:active {
    box-shadow: 1px 1px 0 var(--ink);
    transform: translate(3px, 3px);
  }

  /* Comfortable thumb targets in the drawer. */
  .rail nav li {
    margin-bottom: 5px;
  }

  .rail nav a {
    padding: 9px 10px;
    font-size: 15.5px;
  }

  .rail-boundary {
    margin: 18px 0 14px 0;
    font-size: 11px;
  }

  /* -- 18d. table of contents joins the flow ----------------------------- */

  .page-toc {
    position: static;
    width: auto;
    max-width: none;
    max-height: none;
    overflow: visible;
    margin: 0 0 28px 0;
    padding: 0;
    background: var(--card);
    border: var(--bd) solid var(--ink);
    border-left-width: 12px;
    box-shadow: var(--sh-sm);
  }

  .page-toc-title {
    display: none;
  }

  .page-toc-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    width: 100%;
    min-height: 44px;
    margin: 0;
    padding: 10px 14px;
    background: none;
    border: 0;
    color: var(--ink);
    font-family: var(--mono);
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    text-align: left;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
  }

  .page-toc-toggle::after {
    content: "+";
    flex: none;
    font-size: 17px;
    line-height: 1;
  }

  .page-toc-toggle[aria-expanded="true"]::after {
    content: "\2212";
  }

  .page-toc ul {
    display: none;
    border-top: 2px solid var(--ink);
    padding: 8px 10px 12px 10px;
  }

  .page-toc.is-open ul {
    display: block;
  }

  .page-toc li {
    margin-bottom: 2px;
  }

  .page-toc a {
    padding: 8px;
    font-size: 14px;
    line-height: 1.35;
  }

  .page-toc .toc-sub a {
    padding-left: 22px;
    font-size: 13px;
  }

  /* -- 18e. horizontally scrollable tables ------------------------------- */

  .table-wrap {
    max-width: 100%;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    padding: 0 9px 9px 0;
    margin: 0 0 19px 0;
    scrollbar-width: thin;
    scrollbar-color: var(--ink) var(--paper);
  }

  .table-wrap::-webkit-scrollbar {
    height: 8px;
  }

  .table-wrap::-webkit-scrollbar-track {
    background: var(--paper);
    border-top: 2px solid var(--ink);
  }

  .table-wrap::-webkit-scrollbar-thumb {
    background: var(--ink);
  }

  /* Squeezing three columns into 340px turns every cell into a word ladder.
     Holding a floor and letting the wrapper scroll keeps the table readable
     and keeps it looking like the same table. */
  .table-wrap[data-cols="2"] > table {
    min-width: 420px;
  }

  .table-wrap[data-cols="3"] > table {
    min-width: 560px;
  }

  .table-wrap[data-cols="4"] > table {
    min-width: 680px;
  }

  /* -- 18f. blocks that were sized for the desktop column ---------------- */

  /* The copy button is absolutely positioned inside the `pre`. When the
     `pre` is itself the horizontal scroll container, scrolling a wide block
     carries the button off the right hand edge with the content, which on a
     phone is where wide blocks always are. Moving the scrolling down onto the
     `code` leaves the button anchored to the block.

     Deliberately mobile only. Doing it on desktop would move the scrollbar
     inside the padding, which is a visible change to blocks that already fit
     and do not need fixing. */
  pre {
    overflow: visible;
    padding: 16px;
  }

  pre > code {
    display: block;
    overflow-x: auto;
    overscroll-behavior-x: contain;
  }

  pre code {
    font-size: 13px;
  }

  .note {
    padding: 13px 15px;
    font-size: 15.5px;
  }

  .closer {
    padding: 18px;
    font-size: 20px;
    margin-top: 44px;
  }

  h2 {
    margin-top: 44px;
  }

  /* -- 18g. entry page --------------------------------------------------- */

  .entry-page {
    min-height: 0;
  }

  .entry-main {
    width: min(100% - 36px, 620px);
    min-height: 0;
    padding: 28px 0 24px;
  }

  .entry-header {
    margin-bottom: 24px;
  }

  .entry-header .motto {
    font-size: 11px;
    padding: 5px 9px;
    margin-bottom: 14px;
  }

  .entry-header h1 {
    font-size: clamp(38px, 11vw, 58px);
  }

  .entry-lede {
    font-size: 17px;
  }

  .entry-options {
    grid-template-columns: minmax(0, 1fr);
    gap: 16px;
  }

  .entry-option {
    min-height: 156px;
    padding: 12px 14px 10px;
  }

  .entry-option-label {
    max-width: 13ch;
    margin: 12px 0 6px;
    font-size: clamp(27px, 8vw, 38px);
  }

  .entry-option-copy {
    min-height: auto;
    font-size: 13px;
    line-height: 1.25;
  }

  .entry-option-action {
    margin-top: 10px;
    padding-top: 8px;
    font-size: 10px;
  }

  .entry-foot {
    margin-top: 30px;
    line-height: 1.7;
  }

  /* -- 18h. hero and setup steps ----------------------------------------- */

  .hero {
    grid-template-columns: minmax(0, 1fr);
    gap: 34px;
  }

  .notif {
    transform: none;
    max-width: 380px;
  }

  .step-n {
    font-size: 64px;
  }

  .step h2,
  .step p,
  .step table,
  .step .table-wrap,
  .step pre,
  .step figure,
  .step .reassure,
  .step ul {
    margin-left: 18px;
    margin-right: 18px;
  }

  .step table,
  .step .table-wrap,
  .step pre {
    max-width: calc(100% - 36px);
  }

  .step .table-wrap > table {
    margin-left: 0;
    margin-right: 0;
    max-width: none;
  }

  /* -- 18i. quick links become a footer ---------------------------------- */

  .site-foot {
    border-top: var(--bd) solid var(--ink);
    padding: 20px 18px 26px 18px;
    background: var(--paper);
  }

  .floating-links {
    position: static;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
  }

  .floating-link {
    width: 44px;
    height: 44px;
    font-size: 12px;
  }

  .ecosystem-note {
    position: static;
    order: 2;
    flex: 1 0 100%;
    width: auto;
    max-width: none;
    margin: 2px 0 0 0;
    font-size: 11px;
    line-height: 1.5;
  }

  /* -- 18j. scroll lock while the drawer is open ------------------------- */

  html.is-scroll-locked,
  html.is-scroll-locked body {
    overflow: hidden;
  }

  html.is-scroll-locked body {
    position: fixed;
    left: 0;
    right: 0;
    width: 100%;
  }
}

/* Very narrow phones. */
@media (max-width: 400px) {
  main {
    padding-left: 14px;
    padding-right: 14px;
  }

  body.has-toc main#content,
  body:has(.page-toc) main#content {
    padding-right: 14px;
  }

  .topbar {
    padding: 8px 12px;
    gap: 10px;
  }

  .topbar-btn {
    padding: 0 11px;
  }

  .site-foot {
    padding-left: 14px;
    padding-right: 14px;
  }
}

@media (prefers-reduced-motion: reduce) {
  * {
    transition: none !important;
    scroll-behavior: auto !important;
  }
}

/* ==========================================================================
   19. debug helpers
   Add ?debug=1 to any URL. assets/qoffee.js sets `data-debug` on <html> and
   outlines anything sticking out past the viewport in coral, which is the
   fastest way to find a responsive regression on a real device.
   ======================================================================== */

[data-debug] .is-overflowing {
  outline: 3px solid var(--coral) !important;
  outline-offset: -3px;
}

[data-debug]::after {
  content: attr(data-debug-note);
  position: fixed;
  left: 8px;
  bottom: 8px;
  z-index: 999;
  padding: 5px 9px;
  background: var(--coral);
  border: 2px solid var(--ink);
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 700;
  pointer-events: none;
}
