/* The display is set in what conn is read in — JetBrains Mono, the
   family ghostty loads for the terminal conn holds — and the body is
   set in the typewriter the manual was typed on. The wordmark, the
   banner under it and the section heads are the terminal's face; the
   paragraphs, tables and figures are Courier Prime. Both advance
   0.6em, so the two faces sit on one grid and the fixed pages keep
   their arithmetic. The ligatures are off the way ghostty has them
   off, so the glyph vocabulary renders as itself. JetBrains Mono
   stops at 800, so the display weights are 800; a 900 would be the
   browser drawing a bold of its own. */

/* conn's site is an operating manual: US-letter pages on a dark desk,
   scanned paper, binder holes, a typewriter body and the terminal's
   own face for the display, with conn's orange as the one spot ink.
   The landing page is the manual's cover; the guide is its interior
   pages, in one scroll. Every page is a fixed artifact, 816 by 1056,
   and never reflows: below the desk's width it is scaled, not
   rewrapped. */

/* The page is conn's scheme, inverted onto paper: what the terminal
   grounds on is what the manual is printed in, and what the terminal
   writes in is the paper it is printed on. So the ink is conn's ground,
   the desk the paper lies on is that same ground, and the paper's own
   shadow is conn's ink.

   Between the ink and the paper the manual needs five rungs; conn names
   four of them — the ground, black, bright black and the console's gray
   — and the fifth, --ink-3, is the step between the first two, spelled
   out because no slot has a name for it.

   A spot color is conn's own at the value paper needs: the hue and the
   saturation are the scheme's to within a fifth of a degree, and only
   the value comes down, until the ink reads against the stock. conn
   picks its colors against a dark ground, where the orange carries at
   5.3:1; laid on cream it would read at 2.8, under the floor. So the
   orange and the green are laid until a mark reads on paper, 3.8:1 —
   where the orange the manual was drawn with already sat — and the blue
   is laid for the stamp, which takes it at part strength. */

:root {
  --desk: #15130F;        /* conn's ground */
  --ink: #15130F;         /* conn's ground, as ink */
  --ink-2: #2A2620;       /* conn's black */
  --ink-3: #433E35;       /* the step between them; conn has no name for it */
  --muted: #5C564A;       /* conn's bright black */
  --faint: #8B8272;       /* the console's gray */
  --orange: #C34E27;      /* conn's #E85D2F at the paper's value */
  --orange-rgb: 195,78,39;
  --green: #5A7B55;       /* conn's #93C98B at the paper's value */
  --blue: 66,87,105;      /* conn's #7FA7C9 at the paper's value; the
                             stamp lays it at part strength, so it is
                             kept as channels rather than a hex */
  --paper: linear-gradient(115deg, #f1ebde 0%, #ece5d6 45%, #E6DFD0 100%);
  --paper-top: #f1ebde;   /* the paper's lit edge, above conn's ink */
  --box: rgba(255,255,255,0.35);
  --dash: rgba(42,38,32,0.35);
  --dots: rgba(42,38,32,0.45);
  --mono: 'Courier Prime', 'Courier New', Courier, monospace;
  --display: 'JetBrains Mono', ui-monospace, 'Courier New', Courier, monospace;
  /* The paper's fibre, drawn once as noise. The ink mask is solid over
     most of the noise, thins a little where it runs high, and only at
     its peaks lets the paper through: the ink that missed a fibre. The fibre overlay is the same noise as a faint warm
     tone, laid over paper and ink alike. */
  --ink-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='f'><feTurbulence type='fractalNoise' baseFrequency='0.55' numOctaves='4' seed='7' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  1 0 0 0 0'/><feComponentTransfer><feFuncA type='table' tableValues='1 1 1 0.97 0.88 0.6 0.25'/></feComponentTransfer></filter><rect width='240' height='240' filter='url(%23f)'/></svg>");
  --fibre: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='320' height='320'><filter id='f'><feTurbulence type='fractalNoise' baseFrequency='0.55' numOctaves='5' seed='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.55  0 0 0 0 0.45  0 0 0 0 0.3  0.3 0 0 0 -0.08'/></filter><rect width='320' height='320' filter='url(%23f)'/></svg>");
}

html {
  background: var(--desk);
  /* A phone's browser inflates text it takes for a desktop page; the
     page is set at its size and stays there. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
body {
  margin: 0;
  background: var(--desk);
  color: var(--ink-2);
  font: 400 14px/1.75 var(--mono);
  font-variant-ligatures: none;
  font-feature-settings: 'liga' 0, 'calt' 0;
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; text-decoration: none; }
a:hover { opacity: 0.8; }
b, strong { font-weight: 700; }

/* The desk, and the stack of pages on it. */
.desk {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 42px;
  padding: 56px 24px 80px;
}

/* A page: letter paper, a shadow onto the desk, and a scan's grain over
   everything on it. Each page in the stack lies a fraction of a degree
   off the last, the way a scanned stack does. The page is letter size,
   and grows rather than clips when a browser sets its text larger than
   the one it was paginated in — a font that has not loaded yet, a
   phone's idea of a readable size: a page a little long is a page; a
   paragraph cut off is a missing page. */
.page {
  position: relative;
  flex: none;
  width: 816px;
  min-height: 1056px;
  background: var(--paper);
  box-shadow: 0 30px 70px -25px rgba(0,0,0,0.9), 0 2px 6px rgba(0,0,0,0.5);
  box-sizing: border-box;
}
.page:nth-child(3n+1) { transform: rotate(-0.25deg); }
.page:nth-child(3n+2) { transform: rotate(0.2deg); }
.page:nth-child(3n) { transform: rotate(-0.15deg); }
.page::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  mix-blend-mode: multiply;
  background:
    radial-gradient(620px 300px at 18% 8%, rgba(120,100,60,0.06), transparent 70%),
    radial-gradient(520px 420px at 88% 94%, rgba(105,85,50,0.08), transparent 70%),
    radial-gradient(140px 90px at 72% 30%, rgba(110,90,55,0.05), transparent 70%),
    radial-gradient(closest-side at 50% 50%, transparent 55%, rgba(90,72,42,0.09) 100%),
    repeating-linear-gradient(0deg, rgba(110,90,60,0.02) 0 1px, transparent 1px 3px);
}
.page:nth-child(3n+2)::before {
  background:
    radial-gradient(620px 300px at 82% 6%, rgba(120,100,60,0.06), transparent 70%),
    radial-gradient(520px 420px at 12% 96%, rgba(105,85,50,0.08), transparent 70%),
    radial-gradient(120px 80px at 30% 55%, rgba(110,90,55,0.05), transparent 70%),
    radial-gradient(closest-side at 50% 50%, transparent 55%, rgba(90,72,42,0.09) 100%),
    repeating-linear-gradient(0deg, rgba(110,90,60,0.02) 0 1px, transparent 1px 3px);
}
.page:nth-child(3n)::before {
  background:
    radial-gradient(620px 300px at 22% 4%, rgba(120,100,60,0.06), transparent 70%),
    radial-gradient(520px 420px at 90% 92%, rgba(105,85,50,0.08), transparent 70%),
    radial-gradient(120px 80px at 66% 40%, rgba(110,90,55,0.05), transparent 70%),
    radial-gradient(closest-side at 50% 50%, transparent 55%, rgba(90,72,42,0.09) 100%),
    repeating-linear-gradient(0deg, rgba(110,90,60,0.02) 0 1px, transparent 1px 3px);
}

/* The fibre lies over the ink as well as the paper: the ::after is the
   last thing painted on a page, and the mouse goes through it. */
.page::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  mix-blend-mode: multiply;
  background: var(--fibre);
}
/* Everything printed is masked by the same fibre, so the ink breaks up
   where the paper's surface did not take it. The holes are punched, not
   printed, and stay out of it. The title block is masked piece by piece
   rather than as a whole: a mask isolates what is under it, and the
   plate inside needs the page for a backdrop to blend with. */
.sheet, .cover > :not(.title), .cover .title > *, .classified {
  -webkit-mask-image: var(--ink-mask);
  mask-image: var(--ink-mask);
}

/* Binder holes, three down the left. */
.hole {
  position: absolute;
  left: 24px;
  width: 17px;
  height: 17px;
  border-radius: 50%;
  z-index: 2;
  background: var(--desk);
  box-shadow: inset 0 2px 3px rgba(0,0,0,0.9), 0 1px 0 rgba(255,255,255,0.4);
}
.hole:nth-of-type(1) { top: 10%; }
.hole:nth-of-type(2) { top: 49.5%; }
.hole:nth-of-type(3) { top: 89%; }

/* The classification marking, top and bottom of every page. The indent
   matches the tracking, so the tracked word sits optically centered. */
.classified {
  position: absolute;
  left: 0;
  right: 0;
  text-align: center;
  font: 700 10px var(--mono);
  letter-spacing: 0.42em;
  text-indent: 0.42em;
  color: var(--muted);
}
.classified.top { top: 13px; }
.classified.bottom { bottom: 12px; }
/* A declassified document keeps its original marking, struck through by
   hand: the strike is a rule over the word, tilted the way a pen would. */
.classified s { position: relative; display: inline-block; text-decoration: none; text-indent: 0; }
.classified s::after {
  content: "";
  position: absolute;
  left: -4px;
  right: 0;
  top: 46%;
  border-top: 2px solid rgba(42,38,32,0.65);
  transform: rotate(-1.2deg);
}

/* The interior page's content: a column with the footer pinned to the
   foot, and the binder margin on the left. */
.sheet {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 1056px;
  padding: 42px 64px 38px 96px;
  box-sizing: border-box;
}
.running {
  display: flex;
  justify-content: space-between;
  font: 400 11px var(--mono);
  letter-spacing: 0.12em;
  color: var(--muted);
}
.running b { color: var(--ink-2); }
.running + .rule { margin-top: 10px; }
.rule { border-top: 1px solid var(--ink-2); }
.rule-heavy { border-top: 2px solid var(--ink-2); }
.body { margin-top: 30px; }
/* The last thing on a page carries no margin under it: the air between
   it and the foot's rule is the rule's own, so a page filled to its last
   line stays letter size. */
.body .section > :last-child { margin-bottom: 0; }
.foot { margin-top: auto; }
.foot .rule { margin-top: 12px; }
.folio {
  display: flex;
  justify-content: space-between;
  margin-top: 10px;
  font: 400 11px var(--mono);
  letter-spacing: 0.12em;
  color: var(--muted);
}
.folio b { color: var(--ink-2); }

/* Contents: two columns of dot-leader rows. */
.contents {
  display: flex;
  gap: 28px;
  margin-top: 24px;
  padding-bottom: 22px;
  border-bottom: 1px solid rgba(42,38,32,0.3);
}
.contents > div { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; }
.contents .label {
  font: 700 10.5px var(--mono);
  letter-spacing: 0.24em;
  color: var(--faint);
  margin: 0 0 10px;
}
.contents ol {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  font: 400 12.5px var(--mono);
  color: var(--ink-3);
}
.contents li a { display: flex; align-items: baseline; gap: 8px; }
.contents li .n { color: var(--orange); font-weight: 700; }
.contents li .dots { flex: 1; border-bottom: 1px dotted var(--dots); transform: translateY(-3px); }
.contents + .body { margin-top: 34px; }

/* A section: kicker, title, the short orange rule. */
.section + .section { margin-top: 34px; }
.kicker {
  font: 700 12px var(--mono);
  letter-spacing: 0.3em;
  color: var(--orange);
  margin: 0 0 4px;
}
.section h2 {
  font: 800 30px/1.1 var(--display);
  letter-spacing: 0.01em;
  color: var(--ink);
  margin: 0 0 6px;
  text-transform: uppercase;
}
.section h2::after {
  content: "";
  display: block;
  width: 72px;
  border-top: 3px solid var(--orange);
  margin: 6px 0 20px;
}
.section h3 {
  font: 700 12px var(--mono);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin: 4px 0 10px;
}

/* Paragraphs, each opening with its number. */
.para {
  font: 400 14px/1.75 var(--mono);
  color: var(--ink-2);
  margin: 0 0 14px;
}
.para .n { font-weight: 700; color: var(--ink); }
.para .n::after { content: "\00a0\00a0"; }
.para code, .table code, .note code { font: inherit; font-weight: 700; color: var(--ink-2); }
.para .mark { color: var(--orange); font-weight: 700; }

/* A command box, and a figure of code. */
.cmd {
  display: flex;
  align-items: baseline;
  gap: 12px;
  border: 1px solid var(--ink-2);
  background: var(--box);
  padding: 11px 18px;
  font: 400 13px var(--mono);
  color: var(--ink-2);
  box-shadow: 2px 2px 0 rgba(42,38,32,0.18);
  margin: 0 0 16px;
}
.cmd .prompt { color: var(--orange); font-weight: 700; }
.cmd code { flex: 1; font: inherit; }
.cmd .dim { color: var(--faint); }
.copy {
  font: inherit;
  color: var(--faint);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}
.copy:hover { color: var(--ink-2); }
.copy.done { color: var(--orange); }
.figure {
  max-width: 420px;
  margin: 0 auto 6px;
  border: 1px solid var(--ink-2);
  background: var(--box);
  box-shadow: 2px 2px 0 rgba(42,38,32,0.18);
  padding: 14px 20px;
}
.figure.wide { max-width: 540px; }
.figure pre {
  margin: 0;
  font: 400 13px/1.5 var(--mono);
  color: var(--ink-2);
}
.figure .k { color: var(--orange); font-weight: 700; }
.figure .c { color: var(--faint); }
.caption {
  text-align: center;
  font: italic 400 12.5px var(--mono);
  color: var(--ink-3);
  margin: 0 0 6px;
}
.figure + .caption { margin-bottom: 20px; }

/* A ruled table: heavy rules top and bottom, a light rule under the
   header, dashed rules between rows. */
.table {
  border-top: 2px solid var(--ink-2);
  border-bottom: 2px solid var(--ink-2);
  font: 400 12.5px var(--mono);
  color: var(--ink-3);
  margin: 0 0 16px;
}
.table .row {
  display: flex;
  gap: 18px;
  padding: 6px 6px;
  border-bottom: 1px dashed var(--dash);
}
.table .row:last-child { border-bottom: 0; }
.table .head {
  border-bottom: 1px solid var(--ink-2);
  font-weight: 700;
  color: var(--ink-2);
}
.table .row > span:first-child { flex: none; width: 190px; font-weight: 700; }
.table .row > span:last-child { flex: 1; }
.table.keys .row > span:first-child { width: 150px; }
.table.keys .row { padding: 3px 6px; }
.table.chords .row > span:first-child { width: 210px; }
.table.narrow .row > span:first-child { width: 120px; }
.table.marks .row > span:first-child { width: 44px; color: var(--orange); font-weight: 700; }
.table.marks .row > span.good { color: var(--green); }
.table.three .row > span:nth-child(2) { flex: none; width: 110px; }
.table.paths .row > span:first-child { width: 250px; }
.table.steps { border-top: 0; border-bottom: 0; margin: 0 0 18px 28px; }
.table.steps .row > span:first-child { width: 22px; }
.table.steps .row:last-child { border-bottom: 0; }
.table.record .row > span:first-child { width: 60px; font-weight: 400; }
.table.record .row > span:nth-child(2) { flex: none; width: 100px; }
.table.record .row.head span { font-weight: 700; }
.table .row .dim { color: var(--faint); }

/* A note, centered. */
.note {
  max-width: 540px;
  margin: 4px auto 16px;
}
.note .label {
  text-align: center;
  font: 700 12px var(--mono);
  letter-spacing: 0.34em;
  color: var(--ink-2);
  margin: 0 0 8px;
}
.note p {
  font: 400 13px/1.7 var(--mono);
  color: var(--ink-3);
  margin: 0;
  padding: 0 24px;
}
.note p b { color: var(--ink-2); }
.note.caution {
  border: 1px solid var(--ink-2);
  padding: 10px 0 12px;
}
.note.caution .label { color: var(--orange); }
.extract {
  text-align: center;
  font: 400 10.5px var(--mono);
  letter-spacing: 0.24em;
  color: var(--faint);
  margin: 0 0 16px;
}

/* The cover: a column too, its foot pinned to the page's foot. */
.cover { display: flex; flex-direction: column; min-height: 1056px; }
.cover .top {
  position: relative;
  padding: 46px 64px 0 96px;
}
.cover .nav {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font: 700 11px var(--mono);
  letter-spacing: 0.14em;
  color: var(--ink-2);
}
.cover .nav .links { display: flex; gap: 22px; font-weight: 400; color: var(--muted); }
.cover .nav .links .accent { color: var(--orange); }
.cover .nav + .rule-heavy { margin-top: 12px; }
.cover .rule-heavy + .rule { margin-top: 2px; }
.cover .title {
  position: relative;
  text-align: center;
  padding: 44px 64px 0 96px;
}
.cover .docline {
  font: 400 12px var(--mono);
  letter-spacing: 0.42em;
  color: var(--muted);
  margin: 0;
}
.cover h1 {
  font: 800 104px/0.94 var(--display);
  letter-spacing: -0.02em;
  color: var(--ink);
  margin: 24px 0 0;
  text-transform: uppercase;
}
.cover .banner {
  margin: 24px auto 0;
  background: var(--orange);
  /* The plate is ink, so the paper's tone and fibre show through it,
     and the wordmark is not a lighter ink but the paper left bare: white
     under multiply is whatever lies beneath. */
  mix-blend-mode: multiply;
  color: #fff;
  font: 800 21px/1 var(--display);
  letter-spacing: 0.3em;
  padding: 13px 0 12px;
  text-indent: 0.3em;
}
.cover .tagline {
  font: 700 15px/1.6 var(--mono);
  color: var(--ink-2);
  max-width: 520px;
  margin: 28px auto 0;
}
.cover .sub {
  font: 400 13.5px/1.75 var(--mono);
  color: var(--ink-3);
  max-width: 540px;
  margin: 14px auto 0;
}
.cover .install {
  position: relative;
  text-align: center;
  padding: 30px 64px 0 96px;
}
.cover .install .label {
  font: 400 10.5px var(--mono);
  letter-spacing: 0.26em;
  color: var(--faint);
  margin: 0 0 8px;
}
.cover .install .cmd {
  display: inline-flex;
  padding: 12px 22px;
  font-size: 13.5px;
  margin: 0;
}
.cover .install .cmd code { flex: none; }
/* The declassification stamp: blue ink, a different pad from the REV
   stamp's orange, in the margin beside the wordmark, under the document
   line, which runs the width of the block and leaves no room beside it.
   It is placed against the title, not the page, so the cover's top can
   move without the stamp landing on the rules. */
.cover .declassified {
  position: absolute;
  right: 50px;
  top: 102px;
  transform: rotate(-4deg);
  border: 2px solid rgba(var(--blue),0.55);
  color: rgba(var(--blue),0.72);
  padding: 8px 10px 7px;
  font: 700 9px/1.65 var(--mono);
  letter-spacing: 0.12em;
  text-align: left;
}
.cover .declassified small { font-weight: 400; font-size: 8.5px; }
/* The table runs the width of the page, so a release's description has
   the room a line needs; the stamp goes under it, at the right, the way a
   stamp lands after the table is typed. The block ends below the stamp's
   low corner: the ink mask stops at the block's edge, and would cut the
   corner off. */
.cover .revisions {
  position: relative;
  padding: 28px 64px 16px 96px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
}
.cover .revisions .label {
  font: 700 10.5px var(--mono);
  letter-spacing: 0.2em;
  color: var(--ink-2);
  margin: 0 0 6px;
}
.cover .revisions .table { margin: 0; }
.cover .revisions .table .row { gap: 16px; padding: 6px 4px; }
.cover .revisions .table .row > span:first-child { width: 44px; font-weight: 400; }
.cover .revisions .table .row > span:nth-child(2) { flex: none; width: 92px; }
.cover .revisions .table .head span { font-weight: 700; }
.cover .stamp {
  flex: none;
  transform: rotate(-7deg);
  border: 2.5px solid rgba(var(--orange-rgb),0.6);
  color: rgba(var(--orange-rgb),0.78);
  padding: 9px 16px 8px;
  font: 700 12px var(--mono);
  letter-spacing: 0.22em;
  text-align: center;
  align-self: flex-end;
  margin: 18px 22px 0 0;
}
.cover .stamp small {
  display: block;
  font-size: 9.5px;
  letter-spacing: 0.18em;
}
.cover .foot {
  position: relative;
  margin-top: auto;
  padding: 30px 64px 38px 96px;
}
.cover .distribution {
  text-align: center;
  font: 400 10.5px/1.8 var(--mono);
  letter-spacing: 0.1em;
  color: var(--faint);
  margin: 0 0 16px;
}
.cover .foot .rule { margin-bottom: 2px; }
.cover .spec {
  display: flex;
  margin: 13px 0 0;
  font: 400 11.5px var(--mono);
  color: var(--ink-3);
}
.cover .spec > div { flex: 1; }
.cover .spec dt {
  font-weight: 700;
  font-size: 9.5px;
  letter-spacing: 0.2em;
  color: var(--faint);
  margin: 0 0 3px;
}
.cover .spec dd { margin: 0; }

/* Below the desk's width the page is zoomed, not rewrapped: a fixed
   artifact, read smaller, its layout box shrinking with it so the stack
   stays centered. The script sets --scale from the viewport. */
@media (max-width: 880px) {
  body { overflow-x: hidden; }
  .desk { padding: 24px 0 48px; gap: 24px; }
  .page { zoom: var(--scale, 1); }
}
@media (prefers-reduced-motion: reduce) {
  .page { transition: none; }
}
