/* ============================================================
   article.css — the fourteen reading pages.

   Those pages carried fifty-five classes between them, most invented for
   a single page: letter, index-slip, day-track, overlap-bridge, specimen.
   That is the "every section its own thing" problem in one list, and
   restyling fifty-five names one at a time would only move it.

   So the default here is deny. Everything inside the column is raw text —
   no surface, no frame, no indent, no caps — and an element becomes an
   object only by being named below. A class nobody styled lands on the
   law instead of off it, which is the opposite of how the site got here.

   Load order is tokens, chrome, light, article.
   ============================================================ */

/* ------------------------------------------------------------------
   Deny by default
   ------------------------------------------------------------------ */

/* :where() keeps this at zero specificity, so every rule after it wins
   without needing to shout. */
.read :where(div, section, article, header, aside, p, ol, ul, li, dl, dt, dd,
             blockquote, figure, figcaption, h2, h3, h4, h5, span, em, strong, small) {
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  text-transform: none;
  letter-spacing: normal;
  padding: 0;
}

/* Grids were how a page used to make a passage look like a thing. The
   content reads top to bottom; so does the page. */
.read :where(.story-grid, .split, .two-feelings, .day-track, .overlap,
             .contrast-lines, .indexed, .table-wrap, .journal-example, .fieldnote) {
  display: block;
}

/* ------------------------------------------------------------------
   The column
   ------------------------------------------------------------------ */

main.read {
  /* The site's body size is 17px, for the homepage's poster copy. Inside a
     reading column everything inherits 16 unless a rule says otherwise, so a
     bare <span> or a <summary> does not come out a pixel larger than the
     text around it. */
  font-size: var(--t-text);
  line-height: 1.8;
  max-width: var(--measure);
  margin: 0 auto;
  padding: clamp(56px, 9vh, 88px) 28px clamp(72px, 12vh, 112px);
}

.read .hero { display: block; margin-bottom: 44px; }

.read h1 {
  font-size: var(--t-head);
  line-height: 1.04;
  letter-spacing: -0.035em;
  font-weight: 600;
  color: var(--lum-1);
  margin: 0 0 28px;
  text-wrap: balance;
}

/* ------------------------------------------------------------------
   One size for everything else; weight and luminance do the rest
   ------------------------------------------------------------------ */

.read small,
.read caption,
.read summary,
.read p,
.read li,
.read dd,
.read blockquote,
.read figcaption {
  font-size: var(--t-text);
  line-height: 1.8;
  color: var(--lum-3);
  margin: 0 0 20px;
  text-wrap: pretty;
}

.read .lede { color: var(--lum-2); }

.read h2,
.read h3,
.read h4,
.read dt,
.read .story-label,
.read .paper-label,
.read .salutation {
  font-size: var(--t-text);
  line-height: 1.8;
  font-weight: 600;
  color: var(--lum-1);
  margin: 56px 0 20px;
}

.read h3,
.read h4,
.read dt,
.read .story-label,
.read .paper-label { margin-top: 36px; }

.read .section > :first-child,
.read .hero > :first-child { margin-top: 0; }

/* The quiet register: provenance, limits, the aside that says a thing is
   optional. Never a different size — only dimmer. */
.read .sources,
.read .privacy-note,
.read .caption,
.read .story-note,
.read .letter-dates,
.read .signature,
.read small { color: var(--lum-4); }

/* Worked examples run in the flow, set closer together because the lines
   belong to each other and a shade brighter because they are the evidence.
   This is the rule that replaces every callout the pages used to draw. */
.read .story-line,
.read .note-lines li,
.read .contrast-lines p,
.read .specimen p,
.read .entry-slip p,
.read .index-slip p,
.read .letter p,
.read .mood-cell,
.read blockquote {
  color: var(--lum-e);
  margin-bottom: 4px;
}

.read .note-lines,
.read .specimen,
.read .letter,
.read .contrast-lines { margin: 0 0 20px; }

.read ol,
.read ul { padding-left: 1.1em; }
.read .note-lines,
.read .article-nav,
.read .related { list-style: none; padding-left: 0; }

.read strong { color: var(--lum-1); font-weight: 600; }

.read a {
  color: var(--lum-1);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
  text-decoration-color: rgba(255, 255, 255, 0.3);
  transition: text-decoration-color 0.18s var(--ease-soft);
}

.read a:hover,
.read a:focus-visible { text-decoration-color: var(--lum-1); }


/* The download button is an object, not a link in the prose. It carries the
   one inverted surface on this site — a white face with a dark label — and
   the rule above weighs 0,1,1 against .pill's 0,1,0, so without naming it
   here the label is painted white on white and the button goes blank. */
.read a.pill {
  color: var(--btn-label);
  text-decoration: none;
}

.read .section { margin-top: 56px; }

/* ------------------------------------------------------------------
   Link rows — one wrapping group, never a stack of navigations
   ------------------------------------------------------------------ */

.read .article-nav,
.read .related {
  display: flex;
  flex-wrap: wrap;
  gap: 0 26px;
  margin: 0;
}

.read .article-nav a,
.read .related a {
  font-size: var(--t-text);
  line-height: 1.8;
}

/* A related link carries a description; it sets on its own line, quiet. */
.read .related a { display: block; }
.read .related small {
  display: block;
  font-size: var(--t-text);
  line-height: 1.8;
}

.read .related {
  gap: 24px 26px;
  padding-top: 36px;
  border-top: 1px solid var(--hair);
  margin-top: 56px;
}

/* ------------------------------------------------------------------
   Objects — only where the product is doing something
   ------------------------------------------------------------------ */

.read .tool,
.read .download-sheet,
.read .share-object {
  border: 1px solid var(--card-line);
  border-radius: 22px;
  padding: 24px;
  margin: 36px 0;
  transition: border-color 0.22s var(--ease-soft);
}

.read .tool:focus-within { border-color: var(--card-line-hi); }

.read .tool label,
.read .download-sheet h2,
.read .share-object .story-label {
  display: block;
  font-size: var(--t-text);
  line-height: 1.8;
  font-weight: 600;
  color: var(--lum-1);
  margin: 0 0 10px;
}

.read .tool textarea,
.read .tool select,
/* These inputs carry no type attribute at all, so [type="text"] misses
   them and the browser paints them white on a black page. */
.read .tool input:not([type="checkbox"]):not([type="radio"]):not([type="range"]) {
  width: 100%;
  font-family: inherit;
  font-size: var(--t-text);
  line-height: 1.8;
  color: var(--lum-1);
  background: none;
  border: 1px solid var(--card-line);
  border-radius: 14px;
  padding: 10px 14px;
  transition: border-color 0.22s var(--ease-soft);
}

.read .tool textarea { min-height: 140px; resize: vertical; }
/* A field and the label of the NEXT field were touching, so each
   label read as belonging to the box under it. */
.read .tool :is(input, textarea, select) { margin-bottom: 24px; }
.read .tool label { margin-top: 4px; }
.read .tool textarea::placeholder,
.read .tool input::placeholder { color: #555; }
.read .tool :is(textarea, input, select):focus-visible {
  outline: none;
  border-color: var(--card-line-hi);
}

.read button,
.read .jump,
.read .cta a {
  display: inline-block;
  font-family: inherit;
  font-size: var(--t-text);
  line-height: 1.8;
  color: var(--lum-1);
  background: none;
  border: 1px solid var(--card-line);
  border-radius: 999px;
  padding: 8px 18px;
  margin-top: 16px;
  text-decoration: none;
  cursor: pointer;
  transition: border-color 0.22s var(--ease-soft);
}

.read button:hover,
.read .jump:hover,
.read .cta a:hover,
.read button:focus-visible { border-color: var(--card-line-hi); }

.read .result {
  margin-top: 24px;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.read .result :where(div, li) { margin-bottom: 4px; color: var(--lum-e); }

.read .download-sheet { display: block; }

/* ------------------------------------------------------------------
   The figure — an image is a thing, so it keeps its edges
   ------------------------------------------------------------------ */

.read figure { margin: 36px 0; }
.read figure img,
.read .hero-art {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 16px;
}
.read figcaption { margin: 14px 0 0; color: var(--lum-4); }

/* A table is data; it may have hairlines, because without them the rows
   stop being rows. */
.read table { width: 100%; border-collapse: collapse; }
.read :is(th, td) {
  font-size: var(--t-text);
  line-height: 1.8;
  font-weight: 400;
  color: var(--lum-3);
  text-align: left;
  /* A row is read from its first line; centring makes a short cell float
     beside a long one once the column narrows on a phone. */
  vertical-align: top;
  padding: 10px 12px 10px 0;
  border-bottom: 1px solid var(--hair);
}
.read th { color: var(--lum-1); font-weight: 600; }

/* ------------------------------------------------------------------
   Narrow screens
   ------------------------------------------------------------------ */

@media (max-width: 480px) {
  main.read { padding-left: 20px; padding-right: 20px; }
  .read .tool,
  .read .download-sheet,
  .read .share-object { padding: 20px; }
}

@media (prefers-reduced-motion: reduce) {
  .read a,
  .read button,
  .read .tool,
  .read .tool :is(textarea, input, select) { transition: none; }
}

/* ------------------------------------------------------------------
   Load-bearing pieces carried over from journal-workshops.css.

   That stylesheet was replaced wholesale, and these are the parts of it
   that were doing work rather than decorating. Losing them silently is
   how a redesign breaks a page nobody screenshots.
   ------------------------------------------------------------------ */

/* [hidden] is a UA rule, and any author `display` beats it. The tools ship
   their buttons hidden and reveal them from JS, so without this a visitor
   with JS off would see controls that do nothing. */
[hidden] { display: none !important; }

/* Skip link: off screen until it is focused, then first thing on the page. */
.skip {
  position: absolute;
  top: -100px;
  left: 20px;
  z-index: 1001;
  background: var(--lum-1);
  color: #000;
  padding: 12px 16px;
  border-radius: 10px;
  font-size: var(--t-text);
  text-decoration: none;
}
.skip:focus { top: 10px; }

/* Keyboard focus has to be visible on a black page. */
.read :is(a, button, input, select, textarea, summary):focus-visible {
  outline: 2px solid var(--lum-1);
  outline-offset: 4px;
  border-radius: 6px;
}

/* A wide table stays scrollable rather than widening the page. */
.read .table-wrap { overflow-x: auto; }

/* The triage result is a row of text and the category chosen for it. */
.read .result [data-triage-row] {
  display: grid;
  grid-template-columns: 1fr 190px;
  gap: 16px;
  align-items: center;
  padding: 12px 0;
  border-bottom: 1px solid var(--hair);
}
.read .result [data-triage-row] select { margin: 0; }
.read .result:empty { display: none; }
@media (max-width: 560px) {
  .read .result [data-triage-row] { grid-template-columns: 1fr; gap: 8px; }
}

/* The freewriting timer is the product doing something, so it is allowed
   the display size — it is the one large thing on that page. */
.read .timer {
  font-size: var(--t-head);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.04em;
  color: var(--lum-1);
  margin: 32px 0;
}

/* Mixed emotions shows two feelings as light. White disc, mood in the glow,
   six layers on the Figma multipliers — the same recipe as everywhere else,
   written here in CSS because the page sets --affect per object. */
.read .affect-object {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: var(--lum-1);
  margin: 40px auto;
  transform: scale(var(--intensity, 1));
  transition: transform 0.35s var(--ease-soft);
  filter:
    drop-shadow(0 0 8px color-mix(in srgb, var(--affect) 40%, #fff))
    drop-shadow(0 0 16px color-mix(in srgb, var(--affect) 40%, #fff))
    drop-shadow(0 0 55px var(--affect))
    drop-shadow(0 0 111px var(--affect))
    drop-shadow(0 0 190px var(--affect))
    drop-shadow(0 0 250px var(--affect));
}

/* Bullet journal's notation key is a glyph, so it keeps a glyph's font. */
.read .method-key {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  margin-right: 12px;
  color: var(--lum-1);
}

@media (prefers-reduced-motion: reduce) {
  .read .affect-object { transition: none; }
}

/* A figure is an object, so it gets its own measure. Inside the 680px
   reading column (624 of it text) a 1200-wide drawing renders at about half
   scale and its 23px captions land at 12px, which is smaller than anything
   else on the site. At 860px they read at about the body size, which is the
   point, and 860 is still wider than the column. */
/* Only the article's illustration, never every <figure>: the share graphic
   is one too, and it sits inside a narrower parent, where 50% of the parent
   is small but -50% of its own 860px is large. That put it at left: -231 on
   a 940px window, with its text clipped off the page. */
.read figure:has(> img.hero-art) {
  width: min(860px, 100vw - 40px);
  margin-left: 50%;
  transform: translateX(-50%);
}

/* The caption belongs to the text, so it returns to the column. */
.read figure:has(> img.hero-art) figcaption {
  max-width: var(--measure);
  margin-left: auto;
  margin-right: auto;
}

/* ------------------------------------------------------------------
   Source excerpts — the app's own code, quoted.

   An excerpt is an object, so it sits on the panel material tokens.css
   defines (a near-black solid, its top edge catching the light) and takes
   the figure's wider measure; a long line scrolls inside it rather than
   widening the page or wrapping code mid-expression. Body size, in the
   glyph font the bullet-journal key already uses.
   ------------------------------------------------------------------ */

.read figure:has(> pre) {
  width: min(860px, 100vw - 40px);
  margin-left: 50%;
  transform: translateX(-50%);
}

.read figure:has(> pre) figcaption {
  max-width: var(--measure);
  margin-left: auto;
  margin-right: auto;
}

.read pre {
  margin: 0;
  padding: 18px 20px;
  background: var(--panel);
  border: 1px solid var(--edge-dim);
  border-top-color: var(--edge);
  border-radius: 16px;
  overflow-x: auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--t-text);
  line-height: 1.6;
  tab-size: 4;
}

/* Line numbers are drawn, not typed: a counter in ::before, so selecting
   and copying an excerpt gives the code alone. --line-start on the <code>
   is the line before the excerpt's first line in its source file, so the
   numbers match the file a reader may open. */
.read pre code {
  font: inherit;
  counter-reset: line var(--line-start, 0);
  color: rgba(255, 255, 255, 0.85);
}

.read pre .line::before {
  counter-increment: line;
  content: counter(line);
  display: inline-block;
  min-width: 3ch;
  margin-right: 2ch;
  text-align: right;
  color: var(--card-line-hi);
  user-select: none;
}

/* The one place hue appears outside mood light, by the owner's decision:
   code is shown the way the people who write it see it, in Xcode's Default
   (Dark) token colours. Confined to <pre>; nothing else may borrow them. */
.read pre .tok-c  { color: #6C7986; }               /* comments */
.read pre .tok-cc { color: #92A1B1; }               /*  in doc comments */
.read pre .tok-k  { color: #FC5FA3; font-weight: 600; } /* keywords */
.read pre .tok-f  { color: #41A1C0; }               /* the declared name */
.read pre .tok-t  { color: #D0A8FF; }               /* system types */
.read pre .tok-sm { color: #A167E6; }               /* system methods, properties */
.read pre .tok-pm { color: #67B7A4; }               /* the project's own names */
.read pre .tok-s  { color: #FC6A5D; }               /* strings */
.read pre .tok-n  { color: #D0BF69; }               /* numbers */
