/* Local Rules — screen.css
   Foundation stylesheet: tokens, self-hosted type, base rules, and the two
   header objects (masthead + sitebar). See docs/design-spec.md.

   No literal hex values below this import. Every color comes from a custom
   property defined in _tokens.css. The single sanctioned exception —
   the numbox figure staying #17181C in both modes — already lives in
   _tokens.css, not here.
*/

@import "_tokens.css";

/* ==========================================================================
   Type — self-hosted, latin subset, font-display: swap.
   No Google Fonts <link>, no hotlinking. See assets/fonts/README.md for the
   source of each file.
   ========================================================================== */

@font-face {
  font-family: "Barlow Condensed";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/barlow-condensed-v13-latin-500.woff2") format("woff2");
}
@font-face {
  font-family: "Barlow Condensed";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/barlow-condensed-v13-latin-600.woff2") format("woff2");
}
@font-face {
  font-family: "Barlow Condensed";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/barlow-condensed-v13-latin-700.woff2") format("woff2");
}

@font-face {
  font-family: "DM Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/dm-mono-v16-latin-400.woff2") format("woff2");
}
@font-face {
  font-family: "DM Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/dm-mono-v16-latin-500.woff2") format("woff2");
}

/* Source Serif 4 ships from Google as a variable font; one file covers the
   400–600 weight range, referenced twice so `font-weight: 600` resolves to
   its own instance rather than a synthetic bold. */
@font-face {
  font-family: "Source Serif 4";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/source-serif-4-v14-latin-variable.woff2") format("woff2");
}
@font-face {
  font-family: "Source Serif 4";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/source-serif-4-v14-latin-variable.woff2") format("woff2");
}

/* ==========================================================================
   Base / reset beyond what _tokens.css already sets.
   ========================================================================== */

img { max-width: 100%; display: block; }

/* Koenig editor card widths. The editorial column stays at --wrap for text,
   but an author can mark an image "wide" or "full" and it should be able to
   break out of that column rather than being clipped. */
.kg-width-wide {
  width: 100vw;
  max-width: 1040px;
  margin-left: 50%;
  transform: translateX(-50%);
}
.kg-width-full {
  width: 100vw;
  max-width: 100vw;
  margin-left: 50%;
  transform: translateX(-50%);
}

/* ---- links -----------------------------------------------------------------
   NO global underline on hover. It was `a:hover { text-decoration: underline }`,
   which underlined every link in the theme — including `.lr-row`, whose <a> IS
   the row's flex container and therefore contains the numbox. The mark rendered
   as a styled link on hover, which it must never do.

   The row wrap itself is correct and stays: the whole row is a single link
   target, which is what makes it usable at 375px. The fix is that no rule may
   decorate text inside a link generically — each link class states its own
   hover, and the numbox is explicitly immune below. */
a {
  color: inherit;
  text-decoration: none;
}
/* Focus is always visible. Removing the underline removes an affordance, so the
   keyboard affordance is not also removed. */
a:focus-visible {
  outline: var(--rule-major) solid var(--blue);
  outline-offset: 3px;
}

/* The mark is never a link, whatever contains it. Belt and braces: if a future
   template wraps a numbox in an anchor, nothing here can decorate it. */
a .lr-numbox,
a .lr-numbox .fig,
a .lr-numbox .lbl {
  text-decoration: none !important;
}

/* Prose links are the ONE place an underline belongs — it is the reading layer
   and a reader needs to see what is clickable mid-sentence. Persistent hairline,
   solid on hover, so the affordance does not depend on hovering. */
.lr-body a {
  color: var(--blue);
  border-bottom: var(--rule-hair) solid var(--blue-35);
}
.lr-body a:hover {
  border-bottom-color: var(--blue);
}

/* ==========================================================================
   The numbered box — size tiers.
   Built once (partials/numbox.hbs), sized here. `border-width` on the two
   small tiers is a fraction of --numbox-border-width, not a literal value,
   so the dark-stock rule (border drops to 0) applies at every size without
   a second override.
   ========================================================================== */

.nb-xl { width: 132px; height: 132px; gap: 6px; }
.nb-xl .lbl { font-size: 12px; }
.nb-xl .fig { font-size: 62px; }

.nb-md { width: 64px; height: 64px; gap: 2px; }
.nb-md .lbl { font-size: 8px; }
.nb-md .fig { font-size: 30px; }

.nb-sm {
  width: 40px;
  height: 40px;
  gap: 1px;
  border-width: calc(var(--numbox-border-width) * .75);
}
.nb-sm .lbl { font-size: 6px; }
.nb-sm .fig { font-size: 19px; }

 /* Sitebar lockup box. Sized to the wordmark's line (21px), not to a tier —
    see partials/sitebar.hbs for why line height and not cap height. */
.lr-lockup { display: flex; align-items: center; gap: 9px; min-width: 0; }
.nb-mark { width: 21px; height: 21px; border-width: calc(var(--numbox-border-width) * .5); }
.nb-mark .lbl { display: none; }
.nb-mark .fig { font-size: 14px; }

.nb-xs {
  width: 24px;
  height: 24px;
  border-width: calc(var(--numbox-border-width) * .5);
}
.nb-xs .lbl { display: none; }
.nb-xs .fig { font-size: 13px; }

/* Missing number degrades to an em dash rather than a blank yellow square. */
.lr-numbox .fig:empty::after { content: "\2014"; }

/* ==========================================================================
   Masthead — index, archive, tag, author, pages.
   No. 19 at xl beside the large wordmark lockup, tagline, 2px rule below.
   ========================================================================== */

.lr-masthead {
  display: flex;
  align-items: flex-end;
  gap: 24px;
  flex-wrap: wrap;
}
.lr-masthead-type {
  flex: 1 1 220px;
  min-width: 0;
}
.lr-masthead .lr-wordmark { margin: 6px 0 0; }
.lr-masthead .lr-tagline { margin: 12px 0 0; }
.lr-masthead-rule { margin-top: 26px; }

/* ==========================================================================
   Site bar — entry pages (post.hbs). Compact wordmark, no box.
   ========================================================================== */

.lr-sitebar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding-bottom: 11px;
  margin-bottom: 34px;
  border-bottom: var(--rule-major) solid var(--ink);
}
.lr-sitebar-mark {
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  font-size: 21px;
  letter-spacing: .04em;
  line-height: 1;
  margin: 0;
}
.lr-sitebar-tagline {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: .19em;
  text-transform: uppercase;
  color: var(--blue);
  margin: 0;
  text-align: right;
}

/* The site bar must be allowed to wrap. Measured at 375px: the wordmark
   (158px) plus the tagline (173px) plus gaps already need ~345px, against
   327px of content width inside --wrap — so the bar overflowed even BEFORE the
   No. 19 box was added, and horizontal overflow on the page pushes the entry's
   numbox out of its flex row entirely. Wrapping puts the tagline on its own
   line at narrow widths, left-aligned, and keeps it rather than hiding it. */
.lr-sitebar { flex-wrap: wrap; }
@media (max-width: 559px) {
  .lr-sitebar-tagline { flex-basis: 100%; text-align: left; margin-top: 8px; }
}

/* ==========================================================================
   Facet archive — tag.hbs. Every /archive/{slug}/ page: state, ownership,
   architect, access, price band, location, opened, green fee, and the full
   `course` archive. Eyebrow names the facet kind (branched on slug prefix
   in the template), title is the tag's own name — same eyebrow-over-title
   grammar as .lr-entry-head and .lr-piece-head, so a facet page reads as
   the same publication rather than a generic Ghost tag page.
   ========================================================================== */

/* 32px of clearance under the masthead rule, matching .lr-list and .lr-archive.
   Measured 0.0px before this: .lr-masthead-rule carries margin-top only, and
   nothing else sat between it and this header. Only tag.hbs and page.hbs feed
   the masthead straight into their own header — every other top-level page gets
   its space from .lr-list/.lr-archive, and post.hbs is covered by the sitebar's
   34px, which is why this surfaced only after pages stopped using the sitebar.
   Scoped to .lr-facet-head / .lr-page-head so post.hbs's shared .lr-piece-head
   (verified at 34px on /coming-soon/) is untouched. */
.lr-facet-head { margin: 32px 0 0; }
/* Two classes, not one: page.hbs's header is `class="lr-piece-head lr-page-head"`,
   and `.lr-piece-head { margin: 0 }` lives ~550 lines further down this file. At
   equal specificity source order wins, so a bare `.lr-page-head` rule here was
   silently overridden — measured still 0.0px after adding it. The compound
   selector outranks it regardless of order. */
.lr-piece-head.lr-page-head { margin-top: 32px; }
.lr-facet-head .lr-eyebrow { margin: 0; }
.lr-facet-title {
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  font-size: clamp(34px, 9vw, 56px);
  line-height: var(--lh-display);
  letter-spacing: .005em;
  margin: 8px 0 0;
  overflow-wrap: break-word;
}
.lr-facet-rule { margin: 20px 0 0; }
/* The facet's own list reuses .lr-list's top border for its rule, so the
   two rules directly back to back would double the ink. Drop .lr-list's
   own top border only when it follows a facet head. */
.lr-facet-rule + .lr-list { border-top: 0; margin-top: 0; }

/* ==========================================================================
   The facet index — archive.hbs, at /archive/. Every way into the archive
   in one place, grouped by kind, each link a live post count. Institutional
   index-card layout, not a tag cloud: groups stack full-width at 375, move
   to a grid at 768+.
   ========================================================================== */

.lr-archive {
  margin-top: 32px;
  display: grid;
  grid-template-columns: 1fr;
  gap: 34px;
}
@media (min-width: 640px) {
  .lr-archive {
    grid-template-columns: repeat(2, 1fr);
    column-gap: 40px;
  }
}
@media (min-width: 960px) {
  .lr-archive { grid-template-columns: repeat(3, 1fr); }
}

/* A group whose {{#get}} returned no tags yet renders an empty <ul> — hide
   the group rather than show a heading over nothing. */
.lr-facet-group:has(.lr-facet-links:empty) { display: none; }

.lr-facet-group-h {
  font-family: var(--mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: var(--blue);
  margin: 0 0 10px;
  padding-bottom: 8px;
  border-bottom: var(--rule-major) solid var(--ink);
}

.lr-facet-links {
  list-style: none;
  margin: 0;
  padding: 0;
}
.lr-facet-links li {
  border-bottom: var(--rule-hair) solid var(--gray-30);
}
.lr-facet-links a {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 9px 0;
  font-family: var(--display);
  font-weight: 600;
  text-transform: uppercase;
  font-size: 16px;
  letter-spacing: .02em;
  color: inherit;
  text-decoration: none;
}
/* Facet rows: the label goes to ink on hover, matching how a row behaves.
   No underline — these are navigation, not prose. */
/* Background only. An earlier version also darkened `.lr-facet-name`, a class
   no template emits — deleted rather than left as a rule describing an intention
   the CSS does not carry out. */
.lr-facet-links a:hover { background: var(--paper-lt); }
.lr-facet-count {
  font-family: var(--mono);
  font-weight: 400;
  font-size: 11px;
  letter-spacing: .05em;
  color: var(--gray);
  flex: none;
  font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   The archive — index.hbs. One row per course entry.
   Target: docs/reference/local-rules-identity-final.html §03 ("collection").
   sm numbox (40px, same tier the reference uses for this row), course name,
   DM Mono meta line, hairline between rows under a 2px top rule — identical
   border treatment to the reference's .collection/.entry pair.
   ========================================================================== */

.lr-list {
  list-style: none;
  margin: 32px 0 0;
  padding: 0;
  border-top: var(--rule-major) solid var(--ink);
}
.lr-list li { margin: 0; }

.lr-list-empty {
  padding: 16px 2px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .1em;
  text-transform: none;
  color: var(--gray);
}

/* The row is the link. Not an overlay anchor — the <a> itself is the flex
   container, so the entire row (box, title, meta line) is one hit target,
   as required. Colour/decoration reset the same way the wordmark link is
   reset (below): the row is furniture, not a body-copy link, so it does not
   take the blue-underline treatment; focus stays visible for keyboard users. */
.lr-row {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 13px 2px;
  border-bottom: var(--rule-hair) solid var(--gray-30);
  color: inherit;
  text-decoration: none;
}
.lr-row:focus-visible {
  outline: var(--rule-major) solid var(--blue);
  outline-offset: 3px;
}

/* min-width: 0 is load-bearing on a flex child that must be allowed to wrap
   or truncate instead of forcing the row wider than --wrap. */
.lr-row-info { min-width: 0; flex: 1 1 auto; }

/* The course name is the one thing on this row nothing should hide, so it
   wraps rather than truncates. overflow-wrap matches the same rule already
   applied to .lr-entry-title / .lr-piece-title for the same reason. */
.lr-row-ttl {
  display: block;
  font-family: var(--display);
  font-weight: 600;
  text-transform: uppercase;
  font-size: 21px;
  line-height: 1.1;
  letter-spacing: .02em;
  overflow-wrap: break-word;
}

/* The meta line is secondary and, unlike the title, is allowed to truncate —
   same treatment as the reference's .entry .sub (white-space: nowrap +
   ellipsis). Combined with .lr-row-info's min-width: 0 this makes horizontal
   overflow structurally impossible regardless of how long a location or
   ownership name gets: the line either fits or it ellipsizes, it never
   pushes the row wider than the viewport. */
.lr-row-sub {
  display: block;
  margin-top: 4px;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--gray);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Missing facet degrades to an em dash in its own slot rather than a blank
   gap or a stray leading/trailing separator. Same device as .lr-numbox .fig
   and .lr-data > [data-f] above. */
.lr-meta-f:empty::after { content: "\2014"; }

/* ---- /notes/ rows — partials/notes-row.hbs. Same .lr-row rhythm and
   hairline as an entry row, minus the numbox: pieces are not numbered.
   .lr-row-info's flex: 1 1 auto (above) is what pushes the date to the far
   right with no extra layout rule needed here. ---- */
.lr-row-date {
  flex: none;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--gray);
  white-space: nowrap;
}

/* ---- pagination ---- */
.lr-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 26px;
  padding-top: 16px;
  border-top: var(--rule-hair) solid var(--gray-30);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.lr-pagination-count {
  color: var(--gray);
  order: 2;
  flex: 1 1 auto;
  text-align: center;
}
.lr-pagination-link { color: var(--blue); }
.lr-pagination-prev { order: 1; }
.lr-pagination-next { order: 3; }

/* ==========================================================================
   The entry — post.hbs. Target: docs/reference/local-rules-no-01-council-fire.html,
   with the two corrections in docs/design-spec.md (six-field data block,
   THE GAP not Method).
   ========================================================================== */

.lr-entry-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 18px;
}
.lr-entry-head-type { min-width: 0; }

 /* The entry kicker is its own object, not the generic eyebrow. Council Fire
    .head .kick and identity-final .kicker both say 10px / .2em; the shared
    .lr-eyebrow default is 11px / .16em and is used for section labels. */
.lr-kicker {
  margin: 0;
  font-size: 10px;
  letter-spacing: .2em;
}
/* A missing loc- tag degrades to nothing rather than a stray blank line
   above the title. */
.lr-kicker:empty { display: none; }

.lr-entry-title {
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  font-size: clamp(44px, 13vw, 80px);
  line-height: var(--lh-display);
  letter-spacing: .005em;
  margin: 8px 0 0;
}

.lr-dek {
  font-family: var(--body);
  font-size: 19px;
  line-height: 1.5;
  color: var(--ink-70);
  /* The bottom gap lives HERE, not on .lr-data's top margin. The reference
     (.dek margin:16px 0 0 / .datagrid margin:26px 0 34px) puts all the
     separation on the data block, which is fine in a static file that always
     has one — but a course entry whose values block has not been pasted yet
     then runs the dek straight into the lede with zero gap. Total spacing is
     unchanged at 26px; it just no longer depends on the block existing. */
  margin: 16px 0 26px;
  max-width: 44ch;
}

/* ---- data block — six cells, 3x2, authored in the post body -----------------
   The block is a single HTML card at the top of the post, so the values are
   author text and the KEYS ARE THEME CSS. That is the same device as THE GAP:
   a key cannot be misspelled, cannot drift entry to entry, and cannot be given
   the wrong ink, because the author never types it.

   Author markup, one card, six cells:
     <div class="lr-data">
       <p data-f="location">Chattanooga, Tennessee</p>
       ... opened / architect / access / ownership / fee
     </div>

   Blue names the field, gray states it. `data-f` is also the parse handle
   tools/sync-tags.mjs reads to derive the facet tags, which is why it is an
   attribute and not a class. ------------------------------------------------ */
.lr-data {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border-top: var(--rule-major) solid var(--ink);
  border-bottom: var(--rule-major) solid var(--ink);
  margin: 0 0 34px;
}
.lr-data > [data-f] {
  margin: 0;
  padding: 12px 14px;
  border-right: var(--rule-hair) solid var(--gray-30);
  border-bottom: var(--rule-hair) solid var(--gray-30);
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: .05em;
  color: var(--gray);
  font-variant-numeric: tabular-nums;
}
.lr-data > [data-f]::before {
  display: block;
  margin-bottom: 5px;
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: .17em;
  text-transform: uppercase;
  color: var(--blue);
}
.lr-data > [data-f="location"]::before  { content: "Location"; }
.lr-data > [data-f="opened"]::before    { content: "Opened"; }
.lr-data > [data-f="architect"]::before { content: "Architect"; }
.lr-data > [data-f="access"]::before    { content: "Access"; }
.lr-data > [data-f="ownership"]::before { content: "Ownership"; }
.lr-data > [data-f="fee"]::before       { content: "Green fee"; }

.lr-data > [data-f]:nth-child(3n) { border-right: none; }
.lr-data > [data-f]:nth-child(n + 4) { border-bottom: none; }
.lr-data > [data-f]:nth-child(3n + 1) { padding-left: 0; }

/* An empty cell renders an em dash. ::before is not a child node, so :empty
   still matches a cell whose value is missing. Never a hidden row. */
.lr-data > [data-f]:empty::after { content: "\2014"; }

/* Narrow stock drops to 2x3. Three columns inside --wrap at 375px leaves about
   90px of text per cell, and DM Mono 11.5px values like "Chattanooga,
   Tennessee" wrap inside the cell. The reference solves the identical problem
   the same way (.datagrid is 2 columns under 640px, 4 above). Still six cells,
   still never hidden — only the grid geometry changes. */
@media (max-width: 639px) {
  .lr-data { grid-template-columns: repeat(2, 1fr); }
  .lr-data > [data-f]:nth-child(3n) { border-right: var(--rule-hair) solid var(--gray-30); }
  .lr-data > [data-f]:nth-child(n + 4) { border-bottom: var(--rule-hair) solid var(--gray-30); }
  .lr-data > [data-f]:nth-child(3n + 1) { padding-left: 14px; }
  .lr-data > [data-f]:nth-child(2n) { border-right: none; }
  .lr-data > [data-f]:nth-child(2n + 1) { padding-left: 0; }
  .lr-data > [data-f]:nth-child(n + 5) { border-bottom: none; }
}

/* ---- body ---- */
.lr-body p { margin: 0 0 20px; }

/* The lede — larger serif, the finding stated first. CSS-only, no author
   markup: the first paragraph of the body reads as the lede automatically. */
.lr-body > p:first-of-type {
  font-size: 21px;
  line-height: 1.5;
}
.lr-body > p:first-of-type strong { font-weight: 600; }

.lr-body h2 {
  font-family: var(--display);
  font-weight: 600;
  text-transform: uppercase;
  font-size: 27px;
  letter-spacing: .03em;
  line-height: 1.06;
  margin: 42px 0 4px;
}
.lr-body h2 + p { margin-top: 0; }

.lr-body hr {
  border: 0;
  height: var(--rule-hair);
  background: var(--gray-30);
  margin: 40px 0;
}

.lr-body em { font-style: italic; }
.lr-body strong { font-weight: 600; }

.lr-body figcaption {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .05em;
  color: var(--gray);
  margin-top: 8px;
}

.lr-body blockquote {
  margin: 24px 0;
  padding: 0 0 0 16px;
  border-left: 3px solid var(--blue);
}
.lr-body blockquote p {
  margin: 0;
  font-size: 20px;
  line-height: 1.45;
}
.lr-body blockquote cite {
  display: block;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--gray);
  font-style: normal;
  margin-top: 9px;
}

/* ==========================================================================
   In-body components. {{content}} arrives as one blob — a theme cannot
   inject a partial into the middle of it — so these are CSS components
   styled from author markup delivered by Ghost editor snippets
   (docs/snippets.md). See content-model.md §6.
   ========================================================================== */

/* Pull figure. Ruling in docs/design-spec.md: the rule is ink, not pencil —
   yellow is the number box and nothing else. The figure itself is not blue
   either; figures are never blue. */
.lr-pull {
  border-left: 3px solid var(--ink);
  padding: 2px 0 2px 16px;
  margin: 26px 0;
}
.lr-pull-fig {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(32px, 9vw, 40px);
  line-height: 1;
  letter-spacing: .01em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.lr-pull-cap {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--gray);
  margin-top: 7px;
  line-height: 1.5;
}

/* Points — titled argument blocks. CSS only, on h3 + p runs. No wrapper,
   no author burden: an h3 in the body is a point title by definition,
   because h2 already owns the section-header role above. */
.lr-body h3 {
  font-family: var(--display);
  font-weight: 600;
  text-transform: uppercase;
  font-size: 20px;
  letter-spacing: .03em;
  margin: 26px 0 6px;
  padding-top: 16px;
  border-top: var(--rule-hair) solid var(--gray-30);
}
.lr-body h3:first-of-type {
  border-top: var(--rule-major) solid var(--ink);
  margin-top: 26px;
}
.lr-body h3 + p {
  margin-top: 0;
  padding-bottom: 16px;
  border-bottom: var(--rule-hair) solid var(--gray-30);
}

/* THE GAP. The label is theme ::before content, supplied once here, so it
   cannot be misspelled or drift from entry to entry. Required editorial
   component, not a callout widget: dashed border and panel fill keep it
   visually distinct from the rest of the reading layer. */
.lr-gap {
  background: var(--paper-lt);
  border: 1px dashed var(--gray-30);
  padding: 16px 18px;
  margin: 26px 0;
}
.lr-gap::before {
  content: "The Gap";
  display: block;
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--blue);
  margin-bottom: 8px;
}
.lr-gap p {
  margin: 0 0 10px;
  font-size: 16px;
  color: var(--ink-70);
}
.lr-gap p:last-child { margin-bottom: 0; }

/* Sources / Next colophon. */
.lr-colophon {
  margin-top: 52px;
  padding-top: 18px;
  border-top: var(--rule-major) solid var(--ink);
}
.lr-colophon p {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .08em;
  color: var(--gray);
  margin: 0 0 9px;
  line-height: 1.7;
}
.lr-colophon .lr-label {
  display: block;
  color: var(--blue);
  text-transform: uppercase;
  letter-spacing: .17em;
  font-size: 9px;
}

/* ---- the wordmark is a link on every page ---------------------------------
   It must look identical to the text it replaced: the mark is the mark, not a
   link in the reading layer, so it takes none of the blue-underline treatment
   that body links get. Colour and decoration are inherited, so the wordmark
   stays ink and the tagline stays blue. Focus IS visible, because removing the
   only route back to the archive from keyboard users would be worse than a
   ring that never shows for mouse users. */
.lr-wordmark a,
.lr-sitebar-mark a {
  color: inherit;
  text-decoration: none;
  background: none;
  border: 0;
}
/* The wordmark was the only link on the site with no mouse affordance at all.
   It may not change ink — it is the mark — so it dims slightly instead. This is
   the one navigational link present on every page: home. */
.lr-wordmark a:hover,
.lr-sitebar-mark a:hover { opacity: .74; }

.lr-wordmark a:focus-visible,
.lr-sitebar-mark a:focus-visible {
  outline: var(--rule-major) solid var(--blue);
  outline-offset: 3px;
}

/* ---- long tokens must not widen the page -----------------------------------
   Body content is author HTML and will contain URLs, code and long unbroken
   strings. Without this a single token wider than the viewport widens the whole
   layout, and because .lr-entry-head is a flex row the No. NN box is pushed off
   screen entirely — the page looks like the numbox is missing rather than like
   it overflowed. Found at 375px with an inline <code> selector in body copy. */
.lr-body { overflow-wrap: break-word; }
.lr-body pre { overflow-x: auto; max-width: 100%; }
.lr-body code { overflow-wrap: anywhere; word-break: break-word; }
.lr-body img, .lr-body iframe, .lr-body table { max-width: 100%; }
.lr-body table { display: block; overflow-x: auto; }

/* The entry title is a long single word often enough (course names) that it
   needs to break rather than push the numbox out of the row. */
.lr-entry-title, .lr-piece-title { overflow-wrap: break-word; }

/* ---- non-course pieces: essays, biography, industry. Plain article
   furniture, same stock and type, no numbox and no data block. ---- */
/* Type left, marker right — the same grammar as .lr-entry-head, so a piece
   reads as a sibling of an entry rather than as a different publication.
   flex-wrap so the date drops below the title at narrow widths instead of
   squeezing it. */
.lr-piece-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 18px;
  flex-wrap: wrap;
  margin: 0;
}
.lr-piece-head-type { min-width: 0; flex: 1 1 220px; }
.lr-piece-date {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: var(--gray);
  white-space: nowrap;
  flex: none;
  margin: 4px 0 0;
}
/* Echoes the rules that bracket an entry's data block without imitating it. */
.lr-piece-rule {
  border: 0;
  border-top: var(--rule-major) solid var(--ink);
  margin: 20px 0 0;
}
.lr-piece-title {
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  font-size: clamp(38px, 10vw, 64px);
  line-height: var(--lh-display);
  letter-spacing: .005em;
  margin: 0;
}

/* ---- adjacent-entry navigation ---- */
.lr-entry-nav {
  display: flex;
  flex-direction: column;
  gap: 20px;
  margin-top: 40px;
  padding-top: 20px;
  /* Hairline, not the major rule. The colophon above already closes the piece
     with 2px ink; a second full-weight rule directly beneath it reads as a
     doubled footer rather than one institutional close. The nav is
     after-matter, so it recedes. */
  border-top: var(--rule-hair) solid var(--gray-30);
}
.lr-entry-nav:empty { display: none; }
.lr-entry-nav-link { display: block; }
@media (min-width: 640px) {
  .lr-entry-nav {
    flex-direction: row;
    justify-content: space-between;
    gap: 24px;
  }
  .lr-entry-nav-prev { text-align: left; }
  .lr-entry-nav-next { text-align: right; margin-left: auto; }
}
.lr-entry-nav-title {
  display: block;
  font-family: var(--display);
  font-weight: 600;
  text-transform: uppercase;
  font-size: 20px;
  line-height: 1.15;
  margin-top: 4px;
}

/* ---- deliberate hover treatments, one per link class ----------------------
   Rows and navigation shift ground rather than decorating type: the panel
   colour comes forward. Nothing changes the numbox, and nothing underlines. */
/* Background only, same reason: .lr-row-ttl sets no colour, so it is already
   --ink at rest and there was nothing for a hover rule to change. */
.lr-row:hover { background: var(--paper-lt); }

.lr-pagination-link:hover,
.lr-entry-nav-link:hover { color: var(--ink); }
.lr-entry-nav-link:hover .lr-entry-nav-title { color: var(--ink); }

/* Pages are the only place a feature image can appear, and nothing gave it
   spacing — it would sit flush against the rule above and the first paragraph
   below, since .lr-piece-rule is margin-top-only and .lr-body p is
   margin-bottom-only. */
.lr-page-feature { margin: 22px 0; }
