/*
Theme Name: The Reading Room
Theme URI: https://literaryinspired.com
Author: Literary Inspired
Author URI: https://literaryinspired.com
Description: The Reading Room — Literary Inspired's ARC reader hub. The same design system as the main LI site (Fraunces soft/wonky, forest/chartreuse/lavender, chapter chips, tilted hard-shadow cards) in a warmer, bookish, reader-facing register. Block theme — every page is editable in the WordPress editor, no code needed.
Version: 0.38.1
Requires at least: 6.6
Tested up to: 6.8
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: reading-room
Tags: block-patterns, full-site-editing, one-column
*/

/* ==========================================================
   THE READING ROOM · Literary Inspired's reader home.
   Forked from the LI theme v1.3.0 (the canonical token/CSS
   source). Same design system, same class namespace (li-*),
   so li-motion.js and PATTERN_CONVENTIONS.md apply verbatim;
   Reading-Room-only components use the rr-* prefix (foot of
   this file).

   THE WARMER READER-FACING VARIANT IS DEFINED HERE, ONCE,
   AT TOKEN LEVEL — never as per-page overrides:
   · cream / cream-deep / paper warmed a few degrees toward
     gold (candlelight, not office lighting)
   · butter promoted from stray accent to a section colour
     (--li-butter-soft + the butter-soft palette slot)
   · corners softened (--li-radius 22px → 26px)
   Everything else (forest, chartreuse, lavender, type,
   devices, motion) is identical to the main site: this is
   LI's reading room, not a different company.
   ========================================================== */

:root {
  --li-forest: #1d3527;
  --li-forest-deep: #142619;
  --li-chartreuse: #c9d64f;
  --li-chartreuse-soft: #e2ea9c;
  --li-lavender: #b2a1e0;
  --li-lavender-deep: #5c46a8; /* QA-2 port: was #6b54b8 — 4.45:1 on cream-deep. Now 5.51:1. */
  --li-lilac: #ddd4f1;
  --li-butter: #f3c75c;
  --li-butter-soft: #f8e3aa;
  --li-cream: #f7eed9;
  --li-cream-deep: #efdfbd;
  --li-paper: #fdf8e7;
  --li-ink: #1e2019;
  --li-display: "Fraunces", "Cooper Black", Georgia, serif;
  --li-sans: "Hanken Grotesk", -apple-system, sans-serif;
  --li-hand: "Caveat", cursive;
  --li-radius: 26px;
  --li-head-h: 84px;
  --li-pop: cubic-bezier(.34, 1.56, .64, 1);
  /* RR-P4 · the single marginalia dim. Every recessive small-text device
     (footnotes, card dates, price notes, calendar day numbers, cites)
     used to pick its own opacity between .55 and .7, which is how eight
     separate devices ended up failing contrast in eight different ways.
     .8 is the floor that clears 4.5:1 for ink text on the WORST light
     band in the palette — lavender #b2a1e0, which needs .764 — so it is
     safe on every band the theme has. Change it here, nowhere else. */
  --li-dim: .8;
}

/* ==========================================================
   RR-P4 · Inline link colour, band-aware — --li-link
   ----------------------------------------------------------
   ROOT CAUSE (measured, 2026-07-28): theme.json set
   styles.elements.link.color.text = ink, which WordPress emits
   as `:root :where(a:where(:not(.wp-element-button)))`. That
   beats plain inheritance, so every inline link on a dark band
   rendered ink-on-forest: Home's "Get booked" at 1.02:1 and
   "Browse Past ARCs" at 1.16:1, the Terms page's "ARC Service
   Terms" at 1.25:1. Effectively invisible text, and the reason
   was one line of JSON, not the bands. That key is now deleted
   from theme.json and the colour lives here instead.

   The colour is carried as an INHERITED custom property, not as
   a descendant selector, on purpose: a paper card sitting inside
   a forest band resets --li-link for its own subtree for free.
   A `.has-forest… a` rule cannot do that — it would repaint the
   links inside every light card nested in a dark section.

   Specificity is deliberately (0,1,1) and this block sits EARLY,
   so every existing component rule (.li-head a, .li-foot a,
   .li-card--forest a, .li-chip a, .li-pill a, .rr-book__links a)
   still wins on order. This is the default, not an override.
   Chartreuse-on-dark is not a new choice — .li-card--forest a
   already shipped it. Measured: chartreuse on forest 8.31:1,
   on forest-deep 10.00:1; at the --li-dim marginalia opacity,
   5.91:1 and 6.90:1. All clear 4.5. */
:root { --li-link: var(--li-ink); }

/* Dark grounds → chartreuse */
.has-forest-background-color, .has-forest-deep-background-color, .has-ink-background-color,
.has-lavender-deep-background-color,
.li-hero, .li-pagehero, .li-foot { --li-link: var(--li-chartreuse); }

/* Light containers reset for their own subtree — this is what keeps a paper
   card inside a forest band from inheriting a chartreuse link. */
.li-card, .li-pkg, .rr-past, .rr-team, .rr-perm, .rr-monthcal, .rr-slot,
.has-paper-background-color, .has-cream-background-color, .has-cream-deep-background-color,
.has-lavender-background-color, .has-lilac-background-color, .has-butter-background-color,
.has-butter-soft-background-color, .has-chartreuse-background-color,
.has-chartreuse-soft-background-color { --li-link: var(--li-ink); }

/* …and the dark components re-assert, after the light reset above. */
.li-card--forest, .li-card--ink, .li-pkg--feature, .rr-monthcal__detail { --li-link: var(--li-chartreuse); }

/* Chips paint their own ground, so they set their own link colour. */
.li-chip { --li-link: var(--li-forest-deep); }
.li-chip--outline { --li-link: var(--li-cream); }

a:not(.wp-element-button) { color: var(--li-link); }

html { scroll-behavior: smooth; }
body {
  /* `clip`, not `hidden`: overflow-x:hidden forces overflow-y to `auto`, which
     turns <body> into the scroll container (breaks window.scrollTo, scroll
     anchoring, and scroll-linked motion). `clip` gives the same horizontal
     protection with no scroll container. Paired with .wp-site-blocks below.
     Ported from the LI theme, E2-B. */
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
}
/* Contains every rotated/tilted full-bleed band (present and future) — a
   .li-marquee--tilt otherwise pushes the document ~5px wide at 390px. */
.wp-site-blocks { overflow-x: clip; }

/* Paper grain (front end only — JS adds li-js) */
body.li-js::after {
  content: "";
  position: fixed; inset: 0;
  pointer-events: none; z-index: 9990;
  opacity: 0.06;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E");
}

::selection { background: var(--li-chartreuse); color: var(--li-ink); }

/* ---------- Display type: soft, chunky, a little wonky ---------- */
h1, h2, h3, h4,
.li-display {
  font-family: var(--li-display);
  font-optical-sizing: auto;
  font-variation-settings: "SOFT" 100, "WONK" 1;
  font-weight: 600;
  letter-spacing: -0.015em;
}
h1 em, h2 em, h3 em, .li-display em {
  font-style: italic;
  font-weight: 480;
}
h2 em { color: var(--li-lavender-deep); }
.has-forest-background-color h2 em,
.has-forest-deep-background-color h2 em { color: var(--li-chartreuse); }

/* Long-form emphasis keeps the display italic feel */
.li-prose em, .li-readmore em { font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; }

/* ---------- Buttons (core button block) ---------- */
.wp-block-button .wp-block-button__link {
  font-family: var(--li-sans); font-weight: 700; font-size: 1rem;
  padding: 1rem 1.9rem; border-radius: 999px;
  border: 2px solid var(--li-ink);
  background: transparent; color: var(--li-ink);
  transition: transform .25s var(--li-pop), background-color .25s, color .25s, box-shadow .25s;
  will-change: transform;
}
.wp-block-button .wp-block-button__link:hover { box-shadow: 4px 4px 0 var(--li-ink); }
.is-style-li-chartreuse .wp-block-button__link { background: var(--li-chartreuse); color: var(--li-ink); }
.is-style-li-chartreuse .wp-block-button__link:hover { background: var(--li-chartreuse-soft); }
.is-style-li-lavender .wp-block-button__link { background: var(--li-lavender); color: var(--li-ink); }
.is-style-li-lavender .wp-block-button__link:hover { background: var(--li-lilac); }
.is-style-li-butter .wp-block-button__link { background: var(--li-butter); color: var(--li-ink); }
.is-style-li-ghost-light .wp-block-button__link { border-color: var(--li-cream); color: var(--li-cream); background: transparent; }
.is-style-li-ghost-light .wp-block-button__link:hover { background: var(--li-cream); color: var(--li-forest); box-shadow: 4px 4px 0 rgba(0,0,0,.25); }
.li-btn-big .wp-block-button__link { padding: 1.3rem 2.4rem; font-size: clamp(1rem, 2vw, 1.25rem); }
/* Safety net: a variant-less button on a dark band would be ink-on-ink and read
   as bare underlined text. Give any un-styled button on forest / forest-deep /
   lavender-deep the ghost-light chrome so no button is ever invisible. Every
   button should still carry one of the four variants; this only catches misses. */
.has-forest-background-color .wp-block-button:not([class*="is-style"]) .wp-block-button__link,
.has-forest-deep-background-color .wp-block-button:not([class*="is-style"]) .wp-block-button__link,
.has-lavender-deep-background-color .wp-block-button:not([class*="is-style"]) .wp-block-button__link {
  border-color: var(--li-cream); color: var(--li-cream); background: transparent;
}

/* ---------- Header ---------- */
.li-head {
  position: fixed; top: 0; left: 0; right: 0; z-index: 1000;
  min-height: var(--li-head-h);
  display: flex; align-items: center; justify-content: space-between; gap: 1.5rem;
  padding: 0 clamp(1.2rem, 4vw, 3rem);
  /* QA-2 port · Safari fallback FIRST. Below WebKit 16.2 the color-mix()
     declaration is dropped wholesale, leaving a transparent fixed header
     over scrolling content. This plain rgba() is #142619 at 88%. */
  background: rgba(20,38,25,.88);
  background: color-mix(in srgb, var(--li-forest-deep) 88%, transparent);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid rgba(245,239,223,.12);
  color: var(--li-cream);
  transition: transform .45s ease;
}
body.admin-bar .li-head { top: var(--wp-admin--admin-bar--height, 32px); }
.li-head.is-hidden { transform: translateY(-100%); }
.li-head a { color: var(--li-cream); text-decoration: none; }
.li-head__logo p {
  font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1;
  font-weight: 560; font-size: 1.45rem; letter-spacing: .005em; white-space: nowrap; margin: 0;
}
/* Lavender, never chartreuse. Meg's rule, 2026-08-03: the accent is assigned
   PER BRAND, not per background — the Reading Room's accent is lilac and
   Literary Inspired's is chartreuse. This rule supersedes the older
   "lavender-on-dark / chartreuse-on-light" split recorded further down this
   file for the logo lockups. Nothing in the RR markup carries `.li-mark`
   today (the drawn logo replaced the text stand-in), so this is here to stop
   the chartreuse creeping back if the text lockup is ever restored. */
.li-head__logo .li-mark { color: var(--li-lavender); display: inline-block; margin: 0 .08em; font-size: .8em; font-style: normal; }
/* ---------- Core navigation block inside the header (ported from the LI
   theme, E2-B item A-1). Without real inner blocks the navigation block falls
   back to listing EVERY published page — which is what the Reading Room was
   shipping. The real menu now lives inline in parts/header.html. ---------- */
.li-head .wp-block-navigation a { font-weight: 600; font-size: .95rem; position: relative; }
.li-head .wp-block-navigation a:hover { color: var(--li-chartreuse); }
.li-head .wp-block-navigation__submenu-container {
  background: var(--li-forest-deep) !important;
  border-radius: 16px; border: 1.5px solid rgba(245,239,223,.16);
  padding: .5rem; min-width: 252px;
  box-shadow: 0 18px 40px rgba(0,0,0,.34);
  transform: translateY(-8px) rotate(-.5deg); opacity: 0;
  transition: opacity .22s ease, transform .3s var(--li-pop);
}
.li-head .wp-block-navigation-item:hover > .wp-block-navigation__submenu-container,
.li-head .wp-block-navigation-item:focus-within > .wp-block-navigation__submenu-container,
.li-head .wp-block-navigation__submenu-container:hover,
.li-head .wp-block-navigation-item .wp-block-navigation__submenu-container[aria-hidden="false"] {
  opacity: 1; transform: translateY(0) rotate(0);
}
.li-head .wp-block-navigation__submenu-container a {
  color: var(--li-cream) !important; display: block;
  padding: .58rem .85rem !important; border-radius: 10px; font-size: .9rem !important;
  transition: background .2s ease, transform .2s var(--li-pop), color .2s ease;
}
.li-head .wp-block-navigation__submenu-container a:hover,
.li-head .wp-block-navigation__submenu-container a:focus-visible {
  background: rgba(201,214,79,.14); color: var(--li-chartreuse) !important; transform: translateX(5px);
}
.li-head .wp-block-navigation__submenu-container .wp-block-navigation-item__label::after { display: none; }
/* stagger the submenu items in behind the container */
.li-head .wp-block-navigation__submenu-container > .wp-block-navigation-item { opacity: 0; transform: translateX(-6px); transition: opacity .24s ease, transform .24s var(--li-pop); }
.li-head .wp-block-navigation-item:hover > .wp-block-navigation__submenu-container > .wp-block-navigation-item,
.li-head .wp-block-navigation-item:focus-within > .wp-block-navigation__submenu-container > .wp-block-navigation-item { opacity: 1; transform: translateX(0); }
.li-head .wp-block-navigation__submenu-container > .wp-block-navigation-item:nth-child(1) { transition-delay: .04s; }
.li-head .wp-block-navigation__submenu-container > .wp-block-navigation-item:nth-child(2) { transition-delay: .07s; }
.li-head .wp-block-navigation__submenu-container > .wp-block-navigation-item:nth-child(3) { transition-delay: .10s; }
.li-head .wp-block-navigation__submenu-container > .wp-block-navigation-item:nth-child(4) { transition-delay: .13s; }
.li-head .wp-block-navigation__submenu-container > .wp-block-navigation-item:nth-child(5) { transition-delay: .16s; }
.li-head .wp-block-navigation__submenu-container > .wp-block-navigation-item:nth-child(6) { transition-delay: .19s; }

/* mobile overlay.
   GOTCHA (found E2-B on the LI theme, same header CSS here): .li-head carries
   backdrop-filter, and a backdrop-filter makes the element a CONTAINING BLOCK
   for position:fixed descendants — which clips the whole overlay to the 84px
   header and leaves it white-on-white. Dropping the filter while the menu is
   open releases the overlay back to the viewport. Do not re-add
   backdrop-filter unconditionally. */
.li-head:has(.wp-block-navigation__responsive-container.is-menu-open) {
  backdrop-filter: none; -webkit-backdrop-filter: none;
  background: transparent; border-bottom-color: transparent;
}
.li-head .wp-block-navigation__responsive-container.is-menu-open {
  position: fixed; inset: 0; height: auto; width: auto;
  background: var(--li-forest-deep) !important;
  color: var(--li-cream) !important;
  padding: 5.5rem clamp(1.4rem, 6vw, 2.5rem) 2.5rem;
  overflow-y: auto;
}
body.admin-bar .li-head .wp-block-navigation__responsive-container.is-menu-open { top: var(--wp-admin--admin-bar--height, 32px); }
.li-head .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
  align-items: flex-start; gap: .3rem;
}
.li-head .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item { color: var(--li-cream); }
.li-head .wp-block-navigation__responsive-container.is-menu-open a { font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; font-size: 1.6rem; color: var(--li-cream); }
.li-head .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container {
  opacity: 1; transform: none; border: 0; box-shadow: none; background: transparent !important; padding-left: .6rem;
}
.li-head .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container > .wp-block-navigation-item { opacity: 1; transform: none; }
.li-head .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container a { font-size: 1.05rem !important; opacity: .85; }
/* staggered entrance for the overlay's top-level items */
.li-head .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container > .wp-block-navigation-item {
  animation: li-navin .38s var(--li-pop) backwards;
}
.li-head .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container > .wp-block-navigation-item:nth-child(1) { animation-delay: .05s; }
.li-head .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container > .wp-block-navigation-item:nth-child(2) { animation-delay: .10s; }
.li-head .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container > .wp-block-navigation-item:nth-child(3) { animation-delay: .15s; }
.li-head .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container > .wp-block-navigation-item:nth-child(4) { animation-delay: .20s; }
.li-head .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container > .wp-block-navigation-item:nth-child(5) { animation-delay: .25s; }
.li-head .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container > .wp-block-navigation-item:nth-child(6) { animation-delay: .30s; }
.li-head .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container > .wp-block-navigation-item:nth-child(7) { animation-delay: .35s; }
@keyframes li-navin { from { opacity: 0; transform: translateY(14px) rotate(-1.2deg); } to { opacity: 1; transform: none; } }
.li-head .wp-block-navigation__responsive-container-open,
.li-head .wp-block-navigation__responsive-container-close { color: var(--li-cream); }
/* Space below fixed header comes from hero padding (heroes are dark, header floats over) */
@media (max-width: 640px) {
  .li-head { gap: .8rem; }
  .li-head__logo p { font-size: 1.15rem; }
  .li-head .wp-block-button__link { padding: .55rem 1rem; font-size: .82rem; white-space: nowrap; }
}

/* ---------- Shared devices ---------- */
.li-label {
  display: inline-block; font-weight: 700; font-size: .8rem;
  letter-spacing: .22em; text-transform: uppercase; color: var(--li-forest);
  font-family: var(--li-sans);
}
.li-label::before { content: "✦ "; color: var(--li-lavender-deep); }

.li-chapter { display: flex; align-items: center; gap: .9rem; flex-wrap: wrap; color: var(--li-forest); margin-bottom: 1.6rem; }
.li-chapter p { margin: 0; }
.li-chapter__num {
  font-family: var(--li-display); font-style: italic; font-weight: 480;
  font-variation-settings: "SOFT" 100, "WONK" 1;
  font-size: 1.05rem; letter-spacing: .04em;
  border: 1.5px dashed currentColor; border-radius: 999px;
  padding: .3rem 1.05rem;
}
.li-chapter__name { font-weight: 700; font-size: .8rem; letter-spacing: .2em; text-transform: uppercase; font-family: var(--li-sans); }
.li-chapter--light, .has-forest-background-color .li-chapter, .has-forest-deep-background-color .li-chapter { color: var(--li-chartreuse); }
.li-chapter--center { justify-content: center; }
/* Reader-first (2026-08-24): the Reading Room sheds the LI chapter-chip
   signature site-wide ("Chapter 01 / On the shelf right now", "Final chapter",
   FAQ "Footnotes"). The chips stay in the markup so the LI site keeps them and
   so a section's heading is untouched; they are simply hidden on this site. */
.li-chapter { display: none !important; }

/* Interior page header (reader-first, 2026-08-24): replaces the full-height
   hero on inner pages so the page opens on content, not a wall of air (Meg's
   "it opens horrible / too much padding"). A plain centred heading and a
   one-line lede, nothing else. The homepage keeps its hero; every other page
   uses this. */
.rr-pagehead { text-align: center; padding-top: clamp(1.8rem, 4vw, 3rem); padding-bottom: clamp(1rem, 2.6vw, 1.8rem); }
.rr-pagehead h1 { font-size: clamp(2.1rem, 1.5rem + 2.8vw, 3.4rem); }
.rr-pagehead .li-lede { margin: 1rem auto 0; }

/* Process strip band (reader-first): the slim "how it works" strip is its own
   component now (rr_process_strip_markup) and carries NO section heading, lede,
   or trailing pull-quote — just the six steps. Tighter vertical rhythm than a
   normal section so it reads as a strip, not a full band. */
.rr-procband { padding-top: clamp(1.8rem, 4vw, 2.8rem); padding-bottom: clamp(1.8rem, 4vw, 2.8rem); }

/* Standalone "See All …" button rows sit centred with real breathing room above
   and below, not jammed against the band on either side (Meg's centred-buttons
   note, 2026-08-24). */
.rr-seeall { margin: clamp(1.6rem, 3.5vw, 2.6rem) auto !important; }

/* FAQ live filter (reader-first, 2026-08-24): a plain search over the Q&As so a
   reader types what they need instead of scrolling three tiers. Progressive
   enhancement — with JS off, every question shows and the box simply sits there
   (li-motion.js reveals its behaviour). */
.rr-faq-search-wrap { max-width: 560px; margin: 1.5rem auto 0; text-align: left; }
.rr-faq-search {
  width: 100%; font-family: var(--li-sans); font-size: 1rem;
  padding: .9rem 1.2rem; border-radius: 999px; border: 2px solid var(--li-ink);
  background: var(--li-paper); color: var(--li-ink); box-shadow: 4px 4px 0 var(--li-ink);
}
.rr-faq-search::placeholder { color: rgba(30,32,25,.55); }
.rr-faq-search:focus-visible { outline: 3px solid var(--li-lavender-deep); outline-offset: 2px; }
.rr-faq-search__none { margin: 1rem 0 0; font-family: var(--li-hand); font-size: 1.35rem; color: var(--li-lavender-deep); text-align: center; }
.wp-block-details.rr-faq-hide, .li-faq-section.rr-faq-hide { display: none !important; }
.rr-faq-search mark, .li-faq mark.rr-faq-hit { background: var(--li-chartreuse-soft); color: inherit; }

.li-chip {
  display: inline-block; font-weight: 700; font-size: .8rem; letter-spacing: .06em;
  padding: .45rem 1rem; border-radius: 999px; font-family: var(--li-sans);
  background: var(--li-chartreuse); color: var(--li-forest-deep); transform: rotate(-2deg);
  margin: 0;
}
.li-chip--outline { background: transparent; color: var(--li-cream); border: 1.5px dashed var(--li-cream); transform: rotate(1.5deg); }
.li-eyebrow { display: flex; gap: .8rem; justify-content: center; flex-wrap: wrap; margin-bottom: 2.2rem; }

/* Handwriting margin note */
.li-note {
  font-family: var(--li-hand) !important; font-weight: 500;
  font-size: 1.45rem !important; line-height: 1.2;
  color: var(--li-lavender-deep);
  /* rr-final-1 · port of Meg's 2026-07-22 LI ruling, which never reached RR:
     handwritten notes CENTRE by default. As `inline-block` with no margins the
     note took the parent's text-align, and in a left-aligned band that put it
     hard against the left edge — "step five: immediately join another team"
     and "3,400+ readers already have a seat in here" both did exactly that,
     measured 26px and 13px from the padding box with 520px and 823px of empty
     band to their right. Block + auto margins centres the ROTATED note
     regardless of the parent's text-align. `.li-note--left` is the opt-out for
     a spot we genuinely want in the left margin.
     The note must also be named in the A1 centring allowlist further down —
     auto margins alone lose to A1 on specificity. */
  transform: rotate(-2deg); display: block; width: fit-content;
  margin-left: auto; margin-right: auto; text-align: center;
}
.li-note--left { margin-left: 0; margin-right: auto; text-align: left; }
.has-forest-background-color .li-note, .has-forest-deep-background-color .li-note, .li-note--light { color: var(--li-lavender); }

/* rr-final-1 · opacity taken off `--li-dim` (.8) and pinned to LI's .65. The
   footnote is the quietest voice on the page and RR was printing it a fifth
   louder than LI does. `--li-dim` stays where it belongs — on the micro-labels
   and day numbers that RR-P4 introduced it for. */
.li-footnote { font-size: .85rem !important; font-style: italic; font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 420; opacity: .65; }

/* ---------- Heroes ---------- */
.li-hero, .li-pagehero {
  position: relative; overflow: hidden;
  background: var(--li-forest); color: var(--li-cream);
  text-align: center;
  padding: calc(var(--li-head-h) + clamp(3rem, 7vw, 5rem)) clamp(1.2rem, 5vw, 4rem) clamp(4rem, 8vw, 6rem);
}
.li-hero { min-height: 92svh; display: grid; align-content: center; }
.li-hero > *, .li-pagehero > * { position: relative; z-index: 2; }
.li-hero h1, .li-pagehero h1 {
  font-size: clamp(2.6rem, 7vw, 5.8rem); line-height: 1.02;
  max-width: 16ch; margin-left: auto; margin-right: auto;
}
.li-pagehero h1 { font-size: clamp(2.4rem, 5.8vw, 4.6rem); max-width: 18ch; }
.li-hero h1 em, .li-pagehero h1 em { color: var(--li-chartreuse); font-style: italic; }
.li-hero__sub, .li-pagehero__sub {
  max-width: 58ch; margin: 2rem auto 0;
  font-size: clamp(1.02rem, 1.6vw, 1.22rem); color: rgba(245,239,223,.82); font-weight: 500;
}
.li-hero .wp-block-buttons, .li-pagehero .wp-block-buttons { justify-content: center; margin-top: 2.4rem; }
.li-hero .li-note, .li-pagehero .li-note { margin-top: 2.4rem; }
.li-hero .li-footnote, .li-pagehero .li-footnote { margin-top: 2.2rem; color: rgba(245,239,223,.6); opacity: 1; }

/* squiggle underline under the <em> in a hero H1 (drawn in by JS) */
.li-squiggle-wrap { position: relative; display: inline-block; }
.li-squiggle-svg { position: absolute; left: -2%; right: -4%; bottom: -.34em; width: 104%; height: auto; overflow: visible; pointer-events: none; }
.li-squiggle-svg path { fill: none; stroke: var(--li-lavender); stroke-width: 6; stroke-linecap: round; }

/* Google stamp */
.li-stamp {
  position: absolute; z-index: 3;
  top: calc(var(--li-head-h) + 2rem); right: clamp(1rem, 4vw, 4rem);
  display: grid; gap: .15rem; place-items: center;
  padding: 1.1rem 1.4rem;
  border: 2px dashed var(--li-butter); border-radius: 14px;
  color: var(--li-butter);
  transform: rotate(5deg);
  transition: transform .35s var(--li-pop);
  background: rgba(20,38,25,.4);
}
.li-stamp:hover { transform: rotate(-2deg) scale(1.06); }
.li-stamp p { margin: 0; }
.li-stamp__stars { letter-spacing: .2em; font-size: .9rem; }
.li-stamp__score { font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; font-size: 1.3rem; }
.li-stamp__count { font-size: .75rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; opacity: .85; }
@media (max-width: 1100px) { .li-stamp { position: static; width: fit-content; margin: 2.4rem auto 0; transform: rotate(-1deg); } }

/* Floating decorative shapes (injected by JS into .li-hero / .li-pagehero) */
.li-shapes { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.li-shape { position: absolute; will-change: transform; }
.li-shape--spark1 { width: 40px; top: 20%; left: 11%; }
.li-shape--spark1 path { fill: var(--li-butter); }
.li-shape--spark2 { width: 26px; top: 66%; right: 13%; }
.li-shape--spark2 path { fill: var(--li-lavender); }
.li-shape--asterisk { width: 60px; top: 56%; left: 7%; }
.li-shape--asterisk line { stroke: var(--li-chartreuse); stroke-width: 9; stroke-linecap: round; }
.li-shape--squiggle { width: 180px; top: 13%; right: 8%; }
.li-shape--squiggle path { fill: none; stroke: var(--li-lavender); stroke-width: 7; stroke-linecap: round; }
.li-shape--book { width: 78px; bottom: 13%; right: 23%; }
.li-shape--book path { fill: none; stroke: var(--li-chartreuse); stroke-width: 5; stroke-linejoin: round; }
/* RR-P3 (2026-07-28) · the Home H1 "ghost".
   The audit saw a faint grey ghost of a W and an h behind "Where" at x≈250-330
   and flagged it as possibly a duplicated text layer or animation residue.
   Measured instead: the H1 has exactly 5 .li-w spans (one per word), no
   text-shadow, no ::before, no ::after, and no repeated word. The ghost is THIS
   shape — a 130px cream loop at 30% opacity, which at 1280 landed at
   [249, 335, 135, 75], directly behind the first word of an 88px headline. Its
   two curves read as glyphs. Not a capture artefact; a real placement fault.
   Moved below the headline band and dimmed, so it stays decoration instead of
   masquerading as double-printed type. */
.li-shape--loop { width: 118px; top: 71%; left: 5%; }
.li-shape--loop path { fill: none; stroke: rgba(245,239,223,.2); stroke-width: 6; stroke-linecap: round; }
@media (max-width: 760px) { .li-shape--asterisk, .li-shape--book, .li-shape--loop { display: none; } }
body.li-js .li-shape { animation: li-float 3s ease-in-out infinite alternate; }
.li-shape:nth-child(2n) { animation-duration: 3.6s; animation-delay: .4s; }
.li-shape:nth-child(3n) { animation-duration: 4.2s; animation-delay: .8s; }
@keyframes li-float { from { translate: 0 0; rotate: -4deg; } to { translate: 0 14px; rotate: 5deg; } }

/* Rotating badge (JS injects into .li-hero) */
.li-badge {
  position: absolute; z-index: 3;
  left: clamp(0.5rem, 2.5vw, 3rem); bottom: 3.5%;
  width: 116px; height: 116px; display: grid; place-items: center;
  color: var(--li-cream);
}
.li-badge svg { position: absolute; inset: 0; animation: li-spin 16s linear infinite; }
.li-badge text { font-size: 10px; font-weight: 700; letter-spacing: .16em; fill: var(--li-cream); font-family: var(--li-sans); }
.li-badge__mark { font-size: 2rem; color: var(--li-chartreuse); }
@keyframes li-spin { to { transform: rotate(360deg); } }
@media (max-width: 1100px) { .li-badge { display: none; } }

/* ---------- Marquee ----------
   RR-P3 (2026-07-28) · rotation and clipping are now on SEPARATE elements.

   ROOT CAUSE of "the scrolling banner is appalling": `overflow:hidden` and
   `transform:rotate()` sat on the same element, so the clipping box rotated
   with the content and sheared every ascender and descender, and the old
   `scale(1.02)` was nowhere near enough to cover the wedge the rotation opens.

   THE GEOMETRY, derived rather than eyeballed. A bar of width W rotated by θ
   about its centre lifts one end by W·tan(θ)/2 and drops the other by the same,
   so a band shows a raw triangle of page colour at each end unless the bar
   bleeds past its own box by that much, top and bottom:

       bleed = 50vw · tan(θ)        θ = 1.2°, tan θ = 0.020945
             = 13.4px at 1280 · 20.1px at 1920 · 4.1px at 390

   +2px covers the ink border. The wrapper carries the rotation and
   `overflow: visible`; the rail carries the background, the borders and the
   `overflow: hidden` that the horizontal scroll actually needs. Negative
   margins on the wrapper absorb the bleed so the tilt overlaps its neighbours
   (which is the design) instead of adding vertical space.

   ---- rr-final-1 (2026-08-02) · PARITY WITH LI. Meg's item 1. ----

   Two RR-P3 decisions are reversed here, both on her instruction, and both
   were making the bar read as a different brand from the LI bar it is meant
   to mirror. Measured in Chrome at 1280 on the real rendered pages:

                          RR (v0.11.0)   LI (v1.17.x)
     rail height              119px          99px
     word size               19.2px        24.8px

     — a bar 20% taller carrying type 23% smaller. That is the whole of
     "the proportions are all wrong".

   1. THE BLEED WAS COUNTED TWICE. It was added to `padding-block` AND
      subtracted as negative `margin-block`. Only the margin is load-bearing.
      Work the wedge condition through: the wrapper's margin box ends
      `H/2 − bleed` from the bar's centre line, and the rotated bar's own edge
      at the far column sits `H/2 − 50vw·tanθ` from it. The bar still covers
      the boundary by `bleed − 50vw·tanθ` = **+2px, at every viewport width**,
      because that +2 is exactly the constant in the bleed formula. So the
      padding never needed the bleed, and adding it inflated the painted bar
      by 2×bleed (30.8px at 1280) for nothing. Verified: 0 cream wedge at
      390/768/1280/1920 after the change, same as before it.
   2. THE WORD SCALE GOES BACK UP to LI's `clamp(1.1rem, 2.3vw, 1.55rem)`.
      RR-P3 reduced it to `clamp(.95rem, 1.6vw, 1.2rem)` as a judgment call
      ("read as a runaway ticker"); Meg has overruled that. The explicit
      `line-height: 1.5` goes too — LI sets none, so the line box follows the
      body line-height, and that is what makes the two rails the same height.

   The `li-tilt` wrapper/rail structure STAYS. It is the anti-shear fix and
   PATTERN_CONVENTIONS.md makes it canonical; do not regress to LI's
   single-element `.li-marquee--tilt` form, which is what sheared the glyphs. */
.li-marquee {
  overflow: hidden; padding: var(--li-marq-pad, 1.1rem) 0; white-space: nowrap;
  border-top: 2px solid var(--li-ink); border-bottom: 2px solid var(--li-ink);
  background: var(--li-chartreuse); color: var(--li-forest-deep);
}
.li-marquee--lavender { background: var(--li-lavender); color: var(--li-ink); }
.li-marquee--lilac { background: var(--li-lilac); color: var(--li-ink); }
/* Homepage marquee, reader-first (2026-08-24): cream/paper, not purple, and the
   highlights spaced so they read easily rather than running together (Meg). */
.li-marquee--cream { background: var(--li-cream-deep); color: var(--li-ink); }
.li-marquee--cream .li-spark { color: var(--li-lavender-deep); }
.li-marquee .li-spark { margin: 0 .95em !important; }

/* The tilt wrapper. Never put a background or a border here — it does not clip,
   so anything painted on it would show its own untinted corners. */
.li-tilt {
  --li-tilt-angle: -1.2deg;
  --li-tilt-bleed: calc(50vw * 0.020945 + 2px);
  position: relative; z-index: 2;
  overflow: visible;
  transform: rotate(var(--li-tilt-angle));
  transform-origin: 50% 50%;
  margin-block: calc(var(--li-tilt-bleed) * -1);
}
/* The rail inside a tilt wrapper bleeds HORIZONTALLY only, so the rotated ends
   still reach past both viewport corners. Vertical cover comes from the
   wrapper's negative margin-block alone — see the +2px proof in the block
   comment above. Do not re-add `+ var(--li-tilt-bleed)` to the padding. */
.li-tilt > .li-marquee {
  margin-inline: calc(var(--li-tilt-over, 3rem) * -1);
  padding-inline: var(--li-tilt-over, 3rem);
}
/* Legacy single-element form. Kept so a pattern that has not been re-cut yet
   degrades to a straight, unsheared bar instead of a clipped tilted one. */
.li-marquee--tilt { transform: none; }

.li-marquee p, .li-marquee__track span {
  font-family: var(--li-display); font-style: italic; font-weight: 500;
  font-variation-settings: "SOFT" 100, "WONK" 1;
  font-size: clamp(1.1rem, 2.3vw, 1.55rem); letter-spacing: .03em; margin: 0;
}
/* No vertical clip on the line box: `overflow:hidden` here is what cut the
   glyphs. Horizontal runover is handled by the rail. */
.li-marquee p { overflow: visible; }
.li-marquee__track { display: inline-flex; align-items: center; animation: li-marquee 28s linear infinite; }
.li-marquee__track span { padding-right: .5ch; }
/* rr-final-1 · ported from LI (S3·8, 2026-08-02), and it is the last 11px of
   the height parity. Two things inflate this line box if left alone:
     1. WordPress's `> * + *` block gap puts a stray 20px margin-top on the
        JS-on version of the paragraph, which the JS-off version never has —
        so the two states did not even match each other.
     2. The ✦ separator falls back to a font with a huge ascent/descent, which
        pushes the line box far past what the type needs. RR's marquee line
        uses the same glyph, so it inherited the same defect.
   Measured after: RR rail 68px at 1280 against LI's 70px. */
.li-marquee > * { margin-block-start: 0 !important; }
.li-marquee p, .li-marquee__track span { line-height: 1.15; }
.li-marquee--reverse .li-marquee__track { animation-direction: reverse; }
@keyframes li-marquee { to { transform: translateX(-50%); } }

/* ---------- Past releases banner ----------
   RR-P3 (2026-07-28) · rebuilt as a DOM track of individual covers.

   It used to be three pre-composited 12,180×300 JPEG strips, ~1MB each, each
   emitted twice: 3.12MB decoding ~22 million pixels to paint a band 140px tall.
   That is what made it render EMPTY for about six seconds — Meg read the empty
   band as "white gaps" — and being one flat image, it was a frozen snapshot
   that could never pick up a new cover.

   Now each cover is its own lazy, srcset-ed <img>, generated from
   past-arcs.php, so the band regenerates when the shelf does. The duplicate
   half of each track reuses the SAME URLs, so the seamless loop costs zero
   extra bytes — the browser serves the second copy from cache.

   Scroll speed is not a magic number here: rr_pastarcs_banner_markup() divides
   the real track distance by a target px/s and writes the result into
   --li-arc-dur per row, so the speed stays inside the 40-80px/s comfort band
   whatever the cover count does. */
.li-arcwall { margin-top: 2.4rem; display: block; }
.li-arcrow {
  overflow: hidden; margin: 0 0 clamp(.55rem, 1.4vw, .9rem);
  /* rr-final-1 · THE NO-EMPTY-BAND RULE. The row reserves its own height from
     the token, not from whatever its <img>s happen to have decoded. Without it
     a row whose covers have not painted yet collapses to 0 and the band reads
     as the blank forest void Meg called "white gaps" — the same symptom the
     composited strips produced, arriving by a different route. */
  min-height: clamp(96px, 12vw, 140px);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
}
.li-arctrack {
  display: flex; flex-wrap: nowrap; align-items: flex-end;
  gap: clamp(.5rem, 1.3vw, .85rem);
  width: max-content;
  animation: li-arcscroll var(--li-arc-dur, 90s) linear infinite;
  will-change: transform;
}
.li-arctrack--rev { animation-direction: reverse; }
.li-arcrow:hover .li-arctrack { animation-play-state: paused; }
/* ⚠ rr-final-1 · BOTH SELECTORS, DELIBERATELY. `.li-arctrack__img` is the class
   the helper puts on the WRAPPER; `.li-arctrack__img img` is the descendant.
   The descendant form alone is what let one cover escape its height cap for a
   month — see the rr_picture() header in functions.php. Naming both means the
   cap holds whether the class lands on a <picture>, a <span> or an <img>. */
.li-arctrack__img { margin: 0 !important; flex: 0 0 auto; display: block; line-height: 0; }
.li-arctrack__img, .li-arctrack__img img {
  width: auto;
  height: clamp(96px, 12vw, 140px);
  max-width: none; border: 0; border-radius: 0; box-shadow: none;
  /* a cover that has not decoded yet holds its slot in the paper tone instead
     of collapsing the row and shunting every cover after it */
  background: var(--li-cream-deep);
}
.li-arctrack__img img { display: block; }
@keyframes li-arcscroll { to { transform: translateX(-50%); } }

/* ---------- Sections ---------- */

/* ⚠ rr-final-1 (2026-08-02) · THE 20px CREAM STRIPE BETWEEN EVERY BAND.
   Meg's item 3, "spacing and padding: clean rhythm, no messy one-offs" — and
   this was the single biggest offender on the page.

   Measured on a REAL WordPress render of this theme (Playground, full page
   template, header and footer included, not a pattern in isolation): nine 20px
   gaps, one between every pair of top-level bands, plus a tenth between <main>
   and <footer>. WordPress's flow layout gives every sibling inside
   `.wp-block-post-content` `margin-block-start: var(--wp--style--block-gap)`,
   which this theme sets to 1.25rem.

   The page ground is cream, so on a page of full-bleed COLOURED bands each of
   those gaps paints as a cream stripe: forest | cream | lavender | cream |
   butter-soft | cream … The page reads as stacked slabs instead of one
   continuous surface, and it is why the zigzag looked detached from the forest
   band above it rather than torn out of it.

   LI has the identical structure and the identical rule, and has never shown it
   between bands, because almost every LI band is cream-ground — a cream gap
   between cream bands is invisible. LI hit it in the ONE place it does show,
   above the ink footer, and fixed that half (`.wp-site-blocks > *`, S3·1). The
   Reading Room needed both halves.

   Scoped to the full-bleed band classes ON PURPOSE. A blanket
   `.wp-block-post-content > * { margin-block-start: 0 }` would also flatten the
   deliberate spacing between plain blocks on a text page (the legal set).
   `.li-tilt` is NOT on this list: it carries its own negative margin-block, and
   zeroing it here would remove the marquee's overlap. */
.wp-site-blocks > * { margin-block-start: 0; }
.wp-block-post-content > .li-section,
.wp-block-post-content > .li-cta,
.wp-block-post-content > .li-bigtype,
.wp-block-post-content > .li-hero,
.wp-block-post-content > .li-pagehero,
.wp-block-post-content > .li-readmore,
.wp-block-post-content > .li-marquee { margin-block-start: 0 !important; }

.li-section { padding: clamp(2.4rem, 5vw, 3.8rem) clamp(1.2rem, 5vw, 4rem); }

/* Reader-first spacing (2026-08-24): the reader pages are TIGHT, not agency-
   bulky. `.li-section` above was clamp(5rem,10vw,9rem) top and bottom (up to
   144px a side) which is what made every page open on a wall of dead cream and
   read as "too much scroll" (Meg). These use `.li-section.<mod>` (specificity
   0,2,0) so they win over the base rule AND over any leftover Additional CSS on
   the live site. The LI zigzag torn-edge device is dropped: on a reader site it
   reads as noise and its teeth take the colour of the wrong neighbour. */
.li-section.rr-pagehead { padding-top: clamp(1.6rem, 3.5vw, 2.6rem); padding-bottom: clamp(.5rem, 1.5vw, 1rem); }
.li-section.rr-procband { padding-top: clamp(1.3rem, 3vw, 2.1rem); padding-bottom: clamp(1.3rem, 3vw, 2.1rem); }
.rr-pagehead + .li-section, .rr-pagehead + .rr-procband, .rr-pagehead + .rr-calwrap { padding-top: clamp(.6rem, 1.6vw, 1.2rem) !important; }
.li-zigzag::before { display: none !important; }
.li-section--tight { padding: clamp(4rem, 8vw, 6.5rem) clamp(1.2rem, 5vw, 4rem); }
.li-section h2 { font-size: clamp(2.3rem, 5.4vw, 4rem); line-height: 1.04; max-width: 21ch; }
.li-section--center h2 { margin-left: auto; margin-right: auto; }
/* rr-final-1 · clamp brought to LI's. RR ran ~12% larger, which compounded
   with the (then) undersized marquee to make the page read as a different
   typographic system from the LI site it mirrors. */
.li-lede { font-size: clamp(.95rem, 1.6vw, 1.12rem); font-weight: 500; opacity: .8; max-width: 52ch; }
.has-forest-background-color, .has-forest-deep-background-color { color: var(--li-cream); }
.has-forest-background-color h2, .has-forest-deep-background-color h2 { color: var(--li-cream); }

/* lavender-deep is a DARK band and must read like forest, not like a light one.
   Shipped once (RR Home Chapter 01) with no dark-band treatment, so the ink
   heading and lavender-deep <em> rendered dark-on-dark / same-on-same and the
   italic phrase was invisible. Mirrors the forest treatment. Added v0.30.0. */
.has-lavender-deep-background-color { color: var(--li-cream); }
.has-lavender-deep-background-color h2,
.has-lavender-deep-background-color h3 { color: var(--li-cream); }
.has-lavender-deep-background-color h2 em { color: var(--li-chartreuse); }
.has-lavender-deep-background-color .li-chapter { color: var(--li-chartreuse); }
.has-lavender-deep-background-color .li-note { color: var(--li-cream); }

/* Section edge treatments */
/* RR-P3 (2026-07-28) · the sawtooth is now colour-aware.

   ROOT CAUSE of "zig zag at the bottom is displaying weirdly": the teeth were
   painted `var(--li-cream)` regardless of the band above. On Home the band
   above is forest, so cream teeth floated between a forest band and a lilac
   one, matching neither — a stray stripe rather than a torn edge.

   The teeth must be the colour of whatever ACTUALLY precedes the band, so each
   instance sets it: add `li-zigzag--from-<colour>` alongside `li-zigzag`.
   Default stays cream, which is the page ground and the commonest neighbour.

   The `border-top: 2px solid var(--li-ink)` is GONE, deliberately. The teeth
   start at the band's top edge, and the clip-path only touches y=0 at the tips,
   so the ink rule showed through every gap between them — a hard straight line
   running through a torn edge, which is the opposite of what the device says.
   A torn edge is the edge; it does not also get ruled. Bands that want an ink
   rule already have `li-edge`, and the two were never meant to stack. */
.li-zigzag {
  position: relative;
  --li-zigzag-from: var(--li-cream);
}
.li-zigzag::before {
  content: ""; position: absolute; top: -1px; left: 0; right: 0; height: 24px; z-index: 1;
  background: var(--li-zigzag-from);
  clip-path: polygon(0 0, 4% 100%, 8% 0, 12% 100%, 16% 0, 20% 100%, 24% 0, 28% 100%, 32% 0, 36% 100%, 40% 0, 44% 100%, 48% 0, 52% 100%, 56% 0, 60% 100%, 64% 0, 68% 100%, 72% 0, 76% 100%, 80% 0, 84% 100%, 88% 0, 92% 100%, 96% 0, 100% 100%, 100% 0);
}
.li-zigzag--from-cream       { --li-zigzag-from: var(--li-cream); }
.li-zigzag--from-cream-deep  { --li-zigzag-from: var(--li-cream-deep); }
.li-zigzag--from-paper       { --li-zigzag-from: var(--li-paper); }
.li-zigzag--from-forest      { --li-zigzag-from: var(--li-forest); }
.li-zigzag--from-forest-deep { --li-zigzag-from: var(--li-forest-deep); }
.li-zigzag--from-lavender    { --li-zigzag-from: var(--li-lavender); }
.li-zigzag--from-lilac       { --li-zigzag-from: var(--li-lilac); }
.li-zigzag--from-butter      { --li-zigzag-from: var(--li-butter); }
.li-zigzag--from-butter-soft { --li-zigzag-from: var(--li-butter-soft); }
.li-zigzag--from-chartreuse  { --li-zigzag-from: var(--li-chartreuse); }
.li-edge { border-top: 2px solid var(--li-ink); border-bottom: 2px solid var(--li-ink); }

/* ---------- Grids ---------- */
.li-grid { display: grid; gap: 1.2rem; }
.li-grid--2 { grid-template-columns: repeat(2, 1fr); }
.li-grid--3 { grid-template-columns: repeat(3, 1fr); }
.li-grid--4 { grid-template-columns: repeat(4, 1fr); }
.li-grid--5 { grid-template-columns: repeat(5, 1fr); }
.li-grid--6 { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 1100px) {
  .li-grid--4, .li-grid--5 { grid-template-columns: repeat(2, 1fr); }
  .li-grid--3, .li-grid--6 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
  .li-grid--2, .li-grid--3, .li-grid--4, .li-grid--5, .li-grid--6 { grid-template-columns: 1fr; }
}

/* ---------- Shelf grid (RR-P2, 2026-07-27) ----------
   The book-shelf layout for cover-led card bands: Home's current-signups
   shelf, Just Released, and (RR-P4) Past ARCs and the Calendar cards.

   Why this is not `.li-grid--4`: a fixed `repeat(N, 1fr)` grid left-aligns a
   ragged last row, so a shelf of 7 cards renders 4 + 3-and-a-hole. Meg read
   exactly that hole as the band "displaying weirdly". A wrapping flex row with
   `justify-content: center` centres the short row instead, so ANY card count
   reads deliberate — which is the one rule the whole site now handles a ragged
   count with. A full row is unaffected: the items sum to 100% minus the gaps,
   so there is nothing left to centre.

   Column count is a custom property so the ladder lives in one place, and it
   steps at the same widths as the shipped `.li-grid` ladder (1100 / 900 / 640)
   so a shelf never reflows at a width nothing else on the site does. The steps
   are inclusive of their named width, matching `.li-grid`: measured rendered
   counts for a 4-card shelf are 4 / 3+1 / 2+2 / 1 at 1280 / 1100 / 900 / 640,
   and for a 7-card shelf 4+3 / 3+3+1 / 2+2+2+1 / 1. Every short row is
   centred, so none of those tails reads as a hole. */
.rr-shelf {
  --rr-shelf-cols: 5;
  --rr-shelf-gap: 1.2rem;
  display: flex; flex-wrap: wrap; gap: var(--rr-shelf-gap);
  justify-content: flex-start; align-items: stretch;
}
.rr-shelf > * {
  flex: 0 1 calc((100% - (var(--rr-shelf-cols) - 1) * var(--rr-shelf-gap)) / var(--rr-shelf-cols));
  max-width: calc((100% - (var(--rr-shelf-cols) - 1) * var(--rr-shelf-gap)) / var(--rr-shelf-cols));
  /* RR-P4: a flex item defaults to `min-width: auto`, which resolves to its
     min-content width and OUTRANKS max-width. The calendar's month cards have
     a ~627px min-content (the 7-column day grid inside them), so at a 565px
     basis they silently rendered one-per-row instead of two — measured, not
     guessed. Without this line the shelf quietly ignores its own column count
     for any card whose contents are wide. */
  min-width: 0;
  /* RR-P4: and content-box is the second half of the same bug. This theme sets
     no global border-box, so .rr-monthcal's 28.8px padding + 2px border landed
     OUTSIDE the 565px max-width and made each card 627px — two of them no
     longer fit a 1150px row. max-width alone does not constrain a padded
     content-box item; this does. */
  box-sizing: border-box;
  margin-top: 0 !important;
}
.rr-shelf--5 { --rr-shelf-cols: 5; }
/* RR-P4 · the 2-across variant. It was written for the Calendar's month cards
   and rr-final-2 (2026-08-03) took the Calendar off it — the month card is a
   full-width band now, because two cards side by side is what forced 70px day
   cells and made cover stickers on the days impossible. UNUSED TODAY, kept
   because it is a correct general variant and the ladder logic below depends
   on its existence; if you want a 2-across shelf, this is it.
   The ladder must never widen a shelf, so every step excludes the variants
   whose base is already at or below that step's count — without the :not(),
   the later `.rr-shelf` rule wins on order at equal specificity and a 2-col
   shelf becomes 3-col at 1100px. */
.rr-shelf--2 { --rr-shelf-cols: 2; }
/* :where() keeps this at (0,1,0) so the 900 and 640 steps below — plain
   .rr-shelf, also (0,1,0) — still win on order. A bare :not(.rr-shelf--2)
   is (0,2,0) and outranks them regardless of media query, which pinned
   every shelf at 3 columns from 1100px all the way down to 390px. */
@media (max-width: 1100px) { .rr-shelf:not(:where(.rr-shelf--2)), .rr-shelf--5 { --rr-shelf-cols: 3; } }
@media (max-width: 900px)  { .rr-shelf, .rr-shelf--5 { --rr-shelf-cols: 2; } }
@media (max-width: 640px)  { .rr-shelf, .rr-shelf--5 { --rr-shelf-cols: 1; } }

/* Two-column blocks (image + copy) need real air between the columns (item 4). */
.li-section .wp-block-columns { gap: clamp(2rem, 5vw, 4.5rem); }
@media (max-width: 781px) { .li-section .wp-block-columns { gap: clamp(1.6rem, 5vw, 2.4rem); } }

/* ---------- Cards ---------- */
.li-card {
  background: var(--li-paper); border: 2px solid var(--li-ink); border-radius: var(--li-radius);
  padding: 1.8rem 1.5rem 2rem; position: relative;
  transition: box-shadow .3s ease, transform .3s var(--li-pop);
  color: var(--li-ink);
}
.li-card:hover { box-shadow: 8px 10px 0 rgba(30,32,25,.16); transform: translateY(-4px); }
.li-card h3 { font-size: 1.5rem; line-height: 1.1; margin-bottom: .55rem; }
.li-card__for { font-family: var(--li-display); font-style: italic; font-weight: 460; font-variation-settings: "SOFT" 100, "WONK" 1; font-size: 1.05rem !important; margin-bottom: .7rem; opacity: .85; }
.li-card p:not(.li-card__for) { font-size: .95rem; opacity: .92; }
.li-card--forest { background: var(--li-forest); color: var(--li-cream); }
.li-card--forest h3 { color: var(--li-cream); }
.li-card--chartreuse { background: var(--li-chartreuse); }
.li-card--lavender { background: var(--li-lavender); }
.li-card--lilac { background: var(--li-lilac); }
.li-card--ink { background: var(--li-forest-deep); color: var(--li-cream); }
.li-card--ink h3 { color: var(--li-cream); }
.li-card a { font-weight: 700; text-decoration: none; border-bottom: 2px solid var(--li-lavender-deep); }
.li-card--forest a, .li-card--ink a { color: var(--li-chartreuse); border-bottom-color: var(--li-chartreuse); }

/* Tilted manifesto-style cards */
.li-mcards { display: grid; gap: 1.5rem; }
.li-mcard {
  position: relative;
  width: min(640px, 92%);
  background: var(--li-paper); border: 2px solid var(--li-ink); border-radius: var(--li-radius);
  padding: 1.5rem 1.7rem;
  transition: transform .3s var(--li-pop), box-shadow .3s ease;
}
.li-mcard--1 { transform: rotate(-1.4deg); }
.li-mcard--2 { margin-left: auto; transform: rotate(1.1deg); background: var(--li-lilac); }
.li-mcard--3 { margin-left: 7%; transform: rotate(-.8deg); background: var(--li-chartreuse-soft); }
.li-mcard:hover { transform: rotate(0) translateY(-4px); box-shadow: 6px 8px 0 rgba(30,32,25,.15); }
.li-mcard h3 { font-size: clamp(1.25rem, 2.4vw, 1.6rem); line-height: 1.22; margin: 0 0 .3rem; font-weight: 540; }
.li-mcard p { font-size: 1rem; margin: 0; opacity: .85; }
.li-mcard__note {
  position: absolute; top: -1.15rem; right: 1.2rem; margin: 0 !important;
  font-family: var(--li-hand) !important; font-size: 1.25rem !important; color: var(--li-lavender-deep);
  transform: rotate(2deg);
  background: var(--li-cream); padding: 0 .5rem;
}
@media (max-width: 700px) { .li-mcard, .li-mcard--2, .li-mcard--3 { width: 100%; margin-left: 0; } }

/* Pull line (highlight sweeps in) */
.li-pull {
  font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 540;
  font-size: clamp(1.7rem, 3.6vw, 2.7rem) !important; line-height: 1.18;
}
.li-pull--right { text-align: right; margin-left: auto; max-width: 30ch; }
/* Breathing room where a pull line follows the tilted note-cards (item 4). */
.li-mcards + .li-pull { margin-top: clamp(2.4rem, 4vw, 3.4rem); }

/* ---------- Home Chapter 02: the six-step process flow ----------
   Individual step badges with a marching dashed connector. Horizontal on
   desktop, a vertical timeline on phones. Movement is decorative and fully
   disabled under prefers-reduced-motion. */
.rr-flow {
  list-style: none;
  margin: clamp(2rem, 4vw, 3rem) 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(1.4rem, 2.4vw, 2rem) 0;
}
.rr-flow__step {
  flex: 1 1 150px;
  max-width: 182px;
  min-width: 132px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 0 .4rem;
  position: relative;
}
.rr-flow__step:not(:last-child)::after {
  content: "";
  position: absolute;
  top: 2rem;
  left: 60%;
  width: 80%;
  height: 3px;
  background: repeating-linear-gradient(90deg, var(--li-lavender) 0 7px, transparent 7px 15px);
  background-size: 15px 3px;
  animation: rr-march 1s linear infinite;
  z-index: 0;
}
@keyframes rr-march { to { background-position: -15px 0; } }
/* Doodle badge (2026-08-24): the reader doodle IS the graphic (recoloured
   lavender-deep, gently bobbing), not an icon in a circle. The Reading Room
   "pulls hardest on the reader doodles" per the brand guide. */
.rr-flow__badge {
  position: relative; z-index: 1;
  width: 4rem; height: 4rem;
  display: grid; place-items: center;
  margin-bottom: .55rem;
}
.rr-flow__icon { line-height: 1; display: grid; place-items: center; }
.rr-flow__icon .li-dood { --li-dood-size: 3.5rem; }
.rr-flow__num { display: none; }
.rr-flow__text { display: flex; flex-direction: column; }
.rr-flow__label { font-weight: 700; font-size: 1rem; line-height: 1.2; margin-bottom: .2rem; color: var(--li-forest); }
.rr-flow__sub { font-size: .82rem; opacity: .78; line-height: 1.3; }
@media (max-width: 720px) {
  .rr-flow { flex-direction: column; align-items: flex-start; gap: 0; max-width: 360px; margin-inline: auto; }
  .rr-flow__step { flex: none; width: 100%; max-width: none; flex-direction: row; align-items: flex-start; text-align: left; gap: 1rem; padding: 0 0 1.7rem; }
  .rr-flow__step:not(:last-child)::after {
    top: 4rem; left: 2rem; width: 3px; height: calc(100% - 3.4rem);
    background: repeating-linear-gradient(180deg, var(--li-lavender) 0 7px, transparent 7px 15px);
    background-size: 3px 15px;
    animation: rr-march-v 1s linear infinite;
  }
  .rr-flow__badge { margin-bottom: 0; flex: none; }
  .rr-flow__text { padding-top: .5rem; }
}
@keyframes rr-march-v { to { background-position: 0 -15px; } }
@media (prefers-reduced-motion: reduce) {
  .rr-flow__step::after { animation: none; }
  .rr-flow__badge { animation: none; opacity: 1; transform: none; }
}
.li-pull mark {
  position: relative; z-index: 1; padding: 0 .12em; background: transparent; color: inherit;
}
.li-pull mark::before {
  content: ""; position: absolute; inset: .08em -.05em; z-index: -1;
  background: var(--li-chartreuse); border-radius: .3em;
  transform: rotate(-1deg) scaleX(1); transform-origin: left center;
}
body.li-js .li-pull:not(.li-inview) mark::before { transform: rotate(-1deg) scaleX(0); }
.li-pull.li-inview mark::before { transform: rotate(-1deg) scaleX(1); transition: transform .8s cubic-bezier(.7,0,.2,1) .15s; }
/* Reduced-motion fallback: the reveal observer only runs when motion is not
   reduced, so these visitors never get .li-inview and the highlight would stay
   at scaleX(0) under body.li-js. Show it fully instead of hiding it. Fixes the
   "honest means honest" highlight not displaying. */
@media (prefers-reduced-motion: reduce) {
  body.li-js .li-pull mark::before { transform: rotate(-1deg) scaleX(1); }
}

/* ---------- Stats ---------- */
.li-stat {
  background: var(--li-cream);
  border: 2px solid var(--li-ink); border-radius: var(--li-radius);
  padding: 1.8rem 1.2rem; text-align: center;
  transition: transform .3s var(--li-pop), box-shadow .3s;
  color: var(--li-ink);
}
.li-stat:nth-child(odd) { transform: rotate(-1deg); }
.li-stat:nth-child(even) { transform: rotate(1deg); }
.li-stat:hover { transform: translateY(-6px) rotate(0deg); box-shadow: 6px 8px 0 var(--li-forest); }
.li-stat__num { font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 570; font-size: clamp(2.3rem, 4vw, 3.4rem) !important; line-height: 1; color: var(--li-forest); margin: 0 !important; }
.li-stat__label { margin: .6rem 0 0 !important; font-weight: 600; font-size: .92rem !important; opacity: .78; }

/* ---------- Numbered steps ---------- */
.li-step {
  position: relative;
  background: var(--li-cream); color: var(--li-ink);
  border: 2px solid var(--li-ink); border-radius: var(--li-radius);
  padding: 1.7rem 1.3rem 1.8rem;
  transition: transform .3s var(--li-pop), box-shadow .3s;
}
.li-step:nth-child(odd) { transform: rotate(-1.2deg); }
.li-step:nth-child(even) { transform: rotate(1.2deg); }
.li-step:hover { transform: translateY(-6px) rotate(0); box-shadow: 6px 8px 0 var(--li-chartreuse); }
.li-step__num {
  position: absolute; top: -16px; right: 14px; margin: 0 !important;
  width: 34px; height: 34px; display: grid; place-items: center;
  background: var(--li-chartreuse); border: 2px solid var(--li-ink); border-radius: 50%;
  font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; font-size: 1.05rem !important;
  color: var(--li-ink);
}
.li-step p:not(.li-step__num) { font-size: .94rem; font-weight: 500; margin: 0; }
.li-step h3 { font-size: 1.25rem; margin: 0 0 .4rem; }

/* ---------- Quotes / testimonials ---------- */
.li-quotes { columns: 3; column-gap: 1.2rem; display: block !important; }
@media (max-width: 1100px) { .li-quotes { columns: 2; } }
@media (max-width: 680px) { .li-quotes { columns: 1; } }
.li-quotes .wp-block-quote, .li-quote {
  break-inside: avoid; margin: 0 0 1.2rem;
  background: var(--li-paper); color: var(--li-ink);
  border: 2px solid var(--li-ink) !important; border-radius: var(--li-radius);
  padding: 1.6rem 1.5rem !important;
  transition: box-shadow .3s ease, transform .3s var(--li-pop);
}
.li-quotes .wp-block-quote:hover { box-shadow: 7px 9px 0 rgba(30,32,25,.2); transform: rotate(0) scale(1.015); }
.li-quotes .wp-block-quote:nth-child(3n+1) { transform: rotate(-.9deg); }
.li-quotes .wp-block-quote:nth-child(3n+2) { transform: rotate(.8deg); }
.li-quotes .wp-block-quote p { font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 470; font-size: 1.18rem; line-height: 1.35; margin: 0; }
.li-quotes .wp-block-quote cite { display: block; margin-top: 1rem; font-weight: 700; font-size: .82rem; letter-spacing: .08em; text-transform: uppercase; opacity: var(--li-dim); font-style: normal; font-family: var(--li-sans); }
.li-quotes .li-quote--feature { background: var(--li-chartreuse); }
.li-quotes .li-quote--feature p { font-size: 1.36rem; }
.li-quotes .li-quote--lavender { background: var(--li-lavender); }

/* Google review badge */
.li-google {
  display: flex; align-items: center; gap: 1.2rem; flex-wrap: wrap;
  border: 2px dashed var(--li-ink); border-radius: 14px;
  padding: 1.1rem 1.5rem; width: fit-content;
  transform: rotate(-1deg);
  transition: transform .3s var(--li-pop);
  background: var(--li-cream); color: var(--li-ink);
}
.li-google:hover { transform: rotate(1deg) scale(1.03); }
.li-google p { margin: 0; font-size: .98rem; }
.li-google__stars { color: var(--li-lavender-deep); letter-spacing: .25em; font-size: 1.1rem; }

/* ---------- Principles ---------- */
.li-principle {
  border: 2px solid var(--li-cream); border-radius: var(--li-radius);
  padding: 2rem 1.8rem;
  background: var(--li-forest-deep); color: var(--li-cream);
  transition: transform .3s var(--li-pop), box-shadow .3s;
}
.li-principle:hover { transform: translateY(-5px) rotate(-.5deg); box-shadow: 6px 8px 0 rgba(0,0,0,.3); }
.li-principle__num { font-family: var(--li-display); font-style: italic; font-weight: 480; font-size: 1.6rem !important; color: var(--li-chartreuse); display: block; margin: 0 0 .8rem !important; }
.li-principle h3 { font-size: clamp(1.5rem, 2.6vw, 1.9rem); margin-bottom: .7rem; color: var(--li-cream); }
.li-principle p:not(.li-principle__num) { color: rgba(245,239,223,.88); max-width: 52ch; }

/* ---------- Packages / pricing ---------- */
/* Pricing cards redesigned (item 9): the PRICE is the hero, tag is a quiet
   kicker, the "for whom" line is one italic sentence, list is ≤4 punchy items
   above a full-width button. Confident, few words. Featured card is
   unmistakable — deeper colour, hard offset shadow, lifted and scaled. */
.li-pkg {
  background: var(--li-paper); border: 2px solid var(--li-ink); border-radius: var(--li-radius);
  padding: 1.6rem 1.4rem 1.4rem; display: flex; flex-direction: column; gap: .35rem;
  position: relative; transition: box-shadow .3s ease, transform .3s var(--li-pop);
  color: var(--li-ink);
}
.li-pkg:hover { box-shadow: 8px 10px 0 rgba(30,32,25,.16); transform: translateY(-4px); }
.li-pkg__tag {
  width: fit-content; font-weight: 800; font-size: .74rem !important; letter-spacing: .16em; text-transform: uppercase; /* QA-2 port: was .64rem = 10.2px */
  color: var(--li-lavender-deep); margin: 0 0 .15rem !important;
}
.li-pkg h3 { font-size: 1.4rem; margin: 0; line-height: 1.04; }
.li-pkg__price { font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 580; font-size: clamp(2.7rem, 4vw, 3.3rem) !important; color: var(--li-forest); margin: .35rem 0 0 !important; line-height: .92; letter-spacing: -.02em; }
.li-pkg__pricenote { font-weight: 700; font-size: .74rem !important; opacity: var(--li-dim); margin: .2rem 0 0 !important; text-transform: uppercase; letter-spacing: .05em; }
/* The one-line "for whom" descriptor — an unclassed paragraph inside the card. */
.li-pkg > p:not([class]) { font-family: var(--li-display); font-style: italic; font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 460; font-size: .92rem !important; opacity: .8; margin: .55rem 0 .1rem !important; line-height: 1.32; }
.li-pkg ul { list-style: none; flex: 1; display: grid; gap: .4rem; margin: .35rem 0 0; padding: .9rem 0 0; border-top: 1px solid rgba(30,32,25,.14); }
.li-pkg ul li { padding-left: 1.3rem; position: relative; font-size: .9rem; font-weight: 500; }
.li-pkg ul li::before { content: "✦"; position: absolute; left: 0; color: var(--li-lavender-deep); }
.li-pkg .wp-block-buttons { margin-top: .9rem; }
.li-pkg .wp-block-button { width: 100%; }
.li-pkg .wp-block-button__link { width: 100%; text-align: center; }
/* Featured card differentiated by persistent traits (bg, accent, hard shadow,
   flag) — NOT a resting transform, which the reveal animation would clobber. */
.li-pkg--feature { background: var(--li-forest); color: var(--li-cream); box-shadow: 10px 12px 0 var(--li-chartreuse); z-index: 2; }
.li-pkg--feature:hover { box-shadow: 13px 15px 0 var(--li-chartreuse); transform: translateY(-4px); }
.li-pkg--feature h3 { color: var(--li-cream); }
.li-pkg--feature .li-pkg__tag { color: var(--li-chartreuse); }
.li-pkg--feature .li-pkg__price { color: var(--li-chartreuse); }
.li-pkg--feature .li-pkg__pricenote { color: rgba(245,239,223,.7); opacity: 1; }
.li-pkg--feature > p:not([class]) { color: rgba(245,239,223,.9); opacity: 1; }
.li-pkg--feature ul { border-top-color: rgba(245,239,223,.22); }
.li-pkg--feature ul li::before { color: var(--li-chartreuse); }
.li-pkg__flag {
  position: absolute; top: -14px; right: 16px; margin: 0 !important;
  background: var(--li-chartreuse); border: 2px solid var(--li-ink); color: var(--li-ink);
  font-weight: 800; font-size: .75rem !important; letter-spacing: .08em; text-transform: uppercase;
  padding: .3rem .8rem; border-radius: 999px; transform: rotate(3deg);
}

/* ---------- FAQ + Read-more accordions (core details block) ---------- */
.li-faq { display: grid; gap: .9rem; }
.li-faq .wp-block-details {
  background: var(--li-cream); border: 2px solid var(--li-ink); border-radius: 18px;
  padding: 0 1.5rem; margin: 0;
  transition: box-shadow .3s ease;
  color: var(--li-ink);
}
.li-faq .wp-block-details:hover { box-shadow: 5px 6px 0 rgba(30,32,25,.18); }
.li-faq .wp-block-details summary {
  list-style: none; cursor: pointer;
  display: flex; justify-content: space-between; align-items: center; gap: 1rem;
  padding: 1.2rem 0;
  font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 520;
  font-size: clamp(1.15rem, 2.2vw, 1.4rem);
}
.li-faq .wp-block-details summary::-webkit-details-marker { display: none; }
.li-faq .wp-block-details summary::after {
  content: "+"; flex: none; width: 34px; height: 34px; display: grid; place-items: center;
  border: 2px solid var(--li-ink); border-radius: 50%;
  font-family: var(--li-sans); font-weight: 700; font-size: 1.2rem;
  transition: transform .3s ease, background-color .3s ease;
}
.li-faq .wp-block-details[open] summary::after { transform: rotate(45deg); background: var(--li-chartreuse); }
.li-faq .wp-block-details > :not(summary) { max-width: 64ch; opacity: .9; }
.li-faq .wp-block-details > p:last-child { padding-bottom: 1.4rem; }

/* Read-more SEO accordion — near-invisible by design (item 8). It exists for
   search engines and the genuinely curious, not as a page feature: no border,
   a tiny muted summary, no loud indicator. Findable if you look, ignorable if
   you don't. Content stays fully present for SEO. */
.li-readmore .wp-block-details {
  background: transparent; border: none; border-top: 1px solid rgba(30,32,25,.1);
  border-radius: 0; padding: 0; margin: 0;
}
.li-readmore .wp-block-details summary {
  list-style: none; cursor: pointer; padding: .55rem 0;
  display: inline-flex; align-items: center; gap: .4rem;
  font-family: var(--li-sans); font-style: normal; font-weight: 500;
  font-size: .78rem; letter-spacing: .02em; color: rgba(30,32,25,.70); /* QA-2 port: was .38 = 2.28:1. Now 5.66:1. */
  transition: color .3s ease;
}
.li-readmore .wp-block-details summary:hover { color: rgba(30,32,25,.88); }
.li-readmore .wp-block-details summary::-webkit-details-marker { display: none; }
.li-readmore .wp-block-details summary::after {
  content: "+"; font-family: var(--li-sans); font-weight: 600; font-size: .82rem;
  opacity: .3; transition: transform .3s ease, opacity .3s ease;
}
.li-readmore .wp-block-details summary:hover::after { opacity: .55; }
.li-readmore .wp-block-details[open] summary::after { transform: rotate(45deg); }
.li-readmore .wp-block-details > :not(summary) { max-width: 68ch; }
.li-readmore .wp-block-details h3 { font-size: 1.35rem; margin-top: 1.6rem; }
.li-readmore .wp-block-details > p:last-child, .li-readmore .wp-block-details > ul:last-child { padding-bottom: 1.4rem; }

/* ---------- CTA band (final chapter) ---------- */
.li-cta { text-align: center; position: relative; overflow: hidden; }
.li-cta .li-chapter { justify-content: center; }
.li-cta h2 { max-width: 22ch; margin-left: auto; margin-right: auto; font-size: clamp(2.2rem, 5.8vw, 4.4rem); line-height: 1.06; }
/* Closing punch (the italic <em>) drops to its own line in every final-chapter CTA. */
.li-cta h2 em { display: block; margin-top: .1em; }
.li-cta__sub { margin: 1.6rem auto 0; max-width: 52ch; opacity: .85; }
.li-cta .wp-block-buttons { justify-content: center; margin-top: 3rem; }

/* ---------- Images: placeholder frames ---------- */
.li-imgframe img {
  border: 2px solid var(--li-ink); border-radius: var(--li-radius);
  box-shadow: 8px 10px 0 rgba(30,32,25,.16);
  /* Carried over from the LI theme, 2026-08-04. An SVG with only a viewBox has
     no intrinsic size and collapses inside an <img>; it cost the LI ARC Starter
     Kit its diagram, which rendered at 4x4px on every device. No RR SVG is
     currently affected, and this keeps it that way. */
  width: 100%; height: auto;
}
.li-imgframe { transform: rotate(-1.2deg); transition: transform .3s var(--li-pop); }
.li-imgframe:hover { transform: rotate(0); }
.li-imgframe--r { transform: rotate(1.2deg); }
.li-imgframe figcaption { font-family: var(--li-hand); font-size: 1.15rem; color: var(--li-lavender-deep); text-align: center; }
.li-imgframe--tape { position: relative; }
.li-imgframe--tape::before {
  content: ""; position: absolute; top: -12px; left: 50%; transform: translateX(-50%) rotate(-3deg); z-index: 2;
  width: 110px; height: 28px; background: rgba(243,199,92,.75); border-radius: 2px;
}

/* ---------- Prose (long-form inner column) ---------- */
.li-prose h2 { font-size: clamp(1.9rem, 3.6vw, 2.7rem); margin-top: 2.2rem; }
.li-prose h3 { font-size: clamp(1.35rem, 2.4vw, 1.7rem); margin-top: 1.8rem; }
.li-prose p { max-width: 68ch; }
.li-prose ul, .li-prose ol { max-width: 62ch; }
.li-prose a { border-bottom: 2px solid var(--li-lavender); text-decoration: none; }
.li-prose a:hover { border-bottom-color: var(--li-lavender-deep); }

/* ---------- Blog cards (query loop) ---------- */
.li-postcard {
  background: var(--li-paper); border: 2px solid var(--li-ink); border-radius: var(--li-radius);
  overflow: hidden; transition: box-shadow .3s ease, transform .3s var(--li-pop);
  height: 100%;
}
.li-postcard:hover { box-shadow: 8px 10px 0 rgba(30,32,25,.16); transform: translateY(-4px); }
.li-postcard .wp-block-post-featured-image img { border-radius: 0; }
.li-postcard .wp-block-post-title { font-size: 1.35rem; padding: 1.1rem 1.3rem 0; }
.li-postcard .wp-block-post-title a { text-decoration: none; }
.li-postcard .wp-block-post-excerpt { padding: .5rem 1.3rem 1.3rem; font-size: .95rem; opacity: .85; }
.li-postcard .wp-block-post-date { padding: 0 1.3rem; font-size: .8rem; text-transform: uppercase; letter-spacing: .08em; opacity: .6; }

/* ---------- Single post: prev/next nav + back link ---------- */
.li-postnav { margin-top: 2.8rem; padding-top: 1.8rem; border-top: 1px solid rgba(30,32,25,.14); }
.li-postnav__links { gap: 1rem; }
.li-postnav .wp-block-post-navigation-link a {
  display: inline-block; font-family: var(--li-sans); font-weight: 700; font-size: .9rem;
  padding: .7rem 1.3rem; border: 2px solid var(--li-ink); border-radius: 999px;
  text-decoration: none; color: var(--li-ink);
  transition: transform .25s var(--li-pop), box-shadow .25s;
}
.li-postnav .wp-block-post-navigation-link a:hover { box-shadow: 4px 4px 0 var(--li-ink); transform: translateY(-2px); }
/* post-terms rendered inside a chip (single hero) */
.li-chip a { color: inherit; text-decoration: none; }
.li-pagehero .wp-block-post-terms.li-chip { transform: rotate(1.5deg); }

/* ---------- Footer ---------- */
.li-foot { background: var(--li-ink); color: var(--li-cream); padding: 3.5rem clamp(1.2rem, 5vw, 4rem) 2rem; }
.li-foot a { color: var(--li-cream); opacity: .8; font-weight: 600; text-decoration: none; }
.li-foot a:hover { opacity: 1; color: var(--li-chartreuse); }
.li-foot__logo { font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 560; font-size: 1.7rem !important; margin: 0; }
.li-foot__logo .li-mark { color: var(--li-chartreuse); }
.li-foot__end { margin-top: 1.2rem !important; font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 500; font-size: 1.45rem !important; }
.li-foot__end-note { font-family: var(--li-hand) !important; font-weight: 500; font-size: 1.25rem !important; color: var(--li-lavender); }
.li-foot__col-title { font-weight: 800; font-size: .78rem !important; letter-spacing: .18em; text-transform: uppercase; color: var(--li-chartreuse); margin-bottom: .9rem !important; }
.li-foot__base { padding-top: 1.6rem; margin-top: 2.5rem; border-top: 1px solid rgba(245,239,223,.15); font-size: .85rem; opacity: .6; }

/* ---------- Reveal-on-scroll (JS adds li-anim + li-inview; safe without JS) ---------- */
/* Travel is deliberately short (14px, not 34px): a display-size h2 has
   margin-bottom:0, so a long rise visibly crosses the paragraph beneath it for
   the length of the transition. Keep travel < the h2/paragraph gap (20px).
   Ported from the LI theme, E2-B — verify by measuring gap vs travel, not by
   screenshotting (a screenshot catches the element mid-transition and lies). */
body.li-js .li-anim { opacity: 0; transform: translateY(14px); transition: opacity .6s cubic-bezier(.22,.61,.36,1), transform .6s cubic-bezier(.22,.61,.36,1); transition-delay: var(--li-anim-delay, 0s); }
body.li-js .li-anim.li-inview { opacity: 1; transform: none; }
body.li-js .li-anim--pop { transform: translateY(24px) scale(.92) rotate(-2deg); }
body.li-js .li-anim--pop.li-inview { transform: none; }

/* Hero word stagger (JS splits words into .li-w spans) */
body.li-js .li-w { display: inline-block; opacity: 0; transform: translateY(.55em); transition: opacity .7s cubic-bezier(.22,.61,.36,1), transform .7s cubic-bezier(.22,.61,.36,1); transition-delay: var(--li-w-delay, 0s); }
body.li-js .li-hero-in .li-w { opacity: 1; transform: none; }

/* Squiggle draw-in */
.li-squiggle-svg path { stroke-dasharray: var(--li-sq-len, 340); stroke-dashoffset: 0; }
body.li-js .li-squiggle-svg path { stroke-dashoffset: var(--li-sq-len, 340); }
body.li-js .li-hero-in .li-squiggle-svg path, body.li-js .li-inview .li-squiggle-svg path { stroke-dashoffset: 0; transition: stroke-dashoffset .9s ease-in-out .7s; }

/* ---------- Custom cursor: REMOVED 2026-08-07 (Meg) ----------
   The Reading Room must match Literary Inspired, which has no custom cursor.
   The JS injector in li-motion.js is gone too. Do not reinstate. */
.li-cursor, .li-cursor-dot { display: none !important; }

/* ---------- Preloader (JS injects, once per session) ---------- */
.li-preloader { position: fixed; inset: 0; z-index: 10000; display: grid; place-items: center; background: var(--li-forest-deep); transition: opacity .5s ease, visibility .5s; }
.li-preloader.is-done { opacity: 0; visibility: hidden; }
.li-preloader__inner { text-align: center; color: var(--li-cream); }
.li-preloader__book { width: 64px; margin: 0 auto 1rem; display: block; }
.li-preloader__book path { fill: none; stroke: var(--li-chartreuse); stroke-width: 5; stroke-linejoin: round; }
.li-preloader__word { font-family: var(--li-display); font-style: italic; font-variation-settings: "SOFT" 100, "WONK" 1; font-size: clamp(1.5rem, 3vw, 2.4rem); margin: 0 0 .4rem; }
.li-preloader__count { font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; font-size: clamp(3.4rem, 9vw, 6.5rem); line-height: 1; margin: 0; }

/* ---------- Editor-only: the page-title field above the canvas is admin
   chrome, not page content. Shrink it to a quiet label so it can't be
   mistaken for a heading on the page (the front end never prints it). ---------- */
.editor-styles-wrapper .editor-post-title,
.editor-styles-wrapper .wp-block-post-title.editor-post-title__input {
  font-family: var(--li-sans) !important;
  font-size: 1rem !important;
  font-weight: 700 !important;
  letter-spacing: .12em;
  text-transform: uppercase;
  opacity: .45;
  font-variation-settings: normal !important;
}
.editor-styles-wrapper .editor-post-title::after {
  content: " — page title (not shown on the site)";
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
}

/* ---------- Keyboard focus (a11y — visible focus ring everywhere) ---------- */
a:focus-visible,
.wp-block-button__link:focus-visible,
summary:focus-visible,
.wp-block-navigation a:focus-visible,
input:focus-visible,
button:focus-visible {
  outline: 3px solid var(--li-lavender-deep);
  outline-offset: 3px;
  border-radius: 4px;
}
.has-forest-background-color a:focus-visible,
.has-forest-deep-background-color a:focus-visible,
.has-forest-background-color .wp-block-button__link:focus-visible,
.has-forest-deep-background-color .wp-block-button__link:focus-visible,
.li-head a:focus-visible,
.li-head .wp-block-button__link:focus-visible,
.li-foot a:focus-visible,
.li-linkbio a:focus-visible {
  outline-color: var(--li-chartreuse);
}

/* ---------- Resources: tool cards + featured band (item 11) ---------- */
.li-tool {
  background: var(--li-paper); border: 2px solid var(--li-ink); border-radius: var(--li-radius);
  padding: 1.4rem; display: flex; flex-direction: column; gap: .5rem; align-items: flex-start;
  transition: box-shadow .3s ease, transform .3s var(--li-pop); color: var(--li-ink); height: 100%;
}
.li-tool:hover { box-shadow: 8px 10px 0 rgba(30,32,25,.16); transform: translateY(-5px) rotate(-.5deg); }
.li-tool__logo { width: 100%; border: 1.5px dashed rgba(30,32,25,.3); border-radius: 14px; background: var(--li-cream); aspect-ratio: 16 / 7; display: grid; place-items: center; overflow: hidden; margin-bottom: .3rem; }
.li-tool__logo img { max-width: 80%; height: auto; }
.li-tool__cat { font-weight: 800; font-size: .74rem !important; letter-spacing: .16em; text-transform: uppercase; color: var(--li-lavender-deep); margin: 0 !important; }
.li-tool h3 { font-size: 1.3rem; margin: 0; }
.li-tool p { font-size: .92rem; opacity: .85; margin: 0; }
.li-tool a { margin-top: auto; font-weight: 700; text-decoration: none; border-bottom: 2px solid var(--li-lavender-deep); padding-top: .4rem; }
.li-toolfeature {
  background: var(--li-chartreuse-soft); border: 2px solid var(--li-ink); border-radius: var(--li-radius);
  padding: clamp(1.6rem, 4vw, 2.4rem); display: grid; grid-template-columns: 220px 1fr; gap: clamp(1.4rem, 4vw, 2.6rem); align-items: center;
  transition: box-shadow .3s ease; color: var(--li-ink);
}
.li-toolfeature:hover { box-shadow: 8px 10px 0 rgba(30,32,25,.16); }
.li-toolfeature .li-tool__logo { aspect-ratio: 1; margin: 0; background: var(--li-paper); }
.li-toolfeature h3 { font-size: clamp(1.6rem, 3vw, 2.2rem); margin: 0 0 .4rem; }
.li-toolfeature p { max-width: 56ch; }
@media (max-width: 700px) { .li-toolfeature { grid-template-columns: 1fr; text-align: left; } }

/* ---------- Affiliate disclosure line ---------- */
.li-disclosure { font-size: .82rem !important; opacity: .6; font-style: italic; max-width: 60ch; }
.has-forest-background-color .li-disclosure, .has-forest-deep-background-color .li-disclosure { opacity: .7; }

/* ---------- Blog: category pills + search (item 10 / 2.2) ---------- */
.li-pills { display: flex; flex-wrap: wrap; gap: .6rem; justify-content: center; margin: 0 auto 1.4rem; }
.li-pill { display: inline-block; margin: 0 !important; border-radius: 999px; border: 2px solid var(--li-ink); background: var(--li-paper); overflow: hidden; transition: background-color .25s, transform .25s var(--li-pop); }
.li-pill a { display: block; padding: .5rem 1.1rem; font-family: var(--li-sans); font-weight: 700; font-size: .82rem; color: var(--li-ink); text-decoration: none; }
.li-pill:hover, .li-pill--active { background: var(--li-chartreuse); transform: translateY(-2px); }
.li-search { display: flex; gap: .6rem; max-width: 460px; margin: 1.6rem auto 0; }
.li-search input[type="search"], .li-search .wp-block-search__input { flex: 1; border: 2px solid var(--li-ink) !important; border-radius: 999px !important; padding: .85rem 1.3rem; font-family: var(--li-sans); font-size: .95rem; background: var(--li-paper); color: var(--li-ink); }
.wp-block-search__button { border: 2px solid var(--li-ink); border-radius: 999px; background: var(--li-chartreuse); color: var(--li-ink); font-weight: 700; padding: .6rem 1.3rem; }

/* ---------- Link in Bio (item 2.4) ---------- */
.li-imgframe--round { transform: rotate(0); }
.li-imgframe--round img { border-radius: 50% !important; aspect-ratio: 1; object-fit: cover; box-shadow: 6px 8px 0 rgba(30,32,25,.2); }
.li-linkbio.li-pagehero { min-height: 100svh; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; text-align: center; padding: clamp(2.4rem, 7vw, 4rem) 1.4rem 2.4rem; }
.li-linkbio > * { position: relative; z-index: 2; width: 100%; max-width: 420px; margin-left: auto; margin-right: auto; }
.li-linkbio__wordmark { font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 560; font-size: 1.9rem !important; margin: 1.1rem 0 .2rem !important; color: var(--li-cream); }
.li-linkbio__wordmark mark { background: transparent; color: var(--li-chartreuse); }
.li-linkbio__bio { color: rgba(245,239,223,.82); font-weight: 500; margin: 0 0 1.6rem !important; }
.li-linkstack { display: grid; gap: .9rem; width: 100%; }
.li-linkstack .wp-block-button { width: 100%; }
.li-linkstack .wp-block-button__link { width: 100%; text-align: center; padding: 1.05rem 1.4rem; font-size: 1.02rem; }
.li-linkbio__socials { margin-top: 1.8rem !important; font-size: .9rem; color: rgba(245,239,223,.7); }
.li-linkbio__socials a { color: var(--li-cream); font-weight: 700; text-decoration: none; }

/* ==========================================================
   READING ROOM COMPONENTS (rr-*) — everything below is new
   to this theme. LI-shared devices stay li-* above.
   ========================================================== */

/* ---------- Team card (Current ARCs grid + Home current strip) ----------
   The markup contract RR-B's publish loop fills — see DATA_CONTRACT.md
   beside PATTERN_CONVENTIONS.md. Cover is a 600x900 placeholder until
   Meg drops real covers. */
.rr-team, .rr-past, .rr-perm {
  --rr-card-pad: 1.1rem;
  background: var(--li-paper); border: 2px solid var(--li-ink); border-radius: var(--li-radius);
  overflow: hidden;
  padding: var(--rr-card-pad) var(--rr-card-pad) calc(var(--rr-card-pad) + .2rem);
  display: flex; flex-direction: column; gap: .5rem;
  color: var(--li-ink); height: 100%;
  transition: box-shadow .3s ease, transform .3s var(--li-pop);
}
.rr-team:hover, .rr-past:hover, .rr-perm:hover { box-shadow: 8px 10px 0 rgba(30,32,25,.16); transform: translateY(-4px) rotate(-.4deg); }
/* Cover FILLS to the card border (Meg, 2026-08-24): the cover bleeds to the
   card's top and side edges via a negative margin equal to the card padding, so
   the card's own 2px border frames it instead of a paper margin floating around
   a second framed image. A hairline closes it off above the title. */
.rr-team .wp-block-image, .rr-past .wp-block-image, .rr-perm .wp-block-image {
  margin: calc(-1 * var(--rr-card-pad)) calc(-1 * var(--rr-card-pad)) .7rem;
}
/* Cover frame — NEVER crop an author's cover art (RR-P2, 2026-07-27).
   This was `object-fit: cover` in a 2/3 box, which silently sliced 5.9% off
   Love, Loch (600x957, ratio .627) and 6.1% off Dirty Goddess (600x959,
   ratio .626) — the covers' own titles and credits sit in exactly that band.
   `contain` shows the whole cover; the frame stays 2/3 so every card in a row
   is the same width; `object-position: bottom` drops any slack ABOVE the
   cover so the books line up on one shelf edge instead of floating. The
   paper fill is what shows in the slack, so it reads as shelf, not as gap.
   The 2/3 frame is chosen because .667 is the commonest ratio in the library
   (17 of 65 covers on file), so most covers fill it exactly and the narrower
   ones take a couple of millimetres of paper at the sides. */
/* Anti-crop is intact (RR-P2, 2026-07-27): object-fit stays `contain` on a 2/3
   frame so an author's title/credit band is never sliced. The frame is now
   full-card-width and flush to the card border; the cream fill inside it reads
   as shelf, not as a floating gap. Top corners follow the card radius; a bottom
   hairline separates the cover from the title block. */
.rr-team .wp-block-image img, .rr-past .wp-block-image img, .rr-perm .wp-block-image img {
  width: 100%; height: auto; aspect-ratio: 2 / 3;
  object-fit: contain; object-position: bottom; background: var(--li-cream-deep);
  border: 0; border-bottom: 2px solid var(--li-ink);
  border-radius: calc(var(--li-radius) - 2px) calc(var(--li-radius) - 2px) 0 0; display: block;
}
.rr-team .li-chip, .rr-past .li-chip, .rr-perm .li-chip { font-size: .7rem; padding: .35rem .8rem; transform: rotate(-1deg); width: fit-content; }
.rr-team h3, .rr-past h3, .rr-perm h3 { font-size: 1.3rem; line-height: 1.1; margin: 0; }
.rr-team__author, .rr-past .rr-team__author, .rr-perm__series { font-family: var(--li-display); font-style: italic; font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 460; font-size: .95rem !important; opacity: .8; margin: 0 !important; }
.rr-team__dates, .rr-perm__count { font-weight: 700; font-size: .72rem !important; letter-spacing: .1em; text-transform: uppercase; opacity: var(--li-dim); margin: 0 !important; }
.rr-team .wp-block-buttons, .rr-past .wp-block-buttons, .rr-perm .wp-block-buttons { margin-top: auto; padding-top: .6rem; display: grid; gap: .5rem; }
.rr-team .wp-block-button, .rr-past .wp-block-button, .rr-perm .wp-block-button { width: 100%; }
.rr-team .wp-block-button__link, .rr-past .wp-block-button__link, .rr-perm .wp-block-button__link { width: 100%; text-align: center; padding: .75rem 1rem; font-size: .88rem; }

/* Compact card, for the 4-across shelf (RR-P2, 2026-07-27).
   The card internals were sized for a 371px card in a 3-column grid. On the
   shelf the card is ~274px at 1280, so the padding, title and button label all
   come down a step. Only the shelf context is retuned — a .rr-team card
   anywhere else keeps the roomier scale. The team-card CTA labels are long by
   design ("Signups open 28 July — get the invite"), so the button keeps a
   tighter horizontal padding and a slightly looser line-height to wrap to two
   lines cleanly rather than being clipped. */
.rr-shelf .rr-team, .rr-shelf .rr-past, .rr-shelf .rr-perm { --rr-card-pad: .85rem; gap: .4rem; }
.rr-shelf .rr-team h3, .rr-shelf .rr-past h3, .rr-shelf .rr-perm h3 { font-size: 1.08rem; }
/* RR-P5 (2026-08-24): reserve two title lines on every shelf card so a book with
   a two-line title (e.g. "Klauth: History of the Red Cursed Egg") does not sit
   taller than its single-line neighbours. With the title band fixed, the meta
   line, buttons and card height match across the row and the button baseline
   lines up — the uneven baseline the stretch alone was not equalising. */
.rr-shelf .rr-team h3, .rr-shelf .rr-past h3, .rr-shelf .rr-perm h3 { min-height: 2.3em; }
.rr-shelf .rr-team .li-chip, .rr-shelf .rr-past .li-chip, .rr-shelf .rr-perm .li-chip { font-size: .62rem; padding: .28rem .6rem; }
.rr-shelf .rr-team__author, .rr-shelf .rr-past .rr-team__author, .rr-shelf .rr-perm__series { font-size: .85rem !important; }
.rr-shelf .rr-team__dates, .rr-shelf .rr-perm__count { font-size: .65rem !important; letter-spacing: .08em; }
.rr-shelf .rr-team .wp-block-button__link, .rr-shelf .rr-past .wp-block-button__link, .rr-shelf .rr-perm .wp-block-button__link {
  padding: .58rem .6rem; font-size: .77rem; line-height: 1.3;
}
@media (max-width: 640px) {
  /* One card per row — the roomy scale is right again. */
  .rr-shelf .rr-team, .rr-shelf .rr-past, .rr-shelf .rr-perm { --rr-card-pad: 1.1rem; gap: .5rem; }
  .rr-shelf .rr-team h3, .rr-shelf .rr-past h3, .rr-shelf .rr-perm h3 { font-size: 1.3rem; }
  .rr-shelf .rr-team .wp-block-button__link, .rr-shelf .rr-past .wp-block-button__link, .rr-shelf .rr-perm .wp-block-button__link { padding: .75rem 1rem; font-size: .88rem; }
}

/* ---------- Past ARCs card — the shared card (above) with its own buttons ----
   Goodreads + Amazon sit side by side; for a landing-page author a third
   "Sign Up For Invites" button (.rr-invite) spans the full width beneath them
   as a single bar. Unified into the one card 0.31.0 (2026-08-24): the old
   smaller .rr-past shell was retired so Past ARCs matches every other shelf. */
.rr-past .wp-block-buttons { grid-template-columns: 1fr 1fr; }
.rr-past .wp-block-buttons .rr-invite { grid-column: 1 / -1; }

/* ---------- Marked slot (embeds/wiring that land in a later session) ----------
   A visible, honest placeholder: MailerLite form (RR-C), booking flow (RR-D),
   member exclusives (RR-E). Meg can leave or delete them in the editor. */
.rr-slot {
  border: 2px dashed rgba(30,32,25,.4); border-radius: var(--li-radius);
  padding: clamp(1.4rem, 3vw, 2.2rem); text-align: center;
  background: rgba(255,255,255,.4); color: var(--li-ink);
}
.has-forest-background-color .rr-slot, .has-forest-deep-background-color .rr-slot {
  border-color: rgba(245,239,223,.45); background: rgba(20,38,25,.35); color: var(--li-cream);
}
.rr-slot .li-footnote { opacity: .75; }

/* ---------- Genre filter pills (Current ARCs page, RR-B) ----------
   JS-driven: the row only appears once li-motion adds body.li-js, so a
   no-JS visitor simply sees every card (nothing hidden, nothing broken).
   Cards carry rr-g-<genre-slug> classes the filter matches against. */
.rr-filter { display: none; margin-bottom: 1.6rem; }
body.li-js .rr-filter { display: flex; flex-wrap: wrap; gap: .6rem; }
.rr-team.rr-hidden { display: none; }

/* ---------- ARC Calendar — the wall calendar (REBUILT rr-final-2, 2026-08-03)
   ----------------------------------------------------------------------
   Meg's spec, and it is a rebuild rather than a polish: ONE month on screen
   with prev/next paging, and every event's cover taped to its own day cell as
   a tilted hard-shadow sticker, scattered across the grid on the real dates —
   explicitly NOT corralled into an "upcoming releases" block in a corner.

   Colour key unchanged, and it still matches the internal dashboard:
   chartreuse = signups open, lavender = ARC sendout, butter = release day.

   Three things here are load-bearing and a later session should not "tidy"
   them away:

   · The month card is FULL BAND WIDTH now, not `.rr-shelf--2`. Two month cards
     side by side is what forced 70px day cells, and a 42px sticker in a 70px
     cell is why the covers could never have gone on the days before. One month
     at a time buys ~150px cells at 1280 — which is what makes the whole device
     possible, not just what Meg asked for.
   · Fluid `minmax(0,1fr)` columns and a sticker that clamps with the viewport.
     The first month-grid attempt was rejected for overflowing at 390px.
   · JS-off is the STACKED fallback (every month rendered, nothing hidden).
     Paging is added by li-motion.js, which is why nothing in here hides a
     month by default. */
.rr-cal { display: block; }
/* The pager only exists once JS has built it; until then every month shows. */
.rr-cal__nav {
  display: flex; align-items: center; justify-content: center; gap: .6rem;
  margin: 0 0 1rem;
}
.rr-cal__arrow {
  font-family: var(--li-sans); font-size: 1.4rem; line-height: 1;
  width: 44px; height: 44px; border-radius: 999px; cursor: pointer;
  border: 2px solid var(--li-ink); background: var(--li-paper); color: var(--li-ink);
  box-shadow: 3px 4px 0 rgba(30,32,25,.2);
  transition: transform .2s var(--li-pop), box-shadow .2s ease;
}
.rr-cal__arrow:hover:not(:disabled) { transform: translate(-1px,-1px); box-shadow: 5px 6px 0 rgba(30,32,25,.2); }
.rr-cal__arrow:disabled { opacity: .35; cursor: default; box-shadow: none; }
.rr-cal__label {
  font-family: var(--li-display); font-size: clamp(1.25rem, 3vw, 1.6rem);
  font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 500;
  min-width: 9.5em; text-align: center; color: var(--li-ink);
}
/* Belt and braces: the pager hides months with the `hidden` attribute, and a
   stray `display` rule from anywhere else in the cascade must not beat it. */
.rr-cal [hidden] { display: none !important; }

.rr-monthcal {
  display: block;
  /* Branded green wall calendar (Meg, 2026-08-24): the card is forest, so the
     3px grid gaps read as green rules between light cells, like a real wall
     calendar hung on the cream page. */
  background: var(--li-forest); border: 2.5px solid var(--li-ink); border-radius: var(--li-radius);
  padding: clamp(1rem, 2.5vw, 1.8rem); margin-bottom: 1.4rem; color: var(--li-cream);
  box-sizing: border-box;
}
.rr-cal--paged .rr-monthcal { margin-bottom: 0; }
/* Paged: the month name lives in the pager label instead, which carries
   role="heading" aria-level="3" so the outline is unchanged. */
.rr-cal--paged .rr-monthcal__name { display: none; }
.rr-monthcal--quiet {
  /* RR-P4: was `opacity: .6`, which did nothing — .li-anim.li-inview (0,2,0)
     outranks this (0,1,0), so every month card reveals to opacity 1 and the
     "nothing happening this month" signal was silently lost. Measured with
     reveals OFF: computed opacity 1. Raising the specificity instead would
     have compounded .6 with the --li-dim day numbers (.8 × .6 = .48 → 2.9:1),
     i.e. fixed the device by breaking the contrast this session just fixed.
     So the quiet state is carried by the card's ground and border, which
     dims nothing readable. */
  background: var(--li-forest-deep);
  border-color: rgba(30, 32, 25, .45);
}
.rr-monthcal__name {
  font-family: var(--li-display); font-size: 1.5rem; margin: 0 0 1rem !important;
  color: var(--li-cream);
  padding-bottom: .6rem; border-bottom: 2px solid rgba(245,239,223,.22);
}
.rr-monthcal__weekdays, .rr-monthcal__grid {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 3px;
}
.rr-monthcal__weekdays {
  margin-bottom: 4px; font-size: .68rem; font-weight: 800; text-transform: uppercase;
  letter-spacing: .06em; text-align: center; color: var(--li-chartreuse);
}
.rr-monthcal__day {
  position: relative; min-height: clamp(46px, 6vw, 76px); padding: 3px 3px 5px;
  border-radius: 8px; background: var(--li-cream);
  font-size: .72rem; overflow: visible;
}
.rr-monthcal__day--empty { background: none; }
/* CONTRAST (rr-final-2). This used to be `opacity: var(--li-dim)`, and the
   2026-07-27 audit measured the result at 3.61:1. Opacity was the wrong lever:
   it composites the number against whatever ground the cell happens to have,
   so the same rule scored differently on a plain cell, a chartreuse event cell
   and a `--quiet` card. Recession is carried by SIZE and WEIGHT instead, and
   the colour is stated once, so the number scores the same everywhere.
   Do not put `opacity` back on this element. */
.rr-monthcal__daynum {
  display: block; font-weight: 700; font-size: .74rem;
  color: rgba(30,32,25,.86); opacity: 1;
}
/* An event day is warmer paper — "something is on this day". The event TYPE is
   carried by the tab under each sticker, not by the cell, because one day can
   hold two events of different types and a cell can only be one colour. That
   also makes the legend literally true, which it was not before: a release-day
   cell used to paint chartreuse with a butter chip on it. */
.rr-monthcal__day--event { background: var(--li-cream-deep); }
/* Today, marked by li-motion.js off the client clock — the whole point of
   paging to "this month" is being able to see where in it you are.
   The ring goes on the NUMBER, not the cell: grid rows are as tall as their
   tallest cell, so a two-event row makes every other cell in it 210px tall and
   a ring around the cell reads as a large empty box, not as "today". */
.rr-monthcal__day--today .rr-monthcal__daynum {
  display: inline-block; min-width: 1.55em; text-align: center;
  background: var(--li-ink); color: var(--li-cream); border-radius: 999px;
  padding: 1px 0;
}
.rr-monthcal__evt { margin-top: 3px; }
/* The summary is a TRANSPARENT stack, not a card.
   It used to be a bordered, filled chip with the cover inside it, and that was
   the whole problem: a tilted cover inside a straight-edged box does not read
   as tilted at all, so the stickers read as thumbnails in cells. Taking the
   box away puts the cover directly on the cell with its own hard shadow, which
   is the sticker-on-a-wall-calendar effect Meg asked for. */
.rr-monthcal__evt summary {
  list-style: none; cursor: pointer; background: none; border: 0; padding: 1px 0 2px;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
}
.rr-monthcal__evt summary::-webkit-details-marker { display: none; }
.rr-monthcal__evt summary:focus-visible { outline: 2px solid var(--li-ink); outline-offset: 2px; border-radius: 8px; }
/* The handwritten label sits on the type-coloured tab — this is where the
   legend at the foot of the page is cashed in. */
.rr-monthcal__note {
  font-family: var(--li-hand); font-size: clamp(.68rem, 1.6vw, .82rem); line-height: 1.1;
  display: inline-block; text-align: center; word-break: break-word;
  background: var(--li-chartreuse-soft, #e2ea9c);
  border: 1.5px solid var(--li-ink); border-radius: 999px; padding: 0 .45rem 1px;
}
.rr-monthcal__evt--signups-open .rr-monthcal__note { background: var(--li-chartreuse); }
.rr-monthcal__evt--sendout .rr-monthcal__note { background: var(--li-lilac, #ddd4f1); }
.rr-monthcal__evt--release .rr-monthcal__note { background: var(--li-butter, #f3c75c); }

/* ---- The sticker ----
   42x62px, MEASURED LIVE on the LI dev homepage's testimonial cover thumbnails
   (`.li-qcover--* cite::before`, identical at 1280 and 390) on 2026-08-03, so
   both sites share one thumbnail scale. Same 3px radius, same hard
   `2px 3px 0 rgba(30,32,25,.18)` shadow, same ink hairline.

   WIDTH is what is pinned; height is `auto`. Covers on this site run 600x900
   through 600x959 and the standard is that an author's cover is never silently
   cropped — `object-fit: cover` on a mismatched aspect IS a crop. A stack of
   stickers at slightly different heights reads as stickers anyway.

   The clamp floor is 26px because a 390px viewport gives a ~44px day cell. */
.rr-monthcal__sticker {
  display: block; width: clamp(26px, 3.3vw, 42px); line-height: 0;
  border: 1.5px solid var(--li-ink); border-radius: 3px;
  box-shadow: 2px 3px 0 rgba(30, 32, 25, .18);
  background: var(--li-cream-deep);   /* paper fill, so a slow cover is never a hole */
  transition: transform .3s var(--li-pop);
}
.rr-monthcal__sticker img {
  display: block; width: 100%; height: auto; border-radius: 2px;
}
/* Six tilt/offset variants, advanced across the page rather than per month, so
   no two stickers near each other sit at the same angle. A wall calendar where
   every sticker is rotated -3deg reads as a print artefact, not as stickers. */
.rr-monthcal__sticker--t1 { transform: rotate(-3.4deg) translateX(-1px); }
.rr-monthcal__sticker--t2 { transform: rotate(2.6deg)  translateX(1px); }
.rr-monthcal__sticker--t3 { transform: rotate(-2deg); }
.rr-monthcal__sticker--t4 { transform: rotate(3.8deg)  translateX(-1px); }
.rr-monthcal__sticker--t5 { transform: rotate(-4deg)   translateX(1px); }
.rr-monthcal__sticker--t6 { transform: rotate(2deg); }
.rr-monthcal__evt summary:hover .rr-monthcal__sticker { transform: rotate(0) scale(1.08); }

.rr-monthcal__detail {
  position: absolute; z-index: 5; left: 0; top: 100%; margin-top: 4px; width: max-content;
  max-width: 220px; background: var(--li-ink); color: var(--li-cream);
  border-radius: 14px; padding: .9rem 1rem; box-shadow: 4px 6px 0 rgba(30,32,25,.2);
}
.rr-monthcal__detaillabel {
  margin: 0 0 .45rem !important; font-size: .7rem !important; font-weight: 800;
  text-transform: uppercase; letter-spacing: .07em; color: var(--li-chartreuse);
}
.rr-monthcal__detailtitle { margin: 0 0 .25rem !important; font-size: .92rem !important; }
.rr-monthcal__detailgenre {
  margin: 0 0 .6rem !important; font-size: .72rem !important; text-transform: uppercase;
  letter-spacing: .06em; color: rgba(247,238,217,.75);
}
.rr-monthcal__signup {
  display: inline-block; background: var(--li-chartreuse); color: var(--li-ink) !important;
  border-radius: 999px; padding: .45rem .9rem; font-size: .78rem; font-weight: 700;
  text-decoration: none;
}
.rr-monthcal__quiet {
  margin: 1rem 0 0 !important; font-family: var(--li-hand);
  font-size: 1.05rem; text-align: center; color: rgba(30,32,25,.78);
}
/* A detail panel opening from a cell in the last two columns would run off the
   card's right edge; flip it to hang from the right instead. */
.rr-monthcal__grid > .rr-monthcal__day:nth-child(7n) .rr-monthcal__detail,
.rr-monthcal__grid > .rr-monthcal__day:nth-child(7n+6) .rr-monthcal__detail {
  left: auto; right: 0;
}
@media (max-width: 560px) {
  /* A ~40px day cell cannot hold a sticker AND a handwritten label, so the
     label COLLAPSES TO THE COLOURED TAB IT SITS ON. The colour key survives
     at this width — which a plain sr-only label would have quietly taken
     away — and the words are not lost either: every summary's accessible name
     is the full sentence ("7 August — Release day — Our Journey by H K
     Brown"), and the open panel repeats the label in its own header line.
     `font-size: 0` on a span that is already aria-hidden is decoration
     shrinking to a bar, not text being hidden from anyone. */
  .rr-monthcal__note {
    font-size: 0; line-height: 0; padding: 0; height: 6px; width: 72%;
    border-width: 1px;
  }
  .rr-monthcal__daynum { font-size: .68rem; }
  .rr-monthcal__detail { left: -40px; max-width: 180px; }
  .rr-monthcal__grid > .rr-monthcal__day:nth-child(7n) .rr-monthcal__detail,
  .rr-monthcal__grid > .rr-monthcal__day:nth-child(7n+6) .rr-monthcal__detail {
    left: auto; right: -8px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .rr-monthcal__sticker, .rr-cal__arrow { transition: none; }
  .rr-monthcal__evt summary:hover .rr-monthcal__sticker { transform: none; }
}

/* ---------- Members Area toolkit rows (RR-B) ---------- */
.rr-tkrow {
  align-items: center; gap: .8rem 1.2rem !important;
  border: 2px solid var(--li-ink); border-radius: 18px; background: var(--li-paper);
  padding: .8rem 1.1rem; margin-bottom: .8rem; color: var(--li-ink);
}
.rr-tkrow:last-child { margin-bottom: 0; }
.rr-tkrow__book { margin: 0 !important; font-size: 1rem !important; }
.rr-tkrow .wp-block-buttons { gap: .5rem; }
.rr-tkrow .wp-block-button__link { padding: .55rem 1rem; font-size: .8rem; }

/* ---------- Insider signup (MailerLite embed, RR-C) ----------
   The wp:html block holds the ml-embedded div + universal script; the form's
   look is designed in the MailerLite dashboard (Meg-editable there). This
   wrapper just sizes and centres whatever MailerLite renders. */
.rr-signup { max-width: 560px; margin: 0 auto; text-align: center; }

/* ---------- The Insider band — an adjacent two-column composition ----------
   rr-final-1 (2026-08-02) · Meg's item 2, the band she singled out.

   It was a single 980px stack: chapter, heading, lede, then a 560px centred
   form, then a centred note. In a 1152px padding box that put the copy on one
   edge, the form floating on its own centre line, and roughly half the band's
   width carrying nothing — her "content islands far left / far right and a
   huge void".

   The band is now a real composition: the copy column states the offer and
   carries the reader-count note under it; the form column IS the object, a
   paper panel with the site's own card language. Neither half is dead, and the
   band no longer mixes a left-aligned stack with a centred one.

   The column widths are 54/46 rather than 50/50 so the lede has a comfortable
   measure while the form still lands as the heavier object. Core stacks
   `wp-block-columns` below 782px on its own; below that the panel goes back to
   full width and the note re-centres, which is right on a phone. */
.rr-insider__cols { gap: clamp(1.8rem, 4vw, 3.4rem); align-items: center; }
.rr-insider .rr-signup {
  max-width: none; margin: 0; text-align: left;
  background: var(--li-paper); color: var(--li-ink);
  border: 2px solid var(--li-ink); border-radius: 18px;
  box-shadow: 6px 8px 0 rgba(30,32,25,.14);
  padding: clamp(1.3rem, 2.6vw, 1.9rem);
}
/* Inside the panel the form is a narrow column, not a wide inline bar, so the
   field and the button each take the full width instead of leaving a ragged
   gap beside the button. */
.rr-insider .rr-signup__form { max-width: none; margin: 0; }
.rr-insider .rr-signup__email,
.rr-insider .rr-signup__button { flex: 1 1 100%; }
.rr-insider .rr-signup .li-footnote { text-align: left; opacity: .7; margin-top: 1.1rem; }
.rr-insider .li-chapter { margin-bottom: 1.2rem; }
.rr-insider .li-note--left { margin-top: 1.6rem; }
@media (max-width: 781px) {
  .rr-insider .rr-signup { margin: 0 auto; }
  .rr-insider .li-note--left { margin-left: auto; margin-right: auto; text-align: center; }
}
.rr-signup .li-footnote { margin-top: .9rem; }

/* ---------- Reader wall of love: initials-only quotes ----------
   Hard rule: no reader names on any public surface. Reader quotes cite
   initials only; author quotes (public marketing info) may use names. */
.li-quotes .rr-quote--reader cite { letter-spacing: .18em; }

/* ==========================================================
   TEXTURE PASS — ported from the LI theme (Session E item 8).
   The flat-band cure: an off-axis radial tint on large solid bands, and an
   oversized ghost mark floating behind the closing CTA. CSS only, no image
   weight, reduced-motion safe, content never obscured. Warmed here: the
   Reading Room's tint leans butter rather than pure chartreuse.
   ========================================================== */
.li-section.has-forest-background-color,
.li-section.has-forest-deep-background-color {
  background-image:
    radial-gradient(130% 90% at 82% -10%, rgba(243,199,92,.085), transparent 55%),
    radial-gradient(92% 80% at 6% 112%, rgba(107,84,184,.16), transparent 55%);
}
.li-hero, .li-pagehero {
  background-image:
    radial-gradient(120% 85% at 86% -6%, rgba(243,199,92,.11), transparent 55%),
    radial-gradient(82% 72% at 5% 110%, rgba(107,84,184,.20), transparent 55%);
}
.li-cta > * { position: relative; z-index: 1; }
.li-cta::after {
  content: "\2731"; position: absolute; z-index: 0; pointer-events: none;
  right: -5vw; bottom: -17vw; line-height: .7;
  font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1;
  font-size: clamp(300px, 47vw, 760px); color: rgba(248,227,170,.06);
}
.li-section.li-ghosted { position: relative; overflow: hidden; }
.li-section.li-ghosted > * { position: relative; z-index: 1; }
.li-section.li-ghosted::after {
  content: "\2731"; position: absolute; z-index: 0; pointer-events: none;
  right: -3vw; top: -12vw; line-height: .7;
  font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1;
  font-size: clamp(240px, 34vw, 520px); color: rgba(107,84,184,.06);
}
.li-section.li-ghosted.has-forest-background-color::after,
.li-section.li-ghosted.has-forest-deep-background-color::after { color: rgba(248,227,170,.05); }

/* ==========================================================
   E2-A SECTION VOCABULARY — ported into the Reading Room (RR-WRAP,
   2026-07-19; deferred here by E2-B's own priority rule). Defined ONCE at
   token level per fork discipline — never as per-page overrides.
   ========================================================== */

/* ---- Tail refactor (BREAKING, do not revert): the closing CTA and the
   read-more accordion are first-class bands, NOT .li-section groups. They
   carry their own padding here. Putting li-section back double-pads them and
   resurrects the uniform section>cta>section>readmore tail. ---- */
.li-cta { padding: clamp(5rem, 10vw, 9rem) clamp(1.2rem, 5vw, 4rem); }
.li-readmore { padding: clamp(3.4rem, 7vw, 5.5rem) clamp(1.2rem, 5vw, 4rem); }
.li-cta.has-forest-background-color,
.li-cta.has-forest-deep-background-color {
  background-image:
    radial-gradient(130% 90% at 82% -10%, rgba(243,199,92,.085), transparent 55%),
    radial-gradient(92% 80% at 6% 112%, rgba(107,84,184,.16), transparent 55%);
}
/* Closing-CTA treatments — vary them across pages, never all the same. */
.li-cta--minimal { padding-top: clamp(3.4rem, 7vw, 5rem); padding-bottom: clamp(3.4rem, 7vw, 5rem); }
.li-cta--minimal::after { display: none; }
.li-cta__lead {
  font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1;
  font-style: italic; font-weight: 460; font-size: clamp(1.35rem, 3vw, 2.1rem);
  max-width: 26ch; margin: 0 auto 1.4rem !important; line-height: 1.25; color: var(--li-lavender);
}

/* ---- Big-type statement band: one sentence at viewport scale. ---- */
.li-bigtype { padding: clamp(4.5rem, 9vw, 8rem) clamp(1.2rem, 5vw, 4rem); text-align: center; position: relative; overflow: hidden; }
.li-bigtype > * { position: relative; z-index: 1; }
.li-bigtype__kicker { font-family: var(--li-hand) !important; font-size: 1.55rem !important; color: var(--li-lavender-deep); transform: rotate(-2deg); display: inline-block; margin: 0 0 1rem !important; }
/* ⚠ rr-final-1 · THE COMPOUND FORMS ARE LOAD-BEARING, not belt-and-braces.
   These two rules were DESCENDANT-only, and the `has-forest-background-color`
   class sits on the `.li-bigtype` ELEMENT ITSELF (page-home.php, "the whole
   idea" band), never on an ancestor — so neither rule could match and the
   kicker rendered lavender-deep on forest: dark on dark, unreadable, live
   right now. LI hit the identical bug and fixed it the same way (P2). */
.has-forest-background-color .li-bigtype__kicker, .has-forest-deep-background-color .li-bigtype__kicker,
.has-forest-background-color.li-bigtype .li-bigtype__kicker, .has-forest-deep-background-color.li-bigtype .li-bigtype__kicker { color: var(--li-lavender); }
.li-bigtype__line {
  font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1;
  font-weight: 560; font-size: clamp(2.6rem, 8vw, 5.8rem); line-height: 1.02;
  letter-spacing: -.02em; max-width: 17ch; margin: 0 auto !important;
}
.li-bigtype__line em { color: var(--li-lavender-deep); font-style: italic; }
.has-forest-background-color .li-bigtype__line em, .has-forest-deep-background-color .li-bigtype__line em,
.has-forest-background-color.li-bigtype .li-bigtype__line em, .has-forest-deep-background-color.li-bigtype .li-bigtype__line em { color: var(--li-chartreuse); }
.li-bigtype::after {
  content: "\2731"; position: absolute; z-index: 0; pointer-events: none;
  left: -4vw; top: -10vw; line-height: .7;
  font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1;
  font-size: clamp(240px, 40vw, 620px); color: rgba(107,84,184,.06);
}
.has-forest-background-color.li-bigtype::after, .has-forest-deep-background-color.li-bigtype::after { color: rgba(248,227,170,.05); }

/* ---- Offset / overlap editorial grid: breaks the symmetric-grid rhythm. ---- */
.li-offset { display: grid; grid-template-columns: repeat(12, 1fr); gap: clamp(1.2rem, 3vw, 2.4rem); align-items: start; margin-top: 2.4rem; }
.li-offset > * { margin: 0; }
.li-offset > :nth-child(odd) { grid-column: 1 / span 7; }
.li-offset > :nth-child(even) { grid-column: 6 / span 7; transform: translateY(clamp(1.6rem, 4vw, 3.2rem)); }
@media (max-width: 780px) { .li-offset { grid-template-columns: 1fr; } .li-offset > * { grid-column: 1 / -1 !important; transform: none !important; } }

/* ---- Motion character (hover) — keyframe-based so reduced-motion kills it. ---- */
@keyframes li-wiggle { 0%,100% { transform: rotate(-2deg); } 25% { transform: rotate(2.5deg); } 55% { transform: rotate(-1deg); } 80% { transform: rotate(1.5deg); } }
body.li-js .li-chip:hover { animation: li-wiggle .55s ease-in-out; }
.li-marquee:hover .li-marquee__track { animation-play-state: paused; }
/* Rotation-settle reveal variant. ALWAYS add both li-anim and li-anim--settle:
   the reduced-motion rule keys off li-anim to force the element visible. */
body.li-js .li-anim--settle { opacity: 0; transform: translateY(30px) rotate(-3deg) scale(.955); }
body.li-js .li-anim--settle.li-inview { opacity: 1; transform: none; }

/* ==========================================================
   RR-B2 · PERMANENT TEAMS + AUTHOR LANDING PAGES
   Standing/returning teams keep a home on the site even when no campaign is
   running. Cards and book strips are GENERATED by publish_site.py from
   authors.csv + books.csv — see DATA_CONTRACT.md §7–8.
   ========================================================== */
/* .rr-perm (author-page standing shelf) is now the shared unified card — its
   shell, cover, and typography come from the `.rr-team, .rr-past, .rr-perm`
   group above (0.31.0, 2026-08-24). Only its field names (.rr-perm__series /
   .rr-perm__count) differ and they alias into the shared rules. Nothing
   card-specific remains here. */

/* ---- Author landing page: per-series book strips ---- */
.rr-series { margin-top: 2.6rem; }
.rr-series__name {
  font-size: clamp(1.6rem, 3.2vw, 2.2rem); margin: 0 0 .3rem !important;
}
.rr-series__meta { font-weight: 700; font-size: .74rem !important; letter-spacing: .12em; text-transform: uppercase; opacity: .6; margin: 0 0 1.4rem !important; }
.rr-books { display: grid; gap: 1rem; }
.rr-book {
  display: grid; grid-template-columns: 108px 1fr; gap: 1.2rem; align-items: start;
  background: var(--li-paper); border: 2px solid var(--li-ink); border-radius: var(--li-radius);
  padding: 1.1rem 1.3rem; color: var(--li-ink);
  transition: box-shadow .3s ease, transform .3s var(--li-pop);
}
.rr-book:hover { box-shadow: 7px 9px 0 rgba(30,32,25,.16); transform: translateY(-3px); }
.rr-book .wp-block-image { margin: 0; }
/* rr-final-3 · same anti-crop ruling (see `.rr-perm` above). `object-position`
   is TOP here, not bottom: this cover sits beside its own title in a two-column
   strip with `align-items: start`, so the slack belongs under the cover and the
   cover's top edge lines up with the heading beside it. */
.rr-book .wp-block-image img {
  width: 100%; height: auto; aspect-ratio: 2 / 3;
  object-fit: contain; object-position: top; background: var(--li-paper);
  border: 2px solid var(--li-ink); border-radius: 10px; display: block;
}
.rr-book h4 { font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 560; font-size: 1.25rem; line-height: 1.15; margin: 0 0 .35rem; }
.rr-book__order { font-weight: 800; font-size: .74rem !important; letter-spacing: .16em; text-transform: uppercase; color: var(--li-lavender-deep); margin: 0 0 .25rem !important; }
.rr-book__line { font-size: .95rem !important; opacity: .88; margin: 0 0 .7rem !important; max-width: 60ch; }
.rr-book__links { margin: 0 !important; font-size: .85rem !important; font-weight: 700; display: flex; flex-wrap: wrap; gap: .9rem; }
.rr-book__links a { text-decoration: none; border-bottom: 2px solid var(--li-lavender-deep); color: var(--li-ink); }
.rr-book__links a:hover { border-bottom-color: var(--li-butter); }
@media (max-width: 560px) {
  .rr-book { grid-template-columns: 84px 1fr; gap: .9rem; padding: .9rem 1rem; }
}

/* ---- Author socials row ---- */
.rr-socials { display: flex; flex-wrap: wrap; gap: .7rem; justify-content: center; margin-top: 1.6rem !important; }
.rr-socials a {
  display: inline-block; padding: .5rem 1.1rem; border-radius: 999px;
  border: 1.5px dashed var(--li-cream); color: var(--li-cream);
  font-family: var(--li-sans); font-weight: 700; font-size: .82rem; text-decoration: none;
  transition: background-color .25s, color .25s, transform .25s var(--li-pop);
}
.rr-socials a:hover { background: var(--li-cream); color: var(--li-forest); transform: translateY(-2px); }

/* ==========================================================
   RR-E · MEMBER EXCLUSIVES + BADGES
   ========================================================== */
.rr-excl {
  background: var(--li-paper); border: 2px solid var(--li-ink); border-radius: var(--li-radius);
  padding: 1.2rem 1.2rem 1.4rem; display: flex; flex-direction: column; gap: .5rem;
  color: var(--li-ink); height: 100%;
  transition: box-shadow .3s ease, transform .3s var(--li-pop);
}
.rr-excl:hover { box-shadow: 8px 10px 0 rgba(30,32,25,.16); transform: translateY(-5px) rotate(-.5deg); }
.rr-excl .wp-block-image { margin: 0 0 .3rem; }
.rr-excl .wp-block-image img {
  width: 100%; height: auto; aspect-ratio: 1 / 1.294; object-fit: cover; object-position: top center;
  border: 2px solid var(--li-ink); border-radius: 12px; display: block; background: var(--li-cream);
}
.rr-excl__kind { font-weight: 800; font-size: .74rem !important; letter-spacing: .16em; text-transform: uppercase; color: var(--li-lavender-deep); margin: 0 !important; }
.rr-excl h3 { font-size: 1.25rem; line-height: 1.12; margin: 0; }
.rr-excl p:not(.rr-excl__kind) { font-size: .92rem; opacity: .88; margin: 0; }
.rr-excl .wp-block-buttons { margin-top: auto; padding-top: .8rem; }
.rr-excl .wp-block-button { width: 100%; }
.rr-excl .wp-block-button__link { width: 100%; text-align: center; padding: .7rem 1rem; font-size: .86rem; }

/* Badges — earned, awarded by hand (see the definitions band). Never a public
   leaderboard, never a reader name without explicit consent. */
.rr-badge {
  text-align: center; padding: 1.4rem 1rem 1.6rem;
  border: 2px dashed var(--li-ink); border-radius: var(--li-radius);
  background: var(--li-cream); color: var(--li-ink);
  transition: transform .3s var(--li-pop), box-shadow .3s;
}
.rr-badge:nth-child(odd) { transform: rotate(-1.4deg); }
.rr-badge:nth-child(even) { transform: rotate(1.4deg); }
.rr-badge:hover { transform: rotate(0) translateY(-5px); box-shadow: 6px 8px 0 var(--li-butter); }
.rr-badge .wp-block-image { margin: 0 auto .7rem; max-width: 116px; }
.rr-badge .wp-block-image img { width: 100%; height: auto; display: block; }
.rr-badge h3 { font-size: 1.15rem; margin: 0 0 .3rem; }
.rr-badge p { font-size: .88rem !important; opacity: .82; margin: 0 !important; }

/* ==========================================================
   RR-D · GET BOOKED — package select + intake form
   Interim request-to-book: no payment step, no PayPal, nothing that takes a
   card. The form composes a prefilled e-mail to Meg; a booking is a REQUEST
   until she confirms it. Payment wiring waits for her config.
   ========================================================== */
.rr-bookform { max-width: 760px; margin: 0 auto; text-align: left; }
.rr-bookform fieldset { border: 0; padding: 0; margin: 0 0 1.6rem; }
.rr-bookform legend {
  font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1;
  font-weight: 540; font-size: 1.3rem; margin-bottom: .8rem; padding: 0;
}
.rr-field { display: block; margin-bottom: 1rem; }
.rr-field > span {
  display: block; font-family: var(--li-sans); font-weight: 700;
  font-size: .82rem; letter-spacing: .04em; margin-bottom: .35rem;
}
.rr-field > span em { font-style: normal; font-weight: 500; opacity: .6; }
.rr-bookform input[type="text"],
.rr-bookform input[type="email"],
.rr-bookform input[type="url"],
.rr-bookform input[type="date"],
.rr-bookform select,
.rr-bookform textarea {
  width: 100%; box-sizing: border-box;
  border: 2px solid var(--li-ink); border-radius: 14px;
  padding: .8rem 1.05rem; background: var(--li-paper); color: var(--li-ink);
  font-family: var(--li-sans); font-size: .95rem;
}
.rr-bookform textarea { min-height: 110px; resize: vertical; border-radius: 18px; }
.rr-bookform input:focus-visible, .rr-bookform select:focus-visible, .rr-bookform textarea:focus-visible {
  outline: 3px solid var(--li-lavender-deep); outline-offset: 2px;
}
.rr-pickrow { display: grid; gap: .7rem; }
@media (min-width: 720px) { .rr-pickrow { grid-template-columns: repeat(3, 1fr); } }
.rr-pick { display: block; cursor: pointer; }
.rr-pick input { position: absolute; opacity: 0; width: 0; height: 0; }
.rr-pick__body {
  display: block; height: 100%;
  border: 2px solid var(--li-ink); border-radius: var(--li-radius);
  background: var(--li-paper); padding: 1rem 1.1rem 1.2rem;
  transition: background-color .25s, box-shadow .25s, transform .25s var(--li-pop);
}
.rr-pick:hover .rr-pick__body { transform: translateY(-3px); box-shadow: 6px 8px 0 rgba(30,32,25,.14); }
.rr-pick input:checked + .rr-pick__body { background: var(--li-chartreuse); box-shadow: 6px 8px 0 var(--li-ink); }
.rr-pick input:focus-visible + .rr-pick__body { outline: 3px solid var(--li-lavender-deep); outline-offset: 3px; }
.rr-pick__name { display: block; font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 560; font-size: 1.1rem; line-height: 1.15; }
.rr-pick__price { display: block; font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 580; font-size: 1.9rem; color: var(--li-forest); line-height: 1.1; margin-top: .2rem; }
.rr-pick input:checked + .rr-pick__body .rr-pick__price { color: var(--li-forest-deep); }
.rr-pick__note { display: block; font-size: .82rem; opacity: .75; margin-top: .3rem; }
.rr-consent { display: flex; gap: .7rem; align-items: flex-start; font-size: .9rem; margin-bottom: 1.3rem; }
.rr-consent input { margin-top: .25rem; width: 20px; height: 20px; accent-color: var(--li-lavender-deep); flex: none; }
.rr-bookform__submit { margin-top: .4rem; }
.rr-bookform__submit button {
  font-family: var(--li-sans); font-weight: 700; font-size: 1.05rem;
  padding: 1.1rem 2.2rem; border-radius: 999px; cursor: pointer;
  border: 2px solid var(--li-ink); background: var(--li-chartreuse); color: var(--li-ink);
  transition: transform .25s var(--li-pop), box-shadow .25s;
}
.rr-bookform__submit button:hover { box-shadow: 5px 5px 0 var(--li-ink); transform: translateY(-2px); }
.rr-bookform__fallback { font-size: .85rem !important; opacity: .7; margin-top: 1rem !important; }
.rr-bookform__status { font-family: var(--li-hand) !important; font-size: 1.3rem !important; color: var(--li-lavender-deep); margin-top: 1rem !important; }

/* ==========================================================
   v0.8.0 · SESSION RR-P1 — §A ROOT-CAUSE LAYOUT FIXES
   Ported from the LI theme v1.8.0. The Reading Room is a fork
   of that theme and shares its constrained-layout markup, so
   it shipped with the identical three bugs. Measured here in
   WordPress Playground at 1280px BEFORE the fix, across 13
   pages: 32 misaligned intro stacks, 19 offset grid rows,
   8 ragged CTA rows. Fixed once, at token level, below.
   ========================================================== */

/* --- A1 · The chapter-intro alignment bug -------------------
   Meg's #1 recurring complaint on the LI site: "a narrow lede
   sitting between empty side gutters, then a full-width
   paragraph underneath."
   CAUSE: WordPress's constrained layout gives every direct
   child `margin-inline: auto`. This theme caps h2 at 21ch and
   .li-lede at 52ch, so each one centres on its OWN centre line
   while the chapter device and the card grids run the full
   band. Measured on Members Area Chapter 01 at 1280px: chapter
   device left edge 65px, heading 201px, lede 349px — three
   left edges in a single intro.
   FIX: in a left-aligned band the intro stack shares the
   band's left edge. Max-widths stay (they protect line
   length); only the centring goes. Centred bands are excluded,
   so .li-section--center, .li-cta and the heroes are untouched.

   NOTE ON THE SELECTOR — do not "simplify" this back.
   The LI theme's version of this rule targets plain body
   paragraphs with `> p:not([class])`. That clause has never
   matched anything: WordPress renders a plain paragraph block
   as `<p class="wp-block-paragraph">`, so the paragraph always
   has a class attribute. Verified in Playground on this theme:
   `p:not([class])` matched 0 elements, `p.wp-block-paragraph`
   matched 5. It has been harmless on LI only because a
   standard band's content width equals the band, making the
   centring a no-op — it bit hard the moment LI-P3 added the
   narrower 780px `li-legal` band.
   So this port targets `p.wp-block-paragraph` and subtracts
   the deliberate offsets instead. `.li-pull--right` is the one
   that MUST stay excluded: it earns its right-hand position
   from its own `margin-left: auto`, which this rule would
   otherwise overwrite.

   ============================================================
   ⚠ rr-final-1 (2026-08-02) · THE RULE ABOVE WAS SUPERSEDED ON
   LI ON 2026-07-26 AND RR NEVER GOT THE CORRECTION. This is
   that port. Meg's item 2 — "one consistent alignment system".

   `margin-left: 0` un-centres the child against the SECTION's
   padding box. Its centred siblings — the chapter device, the
   card grids, anything WordPress's constrained layout is still
   centring — align to the narrower CONSTRAINED COLUMN. Those
   are the same edge ONLY when the two widths happen to match,
   which at 1280 they do for a 1240px or 1150px band (the
   padding box is 1152) and do NOT for anything narrower.

   Measured on this page before the fix, at 1280:
     · the Insider band (980px column): chapter device at 86px,
       heading at 0px, lede at 0px — an 86px hang, and it is
       exactly Meg's "content islands far left / far right".
     · LI measured up to 469px of spread from the same cause.

   FIX (LI-P2b's): shift the intro stack by the column's OWN
   offset instead of to zero, and give every band its column
   width as a class so CSS can name a column that has no box —
   WordPress implements `constrained` as max-width + auto
   margins on each child, not as a wrapper element.
   Falls back to today's behaviour when `--li-col` is unset, so
   an untagged band is never worse off than it is now.
   ============================================================ */
/* rr-final-3 (2026-08-03): 420 / 760 / 860 added when the tagging pass went
   sitewide — the link-in-bio card, the three legal `.li-prose` pages and the
   booking-received hero declare column widths Home never used. A band tagged
   with a class that does not exist silently falls back to the untagged
   behaviour, which is the bug this whole rule exists to fix. */
.li-col-420  { --li-col: 420px; }
.li-col-620  { --li-col: 620px; }
.li-col-680  { --li-col: 680px; }
.li-col-760  { --li-col: 760px; }
.li-col-780  { --li-col: 780px; }
.li-col-860  { --li-col: 860px; }
.li-col-820  { --li-col: 820px; }
.li-col-880  { --li-col: 880px; }
.li-col-900  { --li-col: 900px; }
.li-col-980  { --li-col: 980px; }
.li-col-1080 { --li-col: 1080px; }
.li-col-1100 { --li-col: 1100px; }
.li-col-1120 { --li-col: 1120px; }
.li-col-1150 { --li-col: 1150px; }
.li-col-1200 { --li-col: 1200px; }
.li-col-1240 { --li-col: 1240px; }
.li-col-1320 { --li-col: 1320px; }

/* Belt-and-braces, ported from LI's A1 post-push finding: a component that
   knows its own content width should not depend on a class being remembered by
   whatever PHP concatenates its class list. The class above stays the general
   mechanism; this is the safety net for the helper-built bands. */
.li-arcwall-band { --li-col: 1240px; }
.rr-insider { --li-col: 1080px; }

.li-section:not(.li-section--center) > h2,
.li-section:not(.li-section--center) > h3,
.li-section:not(.li-section--center) > .li-lede,
.li-section:not(.li-section--center) > .wp-block-heading,
/* rr-final-3 (2026-08-03): plain `.li-pull` JOINED the shifted stack.
   rr-final-1 left-aligned Home's pull line ("You bring the reading…") because
   a right-hanging line with no left counterweight is the anti-pattern Meg
   named — and this session did the same to the three that survived on About,
   Review Guide and Get Booked. A left-aligned pull line is part of the
   left-aligned intro stack and has to shift with it, or it hangs at the
   padding box while the heading above it sits at the column: 81px apart at
   1440 in a 1150 band. `--right` and `--center` stay excluded; they earn
   their position from their own margins, which this rule would overwrite. */
.li-section:not(.li-section--center) > p.wp-block-paragraph:not(.li-note):not(.li-pull--right):not(.li-pull--center):not(.li-footnote):not(.li-chip) {
  margin-left: max(0px, calc((100% - var(--li-col, 100%)) / 2)) !important;
  margin-right: auto !important;
}

/* THE CENTRING ALLOWLIST — ported from LI, where its absence caused review
   findings three separate times (PATTERN_CONVENTIONS.md, dev-final-3 section).
   The rule above is (0,3,1). A bare component class is (0,1,0), and BOTH sides
   carry `!important`, so specificity decides and the rule above always wins:
   a class can declare `margin-inline: auto` and still render hard left, with
   nothing erroring. Keep BOTH the `p.x` and bare `.x` forms — the
   element-qualified one to match the weight, the bare one for non-paragraphs.
   ANY new class that wants centring inside a `.li-section` goes on this list. */
.li-section:not(.li-section--center) > p.li-note,
.li-section:not(.li-section--center) > p.li-footnote,
.li-section:not(.li-section--center) > p.li-center,
.li-section:not(.li-section--center) > p.has-text-align-center,
.li-section:not(.li-section--center) > p.li-arcwall__more,
.li-section:not(.li-section--center) > p.li-pull--center,
.li-section:not(.li-section--center) > .li-note,
.li-section:not(.li-section--center) > .li-footnote,
.li-section:not(.li-section--center) > .li-center,
.li-section:not(.li-section--center) > .has-text-align-center,
.li-section:not(.li-section--center) > .li-arcwall__more,
.li-section:not(.li-section--center) > .li-pull--center {
  margin-left: auto !important;
  margin-right: auto !important;
}
/* The one that is deliberately NOT centred: it hangs right. */
.li-section:not(.li-section--center) > p.li-pull--right,
.li-section:not(.li-section--center) > .li-pull--right {
  margin-left: auto !important;
  margin-right: 0 !important;
}

/* --- A2 · "The first card is higher than the rest" ----------
   CAUSE: core's block-gap emulation puts `margin-top` on every
   child EXCEPT the first (`> * + *`). Inside a CSS grid that
   already owns its row-gap that margin does two wrong things:
   it double-spaces the rows, and within the FIRST row it lifts
   child 1 by exactly the gap above its rowmates. Later rows
   look flush because every child in them carries the margin.
   A real layout offset, not a design stagger and not the
   reveal animation.
   FIX: the grid owns its own spacing; drop the sibling margin. */
.li-grid > * { margin-top: 0 !important; }

/* --- A3 · Card CTAs anchor to the card bottom ---------------
   So the CTA links land on ONE line across a row instead of
   floating wherever the copy above them happens to end. Cards
   were never flex columns, so nothing could be pushed down. */
.li-card { display: flex; flex-direction: column; }
.li-card__cta { margin-top: auto; padding-top: .9rem; margin-bottom: 0; }
.li-card__cta a { font-weight: 600; text-decoration-thickness: 2px; text-underline-offset: 3px; }
/* Packages are already flex columns — just push their button row down. */
.li-pkg > .wp-block-buttons { margin-top: auto; padding-top: 1rem; }

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
  body.li-js .li-anim, body.li-js .li-w { opacity: 1 !important; transform: none !important; }
  body.li-js .li-squiggle-svg path { stroke-dashoffset: 0 !important; }
  .li-marquee__track, .li-arctrack { animation: none !important; }
  /* rr-final-1 · port of LI's frozen-track cap, adapted. Each cover track emits
     its set TWICE so the loop is seamless; frozen, the second pass is dead
     weight — ~66 extra <img> nodes for a wall that is no longer moving. The
     helper tags that half `--dup` precisely so this rule can drop it without
     LI's `nth-child(n+2)`, which on RR would have hidden every cover but the
     first (see rr_pastarcs_banner_markup()). The wall stays a wall. */
  .li-arctrack__img--dup { display: none !important; }
  /* nav: keep the hover/focus GATE (submenus must still be closed by default),
     drop only the choreography. Do NOT set opacity:1 on the submenu container
     here — that forces every dropdown permanently open. */
  .li-head .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container > .wp-block-navigation-item { animation: none !important; }
  .li-head .wp-block-navigation__submenu-container > .wp-block-navigation-item { transition-delay: 0s !important; }
  .li-preloader { display: none !important; }
}

/* ==========================================================
   v0.8.1 · SESSION QA-2 — the LI QA-1 fix list, ported
   The RR theme is a fork of the LI theme and shares the same
   components, so it shares the same defects. Ported here:
   the header's Safari fallback, the read-more summary contrast,
   the .li-note colour, the sub-10px micro-labels (all above,
   at their own rules), plus the two below. The announcement
   bar and the Fluent Forms skin have no counterpart in RR —
   this theme has neither — so nothing is ported for those.
   ========================================================== */

/* --- P1·4 · Hamburger tap target (was 24×24; 44 is the floor,
   and on RR the burger is likewise the only route to nav on a
   phone). Core sizes the icon, not the button. */
.li-head .wp-block-navigation__responsive-container-open,
.li-head .wp-block-navigation__responsive-container-close {
  min-width: 44px; min-height: 44px;
  align-items: center; justify-content: center;
  padding: 10px;
}
/* The `display` is set ONLY where core already shows the button. Setting it
   unconditionally overrides core's own `@media (min-width:600px){ …-open
   { display:none } }` — same specificity, later in the cascade — and puts a
   hamburger on the desktop header beside the full nav. Caught in QA-2's
   pre-flight measurement; the first draft of this rule did exactly that. */
@media (max-width: 819px) {
  .li-head .wp-block-navigation__responsive-container-open { display: flex; }
}

/* --- The 600–819px header, ported from LI ------------------------------
   Core drops the overlay menu at exactly 600px. LI's seven-item nav does
   not fit between 600 and 819 (measured: the header CTA sat 121px past the
   viewport at 600, clipped rather than overflowing, so no width sweep ever
   saw it). RR's header carries TWELVE top-level items plus a Join CTA, so
   it cannot fit either. Ported on that reasoning, and stated honestly:
   this one is NOT measured — RR is installed nowhere. Confirm it in
   Playground or on the subdomain at the RR-G install. */
@media (min-width: 600px) and (max-width: 819px) {
  .li-head .wp-block-navigation__responsive-container:not(.is-menu-open) { display: none; }
}
.li-head .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-close { display: flex; }
.li-head .wp-block-navigation__responsive-container-open svg,
.li-head .wp-block-navigation__responsive-container-close svg { width: 26px; height: 26px; }
.li-head .wp-block-navigation__responsive-container-open:focus-visible,
.li-head .wp-block-navigation__responsive-container-close:focus-visible {
  outline: 3px solid var(--li-chartreuse); outline-offset: 2px; border-radius: 8px;
}

/* --- P5·12 · Tap targets on standalone controls. WCAG 2.2
   SC 2.5.8 exempts links inline in a sentence, so this raises
   the controls that stand alone, not every anchor. */
.li-card__cta a { display: inline-flex; align-items: center; min-height: 44px; }
.li-readmore .wp-block-details summary { min-height: 44px; }

/* --- P2·6 extension · lavender-on-lavender, found in QA-2's own
   pre-flight measurement and NOT on QA-1's list. QA-1 measured the
   marginalia at 4.12–4.44:1 on the cream bands. It never caught the
   notes sitting on a LAVENDER band — Brand Assets, Contact and
   Newsletter — where lavender-deep on #b2a1e0 measures 3.13:1 after
   the darkening (and 2.5:1 before it). At 23.2px/500 that is normal
   text by WCAG's reckoning, so 4.5 is the bar, not 3. On the saturated
   light bands the note takes the ink colour instead; the lilac band is
   already fine at 5.1:1 and is deliberately left alone. */
.has-lavender-background-color .li-note,
.has-chartreuse-background-color .li-note,
.has-butter-background-color .li-note { color: var(--li-forest-deep); }
.has-lavender-background-color .li-pkg__tag,
.has-lavender-background-color .li-label::before,
.has-chartreuse-background-color .li-pkg__tag,
.has-chartreuse-background-color .li-label::before { color: var(--li-forest-deep); }

/* ==========================================================
   v0.9.0 · SESSION RR-P4 — the parity pass
   Sitewide fixes measured on the rendered pages, not read off
   the source. Contrast numbers below are composited through
   translucent layers and element opacity; the audit's figures
   (calendar day numbers "1.00:1") came from a checker that did
   neither and are corrected in the run log.
   ========================================================== */

/* --- Screen-reader-only heading utility, ported from LI (QA-2 gave the
   Link in Bio page an li-sr-only H1 by the same reasoning). RR's fork
   never got the port, so /links/ shipped with NO H1 at all and three
   card pages jump h1 → h3. A visible chapter label already names each
   of those sections; it is a <p> for design reasons, so the heading
   that fixes the outline is the invisible one. */
.li-sr-only {
  position: absolute !important; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* --- Marginalia that sets its own opacity outside the --li-dim token.
   .li-mcard__note inherits opacity .85 from `.li-mcard p`, which put the
   (already QA-2-darkened) lavender-deep at 4.44:1 — short of 4.5 by a
   hair. At full opacity the same pair measures 5.34:1. */
.li-mcard p.li-mcard__note { opacity: 1; }

/* --- Footer base links compounded two opacities: .li-foot a at .8 inside
   .li-foot__base at .6 gives .48, and cream-on-ink at .48 measures 4.32:1.
   It read as a contrast failure on all 15 pages that have a footer. The
   base text itself stays dimmed; only the links come back to full. */
.li-foot__base a { opacity: 1; }

/* --- The Insider band ---------------------------------------------------
   2026-07-28: MailerLite is gone (price rise), and with it the whole reason
   this block used to be complicated.

   The history is worth keeping because it explains why the markup changed
   shape: div.ml-embedded measured 560×0 with zero inputs, because MailerLite
   forms created through the API render nothing until a design is saved in
   their dashboard. The site's primary conversion path was an empty box, and
   the hosted share URL for the same form returned 503, so "link to it
   instead" was not available either. The band therefore carried a dashed
   fallback panel and used :empty and :has() to swap states.

   None of that is needed now. Listmonk takes a plain HTML form posting to
   /subscription/form — no external script, no dashboard step, and it renders
   identically with JavaScript switched off. So the fallback panel is gone
   and the band simply holds the form. Fewer states, no third-party request,
   and the empty-box failure mode is structurally impossible.

   The honeypot input is Listmonk's own bot trap: it must exist, must be
   named `nonce`, and must stay empty. Hidden from sight and from assistive
   tech, and skipped in the tab order. */
.rr-signup__form {
  display: flex; flex-wrap: wrap; gap: .7rem; justify-content: center;
  align-items: stretch; margin: 0 auto; max-width: 34rem;
}
.rr-signup__email {
  flex: 1 1 16rem; min-width: 0;
  padding: .85rem 1.1rem;
  font: inherit; font-size: 1rem; color: var(--li-ink, #1e2019);
  background: #fdf8e7;
  border: 2px solid var(--li-ink, #1e2019);
  border-radius: 999px;
}
.rr-signup__email::placeholder { color: rgba(30,32,25,.55); }
.rr-signup__email:focus-visible {
  outline: 3px solid var(--li-chartreuse, #c9d64f); outline-offset: 2px;
}
.rr-signup__button {
  flex: 0 0 auto; padding: .85rem 1.7rem;
  font: inherit; font-size: 1rem; font-weight: 700; cursor: pointer;
  color: var(--li-ink, #1e2019);
  background: var(--li-chartreuse, #c9d64f);
  border: 2px solid var(--li-ink, #1e2019);
  border-radius: 999px;
}
.rr-signup__button:hover { filter: brightness(1.06); }
.rr-signup__button:focus-visible {
  outline: 3px solid var(--li-ink, #1e2019); outline-offset: 3px;
}
/* Listmonk honeypot — present for bots, invisible and unreachable for people. */
.rr-signup__nonce {
  position: absolute !important; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}

/* ── RR-P5 · "cover coming" plate ──────────────────────────────────────────
   Four books on Rochelle L. Wilcox's page are unreleased and have no cover
   yet — that is MEG-WORK and nothing here invents one. What changed is that
   they no longer ship four third-party `placehold.co` requests on a launch-
   bound reader page: the plate is drawn in the theme, keeps the 2:3 cover
   aspect so the grid does not reflow when a real cover lands, and SAYS the
   cover is coming instead of showing a grey box that reads as a broken image.
   The tone modifier keeps the four visually distinct, as the placeholders were.
   ------------------------------------------------------------------------ */
.rr-nocover {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .35rem; aspect-ratio: 2 / 3; width: 100%; margin: 0;
  border: 2px dashed var(--li-ink); border-radius: 6px;
  background: var(--li-lilac); color: var(--li-ink);
  text-align: center; padding: 1rem;
  box-sizing: border-box;
}
.rr-nocover--ddd4f1 { background: var(--li-lilac); }
.rr-nocover--e2ea9c { background: var(--li-chartreuse-soft); }
.rr-nocover--f3c75c { background: var(--li-butter); }
.rr-nocover__mark { font-family: var(--li-sans); font-size: 1.6rem; line-height: 1; opacity: .55; }
.rr-nocover__t {
  font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1;
  font-weight: 600; font-size: clamp(.95rem, 2.2vw, 1.15rem); line-height: 1.15;
}
.rr-nocover__s {
  font-family: var(--li-sans); font-size: .7rem; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase; opacity: .6;
}

/* ── Visually-hidden utility (v0.10.0, 2026-07-28) ────────────────────────
   Added with the Listmonk signup form. Block themes do not inherit
   `.screen-reader-text` from core, so without this the form's hidden label
   renders as visible text above the input.
   ------------------------------------------------------------------------ */
.screen-reader-text {
  position: absolute !important; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}
.screen-reader-text:focus {
  position: static !important; width: auto; height: auto;
  margin: 0; clip: auto; white-space: normal;
}

/* ==========================================================
   §RR-LOGO (v0.9.2) · THE REAL LOGO FILE, finally wired.
   Meg, 2026-07-28: "we still don't have the reading room
   using the actual logo file."

   She was right. `assets/img/logo/` held three FAVICONS and
   nothing else, and all three wordmarks — header, footer and
   Link in Bio — were CSS-styled TEXT ("The Reading✱Room" with
   a chartreuse ✱ span). The drawn logo had never entered the
   theme.

   WHICH VARIANT, AND WHY. All three sites are DARK:
   `.li-head` is forest-deep at 88%, `.li-foot` is --li-ink,
   and the Link-in-Bio wordmark sits on the dark pagehero. So
   all three take the cream-and-lavender lockup, which also
   matches the lavender-on-dark / chartreuse-on-light accent
   split Meg locked for the LI suite. `rr-logo-on-light.svg`
   (forest + chartreuse) is in the theme for any future light
   band; nothing uses it yet.

   NOTE this changes the accent from chartreuse to lavender in
   the header and footer, because that is what the drawn file
   uses. The old chartreuse ✱ was the text stand-in, not the
   logo.

   WHY A BACKGROUND IMAGE and not a <wp:image> block: header
   and footer are TEMPLATE PARTS — .html, never run through
   PHP — so `get_theme_file_uri()` is unavailable and any
   hard-coded URL would break when the RR moves from
   /reading-room/ to its own subdomain. A url() inside
   style.css resolves relative to the STYLESHEET, so it is
   correct at any install path. The accessible name is kept as
   real `li-sr-only` text in the markup, not as alt-on-a-
   background, so screen readers still announce it.
   Link in Bio IS a PHP pattern, so it gets a real <img>.
   ========================================================== */
.li-head__logo p a {
  display: block;
  /* v0.15.0 (Meg, 2026-08-04): matched to the LI header lockup, which is 52px
     tall (.li-head__brand .li-brand-svg). The RR mark was 46px and read smaller
     than its sibling site on the same screen. */
  width: 122px; height: 52px;
  background: url(assets/img/logo/rr-logo-on-dark.svg) left center / contain no-repeat;
}
.li-foot__logo {
  /* LI's footer lockup is 56px. */
  width: 131px; height: 56px;
  background: url(assets/img/logo/rr-logo-on-dark.svg) left center / contain no-repeat;
}
@media (max-width: 780px) {
  .li-head__logo p a { width: 92px; height: 40px; }
  .li-foot__logo { width: 146px; height: 62px; }
}
.li-linkbio__logo { margin: 1.1rem auto .2rem !important; max-width: 210px; }
.li-linkbio__logo img { width: 100%; height: auto; display: block; }

/* 2026-08-17 — hide the "Keep reading" SEO read-more sections (kept in DOM, not shown) */
.li-readmore { display: none !important; }

/* ============================================================
   2026-08-17 — Book Club blog cards matched to the LI blog:
   titlecards (forest block + cream Fraunces title, no featured
   image), ported from the literary-inspired theme.
   ============================================================ */
.li-postcard--tc { display: flex; flex-direction: column; }
.li-titlecard {
  position: relative; overflow: hidden; isolation: isolate;
  background: var(--li-forest); color: var(--li-cream);
  min-height: 190px;
  display: flex; align-items: flex-end;
  padding: 1.5rem 1.4rem 1.4rem;
}
.li-postcard--tc .li-titlecard .wp-block-post-title { padding: 0; margin: 0; }
.li-postcard--tc .li-titlecard .wp-block-post-title,
.li-postcard--tc .li-titlecard .wp-block-post-title a {
  position: relative; z-index: 2;
  color: var(--li-cream);
  font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1;
  font-weight: 500; font-size: clamp(1.2rem, 1.9vw, 1.5rem); line-height: 1.14;
  text-decoration: none;
}
.li-postcard--tc .li-titlecard .wp-block-post-title a:hover { text-decoration: none; }
.li-postcard--tc .wp-block-post-date { padding: 1rem 1.3rem 0; }
.li-postcard--tc .wp-block-post-excerpt { padding: .45rem 1.3rem 1.3rem; }
.li-postcard--tc > .li-chip { margin: 1rem 1.3rem 0; }
/* Blog title-card variety (2026-08-24): the listing was a wall of identical
   forest blocks with a big empty top and one small asterisk, so nothing drew
   the eye. Now each card's title block cycles through the brand's dark colours
   and carries a large hand-drawn doodle watermark in the empty space, so the
   grid reads as a lively, varied shelf. Colour + doodle cycle by position, so
   every post is styled automatically with no per-post image needed. */
.li-postcard--tc:nth-child(3n+1) .li-titlecard { background: var(--li-forest); }
.li-postcard--tc:nth-child(3n+2) .li-titlecard { background: var(--li-lavender-deep); }
.li-postcard--tc:nth-child(3n)   .li-titlecard { background: var(--li-forest-deep); }
.li-titlecard::after {
  content: ""; --li-dood-tint: var(--li-chartreuse);
  position: absolute; z-index: 1; pointer-events: none;
  top: 1.1rem; right: 1.2rem; width: 4.8rem; height: 4.8rem; opacity: .55;
  background: var(--li-dood-tint);
  -webkit-mask: center/contain no-repeat var(--li-tc-dood);
          mask: center/contain no-repeat var(--li-tc-dood);
  animation: li-tc-spin 9s ease-in-out infinite alternate;
}
.li-postcard--tc:nth-child(3n+2) .li-titlecard::after { --li-dood-tint: var(--li-chartreuse-soft); }
.li-postcard--tc:nth-child(3n)   .li-titlecard::after { --li-dood-tint: var(--li-lavender); }
/* doodle shape cycles independently, so a colour run never repeats the same motif */
.li-postcard--tc:nth-child(6n+1) .li-titlecard { --li-tc-dood: url(assets/img/doodles/book.png); }
.li-postcard--tc:nth-child(6n+2) .li-titlecard { --li-tc-dood: url(assets/img/doodles/pencil.png); }
.li-postcard--tc:nth-child(6n+3) .li-titlecard { --li-tc-dood: url(assets/img/doodles/star.png); }
.li-postcard--tc:nth-child(6n+4) .li-titlecard { --li-tc-dood: url(assets/img/doodles/megaphone.png); }
.li-postcard--tc:nth-child(6n+5) .li-titlecard { --li-tc-dood: url(assets/img/doodles/book-open.png); }
.li-postcard--tc:nth-child(6n)   .li-titlecard { --li-tc-dood: url(assets/img/doodles/mug.png); }
@keyframes li-tc-spin {
  from { transform: rotate(-8deg) translate3d(0,0,0); }
  to   { transform: rotate(10deg) translate3d(2px,-3px,0); }
}
.li-postcard--tc { position: relative; transition: box-shadow .3s ease, transform .3s var(--li-pop); }
.li-postcard--tc:nth-child(odd)  { transform: rotate(-1.5deg); }
.li-postcard--tc:nth-child(even) { transform: rotate(1.5deg); }
.li-postcard--tc:hover { transform: rotate(0) translateY(-4px); }
.li-postcard--tc:nth-child(4n+1)::before,
.li-postcard--tc:nth-child(6n+4)::before {
  content: ""; position: absolute; z-index: 4; pointer-events: none;
  top: -12px; left: 50%; width: 108px; height: 28px;
  transform: translateX(-50%) rotate(-3.5deg);
  background: linear-gradient(180deg, rgba(243,199,92,.60), rgba(243,199,92,.84));
  box-shadow: 0 2px 5px rgba(30,32,25,.16); border-radius: 1px;
}
.li-postcard--tc:nth-child(6n+4)::before { transform: translateX(-50%) rotate(2.6deg); left: 46%; }
@media (prefers-reduced-motion: reduce) {
  .li-titlecard::after { animation: none; }
  .li-postcard--tc, .li-postcard--tc:nth-child(odd), .li-postcard--tc:nth-child(even), .li-postcard--tc:hover { transform: none; }
}

/* 2026-08-17 fix: ARC card (.rr-team) titles were inheriting the cream heading
   colour from a coloured-section rule. Pin them to ink so they always read. */
.rr-team h3, .rr-team h3.wp-block-heading { color: var(--li-ink); }

/* ==========================================================
   READER DOODLES (ported from the LI theme, 2026-08-24). The reader side
   "pulls hardest on the reader doodles" (brand guide). A .li-dood is a span
   whose brand-colour fill is cut to a hand-drawn doodle silhouette by a CSS
   mask, so a pack of doodles from any source reads as one recoloured family.
   mask-image is a REAL url() (not a CSS var) so it resolves relative to this
   stylesheet, not the page URL.
   ========================================================== */
.li-dood {
  display: inline-block; vertical-align: middle; flex: none;
  width: var(--li-dood-size, 2.4rem); height: var(--li-dood-size, 2.4rem);
  background: var(--li-forest);
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: contain; mask-size: contain;
}
.li-dood--sm { --li-dood-size: 1.5rem; }
.li-dood--lg { --li-dood-size: 3.4rem; }
.li-dood--xl { --li-dood-size: clamp(4rem, 8vw, 6rem); }
.has-forest-background-color .li-dood, .has-forest-deep-background-color .li-dood,
.has-lavender-deep-background-color .li-dood { background: var(--li-chartreuse); }
.li-dood.li-dood--chartreuse { background: var(--li-chartreuse); }
.li-dood.li-dood--lavender   { background: var(--li-lavender-deep); }
.li-dood.li-dood--cream      { background: var(--li-cream); }
.li-dood.li-dood--butter     { background: var(--li-butter); }
.li-dood.li-dood--ink        { background: var(--li-ink); }
.li-dood.li-dood--forest     { background: var(--li-forest); }
.li-dood--book       { -webkit-mask-image: url(assets/img/doodles/book.png);        mask-image: url(assets/img/doodles/book.png); }
.li-dood--book-open  { -webkit-mask-image: url(assets/img/doodles/book-open.png);   mask-image: url(assets/img/doodles/book-open.png); }
.li-dood--notebook   { -webkit-mask-image: url(assets/img/doodles/notebook.png);    mask-image: url(assets/img/doodles/notebook.png); }
.li-dood--pencil     { -webkit-mask-image: url(assets/img/doodles/pencil.png);      mask-image: url(assets/img/doodles/pencil.png); }
.li-dood--megaphone  { -webkit-mask-image: url(assets/img/doodles/megaphone.png);   mask-image: url(assets/img/doodles/megaphone.png); }
.li-dood--clock      { -webkit-mask-image: url(assets/img/doodles/clock.png);       mask-image: url(assets/img/doodles/clock.png); }
.li-dood--mug        { -webkit-mask-image: url(assets/img/doodles/mug.png);         mask-image: url(assets/img/doodles/mug.png); }
.li-dood--calendar   { -webkit-mask-image: url(assets/img/doodles/calendar.png);    mask-image: url(assets/img/doodles/calendar.png); }
.li-dood--schedule   { -webkit-mask-image: url(assets/img/doodles/schedule.png);    mask-image: url(assets/img/doodles/schedule.png); }
.li-dood--star       { -webkit-mask-image: url(assets/img/doodles/star.png);        mask-image: url(assets/img/doodles/star.png); }
.li-dood--stars5     { -webkit-mask-image: url(assets/img/doodles/stars5.png);      mask-image: url(assets/img/doodles/stars5.png); }
.li-dood--sparkle    { -webkit-mask-image: url(assets/img/doodles/sparkle.png);     mask-image: url(assets/img/doodles/sparkle.png); }
.li-dood--star-bubble{ -webkit-mask-image: url(assets/img/doodles/star-bubble.png); mask-image: url(assets/img/doodles/star-bubble.png); }
.li-dood--medal      { -webkit-mask-image: url(assets/img/doodles/medal.png);       mask-image: url(assets/img/doodles/medal.png); }
.li-dood--laurel     { -webkit-mask-image: url(assets/img/doodles/laurel.png);      mask-image: url(assets/img/doodles/laurel.png); }
.li-dood--camera     { -webkit-mask-image: url(assets/img/doodles/camera.png);      mask-image: url(assets/img/doodles/camera.png); }
.li-dood--question   { -webkit-mask-image: url(assets/img/doodles/question.png);    mask-image: url(assets/img/doodles/question.png); }
.li-dood--sale       { -webkit-mask-image: url(assets/img/doodles/sale.png);        mask-image: url(assets/img/doodles/sale.png); }
@keyframes li-bob  { 0%,100%{ transform: translateY(0) rotate(-3deg); } 50%{ transform: translateY(-6px) rotate(3deg); } }
@keyframes li-bob2 { 0%,100%{ transform: translateY(0) rotate(2deg); }  50%{ transform: translateY(-5px) rotate(-3deg); } }
.li-dood--bob  { animation: li-bob  3.4s ease-in-out infinite; }
.li-dood--bob2 { animation: li-bob2 4s   ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .li-dood--bob, .li-dood--bob2 { animation: none; } }
/* Doodle accent row (About pagehead, 2026-08-24): a small hand-drawn flourish
   under the page lede so the brand's doodle language greets a reader up top,
   without decorating the editorial body. */
.li-doodrow { display: flex; gap: 1.7rem; margin: 1.5rem 0 0; }
.li-doodrow .li-dood { --li-dood-size: 2.5rem; }

/* Author-page shelf (2026-08-24): the "On the shelf" section uses the SAME
   unified .rr-past card as the rest of the site, 4 across, with a centred
   "Read more" reveal for books past the first four (Meg's spec). */
.rr-shelf--4 { --rr-shelf-cols: 4; }
@media (max-width: 1100px) { .rr-shelf--4 { --rr-shelf-cols: 3; } }
@media (max-width: 900px)  { .rr-shelf--4 { --rr-shelf-cols: 2; } }
@media (max-width: 640px)  { .rr-shelf--4 { --rr-shelf-cols: 1; } }
.rr-shelfmore { margin-top: 1.4rem; }
.rr-shelfmore summary {
  list-style: none; cursor: pointer; width: fit-content; margin: 0 auto;
  font-family: var(--li-sans); font-weight: 700; font-size: .92rem;
  padding: .7rem 1.6rem; border-radius: 999px; border: 2px solid var(--li-ink);
  background: var(--li-lavender); color: var(--li-forest-deep);
  box-shadow: 4px 4px 0 var(--li-ink); text-align: center;
  transition: transform .2s var(--li-pop);
}
.rr-shelfmore summary::-webkit-details-marker { display: none; }
.rr-shelfmore summary::marker { content: ""; }
.rr-shelfmore summary:hover { transform: translate(-2px, -2px); }
.rr-shelfmore[open] summary { margin-bottom: 1rem; }

/* ==========================================================
   RR-FINAL-01 · 2026-08-27 · Meg's Reading Room feedback batch
   Items 1, 3 and 6. Appended as one block so the whole round is
   readable in one place and easy to lift back out.
   ========================================================== */

/* --- Item 1 · the home strip ------------------------------
   The strip is LILAC (it had drifted to cream-deep), and the wording is
   spaced out instead of running together as one sentence. The spacing was
   never a CSS problem: li-motion.js rebuilds any .li-marquee that contains a
   <p> by copying its textContent into two track spans, which throws away
   every separator and every gap. So the home strip now ships the track
   markup itself, exactly as literaryinspired.com does, and the JS skips it
   because there is no <p> to find. Same component, same look, both sites. */
.li-marquee .li-mqtrack {
  display: inline-flex; flex-wrap: nowrap; white-space: nowrap;
  animation: li-mqscroll 46s linear infinite; will-change: transform;
}
.li-marquee .li-mqset {
  display: inline-block;
  font-family: var(--li-display); font-style: italic; font-weight: 500;
  font-variation-settings: "SOFT" 100, "WONK" 1;
  font-size: clamp(1.1rem, 2.3vw, 1.55rem); letter-spacing: .03em; line-height: 1.15;
}
.li-marquee .li-mqsep {
  font-style: normal; margin: 0 2.4em; opacity: .5;
  font-size: .72em; vertical-align: .12em; color: var(--li-forest);
}
.li-marquee:hover .li-mqtrack { animation-play-state: paused; }
@keyframes li-mqscroll { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .li-marquee .li-mqtrack { animation: none; } }

/* --- Item 3 · the six-step process strip ------------------
   It read as loose text floating on the page background. It is now its own
   striped banner: a full-bleed soft-chartreuse band with the same hard ink
   rails the marquee uses, so the kit language is consistent.
   The doodle box also stops being square. Several of Meg's doodles are wider
   than they are tall, and `mask-size: contain` inside a square box shrank
   them to a sliver rather than cropping them. A wider box means every doodle
   shows in full AND at a size that reads. */
.rr-procband {
  background: var(--li-chartreuse-soft);
  border-top: 2px solid var(--li-ink);
  border-bottom: 2px solid var(--li-ink);
}
.li-section.rr-procband { padding-top: clamp(2rem, 4vw, 3rem); padding-bottom: clamp(2rem, 4vw, 3rem); }
.rr-procband .rr-flow { margin-top: 0; }
.rr-procband .rr-flow__step:not(:last-child)::after {
  background: repeating-linear-gradient(90deg, var(--li-lavender-deep) 0 7px, transparent 7px 15px);
  background-size: 15px 3px;
  opacity: .55;
}
.rr-flow__badge { width: 5.6rem; height: 4.8rem; }
.rr-flow__icon .li-dood { --li-dood-size: 4.8rem; width: 5.6rem; }
@media (max-width: 720px) {
  .rr-procband .rr-flow__step:not(:last-child)::after {
    background: repeating-linear-gradient(180deg, var(--li-lavender-deep) 0 7px, transparent 7px 15px);
    background-size: 3px 15px;
  }
}

/* --- Item 6 · interior page titles hidden under the header ----
   ROOT FIX, every interior page at once. `.li-head` is position:fixed, and the
   hero patterns pay for that themselves with
   `padding-top: calc(var(--li-head-h) + …)`. The flat `.rr-pagehead` head never
   did, and once the heroes were switched off on the inner pages there was
   nothing left absorbing the offset, so the H1 sat behind the nav. This gives
   the flat head the same compensation the heroes already have, which covers
   Current ARCs, Past ARCs, Calendar, Book Club, About, Contact and the FAQ from
   one rule. The admin-bar variant matters because Meg browses logged in. */
.rr-pagehead,
.li-section.rr-pagehead { padding-top: calc(var(--li-head-h) + clamp(1.6rem, 3.5vw, 2.6rem)); }
body.admin-bar .rr-pagehead,
body.admin-bar .li-section.rr-pagehead {
  padding-top: calc(var(--li-head-h) + var(--wp-admin--admin-bar--height, 32px) + clamp(1.6rem, 3.5vw, 2.6rem));
}

/* --- Item 4 · the Current ARCs page head ------------------
   The title and lede were centred, low-contrast and floating with nothing to
   hold them. They now sit in a 60:40 split against a doodle, left-aligned, at
   full ink contrast. `.rr-pagehead--split` opts a page in; every other page
   keeps the centred head. */
/* `.li-section.rr-pagehead` is (0,2,0) and sets text-align:center, so the split
   variant has to match that weight or the copy stays centred. */
.rr-pagehead--split, .li-section.rr-pagehead--split { text-align: left; }
.li-section.rr-pagehead--split .li-lede { margin-left: 0; margin-right: 0; }
.rr-pagehead--split .rr-headsplit {
  display: flex; align-items: center; gap: clamp(1.5rem, 4vw, 3.5rem);
}
.rr-pagehead--split .rr-headsplit__copy { flex: 0 1 60%; min-width: 0; }
.rr-pagehead--split .rr-headsplit__art  { flex: 0 1 40%; display: grid; place-items: center; }
.rr-pagehead--split .rr-headsplit__art .li-dood {
  --li-dood-size: clamp(7rem, 16vw, 12rem); width: clamp(8rem, 20vw, 15rem);
}
.rr-pagehead--split h1 { margin: 0; }
.rr-pagehead--split .li-lede {
  margin: 1rem 0 0; max-width: 46ch; color: var(--li-ink); opacity: 1;
  font-size: clamp(1.02rem, .95rem + .4vw, 1.18rem);
}
.rr-pagehead--split .li-note { margin: .9rem 0 0; }
@media (max-width: 860px) {
  .rr-pagehead--split .rr-headsplit { flex-direction: column-reverse; align-items: flex-start; gap: 1.2rem; }
  .rr-pagehead--split .rr-headsplit__copy,
  .rr-pagehead--split .rr-headsplit__art { flex: none; width: 100%; }
  .rr-pagehead--split .rr-headsplit__art { place-items: start; }
}

/* --- Item 2 · the "cover coming" plate on a shelf card -----
   Two defects, both only visible on the rendered page. Core's image block
   renders to NOTHING when the figure holds no <img>, so every generated plate
   silently vanished and left a short, top-aligned card in a row of full-height
   ones (the generator now emits wp:html instead). And `.rr-team .wp-block-image`
   out-specifies `.rr-nocover`'s own `margin: 0`, so the plate needs the same
   bleed-to-the-border treatment a real cover gets, or it sits inset while its
   neighbours are flush. */
.rr-team .rr-nocover, .rr-past .rr-nocover, .rr-perm .rr-nocover {
  width: auto;                      /* NOT 100%: with the negative side margins
                                       a 100% width leaves a 2-pad gap on the
                                       right, which made the plate narrower than
                                       its neighbours' covers and, through the
                                       2/3 aspect ratio, shorter as well. */
  border: 0; border-bottom: 2px solid var(--li-ink);
  border-radius: calc(var(--li-radius) - 2px) calc(var(--li-radius) - 2px) 0 0;
}
/* On a team card the title is already the h3 underneath, so the plate does not
   repeat it. The plate on an author-page shelf still carries its own title. */
.rr-team .rr-nocover .rr-nocover__t { display: none; }
.rr-team .rr-nocover .rr-nocover__mark { font-size: 2.4rem; }

/* --- Item 7 · the Contact page, matched to the LI contact page ----
   It was a flat stack of headings and paragraphs. The LI page is a 56:44 split
   with the ask on the left and a coloured card on the right, so this is the
   same shape in the Reading Room's palette. The card sticks while the left
   column scrolls, which is what the LI page does on a tall viewport. */
.rr-contact__card { position: sticky; top: calc(var(--li-head-h) + 1.4rem); }
.rr-contact__card h3 { font-size: 1.35rem; }
.rr-contact__card h3 + p { margin-top: .4rem; }
.rr-contact__rule {
  border: 0; border-top: 2px solid var(--li-ink); opacity: .28;
  margin: 1.4rem 0; width: 100%;
}
.rr-contact__cols .wp-block-column > h3 { margin-top: 1.6rem; }
.rr-contact__cols .wp-block-column > h3 + p { margin-top: .35rem; }
@media (max-width: 781px) { .rr-contact__card { position: static; } }

/* --- RR-Final-01b · 2026-08-27 · the Fluent Forms skin ------
   Meg installed Fluent Forms on the Reading Room and the contact form
   (form 1) rendered in the plugin's factory theme: -apple-system at 13.3px,
   hairline grey borders and a bright blue submit button, on a page built in
   Fraunces and Hanken. This is the LI theme's skin (style.css "P1·1 + P1·2")
   ported across, which is the whole point of the two sites sharing a design
   system. 16px on the controls is deliberate: iOS Safari zooms the viewport
   on focus for anything smaller.
   LiteSpeed UCSS strips the plugin's own stylesheet on this page, so the
   layout rules Fluent Forms would normally supply (the name-field row) are
   restated here rather than assumed. */
.fluentform, .fluentform * { font-family: var(--li-sans); }
.fluentform { margin: 0; }
.fluentform .ff-el-group { margin-bottom: 1.2rem; }
.fluentform .ff-el-group:last-child { margin-bottom: 0; }
.fluentform .ff-el-input--label label,
.fluentform .ff-el-input--label.ff-el-is-required label {
  display: block;
  font-family: var(--li-sans); font-weight: 650; font-size: .92rem;
  color: var(--li-forest); letter-spacing: .005em; margin-bottom: .45rem;
}
.fluentform .ff-el-input--label.ff-el-is-required label::after { color: var(--li-lavender-deep); font-weight: 800; }
.fluentform .ff-el-help-message { font-size: .82rem; color: rgba(30,32,25,.7); margin-top: .35rem; }

/* The name row. Fluent Forms lays first/last out with .ff-t-container and
   .ff-t-cell, and UCSS drops those rules, so the two fields stack full width
   and the form reads twice as long as it is. */
.fluentform .ff-t-container { display: flex; gap: 1rem; }
.fluentform .ff-t-cell { flex: 1 1 0; min-width: 0; }
@media (max-width: 520px) { .fluentform .ff-t-container { flex-direction: column; gap: 0; } }

.fluentform .ff-el-form-control,
.fluentform select.ff-el-form-control,
.fluentform textarea.ff-el-form-control {
  width: 100%; box-sizing: border-box;
  font-family: var(--li-sans); font-size: 16px; font-weight: 450; line-height: 1.45;
  color: var(--li-ink); background: var(--li-paper);
  border: 2px solid var(--li-forest); border-radius: 14px;
  padding: .78rem .95rem;
  box-shadow: none; transition: border-color .18s ease, box-shadow .18s ease;
}
.fluentform .ff-el-form-control::placeholder { color: rgba(30,32,25,.48); }
.fluentform textarea.ff-el-form-control { min-height: 150px; resize: vertical; }
.fluentform .ff-el-form-control:focus,
.fluentform .ff-el-form-control:focus-visible {
  outline: 3px solid var(--li-lavender-deep); outline-offset: 2px;
  border-color: var(--li-forest); box-shadow: 3px 3px 0 rgba(30,32,25,.14);
}
.fluentform .ff-el-form-check input[type="checkbox"]:focus-visible,
.fluentform .ff-el-form-check input[type="radio"]:focus-visible,
.fluentform input[type="file"]:focus-visible {
  outline: 3px solid var(--li-lavender-deep); outline-offset: 2px;
}
.fluentform .ff-el-form-check label { font-size: .95rem; color: var(--li-ink); }
.fluentform .ff-el-form-check { margin-bottom: .5rem; }
.fluentform .ff-el-is-error .ff-el-form-control { border-color: #a8321f; }
.fluentform .error-text, .fluentform .text-danger { font-size: .84rem; color: #8d2718; font-weight: 600; }
.fluentform .ff_screen_reader_title { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* The submit button joins the sitewide button contract. */
.fluentform .ff-btn-submit,
.fluentform .ff-btn.ff-btn-submit,
.fluentform button[type="submit"] {
  font-family: var(--li-sans); font-weight: 700;
  font-size: .95rem; letter-spacing: .03em; text-transform: uppercase;
  color: var(--li-forest-deep) !important; background: var(--li-chartreuse) !important;
  border: 2px solid var(--li-forest) !important; border-radius: 999px;
  padding: .95rem 2.1rem; min-height: 48px; width: auto;
  box-shadow: 4px 4px 0 rgba(30,32,25,.22);
  transition: transform .18s var(--li-pop), box-shadow .18s ease, background .18s ease;
  cursor: pointer;
}
.fluentform .ff-btn-submit:hover, .fluentform button[type="submit"]:hover {
  background: var(--li-chartreuse-soft) !important;
  transform: translate(-2px,-2px); box-shadow: 6px 6px 0 rgba(30,32,25,.26);
}
.fluentform .ff-btn-submit:focus-visible, .fluentform button[type="submit"]:focus-visible {
  outline: 3px solid var(--li-lavender-deep); outline-offset: 3px;
}
.fluentform .ff-el-section-title, .fluentform .ff_section_break h3 {
  font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1;
  font-weight: 560; font-size: 1.3rem; color: var(--li-forest); margin: 2rem 0 .3rem;
}
.fluentform .ff-section-break-desc { font-size: .95rem; opacity: .82; }
.has-forest-background-color .fluentform .ff-el-input--label label,
.has-forest-deep-background-color .fluentform .ff-el-input--label label { color: var(--li-cream); }

/* The card the form sits in. Written out rather than leaning on `.li-card`,
   because UCSS has been seen dropping `.li-card` on this page. */
.rr-contact__form {
  background: var(--li-paper); border: 2px solid var(--li-ink);
  border-radius: var(--li-radius); padding: 1.6rem 1.5rem 1.8rem;
  margin-top: 2rem;
}
.rr-contact__form > h3 { font-size: 1.5rem; line-height: 1.1; margin: 0 0 1.1rem; }
.li-fineprint { font-size: .85rem; opacity: .72; margin-top: .8rem; }

/* ==========================================================================
   RR-Final-02 · 2026-08-27 · calendar paging, page rebuilds, pagination
   --------------------------------------------------------------------------
   Everything in this block is appended deliberately: several of the rules it
   overrides live behind a doubled `.li-section.x` selector (0,2,0), which no
   single-class rule can beat no matter how late it loads. That trap cost time
   twice in RR-Final-01, so every override here carries the doubled selector
   too.
   ========================================================================== */

/* --- 1 · ARC calendar: CSS paging ---------------------------------------
   The month is chosen by a radio group whose reveal rules ship inside the
   markup (see rr_month_calendar_markup). These are the parts that are the
   same for every calendar and can live in the stylesheet. */
.rr-cal--css .rr-cal__radio {
  /* Hidden, but still focusable and still a real radio group, so the months
     remain reachable by keyboard with arrow keys. */
  position: absolute; width: 1px; height: 1px; margin: 0;
  opacity: 0; pointer-events: none;
}
.rr-cal--css .rr-cal__months > .rr-monthcal { display: none; }
.rr-cal--css .rr-monthcal { margin-bottom: 0; }
/* The month name IS the pager label here, so it is not hidden the way the old
   JS pager hid it. */
.rr-cal--css .rr-monthcal__name {
  display: block; border-bottom: 0; padding-bottom: 0;
  margin: 0 !important; text-align: center; color: var(--li-cream);
  font-size: clamp(1.3rem, 3vw, 1.7rem); line-height: 1.1;
}
.rr-cal--css .rr-cal__nav {
  margin: 0 0 1.1rem; gap: clamp(.6rem, 2vw, 1.2rem);
  padding-bottom: .9rem; border-bottom: 2px solid rgba(245,239,223,.22);
}
.rr-cal--css .rr-cal__label { min-width: 0; flex: 1 1 auto; }
.rr-cal--css .rr-cal__arrow {
  display: inline-flex; align-items: center; justify-content: center;
  flex: 0 0 auto; padding: 0; text-decoration: none; user-select: none;
}
.rr-cal--css .rr-cal__arrow--off { opacity: .3; cursor: default; box-shadow: none; }
.rr-cal--css .rr-cal__arrow:not(.rr-cal__arrow--off):hover {
  transform: translate(-1px,-1px); box-shadow: 5px 6px 0 rgba(30,32,25,.2);
}
/* A cover is a sticker stuck ONTO the grid, so it is allowed to sit proud of
   its day cell and to lift above its neighbours when it is being read. */
.rr-monthcal__grid, .rr-monthcal__day { overflow: visible; }
.rr-monthcal__evt { position: relative; }
.rr-monthcal__evt[open], .rr-monthcal__evt:hover { z-index: 6; }
.rr-monthcal__evt summary:hover .rr-monthcal__sticker { transform: rotate(0deg) scale(1.06); }
.rr-monthcal__sticker { transition: transform .25s var(--li-pop); }

/* --- 2 · rr-read: a readable measure ------------------------------------
   Body copy on the interior pages ran the full 1150px column, which is around
   150 characters a line. The column stays wide (the cards and splits need it);
   the prose inside it does not. */
.rr-read p, .rr-read li { max-width: 66ch; }
.rr-read .li-lede { max-width: 54ch; }
.rr-read .li-card p, .rr-read .li-mcard p, .rr-read .wp-block-column p { max-width: none; }

/* --- 3 · rr-split: the 50:50 and 60:40 section splits --------------------
   Core columns do the layout and the responsive stack; this is the vertical
   alignment, the gap, and the art column's behaviour. */
.rr-split.wp-block-columns { gap: clamp(1.6rem, 4vw, 3.2rem); align-items: center; }
.rr-split--top.wp-block-columns { align-items: flex-start; }
.rr-split__art { display: flex; align-items: center; justify-content: center; }
.rr-split__art .li-dood { --li-dood-size: clamp(6rem, 13vw, 10.5rem); }
.rr-split__art .li-doodrow { flex-wrap: wrap; justify-content: center; gap: 1.4rem; }
.rr-split__art .li-doodrow .li-dood { --li-dood-size: clamp(3.2rem, 6vw, 4.6rem); }
@media (max-width: 781px) {
  .rr-split__art { margin-bottom: .4rem; }
  .rr-split__art .li-dood { --li-dood-size: clamp(5rem, 22vw, 7rem); }
}

/* --- 4 · card doodle marks + equal heights ------------------------------- */
.rr-cardmark { --li-dood-size: 2.5rem; display: block; margin: 0 0 .85rem; }
.li-card--chartreuse .rr-cardmark, .li-card--lilac .rr-cardmark { background: var(--li-ink); }
/* Grid children stretch by default; this states it, because a card that grows
   its own height (a hover transform, a nested flex) silently opts out. */
.li-grid > .li-card, .li-grid > .wp-block-group.li-card { height: 100%; box-sizing: border-box; }
.li-card { display: flex; flex-direction: column; }
.li-card > :last-child { margin-bottom: 0; }

/* --- 5 · section eyebrows ------------------------------------------------
   The Reading Room hides the LI chapter chip site-wide (reader-first, 08-24),
   which left every interior section opening on a bare h2 with nothing to
   locate it. This is the reader-facing replacement: a handwritten line, not a
   numbered chip. */
.rr-eyebrow {
  font-family: var(--li-hand); font-size: 1.2rem; line-height: 1;
  color: var(--li-lavender-deep); margin: 0 0 .5rem !important;
}
.has-forest-background-color .rr-eyebrow,
.has-forest-deep-background-color .rr-eyebrow { color: var(--li-chartreuse); }

/* --- 6 · query pagination, site-wide ------------------------------------
   Core ships the pager as bare links: "1 2 3 Next Page" in body type with no
   styling at all. This is the same pill vocabulary as the filter row above it,
   so the foot of an archive matches its head. */
.wp-block-query-pagination {
  gap: .5rem; margin-top: clamp(2rem, 4vw, 3rem); align-items: center; flex-wrap: wrap;
}
.wp-block-query-pagination .page-numbers,
.wp-block-query-pagination .wp-block-query-pagination-previous,
.wp-block-query-pagination .wp-block-query-pagination-next {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 2.6rem; padding: .5rem .95rem;
  font-family: var(--li-sans); font-size: .85rem; font-weight: 700;
  letter-spacing: .02em; text-decoration: none; color: var(--li-ink);
  background: var(--li-paper); border: 2px solid var(--li-ink); border-radius: 999px;
  transition: transform .2s var(--li-pop), box-shadow .2s ease, background .2s ease;
}
.wp-block-query-pagination a.page-numbers:hover,
.wp-block-query-pagination .wp-block-query-pagination-previous:hover,
.wp-block-query-pagination .wp-block-query-pagination-next:hover {
  transform: translate(-1px,-1px); box-shadow: 4px 5px 0 rgba(30,32,25,.2);
  background: var(--li-cream-deep);
}
.wp-block-query-pagination .page-numbers.current {
  background: var(--li-chartreuse); box-shadow: 3px 4px 0 rgba(30,32,25,.2);
}
.wp-block-query-pagination .page-numbers.dots {
  border-color: transparent; background: none; box-shadow: none; min-width: 1.4rem; padding: .5rem .2rem;
}
.wp-block-query-pagination-numbers { display: inline-flex; gap: .5rem; flex-wrap: wrap; }

/* --- 7 · Book Club title cards: keep them on the page --------------------
   The doodle watermark is a CSS mask fed by --li-tc-dood, and the colour cycle
   is nth-child. LiteSpeed's UCSS pass drops both (it cannot see a custom
   property being consumed), which is why the same rules are ALSO inlined into
   the Book Club page content. Keeping the stylesheet copy means the archive
   templates, which are not page content, still get them after a purge. */
.li-postcard--tc .li-titlecard { min-height: 190px; }
.li-postcard--tc .wp-block-post-excerpt { margin-top: 0; }

/* --- 8 · FAQ tiers ------------------------------------------------------- */
.li-faq-section.li-section { padding-top: clamp(2.6rem, 5vw, 4rem); padding-bottom: clamp(2.6rem, 5vw, 4rem); }
.rr-faqhead { display: flex; align-items: center; gap: 1.1rem; margin-bottom: 1.4rem; }
.rr-faqhead .li-dood { --li-dood-size: 3rem; flex: 0 0 auto; }
.rr-faqhead h2 { margin: 0 !important; max-width: 24ch; }

/* --- 1b · calendar contrast + the dead arrow ----------------------------
   The note tab inherited cream from the forest month card, so every tab
   painted cream-on-butter and cream-on-lilac. It was legible on screen at
   full size and nowhere near legible on a phone. The tab grounds are all
   light, so the label is ink, stated once.
   The disabled arrow was paper at .28 opacity on forest, which reads as a
   dark smudge rather than as "there is no earlier month". It is an outline
   now, with no fill to dim. */
.rr-monthcal__note, .rr-cal--css .rr-monthcal__note { color: var(--li-ink); }
.rr-cal--css .rr-cal__arrow--off {
  opacity: 1; background: none; color: rgba(245,239,223,.32);
  border-color: rgba(245,239,223,.28); box-shadow: none; cursor: default;
}
.rr-faqhead__copy { min-width: 0; flex: 1 1 auto; }
.rr-faqhead .rr-eyebrow { margin-bottom: .2rem !important; }
.rr-pagehead--split .rr-headsplit__copy .rr-faq-search-wrap { margin-top: 1.4rem; }
@media (max-width: 640px) {
  .rr-faqhead { gap: .8rem; }
  .rr-faqhead .li-dood { --li-dood-size: 2.2rem; }
}
/* The split head carries a search box on the FAQ, so it needs more room under
   it than a head that ends on a lede. */
.rr-pagehead--split.li-section, .li-section.rr-pagehead--split { padding-bottom: clamp(2rem, 4vw, 3rem); }

/* --- 7b · Book Club title cards: count the RIGHT element ------------------
   Found on the live page RR-Final-02, and it had been wrong since the variety
   pass was written on 2026-08-24. WordPress's post-template wraps every post in
   its own `<li class="wp-block-post">`; the card is INSIDE that li, so it is
   always the only child of its parent and every `:nth-child` on the card
   evaluates to 1. The result was nine identical forest blocks, one doodle motif
   repeated nine times, every card tilted the same way, and the butter tape
   strip on all of them, which is the wall of sameness the variety pass existed
   to break. The counting has to happen on the li. */
.wp-block-post:nth-child(3n+1) .li-titlecard { background: var(--li-forest); }
.wp-block-post:nth-child(3n+2) .li-titlecard { background: var(--li-lavender-deep); }
.wp-block-post:nth-child(3n)   .li-titlecard { background: var(--li-forest-deep); }
.wp-block-post:nth-child(3n+1) .li-titlecard::after { --li-dood-tint: var(--li-chartreuse); }
.wp-block-post:nth-child(3n+2) .li-titlecard::after { --li-dood-tint: var(--li-chartreuse-soft); }
.wp-block-post:nth-child(3n)   .li-titlecard::after { --li-dood-tint: var(--li-lavender); }
.wp-block-post:nth-child(6n+1) .li-titlecard { --li-tc-dood: url(assets/img/doodles/book.png); }
.wp-block-post:nth-child(6n+2) .li-titlecard { --li-tc-dood: url(assets/img/doodles/pencil.png); }
.wp-block-post:nth-child(6n+3) .li-titlecard { --li-tc-dood: url(assets/img/doodles/star.png); }
.wp-block-post:nth-child(6n+4) .li-titlecard { --li-tc-dood: url(assets/img/doodles/megaphone.png); }
.wp-block-post:nth-child(6n+5) .li-titlecard { --li-tc-dood: url(assets/img/doodles/book-open.png); }
.wp-block-post:nth-child(6n)   .li-titlecard { --li-tc-dood: url(assets/img/doodles/mug.png); }
.wp-block-post:nth-child(odd)  .li-postcard--tc { transform: rotate(-1.5deg); }
.wp-block-post:nth-child(even) .li-postcard--tc { transform: rotate(1.5deg); }
.li-postcard--tc:hover, .wp-block-post .li-postcard--tc:hover { transform: rotate(0) translateY(-4px); }
/* The tape's geometry stays in the original rule; this only decides which cards
   wear one. Hiding then re-showing keeps that rule as the single definition. */
.li-postcard--tc:nth-child(4n+1)::before,
.li-postcard--tc:nth-child(6n+4)::before { display: none; }
.wp-block-post:nth-child(4n+1) .li-postcard--tc::before,
.wp-block-post:nth-child(6n+4) .li-postcard--tc::before { display: block; }

/* ==========================================================================
   RR-Final-03 · 2026-08-27 · Meg's round-2 notes on the uploaded 0.33.0
   ========================================================================== */

/* --- 1 · the home strip is the LOGO lavender, not the pale lilac ----------
   Meg: "is this the correct lilac? it looks different to the button and the
   Reading Room logo." It was. `--li-lilac` (#ddd4f1) is the pale band tint;
   the nav button and the logo mark are `--li-lavender` (#b2a1e0). The strip
   now uses the same token they do, so the three read as one colour. */
.li-marquee--lavender { background: var(--li-lavender); color: var(--li-ink); }
.li-marquee--lavender .li-mqsep { color: var(--li-ink); opacity: .38; }

/* --- 2 · section heads: the lede sits BESIDE the heading ------------------
   Meg, repeatedly: the paragraph under a section heading is left-aligned and
   "stops mid-point", which reads as a wrapping accident rather than a layout.
   It is not fixable by widening the lede: 880px of body copy is over 100
   characters a line. So the two sit side by side instead, heading left, lede
   right, tops aligned.

   Done with :has() on the section rather than a wrapper, so it reaches every
   page at once including the ones this session did not re-push. Only a lede
   that IMMEDIATELY follows the heading is moved; every other child still spans
   the full width, so nothing else in the section shifts. */
.li-section:has(> h2 + .li-lede):not(.rr-pagehead):not(.rr-insider):not(.li-cta) {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, .78fr);
  column-gap: clamp(1.8rem, 4vw, 3.4rem);
  align-items: start;
}
.li-section:has(> h2 + .li-lede):not(.rr-pagehead):not(.rr-insider):not(.li-cta) > * {
  grid-column: 1 / -1;
}
.li-section:has(> h2 + .li-lede):not(.rr-pagehead):not(.rr-insider):not(.li-cta) > h2 {
  grid-column: 1; grid-row: 1; margin-bottom: 0;
}
.li-section:has(> h2 + .li-lede):not(.rr-pagehead):not(.rr-insider):not(.li-cta) > h2 + .li-lede {
  grid-column: 2; grid-row: 1; max-width: none; margin-top: .5rem;
}
/* Under 860px the two stack, and the lede goes back to a reading measure. */
@media (max-width: 860px) {
  .li-section:has(> h2 + .li-lede):not(.rr-pagehead):not(.rr-insider):not(.li-cta) {
    display: block;
  }
  .li-section:has(> h2 + .li-lede) > h2 + .li-lede { max-width: 52ch; margin-top: .9rem; }
}

/* --- 3 · the process strip: lavender band, white doodles, ink writing -----
   Meg: the dotted connector shows through the doodles, the faded green is the
   wrong call, and the band should be the bolder purple with white doodles and
   black writing. Lavender (#b2a1e0) is the bolder purple that still carries
   ink text at full contrast; lavender-deep would force the writing to cream
   and lose her "writing in black".

   Both of her connector options are taken, because they solve different halves
   of it: each doodle now sits on a solid forest disc, so the dots cannot show
   through it, AND the connector is inset so it starts and stops clear of the
   discs rather than running under them. */
.li-section.rr-procband, .rr-procband {
  background: var(--li-lavender);
  border-top: 2px solid var(--li-ink); border-bottom: 2px solid var(--li-ink);
}
.rr-procband .rr-flow__badge {
  width: 4.6rem; height: 4.6rem; border-radius: 999px;
  background: var(--li-forest); border: 2px solid var(--li-ink);
  box-shadow: 3px 4px 0 rgba(30, 32, 25, .18);
  z-index: 2;
}
.rr-procband .rr-flow__icon .li-dood,
.rr-procband .li-dood { --li-dood-size: 2.9rem; width: 2.9rem; background: var(--li-cream); }
.rr-procband .rr-flow__step:not(:last-child)::after {
  /* Inset so the dashes begin and end clear of the discs. */
  top: 2.15rem; left: calc(50% + 2.9rem); width: calc(100% - 5.8rem);
  background: repeating-linear-gradient(90deg, var(--li-cream) 0 7px, transparent 7px 15px);
  background-size: 15px 3px; opacity: .9; z-index: 0;
}
.rr-procband .rr-flow__label, .rr-procband .rr-flow__step h3 { color: var(--li-ink); }
.rr-procband .rr-flow__sub { color: var(--li-ink); opacity: .78; }
@media (max-width: 720px) {
  .rr-procband .rr-flow__step:not(:last-child)::after {
    top: calc(2.15rem + 2.9rem); left: 50%; width: 3px; height: calc(100% - 5.8rem);
    background: repeating-linear-gradient(180deg, var(--li-cream) 0 7px, transparent 7px 15px);
    background-size: 3px 15px;
  }
}

/* --- 4 · seamless doodle backgrounds -------------------------------------
   Meg's Creative Fabrica "Book Writing Doodle Seamless Patterns", tiled behind
   a band at low opacity so a plain section has something in it. One PNG per
   pattern, used as a CSS mask so a single file paints in any palette colour.
   The tile is 440px from a 3600px seamless original, so it still tiles true.

   It is a ::before, not a background on the section itself, because the
   sections already carry their own background colour and several carry ink
   rails. Decoration only: it never sits above content. */
.li-pattern { position: relative; isolation: isolate; }
.li-pattern > * { position: relative; z-index: 1; }
.li-pattern::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: var(--li-ink); opacity: .07;
  -webkit-mask: var(--li-pattern-img) repeat 0 0 / 440px 440px;
          mask: var(--li-pattern-img) repeat 0 0 / 440px 440px;
}
.li-pattern--books { --li-pattern-img: url(assets/img/patterns/pattern-books.png); }
.li-pattern--pens  { --li-pattern-img: url(assets/img/patterns/pattern-pens.png); }
.li-pattern--desk  { --li-pattern-img: url(assets/img/patterns/pattern-desk.png); }
/* On a dark band the pattern paints in cream instead, and a touch stronger. */
.li-pattern.has-forest-background-color::before,
.li-pattern.has-forest-deep-background-color::before,
.li-pattern.has-lavender-deep-background-color::before {
  background: var(--li-cream); opacity: .09;
}
@media (prefers-reduced-motion: no-preference) {
  /* Nothing animates. The pattern is static on purpose: a moving background
     behind body copy is a readability problem, not a flourish. */
}

/* --- 5 · reaction and speech-bubble doodles ------------------------------
   Meg's "Reaction Speech Bubbles Doodles" bundle, imported as masks so they
   behave exactly like the rest of the doodle layer. Named for what they say. */
.li-dood--bubble-stars    { -webkit-mask-image: url(assets/img/doodles/bubble-stars.png);    mask-image: url(assets/img/doodles/bubble-stars.png); }
.li-dood--bubble-grawlix  { -webkit-mask-image: url(assets/img/doodles/bubble-grawlix.png);  mask-image: url(assets/img/doodles/bubble-grawlix.png); }
.li-dood--bubble-thumb    { -webkit-mask-image: url(assets/img/doodles/bubble-thumb.png);    mask-image: url(assets/img/doodles/bubble-thumb.png); }
.li-dood--bubble-loveit   { -webkit-mask-image: url(assets/img/doodles/bubble-loveit.png);   mask-image: url(assets/img/doodles/bubble-loveit.png); }
.li-dood--bubble-dots     { -webkit-mask-image: url(assets/img/doodles/bubble-dots.png);     mask-image: url(assets/img/doodles/bubble-dots.png); }
.li-dood--bubble-question { -webkit-mask-image: url(assets/img/doodles/bubble-question.png); mask-image: url(assets/img/doodles/bubble-question.png); }
.li-dood--bubble-idea     { -webkit-mask-image: url(assets/img/doodles/bubble-idea.png);     mask-image: url(assets/img/doodles/bubble-idea.png); }
.li-dood--bubble-sad      { -webkit-mask-image: url(assets/img/doodles/bubble-sad.png);      mask-image: url(assets/img/doodles/bubble-sad.png); }
/* The bubbles are wider than they are tall, or much taller than they are wide,
   so they need a box that is not square or contain shrinks them to a sliver.
   Same lesson as the process-strip doodles in RR-Final-01. */
.rr-headsplit__art .li-dood[class*="bubble-"],
.rr-faqhead .li-dood[class*="bubble-"] { width: auto; aspect-ratio: auto; }
.rr-headsplit__art .li-dood[class*="bubble-"] {
  width: clamp(9rem, 22vw, 17rem); height: clamp(7rem, 16vw, 12rem);
  --li-dood-size: auto;
}
.rr-faqhead .li-dood[class*="bubble-"] { width: 4.2rem; height: 3.2rem; --li-dood-size: auto; }

/* --- 6 · Past ARCs cards match Current ARCs cards -------------------------
   Meg: "the sizing is entirely different to the Current ARCs card."
   Measured: Current ARCs 233px wide with a 229x343 cover, Past ARCs 247px with
   a 243x365 cover. Same 5 columns, same flex-basis, different SHELF width.
   The Current ARCs shelf is a wp:group inside the constrained 1240px layout,
   so it inherits the layout's max-width. The Past ARCs shelf is generated as
   raw HTML, so it escapes that rule and stretches to the section padding box
   at 1312px. Capping the shelf itself fixes it wherever the shelf appears. */
.rr-shelf { max-width: 1240px; margin-inline: auto; }

/* --- 4b · where the pattern lands, decided by rule ------------------------
   Meg asked for consistency across pages, so the pattern is attached to what a
   section CONTAINS rather than hand-tagged page by page. A shelf of books gets
   the book pattern on every page that has one; an FAQ tier gets the desk
   pattern. Add a class only when a one-off section needs a pattern the rules
   would not give it. */
.li-section:has(> .rr-shelf),
.li-section:has(.rr-data--current-arcs),
.li-section:has(.rr-data--past-arcs) {
  position: relative; isolation: isolate;
}
.li-section:has(> .rr-shelf) > *,
.li-section:has(.rr-data--current-arcs) > *,
.li-section:has(.rr-data--past-arcs) > * { position: relative; z-index: 1; }
.li-section:has(> .rr-shelf)::before,
.li-section:has(.rr-data--current-arcs)::before,
.li-section:has(.rr-data--past-arcs)::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: var(--li-ink); opacity: .07;
  -webkit-mask: url(assets/img/patterns/pattern-books.png) repeat 0 0 / 440px 440px;
          mask: url(assets/img/patterns/pattern-books.png) repeat 0 0 / 440px 440px;
}
.li-faq-section { position: relative; isolation: isolate; }
.li-faq-section > * { position: relative; z-index: 1; }
.li-faq-section::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: var(--li-ink); opacity: .06;
  -webkit-mask: url(assets/img/patterns/pattern-desk.png) repeat 0 0 / 440px 440px;
          mask: url(assets/img/patterns/pattern-desk.png) repeat 0 0 / 440px 440px;
}

/* --- 7 · the contact head, matched to the LI page's slim forest hero ------
   The LI contact page opens on `li-pagehero--slim`: a forest band carrying the
   H1 and lede. RR had a plain cream `rr-pagehead`, which is why the page read
   as a different template no matter how well the split below it matched. This
   is the same shape inside RR's own page-head system, so the header offset and
   the admin-bar variant keep working. */
.rr-pagehead--hero, .li-section.rr-pagehead--hero {
  color: var(--li-cream);
  padding-bottom: clamp(2.4rem, 5vw, 3.6rem);
  border-bottom: 2px solid var(--li-ink);
}
.rr-pagehead--hero .wp-block-heading, .li-section.rr-pagehead--hero h1 { color: var(--li-cream); }
.rr-pagehead--hero h1 em { color: var(--li-chartreuse); }
.rr-pagehead--hero .li-lede {
  color: var(--li-cream); opacity: .88; max-width: 56ch;
  margin-left: auto; margin-right: auto;
}


/* ===== RR-Final-06 · 2026-08-28 · full-site audit pass =====
   Mirrors the block appended to the theme's style.css. Absolute asset paths,
   because this is served inline from the page head where a theme-relative
   url() would resolve against the page. */

/* ---------------------------------------------------------------------------
   1 · The big-type band was UNREADABLE on every dark section.
   Measured on the contact page: the line painted ink (#1e2019) on forest
   (#1d3527), a contrast ratio of 1.06:1. The em was already handled, the LINE
   itself never was, so the first half of every statement simply vanished.
   --------------------------------------------------------------------------- */
.has-forest-background-color .li-bigtype__line,
.has-forest-deep-background-color .li-bigtype__line,
.has-forest-background-color.li-bigtype .li-bigtype__line,
.has-forest-deep-background-color.li-bigtype .li-bigtype__line,
.has-lavender-deep-background-color.li-bigtype .li-bigtype__line { color: var(--li-cream); }

/* ---------------------------------------------------------------------------
   2 · Section heads: heading left, lede right, and the lede DROPPED so its
   first line sits against the heading's optical middle instead of its cap
   height. Meg, 2026-08-27: "the paragraph text needs to be adjusted slightly,
   to be just a bit lower." A heading at clamp(2.2–3.2rem) and a lede at
   ~1.1rem do not share a baseline, so the lede is nudged by a fraction of the
   heading's own line box rather than a fixed pixel value: it stays right at
   every width.
   --------------------------------------------------------------------------- */
.li-section:has(> h2 + .li-lede):not(.rr-pagehead):not(.rr-insider):not(.li-cta) > h2 + .li-lede {
  margin-top: 2.1rem;
}

/* Page heads get the same treatment. Past ARCs, the Book Club and the contact
   hero were all a centred H1 over a short ragged centred paragraph with a dead
   half-band beside it, which is the exact shape Meg flagged on the homepage and
   then again on three more pages. One rule, every flat page head. */
.li-section.rr-pagehead:has(> h1 + .li-lede):not(.rr-pagehead--split) {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, .78fr);
  column-gap: clamp(1.8rem, 4vw, 3.4rem);
  align-items: start;
  text-align: left;
}
.li-section.rr-pagehead:has(> h1 + .li-lede):not(.rr-pagehead--split) > * { grid-column: 1 / -1; }
.li-section.rr-pagehead:has(> h1 + .li-lede):not(.rr-pagehead--split) > h1 { grid-column: 1; grid-row: 1; margin-bottom: 0; }
.li-section.rr-pagehead:has(> h1 + .li-lede):not(.rr-pagehead--split) > h1 + .li-lede {
  grid-column: 2; grid-row: 1; margin: 2.1rem 0 0; max-width: 46ch; text-align: left;
}
@media (max-width: 860px) {
  .li-section.rr-pagehead:has(> h1 + .li-lede):not(.rr-pagehead--split) { display: block; }
  .li-section.rr-pagehead:has(> h1 + .li-lede):not(.rr-pagehead--split) > h1 + .li-lede { max-width: 52ch; margin-top: .9rem; }
}

/* ---------------------------------------------------------------------------
   3 · Shelf cards, equal height, every row, every page.
   Measured on the homepage: 528 / 528 / 528 / 548 / 528, and on the just-
   released shelf 515 / 495 / 476. `align-items: stretch` was already on the
   shelf and was doing nothing, because each card carries `height: 100%` and a
   percentage height on a flex item in an auto-height container resolves before
   stretch can apply. `align-self: stretch` with `height: auto` is what actually
   equalises them. With the heights equal, the meta block takes the free space
   instead of the title reserving it, so the author, the date and the button
   line up across the row and not only the card edges.
   --------------------------------------------------------------------------- */
.rr-shelf { align-items: stretch; }
.rr-shelf > .rr-team,
.rr-shelf > .rr-past,
.rr-shelf > .rr-perm { align-self: stretch; height: auto; }
/* Reserving title lines was the old fix and it left a visible hole under every
   one-line title. With the cards genuinely equal height, the better move is to
   let the title sit tight under its cover and push the meta block and the
   button to the FOOT of the card, so the author, the date and the button land
   on one line across the row whether the title runs to one line or three. */
.rr-shelf .rr-team h3,
.rr-shelf .rr-past h3,
.rr-shelf .rr-perm h3 { min-height: 0; }
.rr-shelf .rr-team__author,
.rr-shelf .rr-past .rr-team__author,
.rr-shelf .rr-perm__series { margin-top: auto !important; padding-top: .5rem; }
.rr-shelf .rr-team__dates,
.rr-shelf .rr-perm__count { margin-top: .3rem !important; }
/* Only ONE auto margin may own the free space. The card already gave
   margin-top:auto to the button group, so with a second auto on the author the
   two shared the slack and a two-line title pushed its meta block 11px below
   its neighbours'. The author owns it; the buttons follow it. */
.rr-shelf .rr-team .wp-block-buttons,
.rr-shelf .rr-past .wp-block-buttons,
.rr-shelf .rr-perm .wp-block-buttons { margin-top: 0; }
@media (max-width: 640px) {
  .rr-shelf .rr-team__author, .rr-shelf .rr-past .rr-team__author, .rr-shelf .rr-perm__series { margin-top: 0 !important; }
}

/* ---------------------------------------------------------------------------
   4 · The ARC calendar. Meg, 2026-08-27 and again 08-28: "still so visually
   boring", rows uneven, key written in words, does not feel like a wall
   calendar.
   The first three of those are ONE fault and it is not a design gap. Measured
   on a plain live load: .rr-monthcal painted rgb(253,248,231), which is paper.
   The theme paints it FOREST. LiteSpeed's UCSS pass had stripped the whole
   month-card layer, so the green wall calendar Meg approved on 2026-08-24 was
   rendering as a flat cream box with cream text on it: the month name scored
   1.03:1 and was invisible, the weekday row lost its chartreuse, and the day
   cells lost their paper fill. Restated here, where UCSS cannot reach it.
   --------------------------------------------------------------------------- */
.rr-cal .rr-monthcal,
.rr-cal--css .rr-monthcal {
  background: var(--li-forest);
  border: 2.5px solid var(--li-ink);
  border-radius: var(--li-radius);
  color: var(--li-cream);
  box-shadow: 8px 10px 0 rgba(30, 32, 25, .16);
}
.rr-cal .rr-monthcal__weekdays { color: var(--li-chartreuse); }
.rr-cal .rr-monthcal__day { background: var(--li-cream); border-radius: 8px; }
.rr-cal .rr-monthcal__day--empty { background: none; }
.rr-cal .rr-monthcal__day--event { background: var(--li-cream-deep); }
.rr-cal .rr-monthcal__daynum { color: rgba(30, 32, 25, .86); opacity: 1; }
.rr-cal .rr-cal__label,
.rr-cal--css .rr-monthcal__name { color: var(--li-cream); }

/* Consistent row heights. Meg has asked for this twice. A CSS grid sizes each
   row to its own tallest cell, so a row holding a 42x63 cover sticker came out
   at 118px while an empty row came out at 84px: measured 84/118/84/123/84 on
   the live September grid. Every row now starts from the same floor, and only
   an OPENED event detail can push one taller. */
.rr-cal .rr-monthcal__grid { grid-auto-rows: minmax(clamp(96px, 8.6vw, 124px), auto); }
.rr-cal .rr-monthcal__day { display: flex; flex-direction: column; }

/* The wall-calendar dressing Meg asked for: the card is taped up, not printed
   on. Two strips from the existing kit, one butter and one lavender, crossing
   the top edge the way the shelf covers and the blog title-cards already do. */
.rr-cal { position: relative; }
.rr-cal::before,
.rr-cal::after {
  content: ""; position: absolute; top: -13px; width: clamp(84px, 9vw, 124px); height: 26px;
  border: 2px solid var(--li-ink); border-radius: 3px; z-index: 4; pointer-events: none;
  box-shadow: 2px 3px 0 rgba(30, 32, 25, .14);
}
.rr-cal::before { left: clamp(1.5rem, 7vw, 6rem); background: var(--li-butter); transform: rotate(-2.4deg); }
.rr-cal::after { right: clamp(1.5rem, 7vw, 6rem); background: var(--li-lavender); transform: rotate(2deg); }
@media (prefers-reduced-motion: no-preference) {
  .rr-cal::before { animation: li-bob2 7s ease-in-out infinite; }
}
/* Room for the tape to sit above the card without clipping. */
.page-id-9 .rr-calwrap { padding-top: 1.1rem; }

/* A doodle beside the month name, so the pager row reads as a header and not
   as three controls in a line. */
.rr-cal--css .rr-cal__nav { position: relative; }
.rr-cal--css .rr-cal__nav::before {
  content: ""; width: 2.1rem; height: 2.1rem; flex: 0 0 auto; align-self: center;
  background: var(--li-chartreuse);
  -webkit-mask: url(/wp-content/themes/reading-room/assets/img/doodles/calendar.png) no-repeat center / contain;
  mask: url(/wp-content/themes/reading-room/assets/img/doodles/calendar.png) no-repeat center / contain;
}

/* The key, as colour swatches rather than the words "chartreuse", "lavender"
   and "butter". Meg: "instead of having the colors writing in words, in the
   key, have a little circle of the color." */
.rr-callegend {
  list-style: none; margin: 1rem 0 0; padding: 0;
  display: flex; flex-wrap: wrap; justify-content: center; gap: .5rem clamp(1rem, 3vw, 2.2rem);
}
.rr-callegend li {
  display: inline-flex; align-items: center; gap: .5rem;
  font-family: var(--li-hand); font-size: 1.18rem; line-height: 1; color: var(--li-lavender-deep);
}
.rr-callegend li::before {
  content: ""; width: .95rem; height: .95rem; border-radius: 999px;
  border: 2px solid var(--li-ink); box-shadow: 1px 2px 0 rgba(30, 32, 25, .18);
  background: var(--li-cream-deep);
}
.rr-callegend .rr-callegend--signups::before { background: var(--li-chartreuse); }
.rr-callegend .rr-callegend--sendout::before { background: var(--li-lilac); }
.rr-callegend .rr-callegend--release::before { background: var(--li-butter); }

/* ---------------------------------------------------------------------------
   5 · The FAQ pattern was on every tier at once, which reads as noise rather
   than as texture. Meg: "maybe alternate the patterned background, so one
   section has it, the next doesn't? it looks a bit busy." Odd tiers keep it,
   even tiers are clean.
   --------------------------------------------------------------------------- */
.page-id-13 .li-faq-section:nth-of-type(even)::before { display: none; }

/* ---------------------------------------------------------------------------
   6 · Toolkit rows on the calendar page: a taped cover, the book and author,
   and the two Drive buttons, in two columns. Meg, 2026-08-28: "what about
   having them display the cover (looks like it was taped on, with the branding
   elements), the title by author and then two buttons to each drive. Maybe we
   should have two columns of them?" The old rows were a left-hugging list with
   a dead margin down the whole left side of the band.
   --------------------------------------------------------------------------- */
.rr-data--toolkits {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.1rem, 2.6vw, 1.9rem); margin-top: clamp(1.6rem, 3vw, 2.4rem);
  align-items: stretch; width: 100%; max-width: none;
}
/* WordPress gives every direct child of a group its own block-start margin,
   which in a grid does not collapse and left the first card in each row sitting
   20px above its neighbour. The grid owns the spacing here. */
.rr-data--toolkits > * { margin-block: 0 !important; max-width: none; }
@media (max-width: 860px) { .rr-data--toolkits { grid-template-columns: 1fr; } }
.rr-tkcard {
  display: grid; grid-template-columns: 96px minmax(0, 1fr); grid-template-rows: auto auto;
  gap: clamp(.5rem, 1.4vw, .8rem) clamp(.9rem, 2vw, 1.3rem); align-items: start;
  background: var(--li-paper); border: 2px solid var(--li-ink); border-radius: var(--li-radius);
  padding: 1.1rem 1.15rem 1.15rem; box-sizing: border-box; height: 100%;
  box-shadow: 4px 5px 0 rgba(30, 32, 25, .14);
  transition: transform .3s var(--li-pop), box-shadow .3s ease;
}
.rr-tkcard:hover { transform: translateY(-3px); box-shadow: 8px 10px 0 rgba(30, 32, 25, .16); }
.rr-tkcard__cover { position: relative; margin: 0; }
.rr-tkcard__cover img {
  display: block; width: 100%; height: auto; aspect-ratio: 2 / 3;
  object-fit: contain; object-position: bottom; background: var(--li-cream-deep);
  border: 2px solid var(--li-ink); border-radius: 4px;
  box-shadow: 4px 5px 0 rgba(30, 32, 25, .18); transform: rotate(-2deg);
}
/* The tape strip, same device as the shelf covers and the blog title cards. */
.rr-tkcard__cover::after {
  content: ""; position: absolute; top: -10px; left: 50%; width: 62px; height: 20px;
  transform: translateX(-50%) rotate(-4deg);
  background: var(--li-butter); border: 2px solid var(--li-ink); border-radius: 3px;
  box-shadow: 2px 2px 0 rgba(30, 32, 25, .14);
}
.rr-data--toolkits > .rr-tkcard:nth-child(even) .rr-tkcard__cover img { transform: rotate(2deg); }
.rr-data--toolkits > .rr-tkcard:nth-child(even) .rr-tkcard__cover::after { background: var(--li-lavender); transform: translateX(-50%) rotate(3.5deg); }
/* The cover spans both rows; the title block and the buttons stack in the
   second column, with the buttons pinned to the foot of the card so every card
   in the row ends on one line. */
.rr-tkcard > .rr-tkcard__cover { grid-column: 1; grid-row: 1 / -1; align-self: start; }
.rr-tkcard > .rr-tkcard__head { grid-column: 2; grid-row: 1; min-width: 0; }
.rr-tkcard > .wp-block-buttons { grid-column: 2; grid-row: 2; align-self: end; }
.rr-tkcard__title {
  font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1;
  font-weight: 560; font-size: 1.16rem; line-height: 1.12; margin: 0 !important; color: var(--li-ink);
}
.rr-tkcard__author {
  font-family: var(--li-display); font-style: italic; font-variation-settings: "SOFT" 100, "WONK" 1;
  font-weight: 460; font-size: .92rem !important; opacity: .82; margin: .25rem 0 0 !important;
}
.rr-tkcard .wp-block-buttons {
  margin: 0; padding-top: .7rem; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: .5rem; width: 100%; max-width: 30rem;
}
.rr-tkcard .wp-block-button, .rr-tkcard .wp-block-button__link { width: 100%; }
.rr-tkcard .wp-block-button__link { padding: .58rem .5rem; font-size: .78rem; line-height: 1.25; text-align: center; }
@media (max-width: 460px) { .rr-tkcard .wp-block-buttons { grid-template-columns: 1fr; } }

/* ---------------------------------------------------------------------------
   7 · Related posts under a single Book Club post, and the post's own head,
   matched to the archive cards. Three cards, the same title-card treatment the
   archive uses, so a reader who lands on a post from search sees the same shelf
   they would have seen on the way in.
   --------------------------------------------------------------------------- */
.rr-related { margin-top: clamp(2.4rem, 5vw, 3.6rem); }
.rr-related__grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 2.4vw, 1.7rem); align-items: stretch;
}
@media (max-width: 860px) { .rr-related__grid { grid-template-columns: 1fr; } }
.rr-related__grid > * { height: 100%; }

/* ---------------------------------------------------------------------------
   8 · The process strip goes chartreuse. Meg, 2026-08-28: "I think the bright
   green as the background color would look better." It is the site's lead
   accent and the forest discs with cream doodles read harder against it than
   against the lavender. Ink writing keeps its contrast (12.8:1 on chartreuse),
   and the dashed connector goes forest so it reads as a drawn line rather than
   as a gap in the band.
   --------------------------------------------------------------------------- */
.li-section.rr-procband, .rr-procband { background: var(--li-chartreuse); }
.rr-procband .rr-flow__step:not(:last-child)::after {
  background: repeating-linear-gradient(90deg, var(--li-forest) 0 7px, transparent 7px 15px);
  background-size: 15px 3px; opacity: .5;
}
@media (max-width: 720px) {
  .rr-procband .rr-flow__step:not(:last-child)::after {
    background: repeating-linear-gradient(180deg, var(--li-forest) 0 7px, transparent 7px 15px);
    background-size: 3px 15px;
  }
}

/* The pager arrows lost their pill shell to the same UCSS strip that took the
   month card, so they were rendering as two stray ‹ › glyphs. Restated, and
   the row is laid out properly: doodle and month name centred together, one
   arrow pinned to each edge. */
.rr-cal--css .rr-cal__nav {
  display: flex; align-items: center; justify-content: space-between;
}
.rr-cal--css .rr-cal__nav::before { order: 1; margin-left: auto; }
.rr-cal--css .rr-cal__label { order: 2; margin-right: auto; }
.rr-cal--css .rr-cal__arrow { order: 0; }
.rr-cal--css .rr-cal__arrow + .rr-cal__label ~ .rr-cal__arrow,
.rr-cal--css .rr-cal__arrow:last-child { order: 3; }
.rr-cal .rr-cal__arrow {
  width: 2.5rem; height: 2.5rem; font-size: 1.5rem; line-height: 1;
  border: 2px solid var(--li-cream); border-radius: 999px;
  background: transparent; color: var(--li-cream); cursor: pointer;
  transition: transform .2s var(--li-pop), box-shadow .2s ease, background .2s ease;
}
.rr-cal .rr-cal__arrow:not(.rr-cal__arrow--off):hover { background: rgba(245,239,223,.14); }
.rr-cal .rr-cal__arrow--off { border-color: rgba(245,239,223,.26); color: rgba(245,239,223,.3); }
.rr-cal--css .rr-cal__nav::before { margin-right: .7rem; }

/* The heading/lede grid placed the h2 and its lede explicitly in row 1 and left
   everything else to auto-flow, which pushed a section eyebrow BELOW the
   heading it introduces (caught on the rebuilt Members Area). When a section
   opens on an eyebrow, that eyebrow owns row 1 and the pair drops to row 2. */
.li-section:has(> .rr-eyebrow + h2 + .li-lede):not(.rr-pagehead):not(.rr-insider):not(.li-cta) > .rr-eyebrow { grid-column: 1; grid-row: 1; }
.li-section:has(> .rr-eyebrow + h2 + .li-lede):not(.rr-pagehead):not(.rr-insider):not(.li-cta) > h2 { grid-row: 2; }
.li-section:has(> .rr-eyebrow + h2 + .li-lede):not(.rr-pagehead):not(.rr-insider):not(.li-cta) > h2 + .li-lede { grid-row: 2; }

/* ---------------------------------------------------------------------------
   9 · The single Book Club post. Meg, 2026-08-28: "style this to be more
   consistent with the blog page, in the sense of the title card / featured
   image being the same as the blog post page... this page could be elevated
   slightly."
   Two faults, and neither was cosmetic. The post opened on `li-pagehero`, the
   old decorative hero that every PAGE was moved off on 2026-08-24 (it is
   hidden by page id, and a post has no page id), so a post looked nothing like
   the archive it came from. And the closing CTA was a `li-cta`, which is
   hidden site-wide, so the foot of every post rendered as an invisible block.
   The head is now the same doodle title-card the archive uses, at hero scale,
   and the close is the standard Insider band.
   --------------------------------------------------------------------------- */
.rr-postlead { padding-top: calc(var(--li-head-h, 84px) + 2.4rem); padding-bottom: 0; }
body.admin-bar .rr-postlead { padding-top: calc(var(--li-head-h, 84px) + var(--wp-admin--admin-bar--height, 32px) + 2.4rem); }
.rr-postlead__card {
  position: relative; overflow: hidden; isolation: isolate;
  background: var(--li-forest); color: var(--li-cream);
  border: 2px solid var(--li-ink); border-radius: var(--li-radius);
  box-shadow: 8px 10px 0 rgba(30, 32, 25, .16);
  padding: clamp(2rem, 4vw, 3rem) clamp(1.6rem, 3.4vw, 2.6rem) clamp(1.8rem, 3.4vw, 2.4rem);
  transform: rotate(-.9deg);
}
/* The same doodle watermark the archive cards carry, one step larger, so a
   post and its card in the shelf read as the same object. */
.rr-postlead__card::after {
  content: ""; position: absolute; z-index: 1; pointer-events: none;
  top: 1.2rem; right: 1.4rem; width: clamp(5rem, 9vw, 7.5rem); height: clamp(5rem, 9vw, 7.5rem);
  opacity: .5; background: var(--li-chartreuse);
  -webkit-mask: center/contain no-repeat url(/wp-content/themes/reading-room/assets/img/doodles/book-open.png);
          mask: center/contain no-repeat url(/wp-content/themes/reading-room/assets/img/doodles/book-open.png);
}
/* The tape strip, so the card is stuck to the page like everything else. */
.rr-postlead__card::before {
  content: ""; position: absolute; top: -12px; left: 12%; width: clamp(80px, 10vw, 130px); height: 24px;
  transform: rotate(-3deg); z-index: 3;
  background: var(--li-butter); border: 2px solid var(--li-ink); border-radius: 3px;
  box-shadow: 2px 3px 0 rgba(30, 32, 25, .14);
}
.rr-postlead__card > * { position: relative; z-index: 2; }
.rr-postlead__cat {
  display: inline-block; margin: 0 0 1rem;
  font-family: var(--li-hand); font-size: 1.2rem; line-height: 1; color: var(--li-chartreuse);
}
.rr-postlead__cat a { color: inherit; text-decoration: none; }
.rr-postlead__card .wp-block-post-title {
  margin: 0; color: var(--li-cream);
  font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1;
  font-weight: 540; font-size: clamp(2rem, 4.6vw, 3.2rem); line-height: 1.05; letter-spacing: -.015em;
  max-width: 20ch;
}
.rr-postlead__card .wp-block-post-title em { color: var(--li-chartreuse); }
@media (max-width: 640px) { .rr-postlead__card { transform: none; } }

/* The related shelf. The cards are hand-built (no li.wp-block-post wrapper to
   count), so the ground, doodle and tilt are assigned inline by index in
   rr_related_posts_markup rather than by nth-child here. */
.rr-related > .rr-eyebrow { margin-bottom: .3rem !important; }
.rr-related > h2 { margin-top: 0; }
.rr-related .li-postcard--tc { height: 100%; display: flex; flex-direction: column; }
.rr-related .li-postcard--tc .wp-block-post-excerpt { margin-top: 0; }
.rr-related .li-titlecard { min-height: 168px; }

/* ---------------------------------------------------------------------------
   10 · The accordion layer, restated. UCSS is generated per page, and the
   contact page had never carried an `.li-faq` before RR-Final-03 moved the
   three question types into one, so its stylesheet had dropped the whole
   accordion set. The three questions were rendering as bare browser
   `<details>` with a black triangle marker, on a page whose FAQ is now a
   primary component. Same per-page trap as the doodle layer and the calendar.
   --------------------------------------------------------------------------- */
.li-faq { display: grid; gap: .9rem; }
.li-faq .wp-block-details {
  background: var(--li-cream); border: 2px solid var(--li-ink); border-radius: 18px;
  padding: 0 1.5rem; margin: 0; color: var(--li-ink); transition: box-shadow .3s ease;
}
.li-faq .wp-block-details:hover { box-shadow: 5px 6px 0 rgba(30, 32, 25, .18); }
.li-faq .wp-block-details summary {
  list-style: none; cursor: pointer;
  display: flex; justify-content: space-between; align-items: center; gap: 1rem;
  padding: 1.2rem 0;
  font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 520;
  font-size: clamp(1.15rem, 2.2vw, 1.4rem);
}
.li-faq .wp-block-details summary::-webkit-details-marker { display: none; }
.li-faq .wp-block-details summary::after {
  content: "+"; flex: none; width: 34px; height: 34px; display: grid; place-items: center;
  border: 2px solid var(--li-ink); border-radius: 50%;
  font-family: var(--li-sans); font-weight: 700; font-size: 1.2rem;
  transition: transform .3s ease, background-color .3s ease;
}
.li-faq .wp-block-details[open] summary::after { transform: rotate(45deg); background: var(--li-chartreuse); }
.li-faq .wp-block-details > :not(summary) { max-width: 64ch; opacity: .9; }
.li-faq .wp-block-details > p:last-child { padding-bottom: 1.4rem; }

/* The FAQ jump menu. Meg asked whether the reader FAQ needed one; it does. The
   page is three tiers of accordions and a search box, and a reader arriving
   with a specific question had to scroll past two tiers to find the third.
   Same pill vocabulary as the category filter and the pager, so it reads as
   the site's own navigation rather than a new control. */
.rr-faqjump {
  list-style: none; margin: 1.4rem 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: .6rem;
}
.rr-faqjump a {
  display: inline-flex; align-items: center; padding: .5rem 1rem;
  font-family: var(--li-sans); font-size: .85rem; font-weight: 700; letter-spacing: .02em;
  color: var(--li-ink); background: var(--li-paper);
  border: 2px solid var(--li-ink); border-radius: 999px; text-decoration: none;
  transition: transform .2s var(--li-pop), box-shadow .2s ease, background .2s ease;
}
.rr-faqjump a:hover {
  transform: translate(-1px, -1px); box-shadow: 4px 5px 0 rgba(30, 32, 25, .2);
  background: var(--li-chartreuse);
}
/* A jump target has to clear the fixed header or the tier heading lands under
   the nav, which is the same fault the page heads had. */
.li-faq-section[id] { scroll-margin-top: calc(var(--li-head-h, 84px) + 1rem); }

/* Latest-post cards in a li-grid stretch to the row, stated rather than
   assumed: a card that grows its own height silently opts out. */
.li-grid > .li-postcard--tc { height: 100%; display: flex; flex-direction: column; }

/* ---------------------------------------------------------------------------
   11 · The search block, restated. Measured on the Book Club: the input was
   213px inside a 320px form and the Search button rendered transparent with a
   0px border, because UCSS had dropped `.li-search` and
   `.wp-block-search__button` from that page's stylesheet. Same per-page trap
   as the doodle layer, the calendar and the accordions.
   --------------------------------------------------------------------------- */
.li-search { display: flex; gap: .6rem; max-width: 460px; margin: 1.6rem auto 0; width: 100%; }
.li-search input[type="search"], .li-search .wp-block-search__input {
  flex: 1 1 auto; min-width: 0;
  border: 2px solid var(--li-ink) !important; border-radius: 999px !important;
  padding: .85rem 1.3rem; font-family: var(--li-sans); font-size: .95rem;
  background: var(--li-paper); color: var(--li-ink);
}
.wp-block-search__button {
  border: 2px solid var(--li-ink); border-radius: 999px;
  background: var(--li-chartreuse); color: var(--li-ink);
  font-family: var(--li-sans); font-weight: 700; padding: .6rem 1.3rem;
  transition: transform .2s var(--li-pop), box-shadow .2s ease;
}
.wp-block-search__button:hover { transform: translate(-1px, -1px); box-shadow: 4px 5px 0 rgba(30, 32, 25, .2); }
/* In the split page head the search is a full-width grid child, so it needs
   its own row under the heading and lede rather than sharing one. */
.li-section.rr-pagehead:has(> h1 + .li-lede) > .li-search { grid-row: 2; }

/* ---------------------------------------------------------------------------
   12 · The authors index. The card BOXES were already equal height, but their
   insides were not: covers came out 187 to 199px tall, so the name, the genre
   and the "View author" link started at a different height in every card. Same
   complaint Meg raised about the homepage shelf, on a grid the shelf fix could
   not reach.
   `.rrdir-cov` is a SPAN wrapping the image, so the frame has to go on the IMG:
   putting the aspect-ratio on the span left the unconstrained image overflowing
   it at its natural height. `contain` with a bottom origin is the same anti-crop
   rule the shelf cards use, so an author's art is never sliced.
   Doubled selectors: this page carries its own inline <style> in the post body,
   which loads after the head and would otherwise win.
   --------------------------------------------------------------------------- */
.rrdir-card .rrdir-cov.rrdir-cov { width: 120px; display: block; }
.rrdir-card .rrdir-cov.rrdir-cov img {
  display: block; width: 100%; height: auto; aspect-ratio: 2 / 3;
  object-fit: contain; object-position: bottom;
}
.rrdir-card .rrdir-name.rrdir-name { margin-top: .9rem; }
.rrdir-card .rrdir-go.rrdir-go { margin-top: auto; padding-top: .5rem; }
@media (max-width: 640px) { .rrdir-card .rrdir-cov.rrdir-cov { width: 96px; } }

/* ---------------------------------------------------------------------------
   13 · The single post carries two components that page templates never did:
   the doodle title-card (on the related shelf) and the Insider signup form.
   UCSS is generated per page, so on a post that has never had either, both
   arrive with their rules already stripped: the related-card titles paint ink
   on forest and the signup renders as a browser-default input and button.
   Restated here, where UCSS cannot reach them.
   --------------------------------------------------------------------------- */
.li-postcard--tc .li-titlecard .wp-block-post-title,
.li-postcard--tc .li-titlecard .wp-block-post-title a {
  position: relative; z-index: 2; color: var(--li-cream); text-decoration: none;
  font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1;
  font-weight: 500; font-size: clamp(1.2rem, 1.9vw, 1.5rem); line-height: 1.14;
  padding: 0; margin: 0;
}
.li-postcard--tc .li-titlecard .wp-block-post-title a:hover { text-decoration: none; }
.li-postcard--tc .li-titlecard {
  position: relative; overflow: hidden; isolation: isolate;
  background: var(--li-forest); color: var(--li-cream);
  min-height: 190px; display: flex; align-items: flex-end;
  padding: 1.5rem 1.4rem 1.4rem;
}
.li-postcard--tc .wp-block-post-excerpt { padding: .45rem 1.3rem 1.3rem; }

.rr-signup__form { display: flex; flex-wrap: wrap; gap: .7rem; justify-content: center; align-items: stretch; margin: 0 auto; max-width: 34rem; }
.rr-signup__email {
  flex: 1 1 16rem; min-width: 0; padding: .85rem 1.1rem;
  font: inherit; font-size: 1rem; color: var(--li-ink); background: var(--li-paper);
  border: 2px solid var(--li-ink); border-radius: 999px;
}
.rr-signup__email::placeholder { color: rgba(30, 32, 25, .55); }
.rr-signup__email:focus-visible { outline: 3px solid var(--li-chartreuse); outline-offset: 2px; }
.rr-signup__button {
  flex: 0 0 auto; padding: .85rem 1.7rem;
  font: inherit; font-size: 1rem; font-weight: 700; cursor: pointer;
  color: var(--li-ink); background: var(--li-chartreuse);
  border: 2px solid var(--li-ink); border-radius: 999px;
}
.rr-signup__button:hover { filter: brightness(1.06); }
/* The honeypot must never be visible or focusable. */
.rr-signup__nonce { position: absolute !important; left: -9999px !important; width: 1px !important; height: 1px !important; opacity: 0 !important; }
/* The title-card doodle watermark. `--li-tc-dood` is set inline per card by
   rr_related_posts_markup, but the rule that paints it lives in the theme and
   is stripped on a post that never carried a title card, so the cards came out
   as plain colour blocks. */
.li-postcard--tc .li-titlecard::after {
  content: ""; position: absolute; z-index: 1; pointer-events: none;
  top: 1.1rem; right: 1.2rem; width: 4.8rem; height: 4.8rem; opacity: .55;
  background: var(--li-dood-tint, var(--li-chartreuse));
  -webkit-mask: center/contain no-repeat var(--li-tc-dood);
          mask: center/contain no-repeat var(--li-tc-dood);
}

/* ==========================================================
   0.38.0 · 2026-09-24 · Meg's Reading Room round
   1 · The doodle layer is retired. Every graphic is now a branded mark:
       authored SVG in the LI polished style (assets/img/marks/, rendered
       inline by rr_mark()). Saved page content still carries .li-dood spans,
       so those are remapped here to paint the branded SVG instead of a
       doodle mask. No doodle image is referenced anywhere any more.
   2 · The seamless doodle wallpapers (li-pattern) are gone.
   3 · Blog index, single post and contact page match literaryinspired.com
       as of today's LI round (title cards straight with a branded sticker,
       category pill, forest post hero, LI contact layout).
   4 · Calendar toolkit band narrowed; process strip carries the marks.
   ========================================================== */

/* --- 1a · inline marks --------------------------------------------------- */
.rr-mark{display:inline-block;width:var(--rr-mark-size,4rem);height:var(--rr-mark-size,4rem);line-height:0;vertical-align:middle;flex:0 0 auto}
.rr-mark svg{display:block;width:100%;height:100%;overflow:visible}
@keyframes rrmFloat{0%,100%{transform:translateY(0)}50%{transform:translateY(-6px)}}
@keyframes rrmFloat2{0%,100%{transform:translate(0,0) rotate(0)}50%{transform:translate(0,-5px) rotate(4deg)}}
@keyframes rrmPulse{0%,100%{transform:scale(1)}50%{transform:scale(1.09)}}
@keyframes rrmBlink{0%,100%{opacity:.3}50%{opacity:1}}
@keyframes rrmRise{0%{transform:translateY(4px);opacity:0}25%{opacity:1}80%{opacity:1}100%{transform:translateY(-14px);opacity:0}}
@keyframes rrmDraw{0%{stroke-dashoffset:var(--dl)}50%,92%{stroke-dashoffset:0}100%{stroke-dashoffset:var(--dl)}}
@keyframes rrmTwinkle{0%,100%{opacity:.6;transform:scale(.92)}50%{opacity:1;transform:scale(1.08)}}
.rr-mark .g-float{animation:rrmFloat 3.4s ease-in-out infinite}
.rr-mark .g-float2{transform-box:fill-box;transform-origin:center;animation:rrmFloat2 3.6s ease-in-out infinite}
.rr-mark .g-pulse{transform-box:fill-box;transform-origin:center;animation:rrmPulse 2.2s ease-in-out infinite}
.rr-mark .g-blink{animation:rrmBlink 1.6s ease-in-out infinite}
.rr-mark .g-rise{animation:rrmRise 3.2s ease-in infinite}
.rr-mark .g-draw{stroke-dasharray:var(--dl);animation:rrmDraw 3s ease-in-out infinite}
.rr-mark .g-twinkle{transform-box:fill-box;transform-origin:center;animation:rrmTwinkle 2.6s ease-in-out infinite}
.rr-mark .d1{animation-delay:.2s}.rr-mark .d2{animation-delay:.45s}.rr-mark .d3{animation-delay:.7s}
@media (prefers-reduced-motion:reduce){.rr-mark svg *{animation:none!important}.rr-mark .g-rise{opacity:1}.rr-mark .g-draw{stroke-dasharray:none!important}}

/* --- 1b · saved .li-dood spans paint the branded mark ---------------------- */
.li-dood,.li-dood[class*="li-dood--"]{-webkit-mask:none!important;mask:none!important;-webkit-mask-image:none!important;mask-image:none!important;background-color:transparent!important;background-repeat:no-repeat!important;background-position:center!important;background-size:contain!important;display:inline-block;width:var(--li-dood-size,2.4rem);height:var(--li-dood-size,2.4rem);aspect-ratio:1}
.li-dood--book,.li-dood--sale{background-image:url(/wp-content/themes/reading-room/assets/img/marks/book.svg)!important}
.li-dood--book-open{background-image:url(/wp-content/themes/reading-room/assets/img/marks/glasses-book.svg)!important}
.li-dood--notebook,.li-dood--schedule{background-image:url(/wp-content/themes/reading-room/assets/img/marks/form.svg)!important}
.li-dood--pencil{background-image:url(/wp-content/themes/reading-room/assets/img/marks/pencil.svg)!important}
.li-dood--megaphone{background-image:url(/wp-content/themes/reading-room/assets/img/marks/megaphone.svg)!important}
.li-dood--clock{background-image:url(/wp-content/themes/reading-room/assets/img/marks/night.svg)!important}
.li-dood--mug{background-image:url(/wp-content/themes/reading-room/assets/img/marks/mug.svg)!important}
.li-dood--calendar{background-image:url(/wp-content/themes/reading-room/assets/img/marks/toolkit.svg)!important}
.li-dood--star,.li-dood--camera{background-image:url(/wp-content/themes/reading-room/assets/img/marks/star.svg)!important}
.li-dood--stars5,.li-dood--star-bubble,.li-dood--bubble-stars,.li-dood--bubble-thumb,.li-dood--bubble-loveit{background-image:url(/wp-content/themes/reading-room/assets/img/marks/review.svg)!important}
.li-dood--sparkle{background-image:url(/wp-content/themes/reading-room/assets/img/marks/sparkle.svg)!important}
.li-dood--medal,.li-dood--laurel{background-image:url(/wp-content/themes/reading-room/assets/img/marks/medal-book.svg)!important}
.li-dood--question,.li-dood--bubble-question,.li-dood--bubble-idea{background-image:url(/wp-content/themes/reading-room/assets/img/marks/question.svg)!important}
.li-dood--bubble-dots,.li-dood--bubble-sad,.li-dood--bubble-grawlix{background-image:url(/wp-content/themes/reading-room/assets/img/marks/bubble-heart.svg)!important}
.rr-headsplit__art .li-dood[class*="bubble-"],.rr-faqhead .li-dood[class*="bubble-"]{width:var(--li-dood-size,4rem)!important;height:var(--li-dood-size,4rem)!important;aspect-ratio:1!important}
.li-dood--bob,.li-dood--bob2{animation:rrmFloat 3.4s ease-in-out infinite!important}
/* Marks in the places doodles used to live. */
.rr-pagehead--split .rr-headsplit__art .li-dood,.rr-pagehead--split .rr-headsplit__art .rr-mark{--li-dood-size:clamp(7rem,15vw,11rem);--rr-mark-size:clamp(7rem,15vw,11rem);width:clamp(7rem,15vw,11rem)!important;height:clamp(7rem,15vw,11rem)!important}
.rr-split__art .li-dood,.rr-split__art .rr-mark{--li-dood-size:clamp(6rem,13vw,9.5rem);--rr-mark-size:clamp(6rem,13vw,9.5rem)}
.rr-cardmark,.rr-mark.rr-cardmark{--li-dood-size:3rem;--rr-mark-size:3rem;display:block;margin:0 0 .85rem;background-color:transparent!important}
.page-id-11 .rr-headsplit__art .li-dood,.page-id-11 .rr-split__art .li-dood{background-color:transparent!important}
.rr-faqhead .li-dood,.rr-faqhead .rr-mark{display:none!important}
.rr-cal--css .rr-cal__nav::before,.rr-monthcal::after{display:none!important;content:none!important}

/* --- 2 · wallpapers retired ------------------------------------------------ */
.li-pattern::before{display:none!important;content:none!important}
.li-pattern{isolation:auto}

/* --- 2b · every wallpaper rule, wherever it was declared, is off ------------ */
.li-section:has(> .rr-shelf)::before,.li-section:has(.rr-data--current-arcs)::before,.li-section:has(.rr-data--past-arcs)::before,.li-section:has(.rr-data--just-released)::before,.li-faq-section::before,.li-section.li-pattern::before,.rr-procband::before,.rr-insider::before{content:none!important;display:none!important;-webkit-mask:none!important;mask:none!important;background:none!important}

/* --- 3a · process strip: marks on paper discs, ink writing ------------------ */
.li-section.rr-procband,.rr-procband{background:var(--li-lavender)!important}
.rr-procband .rr-flow__badge{width:5rem!important;height:5rem!important;border-radius:999px;background:var(--li-paper)!important;border:2px solid var(--li-ink)!important;box-shadow:3px 4px 0 rgba(30,32,25,.18);display:grid;place-items:center}
.rr-procband .rr-flow__icon{width:3.4rem;height:3.4rem;display:grid;place-items:center}
.rr-procband .rr-flow__icon .rr-mark{--rr-mark-size:3.4rem}
.rr-procband .rr-flow__icon .li-dood{--li-dood-size:3.2rem!important;width:3.2rem!important;height:3.2rem!important;background-color:transparent!important}
.rr-procband .rr-flow__step:not(:last-child)::after{top:2.4rem!important;left:calc(50% + 3.1rem)!important;width:calc(100% - 6.2rem)!important;background:repeating-linear-gradient(90deg,var(--li-cream) 0 7px,transparent 7px 15px)!important;background-size:15px 3px!important}
@media (max-width:720px){.rr-procband .rr-flow__step:not(:last-child)::after{top:calc(2.4rem + 3.1rem)!important;left:2.45rem!important;width:3px!important;height:calc(100% - 6.2rem)!important;background:repeating-linear-gradient(180deg,var(--li-cream) 0 7px,transparent 7px 15px)!important;background-size:3px 15px!important}}

/* --- 3b · blog index + archives: LI title cards ---------------------------- */
.li-pagehero--blog{padding-bottom:clamp(2.4rem,5vw,3.6rem)}
.li-pagehero--blog .li-pagehero__sub{margin-top:1.4rem}
.li-pagehero .li-search{margin-top:1.8rem}
.li-pagehero .li-note--light{margin-top:1.4rem}
body li.wp-block-post .li-postcard--tc,body li.wp-block-post:nth-child(odd) .li-postcard--tc,body li.wp-block-post:nth-child(even) .li-postcard--tc{transform:none!important;overflow:hidden!important}
body li.wp-block-post .li-postcard--tc:hover{transform:translateY(-4px)!important}
body li.wp-block-post .li-postcard--tc::before,body .rr-related .li-postcard--tc::before,body .rr-related .li-postcard--tc::after{display:none!important;content:none!important}
body li.wp-block-post > .li-postcard--tc{height:100%}
body .li-postcard--tc .li-titlecard{min-height:200px;flex:1 1 auto;position:relative;overflow:hidden;isolation:isolate;background:var(--li-forest);color:var(--li-cream);display:flex;align-items:flex-end;padding:1.5rem 1.4rem 1.4rem}
body .li-postcard--tc .li-titlecard .wp-block-post-title{max-width:22ch;padding:0;margin:0}
body .li-postcard--tc .li-titlecard .wp-block-post-title,body .li-postcard--tc .li-titlecard .wp-block-post-title a{position:relative;z-index:2;color:var(--li-cream);font-family:var(--li-display);font-variation-settings:"SOFT" 100,"WONK" 1;font-weight:500;font-size:clamp(1.2rem,1.9vw,1.5rem);line-height:1.14;text-decoration:none}
body li.wp-block-post:nth-child(3n+1) .li-titlecard{background:var(--li-forest)!important}
body li.wp-block-post:nth-child(3n+2) .li-titlecard{background:var(--li-lavender-deep)!important}
body li.wp-block-post:nth-child(3n) .li-titlecard{background:var(--li-forest-deep)!important}
body .rr-related__grid > .li-postcard--tc:nth-child(3n+1) .li-titlecard{background:var(--li-forest)!important}
body .rr-related__grid > .li-postcard--tc:nth-child(3n+2) .li-titlecard{background:var(--li-lavender-deep)!important}
body .rr-related__grid > .li-postcard--tc:nth-child(3n) .li-titlecard{background:var(--li-forest-deep)!important}
/* The sticker: the branded mark itself, top right, gently rocking. */
body .li-postcard--tc .li-titlecard::after{content:""!important;position:absolute;z-index:1;pointer-events:none;top:.9rem!important;right:1rem!important;left:auto!important;bottom:auto!important;width:4.4rem!important;height:4.4rem!important;font-size:0!important;line-height:0;opacity:1!important;background-color:transparent!important;-webkit-mask:none!important;mask:none!important;background-repeat:no-repeat;background-position:center;background-size:contain;animation:li-tc-spin 9s ease-in-out infinite alternate}
@keyframes li-tc-spin{from{transform:rotate(-6deg) translate3d(0,0,0)}to{transform:rotate(8deg) translate3d(2px,-3px,0)}}
body li.wp-block-post:nth-child(6n+1) .li-titlecard::after,body .rr-related__grid > .li-postcard--tc:nth-child(6n+1) .li-titlecard::after{background-image:url(/wp-content/themes/reading-room/assets/img/marks/book.svg)!important}
body li.wp-block-post:nth-child(6n+2) .li-titlecard::after,body .rr-related__grid > .li-postcard--tc:nth-child(6n+2) .li-titlecard::after{background-image:url(/wp-content/themes/reading-room/assets/img/marks/pencil.svg)!important}
body li.wp-block-post:nth-child(6n+3) .li-titlecard::after,body .rr-related__grid > .li-postcard--tc:nth-child(6n+3) .li-titlecard::after{background-image:url(/wp-content/themes/reading-room/assets/img/marks/star.svg)!important}
body li.wp-block-post:nth-child(6n+4) .li-titlecard::after,body .rr-related__grid > .li-postcard--tc:nth-child(6n+4) .li-titlecard::after{background-image:url(/wp-content/themes/reading-room/assets/img/marks/megaphone.svg)!important}
body li.wp-block-post:nth-child(6n+5) .li-titlecard::after,body .rr-related__grid > .li-postcard--tc:nth-child(6n+5) .li-titlecard::after{background-image:url(/wp-content/themes/reading-room/assets/img/marks/glasses-book.svg)!important}
body li.wp-block-post:nth-child(6n) .li-titlecard::after,body .rr-related__grid > .li-postcard--tc:nth-child(6n) .li-titlecard::after{background-image:url(/wp-content/themes/reading-room/assets/img/marks/mug.svg)!important}
@media (prefers-reduced-motion:reduce){body .li-postcard--tc .li-titlecard::after{animation:none!important}}
body .li-postcard--tc .wp-block-post-excerpt{padding:.45rem 1.3rem 1.3rem}
body .li-postcard--tc .wp-block-post-excerpt__excerpt{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;margin:0}
body .li-postcard--tc .wp-block-post-date,body .rr-related .wp-block-post-date{display:none!important}
.li-postcard__cat{margin:.95rem 1.3rem 0!important;display:flex;flex-wrap:wrap;gap:.4rem;justify-content:flex-start}
.li-postcard__cat a{display:inline-block;font-family:var(--li-sans);font-weight:700;font-size:.68rem;letter-spacing:.06em;padding:.3rem .78rem;border-radius:999px;background:var(--li-chartreuse);color:var(--li-forest-deep);text-decoration:none;border:1.5px solid var(--li-ink);line-height:1.2;text-transform:capitalize}
.li-postcard__cat .wp-block-post-terms__separator{display:none}
.wp-block-query-pagination{gap:.5rem;margin-top:clamp(2rem,4vw,3rem);align-items:center;flex-wrap:wrap}
.wp-block-query-pagination .page-numbers,.wp-block-query-pagination .wp-block-query-pagination-previous,.wp-block-query-pagination .wp-block-query-pagination-next{display:inline-flex;align-items:center;justify-content:center;min-width:2.6rem;padding:.5rem .95rem;font-family:var(--li-sans);font-size:.85rem;font-weight:700;text-decoration:none;color:var(--li-ink);background:var(--li-paper);border:2px solid var(--li-ink);border-radius:999px}
.wp-block-query-pagination .page-numbers.current{background:var(--li-chartreuse);box-shadow:3px 4px 0 rgba(30,32,25,.2)}
.wp-block-query-pagination .page-numbers.dots{border-color:transparent;background:none;box-shadow:none;min-width:1.4rem;padding:.5rem .2rem}
.wp-block-query-pagination-numbers{display:inline-flex;gap:.5rem;flex-wrap:wrap}

/* --- 3c · single post: LI's forest post hero, 760 measure, related 4-up ----- */
.li-pagehero--post{padding-top:calc(var(--li-head-h) + clamp(1.4rem,3vw,2rem));padding-bottom:clamp(1.6rem,3vw,2.4rem)}
body.admin-bar .li-pagehero--post{padding-top:calc(var(--li-head-h) + var(--wp-admin--admin-bar--height,32px) + clamp(1.4rem,3vw,2rem))}
.li-pagehero--post h1{font-size:clamp(2rem,4.4vw,3.4rem);max-width:22ch}
.li-pagehero--post .li-eyebrow{gap:.5rem}
.li-postterms{display:flex;flex-wrap:wrap;gap:.6rem;justify-content:center;margin:0}
.li-postterms a{display:inline-block;font-family:var(--li-sans);font-weight:700;font-size:.72rem;letter-spacing:.06em;padding:.38rem .9rem;border-radius:999px;border:1.5px dashed rgba(245,239,223,.6);color:var(--li-cream);text-decoration:none;transform:rotate(1.4deg);text-transform:capitalize}
.li-postterms a:nth-child(even){transform:rotate(-1.6deg)}
.li-postterms a:hover{background:var(--li-chartreuse);color:var(--li-forest-deep);border-style:solid;border-color:var(--li-ink)}
.li-postterms .wp-block-post-terms__separator{display:none}
.rr-read.li-prose{padding-top:clamp(2rem,4vw,3rem)}
.li-prose > *{max-width:760px;margin-left:auto;margin-right:auto}
.li-prose p,.li-prose ul,.li-prose ol{max-width:760px}
.rr-related-band{padding-top:clamp(1.6rem,3vw,2.4rem)!important}
.rr-related__head{margin:0 0 1.4rem;text-align:left}
.rr-related__head .wp-block-heading{color:var(--li-forest);margin:0}
.rr-related__grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1.2rem;overflow:visible}
@media (max-width:1000px){.rr-related__grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:560px){.rr-related__grid{grid-template-columns:1fr}}
.rr-related__grid .li-postcard--tc{transform:none!important;overflow:hidden!important;height:100%}
.rr-related__grid .li-postcard--tc:hover{transform:translateY(-4px)!important}
.rr-related__grid .li-titlecard{min-height:170px;border-radius:0}
.rr-related__grid .li-titlecard .wp-block-post-title{font-size:1.12rem!important}
.rr-related__grid .li-titlecard::after{width:3.4rem!important;height:3.4rem!important}
.rr-related > .rr-eyebrow{display:none!important}
.rr-postlead,.rr-postlead__card{all:revert}

/* --- 3d · contact: the LI layout --------------------------------------------- */
.rr-contact-top,.li-section.rr-contact-top{padding-top:calc(var(--li-head-h,84px) + clamp(2.2rem,5vw,3.8rem))!important;padding-bottom:clamp(2.4rem,5vw,4rem)}
body.admin-bar .rr-contact-top,body.admin-bar .li-section.rr-contact-top{padding-top:calc(var(--li-head-h,84px) + var(--wp-admin--admin-bar--height,32px) + clamp(2.2rem,5vw,3.8rem))!important}
.li-contact-grid{gap:clamp(1.6rem,4vw,3rem)!important;align-items:start}
.li-contact-form > .wp-block-heading{margin-bottom:.5rem;font-size:clamp(2.1rem,4.2vw,3.2rem)}
.li-contact-form > .wp-block-heading em{color:var(--li-lavender-deep)}
.li-contact-form > p{max-width:56ch}
.li-contact-form .fluentform{margin-top:1.2rem}
.li-contact-card{padding:clamp(1.6rem,3vw,2.4rem);border:2px solid var(--li-ink);border-radius:var(--li-radius);box-shadow:8px 10px 0 rgba(30,32,25,.14);color:var(--li-ink)}
.li-contact-card h3{margin-top:1.5rem;margin-bottom:1.1rem;font-size:clamp(1.5rem,2.6vw,2.1rem)}
.li-contact-card > h3:first-child{margin-top:0}
.li-contact-card p.wp-block-paragraph,.li-contact-card p{font-size:.97rem}
.li-contact-card .li-hr{border:none;border-top:2px dashed rgba(30,32,25,.22);margin:2rem 0;opacity:1;height:0}
.li-contact-card .wp-block-buttons{margin-top:1.1rem!important;justify-content:flex-start}
.li-contact-card .is-style-li-chartreuse .wp-block-button__link{background:var(--li-chartreuse);color:var(--li-ink);border-color:var(--li-ink)}
.li-contact-social{font-weight:600}.li-contact-social a{white-space:nowrap}
.li-fineprint{font-size:.92rem;opacity:.78;margin-top:1.2rem}
.li-faq-section > .wp-block-heading.has-text-align-center{margin-bottom:1.6rem}
@media (max-width:781px){.li-contact-grid{display:block}.li-contact-grid > .wp-block-column{flex-basis:auto!important;width:100%}.li-contact-grid > .wp-block-column + .wp-block-column{margin-top:1.8rem}}

/* --- 4a · calendar: clear the fixed header, and a day with two events grows its row --- */
.rr-pagehead:has(.rr-calwrap),.li-section.rr-pagehead:has(.rr-calwrap){padding-top:calc(var(--li-head-h,84px) + 3.6rem)!important}
body.admin-bar .rr-pagehead:has(.rr-calwrap),body.admin-bar .li-section.rr-pagehead:has(.rr-calwrap){padding-top:calc(var(--li-head-h,84px) + var(--wp-admin--admin-bar--height,32px) + 3.6rem)!important}
.rr-cal .rr-monthcal__grid{grid-auto-rows:minmax(clamp(114px,9.2vw,130px),auto)!important}.rr-cal .rr-monthcal__day--event{padding-bottom:10px}

/* --- 4 · calendar toolkits: narrower, two across, consistent margins --------- */
.page-id-9 .li-section:has(.rr-data--toolkits) > *{max-width:960px;margin-left:auto;margin-right:auto}
.page-id-9 .li-section:has(.rr-data--toolkits) .rr-data--toolkits{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1.2rem}
@media (max-width:760px){.page-id-9 .li-section:has(.rr-data--toolkits) .rr-data--toolkits{grid-template-columns:1fr}}
.rr-tkcard{padding:1rem 1.05rem 1.05rem}

/* --- 5 · hero: the branded stack replaces the line-drawn book shape ---------- */
.li-shape--stack{width:clamp(120px,14vw,190px);bottom:9%;right:10%;height:auto}
.li-shape--stack svg{width:100%;height:auto;overflow:visible}
@media (max-width:760px){.li-shape--stack{display:none}}
