/* The wireframe language on the reading and utility pages.
   ============================================================
   /faq, /instructors, /sign-up and /help. Four pages that have nothing in
   common except that they are none of the things already drawn: not a
   gallery of cards (css/gallery-wire.css), not a scroll rig
   (css/walkthrough-rig.css), not a deck of slides (css/deck-wireframe.css).
   A page carries this by putting `wp` on <body>, plus its own class —
   `wp-faq`, `wp-instructors`, `wp-signup`, `wp-help` — for the handful of
   rules that belong to one page.

   It takes the same four things the other sheets take, with the same
   numbers, so the hand does not change from page to page:

     paper rather than a tinted card       --wp-paper
     a ruled edge and a hard offset cast   1.5px / 3px 3px 0
     mono for anything that labels         --wp-mono
     ink plus one accent, and no third     --wp-ink / --wp-accent

   The values are the walkthroughs' own, borrowed rather than imported, as
   next-paths.css and student-figures.css borrow them: a page can be drawn
   without loading a walkthrough sheet.

   ---- what is drawn and what is ruled ----

   js/wire-page.js replaces the CSS edge on the *plates* with generated
   strokes (js/hand-ink.js) — the cards, the tables, the notices. Chips,
   buttons and form fields keep their ruled edge, exactly as the galleries'
   filter pills and search field do. A drawn box is a thing you read; a
   ruled one is a thing you press or type into, and the two want to look
   different anyway.

   ---- what draws itself, and when ----

   Almost nothing. A box that is on the page when the page is reads as part
   of the page, and eighteen of them drawing in sequence is movement rather
   than an effect — the lesson of /feedback's 167 quotations. So the ink is
   simply there.

   The exception is a box that *comes into being while the reader is
   watching*: a class block they just added, an error summary that was not
   there before they pressed Submit. Those are drawn, because being drawn is
   what says "this is new". `.wp-draw` is the class that opts a box in, and
   js/wire-page.js only ever puts it on a box that arrived after load or was
   hidden at load. Nothing that was visible at load can take it. */

/* ---- tokens ---- */
body.wp {
  --wp-ink: #55555f;
  --wp-strong: #111118;
  --wp-soft: #3f3f46;
  --wp-faint: #bab7b0;
  --wp-paper: #fffefb;
  /* The page the paper sits on. Only a page that paints its own background
     needs it — the templated pages already have one, /help is a fixed-viewport
     app that paints its own. */
  --wp-page: #faf9f6;
  --wp-sunken: #f0eeea;
  --wp-cast: rgba(60, 50, 40, 0.16);
  --wp-hatch: rgba(60, 50, 40, 0.07);
  --wp-accent: #5a5ad1;
  --wp-accent-soft: rgba(90, 90, 209, 0.1);
  /* What is legible on an accent fill, which is not the same colour in the
     two themes. Light's accent is a deep violet and takes paper on it at
     5.5:1; dark's is a pale one, and paper on that is 2.9:1 — white lettering
     on lilac, which is the sort of thing that reads fine to whoever chose it
     and to nobody at the back of a lecture theatre. Ink on it instead, 6.3:1. */
  --wp-on-accent: #fffefb;
  --wp-mono: "Roboto Mono", ui-monospace, Menlo, Consolas, monospace;
  --wp-body: "IBM Plex Sans", Roboto, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
html.dark-mode body.wp {
  --wp-ink: #a8a8b4;
  --wp-strong: #f1f1f5;
  --wp-soft: #b3b3bc;
  --wp-faint: #4b4b5a;
  --wp-paper: #15151e;
  --wp-page: #000000;
  --wp-sunken: #0e0e15;
  --wp-cast: rgba(226, 226, 255, 0.09);
  --wp-hatch: rgba(226, 226, 255, 0.05);
  --wp-accent: #8a8aff;
  --wp-accent-soft: rgba(138, 138, 255, 0.13);
  --wp-on-accent: #15151e;
}

/* ============================================================
   The plate
   ============================================================
   One box of paper with a ruled edge and a hard cast — the shape every
   other sheet on the site draws its cards as. The radius is 5px and the
   cast is a hard offset rather than a blur, which is what keeps it reading
   as a sheet of paper on a page rather than as a floating panel. */
.wp .wp-plate {
  position: relative;
  background: var(--wp-paper);
  border: 1.5px solid var(--wp-ink);
  border-radius: 5px;
  box-shadow: 3px 3px 0 var(--wp-cast);
  padding: 1.5rem 1.6rem 1.4rem;
  margin: 1.6rem 0;
}
/* A plate the reader can press — a link card. Lifting it deepens the cast
   rather than recolouring the edge: the sheet moves off the page to meet
   the pointer. */
.wp a.wp-plate {
  display: block;
  text-decoration: none;
  transition: box-shadow 0.2s ease, transform 0.2s ease;
}
.wp a.wp-plate:hover,
.wp a.wp-plate:focus-visible {
  box-shadow: 5px 5px 0 var(--wp-cast);
  transform: translate(-1px, -1px);
  text-decoration: none;
}

/* The plate's own heading, and the rule under it. Mono, because it labels
   the plate rather than speaking in it. */
.wp .wp-plate-h {
  font-family: var(--wp-mono);
  font-weight: 700;
  font-size: 1rem;
  line-height: 1.4;
  letter-spacing: -0.01em;
  color: var(--wp-strong);
  margin: 0 0 0.75rem;
}
.wp .wp-plate > :last-child { margin-bottom: 0; }

/* ============================================================
   The chip
   ============================================================
   A control: a filter, a button, a toggle. Paper, a ruled edge, a smaller
   cast than a plate takes, and mono. The pressed one takes the accent as
   its fill, so which chip is on stays obvious without a second colour. */
.wp .wp-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  border: 1.5px solid var(--wp-ink);
  border-radius: 5px;
  background: var(--wp-paper);
  box-shadow: 2px 2px 0 var(--wp-cast);
  color: var(--wp-strong);
  padding: 0.55rem 1.05rem;
  font-family: var(--wp-mono);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  line-height: 1.3;
  text-decoration: none;
  cursor: pointer;
  transition: box-shadow 0.18s ease, transform 0.18s ease;
}
.wp .wp-chip:hover,
.wp .wp-chip:focus-visible {
  box-shadow: 4px 4px 0 var(--wp-cast);
  transform: translate(-1px, -1px);
  text-decoration: none;
  color: var(--wp-strong);
}
.wp .wp-chip[aria-pressed="true"],
.wp .wp-chip.is-on {
  background: var(--wp-accent);
  border-color: var(--wp-accent);
  color: var(--wp-on-accent);
}
/* Pressed, in the moment: the sheet goes flat onto the page rather than
   lifting off it. */
.wp .wp-chip:active {
  box-shadow: 1px 1px 0 var(--wp-cast);
  transform: translate(1px, 1px);
}
.wp .wp-chip:disabled,
.wp .wp-chip[aria-disabled="true"] {
  opacity: 0.45;
  cursor: default;
  box-shadow: 2px 2px 0 var(--wp-cast);
  transform: none;
}
/* The one chip on a page that is the ask. Accent fill from the start. */
.wp .wp-chip.wp-chip-go {
  background: var(--wp-accent);
  border-color: var(--wp-accent);
  color: var(--wp-on-accent);
  padding: 0.7rem 1.4rem;
  font-size: 0.82rem;
  letter-spacing: 0.06em;
}

/* ============================================================
   The tag
   ============================================================
   Not a control and not a heading — a word about what a thing is. Dashed
   rather than ruled, so it never reads as pressable, and never filled. */
.wp .wp-tag {
  display: inline-block;
  border: 1px dashed var(--wp-faint);
  border-radius: 3px;
  background: none;
  color: var(--wp-soft);
  padding: 0.16em 0.55em;
  font-family: var(--wp-mono);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  line-height: 1.5;
  text-transform: uppercase;
  white-space: nowrap;
}

/* ============================================================
   The note
   ============================================================
   Something quoted, or set aside from the run of the page. A rule down its
   left rather than a box around it, so it reads as an aside rather than as
   another card inside the card. */
.wp .wp-note {
  border-left: 2px solid var(--wp-accent);
  padding: 0.15rem 0 0.15rem 0.95rem;
  margin: 1.1rem 0;
}
.wp .wp-note > :first-child { margin-top: 0; }
.wp .wp-note > :last-child { margin-bottom: 0; }
/* The same aside, said in the page's own ink — for the one that is a
   caution rather than an example. The palette is ink plus one accent and
   there is no red anywhere on this site, so weight carries the warning. */
.wp .wp-note-firm {
  border-left-color: var(--wp-strong);
}
.wp .wp-note-firm > p { color: var(--wp-strong); font-weight: 500; }

/* ============================================================
   The go-line and the eyebrow
   ============================================================
   Mono, uppercase, tracked, small. The eyebrow labels a region; the go-line
   sits at the foot of a card and says where pressing it leads. */
.wp .wp-eyebrow {
  font-family: var(--wp-mono);
  font-weight: 500;
  font-size: 0.7rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--wp-accent);
  margin: 0 0 0.5rem;
}
.wp .wp-go {
  display: block;
  margin-top: 1rem;
  padding-top: 0.75rem;
  border-top: 1px dashed var(--wp-faint);
  font-family: var(--wp-mono);
  font-weight: 500;
  font-size: 0.71rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--wp-accent);
}

/* ============================================================
   The table
   ============================================================
   The walkthroughs' own table (.wt2-table), at reading size: a ruled outer
   box, faint dashed rules between the rows, a hatched head, and mono for
   the column names. The outer box is what the hand draws, so it cannot
   clip its own overflow and cannot have a radius under the strokes. */
.wp .wp-table {
  position: relative;
  width: 100%;
  border-collapse: collapse;
  border: 1.5px solid var(--wp-ink);
  border-radius: 5px;
  background: var(--wp-paper);
  box-shadow: 3px 3px 0 var(--wp-cast);
  overflow: visible;
  margin: 1.4rem 0 2.2rem;
}
.wp .wp-table th,
.wp .wp-table td {
  text-align: left;
  vertical-align: top;
  padding: 0.95rem 1.1rem;
}
/* The column names. Hatched rather than filled, which is how every head in
   this language is marked — a fill would make the row look selected. */
.wp .wp-table thead th {
  background: var(--wp-hatch);
  border-bottom: 1.5px solid var(--wp-ink);
  font-family: var(--wp-mono);
  font-weight: 700;
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--wp-strong);
  padding-top: 0.6rem;
  padding-bottom: 0.6rem;
}
.wp .wp-table tbody tr + tr > * {
  border-top: 1px dashed var(--wp-faint);
}
/* The row's own name, in the first cell: mono, and the link that carries
   it takes the accent the rest of the page's links take. */
.wp .wp-table tbody th {
  font-family: var(--wp-mono);
  font-weight: 700;
  font-size: 0.9rem;
  line-height: 1.45;
  letter-spacing: -0.01em;
  color: var(--wp-strong);
  width: 34%;
}
.wp .wp-table tbody th { background: none; }
.wp .wp-table tbody th a { color: var(--wp-accent); text-decoration: none; }
.wp .wp-table tbody th a:hover { text-decoration: underline; }
.wp .wp-table tbody td {
  font-family: var(--wp-body);
  font-weight: 400;
  font-size: 0.9rem;
  line-height: 1.65;
  color: var(--wp-soft);
}
/* A paragraph in a cell is the cell, not a paragraph of the page: the
   content sheet's own p rule is more specific than a td, so it has to be
   told. */
.wp .wp-table td p {
  font-size: inherit;
  line-height: inherit;
  color: inherit;
  margin: 0 0 0.6em;
}
.wp .wp-table tbody td > :first-child { margin-top: 0; }
.wp .wp-table tbody td > :last-child { margin-bottom: 0; }
/* The third column is the shortest and the one that answers "do I need this
   now?", so it is set apart rather than set the same. */
.wp .wp-table .wp-when { width: 27%; }
.wp .wp-table tbody .wp-when {
  font-size: 0.85rem;
  color: var(--wp-soft);
}
/* The tag under a row's name says what kind of thing it is — a walkthrough,
   a PDF, a form — before the reader spends a click finding out. */
.wp .wp-table .wp-tag { margin-top: 0.45rem; }

/* A table narrower than its content is a table nobody can read. Below the
   width at which two columns fit, each row unstacks into a block: the name
   on its own line, the description under it, and the dashed rule that used
   to divide the columns dividing the rows instead. No sideways scroll, and
   nothing in a 34% column three words wide. */
@media (max-width: 640px) {
  .wp .wp-table,
  .wp .wp-table tbody,
  .wp .wp-table tbody tr,
  .wp .wp-table tbody th,
  .wp .wp-table tbody td { display: block; width: auto; }
  .wp .wp-table thead { display: none; }
  .wp .wp-table tbody tr { padding: 1rem 1.1rem; }
  .wp .wp-table tbody tr + tr { border-top: 1px dashed var(--wp-faint); }
  .wp .wp-table tbody tr + tr > * { border-top: 0; }
  .wp .wp-table tbody th { padding: 0 0 0.3rem; }
  .wp .wp-table tbody td { padding: 0; }
  .wp .wp-table .wp-when { width: auto; margin-top: 0.55rem; }
  /* The head is gone, so the one column whose meaning came from it says so
     itself. The other two do not need labelling: the first is a title and
     the second is the paragraph under it. */
  .wp .wp-table .wp-when::before {
    content: attr(data-label);
    display: block;
    font-family: var(--wp-mono);
    font-size: 0.62rem;
    font-weight: 500;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--wp-soft);
    opacity: 0.8;
    margin-bottom: 0.15rem;
  }
}

/* ============================================================
   A set of questions
   ============================================================
   /faq. One drawn box per section rather than one per question — the same
   shape the tables on /instructors take, so the two pages read as the same
   page furniture — with the questions as rows inside it, divided by the
   dashed rule that divides a table's rows.

   The questions are real <details>, written as <details> in the source
   rather than folded up by a script afterwards. Without JavaScript they
   open and close exactly the same; a script is needed only to open the one
   somebody has linked to. */
.wp .wp-qa { padding: 0; }
/* The content sheet has its own disclosure rules, which the walkthroughs and
   the showcases still use and which reach these rows too: a solid rule under
   every one of them, and a 26px summary. Both are said differently here —
   the rows are divided by the dashed rule that divides a table's rows, and
   the question is the <h3> inside the summary — so both are turned off
   rather than left to sit under what replaces them. */
.wp .wp-qa > details { padding: 0.25rem 1.4rem; border-bottom: 0; }
.wp .wp-qa > details + details { border-top: 1px dashed var(--wp-faint); }
.wp .wp-qa > details > summary {
  display: flex;
  align-items: baseline;
  gap: 0.8rem;
  list-style: none;
  cursor: pointer;
  padding: 1.05rem 0;
  /* Its own size, not the content sheet's 26px one: what it sizes here is
     the marker and the line the marker sits on, and the question is the h3. */
  font-size: 1rem;
  /* The banner is fixed, so a question jumped to has to clear it. */
  scroll-margin-top: calc(var(--banner-h, 64px) + 24px);
}
.wp .wp-qa > details > summary::-webkit-details-marker { display: none; }
.wp .wp-qa > details > summary::marker { content: ""; }
/* The heading is the question. It sits inside the summary rather than above
   it so that the whole line is the control and the document still has a
   heading for every question in it. */
.wp .wp-qa > details > summary > h3 {
  flex: 1;
  font-family: var(--wp-mono);
  font-weight: 500;
  font-size: 0.98rem;
  line-height: 1.55;
  letter-spacing: -0.01em;
  color: var(--wp-strong);
  margin: 0;
  scroll-margin-top: calc(var(--banner-h, 64px) + 24px);
  /* Not balanced. The content sheet balances headings so none of them
     strands a word, which is right for a heading and wrong for a question:
     balancing "What else does the AI Guide do?" on a phone breaks it after
     "does" and leaves the subject on the second line. */
  text-wrap: normal;
}
.wp .wp-qa > details > summary:hover > h3 { color: var(--wp-accent); }
/* Which way the row is about to go. A cross that closes into a dash, in the
   accent — the accent points at things, and this points at the answer.

   Before the question rather than after it. The column these sit in is a
   thousand pixels wide and the questions are eight words long, so a marker
   pushed to the right edge is a mark on its own in the middle of nothing;
   against the question it is part of the row. */
.wp .wp-qa > details > summary::before {
  content: "+";
  flex: 0 0 auto;
  width: 0.8em;
  font-family: var(--wp-mono);
  font-weight: 700;
  font-size: 1.05rem;
  line-height: 1.45;
  color: var(--wp-accent);
}
.wp .wp-qa > details[open] > summary::before { content: "\2212"; }
.wp .wp-qa > details > summary:focus-visible {
  outline: 2px solid var(--wp-accent);
  outline-offset: 2px;
  border-radius: 3px;
}
/* Indented to where the question starts, past the marker, so the answer
   hangs off its own question rather than off the box. */
.wp .wp-qa-body { padding: 0 0 1.2rem 1.65rem; max-width: 46rem; }
@media (max-width: 560px) {
  .wp .wp-qa > details { padding-left: 1rem; padding-right: 1rem; }
  .wp .wp-qa > details > summary { gap: 0.6rem; }
  .wp .wp-qa > details > summary > h3 { font-size: 0.9rem; }
  .wp .wp-qa-body { padding-left: 1.45rem; }
}
.wp .wp-qa-body > :first-child { margin-top: 0; }
.wp .wp-qa-body > :last-child { margin-bottom: 0; }

/* ============================================================
   Fields
   ============================================================
   Ruled, not drawn — a box you type into wants to look like a control, and
   its outline would be regenerated on every keystroke that changes its
   height. Paper, a ruled edge, a small cast, and the accent for focus. */
.wp .wp-field {
  width: 100%;
  box-sizing: border-box;
  background: var(--wp-paper);
  border: 1.5px solid var(--wp-ink);
  border-radius: 5px;
  box-shadow: 2px 2px 0 var(--wp-cast);
  color: var(--wp-strong);
  font-family: var(--wp-body);
  font-size: 1rem;
  line-height: 1.5;
  padding: 0.65rem 0.85rem;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.wp textarea.wp-field {
  min-height: 7rem;
  resize: vertical;
  line-height: 1.65;
}
.wp .wp-field::placeholder { color: var(--wp-soft); opacity: 0.75; }
.wp .wp-field:focus,
.wp .wp-field:focus-visible {
  outline: 2px solid var(--wp-accent);
  outline-offset: 1px;
  border-color: var(--wp-accent);
}
/* A field label is a label, so mono; the asterisk that marks it required is
   the one place the accent is allowed to be decoration. */
.wp .wp-label {
  display: block;
  font-family: var(--wp-mono);
  font-weight: 700;
  font-size: 0.82rem;
  letter-spacing: 0.01em;
  line-height: 1.5;
  color: var(--wp-strong);
  margin: 0 0 0.35rem;
}
.wp .wp-req { color: var(--wp-accent); margin-left: 0.15em; }
.wp .wp-optional {
  font-family: var(--wp-mono);
  font-weight: 400;
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--wp-soft);
  margin-left: 0.45em;
}
.wp .wp-help {
  display: block;
  font-family: var(--wp-body);
  font-weight: 400;
  font-size: 0.85rem;
  line-height: 1.55;
  color: var(--wp-soft);
  margin: 0 0 0.5rem;
}

/* ---- a field that failed ----
   Ink plus one accent, and no third: there is no red token on this site, so
   a field that needs attention is one the accent is pointing at. Weight and
   the message carry the rest, and neither depends on seeing a colour. */
.wp .wp-invalid .wp-field,
.wp .wp-field[aria-invalid="true"] {
  border-color: var(--wp-accent);
  border-width: 2px;
  box-shadow: 2px 2px 0 var(--wp-accent-soft);
}
.wp .wp-invalid > .wp-label { color: var(--wp-accent); }
.wp .wp-error {
  display: none;
  font-family: var(--wp-mono);
  font-weight: 500;
  font-size: 0.76rem;
  line-height: 1.5;
  letter-spacing: 0.01em;
  color: var(--wp-accent);
  margin-top: 0.4rem;
}
.wp .wp-invalid .wp-error { display: block; }
/* One kind of error belongs to a group of fields rather than to any of them
   — "add at least one class" — so it has no .wp-invalid to be inside, and
   shows itself whenever it has something to say. */
.wp .wp-error-standalone:not(:empty) { display: block; margin-top: 0.75rem; }

/* ============================================================
   Rules and separators
   ============================================================ */
.wp .wp-rule {
  border: 0;
  border-top: 1px dashed var(--wp-faint);
  margin: 1.1rem 0;
}

/* ============================================================
   A block written to be taken away
   ============================================================
   Syllabus language an instructor is meant to paste into their own
   document. It is a plate with a head across the top — hatched, the way
   every head in this language is marked — carrying the block's name and the
   one control that matters, which is the one that puts it on the clipboard.

   The head is sticky inside the plate so that the copy chip is still
   reachable partway down a block that runs several screens. */
/* Not `overflow: hidden`, which is the obvious way to keep the head's fill
   inside the plate's rounded corners and is also the one thing that stops
   the head from sticking: it makes the plate a scroll container, and a
   sticky child sticks inside its nearest scrolling ancestor — which here
   never scrolls. The head rounds its own two corners instead. */
.wp .wp-block { padding: 0; }
.wp .wp-block-head {
  position: sticky;
  top: calc(var(--banner-h, 64px) + 4px);
  z-index: 2;
  border-radius: 4px 4px 0 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  /* Paper with the hatch laid over it, rather than the hatch on its own: the
     hatch is a 7% tint, and a head the page's own text scrolls through is a
     smear rather than a bar. Opaque, so there is nothing to see through. */
  background-color: var(--wp-paper);
  background-image: linear-gradient(var(--wp-hatch), var(--wp-hatch));
  border-bottom: 1.5px solid var(--wp-faint);
  padding: 0.7rem 1.1rem;
}
.wp .wp-block-title {
  font-family: var(--wp-mono);
  font-weight: 700;
  font-size: 0.76rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--wp-strong);
  margin: 0;
}
.wp .wp-block-body { padding: 1.3rem 1.5rem 1.4rem; }
/* On a phone the title wraps and the chip drops below it, which is a hundred
   pixels of sticky bar on an eight-hundred-pixel screen. Smaller and tighter,
   but still sticky: reaching the copy chip from partway down a block that runs
   several screens is the whole reason it is up there. */
@media (max-width: 560px) {
  .wp .wp-block-head {
    padding: 0.5rem 0.9rem;
    gap: 0.5rem;
    row-gap: 0.4rem;
  }
  .wp .wp-block-title { font-size: 0.66rem; letter-spacing: 0.08em; }
  .wp .wp-block-body { padding: 1.1rem 1.1rem 1.2rem; }
  html.wp-js .wp .wp-copy { font-size: 0.66rem; padding: 0.32rem 0.7rem; }
}
.wp .wp-block-body > :first-child { margin-top: 0; }
.wp .wp-block-body > :last-child { margin-bottom: 0; }
/* Nothing to press without the script that makes pressing it do something,
   so it is not there without it. */
.wp .wp-copy { display: none; }
html.wp-js .wp .wp-copy {
  display: inline-flex;
  font-size: 0.7rem;
  padding: 0.4rem 0.8rem;
  letter-spacing: 0.1em;
}
/* Said once the clipboard has it, and taken back after a moment. */
.wp .wp-copy .wp-copy-done { display: none; }
.wp .wp-copy.is-done .wp-copy-idle { display: none; }
.wp .wp-copy.is-done .wp-copy-done { display: inline; }
.wp .wp-copy.is-done {
  background: var(--wp-accent);
  border-color: var(--wp-accent);
  color: var(--wp-on-accent);
}

/* The words the instructor is meant to replace with their own. Marked
   rather than described, so nobody pastes "[INSTITUTION NAME]" into a
   syllabus without noticing. They survive the copy as plain brackets. */
.wp .wp-slot {
  font-family: var(--wp-mono);
  font-weight: 700;
  font-size: 0.88em;
  color: var(--wp-accent);
  background: var(--wp-accent-soft);
  border-radius: 3px;
  padding: 0.05em 0.3em;
  overflow-wrap: anywhere;
}

/* ============================================================
   The ink
   ============================================================
   js/wire-page.js sets html.wp-ink, which is what takes the CSS edge off —
   so a page without JavaScript keeps the ruled box above and nothing here
   applies. The drawn outline has square corners, and a rounded fill under
   it shows through where the strokes cross, so the radius goes with the
   border. */
html.wp-ink body.wp .hi-box {
  position: relative;
  border-color: transparent;
  border-radius: 0;
}
/* A drawn table keeps its inner rules — only the outer edge is replaced. */
html.wp-ink body.wp .wp-table.hi-box thead th {
  border-bottom-color: var(--wp-faint);
}
/* Nor does a head inside a drawn plate keep corners the plate no longer has. */
html.wp-ink body.wp .wp-block.hi-box > .wp-block-head { border-radius: 0; }
body.wp .hi-ink {
  position: absolute;
  left: -7px;
  top: -7px;
  overflow: visible;
  pointer-events: none;
  fill: none;
  z-index: 1;
}
body.wp .hi-ink path {
  stroke: var(--wp-ink);
  stroke-width: 1.15;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}
/* The second pass over an edge is lighter, as a real second pass is. */
body.wp .hi-ink path.hi-p2 { stroke-width: 0.85; stroke-opacity: 0.5; }

/* ---- the one thing that draws ----
   Only a box js/wire-page.js has decided came into being under the reader's
   hand carries .wp-draw, and only .wp-draw holds its strokes back. Every
   other box on the page has solid geometry from the moment it has any, so
   there is no state in which a line that was already there is drawn again.

   pathLength="1" normalises every stroke, so one dash length covers any
   edge and a long line takes no longer to draw than a short one. */
@keyframes wp-draw { to { stroke-dashoffset: 0; } }
html.wp-ink body.wp .wp-draw > .hi-ink path {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
}
html.wp-ink body.wp .wp-draw.hi-on > .hi-ink path {
  animation: wp-draw 0.42s cubic-bezier(0.35, 0.05, 0.2, 1) forwards;
  animation-delay: calc(var(--i, 0) * 0.045s);
}
/* Nothing to watch being drawn: the edges are simply there. */
@media (prefers-reduced-motion: reduce) {
  html.wp-ink body.wp .wp-draw > .hi-ink path {
    stroke-dasharray: none;
    stroke-dashoffset: 0;
  }
  html.wp-ink body.wp .wp-draw.hi-on > .hi-ink path { animation: none; }
}

/* ============================================================
   A dateline
   ============================================================
   A few numbers a reading page rests on, said once, in mono, under the
   lede: 400 instructors, 40,000 students, 91% comfortable. A ruled strip
   rather than a row of cards, because on a page whose subject is an
   argument the numbers are context for it — /topics says this first and
   says it best: *a dateline, not a dashboard*.

   The same strip that page draws as `.tp-facts`, with the same numbers, in
   the sheet the extension sits on top of. /topics keeps its own name for
   now; the two should be one rule, and are one rule's worth of values.

   The other case is a page whose subject is the measurement itself, which
   wants a band of big figures rather than a dateline. /survey and
   /research/experimental-data are the only two, and each keeps that band in
   its own sheet, where it was before this one existed. */
.wp .wp-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.6rem;
  margin: 1.4rem 0 0;
  padding: 0.8rem 0 0;
  border-top: 1px dashed var(--wp-faint);
  list-style: none;
  font-family: var(--wp-mono);
  font-size: 0.72rem;
  letter-spacing: 0.05em;
  line-height: 1.7;
  color: var(--wp-soft);
}
.wp .wp-facts li { font-size: inherit; line-height: inherit; color: inherit; }
.wp .wp-facts b {
  color: var(--wp-strong);
  font-weight: 700;
  margin-right: 0.4em;
}

/* ============================================================
   The sequence
   ============================================================
   Four things that happen in an order — an event deployment, an
   orientation week, the three steps of a sign-up. Not a numbered list:
   an ordered list's marker belongs to the browser and sets in the body
   face at the body size, and the whole point of a step is that its
   number is furniture rather than prose.

   The number is the walkthroughs' own — a mono two-digit figure in the
   accent, the same "01" the cards on every rig carry — and the steps are
   strung on the dashed spine that runs behind them, so a sequence reads
   as one thing going somewhere rather than as four paragraphs that
   happen to be numbered. */
.wp .wp-steps {
  list-style: none;
  margin: 1.6rem 0 2rem;
  padding: 0;
  counter-reset: wp-step;
}
.wp .wp-steps > li {
  position: relative;
  counter-increment: wp-step;
  padding: 0 0 1.5rem 3.4rem;
}
.wp .wp-steps > li:last-child { padding-bottom: 0; }
.wp .wp-steps > li::before {
  content: "0" counter(wp-step);
  position: absolute;
  left: 0;
  top: 0.1em;
  font-family: var(--wp-mono);
  font-weight: 700;
  font-size: 0.86rem;
  letter-spacing: 0.06em;
  line-height: 1.7;
  color: var(--wp-accent);
}
/* The spine. It starts under the first number and stops under the last,
   so the sequence has a beginning and an end rather than trailing off. */
.wp .wp-steps > li:not(:last-child)::after {
  content: "";
  position: absolute;
  /* Under the middle of the figure above it. Roboto Mono advances 0.6em a
     character, so a two-figure number set at 0.86rem is 1.03rem wide and
     its centre is half that. */
  left: 0.52rem;
  top: 1.95em;
  bottom: 0.15em;
  border-left: 1px dashed var(--wp-faint);
}
.wp .wp-steps > li > :first-child { margin-top: 0; }
.wp .wp-steps > li > :last-child { margin-bottom: 0; }
/* A step that carries its own sub-points keeps them out of the spine. */
.wp .wp-steps ul { margin: 0.5rem 0 0; }
@media (max-width: 560px) {
  .wp .wp-steps > li { padding-left: 2.6rem; }
}

/* ============================================================
   A pair
   ============================================================
   Two things at the same level, side by side, being compared: the two
   scaffolds, the two ways into orientation, what an instructor can and
   cannot see, what moves the progress meter and what does not.

   Only two, and only for a comparison. A row of *destinations* — three
   places to go next at the foot of a page — is the site's own "Up next"
   band (css/next-paths.css), which is drawn, has its own hand and its own
   grid, and is already on nine other pages. A second component that did
   the same job a little differently would be the one thing this language
   is against.

   The floor is in pixels, and wrapped in a min(). Pixels because the root
   font size on this site is fluid: 22rem is 440px on a 1512px screen, which
   is wider than half the 805px column a page gets when the rail is open and
   the contents list is up — so a pair written in rem stacks on the screens
   with the most room. The min() is what lets the one remaining track go
   under the floor on a phone rather than pushing 37px of sideways scroll. */
.wp .wp-pair {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr));
  gap: 1.5rem;
  margin: 1.8rem 0 2.2rem;
}
.wp .wp-pair > .wp-plate {
  margin: 0;
  display: flex;
  flex-direction: column;
}
.wp .wp-pair > .wp-plate > .wp-go { margin-top: auto; }

/* ============================================================
   The quotation
   ============================================================
   Somebody said this, and who they are is part of what it is worth. The
   note's accent rule carries the quotation; the attribution goes under
   the dashed rule that divides everything else in this language, and is
   mono because a name and a title label the quotation rather than speak
   in it.

   No serif quotation mark. The galleries set a huge one behind each card
   because a wall of 167 of them needs something to break the grid; one
   quotation in the run of a page does not, and the mark would be the only
   serif on the sheet. */
.wp .wp-quote { margin: 1.8rem 0; }
.wp .wp-quote p {
  font-size: 1.06rem;
  line-height: 1.7;
  color: var(--wp-strong);
}
.wp .wp-quote > footer,
.wp .wp-quote > .wp-cite {
  margin-top: 0.85rem;
  padding-top: 0.7rem;
  border-top: 1px dashed var(--wp-faint);
  font-family: var(--wp-mono);
  font-size: 0.74rem;
  font-weight: 500;
  line-height: 1.65;
  letter-spacing: 0.02em;
  color: var(--wp-soft);
}
.wp .wp-quote > footer b,
.wp .wp-quote > .wp-cite b {
  font-weight: 700;
  color: var(--wp-strong);
}

/* ============================================================
   Facts about one thing
   ============================================================
   Rows of name and value inside a plate — a creator's degrees and
   fields, a deployment's numbers. A table would be right if there were
   many of these things and one row each; there is one thing and many
   rows, so it is a description list, ruled the way a table's rows are. */
.wp .wp-kv {
  margin: 0;
  display: grid;
  grid-template-columns: minmax(6.5rem, auto) 1fr;
  /* The gap is the name's right padding rather than a column-gap, so that
     the dashed rule between rows crosses both columns as one line. With a
     column-gap it stops at the name and starts again at the value, and a
     rule with a hole in it reads as a fault rather than as a divider. */
  column-gap: 0;
}
.wp .wp-kv > dt {
  font-family: var(--wp-mono);
  font-weight: 500;
  font-size: 0.66rem;
  letter-spacing: 0.13em;
  line-height: 1.9;
  text-transform: uppercase;
  color: var(--wp-soft);
  padding: 0.55rem 1.4rem 0.55rem 0;
}
.wp .wp-kv > dd {
  margin: 0;
  padding: 0.55rem 0;
  font-family: var(--wp-body);
  font-size: 0.9rem;
  line-height: 1.65;
  color: var(--wp-strong);
}
.wp .wp-kv > dt:not(:first-of-type),
.wp .wp-kv > dt:not(:first-of-type) + dd {
  border-top: 1px dashed var(--wp-faint);
}
/* Below the width at which a 6.5rem name and a value fit side by side,
   the name goes above its value — the same unstacking the tables do,
   for the same reason. */
@media (max-width: 560px) {
  .wp .wp-kv { grid-template-columns: 1fr; }
  .wp .wp-kv > dt { padding: 0.55rem 0 0; line-height: 1.5; }
  .wp .wp-kv > dt:not(:first-of-type) + dd { border-top: 0; }
}

/* ============================================================
   The opening line
   ============================================================
   The paragraph under the h1 that says what the page is. A shade larger
   than the run of the page and set in the soft ink, so the eye starts
   there — and no max-width, because a capped measure would leave it
   ending short of every plate and table below it. */
.wp .wp-lede {
  font-size: 1.02rem;
  line-height: 1.65;
  color: var(--wp-ink);
}
.wp .wp-lede strong,
.wp .wp-lede b { color: var(--wp-strong); font-weight: 600; }

/* ---- an address, and the one line that is an address ----
   A block of lines rather than a paragraph, so it does not set in the
   browser's italic and does not run together. The single-line kind — an
   email address that is the whole point of the plate it is in — takes the
   mono the plate headings take, at the size that says "this is the thing
   you came for". */
.wp address {
  font-style: normal;
  font-family: var(--wp-body);
  line-height: 1.85;
  color: var(--wp-strong);
}
.wp .wp-addr {
  font-family: var(--wp-mono);
  font-weight: 700;
  font-size: clamp(1.05rem, 0.8rem + 0.75vw, 1.4rem);
  line-height: 1.4;
  letter-spacing: -0.01em;
  margin: 0 0 0.7rem;
  overflow-wrap: anywhere;
}
.wp .wp-addr-note {
  font-size: 0.9rem;
  line-height: 1.7;
  color: var(--wp-soft);
  margin: 0;
}

/* ============================================================
   A person
   ============================================================
   A portrait, a name, what they do, and the facts that a paragraph of
   biography buries: where they are now, where they were, what they have
   published in, what they hold. /about/creators ran two nine-line
   paragraphs at the full width of the column, which is a 1400px measure
   for a body of text nobody reads twice.

   The portrait keeps its colour and takes a ruled edge, which is what the
   galleries' avatars do (gallery-wire.css) — a photograph of somebody is
   not a diagram, and the palette rule is about the furniture the site
   draws, not about the people in it. */
.wp .wp-person {
  display: grid;
  grid-template-columns: 13.5rem minmax(0, 1fr);
  gap: 0 2.2rem;
  align-items: start;
}
.wp .wp-person-shot {
  grid-row: span 2;
  width: 100%;
  height: auto;
  display: block;
  margin: 0;
  border: 1.5px solid var(--wp-ink);
  border-radius: 4px;
  /* The cast is the plate's, one step smaller: a photograph pinned to the
     sheet rather than a second sheet on top of it. */
  box-shadow: 2px 2px 0 var(--wp-cast);
}
.wp .wp-person-head { margin: 0; }
.wp .wp-person-name {
  font-family: var(--wp-mono);
  font-weight: 700;
  font-size: 1.24rem;
  line-height: 1.35;
  letter-spacing: -0.02em;
  color: var(--wp-strong);
  margin: 0.15rem 0 0.9rem;
}
.wp .wp-person-body > :first-child { margin-top: 0; }
.wp .wp-person-body > :last-child { margin-bottom: 0; }
.wp .wp-person-body p {
  font-size: 0.95rem;
  line-height: 1.75;
  color: var(--wp-soft);
}
/* The facts, under the biography and across both columns, so the list has
   the whole plate to lay its two columns out in rather than the narrower
   one the prose sits in. */
.wp .wp-person-facts {
  grid-column: 1 / -1;
  margin-top: 1.4rem;
  padding-top: 1.2rem;
  border-top: 1px dashed var(--wp-faint);
}
/* Below the width at which a 13.5rem portrait and a readable measure both
   fit, the portrait goes above the name — and gets a cap, because a
   1280px-wide photograph as the first thing on a phone is a whole screen
   of face before the page says whose it is. */
@media (max-width: 720px) {
  .wp .wp-person { grid-template-columns: 1fr; gap: 0; }
  .wp .wp-person-shot {
    grid-row: auto;
    max-width: 10rem;
    margin-bottom: 1.3rem;
  }
  .wp .wp-person-facts { margin-top: 1.2rem; }
}

/* ---- a row of chips ----
   Several controls at the same level, wrapping. Used for the ways off a
   page: sign up, get in touch, the accounts elsewhere. */
.wp .wp-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
  align-items: center;
  /* The same row /topics draws as .tp-actions, with the same numbers. */
  margin: 1.6rem 0 0;
  padding: 0;
  list-style: none;
}

/* ---- specimens ----
   Example statements, shown so that somebody can judge the shape of them
   — three topic statements that split a room, three ways of phrasing the
   same question. Not a bulleted list: what is being displayed is the
   wording, so each one gets its own line and the dashed rule that divides
   a table's rows, and no marker competing with the first word. */
.wp .wp-specimens {
  list-style: none;
  margin: 0;
  padding: 0;
}
.wp .wp-specimens > li {
  padding: 0.75rem 0;
  font-size: 0.97rem;
  line-height: 1.7;
  color: var(--wp-strong);
}
.wp .wp-specimens > li + li { border-top: 1px dashed var(--wp-faint); }
.wp .wp-specimens > li:first-child { padding-top: 0; }
.wp .wp-specimens > li:last-child { padding-bottom: 0; }
/* Quoted rather than asserted: these are things somebody might say, and
   the marks say so without the page having to. */
.wp .wp-specimens > li::before { content: "\201C"; }
.wp .wp-specimens > li::after { content: "\201D"; }

/* ---- a quotation that is a <blockquote> ----
   The content sheet gives every blockquote on a templated page a 4px rule
   and italics. The rule is already this language's own (the note wins on
   specificity); the italics are not, and a whole quotation set in them is
   harder to read than the paragraph above it. */
.wp blockquote.wp-quote { font-style: normal; }

/* ---- facts whose names are figures ----
   A variant of the list above for the case where the left column is not a
   label but the finding itself — "nearly 5x", "51.5%", "-23%". Uppercase
   mono at label size makes a number look like a column head; these are the
   point of their own rows, so they take the size and the ink to match. */
.wp .wp-kv-num > dt {
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  text-transform: none;
  color: var(--wp-strong);
  line-height: 1.5;
  padding-top: 0.7rem;
}
.wp .wp-kv-num > dd { padding-top: 0.7rem; }

/* ---- a marked list ----
   A list whose items are advice rather than prose — the four things that
   move the progress meter, the three that do not. The browser's bullet is
   replaced by a mono mark so the list reads as furniture rather than as a
   paragraph somebody broke up.

   The kept list takes the accent, which is the accent doing what it does
   everywhere else here: pointing. The list of things not to do takes the
   page's own ink at the same weight — there is no danger colour on this
   site, and the eyebrow above it has already said which list this is. */
.wp .wp-marks {
  list-style: none;
  margin: 0;
  padding: 0;
}
.wp .wp-marks > li {
  position: relative;
  padding: 0 0 0 1.7rem;
  font-size: 0.95rem;
  line-height: 1.7;
}
.wp .wp-marks > li + li { margin-top: 0.7rem; }
.wp .wp-marks > li::before {
  content: "\2713";
  position: absolute;
  left: 0;
  top: 0;
  font-family: var(--wp-mono);
  font-weight: 700;
  font-size: 0.85rem;
  line-height: 1.9;
  color: var(--wp-accent);
}
.wp .wp-marks-no > li::before { content: "\00D7"; color: var(--wp-soft); }

/* ---- facts whose names run long ----
   "find common ground" does not fit the 6.5rem the names normally get, and
   a name that wraps to two lines beside a one-line value pulls the row out
   of shape. */
.wp .wp-kv-wide { grid-template-columns: minmax(11rem, auto) 1fr; }
@media (max-width: 640px) {
  .wp .wp-kv-wide { grid-template-columns: 1fr; }
  .wp .wp-kv-wide > dt { padding: 0.55rem 0 0; line-height: 1.5; }
  .wp .wp-kv-wide > dt:not(:first-of-type) + dd { border-top: 0; }
}
