/* prose.css — the reading pages only.
 *
 * Loaded after styles.css and never by the tool page. styles.css resets
 * h1/h2/h3 margins to 0 because every heading on the tool page is positioned by
 * its own layout; prose has no layout to be positioned by, so the vertical
 * rhythm has to be put back here rather than changed there.
 *
 * The marker voice is kept for headings and spent nowhere else. On a page that
 * is mostly running text, setting body copy in the display face is what makes a
 * zine look like a ransom note.
 *
 * THE SHEET — revised 19 Aug 2026 at the owner's request.
 *
 * This file used to argue that an article must not sit on a sheet, because a
 * surface that tall reads as a wall whatever is written on it. The article now
 * sits on one, and the objection is answered by what is printed on the paper
 * rather than by refusing the paper: the sheet is ruled at 28px, the same pitch
 * and the same recipe the tool page rules its paste sheet at, and the ruling
 * cuts the height into rows a reader can measure progress against. Same stock
 * on both surfaces — the sheet you write on, and the sheet the editor already
 * wrote on.
 *
 * Everything in the article is therefore sized in whole rules. Line heights are
 * one rule or two, every vertical margin is a multiple of one, and the ruling is
 * phased from the sheet's own border-box top so nothing above it can knock it
 * out. Add a block here and it owes the grid a multiple: half a rule puts every
 * line beneath it between the lines instead of on them.
 */

.prose-page main {
  max-width: var(--wrap);
  margin-inline: auto;
  padding: 0 var(--pad);
}

/* Yellow flags a phrase, and a reader dragging across a sentence is doing
   exactly that — the same job it already has on a hovered link. This is the
   page people copy out of, and the browser's own blue belongs to no world. */
.prose-page ::selection { background: var(--hl-yellow); color: var(--ink); }

/* --- the masthead's second slot ----------------------------------------- */
/* The tool page puts the check meter here. A prose page has no count to show,
   so the space carries the only thing a reader of this page might want next.
   Same double stroke as .btn, at the smaller tier: 2.5px inner on sketch-a,
   2px outer inset -6px on sketch-b. Never a block shadow — this world draws a
   second line where another world would offset a shadow. */
.prose-cta {
  position: relative;
  font-family: var(--font-marker);
  font-size: var(--t-lg);
  font-weight: 700;
  line-height: 1;
  color: var(--ink);
  background: var(--hl-yellow);
  text-decoration: none;
  padding: .5em 1.1em;
  border: 2.5px solid var(--ink);
  border-radius: var(--sketch-a);
  box-shadow: var(--shadow-key);
  transition: transform .18s var(--ease);
}
.prose-cta::after {
  content: "";
  position: absolute; inset: -6px;
  border: 2px solid var(--ink);
  border-radius: var(--sketch-b);
  opacity: .38;
  transition: opacity .18s var(--ease);
}
.prose-cta:hover { transform: rotate(-.8deg) translateY(-2px); }
.prose-cta:hover::after { opacity: .7; }

/* --- the ruled sheet ----------------------------------------------------- */

.prose {
  /* One pitch governs the ruling and every line of type standing on it. */
  --rule-pitch: 28px;
  /* Tinted from the paper, never grey, and pitched to be read past rather than
     read: at this weight the lines describe the surface and never the words. */
  --rule-faint: rgba(106, 93, 72, .13);
  --rule-margin: transparent;

  /* Where a baseline belongs on a rule. Body type lands 20px down its 28px
     row, which puts the rule just under the baseline and lets descenders cross
     it, and every other line on this page is seated to match.

     The marker face needs help to get there. Shantell Sans carries 1.34em of
     normal leading and 1.018em of ascent, so its baseline sits .348em below the
     centre of whatever line box it is given; at display sizes that is enough to
     drag the rule up through the x-height, which is the one place a rule must
     never fall. A heading is therefore nudged down by the difference and the
     nudge is taken straight back out of the margin under it, so the block stays
     a whole number of rules however the size clamp resolves. Figtree's own drop
     is .323em, small enough at reading sizes to need no correction. */
  --marker-drop: .348;
  --rule-seat: 20px;

  /* Ruled paper decides how big you are allowed to write on it. A display line
     has to stand a whole number of rules tall, and its ink has to fit inside
     them, which leaves two usable bands for the marker face: about 21-27px on
     one rule, and about 38-53px on two. Between those a heading either collides
     with the line under it or strands its own second line half a rule away, so
     the two heading steps are pinned to the bands rather than borrowed from the
     tool page's ramp, which was drawn for a page with no lines on it. */
  --t-prose-title: clamp(2.4rem, 5.6vw, 3rem);
  --t-prose-head:  clamp(1.5rem, 2.9vw, 1.65rem);

  /* The vertical margin rule, and the writing that starts to the right of it.
     Both collapse to nothing until the viewport can spare a margin. */
  --margin-x: 0px;
  --pad-x: clamp(1.35rem, 3vw, 3.25rem);
  --pad-l: var(--pad-x);
  --pad-t: 56px;
  --pad-b: 84px;

  /* Capped in characters, not pixels, like every other reading region here.
     60ch, the bottom of the documented prose range, not the top: `ch` is the
     advance of "0", which is narrower than this font's average lowercase, so
     68ch measured out at 82 real characters per line. 60ch lands at ~72, which
     is inside both the system's range and a comfortable measure. The sheet is
     that measure plus its margins, so the paper grows and the line does not. */
  max-width: calc(60ch + var(--pad-l) + var(--pad-x));
  margin: clamp(.75rem, 2vw, 1.75rem) auto clamp(2rem, 5vw, 4rem);
  padding: var(--pad-t) var(--pad-x) var(--pad-b) var(--pad-l);

  background-color: var(--sheet);
  background-image:
    linear-gradient(to right,
      transparent 0 var(--margin-x),
      var(--rule-margin) var(--margin-x) calc(var(--margin-x) + 1px),
      transparent calc(var(--margin-x) + 1px)),
    repeating-linear-gradient(to bottom,
      transparent 0 calc(var(--rule-pitch) - 1px),
      var(--rule-faint) calc(var(--rule-pitch) - 1px) var(--rule-pitch));
  /* Phased from the sheet's own top edge, so the padding cannot shift the
     ruling, and tiled one rule at a time rather than stretched over the whole
     article: at default sizing the gradient would be an image as tall as the
     page, which is several million pixels for the compositor to hold for what
     is really a 28px repeat. */
  background-origin: border-box;
  background-position: 0 0;
  background-size: 100% var(--rule-pitch);
  /* The one surface on this site that lifts is now two, and both lift the same
     way: the warm offset-and-blur sheet shadow, never a second frame. */
  box-shadow: var(--shadow-sheet);
}

/* Wide enough to spend width on a margin, so the paper gets the vertical rule
   every ruled pad has, and the note beside the text moves into the space it
   opens — written in the margin rather than merely near it. */
@media (min-width: 900px) {
  .prose {
    --margin-x: 74px;
    --pad-l: 92px;
    --pad-x: clamp(2.25rem, 3.4vw, 3.5rem);
    --pad-t: 84px;
    --pad-b: 112px;
    --rule-margin: rgba(106, 93, 72, .22);
  }
}

/* The swipe lands once per page and only under the title. It is the section
   device on the tool page, and it keeps its meaning by staying scarce: put it
   under every h2 of a long article and it becomes a rule, not a mark. */
.prose > h1 {
  --h-size: var(--t-prose-title);
  font-family: var(--font-marker);
  font-size: var(--h-size);
  /* Two rules to the line. A hand writing this big on ruled paper takes two,
     and the second is what leaves the swipe room to sit under each line. */
  line-height: calc(var(--rule-pitch) * 2);
  letter-spacing: -.02em;
  padding-top: calc(var(--rule-seat) - var(--marker-drop) * var(--h-size));
  margin: 0 0 calc(var(--rule-pitch) - var(--rule-seat) + var(--marker-drop) * var(--h-size));
  text-wrap: balance;
}
/* Inline, and cloned per fragment, so a title that wraps is swiped line by
   line at each line's own width rather than banded to the widest one. */
.prose > h1 .swipe {
  display: inline;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
  padding-bottom: .1em;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 40' preserveAspectRatio='none'%3E%3Cpath d='M3 8Q30 4 60 7T124 6T196 9Q200 22 194 34Q150 37 100 34T6 33Q0 19 3 8Z' fill='%2300C7B7'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-size: 100% .13em;
  background-position: 0 100%;
}

.prose > h2 {
  --h-size: var(--t-prose-head);
  font-family: var(--font-marker);
  font-size: var(--h-size);
  /* One rule to the line, so a section head that wraps stays one heading
     instead of two lines a rule apart. A line of type set this near its own
     leading seats half a rule lower than a double-height one does. */
  line-height: var(--rule-pitch);
  letter-spacing: -.015em;
  padding-top: calc(var(--rule-seat) + var(--rule-pitch) / 2 - var(--marker-drop) * var(--h-size));
  /* The space above a section is the padding plus a clear rule; the space below
     is what is left of two rules once the seat is paid for. More above than
     below, so the heading belongs to the text under it. */
  margin: var(--rule-pitch) 0 calc(var(--rule-pitch) * 2 - var(--rule-seat) - var(--rule-pitch) / 2 + var(--marker-drop) * var(--h-size));
  text-wrap: balance;
}

.prose > h3 {
  font-size: var(--t-xl);
  font-weight: 700;
  /* One rule, so a sub-head is a line of the writing rather than a break in it,
     and its paragraph starts on the very next line. */
  line-height: var(--rule-pitch);
  margin: var(--rule-pitch) 0 0;
  text-wrap: balance;
}

.prose > p {
  line-height: var(--rule-pitch);
  margin: 0 0 var(--rule-pitch);
}

/* The opening paragraph carries the answer, because a reader who arrived from
   a search result decides in about four seconds whether this page has it. */
.prose > h1 + p {
  font-size: var(--t-lg);
  line-height: var(--rule-pitch);
}

.prose > ul,
.prose > ol {
  line-height: var(--rule-pitch);
  margin: 0 0 var(--rule-pitch);
  padding-left: 1.35rem;
}
/* A blank rule between items, the same gap paragraphs get. Items packed onto
   consecutive rules are what a written list looks like, but half of these run
   to a second line, and with nothing between them the reader has only the dash
   to tell a wrapped line from the next item. A part-rule gap is not available:
   it would push every item after the first off the lines. */
.prose > ul li,
.prose > ol li { margin: 0 0 var(--rule-pitch); }
.prose > ul { list-style: none; padding-left: 1.2rem; }
.prose > ul li { position: relative; }
/* A short drawn dash, in tinted ink. Not a highlighter: yellow flags a phrase,
   pink marks the strongest signal, teal marks what reads human. A bullet is
   none of those jobs, and spending a pigment on punctuation is how the three
   stop meaning anything. */
.prose > ul li::before {
  content: "";
  position: absolute;
  left: -1.2rem; top: .72em;
  width: .62rem; height: 2px;
  background: var(--ink-soft);
  border-radius: var(--r-hair);
  transform: rotate(-4deg);
}

.prose a {
  color: var(--ink);
  text-decoration-line: underline;
  text-decoration-color: var(--ink-soft);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
  transition: text-decoration-color .16s var(--ease);
}
/* Hovering a link is momentarily flagging a phrase, which is the yellow's
   actual job, so it is the one highlighter that belongs on a link. */
.prose a:hover { text-decoration-color: var(--hl-yellow); }

.prose strong { font-weight: 700; }

.prose code {
  font-family: var(--font-mono);
  font-size: .9em;
  background: var(--paper-deep);
  padding: .1em .35em;
  border-radius: var(--r-hair);
}

/* Pressed paper, the same block the caveat is set on. Not a coloured rule down
   the left edge: this world marks an aside by changing the paper under it. It
   is opaque, so it covers the ruling for its height the way a slip laid on the
   page would, and its own height is whole rules so the lines pick up in phase
   underneath. */
.prose blockquote {
  margin: var(--rule-pitch) 0;
  padding: var(--rule-pitch);
  background: var(--paper-deep);
  line-height: var(--rule-pitch);
}
.prose blockquote p { margin: 0; }

.prose hr {
  border: 0;
  border-top: 2px dashed var(--rule);
  margin: 0 0 calc(var(--rule-pitch) - 2px);
}

/* --- a print laid on the sheet ------------------------------------------- */
/* The one object this world admits that it did not draw or set: a picture,
   which arrives with its own palette and its own idea of an edge. It is not
   allowed to behave like a banner. It is handled the way the desk would handle
   it — a print on the desk's own warmer stock, laid on the ruled sheet at a
   slight angle and lifted on the same shadow the paste sheet uses, so the
   reader meets an object somebody put there rather than an image the template
   dropped in. That holds whatever the picture is: it is what lets a dark render
   and a warm line drawing sit in the same slot without either being recoloured
   toward the palette.

   The print carries no caption. One was tried and taken out: under a paragraph
   that has just answered the page's question in words, a line of marker under
   the picture only says it again. The alt text does the describing. */

.prose > .prose-print {
  margin: calc(var(--rule-pitch) * 2) 0;
}

.prose-print-paper {
  /* The picture measures itself against this box, not the viewport, so the
     trimming below survives any column width. */
  container-type: inline-size;
  /* Half a rule of print margin on every side, which is a whole rule across the
     pair and keeps the print itself standing in whole rules. */
  padding: calc(var(--rule-pitch) / 2);
  background: var(--paper);
  box-shadow: var(--shadow-sheet);
  transform: rotate(-1.1deg);
}

.prose-print img {
  display: block;
  width: 100%;
  /* The picture's own proportions, handed over by the build. */
  aspect-ratio: var(--print-w) / var(--print-h);
  object-fit: cover;
  border-radius: var(--r-hair);
  /* What stands in the frame until the picture lands. Pressed paper rather than
     a grey box: an empty frame on this page is still paper. */
  background: var(--paper-deep);
}

/* Trimmed to a whole number of rules. The picture's own ratio is not one, and a
   picture that is not would land every line of the article beneath it half a
   rule off the ruling — the one thing this page cannot do. The trim is at most
   half a rule in either direction, taken by `cover` off the edges of a subject
   that sits well inside the frame. Where `round()` is missing the picture keeps
   its true ratio and the ruling under it goes out of phase, which is the
   graceful half of this trade rather than the good half. */
@supports (height: round(nearest, 10px, 3px)) {
  .prose-print img {
    aspect-ratio: auto;
    height: round(nearest, calc(100cqw * var(--print-h) / var(--print-w)), var(--rule-pitch));
  }
}

/* --- margin note --------------------------------------------------------- */
/* The editor's handwriting beside the text, same grammar as the notes on the
   tool page: a drawn curl-arrow in tinted ink and marker lettering. Available
   to writers as raw HTML in the markdown. It exists because a long article of
   nothing but paragraphs is the wall again, and this system's answer to a wall
   is not a card — it is something written in the margin. */
.prose-note {
  display: grid;
  grid-template-columns: 40px 1fr;
  align-items: start;
  gap: .7rem;
  margin: calc(var(--rule-pitch) * 2) 0;
  font-family: var(--font-marker);
  font-size: var(--t-base);
  line-height: var(--rule-pitch);
  color: var(--ink);
}
.prose-note svg { width: 40px; height: 22px; color: var(--ink-soft); margin-top: 4px; }
.prose-note b { font-weight: 700; }

/* Once the sheet has a margin, the note takes it: the arrow crosses into the
   space left of the rule and the words stay on the writing line, so the note
   reads as something added beside the text rather than a row inside it. */
@media (min-width: 900px) {
  .prose-note {
    margin-left: calc(-1 * var(--pad-l));
    grid-template-columns: var(--pad-l) 1fr;
    gap: 0;
  }
  .prose-note svg { justify-self: center; }
}

/* --- the way out --------------------------------------------------------- */
/* Every prose page ends by handing the reader back to the tool. This is the
   only link on the page that is allowed to look like a button, and it is the
   same button the tool page ships. */

/* Three rules tall with the button centred in them, so the button keeps the
   proportions it has everywhere else and the line under it still lands on a
   rule. */
.prose-end {
  display: flex;
  align-items: center;
  height: calc(var(--rule-pitch) * 3);
  margin: var(--rule-pitch) 0 0;
}

.prose-end-link {
  position: relative;
  display: inline-block;
  font-family: var(--font-marker);
  font-size: var(--t-xl);
  font-weight: 700;
  line-height: 1;
  color: var(--ink);
  background: var(--hl-yellow);
  text-decoration: none;
  padding: .78em 1.5em;
  border: 2.5px solid var(--ink);
  border-radius: var(--sketch-a);
  box-shadow: var(--shadow-key);
  transition: transform .18s var(--ease);
}
.prose-end-link::after {
  content: "";
  position: absolute; inset: -6px;
  border: 2px solid var(--ink);
  border-radius: var(--sketch-b);
  opacity: .38;
  transition: opacity .18s var(--ease);
}
.prose-end-link:hover { transform: rotate(-.8deg) translateY(-2px); }
.prose-end-link:hover::after { opacity: .7; }

.prose-updated {
  font-size: var(--t-sm);
  line-height: var(--rule-pitch);
  color: var(--ink-soft);
  margin: 0;
}

@media (max-width: 600px) {
  /* The note's arrow column costs more than it returns beside a full-width
     column. With the arrow gone the row holds one item, so the gap never
     applies and the note stays on the rules. */
  .prose-note { grid-template-columns: 1fr; gap: .3rem; }
  .prose-note svg { display: none; }
}
