/* netword-shared/css/reading.css
   ---------------------------------------------------------------------------

   The reading view's whole appearance — the page js/nativeRender.js draws, in
   Studio's preview and in the reader's App, because they are the same page.

   One class per display role and one per display element, named exactly as
   js/nativeRender.js emits them: `role-` and the role's name, `element-` and the
   element's name, both from js/displayRules.js. Nothing here selects on an
   element name alone, so the day a role is drawn with a different tag the
   stylesheet does not quietly stop applying. Kebab-case classes; BEM only where
   the nesting is real (Build Rules, "Names").

   TWO PREFIXES, AND THE DIFFERENCE IS REAL. `role-` styles a meaning a
   container asserted about its own text; `element-` styles a shape the reading
   language drew. A stylesheet that flattened them would be the one place the
   distinction the whole display law rests on goes quiet.

   THIS SHEET DOES NOT CHOOSE HOW ANYTHING LOOKS. It says what each item of the
   standard display vocabulary IS and which declaration each of a view's
   answers lands in; every view carries its own VIEW STYLEMAP naming the
   answers — rank presentation, scale, alignment, colour, all of it view-local,
   presentation only and one way. No view alters, renumbers or writes back a
   semantic fact: heading rank is the publisher's, its dress is the view's.

   So every colour, face, weight, tracking, transform and type size below is a
   bare `var(--reading-*)` WITH NO FALLBACK, and this sheet declares none of
   them. That is the seam's only workable mechanics rather than a preference: a
   custom property inherits, and a declaration ON an element beats a value
   inherited INTO it, so a default on `.reading-view` here would sit between a
   home and its own map and win every time. THERE IS THEREFORE NO SUCH THING AS
   A PLATFORM DEFAULT — a view is taught the whole map or it draws undressed.
   The maps that exist today are netword-app/brands/default/skin.css (`:root`, the Bible
   view) and netword-studio/css/studio.css (`.preview-page` and
   `.tab-panel__document`, the workshop view), and
   netword-shared/test/readingSpacing.test.js asserts every home declares every
   token, so a forgotten one is a red suite rather than a reader's discovery.
   Dark mode is a view's answer by the same seam: a home declares a dark map on
   the containers it owns, or it simply does not change at night.

   WHAT STAYED THE PLATFORM'S, and the rule that decided it. Structure, flow and
   the seams: the MEASURE (`max-width: 34rem` — a fact about the eye, not a look
   this surface chose), which properties exist at all, that a sticky header must
   be opaque and stacked above what scrolls under it, that code preserves
   whitespace and scrolls rather than wraps, that a table scrolls inside its own
   box rather than pushing the page sideways, that paragraphs separated by space
   are not also indented, and that a class whose own NAME fixes both the property
   and its value — `.element-align-center` is the document asking for centring —
   is drawn as named, because a view that reinterpreted it would be altering a
   semantic fact, which the ruling forbids outright. Where a declaration is
   structure but its value is a look, the declaration stays here and consumes a
   token: "the sticky header must be opaque" is the platform's, WHICH opaque
   colour is the map's.

   `.role-quote` and `.role-superscript` are ROLES a container may assert; a
   name may not be in both vocabularies. `.role-subscript` beside
   `.role-superscript` is where the pair used to be made visible: the twin was judged identically
   and not adopted, so the language still draws it and no container may assert
   it.

   The two were spelled `.element-blockquote` and `.element-superscript` before
   that line was drawn, and the declarations under them did not change — only
   the selectors did. The old spellings are named here so that a search for
   either one lands on the reason it is gone rather than on nothing, and so that
   a selector left behind under the old prefix would read as the dead rule it
   would be. The renderer's own test asserts both halves of that against this
   file.
   --------------------------------------------------------------------------- */

.reading-view {
  /* A measure, not a width. Somewhere near 66 characters is where a line stops
     costing the eye its place on the way back to the left margin. */
  max-width: 34rem;
  margin: 0 auto;
  /* The measure above is identity — a fact about the eye that reads the same
     on every device. The gutter is not: Studio is a desk at a desktop width
     and the App is a phone in one hand, and a sheet that fixed one number for
     both would be furniture pretending to be identity. Typography — face,
     size, leading, tracking, weight, colour — is the view's, travelling the
     same road as the gutter.

     THERE IS DELIBERATELY NO FALLBACK IN THESE THREE `var()`s. A home that
     declares none of them gets zero padding — text hard against the paper's
     edge, impossible to miss — rather than a default that quietly papers over
     a home nobody taught to answer. The homes are checked by test
     (`netword-shared/test/readingSpacing.test.js`), so the omission is caught
     before a person ever sees it; the visible failure is the second net.

     Each home declares these on a container IT ALREADY OWNS and inherits them
     in — `.preview-page` and `.tab-panel__document` in Studio,
     `.window__content` in the App. No home selects `.reading-view`. */
  padding: var(--reading-pad-block-start) var(--reading-pad-inline) var(--reading-pad-block-end);
  background: var(--reading-paper);
  color: var(--reading-ink);
  /* Three longhands and not the `font:` shorthand, which is not a style choice:
     the shorthand RESETS every font property it is not given — weight, style,
     variant, stretch — so a view whose map made body text lighter would find it
     silently reset here. Three properties, three tokens, nothing implied. */
  font-family: var(--reading-face);
  font-size: var(--reading-size);
  line-height: var(--reading-leading);
  /* Tabs that arrived as a token — `[[TAB]]`, or the `{{TAB}}` spelling that
     replaced the older ones — are content; this keeps one visible without
     turning the whole paragraph into preformatted text. */
  tab-size: 2;
}

/* ── Blocks ──────────────────────────────────────────────────────────────── */

.reading-view .role-body {
  margin: 0 0 var(--reading-paragraph-gap);
  /* Paragraphs are separated by space, so they are not also indented: doing
     both says the same thing twice and reads as a mistake. */
  text-indent: 0;
}

/* The flush modifier: a paragraph with no first-line indent, drawn beside its
   role class — `role-body flush`, `role-quote flush`, and the two scripture
   forms. One rule for four kinds of paragraph, because the modifier says one
   thing about all of them. In THIS skin it changes nothing visible, since the
   body is already set without an indent (above) and so are the blocks that
   follow it; the rule is here so that a skin that indents its paragraphs has
   the one place to say a flush one does not, and so that the class the
   renderer writes is dressed rather than dangling. Not a `role-` class — the
   scan one test makes over this file reads roles, and `flush` is not one. */
.reading-view .flush {
  text-indent: 0;
}

.reading-view .role-body:last-child {
  margin-bottom: 0;
}

.reading-view .role-heading-1,
.reading-view .role-heading-2,
.reading-view .role-heading-3,
.reading-view .role-heading-4,
.reading-view .element-heading-5,
.reading-view .element-heading-6 {
  margin: 2em 0 0.6em;
  color: var(--reading-heading-color);
  font-family: var(--reading-heading-face);
  font-weight: var(--reading-heading-weight);
  line-height: var(--reading-heading-leading);
  /* Headings in an imported document are frequently shouted in the source.
     Drawing them small-caps-ish rather than reproducing the shouting keeps the
     page calm without editing anybody's text — and WHETHER to do that is the
     view's answer now, which is why the value is a token and the property is
     still here. */
  letter-spacing: var(--reading-heading-tracking);
}

.reading-view .role-heading-1:first-child,
.reading-view .role-heading-2:first-child,
.reading-view .role-heading-3:first-child,
.reading-view .role-heading-4:first-child,
.reading-view .element-heading-5:first-child,
.reading-view .element-heading-6:first-child {
  margin-top: 0;
}

/* Rank one also takes an ALIGNMENT from the map, and it is the one token in the
   set whose two views deliberately disagree: the App centres a book's opening
   heading the way a printed Bible does, and the workshop keeps it left, where a
   bench reads a document as a column of work. Every other token is
   moved-not-chosen. */
.reading-view .role-heading-1 {
  font-size: var(--reading-heading-1-size);
  text-align: var(--reading-heading-1-align);
}

.reading-view .role-heading-2 { font-size: var(--reading-heading-2-size); }
.reading-view .role-heading-3 { font-size: var(--reading-heading-3-size); }

.reading-view .role-heading-4 {
  font-size: var(--reading-heading-4-size);
  color: var(--reading-heading-4-color);
  text-transform: var(--reading-heading-4-transform);
  letter-spacing: var(--reading-heading-4-tracking);
}

/* Ranks five and six. The role vocabulary names four and the language draws
   six, so these are the ranks a document can meet but can never assert — see
   js/displayRules.js on the two ceilings. Drawn quieter than rank four rather
   than smaller than the body text: a heading that is smaller than what it heads
   stops looking like a heading. */
.reading-view .element-heading-5,
.reading-view .element-heading-6 {
  font-size: var(--reading-heading-5-size);
  color: var(--reading-heading-5-color);
  letter-spacing: var(--reading-heading-5-tracking);
}

.reading-view .element-heading-6 {
  font-style: var(--reading-heading-6-style);
  font-weight: var(--reading-heading-6-weight);
}

/* ── Blocks the language draws ───────────────────────────────────────────── */

/* A quotation, drawn by the rule on the left that a printed page would use. No
   quotation marks: the `>` was the author's way of saying this is quoted — or
   the container's, since version 2 — and adding punctuation would be the
   stylesheet editing the text. A `role-` class, and the one block rule in
   this section that is: see the header. */
.reading-view .role-quote {
  margin: 1.4em 0;
  padding: 0.1em 0 0.1em 1.2em;
  border-left: 3px solid var(--reading-rule);
  color: var(--reading-ink-soft);
}

.reading-view .role-quote > :last-child {
  margin-bottom: 0;
}

/* Scripture, drawn two ways, because a publisher does two different things with
   it and the id is what says which (R203).

   THESE ARE FIRST DEFINITIONS AND ARE MEANT TO BE TUNED. What they read as is
   what the bench's own files do: measured over the Oster and Fiensy packages,
   the style carrying set-apart scripture sets a left AND right indent of 18
   against a body at 0 and adds space above and below, while the style carrying
   scripture in the run of the commentary sets no indent at all and differs from
   the body only in weight. So the block form is indented on both sides and set
   off; the running form keeps the body's measure and changes only its face.
   Neither takes a rule on the left: that is `role-quote`'s mark, and scripture
   that borrowed it would be saying it is a quotation, which is the exact
   confusion the two ids were adopted to end.

   No quotation marks, for the reason the blockquote has none: punctuation added
   by a stylesheet is the stylesheet editing the text.

   AND NEITHER TAKES THE `> :last-child` COMPANION the quote above has, which is
   the visible difference between a container and a paragraph id. A quotation
   WRAPS — `> > a` nests, and the wrapper's last child needs its bottom margin
   taken off. A paragraph id says what kind of paragraph THIS paragraph is, so
   the renderer draws one `p` and there is no last child to correct. */
.reading-view .role-scripture-block {
  margin: 1.4em 0;
  padding: 0.2em 1.2em;
  color: var(--reading-ink-soft);
}

/* As the body, with a distinct face. The weight is the whole of the difference,
   which is what "carried in the flow of the commentary's own paragraphs" means:
   a reader should see scripture without the page breaking around it. */
.reading-view .role-scripture-running {
  font-weight: var(--reading-scripture-weight);
}

/* As the body, with a distinct face: prose about the background or context of
   a section, as against the body paragraph about a verse or two. The italic
   is the skin's and nothing of the registry's, and the token is the one
   `.role-em` reads — so a window that sets emphasis upright sets this upright
   too, one word from the skin about what italic means on its page. */
.reading-view .role-intro {
  font-style: var(--reading-emphasis-style);
}

/* AND `role-comment` IS NAMED HERE AND NOT DRAWN, which is a rule and not an
   omission. A comment is a note on the words of a verse, the intro's sibling in
   the vocabulary and its opposite on the page: the intro takes a face because a
   reader meeting a paragraph about a whole section needs to know that is what it
   is, and a note about the verse in front of them reads as what the page is
   already made of. So it is body to look at, exactly, and the class rides on the
   paragraph for the sake of the surfaces that SORT by it — a study window asking
   which of these paragraphs are about this verse — and for nothing that is seen.
   A rule here would be this sheet deciding that a publisher's verse notes look
   different from their prose, which is the publisher's decision and not a
   stylesheet's. See the six role marks below, where the same law is stated for
   spans. */

/* The head of a chapter in a book: number, title, subtitle, any of which may be
   absent. The number makes space above the head and the subtitle space below
   it; the title sits between them with neither, so a head of all three reads as
   one block. Spacing alone: the three are body to look at in every other way,
   and a face for any of them is a skin's to give. Each rule zeroes the margin it
   does not make, so a head missing a part closes up rather than keeping the gap
   the missing part would have had. */
.reading-view .role-chapter-number {
  margin-top: calc(var(--reading-paragraph-gap) * 4);
  margin-bottom: 0;
}

.reading-view .role-chapter-title {
  margin-top: 0;
  margin-bottom: 0;
}

.reading-view .role-chapter-subtitle {
  margin-top: 0;
  margin-bottom: calc(var(--reading-paragraph-gap) * 3);
}

.reading-view .element-list-ordered,
.reading-view .element-list-unordered {
  margin: 1.1em 0;
  padding-left: 1.6em;
}

/* A nested list belongs to its parent item, so it does not also get the space
   between two top-level blocks. */
.reading-view .element-list-item > .element-list-ordered,
.reading-view .element-list-item > .element-list-unordered {
  margin: 0.3em 0;
}

.reading-view .element-list-item {
  margin: 0.35em 0;
}

.reading-view .element-list-item > .role-body:last-child {
  margin-bottom: 0;
}

/* A task item's box is drawn, not built: an `<input type="checkbox" disabled>`
   would be a control in a page that has nothing to submit, and the renderer
   writes no attribute but `class`. The marker replaces the list's own bullet,
   which is why the item is `list-style: none` rather than carrying two marks. */
.reading-view .element-task,
.reading-view .element-task-done {
  list-style: none;
  margin-left: -1.4em;
  padding-left: 1.4em;
  position: relative;
}

.reading-view .element-task::before,
.reading-view .element-task-done::before {
  position: absolute;
  left: 0;
  font-family: var(--reading-display-face);
  color: var(--reading-ink-soft);
}

.reading-view .element-task::before { content: "\2610"; }          /* ballot box */

.reading-view .element-task-done::before {
  content: "\2611";                                                 /* with check */
  color: var(--reading-accent);
}

/* Code is the one place on this page where whitespace is content, so the
   measure does not apply and the text may scroll rather than wrap. */
.reading-view .element-code-block {
  margin: 1.2em 0;
  padding: 0.9em 1em;
  overflow-x: auto;
  background: var(--reading-rule);
  border-radius: 3px;
  font-family: var(--reading-mono-face);
  font-size: var(--reading-code-size);
  line-height: var(--reading-code-leading);
  tab-size: 4;
}

.reading-view .element-rule {
  margin: 2.2em 0;
  border: 0;
  border-top: 1px solid var(--reading-rule);
}

/* A table is wider than the measure more often than not, so it scrolls inside
   its own box rather than pushing the page sideways. */
.reading-view .element-table {
  display: block;
  overflow-x: auto;
  margin: 1.3em 0;
  border-collapse: collapse;
  font-size: var(--reading-table-size);
}

/* NO HOUSE DEFAULT AT ANY TARGET, and the three selectors that used to be one.
   `element-table-head`, `element-table-body` and `element-table-row` carry no
   rule of their own: a head once drew a 2px underline and every body row after
   the first drew a 1px line above it, whatever the source said. A table's lines
   come from its annex or from nowhere, so those two rules are gone rather than
   moved, and the names are written here so their absence reads as a decision.
   What draws a line is `.element-rule-<side>` below, off the per-side custom
   properties the crossing classes set. */

.reading-view .element-table-heading,
.reading-view .element-table-cell {
  padding: 0.4em 0.8em;
  text-align: left;
  vertical-align: top;
}

/* A PARAGRAPH BREAK INSIDE A CELL. The InDesign file is the rule: a cell holds
   the paragraphs the publisher put in it, and the renderer draws the boundary
   between them as `<br class="element-cell-paragraph">`
   because a pipe table's row is one line and the boundary cannot be a newline.

   `display: block` with a margin is what turns that break into a paragraph gap
   rather than the line break a bare `<br>` draws — the difference `{{PB}}` and
   `{{BR}}` mean, made visible. The height is zero: the element contributes the
   space between the paragraphs and nothing else, so a cell holding two of them
   is as tall as two lines and a gap and not as tall as three lines. */

.reading-view .element-cell-paragraph {
  display: block;
  content: "";
  height: 0;
  margin-bottom: 0.55em;
}

.reading-view .element-table-heading {
  font-family: var(--reading-display-face);
  font-weight: var(--reading-label-weight);
}

/* A table's RULES, drawn from the cdx-table annex.

   THIS IS THE ONE PLACE A WEIGHT NAME BECOMES A LENGTH. The annex carries
   `hairline` and never a measurement, the importer projects a measured stroke to
   the nearest name and records the measurement in the ledger, and here — at the
   display layer, where every other style answer lives — the name acquires a
   size. js/displayRules.js's RULE_WIDTHS and DOUBLE_WIDTH hold the same numbers
   as the vocabulary's own definition of what the words mean, and the suite
   asserts these four declarations against them rather than trusting the mirror.

   THE NUMBERS ARE NAMED ONCE, ON THE TABLE. Custom properties inherit, so every
   cell of every table sees them without a selector reaching down for it, and a
   length that has to be tuned is tuned in one line rather than in sixteen.

   A SIDE AT A TIME, BECAUSE EVERY LINE HAS ONE OWNER. The annex's four targets
   are a partition of a table's lines, so a cell lawfully wears four different
   weights — its top from the frame, its bottom from the header rule — and there
   is no cell-wide weight left to name. That is why the custom properties are
   PER SIDE. Two classes do it: `element-rule-top` draws the top border from the
   top's own two properties, and `element-rule-top-double` sets them. Four side
   rules and sixteen crossings, and the crossings carry no lengths of their own.

   AND `double` IS A STYLE, NOT A WIDTH. CSS draws `border-style: double` as
   three equal bands — line, gap, line — so the crossing that reaches it changes
   the style as well as the width, and it is the only one that does. A weight
   name that were merely "thicker" could never produce two lines, which is the
   whole reason the vocabulary names a style among its widths.

   `none` HAS NO CLASS HERE, and its absence is not an omission. A `none` row
   states that a hand suppressed dress at that target; the resolver puts no side
   on any cell for it, so nothing ever asks this stylesheet how to draw one. */
.reading-view .element-table {
  --w-hairline: 0.25pt;
  --w-rule: 0.75pt;
  --w-double: 2.25pt;
  --w-heavy: 1.5pt;
}

/* A tab is an instruction the paragraph style answers, and this is the answer
   for a style that defines no stops: repeating stops 12pt apart. The number
   mirrors js/displayRules.js's TAB_DEFAULT_PT, which is where it is DEFINED,
   the same arrangement the four widths above are under and checked by the same
   kind of test — a mirror nobody checks is a second authority.

   `--tab-stop-width` is the override, and it is deliberately not set here: a
   surface that knows which paragraph style a run is under sets it on the span
   itself, and a surface that does not leaves the default standing. Per style
   and never per tab, because one style cannot draw two widths.

   `inline-block` and not `inline`: an inline box has no width to give. The
   span holds no text, so nothing inside it can be selected, and the caret
   steps over it in a contenteditable rather than into it. */
.reading-view {
  --tab-default: 12pt;
}

.reading-view .tab-stop {
  display: inline-block;
  width: var(--tab-stop-width, var(--tab-default));
}

.reading-view .element-rule-top { border-top: var(--rule-top-width) var(--rule-top-style) var(--reading-rule); }
.reading-view .element-rule-right { border-right: var(--rule-right-width) var(--rule-right-style) var(--reading-rule); }
.reading-view .element-rule-bottom { border-bottom: var(--rule-bottom-width) var(--rule-bottom-style) var(--reading-rule); }
.reading-view .element-rule-left { border-left: var(--rule-left-width) var(--rule-left-style) var(--reading-rule); }

.reading-view .element-rule-top-hairline { --rule-top-width: var(--w-hairline); --rule-top-style: solid; }
.reading-view .element-rule-top-rule { --rule-top-width: var(--w-rule); --rule-top-style: solid; }
.reading-view .element-rule-top-double { --rule-top-width: var(--w-double); --rule-top-style: double; }
.reading-view .element-rule-top-heavy { --rule-top-width: var(--w-heavy); --rule-top-style: solid; }

.reading-view .element-rule-right-hairline { --rule-right-width: var(--w-hairline); --rule-right-style: solid; }
.reading-view .element-rule-right-rule { --rule-right-width: var(--w-rule); --rule-right-style: solid; }
.reading-view .element-rule-right-double { --rule-right-width: var(--w-double); --rule-right-style: double; }
.reading-view .element-rule-right-heavy { --rule-right-width: var(--w-heavy); --rule-right-style: solid; }

.reading-view .element-rule-bottom-hairline { --rule-bottom-width: var(--w-hairline); --rule-bottom-style: solid; }
.reading-view .element-rule-bottom-rule { --rule-bottom-width: var(--w-rule); --rule-bottom-style: solid; }
.reading-view .element-rule-bottom-double { --rule-bottom-width: var(--w-double); --rule-bottom-style: double; }
.reading-view .element-rule-bottom-heavy { --rule-bottom-width: var(--w-heavy); --rule-bottom-style: solid; }

.reading-view .element-rule-left-hairline { --rule-left-width: var(--w-hairline); --rule-left-style: solid; }
.reading-view .element-rule-left-rule { --rule-left-width: var(--w-rule); --rule-left-style: solid; }
.reading-view .element-rule-left-double { --rule-left-width: var(--w-double); --rule-left-style: double; }
.reading-view .element-rule-left-heavy { --rule-left-width: var(--w-heavy); --rule-left-style: solid; }

/* The three alignments a delimiter row can ask for. Classes rather than a
   `style` attribute: alignment is the document speaking, and what it asks for is
   still drawn by the stylesheet. */
.reading-view .element-align-left { text-align: left; }
.reading-view .element-align-center { text-align: center; }
.reading-view .element-align-right { text-align: right; }

.reading-view .element-definitions {
  margin: 1.2em 0;
}

.reading-view .element-term {
  font-family: var(--reading-display-face);
  font-weight: var(--reading-label-weight);
}

.reading-view .element-definition {
  margin: 0.2em 0 0.8em 1.4em;
  color: var(--reading-ink-soft);
}

/* ── Inline ──────────────────────────────────────────────────────────────── */

/* The class name fixes the PROPERTY and not the value: `strong` says heavier
   than the text around it, and how much heavier is the view's answer. Compare
   `.role-strikethrough` below, whose name fixes both, and which is therefore drawn
   as named with no token at all. */
.reading-view .role-strong {
  font-weight: var(--reading-strong-weight);
  color: var(--reading-strong-color);
}

.reading-view .role-em {
  font-style: var(--reading-emphasis-style);
}

/* `sq` is the one role mark this sheet draws: the phrase under discussion, a
   commentary's lead-in naming the words of Scripture it speaks about. It wears
   one look on every surface — medium italic — so a note reads the same in the
   workbench's preview and on a reader's phone, and the weight and the slope are
   therefore written here rather than asked of a token. The colour is the
   view's, and it is the lead-in's colour: the same token `strong` wears, which
   a home sets where its lead-ins are. The slope is literal on purpose — a view
   that draws scripture's emphasis upright turns `--reading-emphasis-style`, and
   that must not straighten a commentary's lead-in, which is not the
   translators' mark. */
.reading-view .role-sq {
  font-weight: 500;
  font-style: italic;
  color: var(--reading-strong-color);
}

/* `sc` is drawn with `font-variant-caps` rather than `text-transform: lowercase` plus a size trick
   for a reason a reader can see: the property asks the FONT for its small
   capitals and falls back to synthesising them, so a face that has real ones
   uses them, and — this is the half that matters here — it leaves capital
   letters alone. The Divine Name is written `Lord` in the source, never `LORD`,
   so the L stays full height and ORD comes down, which is the King James
   setting exactly. Had the source shouted it, this rule would have drawn
   nothing and the page would have looked correct by accident. */
.reading-view .role-sc {
  font-variant-caps: var(--reading-smallcaps-variant);
}

/* Inline code is NOT the fenced block's rule at a smaller size — it sits in a
   line of prose whose leading it must not disturb, so it takes padding
   horizontally and almost none vertically. Two elements, two rules, which is
   why js/displayRules.js names `code` and `code-block` separately. */
.reading-view .element-code {
  padding: 0.1em 0.3em;
  background: var(--reading-rule);
  border-radius: 3px;
  font-family: var(--reading-mono-face);
  font-size: var(--reading-code-inline-size);
  /* A literal `1`, and one of exactly two line-heights left in this sheet. It
     is not a scale: it is the statement that this run must not push the line
     box it sits in. The other is the `0` on sub/sup below. */
  line-height: 1;
}

.reading-view .element-link {
  color: var(--reading-accent);
  /* Underlined from the text's own baseline rather than by a border, so a link
     broken across two lines is underlined on both. */
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

/* No asset system exists yet, so every image is drawn from whatever URL the
   document names. What the sheet can promise is that it never pushes the page
   sideways — see the renderer's header for the rest of that sentence. */
.reading-view .element-image {
  max-width: 100%;
  height: auto;
}

.reading-view .role-strikethrough {
  text-decoration: line-through;
  color: var(--reading-ink-soft);
}

.reading-view .role-highlight {
  padding: 0.05em 0.15em;
  background: var(--reading-mark);
  color: inherit;
}

/* Both take the browser's own vertical-align, which `sub`/`sup` already carry;
   what is set here is the size, because the default shrinks the text enough to
   cost a reader the character at this measure. */
.reading-view .role-subscript,
.reading-view .role-superscript {
  font-size: var(--reading-super-size);
  line-height: 0;
}

/* THE SIX THAT ARE NAMED AND NOT DRAWN, and the absence is a rule rather
   than a hole. `role-gr`, `role-hb`, `role-tl`, `role-fw`, `role-wj` and
   `role-nd` are six of the registry's seven role marks — the seventh, `sq`, is
   drawn above — and each says what a span
   IS — "this text is Greek" — and nothing about how it looks, and
   js/nativeRender.js states the law in three words, *no default dress,
   anywhere*. A stylesheet MAY isolate every Greek span and give it a font, and
   this one does not, because choosing a Greek face for every publisher in the
   world is not a decision a reading view gets to make.

   They are named here in the shape the three undrawn ELEMENTS are named —
   `element-table-head`, `element-table-body` and `element-table-row` — and for
   the same reason: without the note, "no rule" and "somebody forgot" read
   identically, and the suite has no way to tell a decision from an omission.

   `role-wj` is the one a reader might expect here, since a red-letter edition
   is exactly a stylesheet isolating a role. Red letter is a READER'S setting
   and never the file's, so it is dressed where the setting lives — the editor's
   chip view, js/cdx-views.js, at the last possible moment — and not in a sheet
   that would make every reader's page the same. */

.reading-view .element-footnote-ref {
  font-size: var(--reading-super-size);
  line-height: 0;
}

/* A deliberate omission. Greyed and in the display face, because it is the
   view's apparatus and not the publisher's text — the same argument the three
   faces are a token each for — and at the body's size rather than smaller,
   since a reader has to be able to see it to know a decision was made. */
.reading-view .element-omit {
  color: var(--reading-ink-soft);
  font-family: var(--reading-display-face);
}

.reading-view .element-footnote-ref a {
  color: var(--reading-accent);
  text-decoration: none;
  /* A reference is one or two characters, which is a small target; the padding
     is the click, not the look. */
  padding: 0 0.15em;
}

/* A CALL WITH NOWHERE ON THIS PAGE TO SEND ANYBODY. R161: a footnote call is an
   internal link, and a link is a promise that the thing it names is here. Where
   the note's rows are not on the page being drawn — A-036 Four's lost note, and
   every block of a surface that draws one paragraph at a time — the call keeps
   its numeral and loses its anchor, and `data-note` is the seam a surface with
   somewhere ELSE to send the reader listens on. Muted rather than accented,
   because on a page where nothing is listening this is a number to read and not
   a link to follow, and a reader must be able to see which it is. */
.reading-view .element-footnote-ref[data-note] {
  color: var(--reading-ink-soft);
}

/* ── Notes, at the document's end ────────────────────────────────────────── */

.reading-view .element-footnotes {
  margin: 2.5em 0 0;
  padding-top: 1.2em;
  border-top: 1px solid var(--reading-rule);
  font-size: var(--reading-notes-size);
  color: var(--reading-ink-soft);
}

.reading-view .element-footnote {
  margin: 0 0 0.5em;
}

/* ── Interlinks: what NetWord knows, drawn ───────────────────────────────── */

/* A reference is a citation, not a link — there is no popup yet and nothing to
   tap. So it is marked the way print marks a citation, by weight and colour and
   not by an underline, which on this page means "this goes somewhere". The day
   `@` gets its popup, an underline is what will be added, and it will mean
   something because it does not mean anything now. */
.reading-view .element-interlink-reference {
  color: var(--reading-accent);
  white-space: nowrap;                    /* "1 Corinthians 3:12" never breaks */
}

/* A term is the source's own word — Greek, Hebrew, a technical term — and it is
   CONTENT: translated, styled, read. The rule is therefore almost nothing. It
   exists so a term is findable in the DOM and so the day the database lands
   there is a selector already in the sheet to hang the link on. */
.reading-view .element-interlink-term {
  border-bottom: 1px dotted var(--reading-rule);
}

/* And the honest half: every term wears this today, because no term database
   exists — and so does every run a link-ruled style gave the import door that
   the grammar could not resolve to a verse: a bare verse number, a chapter and
   verse with no book, a "see" before the name. Those are the author's words
   and nothing else until something links them, and they draw as PLAIN TEXT:
   the dotted rule above is taken away again here, no cursor, no colour, no
   mark on the page at all. The term rule stays for the day a term is known to
   NetWord; this one stands after it in the sheet so that it wins. (Nathan's
   ruling: the unresolved runs take no dotted underline.) */
.reading-view .element-interlink-unlinked {
  border-bottom: none;
  cursor: text;
}

/* ── Verse numbers ───────────────────────────────────────────────────────── */

/* THE NUMBER IS AN ATTRIBUTE, NOT A CLASS, and that is this section's one
   departure from the header's rule. Every other selector in this file names a
   category — a role, an element — and there are a few dozen of them. A verse
   number is a VALUE: `.verse-1` through `.verse-176` is not a vocabulary, it is
   a table. So the number rides `data-verse` and is drawn with `attr()`.

   IT IS DRAWN, NOT INSERTED. Generated content is not part of the document's
   text: a reader who selects a passage and copies it gets the words, without
   numbers interleaved through them, and a search over the page's text never
   matches a number that the source did not write. That is also why the number
   cannot arrive as content from the renderer — see netword-app/js/readingJoin.js
   on why it cannot arrive through the annotations channel either.

   WHO WRITES THE ATTRIBUTE IS THE HOME'S BUSINESS. The App writes it
   (numberVerses); Studio's preview does not, because a document being edited is
   not yet a numbered book. A segment with no `data-verse` is drawn with no
   number and needs no rule, which is why the base `.segment` has none here. */
.reading-view .segment[data-verse]::before {
  content: attr(data-verse);
  /* Superscript by the same numbers the language's own `sup` takes, so a verse
     number and a footnote reference sit on one line without fighting. */
  font-size: var(--reading-super-size);
  line-height: 0;
  vertical-align: super;
  font-family: var(--reading-display-face);
  color: var(--reading-ink-soft);
  /* The gap is on the right only. A number belongs to the verse that FOLLOWS
     it, and space on both sides would leave it floating between two. */
  margin-right: 0.25em;
  /* Nothing about a verse number is selectable, tappable, or a target; the tap
     that matters is on the verse, and the number must not steal it. */
  user-select: none;
}

/* A VERSE THE SOURCE NEVER CARRIED still has a number, and behind it nothing —
   the reserved slot, reaching the page. The span is empty by construction, so
   what the reader sees is the number and then the next verse.

   It is drawn quieter than a number with words after it, and NOT replaced by an
   invented glyph: a dash or a bracket here would be the stylesheet writing text
   into a Bible, which is the one thing this file may never do. The gap itself is
   the statement. Where the gap came from — a source that skipped the verse, a
   translation that joins it to its neighbour — is a question for the App's
   navigation to answer, not for a colour. */
.reading-view .segment--empty[data-verse]::before {
  opacity: 0.55;
  /* The right margin is now separating this number from the NEXT verse's
     number rather than from its own words, and at 0.25em two numbers in a row
     read as one four-digit number. */
  margin-right: 0.45em;
}

/* A READER WHO TURNED THE NUMBERS OFF.

   THE SUPPRESSION IS ONE RULE AND IT IS HERE, three lines under the rule it
   answers, because hiding a number is the same question as drawing one and the
   two must be read together. The alternative was to stop emitting `data-verse`
   — to re-run js/readingJoin.js with the setting in hand — and that road was
   refused: the number is not content, so a setting about whether it is SHOWN is
   a question for presentation, and routing it through the transform would make
   the App rebuild the ribbon to change how it looks. That crossing is the
   place to stop.

   `content: none` AND NOT `display: none`, because they are not the same claim.
   `display: none` would leave the pseudo-element generated and then hide its
   box; `content: none` means it is never generated at all — the number does not
   exist for the layout, for the accessibility tree, or for a browser's find.
   Off is therefore the same page a reader would get from a Bible printed
   without numbers, not that page with something painted over.

   IT IS ONE STATE AND IT IS THE MINORITY ONE. There is no `="on"` rule anywhere:
   ABSENCE IS ON, so a page that never heard of this setting draws numbers, and
   the default shell is byte-identical to what it was before the setting existed.
   Only the reader who chose the unusual thing costs the markup an attribute.

   WHO WRITES THE ATTRIBUTE IS THE HOME'S BUSINESS, exactly as it is for
   `data-verse` above. The App writes it, on the Bible window's content box and
   nowhere else, and names it there (`VERSE_NUMBERS_ATTRIBUTE` in
   netword-app/js/appShell.js). Studio's preview writes neither attribute, so
   this rule matches nothing over there — a document being edited has no numbers
   to hide. And because the App writes it on an ANCESTOR of the reading view
   rather than on the view, it survives every redraw that replaces the ribbon's
   contents, which is the whole of what a chapter jump does.

   The empty-verse rule above declares no `content`, so it has nothing to say
   here: a pseudo-element that is not generated cannot be made 0.55 opaque. */
[data-verse-numbers="off"] .reading-view .segment[data-verse]::before {
  content: none;
}

/* ── Book and chapter headers ─────────────────────────────────────────────── */

/* TWO PIECES OF APPARATUS, AND THEY WEAR THE DOCUMENT'S OWN RANKS. A book
   heading is drawn at rank one and a chapter header at rank two — not at sizes
   of their own, and not at literals copied from the rank rules above. They
   consume the SAME tokens `.role-heading-1` and `.role-heading-2` consume, so a
   view that redresses its headings redresses these in the same breath and the
   two can never drift into two answers. That is the dispatch's "by shared
   token, not by copied literals" satisfied structurally: there is no book-
   heading size token and no chapter-header size token, because there is nothing
   for one to say that the rank does not already say.

   WHY RANK TWO IS THE RIGHT RANK FOR A CHAPTER, measured and not assumed. In
   the Disciple Study Bible's 27 containers the rank-2 headings are 129 rows
   from the source style `Header 1`, of which 27 read "WRITER", 26 "DATE", 26
   "PURPOSE", 25 "THEME" and 13 "HISTORICAL BACKGROUND". That is the dress the
   dispatch named, and a chapter header standing beside those in one reading
   surface should be the same size as them rather than near it.

   THE PLATFORM STILL OWNS THE STICKING, THE STACKING AND THE OPACITY. Those are
   structure — see below — and only their colour is the map's. */

/* A BOOK OPENS WITH ITS NAME, AND THE NAME SCROLLS AWAY. The chapter header
   alone sticks: a phone screen has room for one line of address, and two
   stacked bars would spend on furniture what the page has for text. So this
   rule is deliberately WITHOUT `position: sticky` — the absence is the
   behaviour, and it is asserted by test rather than left to be noticed.

   IT IS NOT ALWAYS DRAWN. Where a letter already opens with its own rank-1
   heading — every Disciple Study Bible document does, and its text is the
   registry's display name — that heading IS the book heading and the App adds
   none, because two identical titles stacked is what an unconditional rule
   would have produced. See netword-app/js/readingJoin.js. */
.reading-view .book-heading {
  margin: 0 0 0.9em;
  color: var(--reading-heading-color);
  font-family: var(--reading-heading-face);
  font-size: var(--reading-heading-1-size);
  font-weight: var(--reading-heading-weight);
  line-height: var(--reading-heading-leading);
  letter-spacing: var(--reading-heading-tracking);
  text-align: var(--reading-heading-1-align);
  /* Apparatus, like the chapter header and the verse number: a reader who
     copies a passage gets the passage. */
  user-select: none;
}

/* A REAL ELEMENT, NOT GENERATED CONTENT, and both halves are load-bearing. A
   header that says "Matthew 4" needs the BOOK's name, which no attribute on a
   verse carries and which `attr()` cannot reach. And `position: sticky`
   describes an element's own layout, so generated content inside an inline
   span has nothing to make sticky. `numberVerses` emits an `h2` where the
   chapter's block begins, and this rule dresses it.

   IT IS APPARATUS, NOT DOCUMENT. Every other selector in this file names
   something a publisher wrote — a role, an element, a segment. This names a
   header the reader's App added, which is why its class is neither `role-` nor
   `element-`: see `CHAPTER_HEADING_CLASS` in netword-app/js/readingJoin.js. It
   is `user-select: none` for the same reason the verse number is — a reader who
   copies a passage must get the passage, not the furniture around it.

   VERSE 1 HAS ITS NUMBER: the header is above the block and the verse number
   is inside it, so "Matthew 4" is followed by a "1" — a segment has one
   `::before`, and nothing competes for it.

   THE SIZE IS NOT THIS RULE'S TO PICK. A chapter header is read once on
   arrival and then scrolled under, and a display-sized number at the top of a
   phone would spend the reader's screen on an address they already know — a
   real worry, whose answer is rank two through the shared tokens: a view that
   finds rank two too loud on a phone moves rank two.

   WHY IT MUST NOT BE TRANSPARENT: text scrolls UNDER a sticky header, so a
   header with no background of its own would have the verses of the chapter
   drawn through it. `--reading-paper` is the surface it is lifting off, and the
   `z-index` is what makes lifting off mean something — a sticky element with
   no stacking order is painted before its later siblings, which is to say
   behind the very text it is supposed to cover. NOTE WHICH HALF IS WHOSE:
   *that* the header is opaque is the platform's, and it is not negotiable — a
   view cannot make this transparent, because a transparent one is not a
   quieter design, it is unreadable. WHICH opaque colour it is is entirely the
   map's.

   AND IT MUST NOT HAVE A TOP MARGIN, WHICH IS THE SAME GUARANTEE. A sticky box
   is held inside the scrollport by its MARGIN box and not its border box, so a
   top margin here parks the opaque bar below the scrollport's top edge and
   leaves a transparent band above it — and the verses scrolling past are drawn
   through that band. A margin cannot be painted; no background reaches it. So
   the space above a pinned header is either the header's own padding or it
   comes from what precedes it, and it cannot be margin. The space is not
   lost: `.role-body` already carries `margin-bottom: 1.1em`. And this rule is
   the platform's and not a view's, because it is the opacity rule read to its
   end: a transparent band at the pinned edge IS a transparent header for the
   height of that band. A view may choose every spacing it likes around the
   header; what it may not do is put that spacing where the background cannot
   follow. */
.reading-view .chapter-heading {
  position: sticky;
  top: 0;
  z-index: 1;
  margin: 0 0 0.2em;
  padding: 0.15em 0;
  color: var(--reading-heading-color);
  font-family: var(--reading-heading-face);
  font-size: var(--reading-heading-2-size);
  font-weight: var(--reading-heading-weight);
  line-height: var(--reading-heading-leading);
  letter-spacing: var(--reading-heading-tracking);
  background: var(--reading-paper);
  user-select: none;
}


/* ── Section headings ─────────────────────────────────────────────────────── */

/* THE THIRD PIECE OF APPARATUS, AND THE LADDER IS NOW COMPLETE. Book heading at
   rank one, chapter header at rank two, section heading at rank three — each
   through the rank's own token, none of them with a size of its own, for exactly
   the reason the block above gives: there is nothing for a section-heading size
   token to say that rank three does not already say, and a view that redresses
   rank three redresses this in the same breath.

   IT IS APPARATUS AND ITS TEXT IS A PUBLISHER'S, WHICH IS A NEW COMBINATION
   HERE. "Birth of Jesus" is the IKJV's own editorial heading, carried under that
   edition's CC BY licence — so unlike "Matthew 4" it is not a string the App
   composed. It is still apparatus, because of where it stands rather than who
   wrote it: it is not in the document's text, it is in a sidecar keyed by
   reference, and the App joins the two. See `SECTION_HEADING_CLASS` in
   netword-app/js/readingJoin.js, which argues that at length and names the day
   it stops being true — translation day, when the headings enter the source
   itself and become `role-` classes honestly.

   IT DOES NOT STICK, AND THE ABSENCE IS THE DESIGN RATHER THAN AN OMISSION. One
   line of address is what a phone screen has, and the chapter header already
   holds it; a second sticky bar would take the page's text to say something the
   reader can see by scrolling up. It follows that this rule needs no background
   and no `z-index` — nothing scrolls under it — and that it MAY carry a top
   margin, which the chapter header may not (see above on why a sticky box's
   margin is a band no background reaches). The two rules differ in
   exactly the places that difference reaches, and nowhere else.

   `user-select: none` FOR THE THIRD TIME, and it is not a copied line: a reader
   who copies a passage gets the passage, and furniture the App inserted between
   two verses is the most confusing thing that could arrive in a paste.

   ITS OWN FOUR TOKENS for where it stands, its slant, its weight and its size,
   and not rank three's: a section heading is furniture between verses, and a
   view may dress it quieter than a document's own heading of the same rank
   without moving that heading or any other. The face and the colour stay the
   heading dress every rank shares. */
.reading-view .section-heading {
  margin: 1.4em 0 0.35em;
  color: var(--reading-heading-color);
  text-align: var(--reading-section-align);
  font-family: var(--reading-heading-face);
  font-size: var(--reading-section-size);
  font-style: var(--reading-section-style);
  font-weight: var(--reading-section-weight);
  line-height: var(--reading-heading-leading);
  letter-spacing: var(--reading-heading-tracking);
  user-select: none;
}

/* A SECTION THAT OPENS A CHAPTER STANDS DIRECTLY UNDER ITS HEADER, and without
   this rule it would stand 1.4em under it — the two margins collapse and the
   larger wins, so the gap a section earns between two paragraphs would be spent
   between a chapter header and its own first section. It is not a rare shape:
   the IKJV starts a section at a great many chapter openings, `headingsOf` in
   netword-app/js/readingJoin.js draws them in exactly this order, and the pair
   reads as one address block. 0.2em is the chapter header's own bottom margin,
   which is what makes this a collapse the pair keeps rather than a new number. */
.reading-view .chapter-heading + .section-heading {
  margin-top: 0.2em;
}

/* A READER WHO TURNED THE HEADINGS OFF.

   THE SAME PATTERN AS VERSE NUMBERS. One rule, here, three lines under the rule it
   answers; absence is On, so there is no `="off"`'s counterpart anywhere and a
   page that never heard of this setting draws headings; the App writes the
   attribute on the Bible window's content box and names it there
   (`HEADINGS_ATTRIBUTE` in netword-app/js/appShell.js); Studio's preview writes
   neither attribute, so this matches nothing over there. Every sentence in the
   verse-numbers block above applies here and is not repeated.

   `display: none` AND NOT `content: none`, WHICH IS THE ONE DEPARTURE AND IT IS
   FORCED. The numbers rule could refuse to generate a verse number because a
   verse number is generated content — there is no element, so Off is the page a Bible printed
   without numbers would give, not that page with something painted over. A
   section heading IS an element, carrying a publisher's words, written into the
   letter by the press. There is nothing to un-generate. So this hides a box, and
   the honest statement of what that costs is two things: the heading is still in
   the markup and still in the artifact — which is correct, because the letter is
   the record and a display preference must not edit it — and the PARAGRAPH BREAK
   THE HEADING MADE REMAINS. A heading is a block, so `numberVerses` closed the
   paragraph it landed in and opened a new one after it; hiding the heading does
   not rejoin those halves. A reader with Headings off therefore sees a paragraph
   break where a heading would have been. That is reported rather than repaired:
   repairing it means redrawing the ribbon on every toggle, which is the seam
   this whole pattern exists to avoid, and the break itself is not an error — it
   is where the edition's own editors said a thought turns.

   `.chapter-heading + .section-heading` above is untouched by this, because a
   hidden element is still a child and still matches an adjacent-sibling
   selector; the margin it sets belongs to a box that is not drawn, and the
   chapter header's own 0.2em stands as it did before sections existed. */
[data-headings="off"] .reading-view .section-heading {
  display: none;
}

/* ── One verse per line ──────────────────────────────────────────────────── */

/* THE WHOLE OF VERSE MODE IS ONE DECLARATION, and that is the argument for it
   rather than a boast. A verse is already an element — `nativeToHtml` draws each
   annotation as exactly one `span.segment`, and refuses to draw a page where any
   annotation drew more or fewer — so "every verse begins a new line" is a
   statement about how that element is laid out and nothing else. Flow is the
   same elements, inline. NO CHOICE CHANGES WHAT IS WRITTEN, and here the choice
   does not even change what is MARKED UP: one attribute on a box that outlives
   every redraw, and the ribbon underneath is byte-identical in both modes.

   THE ROAD NOT TAKEN, named because it is the obvious one. The join could have
   emitted each verse as its own block when the setting said Verse — re-running
   js/readingJoin.js with a display preference in hand. That buys exactly these
   pixels and spends the invariant to do it: the module that decides what the
   page SAYS would begin taking an argument about how it LOOKS, the ribbon would
   be rebuilt on every toggle, and a reader's scroll position with it. That
   crossing is the place to stop.

   `[data-verse]` AND NOT BARE `.segment`, which is a claim rather than a
   flourish: what earns a line is a VERSE, not any segment the renderer wrapped.
   In the IKJV the two sets happen to be identical — all 7,957 drawn segments
   carry a verse — so the qualifier buys no pixels today and says what the rule
   means, which is what it is for. In the Disciple Study Bible they are not
   identical at all: 34,465 of its 42,422 segments carry no verse. That window
   never receives the attribute (see below), and if it ever did, this selector is
   the difference between "one verse per line" and "every fragment on its own
   line".

   AN EMPTY VERSE GETS A LINE WITH ITS NUMBER ON IT, which is right and is worth
   saying because the box is empty: the reserved slot draws as its number and
   nothing after it, so in Flow it sits in the run of text and in Verse it takes
   a line of its own — exactly where a printed Bible puts a verse it has nothing
   to print for. The number is the `::before` of this same box, so it comes with
   it and needs no rule.

   THE HEADINGS DO NOT MOVE. All three kinds — book, chapter header, section —
   are blocks that `numberVerses` already placed OUTSIDE the paragraphs, as
   children of the reading view. Nothing here selects them, nothing here changes
   what a paragraph contains, and so a heading stands between exactly the two
   verses it stood between in Flow.

   WHO WRITES THE ATTRIBUTE IS THE HOME'S BUSINESS, exactly as for the two rules
   above. The App writes it, on the Bible window's content box and nowhere else
   (`SCRIPTURE_ATTRIBUTE` in netword-app/js/appShell.js). Studio's preview writes
   none of the three, so this matches nothing over there.

   AND THERE IS NO `="flow"` AND NO `="ref"`. Absence is Flow, so the default
   shell is byte-identical to what it was before this setting could be obeyed;
   and Ref, whose meaning is deferred until it is ruled, renders as Flow by
   writing no attribute rather than by a second rule saying so. A
   `[data-scripture="ref"]` declaration duplicating this one's absence is a
   dead control — it would go on being correct on the day Ref stops being
   Flow. */
[data-scripture="verse"] .reading-view .segment[data-verse] {
  display: block;
}
