/* Quinfinity, the reading pages.
 *
 * The home page is driven. These are read. That is the only difference the
 * design is allowed to have: same tokens, same gutter, same nav and footer,
 * same type. What changes is that the eye sets the pace instead of the scroll.
 *
 * Every measurement below is a ratio or a clamp, never a fixed pixel width, so
 * the page holds from a 220px phone to a 3440px monitor and at any text size
 * the reader chooses.
 */

.reading body,
body.reading { background: var(--g0); }

/* the same 2px rule the scene carries, so the pages read as one site */
.read-rule {
  position: fixed; left: 0; right: 0; top: 0; height: 2px;
  background: var(--line); z-index: 40;
}
.read-rule i {
  display: block; height: 100%; width: var(--p, 0%);
  background: var(--accent);
}

/* the same --frame and --edge every other block on the site uses, so the nav,
   the article and the footer share one left edge. The CONTENT inside is still
   measure limited (62ch of body copy, 34rem of form), so a wide frame does not
   mean a wide line. */
.read {
  padding-inline: var(--edge);
  padding-bottom: var(--s6);
  max-width: var(--frame);
  margin: 0 auto;
}

/* ------------------------------------------------------------------ the top
 * One screen of held breath before the argument starts. The kicker sits on the
 * same baseline grid as the chapter label on the home page.
 */
.read-top {
  padding: clamp(2.5rem, 9vh, 7rem) 0 clamp(2.5rem, 7vh, 5rem);
  border-bottom: 1px solid var(--line);
  margin-bottom: clamp(2.5rem, 6vh, 4.5rem);
}
.read-kicker {
  color: var(--ink-2);
  margin-bottom: clamp(1rem, 3vh, 2rem);
}
.read-h {
  font-size: var(--t-hero);           /* the 64px evidence ceiling, shared */
  line-height: 1.04;
  letter-spacing: -.024em;
  font-weight: 500;
  font-variation-settings: "wght" 520;
  margin: 0 0 clamp(1rem, 2.6vh, 1.75rem);
  max-width: 18ch;
  overflow-wrap: break-word;
}
.read-stand {
  font-size: clamp(1.0625rem, min(1.15vw, 2.3vh), 1.75rem);
  line-height: 1.5;
  max-width: 54ch;
  margin: 0;
  color: var(--ink);
}

/* ----------------------------------------------------------------- the grid
 * An index that stays with you, and a column that never grows past a readable
 * measure no matter how wide the window gets. Wide screens get more margin,
 * not longer lines.
 */
.read-grid {
  display: grid;
  grid-template-columns: minmax(12rem, 17rem) minmax(0, 1fr);
  gap: clamp(2rem, 6vw, 6rem);
  align-items: start;
}

.read-ix { position: sticky; top: clamp(4.5rem, 12vh, 7rem); }
.read-ix > .k { color: var(--ink-2); margin-bottom: var(--s2); }
.read-ix ol { list-style: none; margin: 0; padding: 0; display: grid; gap: .1rem; }
.read-ix a {
  display: grid; grid-template-columns: 2.1rem minmax(0, 1fr);
  gap: .35rem; align-items: baseline;
  padding: .42rem 0;
  font-size: clamp(.8125rem, .62vw, 1.0625rem); line-height: 1.35;
  color: var(--ink-2); text-decoration: none;
  border-top: 1px solid transparent;
  transition: color .2s var(--ease);
}
.read-ix li + li a { border-top-color: var(--line); }
.read-ix .ix { font-variant-numeric: tabular-nums; font-size: var(--t-tech); letter-spacing: .08em; }
.read-ix .it { overflow-wrap: break-word; }
.read-ix a:hover,
.read-ix a:focus-visible { color: var(--ink); }
.read-ix a[aria-current="true"] { color: var(--ink); font-variation-settings: "wght" 560; }
/* The active item is marked with an accent RULE under its number, not accent
   text. The accent measures 6.30:1 on white and 5.56:1 on the dark ground at
   11px, both under the 7:1 floor this site holds small text to. A box-shadow is
   a fill, has no contrast floor, and adds no height to the row. */
.read-ix a[aria-current="true"] .ix { box-shadow: 0 2px 0 var(--accent); }

.read-body { min-width: 0; display: grid; gap: clamp(2.5rem, 7vh, 5rem); }

/* ------------------------------------------------------------- the sections
 * The number is set large and low-contrast behind the heading, which is the
 * only piece of decoration on these pages. It carries the depth: it sits on a
 * plane behind the text and answers the pointer a fraction slower than the
 * cursor moves, so the page has parallax without anything sliding around.
 */
.sec {
  position: relative;
  --nw: clamp(3rem, 5.2vw, 6rem);       /* the number's own gutter */
  padding-left: var(--nw);
}
.sec-n {
  position: absolute; left: 0; top: -.28em;
  width: calc(var(--nw) - .9rem);
  text-align: right;                     /* so the digits hang off the text edge */
  margin: 0;
  font-size: clamp(1.75rem, 3.2vw, 3rem);
  line-height: 1;
  letter-spacing: -.04em;
  font-variant-numeric: tabular-nums;
  font-variation-settings: "wght" 300;
  color: var(--ink);
  opacity: .12;
  pointer-events: none;
  transition: opacity .4s var(--ease);
}
.sec[data-in="1"] .sec-n { opacity: .17; }
.sec-h {
  font-size: clamp(1.25rem, min(1.55vw, 3.1vh), 2.25rem);
  line-height: 1.18;
  letter-spacing: -.016em;
  font-weight: 500;
  font-variation-settings: "wght" 540;
  margin: 0 0 clamp(.7rem, 1.6vh, 1rem);
  /* Section headings are short on purpose and must not wrap: a two word
     heading broken over two lines reads as a mistake. 40ch is well past the
     longest one, and `balance` keeps any that do wrap from leaving one orphan
     word on the second line. */
  max-width: 40ch;
  text-wrap: balance;
  overflow-wrap: break-word;
}
.sec-b {
  margin: 0;
  /* 17px on a 27 inch monitor is a squint. The copy grows with the screen; the
     measure does not, so longer text means a wider column of the SAME number of
     characters, not more characters per line. */
  font-size: clamp(1.0625rem, min(.92vw, 1.9vh), 1.4rem);
  line-height: 1.62;
  max-width: 62ch;                       /* lands near 70 characters, not 79 */
  color: var(--ink);
  overflow-wrap: break-word;
}

/* entrance: the only thing that moves on arrival, and it moves once */
.motion .sec,
.motion .read-end {
  opacity: 0;
  transform: translate3d(0, 1.1rem, 0);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}
.motion .sec[data-in="1"],
.motion .read-end[data-in="1"] { opacity: 1; transform: none; }

.read-end { margin: clamp(1rem, 3vh, 2rem) 0 0; padding-left: 0; }
/* only inside the article body, where it lines up under the section text.
   On 404 there are no sections, so the indent had nothing to line up with. */
.read-body .read-end { padding-left: clamp(3rem, 5.2vw, 6rem); }
.read-end .out { font-size: var(--t-lede); }

.read-404 .read-top { border-bottom: 0; }
.read-404 .read-stand { max-width: 58ch; }

/* ----------------------------------------------------------------- the form
 * Plain fields, one column, generous target sizes. Nothing about a contact
 * form should be clever.
 */
.form { display: grid; gap: clamp(1.1rem, 2.6vh, 1.6rem); max-width: 34rem; }
.fld { display: grid; gap: .45rem; }
.fld label {
  font-size: var(--t-tech); letter-spacing: .11em; text-transform: uppercase;
  color: var(--ink);
}
.fld input,
.fld textarea {
  font: inherit; font-size: var(--t-body); line-height: 1.5;
  color: var(--ink); background: var(--g0);
  /* --line is a hairline for dividing text, and it measures under the 3:1 that
     a user interface boundary needs. Here the border is the only thing telling
     you where the field is, so it uses the text token instead. */
  border: 1px solid var(--ink-2);
  border-radius: 0;
  padding: .7rem .8rem;
  width: 100%;
  min-width: 0;
  transition: border-color .18s var(--ease);
}
.fld textarea { resize: vertical; min-height: 7rem; }
.fld input:focus,
.fld textarea:focus { outline: 0; border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }
.fld input:focus-visible,
.fld textarea:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

.fld-go { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s3); }
.go {
  font: inherit; font-size: var(--t-tech); letter-spacing: .11em; text-transform: uppercase;
  background: var(--ink); color: var(--ground);
  border: 1px solid var(--ink); border-radius: 0;
  padding: .8rem 1.4rem; cursor: pointer;
  transition: background .18s var(--ease), color .18s var(--ease);
}
.go:hover { background: transparent; color: var(--ink); }
.form-alt { color: var(--ink-2); text-transform: none; letter-spacing: 0; font-size: .8125rem; }
.form-alt a { color: var(--ink); overflow-wrap: anywhere; }
.form-said {
  margin: 0; font-size: var(--t-body); line-height: 1.6; max-width: 54ch;
  border-left: 2px solid var(--accent); padding-left: var(--s2);
}

/* ------------------------------------------------------------- narrower now
 * The index stops being a sidebar and becomes a lid: still there, still
 * linked, no longer competing for width with the text.
 */
@media (max-width: 64rem) {
  .read-grid { grid-template-columns: minmax(0, 1fr); gap: clamp(1.75rem, 5vh, 2.75rem); }
  .read-ix {
    position: static;
    border-top: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
    padding: var(--s2) 0;
  }
  .read-ix ol { grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); gap: 0 var(--s3); }
  .read-ix li + li a { border-top-color: transparent; }
  /* stacked, the number sits above the heading. Its size and the space it is
     given are ONE value, so no width can slide them into each other. */
  .sec { --nf: clamp(1.75rem, 6vw, 2.5rem); padding-left: 0; padding-top: calc(var(--nf) + .8rem); }
  .sec-n { top: 0; width: auto; text-align: left; font-size: var(--nf); }
  .read-end { padding-left: 0; }
}

@media (max-width: 40rem) {
  .read-h { max-width: none; }
  .read-ix ol { grid-template-columns: minmax(0, 1fr); }
}

/* very small, or a reader who has zoomed a long way in */
@media (max-width: 22rem) {
  .read { padding-left: 1rem; padding-right: 1rem; }
  .read-stand, .sec-b { font-size: 1rem; }
  .go { width: 100%; }
}

/* short windows: the sticky index would eat the whole screen */
@media (max-height: 34rem) {
  .read-ix { position: static; }
}

@media (prefers-reduced-motion: reduce) {
  .motion .sec,
  .motion .read-end { opacity: 1; transform: none; transition: none; }
}

/* ------------------------------------------------------------- the record
 * A dated list, not prose. The date sits in its own track so every entry
 * begins on the same two lines and the eye can run straight down the column
 * without hunting for where each one starts.
 */
.rec { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; }
.rec-i {
  display: grid;
  grid-template-columns: minmax(6.5rem, 9rem) minmax(0, 1fr);
  grid-template-areas: "when title" "when org" "when note";
  column-gap: clamp(1rem, 2.4vw, 2.25rem);
  row-gap: .18rem;
  padding: clamp(.9rem, 2vh, 1.3rem) 0;
  border-top: 1px solid var(--line);
}
.rec-i:last-child { border-bottom: 1px solid var(--line); }
.rec-when {
  grid-area: when; margin: 0;
  font-size: var(--t-tech); letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-2); line-height: 1.7;
  font-variant-numeric: tabular-nums;
  overflow-wrap: break-word;
}
.rec-t {
  grid-area: title; margin: 0;
  font-size: clamp(1rem, min(1.05vw, 2.1vh), 1.35rem);
  line-height: 1.3; letter-spacing: -.01em;
  font-weight: 500; font-variation-settings: "wght" 540;
  overflow-wrap: break-word;
}
.rec-org {
  grid-area: org; margin: 0;
  font-size: clamp(.875rem, min(.82vw, 1.64vh), 1.0625rem);
  line-height: 1.45; color: var(--ink-2);
  overflow-wrap: break-word;
}
.rec-note {
  grid-area: note; margin: .35rem 0 0;
  font-size: clamp(.9375rem, min(.86vw, 1.72vh), 1.125rem);
  line-height: 1.55; max-width: 58ch;
  overflow-wrap: break-word;
}

/* The first entry of the first group is the one that matters most. It is
   marked with a RULE, not with coloured text: the accent measures 6.30:1 at
   11px, under the 7:1 floor this site holds small text to, and that is exactly
   why it was taken out of text everywhere else. A fill has no such floor. */
#s01 .rec-i:first-child { border-top: 2px solid var(--accent); }
#s01 .rec-i:first-child .rec-t { font-variation-settings: "wght" 620; }

@media (max-width: 34rem) {
  /* the date stops being a column and becomes a label above the entry */
  .rec-i {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "when" "title" "org" "note";
    row-gap: .22rem;
  }
  .rec-when { margin-bottom: .1rem; }
}

/* "optional" sits at the far end of the field, so nobody feels obliged to fill
   it in. As an inline span it dropped to a second line under a long label,
   which reads like part of the question rather than a note about it. */
.fld label {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: .75rem;
}
.fld label .opt {
  flex: 0 0 auto;
  letter-spacing: .06em;
  text-transform: none;
  color: var(--ink-2);
}


/* A field the form has rejected. Marked with weight and a rule, not a hue. */
.fld [aria-invalid="true"] { border-width: 2px; border-color: var(--ink); }
.form-said { border-left-width: 3px; }
