@font-face {
  font-family: 'Sofia Sans';
  src: url('../fonts/SofiaSans-var.woff2') format('woff2');
  font-weight: 1 1000;
  font-display: swap;
}
@font-face {
  font-family: 'Sofia Sans Condensed';
  src: url('../fonts/SofiaSansCondensed-var.woff2') format('woff2');
  font-weight: 1 1000;
  font-display: swap;
}
@font-face {
  font-family: 'Sometype Mono';
  src: url('../fonts/SometypeMono-var.woff2') format('woff2');
  font-weight: 400 700;
  font-display: swap;
}
/* the maker's byline only: the italic, subset to lowercase, space and hyphen */
@font-face {
  font-family: 'Instrument Serif';
  src: url('../fonts/InstrumentSerif-Italic.woff2') format('woff2');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

/*
 * One programme. The page is the hero's module grid: --cols screens across,
 * every column edge on the page is a screen edge in the field.
 */
:root {
  --paper: #ede6d4;
  --ink: #1d1b18;
  --cue: #0b7a5a;
  --ink-2: #4a4640;      /* secondary text, 7.6:1 on paper */
  --cols: 16;
  --wall-span: 2;        /* page columns per screen of the hero wall: phones show fewer, larger screens */
  --margin: 16px;
  --px: calc((100vw - 2 * var(--margin)) / var(--cols));
  --row: calc(var(--px) * 0.78);
  --sans: 'Sofia Sans', 'Helvetica Neue', Arial, sans-serif;
  --cond: 'Sofia Sans Condensed', 'Sofia Sans', 'Arial Narrow', sans-serif;
  --mono: 'Sometype Mono', ui-monospace, Menlo, monospace;
  color-scheme: light;
}
@media (min-width: 600px) { :root { --cols: 24; --margin: 28px; --wall-span: 1; } }
@media (min-width: 900px) { :root { --cols: 32; --margin: 36px; } }
@media (min-width: 1200px) { :root { --cols: 44; --margin: 48px; } }

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background-color: var(--paper);
  background-image: url('../img/paper.png');
  background-blend-mode: multiply;
  background-size: 384px 384px;
  color: var(--ink);
  font-family: var(--sans);
  font-weight: 460;
  font-size: 16px;
  line-height: 1.45;
  font-feature-settings: 'kern', 'lnum';
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 0.18em; }
a:hover { text-decoration-color: var(--cue); text-decoration-thickness: 2px; }
:focus-visible { outline: 2px solid var(--cue); outline-offset: 3px; }
code { font-family: var(--mono); font-size: 0.88em; letter-spacing: -0.01em; }
h1, h2, h3, p, ol, dl, dd, figure { margin: 0; padding: 0; }

.sheet { width: 100%; padding: 0 var(--margin); }
.grid {
  display: grid;
  grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
}
/* text inside the grid sits a hair in from the screen edge */
.grid > * { padding-inline: calc(var(--px) * 0.08); }

/* ---------- masthead ---------- */
.mast {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px calc(var(--px) * 0.08) 10px;
  font-family: var(--cond);
  font-size: 13px;
  font-weight: 560;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.mast a { text-decoration: none; }
.mast__nav { display: flex; gap: 1.4em; }
.mast__nav a:hover { text-decoration: underline; text-decoration-color: var(--cue); }
.mast__gh { display: block; flex: none; width: 22px; height: 22px; color: var(--ink); }
.mast__gh svg { display: block; width: 100%; height: 100%; fill: currentColor; }
.mast__gh:hover { color: var(--cue); }
/* the maker's byline beside the source link: always lowercase, written that way in the markup */
.mast__by {
  margin: 0 14px 0 auto;
  padding-left: 14px;
  font: italic 400 16px/22px 'Instrument Serif', serif;
  letter-spacing: 0;
  text-transform: none;
  white-space: nowrap;
  color: var(--ink);
  opacity: 0.7;
}
.mast__by:hover { color: var(--cue); opacity: 1; }
/* On phones the masthead has no room beside the nav: the byline steps down under the source link,
   across from the name, on the name's baseline. The masthead keeps its height. */
@media (max-width: 599px) {
  .mast { position: relative; }
  .mast__by { position: absolute; top: calc(100% + var(--row) * 0.4 + 15px); right: calc(var(--px) * 0.08); margin: 0; padding: 0; }
}

/* ---------- front: the name, the plate and its caption, filling the first screen under the masthead ---------- */
.front { display: flex; flex-direction: column; height: calc(100svh - 46px); min-height: 540px; }
/* the name, a sleeve title on the wall's first column */
.title {
  flex: none;
  padding: calc(var(--row) * 0.4) calc(var(--px) * 0.08) calc(var(--row) * 0.6);
  font-size: clamp(44px, 1.4rem + 3vw, 72px);
  font-weight: 680;
  line-height: 0.8;
  letter-spacing: -0.028em;
}
/* the wall fills what the viewport leaves it, but never grows taller than 1.75 times its width */
.plate { position: relative; flex: 1 1 auto; min-height: 0; max-height: calc((100vw - 2 * var(--margin)) * 1.75); }
.plate canvas {
  display: block;
  width: 100%;
  height: 100%;
  mix-blend-mode: multiply;
}
.caption { flex: none; }

/* The install line, set in the rows the field leaves unprinted near the foot of the wall. Without
   the field script it sits under the plate. */
.slot { display: flex; justify-content: center; padding: 12px 0; }
.slot[data-placed] { position: absolute; left: 0; right: 0; align-items: center; padding: 0; }
.install {
  display: inline-flex;
  align-items: center;
  gap: 0.8em;
  max-width: 100%;
  padding: 4px 8px;
  border: 0;
  background: none;
  color: var(--ink);
  font-family: var(--mono);
  font-size: clamp(11.25px, 0.55rem + 0.42vw, 15px);
  line-height: 1.4;
  white-space: nowrap;
  cursor: pointer;
}
.install code { font-size: inherit; letter-spacing: 0; }
.install__prompt { min-width: 1ch; color: var(--cue); font-weight: 600; user-select: none; }
.install__copy {
  margin-left: 0.4em;
  font: 600 11px/1 var(--cond);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border: 1px solid var(--ink);
  border-radius: 6px;
  padding: 5px 8px 4px;
}
.install:hover .install__copy { background: var(--ink); color: var(--paper); }
@media (max-width: 599px) {
  .install__copy { display: none; }
  /* the whole line on one row of the narrowest phones: about 27em of mono with its padding */
  .install { font-size: min(11.25px, (100vw - 2 * var(--margin) - 16px) / 27); }
}

.caption {
  padding: calc(var(--row) * 0.9) 0 calc(var(--row) * 1.6);
  row-gap: 16px;
  align-items: start;
}
/* The lamp keeps the wall's first column. The tagline sits on the wall's centre line, under the centred
   install line: the intro spans columns symmetric about the middle and the lede is centred in it.
   Narrower than 900px there is no room for both on one row, so the lamp sits above it. */
.cue { grid-column: 1 / -1; display: flex; align-items: center; gap: 12px; }
.intro { grid-column: 1 / -1; }
@media (min-width: 900px) {
  .cue { grid-column: 1 / span 7; grid-row: 1; }
  .intro { grid-column: 9 / span 16; grid-row: 1; }
}
@media (min-width: 1200px) {
  .cue { grid-column: 1 / span 8; }
  .intro { grid-column: 12 / span 22; }
}

/* the cue light: a lamp in a bezel, standby then go */
.lamp {
  position: relative;
  width: 34px;
  height: 34px;
  flex: none;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--ink);
  cursor: pointer;
}
.lamp__glass {
  position: absolute;
  inset: 6px;
  border-radius: 50%;
  background: var(--paper);
  transition: background-color 120ms linear;
}
.lamp[data-state='standby'] .lamp__glass {
  background-color: var(--paper);
  background-image: radial-gradient(circle, var(--cue) 34%, transparent 38%);
  background-size: 3.2px 3.2px;
  animation: standby 750ms steps(1) infinite;
}
.lamp[data-state='go'] .lamp__glass { background: var(--cue); }
@keyframes standby { 50% { background-image: none; } }
@media (prefers-reduced-motion: reduce) { .lamp[data-state='standby'] .lamp__glass { animation: none; } }
.cue__text {
  font-family: var(--cond);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: 1.2;
}
.cue__q { font-variant-numeric: tabular-nums; margin-right: 0.5em; }

.lede {
  font-size: clamp(21px, 1.15rem + 0.6vw, 26px);
  line-height: 1.18;
  font-weight: 430;
  letter-spacing: -0.006em;
  max-width: 30ch;
  margin-inline: auto;
  text-align: center;
  text-wrap: pretty;
}

/* a button is a screen: same corner as the modules */
.button {
  display: inline-block;
  padding: 11px 18px 12px;
  border-radius: 9px;
  background: var(--ink);
  color: var(--paper);
  font-weight: 620;
  letter-spacing: 0.01em;
  text-decoration: none;
  box-shadow: 0.75px -0.5px 0 0 var(--cue);
  transition: box-shadow 160ms ease-out;
}
/* hover: the cue-ink plate slips out of register */
.button:hover { box-shadow: 4px -3px 0 0 var(--cue); text-decoration: none; }
@media (prefers-reduced-motion: reduce) { .button { transition: none; } }
.link { font-weight: 600; }

/* ---------- strips: one row of the field between parts ---------- */
.strip {
  display: block;
  width: 100%;
  height: var(--row);
  mix-blend-mode: multiply;
}
.strip--end { margin-top: calc(var(--row) * 2); }

/* ---------- parts ---------- */
.part {
  padding: calc(var(--row) * 1.4) 0 calc(var(--row) * 3);
  row-gap: calc(var(--row) * 1.4);
  align-items: start;
}
.part__head { grid-column: 1 / -1; display: flex; align-items: baseline; gap: 12px; }
.part__no {
  font-family: var(--cond);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.08em;
  min-width: 1.5em;
}
h2 {
  font-size: clamp(22px, 1rem + 0.7vw, 28px);
  font-weight: 430;
  letter-spacing: -0.006em;
  line-height: 1.1;
}
h3 { font-size: 16px; font-weight: 680; line-height: 1.3; }
.part p { max-width: 46ch; }
@media (min-width: 900px) {
  .part__head { grid-column: 1 / span 7; flex-direction: column; gap: 4px; }
  .part__no { order: -1; }
}
@media (min-width: 1200px) { .part__head { grid-column: 1 / span 11; } }

/* 1 setup: three plates, each its own small field on the same columns */
.steps { list-style: none; grid-column: 1 / -1; display: grid; grid-template-columns: subgrid; row-gap: calc(var(--row) * 1.6); }
.step { grid-column: 1 / -1; }
.step__plate { display: block; width: 100%; height: calc(var(--row) * 6); margin-bottom: 14px; mix-blend-mode: multiply; }
.step h3 { margin-bottom: 4px; }
.step__no { font-family: var(--cond); font-weight: 600; margin-right: 0.35em; }
.step p { color: var(--ink); }
@media (min-width: 600px) {
  .steps { grid-template-columns: repeat(3, minmax(0, 1fr)); grid-column: 1 / -1; column-gap: var(--px); }
  .step { grid-column: auto; }
}
@media (min-width: 900px) {
  .steps { grid-column: 8 / -1; grid-template-columns: subgrid; column-gap: 0; }
  .step:nth-child(1) { grid-column: 1 / span 8; }
  .step:nth-child(2) { grid-column: 9 / span 8; }
  .step:nth-child(3) { grid-column: 17 / span 8; }
  .step { padding-right: calc(var(--px) * 0.6); }
  .step__plate { width: calc(var(--px) * 7); }
}
@media (min-width: 1200px) {
  .steps { grid-column: 12 / -1; }
  .step:nth-child(1) { grid-column: 1 / span 11; }
  .step:nth-child(2) { grid-column: 12 / span 11; }
  .step:nth-child(3) { grid-column: 23 / span 11; }
  .step__plate { width: calc(var(--px) * 10); }
}

/* 2 screens: a key — each kind of screen in one of the programme's four states */
.table { grid-column: 1 / -1; border-top: 1px solid var(--ink); }
.row {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  padding: 12px 0 14px;
  border-bottom: 1px solid var(--ink);
  row-gap: 2px;
}
.row dt { display: flex; align-items: center; gap: 12px; font-weight: 680; }
.row dd { color: var(--ink); padding-left: calc(var(--px) * 1.6 + 12px); }
.glyph { width: calc(var(--px) * 0.84); height: calc(var(--px) * 0.64); flex: none; mix-blend-mode: multiply; }
@media (min-width: 600px) {
  .row { grid-template-columns: repeat(24, minmax(0, 1fr)); align-items: center; }
  .row dt { grid-column: 1 / span 9; }
  .row dd { grid-column: 10 / -1; padding-left: 0; }
}
@media (min-width: 900px) {
  .table { grid-column: 8 / -1; }
  .row { grid-template-columns: repeat(25, minmax(0, 1fr)); }
  .row dt { grid-column: 1 / span 9; }
  .row dd { grid-column: 10 / -1; }
}
@media (min-width: 1200px) {
  .table { grid-column: 12 / -1; }
  .row { grid-template-columns: repeat(33, minmax(0, 1fr)); }
  .row dt { grid-column: 1 / span 11; }
  .row dd { grid-column: 12 / -1; }
}

/* 3 details: two reading columns */
.details { grid-column: 1 / -1; display: grid; row-gap: calc(var(--row) * 1.4); }
.detail { border-top: 1px solid var(--ink); padding-top: 12px; }
.detail h3 { margin-bottom: 4px; }
.detail__plate { display: block; width: calc(var(--px) * 7); height: calc(var(--row) * 3); margin-top: 16px; mix-blend-mode: multiply; }
@media (min-width: 600px) {
  .details { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--px); }
}
@media (min-width: 900px) {
  .details { grid-column: 8 / -1; }
}
@media (min-width: 1200px) {
  .details { grid-column: 12 / -1; column-gap: var(--px); }
  .detail--pin { grid-row: span 2; }
}

/* 4 install */
.recipe { grid-column: 1 / -1; min-width: 0; }
.recipe__head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 4px; border-top: 1px solid var(--ink); padding-top: 12px; }
.recipe > p { color: var(--ink); }
.recipe > p:last-child { margin-top: 12px; color: var(--ink-2); font-size: 15px; }
pre {
  margin: 12px 0 0;
  padding: 16px 0 16px;
  overflow-x: auto;
  font-family: var(--mono);
  font-size: 13.5px;
  line-height: 1.6;
  border-top: 1px dotted var(--ink-2);
  border-bottom: 1px dotted var(--ink-2);
  -webkit-overflow-scrolling: touch;
}
pre code { font-size: inherit; letter-spacing: 0; }
.copy {
  font: 600 12px/1 var(--cond);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink);
  background: none;
  border: 1px solid var(--ink);
  border-radius: 6px;
  padding: 6px 9px 5px;
  cursor: pointer;
}
.copy:hover { background: var(--ink); color: var(--paper); }
.get { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; column-gap: 22px; row-gap: 12px; }
@media (min-width: 900px) {
  .recipe:nth-of-type(1) { grid-column: 8 / span 12; }
  .recipe:nth-of-type(2) { grid-column: 20 / -1; padding-left: calc(var(--px) * 0.6); }
  .get { grid-column: 8 / -1; }
}
@media (min-width: 1200px) {
  .recipe:nth-of-type(1) { grid-column: 12 / span 15; }
  .recipe:nth-of-type(2) { grid-column: 27 / -1; padding-left: calc(var(--px) * 0.5); }
  .get { grid-column: 12 / -1; }
}

/* ---------- colophon ---------- */
.colophon {
  padding: calc(var(--row) * 1.2) 0 calc(var(--row) * 2.4);
  row-gap: 10px;
  font-size: 14px;
  color: var(--ink-2);
}
.colophon > * { grid-column: 1 / -1; }
.colophon__name { color: var(--ink); font-weight: 680; }
.colophon__name span { font-weight: 460; color: var(--ink-2); margin-left: 0.4em; }
.colophon__links { display: flex; gap: 22px; flex-wrap: wrap; }
.colophon__links a { color: var(--ink); font-weight: 600; }
@media (min-width: 900px) {
  .colophon__name { grid-column: 1 / span 7; }
  .colophon__cat { grid-column: 8 / span 12; }
  .colophon__links { grid-column: 20 / span 13; }
}
@media (min-width: 1200px) {
  .colophon__cat { grid-column: 12 / span 12; }
  .colophon__links { grid-column: 24 / span 10; }
}
