/* ═══════════════════════════════════════════════════════════════
   Decent Infrastructure in an Authoritarian World — Holo Ventures
   Self-contained: tokens, base rules and page styles, tree-shaken
   to what this document actually uses. Geist / Geist Mono load
   from Google Fonts via the <link> above.
   ═══════════════════════════════════════════════════════════════ */

/* ── Colour tokens ───────────────────────────────────────── */
:root {
   --paper-warm-grey-1: #FDFCFC;
   --paper-warm-grey-2: #F4F2F0;
   --paper-warm-grey-3: #F5F3F1;
   --paper-sand-grey: #E9E8E2;
   --paper-grey-separators: #DCDBD8;
   --n-000: #FFFFFF;
   --n-ink: #000000;
   --holochain-tint: #dafff6;
   --holochain-ink: #016a50;
   --holo-tint: #E7F8FF;
   --holo-ink: #027FF8;
   --unyt-tint: #EFEAFF;
   --unyt-ink: #340082;
   --moss-tint: #ECF8E3;
   --moss-ink: #7BA563;
   --holo-band: #C3DCFF;
   --unyt-band: #BFB7E2;
   --moss-band: #98B997;
   --btn-glow-default: #022D91;
   --btn-glow-secondary: #DAEEF9;
   --btn-bloom-size: 400px;
   --paper-cover-bg: var(--n-ink);
   --paper-cover-ink: var(--n-000);
   --surface: var(--paper-warm-grey-1);
   --rule: var(--paper-grey-separators);
}

/* ── Type tokens ─────────────────────────────────────────── */
:root {
   --font-sans: 'Geist', 'Helvetica Neue', Arial, sans-serif;
   --font-mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
   --paper-h1-size: 48px;
   --paper-h1-lh: 0.9;
   --paper-h1-ls: -0.04em;
   --paper-h1-wt: 600;
   --paper-h2-size: 52px;
   --paper-h2-size-m: 36px;
   --paper-h2-lh: 1;
   --paper-h2-ls: -0.04em;
   --paper-h2-wt: 600;
   --paper-h3-size: 32px;
   --paper-h3-size-m: 28px;
   --paper-h3-lh: 1;
   --paper-h3-ls: -0.04em;
   --paper-h3-wt: 600;
   --paper-intro-size: 20px;
   --paper-intro-size-m: 16px;
   --paper-intro-lh: 1.1;
   --paper-intro-ls: -0.02em;
   --paper-intro-wt: 550;
   --paper-intro-opacity: 0.8;
   --paper-body-size: 14px;
   --paper-body-lh: 1.2;
   --paper-body-ls: 0;
   --paper-body-wt: 500;
   --paper-mono-size: 12px;
   --paper-mono-lh: 1.2;
   --paper-mono-ls: 0.01em;
   --paper-mono-wt: 500;
   --paper-subtitle-size: 16px;
   --paper-subtitle-lh: 1.2;
   --paper-subtitle-ls: 0.04em;
   --paper-subtitle-wt: 500;
   --paper-cardtitle-size: 20px;
   --paper-cardtitle-lh: 1.1;
   --paper-cardtitle-ls: -0.02em;
   --paper-cardtitle-wt: 600;
   --paper-prose-size: 17px;
   --paper-prose-lh: 1.65;
   --paper-prose-wt: 400;
}

/* ── Spacing scale ───────────────────────────────────────── */
:root {
   --sp-2: 8px;
   --sp-3: 12px;
   --sp-4: 16px;
   --sp-5: 20px;
   --sp-6: 24px;
   --sp-8: 32px;
   --sp-10: 40px;
   --sp-12: 48px;
   --sp-16: 64px;
   --sp-20: 80px;
   --sp-24: 96px;
}

/* ── Corner radii ────────────────────────────────────────── */
:root {
   --r-btn: 6px;
   --r-sm: 4px;
   --r: 8px;
   --r-lg: 16px;
}

@media (max-width: 699px),
(min-width: 840px) and (max-width: 979px) {
   :root {
      --r-lg: 12px;
   }
}

/* ── Layout grid ─────────────────────────────────────────── */
:root {
   --paper-grid-columns: 2;
   --paper-grid-margin: 12px;
   --paper-grid-gutter: 12px;
   --paper-grid-max-width: 1356px;
}

@media (min-width: 700px) and (max-width: 839px),
(min-width: 980px) {
   :root {
      --paper-grid-columns: 4;
      --paper-grid-margin: 20px;
      --paper-grid-gutter: 12px;
   }
}

@media (min-width: 1305px) {
   :root {
      --paper-grid-columns: 12;
      --paper-grid-margin: 40px;
      --paper-grid-gutter: 12px;
   }
}

@media (min-width: 1721px) {
   :root {
      --paper-grid-columns: 12;
      --paper-grid-gutter: 12px;
   }
}

.paper-grid {
   display: grid;
   grid-template-columns: repeat(var(--paper-grid-columns), 1fr);
   gap: var(--paper-grid-gutter);
   padding-inline: var(--paper-grid-margin);
   width: 100%;
   box-sizing: border-box;
}

/* Wider viewports get a deeper page inset than the base grid margin. It has
   to be padding-inline, not padding-left: the 1721px rule below centres the
   grid instead, but between 980px and there the two sides must match. */
@media (min-width: 980px) {
   .paper-grid {
      padding-inline: var(--sp-10);
   }
}

@media (min-width: 1305px) {
   .paper-grid {
      padding-inline: var(--sp-16);
   }
}

@media (min-width: 1721px) {
   .paper-grid {
      max-width: var(--paper-grid-max-width);
      margin-inline: auto;
      padding-inline: 0;
   }
}

.paper-col-full {
   grid-column: 1 / -1;
}

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

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

body {
   margin: 0;
   background: var(--surface);
   color: var(--n-ink);
   font-family: var(--font-sans);
   font-weight: var(--paper-body-wt);
   font-size: var(--paper-body-size);
   line-height: var(--paper-body-lh);
   -webkit-font-smoothing: antialiased;
   -moz-osx-font-smoothing: grayscale;
}

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

ul,
ol {
   list-style: none;
   margin: 0;
   padding: 0;
}

/* Prose rhythm comes from .paper-prose > * + *; the UA's 1em paragraph
   margins only leak out at the end of a block and skew the gaps around it. */
p {
   margin: 0;
}

a {
   color: inherit;
   text-decoration: none;
}

a:hover {
   opacity: 0.7;
}

@media (prefers-reduced-motion: reduce) {
   html {
      scroll-behavior: auto;
   }

   *,
   *::before,
   *::after {
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
      scroll-behavior: auto !important;
   }
}

/* ── Type scale ──────────────────────────────────────────── */
.paper-h1,
h1 {
   font-family: var(--font-sans);
   font-weight: var(--paper-h1-wt);
   font-size: var(--paper-h1-size);
   line-height: var(--paper-h1-lh);
   letter-spacing: var(--paper-h1-ls);
   margin: 0;
}

.paper-h2,
h2 {
   font-family: var(--font-sans);
   font-weight: var(--paper-h2-wt);
   font-size: var(--paper-h2-size-m);
   line-height: var(--paper-h2-lh);
   letter-spacing: var(--paper-h2-ls);
   margin: 0;
}

.paper-h3,
h3 {
   font-family: var(--font-sans);
   font-weight: var(--paper-h3-wt);
   font-size: var(--paper-h3-size-m);
   line-height: var(--paper-h3-lh);
   letter-spacing: var(--paper-h3-ls);
   margin: 0;
}

.paper-intro {
   font-family: var(--font-sans);
   font-weight: var(--paper-intro-wt);
   font-size: var(--paper-intro-size-m);
   line-height: var(--paper-intro-lh);
   letter-spacing: var(--paper-intro-ls);
   opacity: var(--paper-intro-opacity);
   margin: 0;
}

.paper-body {
   font-family: var(--font-sans);
   font-weight: var(--paper-body-wt);
   font-size: var(--paper-body-size);
   line-height: var(--paper-body-lh);
   letter-spacing: var(--paper-body-ls);
   margin: 0;
}

.paper-mono {
   font-family: var(--font-mono);
   font-weight: var(--paper-mono-wt);
   font-size: var(--paper-mono-size);
   line-height: var(--paper-mono-lh);
   letter-spacing: var(--paper-mono-ls);
   text-transform: uppercase;
   margin: 0;
}

.paper-subtitle {
   font-family: var(--font-mono);
   font-weight: var(--paper-subtitle-wt);
   font-size: var(--paper-subtitle-size);
   line-height: var(--paper-subtitle-lh);
   letter-spacing: var(--paper-subtitle-ls);
   text-transform: uppercase;
   margin: 0;
}

h4,
.paper-cardtitle {
   font-family: var(--font-sans);
   font-weight: var(--paper-cardtitle-wt);
   font-size: var(--paper-cardtitle-size);
   line-height: var(--paper-cardtitle-lh);
   letter-spacing: var(--paper-cardtitle-ls);
   margin: 0;
}

/* The h1 is absent here on purpose: the cover title is the only h1 and
   sizes itself to its column (see .paper-cover__title), with one weight
   and tracking at every width. */
@media (min-width: 1305px) {

   .paper-h2,
   h2 {
      font-size: var(--paper-h2-size);
   }

   .paper-h3,
   h3 {
      font-size: var(--paper-h3-size);
   }

   .paper-intro {
      font-size: var(--paper-intro-size);
      letter-spacing: var(--paper-intro-ls);
   }

   h4,
   .paper-cardtitle {
      font-size: var(--paper-cardtitle-size);
   }
}

/* ── Surfaces ────────────────────────────────────────────── */

/* ── Controls ────────────────────────────────────────────── */
.paper-chip {
   padding: 3px 8px;
   border-radius: var(--r-sm);
   background: var(--paper-warm-grey-2);
   border: 1px solid var(--rule);
   opacity: 0.85;
}

/* ── Blocks ──────────────────────────────────────────────── */
/* Product palettes. These only supply --tile-tint / --tile-ink, so they are a
   BEM mix: pair one with any block that reads those two properties
   (.paper-layer--tinted, .paper-apps). */
.paper-palette--holochain {
   --tile-tint: var(--holochain-tint);
   --tile-ink: var(--holochain-ink);
}

.paper-palette--holo {
   --tile-tint: var(--holo-tint);
   --tile-ink: var(--holo-ink);
}

.paper-palette--unyt {
   --tile-tint: var(--unyt-tint);
   --tile-ink: var(--unyt-ink);
}

.paper-palette--moss {
   --tile-tint: var(--moss-tint);
   --tile-ink: var(--moss-ink);
}

.paper-prose {
   font-family: var(--font-sans);
   font-weight: var(--paper-prose-wt);
   font-size: var(--paper-prose-size);
   line-height: var(--paper-prose-lh);
}

.paper-prose>*+* {
   margin-top: var(--sp-5);
}

.paper-prose a {
   text-decoration: underline;
   text-underline-offset: 2px;
}

.paper-prose a:hover {
   opacity: 0.7;
}

/* ── Page styles ──────────────────────────────────────────────
   Everything below builds on the tokens and base rules above and
   wins ties against them by source order. One namespace, `paper-`.

   Parameters (set inline where an instance differs):
     --paper-flow      vertical rhythm inside .paper-column (inherits —
                       nested blocks must not read it)
     --paper-measure   max line length on statements and ledes
     --paper-cell-pad  cell padding for .paper-table
   ──────────────────────────────────────────────────────────── */

/* ── Page shell ─────────────────────────────────────────────── */
body {
   margin: 0;
   background: var(--paper-warm-grey-1);
   color: var(--n-ink);
   font-family: var(--font-sans);
   -webkit-font-smoothing: antialiased;
}

a {
   color: inherit;
}

a:hover {
   color: var(--n-ink);
}

.paper-prose a {
   color: inherit;
}

.paper-prose a:hover {
   color: inherit;
   opacity: 0.6;
}

.paper {
   display: flex;
   flex-direction: column;
}

/* ── Document scaffold ──────────────────────────────────────── */
/* Every numbered section: a left rail of markers, a right column of
   content, on the design system's 12-column grid. */
.paper-section {
   padding-block: 0;
}

.paper-section__grid {
   row-gap: var(--sp-10);
}

.paper-section__grid--tight {
   row-gap: var(--sp-8);
}

.paper-marker {
   opacity: 0.5;
}

/* section marker / group heading */
.paper-label {
   opacity: 0.45;
}

/* mono label: rail, credits, facts, colophon */

.paper-column {
   grid-column: 1 / -1;
   max-width: var(--paper-col-max);
   display: flex;
   flex-direction: column;
   gap: var(--paper-flow, var(--sp-10));
}

.paper-column--plain {
   display: flex;
   flex-direction: column;
   gap: var(--sp-8);
}

/* ── Cover & closing ────────────────────────────────────────── */
.paper-cover {
   --paper-cover-margin: var(--sp-8);
   position: relative;
   overflow: hidden;
   background: var(--paper-cover-bg);
   color: var(--paper-cover-ink);
   min-height: 100vh;
   min-height: 100svh;
   display: flex;
   flex-direction: column;
   justify-content: space-between;
   gap: var(--sp-16);
   padding-block: var(--sp-16) var(--sp-12);
}

/* The cover ignores the page grid's margins and max-width: its rows run
   edge to edge with one inset, --paper-cover-margin, on every side. Narrow
   viewports get --sp-8; from 840px the inset doubles and the block padding
   follows it so all four margins match. */
.paper-cover .paper-grid {
   max-width: none;
   margin-inline: 0;
   padding-inline: var(--paper-cover-margin);
}

@media (min-width: 840px) {
   .paper-cover {
      --paper-cover-margin: var(--sp-16);
      padding-block: var(--paper-cover-margin);
   }
}

.paper-closing {
   position: relative;
   overflow: hidden;
   background: var(--paper-cover-bg);
   color: var(--paper-cover-ink);
   min-height: 720px;
   display: flex;
   flex-direction: column;
   justify-content: center;
   gap: var(--sp-16);
   padding-block: var(--sp-24);
}

/* Murmuration video behind the cover. object-fit: cover keeps it
   filling the cover at any viewport size or aspect ratio; it sits below
   the cover rows, which are position: relative. */
.paper-cover__video {
   position: absolute;
   inset: 0;
   width: 100%;
   height: 100%;
   max-width: none;
   object-fit: cover;
   object-position: center;
   pointer-events: none;
   display: block;
}

@media (prefers-reduced-motion: reduce) {
   .paper-cover__video {
      display: none;
   }
}

/* Rotating halo behind the closing page. */
@keyframes paper-halo-spin {
   to {
      transform: rotate(360deg);
   }
}

.paper-halo {
   position: absolute;
   top: 46%;
   left: 50%;
   width: min(1120px, 132%);
   max-width: none;
   height: auto;
   aspect-ratio: 2000/1949;
   transform: translate(-50%, -50%);
   pointer-events: none;
   display: block;
   opacity: 0.3;
   animation: paper-halo-spin 160s linear infinite;
}

.paper-halo--closing {
   top: 50%;
   width: min(1000px, 120%);
   opacity: 0.26;
   animation: paper-halo-spin 200s linear infinite reverse;
}

.paper-cover__row {
   position: relative;
}

.paper-cover__title {
   max-width: 16ch;
}

/* From 530px the title is sized to fill its column: font-size is the
   column's content width divided by --paper-cover-title-em, and never
   drops below the 48px mobile heading size. 100cqi already excludes the
   cover margins and the scrollbar, which 100vw would not. */
.paper-cover__block {
   container-type: inline-size;
}

@media (min-width: 530px) {
   .paper-cover__title {
      --paper-cover-title-em: 10.9;
      max-width: none;
      font-size: max(var(--paper-h1-size), calc(100cqi / var(--paper-cover-title-em)));
   }
}

/* "Decent Infrastructure" carries a gradient rather than the cover's white.
   Everything lives inside @supports: without background-clip the paint would
   sit behind the glyphs as a solid block, so the safe fallback is to inherit
   the cover ink and skip the gradient entirely. The span stays inline so the
   ramp slices across the line break instead of restarting on each line. */

.paper-cover__gradient {
   /* It should live on its own line */
   display: block;
}

@supports (background-clip: text) or (-webkit-background-clip: text) {
   .paper-cover__gradient {
      background-image: linear-gradient(90deg, rgb(92, 92, 255), rgb(13, 221, 211));
      -webkit-background-clip: text;
      background-clip: text;
      color: transparent;
   }
}

/* Forced colours drop background images, which would leave nothing to see. */
@media (forced-colors: active) {
   .paper-cover__gradient {
      background-image: none;
      color: CanvasText;
   }
}

.paper-cover__lede {
   opacity: 0.75;
   max-width: 34ch;
}

.paper-cover__block {
   display: flex;
   flex-direction: column;
   gap: var(--sp-6);
}

/* Publication credits — cover and footer. */
.paper-credits {
   display: grid;
   grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
   gap: var(--sp-8);
}

.paper-credits--ruled {
   border-top: 1px solid rgba(255, 255, 255, 0.22);
   padding-top: var(--sp-6);
}

.paper-credit {
   display: flex;
   flex-direction: column;
   gap: var(--sp-3);
}

.paper-credit__logo {
   width: 12em;
   max-width: 100%;
   height: auto;
}

.paper-credit__value {
   list-style: none;
   margin: 0;
   padding: 0;
   font-size: 16px;
   font-weight: 550;
   line-height: 1.35;
   margin: 0;
}

.paper-credit__value--list {
   line-height: 1.5;
}

.paper-footer {
   background: var(--n-ink);
   color: var(--n-000);
   padding-block: var(--sp-12);
}

/* With the sidebar docked, the footer's first column starts where the
   white main panel does — at the sidebar's edge, not the panel's own inset
   — so the credits read as a continuation of that panel. Mobile keeps the
   ordinary grid margin because the sidebar is off-canvas there. */
@media (min-width: 840px) {
   .paper-footer .paper-grid {
      max-width: none;
      margin-inline: 0;
      padding-left: var(--paper-sidebar-w);
   }
}

.paper-footer__value {
   font-size: 15px;
   font-weight: 550;
   line-height: 1.4;
   margin: 0;
}

.paper-footer__value--list {
   font-weight: 500;
   line-height: 1.5;
   opacity: 0.85;
}

.paper-footer__value--stacked {
   line-height: 1.5;
}

.paper-footer__colophon {
   border-top: 1px solid rgba(255, 255, 255, 0.18);
   padding-top: var(--sp-5);
   display: flex;
   flex-wrap: wrap;
   gap: var(--sp-4);
   justify-content: space-between;
}

/* ── Running prose ──────────────────────────────────────────── */
/* .paper-prose centres itself at 720px; inside the paper column the
   column already sets the measure, so release the centring. */
.paper-lede {
   max-width: var(--paper-measure, 42ch);
}

.paper-lede--muted {
   opacity: 0.75;
}

/* A single sentence set apart above a rule — the paper's refrain. */
.paper-statement {
   max-width: var(--paper-measure, 30ch);
}

.paper-statement--plain {
   max-width: var(--paper-measure, 20ch);
}

.paper-emphasis {
   font-style: italic;
}

.paper-strong {
   font-weight: 600;
}

/* ── End notes ──────────────────────────────────────────────── */
.paper-ref {
   font-family: var(--font-mono);
   font-size: 10px;
}

.paper-ref--sm {
   font-size: 9px;
}

.paper-cite-ref {
   font-size: 9px;
}

.paper-ref a,
.paper-cite-ref a {
   text-decoration: none;
}

.paper-notes {
   display: flex;
   flex-direction: column;
   list-style: none;
   margin: 0;
   padding: 0;
}

.paper-note {
   display: grid;
   grid-template-columns: 32px 1fr;
   gap: var(--sp-4);
   padding-block: var(--sp-4);
   border-top: 1px solid var(--rule);
}

.paper-note--last {
   border-bottom: 1px solid var(--rule);
}

.paper-note__num {
   opacity: 0.5;
   text-decoration: none;
}

.paper-note__num:hover {
   opacity: 1;
}

.paper-note__text {
   margin: 0;
   font-size: 14px;
   line-height: 1.6;
}

.paper-note__text a {
   text-decoration: underline;
   text-underline-offset: 2px;
}

.paper-note__text a:hover {
   color: inherit;
   opacity: 0.6;
}

/* ── Contents ───────────────────────────────────────────────── */
.paper-toc {
   list-style: none;
   margin: 0;
   padding: 0;
}

.paper-toc__item {
   display: grid;
   grid-template-columns: 56px 1fr;
   gap: var(--sp-5);
   padding-block: var(--sp-5);
   border-top: 1px solid var(--rule);
   text-decoration: none;
}

.paper-toc__item--last {
   border-block: 1px solid var(--rule);
}

.paper-toc__num {
   opacity: 0.5;
   padding-top: 4px;
}

/* ── Tables ─────────────────────────────────────────────────── */
/* Fixed layout, with widths declared on <col>s rather than left to the
   content: a label column is a fixed share, and every column without a
   width splits the remainder equally — so the two sides of a comparison
   are always the same width, whatever one side has to say. Two sizes:
   --label (26%: a 20-character key on one line at the 720px measure)
   and --short (20%: a one- or two-word cell, e.g. a sector tag). */
.paper-table {
   width: 100%;
   table-layout: fixed;
   border-collapse: collapse;
   font-size: 15px;
   line-height: 1.45;
}

.paper-table__col--label {
   width: 26%;
}

.paper-table__col--short {
   width: 20%;
}

.paper-table__caption {
   text-align: left;
   opacity: 0.55;
   margin-bottom: var(--sp-5);
}

.paper-table th,
.paper-table td {
   text-align: left;
   font-weight: inherit;
   vertical-align: top;
   padding-right: var(--sp-5);
}

.paper-table th:last-child,
.paper-table td:last-child {
   padding-right: 0;
}

.paper-table tbody th,
.paper-table tbody td {
   padding-top: var(--sp-4);
}

.paper-table__head {
   opacity: 0.45;
   padding-bottom: var(--sp-3);
   border-bottom: 1px solid var(--n-ink);
}

.paper-table__key {
   font-weight: 550;
   padding-bottom: var(--paper-cell-pad, var(--sp-5));
   border-bottom: 1px solid var(--rule);
}

.paper-table__key--strong {
   border-bottom-color: var(--n-ink);
}

.paper-table__cell {
   padding-bottom: var(--paper-cell-pad, var(--sp-5));
   border-bottom: 1px solid var(--rule);
}

.paper-table__cell--muted {
   opacity: 0.7;
}

.paper-table__cell--strong {
   border-bottom-color: var(--n-ink);
}

/* ── Labelled facts & comparisons ───────────────────────────── */
.paper-group__label {
   opacity: 0.55;
}

/* ── Statistics ─────────────────────────────────────────────── */
.paper-stats {
   display: grid;
   grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
   gap: var(--sp-8);
}

.paper-stat {
   display: flex;
   flex-direction: column;
   gap: var(--sp-3);
   padding-top: var(--sp-5);
   border-top: 1px solid var(--n-ink);
}

/* The figure takes the part's ink, like the chapter title; outside a part
   it falls back to black. */
.paper-stat__figure {
   letter-spacing: -0.04em;
   color: var(--paper-part-ink, var(--n-ink));
}

.paper-stat__label {
   opacity: 0.75;
}

/* ── Stack layers, product & app tiles ──────────────────────── */
.paper-layer {
   background: var(--paper-sand-grey);
   border-radius: var(--r-lg);
   padding: var(--sp-6) var(--sp-8);
   display: flex;
   flex-direction: column;
   gap: var(--sp-2);
}

.paper-layer--tinted {
   background: var(--tile-tint);
}

.paper-layer--roomy {
   gap: var(--sp-3);
}

.paper-layer--panel {
   gap: var(--sp-4);
}

.paper-layer__eyebrow {
   opacity: 0.6;
}

.paper-layer__eyebrow--tinted {
   color: var(--tile-ink);
   filter: brightness(0.7);
}

.paper-apps {
   display: grid;
   grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
   gap: var(--sp-3);
}

.paper-app {
   background: var(--tile-tint);
   border-radius: var(--r);
   padding: var(--sp-5);
   display: flex;
   flex-direction: column;
   gap: var(--sp-2);
}

.paper-app__name {
   color: var(--tile-ink);
   filter: brightness(0.7);
}

.paper-app__desc {
   opacity: 0.8;
}

.paper-card {
   background: var(--n-000);
   border: 1px solid var(--rule);
   border-radius: var(--r);
   padding: var(--sp-6);
   display: flex;
   flex-direction: column;
   gap: var(--sp-4);
}

.paper-cards {
   display: grid;
   grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
   gap: var(--sp-5);
}

/* ── Pull quotes ────────────────────────────────────────────── */
.paper-quote {
   margin: 0;
   display: flex;
   flex-direction: column;
   gap: var(--sp-5);
   padding: var(--sp-8);
   background: var(--paper-sand-grey);
   border-radius: var(--r-lg);
}

/* Third-party quotes: pull-quote tracking and leading, body-copy weight. */
.paper-quote__text {
   margin: 0;
   font-weight: var(--paper-prose-wt);
}

.paper-quote__cite {
   opacity: 0.55;
   font-size: var(--paper-prose-size);
}

/* ── Questions & objections ─────────────────────────────────── */
.paper-qa {
   display: flex;
   flex-direction: column;
   gap: var(--sp-4);
}

.paper-qa__answer {
   margin: 0;
   font-size: 16px;
   line-height: 1.65;
   font-weight: var(--paper-prose-wt);
}

.paper-qa__answer--narrow {
   max-width: 70ch;
}

/* ── Process flow ───────────────────────────────────────────── */
.paper-flow {
   display: flex;
   flex-wrap: wrap;
   align-items: center;
   gap: var(--sp-2) var(--sp-3);
   font-family: var(--font-mono);
   font-size: 13px;
   line-height: 1.3;
}

.paper-flow__arrow {
   opacity: 0.4;
}

/* The bibliography is grouped by the chapter that cites each note, the way
   the single-page version was. */
.paper-note-group + .paper-note-group {
   margin-top: var(--sp-10);
}

/* Section heading inside an appendix: a step below the page title on the
   design system's own scale (h1 paper-h2 -> h2 paper-h3 -> h3 cardtitle),
   with a rule above it so each group reads as a break, not a caption. */
.paper-subhead {
   padding-top: var(--sp-6);
   border-top: 1px solid var(--n-ink);
   margin-bottom: var(--sp-6);
}

.paper-subhead a:hover {
   opacity: 0.6;
}

.paper-reslist {
   list-style: disc;
   margin: 0;
   padding-left: var(--sp-5);
}

.paper-reslist li {
   margin-top: var(--sp-2);
}

.paper-reslist li::marker {
   color: color-mix(in srgb, currentColor 45%, transparent);
}

.paper-note-body {
   margin: 0;
   font-size: 15px;
   line-height: 1.6;
}

.paper-legal {
   margin: 0;
   font-size: 15px;
   line-height: 1.7;
   max-width: 74ch;
}

.paper-legal--tight {
   max-width: none;
   line-height: 1.55;
}

.paper-stack-list li {
   font-weight: var(--paper-intro-wt);
   list-style-type: none;
}

.paper-stack-list li::before {
   content: "\25B6";
   padding-right: 1em;
}

.paper-stack-list a {
   text-decoration: none;
}

.paper-chip {
   margin-top: var(--sp-4);
   align-self: flex-start;
}

.paper-link {
   text-decoration: none;
   border-bottom: 1px solid currentColor;
}

.paper-heading-measure {
   max-width: 26ch;
}

/* ── Section head ───────────────────────────────────────────── */
/* Each section is white; the heading and lede sit on a warm-grey
   band that runs the full width of the content area. */

/* The band's colour is the part's ink washed to --paper-part-wash-header.
   Pages outside any part (the appendices) carry no data-part, and the ink
   fallback there is black — which washes to a neutral grey that sits oddly
   against the warm greys everywhere else. So the band defaults to the warm
   off-white and only a part sets the wash; the two are kept apart in
   --paper-head-bg rather than folded into the ink fallback. */
.paper-section__head {
   --paper-head-bg: var(--paper-warm-grey-2);
   background: var(--paper-head-bg);
   color: var(--paper-part-ink, var(--n-ink));
   padding-block: var(--sp-16);
   margin-bottom: var(--sp-12);
}

[data-part] .paper-section__head {
   --paper-head-bg: color-mix(in srgb, var(--paper-part-ink) var(--paper-part-wash-header), transparent);
}

/* The chapter marker runs inline with the title at the title's own size.
   The rail it used to hang in is gone, so the left margin is now just the
   grid inset, which steps up with the viewport. */
.paper-section__num {
   white-space: nowrap;
   display: block;
   margin-bottom: var(--sp-3);
}

/* Hold the content column where the rail used to put it. */

/* ── Contents sidebar ───────────────────────────────────────── */
/* Docks as a black column at >= 840px (3x its own width, so the prose
   keeps at least twice the sidebar's measure). Below that it becomes an
   off-canvas drawer behind a labelled button. The dock is plain
   position:sticky — it detaches on its own once the cover has scrolled
   past, so no JS is involved in the pinning. */
:root {
   /* Per-part ink. All black for now, so the wash is invisible on the black
     sidebar and — at the alpha below — indistinguishable from the warm smoke
     grey the chapter head used to carry. Set real hues here to colour-code
     the parts. --paper-part-wash-* set the two background strengths. */
   --paper-part-1-ink: #791ab8;
   --paper-part-2-ink: #4820e3;
   --paper-part-3-ink: #00635e;
   --paper-part-wash-sidebar: 30%;
   --paper-part-wash-header: 10%;
   /* how far the masthead's part text is tinted from the ink toward white */
   --paper-part-tint: 60%;

   /* the single content measure: nothing in the flow is wider */
   --paper-col-max: 720px;

   --paper-sidebar-w: 280px;
   /* ToC entry = [number][gap][title]. The title's vertical is what the
     masthead and the /contents/ labels align to. */
   /* Every entry number is two monospace characters, so the track only has
      to hold that much — at 32px it carried 17px of dead space that read as
      an unexplained gap, since it is neither margin nor padding. */
   --paper-toc-num-w: 16px;

   /* 2em at the sidebar's 14px base. Held in px because --paper-toc-indent
      also positions the masthead, where the font-size differs and an em
      would not resolve to the same distance. */
   --paper-toc-gap: 10px;

   --paper-toc-gutter: calc(var(--paper-toc-num-w) + var(--paper-toc-gap));
   --paper-toc-indent: calc(var(--sp-6) + var(--paper-toc-gutter));
}

.paper-sidebar {
   box-sizing: border-box;
   background: var(--n-ink);
   color: var(--n-000);
   padding-block: 0 var(--sp-10);
}

/* Each part is a tinted block that bleeds to the sidebar's edges, so the
   horizontal padding lives here rather than on the sidebar. */
/* No data-part, so it would otherwise inherit the current page's ink. */
.paper-sidebar__part--plain {
   --paper-part-ink: var(--n-ink);
}

.paper-sidebar__part {
   padding: var(--sp-5) var(--sp-6);
   background: color-mix(in srgb, var(--paper-part-ink, var(--n-ink)) var(--paper-part-wash-sidebar), transparent);
}

[data-part="1"] {
   --paper-part-ink: var(--paper-part-1-ink);
}

[data-part="2"] {
   --paper-part-ink: var(--paper-part-2-ink);
}

[data-part="3"] {
   --paper-part-ink: var(--paper-part-3-ink);
}

.paper-sidebar__title {
   margin: 0 0 var(--sp-4) var(--paper-toc-gutter);
   color: var(--n-000);
}

.paper-sidebar__partnum {
   display: block;
   font-family: var(--font-mono);
   font-weight: var(--paper-mono-wt);
   font-size: var(--paper-mono-size);
   line-height: var(--paper-mono-lh);
   letter-spacing: var(--paper-mono-ls);
   text-transform: uppercase;
}

.paper-sidebar__partname {
   display: block;
   margin-top: var(--sp-2);
   font-family: var(--font-sans);
   font-weight: 700;
   font-size: 18px;
   line-height: 1.2;
   letter-spacing: -0.01em;
}

.paper-sidebar a {
   color: inherit;
}

.paper-sidebar a:hover {
   color: inherit;
}

/* the page rule paints links ink-black */
.paper-sidebar .paper-toc__item {
   grid-template-columns: var(--paper-toc-num-w) 1fr;
   gap: var(--paper-toc-gap);
   padding-block: var(--sp-3);
   border-top-color: rgba(255, 255, 255, 0.18);
}

.paper-sidebar .paper-toc__item--last {
   border-block-color: rgba(255, 255, 255, 0.18);
}

.paper-sidebar .paper-toc__num {
   opacity: 0.4;
   padding-top: 2px;
}

.paper-sidebar .paper-cardtitle {
   font-size: 14px;
   line-height: 1.25;
   letter-spacing: -0.01em;
   opacity: 0.7;
   transition: opacity 0.15s ease;
}

.paper-sidebar .paper-toc__item:hover .paper-cardtitle {
   opacity: 1;
}

/* Current section */
.paper-sidebar .paper-toc__item[aria-current] {
   position: relative;
}

.paper-sidebar .paper-toc__item[aria-current] .paper-cardtitle,
.paper-sidebar .paper-toc__item[aria-current] .paper-toc__num {
   opacity: 1;
}

.paper-sidebar .paper-toc__item[aria-current]::before {
   content: '';
   position: absolute;
   left: calc(var(--sp-6) * -1);
   top: -1px;
   bottom: 0;
   width: 2px;
   background: currentColor;
}

.paper-sidebar a:focus-visible,
.paper-nav-toggle:focus-visible {
   outline: 2px solid currentColor;
   outline-offset: 3px;
}

/* Trigger: icon + word, 44px target, bottom-right for thumb reach. */
.paper-nav-toggle {
   position: fixed;
   z-index: 65;
   right: var(--sp-5);
   bottom: var(--sp-5);
   display: inline-flex;
   align-items: center;
   gap: var(--sp-3);
   min-height: 44px;
   padding: 0 var(--sp-5);
   background: var(--n-ink);
   color: var(--n-000);
   border: 1px solid var(--n-000);
   border-radius: 999px;
   box-shadow: 0 6px 20px rgba(0, 0, 0, 0.28);
   cursor: pointer;
   font-family: var(--font-mono);
   font-weight: var(--paper-mono-wt);
   font-size: var(--paper-mono-size);
   line-height: 1;
   letter-spacing: var(--paper-mono-ls);
   text-transform: uppercase;
}

.paper-nav-toggle__icon {
   width: 16px;
   height: 16px;
   flex: none;
}

/* ── Docked ─────────────────────────────────────────────────── */
@media (min-width: 840px) {
   .paper-shell {
      display: grid;
      grid-template-columns: var(--paper-sidebar-w) minmax(0, 1fr);
      align-items: start;
   }

   .paper-sidebar {
      position: sticky;
      top: 0;
      height: 100vh;
      height: 100svh;
      overflow-y: auto;
      overscroll-behavior: contain;
   }

   .paper-nav-toggle,
   .paper-scrim {
      display: none;
   }
}

/* ── Collapsed: off-canvas drawer ───────────────────────────── */
@media (max-width: 839px) {
   .paper-sidebar {
      position: fixed;
      inset-block: 0;
      left: 0;
      z-index: 60;
      width: min(320px, 86vw);
      overflow-y: auto;
      overscroll-behavior: contain;
      transform: translateX(-100%);
      visibility: hidden;
      transition: transform 0.28s ease, visibility 0s linear 0.28s;
   }

   .paper-sidebar[data-open="true"] {
      transform: none;
      visibility: visible;
      transition: transform 0.28s ease;
   }

   .paper-scrim {
      position: fixed;
      inset: 0;
      z-index: 55;
      background: rgba(0, 0, 0, 0.5);
      opacity: 0;
      pointer-events: none;
      transition: opacity 0.28s ease;
   }

   .paper-scrim[data-open="true"] {
      opacity: 1;
      pointer-events: auto;
   }
}

@media (prefers-reduced-motion: reduce) {

   .paper-sidebar,
   .paper-scrim,
   .paper-sidebar .paper-cardtitle {
      transition: none;
   }
}

@media (prefers-reduced-motion: no-preference) {
   html,
   .paper-notes-rail {
      scroll-behavior: smooth;
   }
}

/* One rhythm between prose, next and end notes — and the same again below
   the last of them, so nothing sits flush against the footer. */
.paper-shell__main {
   display: flex;
   flex-direction: column;
   gap: var(--sp-20);
   padding-bottom: var(--sp-20);
   background: var(--n-000);
}

/* ── Footnote rail ──────────────────────────────────────────────
   From 1360px the end notes leave the page foot and become a sticky
   column beside the prose. One DOM copy either way: the ids are the
   citation link targets, so rendering twice would duplicate every #nN.

   Column 1 is the measure plus its two insets, so a .paper-grid inside
   it yields exactly 720px and the right inset doubles as the gap. The
   rail redefines --paper-col-max for its own subtree, which is all the
   inner .paper-column needs to cap itself.

   This block MUST stay below the base .paper-shell__main rule: media
   queries add no specificity, so a later base declaration would win. */
@media (min-width: 1360px) {
   .paper-shell__main {
      display: grid;
      grid-template-columns: calc(var(--paper-col-max) + 2 * var(--sp-16)) minmax(200px, 1fr);
      align-items: start;
      gap: 0;
   }

   /* With the head promoted to a grid row, main's row-gap stacked on top of
      the head's own margin-bottom and the pair measured 128px. Zero the gap
      and let each block state its own spacing: the head keeps its 48px, the
      same as below this breakpoint, and the major blocks keep the --sp-20
      rhythm. */
   .paper-shell__main > .paper-closing,
   .paper-shell__main > .paper-section__grid:not(.paper-notes-rail) {
      margin-top: var(--sp-20);
   }

   /* The section dissolves so its head and body become rows of this grid:
      the head band then spans the full width (row 1) and the rail can begin
      alongside the body (row 2) instead of over the band. Every page is
      exactly header + one body row, so the row numbers are stable. */
   .paper-section {
      display: contents;
   }

   /* Everything spans both columns by default: the head band bleeds to the
      page edge, and so do the closing card and the next link. */
   .paper-shell__main > *,
   .paper-section > * {
      grid-column: 1 / -1;
   }

   /* The body is the exception. It has to be placed in column 1 of row 2
      explicitly, or auto-placement finds row 2 already partly held by the
      rail, refuses to straddle it, and drops the whole body to row 3 —
      below a rail that is up to 100svh tall. Sharing the row also gives
      the rail a sticky range (the body's height) and stops it drifting
      over the closing card, which sits in a later row. */
   .paper-section > .paper-section__grid {
      grid-column: 1;
      grid-row: 2;
   }

   /* the wide-viewport centring would push the text away from the rail */
   .paper-shell__main .paper-grid {
      max-width: none;
      margin-inline: 0;
      padding-inline: var(--sp-16);
   }

   .paper-shell__main .paper-notes-rail {
      grid-column: 2;
      grid-row: 2;
      --paper-col-max: 320px;
      position: sticky;
      top: 0;
      max-height: 100svh;
      overflow-y: auto;
      overscroll-behavior: contain;
      --paper-flow: var(--sp-4);
      padding-block: var(--sp-2);
      padding-inline: 0 var(--sp-5);
   }

   /* narrower gutter than the page-foot list: every pixel is line length */
   .paper-notes-rail .paper-note {
      grid-template-columns: 20px 1fr;
      gap: var(--sp-2);
      padding-block: var(--sp-3);
   }

   .paper-notes-rail .paper-note__num,
   .paper-notes-rail .paper-note__text {
      font-size: 12px;
   }

   .paper-notes-rail .paper-note__text {
      line-height: 1.5;
      overflow-wrap: anywhere;
   }

   /* notes rest quiet and come forward while their citation is on screen */
   .paper-notes-rail .paper-note {
      position: relative;
      opacity: 0.5;
      transition: opacity 0.2s ease;
   }

   .paper-notes-rail .paper-note.is-cited {
      opacity: 1;
   }

   .paper-notes-rail .paper-note.is-cited::before {
      content: '';
      position: absolute;
      left: calc(var(--sp-4) * -1);
      top: 0;
      bottom: 0;
      width: 2px;
      background: var(--paper-part-ink, var(--n-ink));
   }
}

.paper-shell__main>section {
   scroll-margin-top: var(--sp-6);
}

/* ── Print ──────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
   * {
      animation-duration: 0.01ms !important;
   }
}

@media print {
   @page {
      margin: 0.5cm;
   }

   .paper-copy {
      display: none;
   }

   figure,
   table {
      break-inside: avoid;
   }

   *,
   *::before,
   *::after {
      print-color-adjust: exact;
      -webkit-print-color-adjust: exact;
      backdrop-filter: none !important;
      -webkit-backdrop-filter: none !important;
      animation-delay: -99s !important;
      animation-duration: .001s !important;
      animation-iteration-count: 1 !important;
      animation-fill-mode: both !important;
      animation-play-state: running !important;
      transition-duration: 0s !important;
   }
}

/* ── Multi-page chrome ──────────────────────────────────────── */
/* Full-bleed masthead on every page but the cover, so a reader landing
   mid-paper sees which document they are in. Shares the cover's palette
   through --paper-cover-bg / --paper-cover-ink. */
.paper-titlebar {
   background: var(--paper-cover-bg);
   color: var(--paper-cover-ink);
   padding-block: var(--sp-5);
   padding-inline: var(--paper-grid-margin);
}

/* Once the sidebar is docked the masthead lines up with the ToC entry
   titles rather than the page margin. */
@media (min-width: 840px) {
   .paper-titlebar {
      padding-left: var(--paper-toc-indent);
   }
}

.paper-titlebar__title {
   font-family: var(--font-sans);
   font-weight: 550;
   font-size: 15px;
   line-height: 1.3;
   letter-spacing: -0.01em;
   margin: 0;
   text-align: left;
}

.paper-titlebar__part {
   color: color-mix(in srgb, var(--paper-cover-ink) var(--paper-part-tint), var(--paper-part-ink, var(--n-ink)));
}

@media (min-width: 1305px) {
   .paper-titlebar__title {
      font-size: 17px;
   }
}

/* The paper's own title at the head of the sidebar, so a reader landing on
   any single page knows the page belongs to a larger document. Suppressed
   on the cover, which states the title at full size already. */


/* Buttons — ported from the Holo Ventures design system (base/controls.css).
   Black pill, label and trailing arrow pushed apart, and a radial bloom that
   tracks the cursor: the ::before sits at z-index -1 inside a stacking context
   the button makes for itself, so it paints above the background and below the
   label with no extra markup. --x/--y default to the centre so it still reads
   as a bloom from the middle before the pointer moves (or with JS off). */
.btn {
   display: inline-flex;
   align-items: center;
   justify-content: space-between;
   gap: var(--sp-4);
   background: var(--n-ink);
   color: var(--n-000);
   border-radius: var(--r-btn);
   font-family: var(--font-sans);
   font-weight: 500;
   line-height: 1;
   text-decoration: none;
   transition: color 0.18s ease;
   position: relative;
   overflow: hidden;
   isolation: isolate;
   --x: 50%;
   --y: 50%;
}

.btn::before {
   content: '';
   position: absolute;
   left: var(--x);
   top: var(--y);
   width: 0;
   height: 0;
   background: radial-gradient(circle closest-side, var(--btn-glow-default), transparent);
   transform: translate(-50%, -50%);
   transition: width 0.2s ease, height 0.2s ease;
   z-index: -1;
   pointer-events: none;
}

.btn:hover::before,
.btn:focus-visible::before {
   width: var(--btn-bloom-size);
   height: var(--btn-bloom-size);
}

.btn:hover {
   color: var(--n-000);
   opacity: 1;
}

.btn__icon {
   flex-shrink: 0;
   width: 16px;
   height: 16px;
}

.btn--l {
   font-size: 18px;
   padding: 15px 16px 15px 20px;
   min-width: 197px;
}

/* S primary — inline actions. Measurements verbatim from the design
   system's controls.css, like .btn--l above. */
.btn--s {
   font-size: 16px;
   padding: 8px 8px 8px 12px;
   min-width: 139px;
}

/* Secondary — a filled sand-grey well with a hairline, not a transparent
   outline. The bloom takes the pale blue rather than the ink blue. */
.btn--secondary {
   background: var(--paper-sand-grey);
   color: var(--n-ink);
   border: 1px solid var(--rule);
}

.btn--secondary:hover {
   color: var(--n-ink);
}

.btn--secondary::before {
   background: radial-gradient(circle closest-side, var(--btn-glow-secondary), transparent);
}

/* "Copy as Markdown", injected into the chapter head by copy-markdown.js.
   The head sits on the part's tinted wash, so the secondary button's grey
   well and blue bloom are multiplied into it rather than laid on top as a
   flat grey — the ink label is unaffected, black times anything is black.
   It is a grid item of the head's own grid, not part of the title column.
   Narrow: its own row under the lede. From 1360px, where the main column
   has room beside a 720px title block, it shares the title's row and is
   justified to the grid's end, so it floats top-right at the page's
   standard inline margin without adding height. The label swaps to
   "Copied" for a moment after a click. */
.paper-copy {
   grid-column: 1 / -1;
   justify-self: start;
   margin-top: var(--sp-2);
   mix-blend-mode: multiply;
}

@media (min-width: 1360px) {
   .paper-section__head .paper-column {
      grid-row: 1;
   }

   .paper-copy {
      grid-row: 1;
      justify-self: end;
      align-self: start;
      margin-top: 0;
   }
}

.paper-copy[data-state="copied"] {
   color: var(--btn-glow-default);
}

.paper-copy[data-state="error"] {
   color: rgb(180, 40, 40);
}

@media (prefers-reduced-motion: reduce) {
   .btn::before {
      transition: none;
   }
}

/* "Next" at the foot of every page but the last, built from the same
   collection that orders the sidebar so the two cannot disagree. */
.paper-next {
   align-self: flex-start;
   max-width: 100%;
}

.paper-next__text {
   flex: 1;
   display: flex;
   flex-direction: column;
   gap: var(--sp-2);
   text-align: left;
   min-width: 0;
}

/* The arrow rides the title's line rather than centring on the two-line
   stack, while keeping the design system's label/arrow gap at the edge. */
.paper-next__line {
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: var(--sp-4);
}

.paper-next__label {
   opacity: 0.55;
}

.paper-next__title {
   font-weight: 600;
   letter-spacing: -0.01em;
}

.paper-next__num {
   opacity: 0.55;
   margin-right: var(--sp-2);
}

/* A1 is an index: each entry links back to the chapter that cites it. */