/*
Theme Name: Literary Inspired
Theme URI: https://literaryinspired.com
Author: Literary Inspired
Author URI: https://literaryinspired.com
Description: Author marketing studio theme for Literary Inspired. Bold, warm, playful. Block theme — every page is editable in the WordPress editor, no code needed. Display font: Fraunces (soft + wonky, the Cooper-adjacent one). Body: Poppins. Margin notes: Caveat.
Version: 1.49.0
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: literary-inspired
Tags: block-patterns, full-site-editing, one-column
*/

/* ==========================================================
   LITERARY INSPIRED · Authored, not agency.
   Palette: dark forest · chartreuse · lavender/lilac ·
   warm off-white · butter (supporting accent only)
   Type: Fraunces soft/wonky (display) · Poppins (body)
         Caveat (margin notes)
   ========================================================== */

:root {
  --li-forest: #1d3527;
  --li-forest-deep: #142619;
  --li-chartreuse: #c9d64f;
  --li-chartreuse-soft: #e2ea9c;
  --li-lavender: #b2a1e0;
  --li-lavender-deep: #5c46a8; /* QA-2: was #6b54b8 — 4.44:1 on cream-deep, under 4.5. Now 5.49:1. */
  --li-lilac: #ddd4f1;
  --li-butter: #f3c75c;
  --li-cream: #f5efe0;
  --li-cream-deep: #ebdfc6;
  --li-paper: #fdf9ee;
  --li-ink: #1e2019;
  --li-display: "Fraunces", "Cooper Black", Georgia, serif;
  --li-sans: "Poppins", -apple-system, BlinkMacSystemFont, sans-serif;
  --li-hand: "Caveat", cursive;
  --li-radius: 22px;
  --li-topbar-h: 36px;
  --li-head-h: 120px;
  --li-pop: cubic-bezier(.34, 1.56, .64, 1);

  /* CONSOLIDATION TOKENS (v1.40.0) — the audit's fix for "the same thing built
     more than once". Define each signature detail ONCE here; every component
     references the token instead of hand-setting its own value. */
  --li-shadow: 4px 4px 0 var(--li-ink);        /* the hard offset shadow (brand guide) */
  --li-tape: var(--li-chartreuse-soft);         /* the ONE tape colour, everywhere */
  --li-tape-edge: 1px dashed rgba(30,32,25,.35);/* the ONE tape edge */
  --li-edge-lav-w: 2px;                          /* the ONE lavender-edge thickness */
  --li-edge-lav-c: var(--li-lavender-deep);      /* the ONE lavender-edge colour */
}

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. */
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
}

/* 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);
  text-transform: uppercase; letter-spacing: 0.03em;
  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); }

/* ==========================================================
   CTA CONTRAST BY SURFACE — the ONE place this is decided (S1, 2026-08-02)
   ==========================================================
   Meg, 2026-07-31: "Section CTAs must not dissolve into their background —
   chartreuse buttons on chartreuse-adjacent/green sections are banned. Define
   per-background button color rules in one place in style.css and apply
   sitewide." This is that one place. Do not solve it per-page again.

   Measured on live dev v1.22.0, fill-vs-band contrast — every one real:
     chartreuse on lilac            1.12:1   Social, Newsletter
     chartreuse on cream-deep       1.20:1   Author Website Design
     chartreuse on chartreuse-soft  1.25:1   Digital Strategy (a chartreuse
                                             button on a chartreuse band)
     chartreuse on the page ground  1.39:1   About, Blog
     chartreuse on lavender         1.46:1   Services, Contact, Strategy, ARC,
                                             Brand Assets

   ⚠ WHY THIS INVERTS THE DEFAULT INSTEAD OF OVERRIDING LIGHT BANDS.
   The first cut of this fix keyed off light `has-*-background-color` ancestors
   and changed NOTHING (measured: 0 of 10 fixed). Most of these buttons have no
   painted ancestor at all — they sit on the page ground, so there is no light
   class to hook. Only the DARK surfaces are reliably identifiable. So: the dark
   pill is the default, and the pale pill is restored on the explicit list of
   dark surfaces below. Those are enumerated, not guessed — each one was found
   by grepping every rule that paints a forest/ink background.

   If you add a new dark surface that contains a button, add it to the allowlist
   or its CTA will render forest-on-forest. The S6 QA sweep measures both
   directions (fill-vs-band AND text-on-fill) and will catch it.
   ========================================================== */
:is(.is-style-li-chartreuse, .is-style-li-lavender, .is-style-li-butter) .wp-block-button__link {
  background: var(--li-forest);
  color: var(--li-cream);
  border-color: var(--li-forest);
}
:is(.is-style-li-chartreuse, .is-style-li-lavender, .is-style-li-butter) .wp-block-button__link:hover {
  background: var(--li-forest-deep);
  color: var(--li-cream);
  box-shadow: 4px 4px 0 var(--li-ink);
}

/* The dark surfaces, where the pale pill is the legible one. */
:is(.li-head, .li-hero, .li-pagehero, .li-foot,
    .has-forest-background-color, .has-forest-deep-background-color,
    .li-pcard--feature, .li-pkg--feature, .li-card--forest, .li-card--ink,
    .li-fit__col--yes)
:is(.is-style-li-chartreuse) .wp-block-button__link {
  background: var(--li-chartreuse); color: var(--li-ink); border-color: var(--li-ink);
}
:is(.li-head, .li-hero, .li-pagehero, .li-foot,
    .has-forest-background-color, .has-forest-deep-background-color,
    .li-pcard--feature, .li-pkg--feature, .li-card--forest, .li-card--ink,
    .li-fit__col--yes)
:is(.is-style-li-chartreuse) .wp-block-button__link:hover {
  background: var(--li-chartreuse-soft); color: var(--li-ink); box-shadow: 4px 4px 0 var(--li-ink);
}
:is(.li-head, .li-hero, .li-pagehero, .li-foot,
    .has-forest-background-color, .has-forest-deep-background-color,
    .li-pcard--feature, .li-pkg--feature, .li-card--forest, .li-card--ink,
    .li-fit__col--yes)
:is(.is-style-li-lavender) .wp-block-button__link {
  background: var(--li-lavender); color: var(--li-ink); border-color: var(--li-ink);
}
:is(.li-head, .li-hero, .li-pagehero, .li-foot,
    .has-forest-background-color, .has-forest-deep-background-color,
    .li-pcard--feature, .li-pkg--feature, .li-card--forest, .li-card--ink,
    .li-fit__col--yes)
:is(.is-style-li-butter) .wp-block-button__link {
  background: var(--li-butter); color: var(--li-ink); border-color: var(--li-ink);
}

/* ---------- Header ---------- */
.li-head {
  position: fixed; top: var(--li-topbar-h); left: 0; right: 0; z-index: 1000;
  min-height: 84px;
  display: flex; align-items: center; justify-content: space-between; gap: 1.5rem;
  padding: 0 clamp(1.2rem, 4vw, 3rem);
  /* QA-2 · Safari fallback FIRST. On WebKit below 16.2 the color-mix()
     declaration is dropped wholesale, which would leave 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: calc(var(--wp-admin--admin-bar--height, 32px) + var(--li-topbar-h)); }
body.admin-bar .li-topbar { top: var(--wp-admin--admin-bar--height, 32px); }

/* ---------- Announcement top-bar ---------- */
.li-topbar {
  position: fixed; top: 0; left: 0; right: 0;
  z-index: 1001;
  height: var(--li-topbar-h);
  display: flex; align-items: center; justify-content: center;
  background: var(--li-chartreuse);
  color: var(--li-ink);
  font-family: var(--li-sans);
  font-size: .8rem;
  font-weight: 600;
  letter-spacing: .02em;
  text-transform: uppercase;
  overflow: hidden;
}
.li-topbar__msg {
  position: absolute;
  opacity: 0;
  transition: opacity .6s ease;
  margin: 0;
  /* QA-2 · was `white-space: nowrap` inside `overflow:hidden` — 69 of 192
     sweep rows clipped, every page at 320/375/390, and the Reading Room
     tease (the longer line) was the one cut mid-sentence. It now wraps,
     and the bar grows to two lines at phone widths (see the media query). */
  left: 0; right: 0; padding: 0 .9rem; text-align: center;
  white-space: normal; line-height: 1.15; text-wrap: balance;
}
.li-topbar__msg--active { opacity: 1; }
.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;
}
.li-head__logo .li-mark { color: var(--li-chartreuse); display: inline-block; margin: 0 .08em; font-size: .8em; font-style: normal; }
/* Real logo lockup (v1.6.5) — Meg's inline SVG mark replaces the text wordmark.
   Header + footer both sit on dark grounds, so both use the Light (cream +
   lavender) colourway. Inlined SVG (not a URL) so it survives the /li
   subdirectory dev install with no path resolution. */
.li-head__brand { display: inline-flex; align-items: center; line-height: 0; }
.li-brand-svg { display: block; width: auto; }
.li-head__brand .li-brand-svg { height: 52px; }
.li-head__brand:hover .li-brand-svg { transform: rotate(-1.5deg); transition: transform .3s var(--li-pop); }
@media (max-width: 600px) { .li-head__brand .li-brand-svg { height: 40px; } }
.li-foot__brand { display: inline-block; line-height: 0; margin-bottom: .2rem; }
.li-foot__brand .li-brand-svg { height: 56px; }
/* Core navigation block inside header — E2-B: the real menu, with a submenu.
   The starter CSS had never seen a real dropdown; everything from
   .li-nav down is the E2-B nav pass. */
.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 .li-nav { gap: clamp(.9rem, 1.7vw, 1.6rem); }
.li-head .li-nav .wp-block-navigation-item__label { white-space: nowrap; }

/* animated chartreuse underline on every top-level item */
.li-head .li-nav > .wp-block-navigation-item > a .wp-block-navigation-item__label::after,
.li-head .li-nav > .wp-block-navigation-item > .wp-block-navigation-submenu__toggle .wp-block-navigation-item__label::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -5px; height: 2px;
  background: var(--li-chartreuse); border-radius: 2px;
  transform: scaleX(0); transform-origin: right center;
  transition: transform .32s var(--li-pop);
}
.li-head .li-nav > .wp-block-navigation-item:hover .wp-block-navigation-item__label::after,
.li-head .li-nav > .wp-block-navigation-item:focus-within .wp-block-navigation-item__label::after,
.li-head .li-nav > .wp-block-navigation-item.current-menu-item .wp-block-navigation-item__label::after {
  transform: scaleX(1); transform-origin: left center;
}
.li-head .li-nav .wp-block-navigation-item__label { position: relative; display: inline-block; }

/* submenu — drops in with a settle, staggered items */
.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: 268px;
  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);
  height: auto; width: auto; overflow: visible; visibility: visible;
}
.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; }
.li-head .wp-block-navigation__submenu-container > .wp-block-navigation-item:nth-child(7) { transition-delay: .22s; }

/* mobile overlay.
   GOTCHA (found E2-B): .li-head carries backdrop-filter, and a backdrop-filter
   makes the element a CONTAINING BLOCK for position:fixed descendants — which
   clipped the whole overlay to the 84px header and left 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;
  opacity: 1 !important; visibility: visible !important;
}
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; }
.li-head .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container > .wp-block-navigation-item:nth-child(8) { animation-delay: .40s; }
@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: baseline; 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; }

.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);
  /* Meg review 2026-07-22: handwritten notes centre by default (were sitting
     awkwardly left in section flow). Block + auto margins centre the rotated
     note regardless of the parent's text-align. A `.li-note--left` opt-out
     is available for any spot we deliberately want it in the left margin. */
  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; }
/* Chartreuse-highlighted note. Meg asked for "Remember Google+? Precisely."
   in chartreuse; that note sits on a lavender band, where chartreuse text
   measures roughly 1.3:1 against the background — well under the 4.5:1 this
   build has been holding marginalia to. The colour lands as a marker-pen
   swash behind the ink instead, which is the same device `.li-pull mark`
   already uses, so it reads as brand rather than as a one-off. */
.li-note--mark { position: relative; z-index: 1; }
.li-note--mark::before {
  content: ""; position: absolute; z-index: -1;
  left: -.35em; right: -.35em; top: .12em; bottom: .06em;
  background: var(--li-chartreuse); border-radius: 3px;
  transform: rotate(-1.4deg);
}
.has-forest-background-color .li-note, .has-forest-deep-background-color .li-note, .li-note--light { color: var(--li-lavender); }

.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: 1.6rem auto 0;
  font-size: clamp(.92rem, 1.4vw, 1.08rem); 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; }

/* In-hero section nav (ARC page, 2026-08-06). Small jump-pills on the dark hero
   so a long page has a way in; Meg: "a menu in the hero, so you can navigate to
   the section that matters". Targets carry scroll-margin so the sticky header
   never lands on top of the section. */
.li-pagenav {
  display: flex; flex-wrap: wrap; justify-content: center; align-items: center;
  gap: .5rem .6rem; margin: 2.6rem auto 0; max-width: 48rem;
}
.li-pagenav__label {
  font-size: .7rem; letter-spacing: .12em; text-transform: uppercase;
  color: rgba(245,239,223,.62); margin-right: .2rem;
}
.li-pagenav__link {
  display: inline-block; padding: .42rem .95rem; border-radius: 999px;
  border: 1.5px solid rgba(245,239,223,.32);
  font-size: .82rem; font-weight: 600; color: var(--li-cream); text-decoration: none;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.li-pagenav__link:hover, .li-pagenav__link:focus-visible {
  background: var(--li-chartreuse); color: var(--li-ink); border-color: var(--li-chartreuse);
}
.li-section[id] { scroll-margin-top: calc(var(--li-head-h) + 1.5rem); }
@media (max-width: 600px) {
  .li-pagenav { gap: .45rem; }
  .li-pagenav__label { flex-basis: 100%; text-align: center; margin: 0 0 .1rem; }
}

/* squiggle underline under the <em> in a hero H1 (drawn in by JS)

   ⚠ HEIGHT IS PINNED IN `em`, NOT `auto`. DO NOT REVERT IT TO `auto`.
   2026-07-29, dev-final session 3. With `height: auto` the SVG kept its
   320×28 viewBox ratio, so its height — and therefore the apparent thickness
   of the stroke — scaled with the WIDTH OF THE `<em>`. The longer the phrase,
   the taller and heavier the "underline", anchored at the bottom so all the
   extra height grew UPWARD into the heading. Measured on dev v1.16.0 @1280:

     Author Websites  "use."                      116px em → 10.5px tall, 2.3px stroke
     Social Media     "be writing."               242px em → 22px tall,   4.7px stroke
     KDP     "at the point of purchase."          701px em → 64px tall,  13.7px stroke
     Newsletter                                   718px em → 65px tall,  14px stroke

   A 6× spread in stroke weight across the site, from nothing but character
   count. On the four wide-`em` pages (KDP, Newsletter, Brand Assets, Contact)
   the SVG covered 0.86–0.89 of the whole text line and read as a STRIKETHROUGH
   through the H1 rather than an underline beneath it.

   Pinning the height in `em` makes it scale with FONT SIZE, which is what it
   should always have tracked, and `preserveAspectRatio="none"` (set on the
   markup in li-motion.js) lets a long phrase stretch the wave horizontally
   instead of inflating it. `.3em` reproduces the Social Media hero, which was
   the best-looking of the set. The draw-in animation is unaffected: its
   `stroke-dasharray` is in user units, which non-uniform scaling does not
   change. */
.li-squiggle-wrap { position: relative; display: inline-block; }
.li-squiggle-svg { position: absolute; left: -2%; right: -4%; bottom: -.12em; width: 104%; height: .3em; 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; }
.li-shape--loop { width: 130px; top: 33%; left: 14%; }
.li-shape--loop path { fill: none; stroke: rgba(245,239,223,.3); 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 hero badge — REMOVED 2026-08-02 (S1), Meg's instruction. The
   `.li-badge` rules and their JS injection are both gone; see li-motion.js
   decorateHero(). `li-spin` is kept because .li-rotor still uses it if that
   component is ever re-used, but no rotor is currently emitted anywhere. */
@keyframes li-spin { to { transform: rotate(360deg); } }

/* ---------- Marquee ---------- */
.li-marquee {
  overflow: hidden; padding: 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--tilt { transform: rotate(-1.2deg) scale(1.02); }
/* E2-B mobile audit: the tilt's rotated bounding box pushed the document 5px
   wider than the viewport at 390px. `overflow-x: clip` on the site wrapper is
   the systematic cure for every rotated/tilted band (present and future) —
   and unlike `hidden` it does NOT create a scroll container, so the fixed
   header and any position:sticky keep working. */
.wp-site-blocks { overflow-x: clip; }
.li-marquee--lavender { background: var(--li-lavender); color: var(--li-ink); }
.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;
}
.li-marquee p { overflow: hidden; text-overflow: ellipsis; }
.li-marquee__track { display: inline-flex; animation: li-marquee 28s linear infinite; }
.li-marquee__track span { padding-right: .5ch; }
.li-marquee--reverse .li-marquee__track { animation-direction: reverse; }
@keyframes li-marquee { to { transform: translateX(-50%); } }

/* ---------- Sections ---------- */
.li-section { padding: clamp(5rem, 10vw, 9rem) clamp(1.2rem, 5vw, 4rem); }
.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; }
.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); }

/* Section edge treatments.
   The zigzag is cut out of the section's own top edge with a mask: teeth are
   a fixed 28x14px at every viewport width, and whatever sits above the
   section (cream, forest, an image) shows through the notches — no painted
   colour band to mismatch the neighbouring section. */
/* The mask-cut sawtooth zigzag was messy and did not overlap cleanly
   (Meg 2026-08-24: "looks messy, doesn't overlap properly, replace it").
   Neutralised to a clean band transition: the section keeps its own straight
   top edge and meets the band above with a clean colour change, which is how
   the rest of the site already transitions. If a specific divider device is
   wanted here, it gets built to spec rather than the sawtooth. */
.li-zigzag { position: relative; }
.li-zigzag::before { content: none; }
.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; }
}

/* A SECOND SAMPLE IN A PROOF BAND (S2, 2026-08-02) — the subordinate button.
   Digital Strategy carries two: the positioning sample and the brand audit.
   Naming a different button STYLE for the second one does nothing, because the
   "CTA CONTRAST BY SURFACE" block above deliberately collapses chartreuse,
   lavender and butter into one dark pill on light surfaces — measured, both
   buttons came out identical at 11.51:1. So the distinction is made here, on
   position, and the first button keeps the solid pill untouched.
   Outline rather than a paler fill: an outline is unambiguously secondary and
   still hits AA on the band it sits on, where a pale fill would be one more
   colour decision to keep in sync with the surface allowlist. */
.li-exdoc__dl .wp-block-button:not(:first-child) .wp-block-button__link {
  background: transparent;
  color: var(--li-forest);
  border: 2px solid var(--li-forest);
  box-shadow: none;
}
.li-exdoc__dl .wp-block-button:not(:first-child) .wp-block-button__link:hover {
  background: var(--li-forest); color: var(--li-cream);
  box-shadow: 4px 4px 0 var(--li-ink);
}
:is(.has-forest-background-color, .has-forest-deep-background-color)
.li-exdoc__dl .wp-block-button:not(:first-child) .wp-block-button__link {
  color: var(--li-cream); border-color: var(--li-cream);
}

/* The ARC process grid (S2, 2026-08-02) — seven steps in a four-column grid.
   The Starter Kit's Chapter 05, which Meg named as the model, has exactly five
   phases and fills its row. Seven does not, so the last card spans the empty
   track: four across, then three with the closing step running wide. That reads
   as the payoff it is ("Release day celebration") instead of as a grid with a
   cell missing, which is what a ragged trailing row looks like.
   Only at the 4-across size — at 2 columns the span makes it full width, which
   is still deliberate, and at 1 column there is nothing to span. */
.li-arcsteps > .li-step:last-child { grid-column: span 2; }
@media (max-width: 640px) {
  .li-arcsteps > .li-step:last-child { grid-column: auto; }
}

/* 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); }

/* ---------- Inline links on dark bands (dev-final-session-8) --------------
 * theme.json sets elements.link to `ink` (#1e2019) with textDecoration:none.
 * On forest (#1d3527) that computes to about 1.05:1 — invisible — and with the
 * underline off there is no affordance either. The CARD variants were fixed
 * above; the SECTION-level case never was, so every inline prose link inside a
 * forest band inherited ink. Meg found it on the SmarterQueue link on Social,
 * but it hit Home, Services, Blog, KDP and the ARC Starter Kit the same way.
 * Chartreuse on forest is 8.3:1, on forest-deep 10.0:1. Buttons are excluded —
 * they carry their own background and were already legible.
 */
.has-forest-background-color a:not(.wp-block-button__link),
.has-forest-deep-background-color a:not(.wp-block-button__link) {
  color: var(--li-chartreuse);
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}
.has-forest-background-color a:not(.wp-block-button__link):hover,
.has-forest-deep-background-color a:not(.wp-block-button__link):hover {
  color: var(--li-chartreuse-soft);
}
/* Cards keep the border-bottom treatment they already had. */
.has-forest-background-color .li-card a,
.has-forest-deep-background-color .li-card a {
  text-decoration: none;
  border-bottom: 2px solid 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: 8px 10px 0 rgba(30,32,25,.16); }
.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: .92rem; 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.5rem !important; color: var(--li-lavender-deep);
  font-weight: 700;
  transform: rotate(2deg);
  background: var(--li-cream); padding: .1rem .6rem;
  border-bottom: 2px solid var(--li-lavender);
}
@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; }
/* Centered variant. Meg flagged the KDP "Both are decisions, not guesses"
   line as reading oddly hanging right — it is a summing-up statement, not a
   marginal aside, so it sits centered. */
.li-pull--center { text-align: center; margin-inline: auto; max-width: 34ch; }
/* 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); }
/* --- S3·11 · THE PULL-QUOTE HIGHLIGHTER (2026-08-02) --------
   Meg, on KDP Chapter 04: "'both are decisions': highlighter animation not
   firing properly — fix."

   The observer WAS firing. Measured on live dev after scrolling the page the
   way a reader does: `.li-inview` lands on the element and the transform
   reaches scaleX(1), so the trigger, the class and the transition were all
   working — which is why this survived being looked at.

   The bug is the geometry. The highlight was an absolutely-positioned
   `::before` on an INLINE `<mark>`, and in a 2.7rem Fraunces pull quote the
   marked phrase always wraps. For a relatively-positioned inline that spans
   more than one line, the containing block a browser gives an absolute child is
   its FIRST fragment — so the bar measured 26px wide and 97px tall: a vertical
   chartreuse sliver beside the text instead of a highlighter across it. On a
   phrase that happens not to wrap it looked fine, which is the other half of
   why it was never caught.

   The fix is to stop faking a highlighter with a box and let the mark carry its
   own background, with `box-decoration-break: clone` so every line fragment
   gets its own bar — which is what a real highlighter does across wrapped text.
   `background-size` animates, so the sweep survives intact.

   COST, stated: the -1deg marker tilt is gone from this device. Inline elements
   cannot be transformed, and a tilted bar across three wrapped lines never read
   as one stroke anyway. `.li-note--mark` keeps its tilt — those notes are one
   line by construction. */
.li-pull mark {
  position: relative; z-index: 1; padding: 0 .12em; color: inherit;
  background-color: transparent;
  background-image: linear-gradient(var(--li-chartreuse), var(--li-chartreuse));
  background-repeat: no-repeat;
  background-position: 0 .58em;
  background-size: 100% .72em;
  border-radius: .12em;
  -webkit-box-decoration-break: clone;
          box-decoration-break: clone;
}
body.li-js .li-pull:not(.li-inview) mark { background-size: 0 .72em; }
.li-pull.li-inview mark { background-size: 100% .72em; transition: background-size .8s cubic-bezier(.7,0,.2,1) .15s; }

/* ---------- 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: .7; 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: 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: .55; 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: was .38 = 2.28:1. Now 5.69:1 on cream. */
  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); }

/* ---------- STAGE 4 · Pricing cards + "i" detail (ONE reusable component) ----------
   Used on every service page's pricing block AND the packages block. A short
   pointed summary + price + one aligned button sit on the face; the full service
   description lives behind a small "i". The "i" is a native <details>/<summary>,
   so the detail is reachable with JS off (the li-pcard JS only adds
   one-open-at-a-time + outside-click/Escape close). Buttons align across the row
   because each card is a flex column with the CTA pinned to the bottom. */
.li-pcards { display: grid; gap: 1.2rem; align-items: stretch; }
/* One card, centred and capped — so a single offer uses the SAME component
   as every tier row rather than a page-local card. S1, 2026-08-02. */
.li-pcards--1 { grid-template-columns: minmax(0, 460px); justify-content: center; }
.li-pcards--2 { grid-template-columns: repeat(2, 1fr); }
.li-pcards--3 { grid-template-columns: repeat(3, 1fr); }
.li-pcards--4 { grid-template-columns: repeat(4, 1fr); }
.li-pcard {
  position: relative; 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: .3rem; color: var(--li-ink);
  transition: box-shadow .3s ease, transform .3s var(--li-pop);
}
.li-pcard:hover { box-shadow: 8px 10px 0 rgba(30,32,25,.16); transform: translateY(-4px); }
.li-pcard__tag { width: fit-content; font-weight: 800; font-size: .64rem; letter-spacing: .18em; text-transform: uppercase; color: var(--li-lavender-deep); margin: 0 0 .1rem; }
.li-pcard__title { font-family: var(--li-display); font-weight: 600; font-size: 1.4rem; line-height: 1.05; margin: 0; padding-right: 2.6rem; }
.li-pcard__price { font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 580; font-size: clamp(2.4rem, 3.6vw, 3.1rem); color: var(--li-forest); margin: .4rem 0 0; line-height: .92; letter-spacing: -.02em; }
.li-pcard__note { font-weight: 700; font-size: .72rem; opacity: .55; margin: .2rem 0 0; text-transform: uppercase; letter-spacing: .05em; }
.li-pcard__sum { font-family: var(--li-display); font-style: italic; font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 460; font-size: .95rem; opacity: .82; margin: .7rem 0 0; line-height: 1.34; }
.li-pcard__cta { margin-top: auto; padding-top: 1.2rem; }
.li-pcard__btn {
  /* box-sizing is the whole fix for "the buttons are overlapping".
     width:100% + 1rem of horizontal padding + a 2px border on a
     content-box element computes 12px WIDER than the card, so every
     card CTA on every service page hung over its own right edge.
     Measured on dev v1.10.2 at 1280: overflowR = +12 on all four
     Website Design cards; with border-box it becomes -24, i.e.
     correctly inset by the card's padding. */
  box-sizing: border-box;
  display: block; width: 100%; text-align: center; text-decoration: none;
  font-family: var(--li-sans); font-weight: 700; font-size: .95rem;
  padding: .8rem 1rem; border-radius: 999px; border: 2px solid var(--li-ink);
  background: var(--li-chartreuse); color: var(--li-ink);
  transition: transform .25s var(--li-pop), box-shadow .25s ease, background-color .25s ease;
}
.li-pcard__btn:hover { box-shadow: 4px 4px 0 var(--li-ink); background: var(--li-chartreuse-soft); }

/* The theme carries no global border-box reset, so every LI component that
   combines `width:100%` with its own padding and 2px border has the same
   overflow bug the pricing-card CTA had. These are the other instances:
   full-width buttons inside a fixed-width parent. Scoped deliberately
   rather than reset globally — a `*` reset would also move WP core block
   layouts that were built and measured against content-box. */
.li-pkg .wp-block-button__link,
.li-linkstack .wp-block-button__link,
.li-tool__logo { box-sizing: border-box; }

/* The "i" — a styled <summary>. Focusable, keyboard-operable, native JS-off. */
.li-pcard__more { position: static; }
.li-pcard__i {
  position: absolute; top: 1.25rem; right: 1.25rem; z-index: 3;
  list-style: none; cursor: pointer;
  width: 30px; height: 30px; display: grid; place-items: center;
  border: 2px solid var(--li-ink); border-radius: 50%;
  font-family: var(--li-display); font-style: italic; font-weight: 600; font-size: 1.02rem; line-height: 1;
  background: var(--li-cream); color: var(--li-ink);
  transition: background-color .2s ease, transform .2s var(--li-pop);
}
.li-pcard__i::-webkit-details-marker { display: none; }
.li-pcard__i:hover { background: var(--li-lavender); transform: rotate(-6deg); }
.li-pcard__more[open] .li-pcard__i { background: var(--li-lavender-deep); color: var(--li-cream); }
.li-pcard__panel {
  position: absolute; top: 3.5rem; right: 1rem; left: 1rem; z-index: 6;
  background: var(--li-ink); color: var(--li-cream);
  border-radius: 16px; padding: 1.1rem 1.2rem 1.2rem;
  box-shadow: 6px 8px 0 rgba(30,32,25,.28);
  animation: li-pcard-pop .28s var(--li-pop) backwards;
}
@keyframes li-pcard-pop { from { opacity: 0; transform: translateY(-8px) scale(.98); } }
.li-pcard__panel::before {
  content: ""; position: absolute; top: -8px; right: 1.05rem;
  border: 8px solid transparent; border-top: 0; border-bottom: 8px solid var(--li-ink);
}
.li-pcard__paneltitle { font-family: var(--li-sans); font-weight: 800; font-size: .62rem; letter-spacing: .18em; text-transform: uppercase; color: var(--li-chartreuse); margin: 0 0 .55rem; }
.li-pcard__panel p { font-size: .9rem; line-height: 1.42; margin: 0 0 .5rem; color: rgba(245,239,223,.92); }
.li-pcard__panel ul { list-style: none; margin: .4rem 0 0; padding: .6rem 0 0; border-top: 1px solid rgba(245,239,223,.2); display: grid; gap: .35rem; }
.li-pcard__panel li { position: relative; padding-left: 1.2rem; font-size: .86rem; line-height: 1.3; }
.li-pcard__panel li::before { content: "\2726"; position: absolute; left: 0; color: var(--li-chartreuse); }

/* Featured card — persistent traits (bg, accent, hard shadow, flag), never a
   resting transform (the reveal animation would clobber it). */
.li-pcard--feature { background: var(--li-forest); color: var(--li-cream); box-shadow: 10px 12px 0 var(--li-chartreuse); z-index: 2; }
.li-pcard--feature:hover { box-shadow: 13px 15px 0 var(--li-chartreuse); transform: translateY(-4px); }
.li-pcard--feature .li-pcard__title { color: var(--li-cream); }
.li-pcard--feature .li-pcard__tag { color: var(--li-chartreuse); }
.li-pcard--feature .li-pcard__price { color: var(--li-chartreuse); }
.li-pcard--feature .li-pcard__note { color: rgba(245,239,223,.7); opacity: 1; }
.li-pcard--feature .li-pcard__sum { color: rgba(245,239,223,.9); opacity: 1; }
.li-pcard--feature .li-pcard__i { background: var(--li-chartreuse); border-color: var(--li-chartreuse); color: var(--li-ink); }
.li-pcard--feature .li-pcard__more[open] .li-pcard__i { background: var(--li-cream); border-color: var(--li-cream); }
.li-pcard__flag {
  position: absolute; top: -14px; left: 16px; z-index: 4; margin: 0;
  background: var(--li-chartreuse); border: 2px solid var(--li-ink); color: var(--li-ink);
  font-family: var(--li-sans); font-weight: 800; font-size: .7rem; letter-spacing: .08em; text-transform: uppercase;
  padding: .3rem .8rem; border-radius: 999px; transform: rotate(-3deg);
}
@media (max-width: 900px) { .li-pcards--4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 760px) { .li-pcards--1, .li-pcards--2, .li-pcards--3, .li-pcards--4 { grid-template-columns: 1fr; } }

/* ---------- STAGE 4 · Main Pricing page — the menu ----------
   Jump-to-section links by need, then each service as a scannable row that
   expands (native <details>) to a short description, plus one button to the
   service's dedicated page. Everything is reachable with JS off. */
.li-pmenu__jump { display: flex; flex-wrap: wrap; gap: .5rem; justify-content: center; margin: 0 auto 3rem; max-width: 940px; }
.li-pmenu__jump a { font-family: var(--li-sans); font-weight: 700; font-size: .8rem; letter-spacing: .01em; text-decoration: none; color: var(--li-ink); background: var(--li-cream); border: 2px solid var(--li-ink); border-radius: 999px; padding: .5rem 1rem; transition: background-color .2s ease, transform .2s var(--li-pop); }
.li-pmenu__jump a:hover { background: var(--li-chartreuse); transform: translateY(-2px); }
.li-pmenu__sec { scroll-margin-top: 110px; margin: 0 auto 3.4rem; max-width: 1000px; }
.li-pmenu__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: .5rem 1.2rem; margin-bottom: 1.1rem; padding-bottom: .85rem; border-bottom: 2px solid var(--li-ink); }
.li-pmenu__head h3 { font-family: var(--li-display); font-size: clamp(1.6rem, 3vw, 2.1rem); margin: 0; }
.li-pmenu__blurb { flex: 1 1 240px; font-family: var(--li-display); font-style: italic; font-variation-settings: "SOFT" 100, "WONK" 1; font-size: 1rem; opacity: .82; margin: 0; }
.li-pmenu__see { flex: none; font-family: var(--li-sans); font-weight: 700; font-size: .82rem; text-decoration: none; color: var(--li-ink); border-bottom: 2px solid var(--li-lavender-deep); white-space: nowrap; transition: color .2s ease; }
.li-pmenu__see:hover { color: var(--li-lavender-deep); }
.li-pmenu__rows { display: grid; gap: .3rem; }
.li-pmenu__row { border-bottom: 1px solid rgba(30,32,25,.16); }
.li-pmenu__row > summary { list-style: none; cursor: pointer; display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; padding: .9rem .2rem; }
.li-pmenu__row > summary::-webkit-details-marker { display: none; }
.li-pmenu__name { font-family: var(--li-sans); font-weight: 600; font-size: 1.02rem; display: flex; align-items: baseline; gap: .55rem; }
.li-pmenu__name::before { content: "+"; font-weight: 700; color: var(--li-lavender-deep); width: 1ch; flex: none; }
.li-pmenu__row[open] .li-pmenu__name::before { content: "\2013"; }
.li-pmenu__price { font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 580; font-size: 1.5rem; color: var(--li-forest); white-space: nowrap; }
.li-pmenu__detail { padding: 0 0 1.1rem 1.55ch; }
.li-pmenu__detail p { font-size: .92rem; line-height: 1.45; opacity: .9; margin: 0 0 .5rem; max-width: 70ch; }
.li-pmenu__detail ul { list-style: none; margin: .3rem 0 0; padding: 0; display: grid; gap: .3rem; }
.li-pmenu__detail li { position: relative; padding-left: 1.2rem; font-size: .88rem; }
.li-pmenu__detail li::before { content: "\2726"; position: absolute; left: 0; color: var(--li-lavender-deep); }
@media (max-width: 560px) {
  .li-pmenu__head { flex-direction: column; align-items: flex-start; }
  .li-pmenu__price { font-size: 1.2rem; }
}
/* Jump-link target on the packages block clears the sticky header. */
#packages { scroll-margin-top: 110px; }
.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);
  /* An SVG carrying only a viewBox has NO intrinsic size, so a browser gives
     it the CSS default 300x150 replaced-element box or, inside a flex/grid
     parent, collapses it to nothing. arckit-file-map.svg rendered at 4x4px on
     the live ARC Starter Kit page, at every width, because of exactly this.
     All 16 theme SVGs now declare width and height (2026-08-04), which is the
     real fix; this is the belt-and-braces so the next one added without them
     scales instead of vanishing. */
  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; }
/* Transparent-PNG mockups in a tape frame: no rectangular border (it draws a
   box around the transparent bounding rectangle — the black border Meg flagged
   on the Joy Adare cover reveal, 2026-08-07). Drop-shadow instead, like the
   example-doc shots. */
.li-imgframe--nb img { border: 0 !important; box-shadow: none !important; border-radius: 0 !important; filter: drop-shadow(8px 12px 16px rgba(30,32,25,.18)); }
.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: var(--li-tape); border: var(--li-tape-edge); 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. */
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 v1.25.0 (Meg, 2026-08-04) ----------
   Deleted with its JS in li-motion.js. Do not reinstate. */

/* ---------- 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: .64rem !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; }
/* Slim fine-print band for the standing affiliate notice at the bottom of any
   page that links to a tool page (li_affiliate_note_markup). Deliberately NOT
   .li-section: this is fine print and must not carry a section's rhythm. The
   max-width override centres it, since .li-disclosure is 60ch left-aligned by
   default on the affiliate pages where it sits inside body copy. */
.li-affnote { padding: 2.2rem clamp(1.2rem, 5vw, 4rem) 2.6rem; }
.li-affnote .li-disclosure { max-width: 68ch; margin-left: auto; margin-right: auto; text-align: center; }
.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; }

/* ---------- Deliverables showcase (Look inside) ---------- */
/* Class-driven + edit-safe: with JS off every panel and every page-image shows,
   stacked. li-motion.js enhances it into a tabbed, paged viewer. */
.li-showcase__tabs { display: flex; flex-wrap: wrap; gap: .7rem; justify-content: center; margin: 1.8rem 0 1.4rem !important; }
.li-showcase__tab {
  font-family: var(--li-sans); font-weight: 800; font-size: .82rem; letter-spacing: .04em;
  padding: .6rem 1.15rem; border: 2px solid var(--li-ink); border-radius: 999px;
  background: var(--li-paper); color: var(--li-ink); cursor: pointer; margin: 0 !important;
  transition: background-color .2s, color .2s, transform .2s var(--li-pop), box-shadow .2s;
}
body.li-js .li-showcase__tab:hover { transform: translateY(-2px); box-shadow: 3px 3px 0 var(--li-ink); }
.li-showcase__tab.is-active { background: var(--li-chartreuse); box-shadow: 3px 3px 0 var(--li-ink); }
.li-showcase__panel { margin-top: 1.4rem; }
.li-showcase__meta { text-align: center; max-width: 640px; margin: 0 auto 1.4rem; }
.li-showcase__meta h3 { margin: 0 0 .4rem; }
.li-showcase__kind { font-family: var(--li-hand); font-size: 1.25rem; color: var(--li-lavender-deep); display: block; margin-bottom: .2rem; }
.li-showcase__desc { color: #4f4c40; margin: 0 0 1rem !important; }
.li-showcase__stage { position: relative; }
.li-showcase__pages { display: flex; flex-direction: column; gap: 1.6rem; align-items: center; }
.li-showcase__pages .wp-block-image { margin: 0; width: 100%; max-width: 760px; }
.li-showcase__pages .wp-block-image img,
.li-showcase__pages img {
  width: 100%; height: auto; display: block; border-radius: 14px;
  border: 2.5px solid var(--li-ink); box-shadow: 7px 7px 0 var(--li-ink);
}
.li-showcase__pages .wp-block-image:nth-child(odd) { transform: rotate(-1deg); }
.li-showcase__pages .wp-block-image:nth-child(even) { transform: rotate(1deg); }
/* JS-enhanced: one panel + one page at a time */
body.li-js .li-showcase__panel { display: none; }
body.li-js .li-showcase__panel.is-active { display: block; }
body.li-js .li-showcase__pages { flex-direction: row; justify-content: center; min-height: 60px; }
body.li-js .li-showcase__pages .wp-block-image { display: none; transform: rotate(-.6deg); }
body.li-js .li-showcase__pages .wp-block-image.is-current { display: block; }
.li-showcase__nav { display: none; margin-top: 1.3rem; align-items: center; justify-content: center; gap: 1.1rem; }
body.li-js .li-showcase__nav { display: flex; }
.li-showcase__arrow {
  font-family: var(--li-sans); font-weight: 800; font-size: 1.1rem; line-height: 1;
  width: 3rem; height: 3rem; border-radius: 50%; border: 2px solid var(--li-ink);
  background: var(--li-cream); color: var(--li-ink); cursor: pointer;
  transition: transform .2s var(--li-pop), box-shadow .2s, background-color .2s;
}
.li-showcase__arrow:hover { transform: translateY(-2px); box-shadow: 3px 3px 0 var(--li-ink); background: var(--li-chartreuse); }
.li-showcase__arrow[disabled] { opacity: .35; cursor: default; box-shadow: none; transform: none; }
.li-showcase__count { font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; font-size: 1.15rem; min-width: 5.5rem; text-align: center; }
.li-showcase__dl { margin-top: 1.4rem !important; text-align: center; }
@media (max-width: 640px) {
  .li-showcase__pages .wp-block-image img, .li-showcase__pages img { box-shadow: 4px 4px 0 var(--li-ink); }
  .li-showcase__tab { font-size: .74rem; padding: .5rem .85rem; }
}

/* ==========================================================
   TEXTURE PASS (Session E, item 8)
   The flat-green-band cure. Break the dead-flat fill on large solid bands
   with an off-axis radial tint (warm chartreuse top-right, cool lavender
   bottom-left) and float an oversized ghost mark behind the closing CTA.
   Everything here is additive, CSS/SVG only, no image weight, reduced-motion
   safe — content is never obscured.
   ========================================================== */
.li-section.has-forest-background-color,
.li-section.has-forest-deep-background-color {
  background-image:
    radial-gradient(130% 90% at 82% -10%, rgba(201,214,79,.075), 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(201,214,79,.10), transparent 55%),
    radial-gradient(82% 72% at 5% 110%, rgba(107,84,184,.20), transparent 55%);
}
/* Ghost chapter mark behind the closing CTA (biggest single flat expanse). */
.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(226,234,156,.055);
}
/* A quieter ghost mark on plain coloured sections that carry a chapter device,
   so the mid-page bands read as composed pages, not stacked boxes. */
.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(226,234,156,.05); }

/* ==========================================================
   WEBSITE PORTFOLIO BAND (Session E, item 1) — real screenshots in
   browser-frame mockups: hover tilt, click-through, platform chip.
   ========================================================== */
.li-portfolio { display: grid; grid-template-columns: repeat(2, 1fr); gap: clamp(1.8rem, 4vw, 3rem); margin-top: 2.6rem; }
@media (max-width: 720px) { .li-portfolio { grid-template-columns: 1fr; gap: 2.2rem; } }
.li-portfolio__item { margin: 0; }
.li-browser {
  position: relative; padding-top: 34px; overflow: hidden;
  border: 2px solid var(--li-ink); border-radius: 15px; background: var(--li-paper);
  box-shadow: 8px 10px 0 rgba(30,32,25,.16);
  transition: transform .35s var(--li-pop), box-shadow .35s ease;
}
.li-browser::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 34px;
  background: var(--li-cream-deep); border-bottom: 2px solid var(--li-ink);
}
.li-browser::after {
  content: ""; position: absolute; top: 13px; left: 15px; width: 8px; height: 8px; border-radius: 50%;
  background: #e2685f; box-shadow: 15px 0 0 #e8b24d, 30px 0 0 #7cbf6a;
}
.li-portfolio__item:nth-child(odd) .li-browser { transform: rotate(-1.1deg); }
.li-portfolio__item:nth-child(even) .li-browser { transform: rotate(1.1deg); }
.li-browser:hover { transform: rotate(0) translateY(-6px); box-shadow: 13px 15px 0 var(--li-forest); }
.li-browser__shot { margin: 0; }
.li-browser__shot a { display: block; }
/* E2-B — full-page captures pan top->bottom on hover.
   The frame clips to a fixed window and the image slides by its own height
   minus that window: translateY(calc(-100% + <frame height>)). The `%` resolves
   against the IMAGE's height, so one rule pans every capture correctly no
   matter how tall it is — no per-image maths, no JS.
   (Tried object-position first: this engine jumps it rather than interpolating,
   so the pan never animated. transform is the reliable, GPU-accelerated route.)
   prefers-reduced-motion freezes it at the top via the global duration override. */
.li-browser__shot {
  height: var(--li-browser-h, 300px); overflow: hidden;
}
.li-browser__shot img {
  display: block; width: 100%; height: auto;
  border: 0; border-radius: 0; box-shadow: none;
  transform: translateY(0); will-change: transform;
  transition: transform 6s cubic-bezier(.33,.02,.28,1);
}
.li-browser:hover .li-browser__shot img,
.li-browser:focus-within .li-browser__shot img {
  transform: translateY(calc(-100% + var(--li-browser-h, 300px)));
}
@media (max-width: 720px) { .li-browser { --li-browser-h: 240px; } }
.li-portfolio__meta { margin-top: 1rem; align-items: baseline; gap: .7rem; }
.li-portfolio__site { font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 540; font-size: 1.18rem !important; margin: 0 !important; }
.li-portfolio__plat {
  margin: 0 !important; font-family: var(--li-sans); font-weight: 800; font-size: .72rem !important; /* QA-2: was .62rem = 9.9px */
  letter-spacing: .12em; text-transform: uppercase; color: var(--li-forest);
  border: 1.5px solid var(--li-forest); border-radius: 999px; padding: .3rem .75rem;
}
.li-portfolio__more { text-align: center; margin: 2.8rem auto 0; max-width: 56ch; font-size: 1.06rem; opacity: .9; }

/* ==========================================================
   CLIENT LOGO MARQUEE (Session E, item 2) — two rows of real client
   wordmarks, opposite directions, pure-CSS scroll (no JS dependency).
   ========================================================== */
.li-logos { text-align: center; overflow: hidden; }
.li-logos__label { margin: 0 auto 1.6rem !important; }
/* v1.25.0 (Meg, 2026-08-04): logo band is the two marquee rows and nothing
   else, matching the current live site. No label, so the section padding that
   was sized to sit under a heading is roughly halved top and bottom. Overrides
   .li-section--tight, which is why it needs the extra specificity. */
.li-logos.li-logos--bare { padding-top: clamp(2rem, 3.5vw, 2.8rem); padding-bottom: clamp(2rem, 3.5vw, 2.8rem); }
.li-logos--bare .li-logomarquee + .li-logomarquee { margin-top: .9rem; }
.li-logomarquee {
  overflow: hidden; width: 100%; margin: .35rem 0;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
}
.li-logotrack { display: flex; flex-wrap: nowrap; width: max-content; align-items: center; animation: li-logoscroll 350s linear infinite; }
.li-logotrack--rev { animation-direction: reverse; }
.li-logotrack__img { margin: 0 1.6rem 0 0 !important; flex: none; }
.li-logotrack__img img { display: block; height: 60px; width: auto; max-width: none; border: 0; border-radius: 0; box-shadow: none; }
@keyframes li-logoscroll { to { transform: translateX(-50%); } }
.li-logomarquee:hover .li-logotrack { animation-play-state: paused; }
@media (max-width: 640px) { .li-logotrack__img img { height: 44px; } }

/* ==========================================================
   ARC / LAUNCH COVERS STRIP (Session E, item 3) — real client covers in
   tilt frames at a consistent 2:3, with author + genre.
   ========================================================== */
.li-covers { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(1.5rem, 3.2vw, 2.6rem); margin-top: 2.4rem; align-items: start; }
@media (max-width: 900px) { .li-covers { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 560px) { .li-covers { grid-template-columns: repeat(2, 1fr); } }
.li-cover { margin: 0; text-align: center; }
/* The whole cover card is a link to the book's Amazon listing (Meg, 2026-07-28).
   The anchor wraps the image and both captions, so the hit area is the card
   rather than just the artwork, and the lift makes it read as clickable. */
.li-cover__link { display: block; text-decoration: none; color: inherit; border-radius: var(--li-radius); transition: transform .25s var(--li-pop); }
.li-cover__link:hover { transform: translateY(-5px); }
.li-cover__link:hover .li-cover__title { text-decoration: underline; text-underline-offset: 3px; }
.li-cover__link:focus-visible { outline: 3px solid var(--li-chartreuse); outline-offset: 5px; }
@media (prefers-reduced-motion: reduce) { .li-cover__link:hover { transform: none; } }
.li-cover__img { margin: 0 auto !important; width: 100%; }
.li-cover__img img { width: 100%; height: auto; aspect-ratio: 2 / 3; object-fit: cover; }
.li-cover:nth-child(3n+1) .li-cover__img { transform: rotate(-1.6deg); }
.li-cover:nth-child(3n+2) .li-cover__img { transform: rotate(1.3deg); }
.li-cover:nth-child(3n) .li-cover__img { transform: rotate(-.6deg); }
.li-cover__img:hover { transform: rotate(0) translateY(-4px); }
.li-cover__author { font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 540; font-size: 1.02rem !important; margin: 1.05rem 0 0 !important; }
.li-cover__genre { font-family: var(--li-sans); font-weight: 700; font-size: .66rem !important; letter-spacing: .12em; text-transform: uppercase; opacity: .62; margin: .22rem 0 0 !important; }

/* ==========================================================
   E2-A · PERSONALITY PASS (v1.5.0)
   New section vocabulary, signature proof bands, motion character,
   and the tail refactor. Everything additive, class-driven, edit-safe;
   the reduced-motion block below neutralises every keyframe, and JS-driven
   drift is gated on prefers-reduced-motion in li-motion.js.
   ========================================================== */

/* ---- Tail refactor (item 6): the closing CTA and the read-more accordion
   are now first-class bands, not generic .li-section groups — so the uniform
   "section>cta>section>cta … section>readmore" tail is gone site-wide. They
   carry their own padding here and keep the forest texture. ---- */
.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(201,214,79,.075), transparent 55%),
    radial-gradient(92% 80% at 6% 112%, rgba(107,84,184,.16), transparent 55%);
}
/* Closing-CTA treatments, varied across pages. */
.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, scroll-reveal.
   Ships WITH motion (word-settle via .li-anim) and reads fine with JS off. ---- */
.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; }
/* P2 · these two were DESCENDANT-only (`.has-forest-… .li-bigtype__…`), but the
   canonical snippet in PATTERN_CONVENTIONS puts the background class ON the
   `.li-bigtype` element itself, so neither rule could ever match — the kicker
   would have rendered #5c46a8 on forest green. Compound forms added alongside;
   the descendant forms are kept in case a band ever nests one. Found when
   Contact became the first page in the theme to actually use `li-bigtype`. */
.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(226,234,156,.05); }

/* ---- Offset / overlap editorial grid: breaks the symmetric-grid rhythm.
   Two columns that stagger vertically and overlap; collapses to one on mobile. ---- */
.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), all keyframe-based so reduced-motion kills them ---- */
@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 (richer entrance for proof-band children). */
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; }

/* ==========================================================
   SIGNATURE PROOF BANDS (E2-A item 4) — one per service page,
   each at a different position, real assets baked in via helpers.
   ========================================================== */
/* Instagram grid (Social Media page). */
/* (E2-A's static 3-up .li-iggrid rules were removed in E2-B — the band is now
   a two-row marquee of 24 real client grids; its rules live in the E2-B proof
   bands section below. The old `.li-iggrid .wp-block-image img` rule outranked
   the new one on specificity and forced the tiles to 464px.) */

/* A+ content module (KDP page): the tall A+ image beside a short read. */
.li-aplus { display: grid; grid-template-columns: 0.9fr 1.1fr; gap: clamp(1.6rem, 4vw, 3.2rem); margin-top: 2.4rem; align-items: center; }
@media (max-width: 760px) { .li-aplus { grid-template-columns: 1fr; } }
.li-aplus .wp-block-image { margin: 0; }
.li-aplus .wp-block-image img { width: 100%; height: auto; display: block; border: 2px solid var(--li-ink); border-radius: 14px; box-shadow: 8px 10px 0 rgba(30,32,25,.16); }
.li-aplus__read p { max-width: 46ch; }

/* Covers Meg designed (Brand Assets page): native aspect ratios, contained. */
.li-designed { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(1.2rem, 3vw, 2.2rem); margin-top: 2.4rem; align-items: center; justify-items: center; }
@media (max-width: 720px) { .li-designed { grid-template-columns: repeat(2, 1fr); } }
.li-designed .wp-block-image { margin: 0; width: 100%; }
.li-designed .wp-block-image img { width: 100%; height: auto; max-height: 340px; object-fit: contain; display: block; border: 0; border-radius: 10px; box-shadow: 8px 10px 0 rgba(30,32,25,.14); }
.li-designed .wp-block-image { transition: transform .3s var(--li-pop); }
.li-designed .wp-block-image:nth-child(odd) { transform: rotate(-1.5deg); }
.li-designed .wp-block-image:nth-child(even) { transform: rotate(1.4deg); }
.li-designed .wp-block-image:hover { transform: rotate(0) translateY(-4px); }

/* ---------- E2-B proof bands ---------- */

/* Instagram feed grids — two opposite-scrolling rows (scale).
   Same pure-CSS track mechanism as .li-logotrack: each row's set is emitted
   twice, the track is animated -50%, so the loop is seamless with no JS. */
.li-iggrid { margin-top: 2.4rem; display: block; }
.li-igmarquee { overflow: hidden; margin: 0 0 clamp(.8rem, 2vw, 1.2rem); -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent); mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent); }
.li-igtrack { display: flex; flex-wrap: nowrap; gap: clamp(.7rem, 1.8vw, 1.1rem); width: max-content; animation: li-igscroll 78s linear infinite; will-change: transform; }
.li-igtrack--rev { animation-direction: reverse; animation-duration: 92s; }
.li-igmarquee:hover .li-igtrack { animation-play-state: paused; }
.li-igtrack__img { margin: 0 !important; flex: 0 0 auto; }
.li-igtrack__img img { display: block; width: clamp(128px, 15vw, 186px); aspect-ratio: 4 / 5; object-fit: cover; border: 2px solid var(--li-ink); border-radius: 13px; box-shadow: 4px 5px 0 rgba(30,32,25,.16); }
@keyframes li-igscroll { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* Instagram pinned-post banners — calm 3-col grid of wide 3-tile sets. */
.li-pinned { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1.2rem, 3vw, 2.1rem); margin-top: 2.4rem; }
@media (max-width: 900px) { .li-pinned { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .li-pinned { grid-template-columns: 1fr; } }
.li-pinned__item { margin: 0; }
/* §I4 (LI-P2b): the set is now three separate post tiles in a real 3-up grid
   with an Instagram-tight gutter, not one glued-together banner. The tilt moved
   from the individual shot to the SET, so the three tiles stay square to each
   other and read as a profile row rather than three loose cards. */
.li-pinned__set { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px;
  transition: transform .3s var(--li-pop); }
.li-pinned__shot { margin: 0 !important; }
.li-pinned__shot img { display: block; width: 100%; height: 100%; aspect-ratio: 3 / 4; object-fit: cover;
  border: 2px solid var(--li-ink); border-radius: 8px; box-shadow: 3px 4px 0 rgba(30,32,25,.14); }
.li-pinned__item:nth-child(3n+1) .li-pinned__set { transform: rotate(-.9deg); }
.li-pinned__item:nth-child(3n+2) .li-pinned__set { transform: rotate(.7deg); }
.li-pinned__item:hover .li-pinned__set { transform: rotate(0) translateY(-4px); }
.li-pinned__who { margin: .8rem 0 0 !important; font-size: .95rem !important; letter-spacing: .04em; text-transform: uppercase; opacity: .78; }

/* A+ content — two vertical module stacks, the shape of the real listing. */
.li-aplus { display: grid; grid-template-columns: repeat(2, 1fr); gap: clamp(1.8rem, 4vw, 3.4rem); margin-top: 2.4rem; align-items: start; }
@media (max-width: 780px) { .li-aplus { grid-template-columns: 1fr; } }
.li-aplus__stack { margin: 0; padding: clamp(.9rem, 2vw, 1.3rem); background: var(--li-paper); border: 2px solid var(--li-ink); border-radius: 16px; box-shadow: 8px 10px 0 rgba(30,32,25,.15); }
.li-aplus__head { align-items: baseline; gap: .7rem; margin-bottom: .9rem; }
.li-aplus__title { margin: 0 !important; font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 540; font-size: 1.2rem !important; }
.li-aplus__genre { margin: 0 !important; font-size: .8rem !important; letter-spacing: .05em; text-transform: uppercase; padding: .22rem .6rem; border: 1.5px solid var(--li-ink); border-radius: 999px; background: var(--li-chartreuse-soft); }
.li-aplus__mod { margin: 0 0 .5rem !important; }
.li-aplus__mod:last-child { margin-bottom: 0 !important; }
.li-aplus__mod img { display: block; width: 100%; height: auto; border: 0; border-radius: 7px; box-shadow: none; }
.li-aplus__note { margin-top: 1.9rem !important; text-align: center; }

/* Print design — bookmark/card sides as an overlapping physical pair. */
.li-print { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(1.6rem, 3.5vw, 2.8rem); margin-top: 2.6rem; align-items: start; }
@media (max-width: 900px) { .li-print { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .li-print { grid-template-columns: 1fr; max-width: 260px; margin-left: auto; margin-right: auto; } }
.li-print__item { margin: 0; }
.li-print__item--card { grid-column: span 1; }
/* §F3 (LI-P2b) · the bookmark/name overlap, fixed at the cause.
   The back sheet was anchored `top: 6%`. Both sheets are the same width and so
   the same height, which put the back sheet's bottom edge 6% BELOW the front
   one — and 6% of a 2:6 bookmark is a lot of pixels, which is why bookmarks
   collided with their author name while the short business card did not. An
   earlier pass added `z-index: 3` to the meta, but stacking order was never the
   problem: the text was physically underneath the image. Anchoring the back
   sheet to the BOTTOM instead means it can only ever overhang upward, into the
   band's own padding, where there is nothing to hit. */
.li-print__pair { position: relative; display: block; padding-right: 22%; padding-top: 5%; }
.li-print__side { margin: 0 !important; transition: transform .35s var(--li-pop); }
.li-print__side img { display: block; width: 100%; height: auto; border: 2px solid var(--li-ink); border-radius: 8px; box-shadow: 5px 6px 0 rgba(30,32,25,.17); background: var(--li-paper); }
.li-print__side--a { transform: rotate(-2.2deg); position: relative; z-index: 2; }
.li-print__side--b { position: absolute; top: auto; bottom: 3%; right: 0; width: 78%; transform: rotate(3.4deg); z-index: 1; }
.li-print__item:hover .li-print__side--a { transform: rotate(0) translateY(-5px); }
.li-print__item:hover .li-print__side--b { transform: rotate(6deg) translateX(6px); }
.li-print__meta { margin-top: 1.4rem; align-items: baseline; gap: .5rem; }
.li-print__who { margin: 0 !important; font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 540; font-size: 1.02rem !important; }
.li-print__kind { margin: 0 !important; font-size: .74rem !important; letter-spacing: .06em; text-transform: uppercase; opacity: .7; }

/* ARC campaign cover wall — a DOM track of individual covers, ported from the
   Reading Room (2026-08-10). Every cover is its own element; each row divides
   its real track distance by a target px/s and writes the result into
   --li-arc-dur, so the speed stays in the 40-80px/s comfort band whatever the
   cover count does. The set is emitted TWICE per row for the seamless loop;
   the browser serves the duplicate half from cache. */
.li-arcwall { margin-top: 2.4rem; display: block; }
.li-arcrow {
  overflow: hidden; margin: 0 0 clamp(.55rem, 1.4vw, .9rem);
  /* THE NO-EMPTY-BAND RULE. The row reserves its own height from the token, not
     from whatever its covers happen to have decoded, so a row whose covers have
     not painted yet does not collapse to 0 and read as a blank band. */
  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; }
/* BOTH SELECTORS, DELIBERATELY. `.li-arctrack__img` is the class the helper
   puts on the WRAPPER (<picture>); `.li-arctrack__img img` is the descendant.
   Naming both means the height cap holds whether the class lands on a <picture>
   or the <img> itself. */
.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%); } }
.li-arcwall__more { text-align: center; margin: 2.6rem auto 0; max-width: 60ch; font-size: 1.04rem; opacity: .92; }

/* Editorial 3D mockup moments — scatter, not a grid. */
.li-mockups { display: grid; gap: clamp(1.2rem, 3vw, 2.2rem); margin-top: 2.4rem; align-items: center; }
.li-mockup-band--redesign .li-mockups { grid-template-columns: repeat(2, 1fr); }
.li-mockup-band--objects .li-mockups { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 860px) { .li-mockup-band--objects .li-mockups { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .li-mockup-band--redesign .li-mockups, .li-mockup-band--objects .li-mockups { grid-template-columns: 1fr; } }
.li-mockups__img { margin: 0 !important; transition: transform .35s var(--li-pop); }
.li-mockups__img img { display: block; width: 100%; height: auto; border: 2px solid var(--li-ink); border-radius: 14px; box-shadow: 7px 9px 0 rgba(30,32,25,.16); }
.li-mockups__img:nth-child(3n+1) { transform: rotate(-1.6deg); }
.li-mockups__img:nth-child(3n+2) { transform: rotate(1.2deg); }
.li-mockups__img:nth-child(3n)   { transform: rotate(-.6deg); }
.li-mockups__img:hover { transform: rotate(0) translateY(-6px) scale(1.02); }

/* ==========================================================
   v1.6.2 · STAGE 1 SITEWIDE GLOBALS (2026-07-23)
   Structural polish from Meg's 2026-07-22 review. Placed below
   the component rules so these win on equal specificity, and
   above the reduced-motion block so that keeps the last word.
   ========================================================== */

/* Body paragraph alignment: unclassed body copy reads left, always.
   Scoped to :not([class]) so classed component paragraphs
   (li-note, li-pull--right, li-lede, li-cta__sub, li-pkg copy) keep
   their own alignment untouched. */
.li-section p:not([class]),
.li-section li:not([class]) { text-align: left; }
.li-lede { text-align: left; }

/* Equal-weight content boxes: cards/steps/packages fill their grid
   cell so a wrapped row (a 4-up breaking to 2×2) reads as one even
   block rather than "the first box is bigger". Column width is
   already equal via the 1fr tracks; section widths were normalised
   to 1150px in the patterns so equivalent chapters (2/3/4) match. */
.li-grid { align-items: stretch; }
.li-grid > .li-card,
.li-grid > .li-step,
.li-grid > .li-pkg,
.li-grid > .wp-block-group { height: 100%; }

/* Standalone section buttons that follow a centred intro: centre them,
   the way .li-cta already centres its own. Only section-level button
   rows (direct children of a section band) are affected — buttons inside
   cards/packages keep their own full-width layout. */
.li-section > .wp-block-buttons { justify-content: center; }
.li-buttons--center { justify-content: center; }

/* Reusable section icon for dense pages (e.g. Services). Drop
   <p class="li-secicon">✱</p> (a glyph or emoji) at the top of a
   section, above the chapter/heading. Add --center to centre it in a
   centred band. */
.li-secicon {
  width: 54px; height: 54px; margin: 0 0 1.1rem !important;
  display: grid; place-items: center;
  background: var(--li-chartreuse); color: var(--li-ink);
  border: 2px solid var(--li-ink); border-radius: 16px;
  box-shadow: 5px 6px 0 rgba(30,32,25,.16);
  font-size: 1.55rem; line-height: 1; transform: rotate(-3deg);
  transition: transform .3s var(--li-pop);
}
.li-secicon:hover { transform: rotate(0) translateY(-3px); }
.li-secicon--center { margin-left: auto !important; margin-right: auto !important; }
.li-cta .li-secicon { margin-left: auto !important; margin-right: auto !important; }

/* Density-lightening utility for flagged dense text: caps the measure
   for readability and eases weight/colour without touching structure.
   Opt-in per section: add li-lighten to a section or a paragraph. */
.li-lighten p:not([class]), p.li-lighten { max-width: 66ch; font-weight: 450; opacity: .9; }

/* ==========================================================
   v1.6.x · STAGE 3 — ARC PAGE DEEP REBUILD (2026-07-23)
   The 7-step visual timeline, the overlap-proof rotating
   badge, the 6-cover named ARC shelf, and the What-You-Get
   checklist. All pure CSS/SVG — no JS dependency, so every
   piece renders JS-off and survives a pattern mode:replace.
   ========================================================== */

/* ---- Visual timeline (the 7-step ARC process) ----
   A centre spine with numbered nodes; cards alternate left/right
   on desktop, and collapse to a single left-rail column on mobile
   where the spine slides to the left edge. Numbered nodes sit ON
   the spine. Handwriting notes hang under the card they belong to. */
.li-timeline { position: relative; margin: 3rem auto 0; max-width: 940px; }
.li-timeline::before {
  content: ""; position: absolute; top: 6px; bottom: 6px; left: 50%;
  width: 3px; transform: translateX(-50%);
  background: repeating-linear-gradient(var(--li-forest) 0 10px, transparent 10px 18px);
  opacity: .5;
}
.li-tl {
  position: relative; width: calc(50% - 3rem); box-sizing: border-box;
  margin-bottom: 2.4rem;
}
.li-tl:last-child { margin-bottom: 0; }
.li-tl:nth-child(odd) { margin-left: 0; text-align: right; }
.li-tl:nth-child(even) { margin-left: calc(50% + 3rem); text-align: left; }
.li-tl__card {
  background: var(--li-paper); border: 2px solid var(--li-ink);
  border-radius: var(--li-radius); padding: 1.3rem 1.5rem;
  box-shadow: 5px 6px 0 rgba(30,32,25,.14);
  transition: transform .3s var(--li-pop), box-shadow .3s var(--li-pop);
}
.li-tl:nth-child(odd) .li-tl__card { transform: rotate(.7deg); }
.li-tl:nth-child(even) .li-tl__card { transform: rotate(-.7deg); }
.li-tl__card:hover { transform: rotate(0) translateY(-4px); box-shadow: 7px 9px 0 var(--li-chartreuse); }
.li-tl__num {
  position: absolute; top: 4px; width: 46px; height: 46px; z-index: 2;
  display: grid; place-items: center; border-radius: 50%;
  background: var(--li-forest); color: var(--li-chartreuse);
  border: 3px solid var(--li-paper);
  font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1;
  font-weight: 600; font-size: 1.3rem; box-shadow: 0 0 0 2px var(--li-ink);
}
.li-tl:nth-child(odd) .li-tl__num { right: -3rem; transform: translateX(50%); }
.li-tl:nth-child(even) .li-tl__num { left: -3rem; transform: translateX(-50%); }
.li-tl__title {
  font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1;
  font-weight: 560; font-size: 1.28rem !important; line-height: 1.12; margin: 0 0 .4rem !important;
}
.li-tl__body { font-size: .96rem !important; opacity: .9; margin: 0 !important; }
.li-tl .li-note { margin-top: .9rem; }
.li-tl:nth-child(odd) .li-note { margin-left: auto; margin-right: 0; }
.li-tl:nth-child(even) .li-note { margin-left: 0; margin-right: auto; }
@media (max-width: 820px) {
  .li-timeline::before { left: 23px; }
  .li-tl, .li-tl:nth-child(odd), .li-tl:nth-child(even) {
    width: 100%; margin-left: 0; padding-left: 4rem; text-align: left;
  }
  .li-tl:nth-child(odd) .li-tl__card, .li-tl:nth-child(even) .li-tl__card { transform: rotate(-.5deg); }
  .li-tl:nth-child(odd) .li-tl__num, .li-tl:nth-child(even) .li-tl__num {
    left: 0; right: auto; transform: none; width: 40px; height: 40px; font-size: 1.1rem;
  }
  .li-tl:nth-child(odd) .li-note, .li-tl:nth-child(even) .li-note { margin-left: 0; margin-right: auto; }
}

/* ---- Rotating circle badge (overlap-proof) ----
   Reuses the Home badge idea (SVG textPath on a circle) but fixes the
   overlap: the Home one let a long string wrap past 360° onto itself.
   Here the text is short AND textLength pins it to exactly one loop
   (lengthAdjust="spacing"), so it can never overrun. Self-contained,
   placed inline in the content (not JS-injected into a hero), so it
   sits where the pattern puts it and never collides with hero decor. */
.li-rotor {
  position: relative; width: 148px; height: 148px; flex: 0 0 auto;
  display: grid; place-items: center; margin: 0 auto;
}
.li-rotor svg { position: absolute; inset: 0; width: 100%; height: 100%; animation: li-spin 18s linear infinite; }
.li-rotor text { font-family: var(--li-sans); font-size: 11px; font-weight: 700; letter-spacing: .01em; fill: currentColor; }
.li-rotor__seal {
  width: 62px; height: 62px; border-radius: 50%; display: grid; place-items: center;
  background: var(--li-chartreuse); color: var(--li-forest-deep);
  font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1;
  font-size: 1.9rem; box-shadow: 0 0 0 2px var(--li-ink);
}
.li-rotor--onforest { color: var(--li-cream); }

/* ---- 6-cover named ARC shelf (Recruited, Read, Reviewed) ---- */
.li-arcshelf {
  display: grid; grid-template-columns: repeat(6, 1fr);
  gap: clamp(1rem, 2.2vw, 1.8rem); margin-top: 2.6rem; align-items: start;
}
@media (max-width: 1000px) { .li-arcshelf { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 520px) { .li-arcshelf { grid-template-columns: repeat(2, 1fr); } }
.li-arcshelf .li-cover__title {
  font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1;
  font-weight: 540; font-size: .92rem !important; line-height: 1.12; margin: .8rem 0 0 !important;
}
.li-arcshelf .li-cover__author {
  font-family: var(--li-sans); font-weight: 700; font-size: .64rem !important;
  letter-spacing: .12em; text-transform: uppercase; opacity: .7; margin: .28rem 0 0 !important;
}

/* ---- What-You-Get checklist (handwriting-note flavour) ---- */
.li-getlist-head { text-align: center; margin: 3.6rem 0 0 !important; font-size: 1.15rem; }
.li-getlist { list-style: none; margin: 1.2rem auto 0 !important; padding: 0 !important; max-width: 560px; display: grid; gap: .7rem; }
.li-getlist li {
  position: relative; padding-left: 2rem; font-weight: 500; font-size: 1.02rem;
}
.li-getlist li::before {
  content: "✓"; position: absolute; left: 0; top: -.05em;
  color: var(--li-lavender-deep); font-weight: 800; font-size: 1.15rem;
}
.has-forest-background-color .li-getlist li::before,
.has-forest-deep-background-color .li-getlist li::before { color: var(--li-chartreuse); }

/* ---------- 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 { animation: none !important; }
  .li-logotrack { animation: none !important; }
  .li-igtrack, .li-arctrack { animation: none !important; }
  /* nav: keep the hover/focus GATE (submenus must still be closed by default),
     drop only the choreography — transition-duration above already makes the
     open/close instant, so the overlay stagger is all that needs killing. */
  .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; }
  /* the tracks emit their set twice for the seamless loop; frozen, the second
     pass is redundant, so hide it and let the rows read as static walls. The
     ARC wall is now N individual covers emitted twice (not one strip), so its
     redundant half is tagged --dup rather than caught by nth-child(n+2), which
     here would hide every cover but the first and leave near-empty rails. */
  .li-igtrack__img:nth-child(n+13) { display: none; }
  .li-arctrack__img--dup { display: none !important; }
  .li-browser__shot img { transform: none !important; }
  .li-preloader { display: none !important; }
}

/* ============================================================
   v1.6.7 · STAGE 5 — SERVICE PAGES (2026-07-23)
   Copy went into the patterns; these are the presentational
   fixes: page-hero decoration overlap, the single-doc viewer,
   the IG pinned pin, the website portfolio wall + examples,
   the cover carousel, and the print name safeguard.
   ============================================================ */

/* Page-hero decoration must never sit under the heading text.
   Only the opacity survives here. The positioning that used to live in
   this block was a percentage of the text column (see the A5 note far
   below for why that could never work) and has been superseded by the
   gutter calc() there. Do not re-add per-shape insets at this point in
   the file — they would win on source order and put the squiggle back
   on top of Meg's headings for the third time. */
.li-pagehero .li-shape { opacity: .55; }

/* Single-document page-through (Strategy sample, Brand-Assets press kit).
   Reuses .li-showcase; there is no tab row, so hide it, and cap the tall
   portrait sample pages so one page fits the viewport in the flipper. */
.li-showcase--single .li-showcase__tabs { display: none; }
.li-showcase--single .li-showcase__pages .wp-block-image { max-width: 620px; }
.li-showcase--single .li-showcase__pages .wp-block-image img { max-height: 82vh; width: auto; object-fit: contain; margin: 0 auto; }
body.li-js .li-showcase--single .li-showcase__pages { min-height: 320px; }

/* IG pinned band: it is already a 3-column split — add the pinned-post pin
   icon to each set so it reads as "these are pinned to the top of profile". */
/* LI-P2b: this pin was a colour EMOJI (U+1F4CC) until 2026-07-26. LI-P2's §A4
   "remove emoji-as-icons sitewide" swept patterns/, functions.php and parts/
   but never style.css, so the one Meg would actually have seen — on the Social
   page she flagged — survived the sweep. It is now a drawn pushpin: brand ink
   and lavender, same silhouette, no system font roulette. Any future sweep must
   include the stylesheet. */
.li-pinned__shot { position: relative; }
.li-pinned__shot::after {
  content: ""; position: absolute; top: 5px; right: 5px;
  width: 20px; height: 20px; background: no-repeat center/contain;
  background-image: var(--li-pin);
  filter: drop-shadow(1.5px 1.5px 0 rgba(30,32,25,.3));
  transform: rotate(8deg); pointer-events: none; z-index: 4;
}

/* Author Website Design — "see a real example" row, one per package tier. */
.li-webex { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(1rem, 2.4vw, 1.8rem); margin: 1.8rem 0 2.2rem; }
@media (max-width: 900px) { .li-webex { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) { .li-webex { grid-template-columns: 1fr; } }
.li-webex__item { margin: 0; }
/* §G1 (LI-P2b): the tier label and the author/platform chips are gone from the
   markup — the pricing card under each frame names the tier, and the portfolio
   wall below names the author. `.li-webex__tier` and the meta rule are kept as
   no-ops only so an older cached page doesn't render an unstyled stray. */
.li-webex__tier, .li-webex .li-portfolio__meta { display: none; }
.li-webex .li-browser { --li-browser-h: 200px; }
.li-webex .li-browser__shot img { transition-duration: 9s; }

/* Website portfolio WALL: smaller frames, 3 per row, slower hover-scroll. */
.li-portfolio--wall { grid-template-columns: repeat(3, 1fr); gap: clamp(1.2rem, 2.6vw, 2rem); }
@media (max-width: 900px) { .li-portfolio--wall { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .li-portfolio--wall { grid-template-columns: 1fr; } }
.li-portfolio--wall .li-browser { --li-browser-h: 230px; }
.li-portfolio--wall .li-browser__shot img { transition-duration: 11s; }
.li-portfolio--wall .li-portfolio__item:nth-child(3n+1) .li-browser { transform: rotate(-1deg); }
.li-portfolio--wall .li-portfolio__item:nth-child(3n+2) .li-browser { transform: rotate(0.6deg); }
.li-portfolio--wall .li-portfolio__item:nth-child(3n) .li-browser { transform: rotate(1deg); }

/* Cover-design portfolio → a swipeable carousel. A fixed card height + object
   -fit contain normalises the mixed cover dimensions Meg flagged, so no cover
   renders stretched; scroll-snap makes it feel like a rotating shelf. */
.li-designed--carousel {
  display: flex !important; grid-template-columns: none !important;
  gap: clamp(1rem, 2.5vw, 1.8rem); overflow-x: auto; scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch; padding-bottom: 1rem; scrollbar-width: thin;
}
.li-designed--carousel .wp-block-image { flex: 0 0 auto; width: clamp(150px, 22vw, 205px); scroll-snap-align: center; }
.li-designed--carousel .wp-block-image img { height: 300px; max-height: 300px; object-fit: contain; }
.li-designed--carousel::-webkit-scrollbar { height: 8px; }
.li-designed--carousel::-webkit-scrollbar-thumb { background: var(--li-lavender); border-radius: 4px; }

/* Print band: keep the author names below each pair visible and clear of the
   overlapping back-of-card, which was hiding them on some rows. */
.li-print__meta { position: relative; z-index: 3; margin-top: 1.1rem; }
.li-print__who { color: var(--li-ink) !important; opacity: 1 !important; visibility: visible; }

/* Centered helper for standalone lines (e.g. the Platforms line). */
.li-center { text-align: center; max-width: 60ch; margin-left: auto; margin-right: auto; }

/* ==========================================================
   v1.6.x · STAGE 6 — UTILITY PAGES (2026-07-23)
   Real blog index + functional Contact page + section-icon
   density work. All additive; no dependency on JS. Slim
   page-hero variant lets Blog/Contact lead with content
   instead of a full marketing hero.
   ========================================================== */

/* Slim page hero: keeps the dark header band + H1 for SEO, but
   drops the tall padding so the posts grid / contact form comes
   up front-and-centre. */
.li-pagehero--slim {
  padding-top: calc(var(--li-head-h) + clamp(2rem, 4vw, 3rem));
  padding-bottom: clamp(2rem, 4.5vw, 3.2rem);
}
.li-pagehero--slim h1 { font-size: clamp(2.1rem, 4.8vw, 3.6rem); max-width: 20ch; }
.li-pagehero--slim .li-pagehero__sub { margin-top: 1.3rem; }

/* Contact: two-column form + details card. */
.li-contact-grid { gap: clamp(1.6rem, 4vw, 3rem) !important; align-items: start; }
.li-contact-form > .wp-block-heading { margin-bottom: .5rem; }
.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);
}
.li-contact-card h3 { margin-top: 1.5rem; }
.li-contact-card > h3:first-child { margin-top: 0; }
.li-contact-facts { list-style: none; margin: 0; padding: 0; display: grid; gap: 1rem; }
.li-contact-facts li { padding-left: 0; }
.li-contact-card .li-note { margin: 1.4rem 0 0; }
/* Meg review 2026-07-27: "Add some padding under 'The Way I Work'." The h3 sat
   hard against the fact list, and the whole card sat hard against the divider
   below it. Both gaps opened. */
.li-contact-card h3 { margin-bottom: 1.1rem; }
.li-contact-card .li-contact-facts { margin-bottom: .4rem; }
.li-contact-card .li-hr { margin-block: 2rem; }
.li-contact-card .wp-block-buttons { margin-top: 0; justify-content: flex-start; }
.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-hr {
  border: none; border-top: 2px dashed rgba(30, 32, 25, .22);
  margin: 1.5rem 0; opacity: 1; height: 0;
}

/* Fluent Forms embed: let the plugin's fields inherit the paper
   surface + Poppins without fighting its own base styles. */
.li-contact-form .fluentform { margin-top: .4rem; }

/* ==========================================================
   v1.8.0 · SESSION LI-P2 — §A SITEWIDE ROOT-CAUSE FIXES
   (2026-07-25, from Meg's round-2 visual review)
   Five defects she reported across many pages each turned out
   to be ONE shared cause. Diagnosed on the rendered live page,
   fixed here once, verified per page afterwards.
   ========================================================== */

/* --- A1 · The chapter-intro alignment bug -------------------
   Meg's #1 recurring complaint: "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`. The theme caps the heading at 21ch and
   the lede at 52ch, so each one centred on its OWN centre line
   while the chapter device and the card grids ran the full band.
   Measured on Home Chapter 01 at 1280px: chapter device left
   edge 64px, heading 194px, lede 334px — three left edges in a
   single intro, which is exactly what read as broken.
   FIX: in a left-aligned band the intro stack shares the band's
   left edge. The 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. */
/* --- A1, CORRECTED (LI-P2b, 2026-07-26) ---------------------
   A1 was only ever verified on Home at 1280px, where a band's
   content box happens to equal its constrained column, so the
   two possible left edges coincide and nothing shows. Measured
   on the LIVE v1.9.2 site at 1280 AND 1440 across Home, ARC,
   Services and Website Design, they do not coincide anywhere
   else, and A1 was making it worse rather than better:

     · 1280px, every FAQ band on the site: the H2 sits at 64
       while the chapter device and the accordion sit at 200 —
       a 136px hang, on ~13 bands.
     · 1440px: 3-8 misaligned bands per page, worst spread 469px.
     · Home at 1280: 5 misaligned bands, worst spread 425px.

   CAUSE: "un-centre the child" aligns it to the SECTION's
   padding box, but its centred siblings align to the narrower
   CONSTRAINED column. Those are the same edge only when the two
   widths match. So the child must align to the column, and CSS
   has no way to reference a column that has no box — WordPress
   implements `constrained` as max-width + auto margins on each
   child, not as a wrapper element.

   FIX: give each band its column width as a class (`li-col-880`
   … `li-col-1320`, written into the pattern markup, which keeps
   the block valid because className is a real block attribute)
   and shift the intro stack by exactly the column's own offset.
   The max-widths stay — they protect line length. Falls back to
   the old behaviour when `--li-col` is unset, so an untagged or
   hand-added band is never worse off than today. */
.li-col-620  { --li-col: 620px; }
.li-col-680  { --li-col: 680px; }
.li-col-780  { --li-col: 780px; }
.li-col-820  { --li-col: 820px; }
.li-col-880  { --li-col: 880px; }
.li-col-900  { --li-col: 900px; }
.li-col-1080 { --li-col: 1080px; }
.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; }

.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) > .li-eyebrowline,
.li-section:not(.li-section--center) > p:not([class]),
.li-section:not(.li-section--center) > p.wp-block-paragraph,
.li-section:not(.li-section--center) > .wp-block-heading {
  margin-left: max(0px, calc((100% - var(--li-col, 100%)) / 2)) !important;
  margin-right: auto !important;
}
/* Deliberate exceptions — these earn their position and must not be
   dragged back to the column's left edge. `li-pull--right` in particular
   is positioned by its own `margin-left:auto`; RR-P1 recorded that a naive
   port of this rule destroyed it.

   ⚠ SPECIFICITY, 2026-07-27. These exceptions were SILENTLY DEAD for every
   paragraph on the site. When `p.wp-block-paragraph` was added to the base
   selector above (see the note below it), that clause became (0,3,1) — one
   element selector more specific than these exceptions at (0,3,0). Both
   sides are `!important`, so specificity decided it and the base rule won:
   every `.li-note`, `.li-center` and `.has-text-align-center` PARAGRAPH was
   yanked to the left edge. Measured on dev v1.10.2, Newsletter: the note
   "Remember Google+? Precisely." computed `margin-left:0; margin-right:906px`.

   That one regression is behind most of Meg's "this should be centered"
   review items. The exceptions now carry the same `p` element selector so
   they match the base rule's weight and win on source order. Keep BOTH the
   `p.x` and bare `.x` forms — the bare one still serves non-paragraph nodes. */
/* ⚠ 2026-07-29, dev-final session 3. THE SAME TRAP CAUGHT TWO MORE, and both
   were classes whose OWN rule already asked to be centred — which is exactly
   why nobody noticed. A class carrying `margin-inline: auto` (or even
   `margin: … auto … !important`) still loses to the base rule above, because
   the base rule is (0,3,1) and a bare `.li-x` is (0,1,0); with `!important` on
   both sides specificity decides. Measured on dev v1.16.0 at 1280:
     · KDP  `.li-pull--center`     → margin-left 1px / margin-right 185px,
       i.e. 92px off centre. This is Meg's "alignment/layout is off" on
       "Both are decisions, not guesses…" — the line had already been switched
       from `--right` to `--center` in a previous pass and the switch was DEAD.
     · ARC Signup `.li-formband__trust` → 126px / 434px, 154px off centre,
       which is her "text beneath the form needs centering". The `.li-note`
       directly below it centred correctly, because THAT one is on this list —
       so the two lines sat visibly out of line with each other.
   ANY new class that wants centring inside a `.li-section` must be added here.
   Its own `text-align: center` will work; its own auto margins will not. */
.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-portfolio__more,
.li-section:not(.li-section--center) > p.li-pull--center,
.li-section:not(.li-section--center) > p.li-formband__trust,
.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-portfolio__more,
.li-section:not(.li-section--center) > .li-pull--center,
.li-section:not(.li-section--center) > .li-formband__trust {
  margin-left: auto !important;
  margin-right: auto !important;
}
/* The one that is deliberately NOT centered: 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;
}
/* `p.wp-block-paragraph` is now in the selector above. LI-P3 and RR-P1 both
   found that the old `p:not([class])` clause matched NOTHING on a rendered
   page, because WordPress renders a plain paragraph block as
   `<p class="wp-block-paragraph">`. A1 has been running on its heading and
   lede clauses alone since it shipped. */

/* --- A2 · "The first card is higher than the rest" ----------
   Reported on the Home services grid, the Home numbers band and
   the About Chapter 04 squares — one cause behind all three.
   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 (20px) above its rowmates. Later
   rows look flush because every child in them carries the
   margin. Hence "the first one is higher" — a real 20px 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 "Read more" / "Start there" / "Book this" land on ONE line
   across a row instead of floating wherever the copy above them
   happens to end. Cards are already full-height in their grid
   cell (see the v1.6.2 block); they just were not flex, 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; }
/* Website Design pricing cards use the same contract. */
.li-webpkg > .wp-block-buttons { margin-top: auto; padding-top: 1rem; }

/* ==========================================================
   v1.8.0 · SESSION LI-P2 — §D ARC PAGE REDESIGN
   D2 (dashboard gets its own 50:50 chapter) and D3 (Chapter 03
   becomes the formal Reading Room introduction). The 7-step
   zig-zag (D1) and its mobile collapse were already built in a
   prior session — see .li-timeline / .li-tl above; nothing to
   add here. D4 reuses the existing .li-offset editorial grid.
   ========================================================== */

/* --- D3 · The Reading Room band (forest, sits between a lilac
   and a cream chapter so the dark-adjacency rule still holds) --- */
.li-rr-band .li-rr-cols { gap: clamp(1.8rem, 4vw, 3.4rem) !important; }
.li-rr-logo { margin: 0 0 1.3rem !important; }
.li-rr-logo img {
  display: block; width: 100%; max-width: 420px; height: auto;
  border: 0; border-radius: 0; box-shadow: none;
}
.li-rr-chip { display: inline-block; margin: 0 0 1.5rem !important; }
/* The value list runs the column's own measure here rather than the
   centred 560px it uses as a full-band "what you get" summary. */
.li-getlist--light { margin: 1.2rem 0 0 !important; max-width: none; }
.li-stat--light { max-width: 360px; margin-inline: 0; }
.li-rr-band .li-rotor { margin: 1.9rem 0 0; }
@media (max-width: 781px) {
  .li-rr-logo img { max-width: 320px; }
  .li-stat--light { max-width: none; }
  .li-rr-band .li-rotor { margin-inline: auto; }
}

/* --- D2 · Dashboard in a browser frame, shown whole ----------
   The portfolio frames crop to --li-browser-h and pan on hover
   because those are full-page captures. The dashboard is a single
   screen, so --fit lets it show complete and drops the pan. */
.li-browser--fit .li-browser__shot { height: auto; }
.li-browser--fit:hover .li-browser__shot img,
.li-browser--fit:focus-within .li-browser__shot img { transform: none; }
.li-dash-band .li-dash-cols { gap: clamp(1.8rem, 4vw, 3.2rem) !important; }

/* --- D6 · ARC signup: the form as a card on a brand band -------- */
.li-formband .li-chapter { margin-bottom: 1.4rem; }
.li-formcard {
  background: var(--li-paper); border: 2px solid var(--li-ink);
  border-radius: var(--li-radius); padding: clamp(1.4rem, 3.5vw, 2.6rem);
  box-shadow: 8px 10px 0 rgba(30, 32, 25, .14);
}
.li-formcard .fluentform { margin: 0; }
.li-formband__trust {
  margin: 1.6rem auto 0 !important; max-width: 62ch;
  text-align: center; font-size: .95rem; opacity: .82;
}
.li-formband .li-note { text-align: center; margin-top: 1.1rem !important; }

/* --- A5 · Decorative hero shapes stay OUT of the text column ----
   THE ACTUAL CAUSE, found 2026-07-27 by measuring the live box rather
   than reading the percentages. `.li-shapes` is a direct child of
   `.li-pagehero`, and `.li-pagehero` is a WordPress CONSTRAINED layout
   group (contentSize 980px). Constrained layout applies
   `max-width:980px; margin-inline:auto` to every direct child — so the
   decoration container is not the hero, it is EXACTLY the text column.
   Measured on dev v1.10.2 at 1280: hero 1265px wide, `.li-shapes`
   980px at x=143..1123, squiggle at x=970..1104 — i.e. 89px INSIDE the
   H1's span.

   That is why the two previous passes failed. Both of them (this block
   and the one further up) re-tuned percentages like `right: 2%` — but
   2% OF THE TEXT COLUMN is still in the text column. No percentage in
   that container can ever reach the gutter, because the container has
   no gutter.

   The cure is to take `.li-shapes` out of the constrained layout so it
   spans the full hero band, then place each shape against the OUTER
   edge with a calc() that keeps its inner edge clear of the content
   column by --li-decor-gap. Below the width where the gutter can no
   longer hold a shape, that shape is simply gone. */
.li-hero, .li-pagehero { --li-decor-col: 980px; --li-decor-gap: 34px; }

.li-hero .li-shapes,
.li-pagehero .li-shapes {
  max-width: none;      /* break out of the constrained layout */
  width: auto;
  margin-inline: 0;
  left: 0; right: 0;
  z-index: 0;
}
.li-pagehero > *:not(.li-shapes) { position: relative; z-index: 2; }

/* Each shape is pinned to the outer gutter. The inner edge lands at
   (50% - half the content column - the shape's own width - the gap), so it
   is mathematically outside the measure at every viewport.

   ⚠ The width is declared as `--li-sw` and then USED in the offset, rather
   than hard-coded twice. The first cut of this block wrote the width into the
   calc as a literal, and because removing the old override also removed its
   `width: 132px`, the squiggle rendered at its 180px base width against a calc
   that still assumed 134 — 27px back over the heading at 1440. Binding the two
   to one variable makes that class of drift impossible. If you change a
   shape's width, change --li-sw and the breakpoint below; nothing else. */
.li-pagehero .li-shape { width: var(--li-sw); }
.li-pagehero .li-shape--spark1,
.li-pagehero .li-shape--asterisk,
.li-pagehero .li-shape--loop { right: auto; }
.li-pagehero .li-shape--spark1  { --li-sw: 40px;  left: calc(50% - (var(--li-decor-col) / 2) - var(--li-sw) - var(--li-decor-gap)); }
.li-pagehero .li-shape--asterisk{ --li-sw: 60px;  left: calc(50% - (var(--li-decor-col) / 2) - var(--li-sw) - var(--li-decor-gap)); }
.li-pagehero .li-shape--loop    { --li-sw: 130px; left: calc(50% - (var(--li-decor-col) / 2) - var(--li-sw) - var(--li-decor-gap)); }
.li-pagehero .li-shape--spark2,
.li-pagehero .li-shape--squiggle,
.li-pagehero .li-shape--book { left: auto; }
.li-pagehero .li-shape--spark2  { --li-sw: 26px;  right: calc(50% - (var(--li-decor-col) / 2) - var(--li-sw) - var(--li-decor-gap)); }
.li-pagehero .li-shape--squiggle{ --li-sw: 132px; right: calc(50% - (var(--li-decor-col) / 2) - var(--li-sw) - var(--li-decor-gap)); }
.li-pagehero .li-shape--book    { --li-sw: 78px;  right: calc(50% - (var(--li-decor-col) / 2) - var(--li-sw) - var(--li-decor-gap)); }

/* Vertical placement: keep the decor away from the vertical middle,
   where the H1 and lede live, on the short interior heroes. */
.li-pagehero .li-shape--spark1   { top: 8%; }
.li-pagehero .li-shape--squiggle { top: 6%; }
.li-pagehero .li-shape--spark2   { top: auto; bottom: 10%; }
.li-pagehero .li-shape--book     { top: auto; bottom: 14%; }
.li-pagehero .li-shape--loop     { top: 34%; }
.li-pagehero .li-shape--asterisk { top: 58%; }

/* A shape only exists while the gutter is wide enough to hold it:
   content column + 2 x (shape width + gap). Below that it is hidden
   rather than allowed back over the text. */
/* Each threshold is 980 + 2*(--li-sw + --li-decor-gap), i.e. the narrowest
   viewport whose gutter can still hold that shape clear of the measure. */
@media (max-width: 1312px) { /* 980 + 2*(132+34) */
  .li-pagehero .li-shape--squiggle { display: none; }
}
@media (max-width: 1308px) { /* 980 + 2*(130+34) */
  .li-pagehero .li-shape--loop { display: none; }
}
@media (max-width: 1204px) { /* 980 + 2*(78+34) */
  .li-pagehero .li-shape--book { display: none; }
}
@media (max-width: 1168px) { /* 980 + 2*(60+34) */
  .li-pagehero .li-shape--asterisk { display: none; }
}
@media (max-width: 1128px) { /* 980 + 2*(40+34) */
  .li-pagehero .li-shape--spark1 { display: none; }
}
@media (max-width: 1100px) { /* 980 + 2*(26+34) */
  .li-pagehero .li-shape--spark2 { display: none; }
}

/* --- A5b · THE SAME FIX, NOW ON THE HOME HERO (S1, 2026-08-02) -------
   The 2026-07-27 pass above diagnosed this properly and fixed it — but only
   for `.li-pagehero`. `.li-hero` (Home, and only Home) got the break-out rule
   for `.li-shapes` and none of the per-shape gutter calcs, so it kept the base
   percentages (`--loop { top:33%; left:14% }` etc.) which are positions inside
   the text column. Measured on live dev v1.22.0, shapes crossing the H1's
   horizontal span:
       1280 → squiggle, book, loop      1440 → squiggle, book, loop      1920 → book
   That is the "purple element overlapping the heading" Meg has reported
   repeatedly on Home. Same cause, same cure, one component.

   `.li-hero` differs from `.li-pagehero` in exactly one number: its constrained
   contentSize is 1080px, not 980px (measured: 64px hero padding, children capped
   at 1080, widest real child the H1 at 918). So --li-decor-col is 1080 here and
   every threshold below is 1080 + 2*(--li-sw + gap). The gap is 24px rather than
   34px so that the asterisk still survives at 1280, where the gutter is only
   100px a side. Consequence, and it is deliberate: at 1280 Home shows spark1,
   spark2 and asterisk; book, loop and squiggle return at 1284/1388/1392. A shape
   is hidden rather than allowed back over the measure. */
.li-hero { --li-decor-col: 1080px; --li-decor-gap: 24px; }
/* ⚠ .li-stamp MUST be excluded here, alongside .li-shapes (Meg, 2026-08-04:
   "the 5 star badge that goes on the hero is not displaying on the hero, it is
   cut off"). This selector is (0,2,0); `.li-stamp` at line ~471 is (0,1,0), so
   this wins on specificity no matter what order they sit in, and it overwrote
   `position: absolute` with `position: relative`. The badge then fell out of
   its top-right pin and into normal flow at the BOTTOM of the hero, where the
   tilted marquee band overlaps and clips it. Verified against the live DOM. */
.li-hero > *:not(.li-shapes):not(.li-stamp) { position: relative; z-index: 2; }

.li-hero .li-shape { width: var(--li-sw); }
.li-hero .li-shape--spark1,
.li-hero .li-shape--asterisk,
.li-hero .li-shape--loop { right: auto; }
.li-hero .li-shape--spark1  { --li-sw: 40px;  left: calc(50% - (var(--li-decor-col) / 2) - var(--li-sw) - var(--li-decor-gap)); }
.li-hero .li-shape--asterisk{ --li-sw: 60px;  left: calc(50% - (var(--li-decor-col) / 2) - var(--li-sw) - var(--li-decor-gap)); }
.li-hero .li-shape--loop    { --li-sw: 130px; left: calc(50% - (var(--li-decor-col) / 2) - var(--li-sw) - var(--li-decor-gap)); }
.li-hero .li-shape--spark2,
.li-hero .li-shape--squiggle,
.li-hero .li-shape--book { left: auto; }
.li-hero .li-shape--spark2  { --li-sw: 26px;  right: calc(50% - (var(--li-decor-col) / 2) - var(--li-sw) - var(--li-decor-gap)); }
.li-hero .li-shape--squiggle{ --li-sw: 132px; right: calc(50% - (var(--li-decor-col) / 2) - var(--li-sw) - var(--li-decor-gap)); }
.li-hero .li-shape--book    { --li-sw: 78px;  right: calc(50% - (var(--li-decor-col) / 2) - var(--li-sw) - var(--li-decor-gap)); }

@media (max-width: 1392px) { .li-hero .li-shape--squiggle { display: none; } } /* 1080 + 2*(132+24) */
@media (max-width: 1388px) { .li-hero .li-shape--loop     { display: none; } } /* 1080 + 2*(130+24) */
@media (max-width: 1284px) { .li-hero .li-shape--book     { display: none; } } /* 1080 + 2*(78+24)  */
@media (max-width: 1248px) { .li-hero .li-shape--asterisk { display: none; } } /* 1080 + 2*(60+24)  */
@media (max-width: 1208px) { .li-hero .li-shape--spark1   { display: none; } } /* 1080 + 2*(40+24)  */
@media (max-width: 1180px) { .li-hero .li-shape--spark2   { display: none; } } /* 1080 + 2*(26+24)  */

/* --- D5 · Pricing card: the flag can never reach the "i" button --
   .li-pcard__flag is pinned top-left and .li-pcard__i top-right, and
   they share a horizontal band, so on a narrow card (or with a longer
   flag label than "Most complete") they collide. Reserving the
   top-right corner fixes it at every card width instead of per page. */
.li-pcard__flag { max-width: calc(100% - 5.5rem); }

/* --- B1 / B2 · Home chapter tweaks ------------------------------- */
/* .li-ch2-btn RETIRED v1.40.0 (audit: one-off button wrapper). Its single
   caller on the home page now uses a real button style + standard spacing. */
/* Meg: "add padding above SEE HOW IT ALL FITS TOGETHER" — the button row
   sat hard under the card grid above it. */
.li-btnrow--spaced { margin-top: clamp(2.2rem, 4.5vw, 3.4rem) !important; }

/* --- J · Link in Bio: icon logo + the coming-soon Reading Room pill --- */
.li-linkbio__icon { margin: 0 auto !important; }
.li-linkbio__icon img { display: block; margin: 0 auto; border: 0; border-radius: 0; box-shadow: none; }
/* The Reading Room has no live URL yet, so it reads as a stack row without
   being a link. Matches the pill geometry so the stack stays even. */
.li-linkbio__soon {
  margin: .8rem auto !important; padding: .85rem 1.2rem;
  border: 2px dashed rgba(245, 239, 223, .45); border-radius: 999px;
  color: rgba(245, 239, 223, .72); font-weight: 600; font-size: .98rem;
  display: flex; align-items: center; justify-content: center; gap: .5rem;
  flex-wrap: wrap;
}
.li-linkbio__soon strong {
  font-size: .68rem; letter-spacing: .1em; text-transform: uppercase;
  padding: .2rem .55rem; border-radius: 999px;
  background: var(--li-lavender); color: var(--li-forest-deep); font-weight: 700;
}
.li-linkbio .li-linkstack { margin-bottom: 0; }

/* --- K3 · Results: case studies load as posts from the two
   Case Study categories (campaign-case-study 4, digital-strategy-case-study 3).
   Both are empty today, so the no-results state has to read as a deliberate
   sentence rather than a blank hole — the band fills itself as the
   li-campaign-case-studies / li-digital-strategy-case-studies runs publish. */
.li-casestudies { margin-top: 2.2rem; }
.li-casestudies__soon {
  max-width: 62ch; margin: 1.4rem 0 0; font-size: 1rem; opacity: .85;
}
.li-casestudies .li-postcard .li-chip { margin-bottom: .6rem; }

/* ==========================================================
   §B5 · Book cover inside the testimonial bubble
   (Meg's 2026-07-24 proposal, built 2026-07-25 with her chosen
   titles.) The cover sits beside the attribution rather than
   beside the quote text: the eye reads the words, then lands on
   "which book was this about" — and the quote's own line length
   is left completely alone.
   Delivered as a background-image keyed off a class rather than a
   nested wp:image, so the editor cannot invalidate a quote block.
   URLs are relative to style.css, i.e. the theme root.
   ========================================================== */
.li-quotes .wp-block-quote[class*="li-qcover--"] cite,
.li-quote[class*="li-qcover--"] cite {
  position: relative;
  min-height: 62px;
  padding-left: 56px;
  display: flex;
  align-items: center;
}
.li-quotes .wp-block-quote[class*="li-qcover--"] cite::before,
.li-quote[class*="li-qcover--"] cite::before {
  content: "";
  position: absolute; left: 0; top: 50%;
  width: 42px; height: 62px; margin-top: -31px;
  background-size: cover; background-position: center;
  border: 1.5px solid var(--li-ink); border-radius: 3px;
  box-shadow: 2px 3px 0 rgba(30, 32, 25, .18);
  transform: rotate(-2.5deg);
  transition: transform .3s var(--li-pop);
}
.li-quotes .wp-block-quote[class*="li-qcover--"]:hover cite::before { transform: rotate(0) scale(1.06); }
/* Feature/lavender quote variants sit on colour — keep the cover readable. */
.li-quote--feature cite::before, .li-quote--lavender cite::before { border-color: var(--li-ink); }

.li-qcover--gary-kotowski         cite::before { background-image: url(assets/img/quotecovers/gary-kotowski.jpg); }
.li-qcover--anette-nilsson        cite::before { background-image: url(assets/img/quotecovers/anette-nilsson.jpg); }
.li-qcover--ingrid-seymour        cite::before { background-image: url(assets/img/quotecovers/ingrid-seymour.jpg); }
.li-qcover--heather-grace-stewart cite::before { background-image: url(assets/img/quotecovers/heather-grace-stewart.jpg); }
.li-qcover--rochelle-l-wilcox     cite::before { background-image: url(assets/img/quotecovers/rochelle-l-wilcox.jpg); }
.li-qcover--sara-sines            cite::before { background-image: url(assets/img/quotecovers/sara-sines.jpg); }
.li-qcover--lj-robbins            cite::before { background-image: url(assets/img/quotecovers/lj-robbins.jpg); }
.li-qcover--david-norris          cite::before { background-image: url(assets/img/quotecovers/david-norris.jpg); }
.li-qcover--sky-sommers           cite::before { background-image: url(assets/img/quotecovers/sky-sommers.jpg); }
.li-qcover--ella-outlaw           cite::before { background-image: url(assets/img/quotecovers/ella-outlaw.jpg); }
.li-qcover--dave-bartell          cite::before { background-image: url(assets/img/quotecovers/dave-bartell.jpg); }

/* --- About page sign-off (LI-P3) ------------------------------------------ */
.li-signoff { padding: 4.5rem 1.25rem 5.5rem; text-align: center; }
.li-signoff__end { font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1;
  font-size: clamp(2rem, 4vw, 3rem); font-weight: 600; line-height: 1; margin: 0; }
.li-signoff__note { margin-top: .75rem !important; opacity: .85; }
@media (max-width: 780px) { .li-signoff { padding: 3rem 1.25rem 3.5rem; } }

/* --- Legal pages: privacy + terms (LI-P3) ---------------------------------
   The band runs a narrower 780px content width than a standard li-section,
   and WordPress's constrained layout centres every direct child inside it.
   On a page that is almost entirely plain body paragraphs that reproduced
   Meg's #1 complaint exactly: H2 at the band's left edge (64) with every
   paragraph floating at 334. The sitewide A1 fix does NOT catch this — its
   paragraph clause is `p:not([class])`, and WordPress renders a plain
   paragraph as `<p class="wp-block-paragraph">`, so that clause matches
   nothing. It is harmless on standard sections, where the content width
   equals the band and the centring is a no-op, which is why A1 verified
   green on Home. Here it is not a no-op, so the band left-aligns its own
   children. Measured after: every H2 and paragraph at 64. */
.li-legal > * { margin-left: 0 !important; margin-right: auto !important; }
.li-legal > h2 { margin-top: 2.6rem !important; }
.li-legal > h2:first-of-type { margin-top: 1rem !important; }
.li-legal .li-footnote { margin-bottom: 2rem; }

/* ==========================================================
 * LI-P2b — DESIGN COMPLETION (2026-07-26)
 * The sections LI-P2 left outstanding plus the structural
 * work LI-P3 handed over. Calibrated against Meg's design
 * north star: more KDP-style split mockups with tape and
 * subtle animation, the Example Doc pattern, zero emoji.
 * Every device below reuses the existing vocabulary —
 * li-qcover's tilt, the tape detail, li-offset, --fit
 * browser frames — rather than inventing a new one.
 * ========================================================== */

:root {
  /* Drawn pushpin, replacing the U+1F4CC emoji (see .li-pinned__shot). Ink body,
     lavender head, chartreuse highlight — the site's own three marks. */
  /* Percent-encoded, not raw. A `;utf8,` data URI with unescaped <, > and "
     computes fine in getComputedStyle but does not decode to a painted image
     in Chrome — the pin was silently invisible on the rendered page until this
     was checked in a screenshot rather than in the computed style. Cream stroke
     so it reads on the dark client tiles. */
  --li-pin: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%3E%3Cpath%20d%3D%22M20.5%202.6l8.9%208.9-2.4%202.4a4%204%200%200%201-4.4.9l-1.9-.8-6.1%206.1.9%204.6a2%202%200%200%201-3.3%201.8L5.4%2020.6a2%202%200%200%201%201.5-3.4l4.9.5%206.1-6.1-.8-1.9a4%204%200%200%201%20.9-4.4z%22%20fill%3D%22%236b54b8%22%20stroke%3D%22%23f5efe0%22%20stroke-width%3D%222%22%20stroke-linejoin%3D%22round%22%2F%3E%3Cpath%20d%3D%22M11.6%2020.4L3.6%2028.4%22%20stroke%3D%22%23f5efe0%22%20stroke-width%3D%222.6%22%20stroke-linecap%3D%22round%22%2F%3E%3Cpath%20d%3D%22M11.6%2020.4L3.6%2028.4%22%20stroke%3D%22%231e2019%22%20stroke-width%3D%221.2%22%20stroke-linecap%3D%22round%22%2F%3E%3Ccircle%20cx%3D%2223.5%22%20cy%3D%228.5%22%20r%3D%222%22%20fill%3D%22%23c9d64f%22%2F%3E%3C%2Fsvg%3E");
}

/* --- §G1 · Website Design build durations in the caveat hand -------------- */
.li-pcard__note--hand {
  font-family: var(--li-hand); font-weight: 600;
  font-size: 1.22rem; line-height: 1.1; letter-spacing: 0;
  text-transform: none; opacity: 1; color: var(--li-lavender-deep);
  margin-top: .35rem;
}
.li-pcard--feature .li-pcard__note--hand { color: var(--li-lavender); opacity: 1; }

/* --- §G4 · Portfolio wall: six sites, then "load more" --------------------
   Ships expanded; li-motion collapses it on load and wires the button, so
   JS-off (and the editor canvas) still shows all 33 rather than hiding
   two-thirds behind a control that cannot work. */
.li-portfolio--wall.is-collapsed .li-portfolio__item--rest { display: none; }
.li-portfolio__loadwrap { display: flex; justify-content: center; margin: .4rem 0 2rem; }
.li-portfolio__load {
  font-family: var(--li-sans); font-weight: 700; font-size: .9rem;
  text-transform: uppercase; letter-spacing: .04em;
  padding: .8rem 1.8rem; border-radius: 999px; cursor: pointer;
  border: 2px solid var(--li-ink); background: var(--li-cream); color: var(--li-ink);
  transition: transform .25s var(--li-pop), box-shadow .25s ease, background-color .25s ease;
}
.li-portfolio__load:hover { background: var(--li-chartreuse); box-shadow: 4px 4px 0 var(--li-ink); transform: translateY(-2px); }
.li-portfolio__load:focus-visible { outline: 3px solid var(--li-lavender-deep); outline-offset: 3px; }
.li-portfolio-band .li-portfolio__load { background: var(--li-paper); }

/* --- §E · Dense grid, one section CTA ------------------------------------- */
.li-pcards--nobtn .li-pcard { padding-bottom: 1.6rem; }
.li-pcards--nobtn .li-pcard__sum { margin-bottom: auto; }
.li-pcards__cta { display: flex; flex-direction: column; align-items: center; gap: .6rem; margin: 2.2rem auto 0; }
.li-pcards__btn {
  font-family: var(--li-sans); font-weight: 700; font-size: 1rem;
  text-transform: uppercase; letter-spacing: .03em; text-decoration: none;
  padding: 1rem 2.4rem; border-radius: 999px;
  border: 2px solid var(--li-ink); background: var(--li-chartreuse); color: var(--li-ink);
  transition: transform .25s var(--li-pop), box-shadow .25s ease, background-color .25s ease;
}
.li-pcards__btn:hover { box-shadow: 5px 5px 0 var(--li-ink); transform: translateY(-2px); background: var(--li-chartreuse-soft); }
.li-pcards__btn:focus-visible { outline: 3px solid var(--li-forest); outline-offset: 3px; }
.li-pcards__note { margin: 0 !important; }

/* --- §F4 · The Example Doc band (the KDP Chapter 01 treatment, reusable) ---
   The mockup PNGs are transparent composites that carry their own tape and
   shadow, so they deliberately do NOT get the .li-imgframe border — a border
   would draw a box around the transparent bounding rectangle. */
.li-exdoc__cols { gap: clamp(1.6rem, 4vw, 3.4rem); align-items: center; }
.li-exdoc__shot { margin: 0 !important; }
.li-exdoc__shot img {
  display: block; width: 100%; height: auto;
  filter: drop-shadow(10px 14px 20px rgba(30,32,25,.20));
  transform: rotate(-1.4deg); transition: transform .45s var(--li-pop);
}
.li-exdoc__shot:hover img { transform: rotate(0) translateY(-6px) scale(1.015); }
.li-exdoc__shot figcaption { font-family: var(--li-hand); font-size: 1.2rem; color: var(--li-lavender-deep); text-align: center; margin-top: 1rem; }
.li-exdoc__kind { font-family: var(--li-sans); font-weight: 800; font-size: .64rem !important; letter-spacing: .18em; text-transform: uppercase; color: var(--li-lavender-deep); margin: 1.6rem 0 .6rem !important; }
.li-exdoc__gains { list-style: none; margin: 0 0 1.6rem; padding: 0; display: grid; gap: .55rem; }
.li-exdoc__gains li { position: relative; padding-left: 1.7rem; font-size: .96rem; line-height: 1.42; }
.li-exdoc__gains li::before { content: "\2726"; position: absolute; left: 0; top: .05em; color: var(--li-lavender-deep); }
.li-exdoc .wp-block-buttons { margin-top: 0; }
.li-exdoc .li-note { margin-top: 1.4rem !important; }
.li-exdoc .li-footnote { margin-top: 2.4rem; }
.has-forest-background-color .li-exdoc__kind, .has-forest-deep-background-color .li-exdoc__kind { color: var(--li-chartreuse); }
.has-forest-background-color .li-exdoc__gains li::before, .has-forest-deep-background-color .li-exdoc__gains li::before { color: var(--li-chartreuse); }
@media (max-width: 780px) {
  .li-exdoc__cols { flex-wrap: wrap; }
  .li-exdoc__cols .wp-block-column { flex-basis: 100% !important; }
  .li-exdoc__shot img { transform: rotate(-1deg); max-width: 420px; margin: 0 auto; }
}

/* --- §C3 · About Chapter 05: the fit test --------------------------------- */
.li-fit { display: grid; grid-template-columns: 1.15fr .85fr; gap: clamp(1.2rem, 3vw, 2.4rem); margin: 2.2rem 0 0; align-items: start; }
@media (max-width: 820px) { .li-fit { grid-template-columns: 1fr; } }
.li-fit__col { border: 2px solid var(--li-ink); border-radius: var(--li-radius); padding: 1.8rem 1.6rem 1.6rem; background: var(--li-paper); }
.li-fit__col--yes { background: var(--li-forest); color: var(--li-cream); box-shadow: 8px 10px 0 var(--li-chartreuse); }
.li-fit__col--no { background: var(--li-cream); box-shadow: 8px 10px 0 rgba(30,32,25,.13); }
.li-fit__label {
  font-family: var(--li-sans); font-weight: 800; font-size: .66rem !important;
  letter-spacing: .18em; text-transform: uppercase; margin: 0 0 1rem !important;
}
.li-fit__col--yes .li-fit__label { color: var(--li-chartreuse); }
.li-fit__col--no .li-fit__label { color: var(--li-lavender-deep); }
.li-fit__list { list-style: none; margin: 0; padding: 0; display: grid; gap: .85rem; }
.li-fit__list li { position: relative; padding-left: 1.75rem; font-size: .98rem; line-height: 1.45; }
.li-fit__col--yes .li-fit__list li { color: rgba(245,239,223,.92); }
.li-fit__list li::before { content: "\2726"; position: absolute; left: 0; top: .06em; }
.li-fit__col--yes .li-fit__list li::before { color: var(--li-chartreuse); }
.li-fit__col--no .li-fit__list li::before { content: "\00D7"; color: var(--li-lavender-deep); font-weight: 700; }
.li-fit__after { margin: 1.4rem 0 0 !important; font-family: var(--li-display); font-style: italic;
  font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 460; font-size: .95rem !important; opacity: .82; }
.li-fit + .li-pull { margin-top: 2.6rem; }

/* --- §H1 · The eyebrow line (was a stranded one-sentence lede) ------------ */
.li-eyebrowline {
  font-family: var(--li-display); font-style: italic;
  font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 460;
  font-size: 1rem !important; opacity: .78; margin: 0 0 .4rem !important; max-width: 46ch;
}

/* --- §I2 · The phone, scrolling real client feeds -------------------------
   Drawn entirely in CSS so it stays crisp at any size and costs no asset. The
   track carries the same set twice and animates to -50%, which is the same
   seamless-loop mechanism as the logo/ARC/IG marquees. */
.li-phone { position: relative; width: min(300px, 100%); margin: 0 auto; padding: 0; }
.li-phone__body {
  position: relative; aspect-ratio: 9 / 19; border-radius: 40px; padding: 11px;
  background: linear-gradient(160deg, #2b2e26 0%, #12140f 55%, #2b2e26 100%);
  border: 2px solid var(--li-ink);
  box-shadow: 0 0 0 3px rgba(245,239,224,.10), 14px 18px 0 rgba(30,32,25,.28);
}
.li-phone__notch {
  position: absolute; top: 13px; left: 50%; transform: translateX(-50%); z-index: 3;
  width: 84px; height: 20px; border-radius: 12px; background: #0c0e0a;
}
/* The screen is now a column: profile chrome, feed, action row — matching the
   frame reference Meg sent. The chrome carries NO invented handle or follower
   count; the bars are abstract placeholders exactly as in her own example. */
.li-phone__screen {
  position: relative; height: 100%; border-radius: 30px; overflow: hidden;
  background: var(--li-cream);
  display: flex; flex-direction: column;
}
.li-phone__viewport { position: relative; flex: 1; overflow: hidden; background: var(--li-ink); }
/* Duration + keyframe name are generated per grid-count in li_phone_scroll_markup(). */
.li-phone__track {
  display: block; will-change: transform;
  animation-timing-function: cubic-bezier(.66, 0, .28, 1);
  animation-iteration-count: infinite;
}
.li-phone__track img { display: block; width: 100%; height: auto; }
.li-phone:hover .li-phone__track,
.li-phone:focus-within .li-phone__track { animation-play-state: paused; }

.li-phone__chrome { flex: none; display: flex; align-items: center; background: var(--li-cream); }
.li-phone__chrome--top { gap: 8px; padding: 9px 10px; }
/* The story ring. Instagram's own gradient, but the avatar itself is a flat
   brand-lavender disc — no borrowed profile picture. */
.li-phone__avatar {
  flex: none; width: 26px; height: 26px; border-radius: 50%;
  background: var(--li-lavender);
  box-shadow: 0 0 0 2px var(--li-cream), 0 0 0 3.5px #e1306c;
}
.li-phone__lines { flex: 1; display: grid; gap: 4px; }
.li-phone__bar { display: block; height: 5px; border-radius: 3px; background: rgba(30,32,25,.22); }
.li-phone__bar--short { width: 42%; }
.li-phone__bar--stub  { width: 22%; }
.li-phone__bar--wide  { width: 66%; }
.li-phone__bar--accent { width: 34%; background: var(--li-lavender-deep); opacity: .7; }
.li-phone__dots {
  flex: none; width: 14px; height: 4px; border-radius: 2px;
  background: radial-gradient(circle 2px at 2px 2px, rgba(30,32,25,.5) 99%, transparent 100%) 0 0/6px 4px repeat-x;
}
.li-phone__chrome--bottom { flex-direction: column; align-items: stretch; gap: 6px; padding: 9px 10px 12px; }
.li-phone__acts { display: flex; align-items: center; gap: 11px; }
.li-phone__ico { width: 17px; height: 17px; fill: none; stroke: var(--li-ink); stroke-width: 1.7; stroke-linejoin: round; }
.li-phone__ico--save { margin-left: auto; }
.li-phone__caption { display: grid; gap: 4px; }
@media (max-width: 780px) { .li-phone { width: min(260px, 100%); } }
@media (prefers-reduced-motion: reduce) {
  /* Still, not hidden: the reader sees the top of a feed and nothing moves. */
  .li-phone__track { animation: none !important; }
}
/* Side buttons — small, but they are what makes it read as a device. */
.li-phone__btn { position: absolute; right: -4px; width: 4px; border-radius: 3px; background: #3a3d33; }
.li-phone__btn--power { top: 27%; height: 8%; }
.li-phone__btn--vol { left: -4px; right: auto; top: 19%; height: 12%; }
.li-phone-band .li-chapter__num, .li-phone-band .li-chapter__name { color: var(--li-cream); }
/* The width and reduced-motion rules for this device now live with the chrome
   block above. They were duplicated here; the copy without !important lost to
   the generated per-grid-count animation, so reduced motion did not actually
   stop the scroll. */

/* --- §K2 · Affiliate pages: "see it working" ------------------------------ */
.li-affres__grid { display: grid; grid-template-columns: 1.05fr .95fr; gap: clamp(1.2rem, 3vw, 2.2rem); margin-top: 2.2rem; align-items: start; }
.li-affres__grid--nov { grid-template-columns: repeat(3, 1fr); }
/* Four-card no-video band (Publisher Rocket, dev-final session 4): 2×2, not
   four columns. See li_affiliate_resources_markup() for the measurement. */
.li-affres__grid--nov2 { grid-template-columns: repeat(2, 1fr); }
.li-affres__grid--nov2 .li-affres__links { display: contents; }
@media (max-width: 860px) { .li-affres__grid, .li-affres__grid--nov, .li-affres__grid--nov2 { grid-template-columns: 1fr; } }
.li-affres__video { position: relative; aspect-ratio: 16 / 9; border: 2px solid var(--li-ink);
  border-radius: var(--li-radius); overflow: hidden; box-shadow: 8px 10px 0 rgba(30,32,25,.16); background: var(--li-ink); }
.li-affres__video iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.li-affres__links { display: grid; gap: 1rem; align-content: start; }
.li-affres__grid--nov .li-affres__links { display: contents; }
.li-affres__card {
  position: relative; display: block; text-decoration: none; color: var(--li-ink);
  background: var(--li-paper); border: 2px solid var(--li-ink); border-radius: var(--li-radius);
  padding: 1.2rem 3rem 1.2rem 1.3rem;
  transition: transform .25s var(--li-pop), box-shadow .25s ease, background-color .25s ease;
}
.li-affres__card:hover { transform: translateY(-3px); box-shadow: 6px 8px 0 rgba(30,32,25,.18); background: var(--li-cream); }
.li-affres__card:focus-visible { outline: 3px solid var(--li-lavender-deep); outline-offset: 3px; }
.li-affres__kicker { display: block; font-family: var(--li-sans); font-weight: 800; font-size: .6rem; letter-spacing: .18em; text-transform: uppercase; color: var(--li-lavender-deep); }
.li-affres__title { display: block; font-family: var(--li-display); font-weight: 600; font-size: 1.2rem; line-height: 1.12; margin: .35rem 0 .4rem; }
.li-affres__desc { display: block; font-size: .89rem; line-height: 1.42; opacity: .82; }
.li-affres__go { position: absolute; top: 1.2rem; right: 1.1rem; width: 30px; height: 30px; display: grid; place-items: center;
  border: 2px solid var(--li-ink); border-radius: 50%; background: var(--li-chartreuse); font-weight: 700; }
.li-affres__card:hover .li-affres__go { transform: translateX(2px); }

/* --- §K2 · Resources: the affiliate tag, and the referral list ------------ */
.li-afftag {
  display: inline-block; font-family: var(--li-sans); font-style: normal;
  font-weight: 800; font-size: .56rem; letter-spacing: .16em; text-transform: uppercase;
  padding: .18rem .5rem; border-radius: 999px; vertical-align: .12em;
  background: var(--li-lavender); color: var(--li-ink); border: 1.5px solid var(--li-ink);
}
.li-card--chartreuse .li-afftag, .li-card--lavender .li-afftag { background: var(--li-cream); }
.li-reflist { list-style: none; margin: 1.6rem 0 0; padding: 0; display: grid; grid-template-columns: repeat(2, 1fr); gap: .7rem 1.6rem; }
@media (max-width: 700px) { .li-reflist { grid-template-columns: 1fr; } }
.li-reflist li { position: relative; padding-left: 1.6rem; }
.li-reflist li::before { content: "\2726"; position: absolute; left: 0; top: .05em; color: var(--li-lavender-deep); }

/* --- A1 belt-and-braces (LI-P2b, post-push) -------------------------------
   Found by measuring the pushed pages, not by reading the source: two band
   helpers build their div's class list by PHP concatenation, so the tagging
   pass gave them `li-col-1150` in the block comment and NOT in the rendered
   class attribute. Digital Strategy's showcase band therefore still drifted
   81px at 1440. The helpers are fixed, but a component that knows its own
   content width should not depend on a class being remembered — so the
   width is declared here too, and the class stays as the general mechanism. */
.li-showcase, .li-exdoc, .li-affres, .li-quotes-band, .li-mockup-band { --li-col: 1150px; }
.li-portfolio-band, .li-logos, .li-arcwall-band { --li-col: 1240px; }
.li-faq-section { --li-col: 880px; }

/* ==========================================================
   v1.10.2 · SESSION QA-2 — the QA-1 fix list
   Everything below is a numbered item from QA-1's ranked list,
   applied at source. Contrast figures are measured, not
   estimated: composited RGB against the actual band colour.
   ========================================================== */

/* --- P1·1 + P1·2 · The Fluent Forms skin -------------------
   Contact (form 3) and ARC Submission (form 5) were rendering
   in the plugin's factory theme: -apple-system at 13.3px, grey
   borders, and a bright blue submit button that did not even
   match itself between the two forms. They are the two money
   paths on the site. 16px on the controls is deliberate — iOS
   Safari zooms the viewport on focus for anything under it. */
.fluentform, .fluentform * { font-family: var(--li-sans); }
.fluentform .ff-el-group { margin-bottom: 1.35rem; }
.fluentform .ff-el-input--label label,
.fluentform .ff-el-input--label.ff-el-is-required label {
  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; }

.fluentform .ff-el-form-control,
.fluentform select.ff-el-form-control,
.fluentform textarea.ff-el-form-control {
  width: 100%;
  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; }

/* The focus state QA-1 item 2 was actually about: 23 of ARC
   Submission's 30 fields had no visible focus style at all,
   because the theme had never styled .ff-el-form-control. */
.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; }

/* The submit button joins the sitewide button contract:
   chartreuse, forest ink, CAPS, hard shadow, no blue. */
.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;
  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;
}
/* Fluent Forms' own section-break headings inherit the display face
   so they read as part of the page, not as plugin chrome. */
.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; }
/* Forms sitting on a dark band keep readable labels. */
.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); }

/* --- P1·3 · Announcement bar, phone widths -----------------
   The bar grows to two lines rather than clipping. The height
   token drives .li-head's offset and the hero clearance, so
   moving it here moves the whole stack correctly. */
@media (max-width: 640px) {
  :root { --li-topbar-h: 54px; }
  .li-topbar { font-size: .72rem; letter-spacing: .015em; }
  .li-topbar__msg { padding: 0 .7rem; }
}
@media (max-width: 380px) {
  :root { --li-topbar-h: 58px; }
  .li-topbar { font-size: .70rem; } /* v1.30.0 · was .64rem (10.24px); floor lifted with the shorter Reading Room line */
}

/* --- P1·4 · The hamburger is the only route to navigation on
   a phone, and it was 24×24. Core sizes the icon, not the
   button, so the target is set here. Close button matches. */
.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, measured in QA-2's pre-flight ---------------
   Core switches the "mobile" overlay menu off at exactly 600px, and the LI
   nav is 463px of links that never shrink. Between 600 and 819 the logo,
   the nav and the booking button therefore do not fit: the CTA's right edge
   sat 121px past the viewport at 600, 74px at 700 and 9px at 768. It never
   registered as horizontal overflow because .li-head clips — the same blind
   spot as the announcement bar and the header CTA. So the overlay is held
   open-able up to 819 instead of 600. The is-menu-open styling this relies
   on is the one LI-P1 already built and verified. */
@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
   deliberately does NOT blanket every anchor — it raises the
   controls that stand alone: card CTAs, the read-more summary,
   the pricing "i", and the pill filters. */
.li-card__cta a, .li-portfolio__more a, .li-arcwall__more a {
  display: inline-flex; align-items: center; min-height: 44px;
}
.li-readmore .wp-block-details summary { min-height: 44px; display: flex; align-items: center; }
.li-pmenu__row > summary { min-height: 44px; }
.li-pills a, .li-pill { min-height: 44px; display: inline-flex; align-items: center; }

/* --- P2·8 · Heading order ----------------------------------
   Three fixes, all in the patterns; this is the CSS they need.
   · Link in Bio renders with no header or footer by design and
     had no heading at all, not even an H1 — it gets a real H1
     that reads to assistive tech without growing a second
     visible title on a page whose whole point is the logo.
   · First Draft (H1→H3) and ARC Submission (H1→H3, Fluent
     Forms' own section headings) had their section title sitting
     in a paragraph. On those two pages `.li-chapter__name` is
     promoted to an H2. It already declares every font property,
     so the only thing to neutralise is heading margin. */
/* ⚠ CORRECTED v1.27.0 (2026-08-04). The note above is wrong: the class does
   NOT hold every font property. `.li-chapter__name` sets `font-size: .8rem`
   with no !important, and theme.json emits the h2 preset size as an element
   style that outranks it. So an h2 carrying this class rendered as 36.8px
   POPPINS, UPPERCASE, 7.36px tracking — heading size with eyebrow styling.
   Meg caught it on /thank-you, which is where the stale live page still has
   the class on its h2. Verified in the browser, not inferred.
   Pinning size, line-height and weight makes the chip look like a chip on any
   heading level, so a stale page can no longer render a fake display font. */
h2.li-chapter__name, h3.li-chapter__name {
  margin: 0 !important; line-height: inherit;
  font-size: .8rem !important; font-weight: 700 !important;
  letter-spacing: .2em; font-family: var(--li-sans) !important;
}
.li-sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* --- 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); }

/* --- Header CTA, phone widths — found by QA-2's own measurement, not on
   QA-1's list. The long label ran 243px wide from x=181, so it sat past
   the right edge at 320/375/390/414 and rendered as "BOOK A FREE DISCOVERY
   CA". It never showed up as horizontal overflow because .li-head clips it,
   the same reason the announcement bar's truncation hid from the width
   sweep. Two buttons in the header part, one visible per breakpoint, so
   the phone keeps a persistent booking CTA instead of losing it. */
.li-head__cta { margin: 0 !important; }
/* Specificity note: core ships `.wp-block-buttons > .wp-block-button
   { display: inline-block }` at 0-2-0, so a single class here loses and both
   buttons render. Measured, not guessed — the first draft of this rule showed
   both labels at every width. */
.li-head__cta > .li-head__cta--short { display: none; }
@media (max-width: 900px) {
  .li-head__cta > .li-head__cta--full { display: none; }
  .li-head__cta > .li-head__cta--short { display: inline-block; }
  .li-head__cta--short .wp-block-button__link { padding: .7rem 1.1rem; font-size: .72rem; white-space: nowrap; }
}
@media (max-width: 360px) {
  .li-head__cta--short .wp-block-button__link { padding: .62rem .85rem; font-size: .68rem; }
}

/* ==========================================================
   §P2-1 · RESULTS — reviews in the blog's card language, and
   the Google 5.0 rescued as a credential.
   Meg, 2026-07-27: "Visually, this page needs more work. The
   5-star on google, is lost… i said to style this like the
   blog, as I am going to load the case studies as blog posts."

   Two separate problems, two separate fixes.

   1. `.li-revcard` is deliberately a SIBLING of `.li-postcard`,
      not a variant of `.li-quotes`. Same paper, same 2px ink
      border, same --li-radius, same lift-on-hover, and a real
      CSS grid instead of the masonry `columns` the quote walls
      use. That is the whole point: once the case studies land
      as posts, the review cards and the post cards on this page
      have to read as one family. Untilted on purpose — the
      bubbles' nth-child rotations are what made the two
      families look unrelated.
   2. `.li-cred` states the Google score ONCE, in its own band
      under the hero, because the old hero stamp could not carry
      it: `.li-stamp` is absolutely positioned inside the same
      `.li-pagehero` box `.li-shapes` decorates, so it competed
      with the hero decoration and a second `.li-google` badge
      repeated the claim 2,000px further down.
      The `li_google_cred_markup()` helper that emitted this band
      was removed on 2026-08-04 with the Results page, its only
      caller. The classes stay: they still describe the markup
      archived at `wordpress-theme/_retired-patterns/`, and the
      band is the reference if Meg ever wants the credential on
      another page.
   ========================================================== */
.li-revcards { display: grid; gap: 1.2rem; margin-top: 2.2rem; }
.li-revcards--3 { grid-template-columns: repeat(3, 1fr); }
.li-revcards--2 { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 1100px) { .li-revcards--3 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 680px)  { .li-revcards--3, .li-revcards--2 { grid-template-columns: 1fr; } }

.li-revcard {
  display: flex; flex-direction: column; gap: .9rem;
  background: var(--li-paper); color: var(--li-ink);
  border: 2px solid var(--li-ink); border-radius: var(--li-radius);
  padding: 1.5rem 1.4rem 1.3rem;
  transition: box-shadow .3s ease, transform .3s var(--li-pop);
}
.li-revcard:hover { box-shadow: 8px 10px 0 rgba(30,32,25,.16); transform: translateY(-4px); }
/* The feature card spans the row on a 3-col grid, and half of it on 2-col —
   it carries the single strongest result on the page and has to out-weigh the
   cards beside it without becoming a section of its own again. */
.li-revcards--3 .li-revcard--feature { grid-column: span 2; background: var(--li-chartreuse); }
.li-revcards--2 .li-revcard--feature { background: var(--li-chartreuse); }
@media (max-width: 680px) { .li-revcards--3 .li-revcard--feature { grid-column: span 1; } }

.li-revcard__tag {
  margin: 0 !important; align-self: flex-start;
  font-family: var(--li-sans); font-weight: 700; font-size: .68rem;
  letter-spacing: .1em; text-transform: uppercase;
  padding: .34rem .8rem; border: 1.5px solid var(--li-ink); border-radius: 999px;
}
.li-revcard__q { margin: 0 !important; padding: 0 !important; border: 0 !important; background: none !important; }
.li-revcard__q p {
  margin: 0; font-family: var(--li-display);
  font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 470;
  font-size: 1.12rem; line-height: 1.38;
}
.li-revcard--feature .li-revcard__q p { font-size: 1.34rem; }
.li-revcard__by {
  display: flex; align-items: center; gap: .85rem;
  margin-top: auto; padding-top: .3rem;
}
.li-revcard__cover {
  flex: 0 0 auto; width: 42px; height: 62px; object-fit: cover;
  border: 1.5px solid var(--li-ink); border-radius: 3px;
  box-shadow: 2px 3px 0 rgba(30,32,25,.18);
  transform: rotate(-2.5deg);
  transition: transform .3s var(--li-pop);
}
.li-revcard:hover .li-revcard__cover { transform: rotate(0) scale(1.06); }
.li-revcard__who { display: grid; gap: .1rem; }
.li-revcard__who strong {
  font-family: var(--li-sans); font-weight: 700; font-size: .82rem;
  letter-spacing: .06em; text-transform: uppercase;
}
.li-revcard__who span { font-family: var(--li-sans); font-size: .78rem; opacity: .68; }

/* --- The credential band --------------------------------------------------- */
.li-cred {
  display: flex; align-items: center; gap: clamp(1.2rem, 3vw, 2.6rem);
  flex-wrap: wrap;
  max-width: 1150px; margin: 0 auto;
  padding: clamp(1.6rem, 3vw, 2.2rem) clamp(1.4rem, 3vw, 2.4rem);
  background: var(--li-cream-deep); color: var(--li-ink);
  border: 2px solid var(--li-ink); border-radius: var(--li-radius);
}
.li-cred__score { display: grid; gap: .1rem; place-items: center; flex: 0 0 auto; }
.li-cred__num {
  font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1;
  font-weight: 600; font-size: clamp(3rem, 7vw, 4.4rem); line-height: .9;
}
.li-cred__stars { color: var(--li-lavender-deep); letter-spacing: .18em; font-size: 1.05rem; }
.li-cred__read { flex: 1 1 22rem; }
.li-cred__read p { margin: 0; }
.li-cred__lead { font-size: clamp(1.05rem, 2vw, 1.25rem); }
.li-cred__sub { margin-top: .5rem !important; font-size: .92rem; opacity: .8; max-width: 62ch; }
@media (max-width: 620px) {
  .li-cred { flex-direction: column; align-items: flex-start; }
  /* `flex: 1 1 22rem` resolves against the MAIN axis, so the moment the band
     turns into a column that 22rem became a 352px minimum HEIGHT and left a
     dead half-screen under the text. Measured at 390 in the pre-upload
     harness. */
  .li-cred__read { flex: 0 1 auto; }
  .li-cred__score { place-items: start; }
}

/* ==========================================================
   §P2-2 · THE TITLE-CARD (post cards, everywhere)
   Meg, 2026-07-27: "Instead of the featured image, can we make
   it display the title section as the featured image? Where it
   shows the title, on the green background, maybe with some of
   the elements moving? … And then below it, have the date, and
   short description… (so we aren't repeating the title)."

   The title moves INTO the card head, so the card is:
     green title block → date → excerpt.
   There is no second title underneath, which was the specific
   repetition she was pointing at.

   Motion is CSS-only on two pseudo-elements, deliberately, not
   the JS `li-shapes` device the heroes use: a query loop renders
   nine of these and li-motion.js has no per-card hook, so a
   JS-driven decor would have to be wired per card and would
   simply be absent with JS off. Pseudo-elements need neither.

   The drift is 3–4px over 9–11s. That is under the 20px rule
   recorded for `.li-anim` (headings sit 20px above the copy
   below them) and it never leaves the card, which is
   `overflow:hidden`.
   ========================================================== */
.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;
}
/* Kill the flat-card padding rules — the title is inside the green block now. */
.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; }

/* --- the moving element ----------------------------------------------------
   ::after is the brand ✱ in chartreuse. It sits behind the title (z-index 2
   above) and is clipped by the card.

   ⚠ THE LAVENDER DISC IS GONE — S3, 2026-08-02, Meg's instruction: "Remove the
   weird purple circle in the featured preview (purple not used elsewhere)."
   The `::before` rule that painted it, and its two nth-child repositions, are
   deleted rather than recoloured; she asked for it removed, not restyled. The
   ✱ keeps its per-position variance on its own, so nine cards in a grid still
   do not read as a stamp. The card she loves — forest block, cream Fraunces
   title in place of a featured image — is otherwise untouched.
   Do not reintroduce a disc here in any colour without asking her. */
.li-titlecard::after { content: ""; position: absolute; z-index: 1; pointer-events: none; }
.li-titlecard::after {
  content: "✱";
  font-family: var(--li-sans); font-size: 3.6rem; line-height: 1;
  color: var(--li-chartreuse); opacity: .42;
  left: -.6rem; top: .3rem;
  animation: li-tc-spin 9s ease-in-out infinite alternate;
}
@keyframes li-tc-spin {
  from { transform: rotate(-8deg) translate3d(0, 0, 0); }
  to   { transform: rotate(14deg) translate3d(3px, -3px, 0); }
}
/* Nine identical cards would read as a stamp, so the ✱ is offset per position
   in the row. The colour stays green throughout — that part was Meg's
   instruction, not a default. */
.li-postcard--tc:nth-child(3n+2) .li-titlecard::after  { left: -.5rem; right: auto; top: auto; bottom: -.4rem; font-size: 3.2rem; }
.li-postcard--tc:nth-child(3n)   .li-titlecard::after  { left: auto; right: -.4rem; top: auto; bottom: -.6rem; font-size: 4.2rem; }

@media (prefers-reduced-motion: reduce) {
  .li-titlecard::after { animation: none; }
}

/* Blog cards: playful tilt + washi tape (Meg 2026-08-06: "make it more fun...
   posts slightly tilted like other elements... some of them have tape"). The
   tilt is subtle, alternates by grid position, and straightens on hover — the
   same behaviour as .li-inlinesvg — and because rotate is a paint transform it
   never shifts the grid. The tape reuses the .li-imgframe--tape colour so the
   whole site reads as one scrapbook; it lands on a couple of cards, not all. */
.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: var(--li-tape); border: var(--li-tape-edge);
  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-postcard--tc,
  .li-postcard--tc:nth-child(odd),
  .li-postcard--tc:nth-child(even),
  .li-postcard--tc:hover { transform: none; }
}

/* ==========================================================
   §P2-3 · THE INLINE SVG FRAME
   Only the Author Websites graphic uses this. Everything else
   in the diagram family is an <img> and keeps `li-imgframe`.
   The tape and the tilt are copied from `li-imgframe--tape` so
   the two read as the same device; what differs is that this
   one's contents can animate.
   ========================================================== */
.li-inlinesvg { position: relative; margin: 0; transform: rotate(-1.2deg); transition: transform .3s var(--li-pop); }
.li-inlinesvg:hover { transform: rotate(0); }
.li-inlinesvg svg { display: block; width: 100%; height: auto; }

/* S4 (2026-08-03) — a STANDALONE inlined diagram, not one in a 46% media column.
   Every other .li-inlinesvg sits in a half-width column, where width:100% is
   correct. SmarterQueue places one as its own band, and at the 1150px content
   width it measured 1155 x 954px — the title rendering at 39px and a large dead
   ring centre. Constrained here, in the theme's own CSS, rather than by wrapping
   it in a li-col-820 group: li-col-* only sets --li-col for the .li-section
   rules, and the real max-width would have come from WordPress's generated
   layout style, which this theme does not control. */
.li-inlinesvg--band { max-width: 820px; margin-inline: auto; }
.li-inlinesvg::before {
  content: ""; position: absolute; top: -12px; left: 50%; transform: translateX(-50%) rotate(-3deg); z-index: 2;
  width: 110px; height: 28px; background: var(--li-tape); border: var(--li-tape-edge); border-radius: 2px;
}
/* 2026-08-31: the six service-graphic SVGs are transparent sticker scenes with
   their own drawn tape; hide the figure's floating tape for those six only. */
.li-inlinesvg:has(.so-gfx,.ss-gfx,.nl-gfx,.wa-gfx,.bl-gfx,.kl-gfx)::before{display:none}

.li-inlinesvg figcaption {
  font-family: var(--li-hand); font-size: 1.15rem;
  color: var(--li-lavender-deep); text-align: center; margin-top: .6rem;
}

/* Pricing's value chart: the SVG is 1000px wide inside a 1200px band, so it is
   capped rather than upscaled, and given air away from the cards above it. */
.li-pricechart { max-width: 1000px; margin: clamp(2.6rem, 5vw, 4rem) auto 0 !important; }

/* ==========================================================
   §P2-4 · THE GLANCE CARD (ARC — "What you get, at a glance")
   Paper card, ink border, chartreuse tape, drawn tick boxes.
   Two columns from 900px, one below it. The tilt is on hover
   only: five rows of copy set permanently askew is harder to
   read, and the tape already says "object" while it is still.
   ========================================================== */
.li-glance {
  position: relative;
  max-width: 940px; margin: clamp(3rem, 5vw, 4.2rem) auto 0;
  padding: clamp(2rem, 4vw, 2.8rem) clamp(1.4rem, 3vw, 2.4rem) clamp(1.6rem, 3vw, 2.2rem);
  background: var(--li-paper); color: var(--li-ink);
  border: 3px solid var(--li-ink); border-radius: var(--li-radius);
  box-shadow: 8px 10px 0 rgba(30,32,25,.14);
  transition: transform .3s var(--li-pop);
}
.li-glance:hover { transform: rotate(-.6deg); }
.li-glance::before {
  content: ""; position: absolute; top: -14px; left: 50%;
  transform: translateX(-50%) rotate(-3deg);
  width: 132px; height: 30px; background: var(--li-tape); border: var(--li-tape-edge);
  border-radius: 2px;
}
.li-glance__head {
  margin: 0 0 1.6rem !important; text-align: center;
  font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1;
  font-weight: 600; font-size: clamp(1.4rem, 2.6vw, 1.85rem);
}
.li-glance__list {
  list-style: none; margin: 0 !important; padding: 0 !important;
  display: grid; gap: 1.1rem 2.2rem;
}
@media (min-width: 900px) { .li-glance__list { grid-template-columns: 1fr 1fr; } }
.li-glance__list li {
  display: grid; grid-template-columns: 30px 1fr; column-gap: .9rem;
  align-items: start; padding-left: 0;
}
.li-glance__box {
  grid-row: span 2; align-self: center;
  width: 26px; height: 26px; border: 2.5px solid var(--li-ink); border-radius: 6px;
  background: var(--li-chartreuse); position: relative;
}
/* The tick is drawn, not a ✓ glyph: the glyph's weight varies wildly by
   fallback font and it was noticeably lighter than the border beside it. */
.li-glance__box::after {
  content: ""; position: absolute; left: 7px; top: 3px;
  width: 8px; height: 14px;
  border: solid var(--li-ink); border-width: 0 3px 3px 0;
  transform: rotate(42deg);
}
.li-glance__t { font-family: var(--li-sans); font-weight: 600; font-size: 1.02rem; line-height: 1.3; }
.li-glance__s { grid-column: 2; font-family: var(--li-sans); font-size: .86rem; opacity: .72; margin-top: .18rem; }
.li-glance__foot {
  margin: 1.8rem 0 0 !important; padding-top: 1.2rem;
  border-top: 2px dashed rgba(30,32,25,.22);
  text-align: center; font-size: .95rem;
}

/* ── THE GLANCE BAND (S2, 2026-08-02) ─────────────────────────────────────
   The card above became the sitewide Chapter 02 on all seven service pages,
   so it needed a section wrapper — see li_glance_band_markup() in
   functions.php for why that is one function and not seven.

   The card's own top margin (clamp 3rem–4.2rem) was tuned for its old life
   TACKED ON THE END of a chapter, under body copy. At the top of its own band,
   directly under a lede, that margin reads as a gap. Reset it here and let the
   section's padding do the spacing, which is what every other band does.

   In the 50:50 variant the card must not also be centred at 940px inside a
   56% column — it would sit off-centre against its own section. Full width of
   the column, and the tape stays centred on the card rather than on the band. */
.li-glance-band .li-glance { margin-top: clamp(1.8rem, 3vw, 2.4rem); }
.li-glance__dl { margin-top: clamp(1.4rem, 2.5vw, 1.9rem); }
.li-glance-band .li-glance__dl { display: flex; justify-content: center; }
/* The 50:50 variant overrides both of the above, so it comes after them —
   these selectors are the same specificity and source order decides. */
.li-glance__cols .li-glance { max-width: none; margin-left: 0; margin-right: 0; }
.li-glance__cols .li-glance__dl { justify-content: flex-start; }
.li-glance-band .li-note--left { margin-top: 1rem; }

/* Phase 2 components are explicitly border-box. The theme carries NO global
   reset (Phase 1 established that, and it is what made `.li-pcard__btn`
   compute 12px wider than its own card), so every new padded box states it for
   itself rather than relying on the container chain to absorb the padding.
   Measured 0 horizontal overflow at 320/360/390/414/768/1024 with this in. */
.li-cred, .li-revcard, .li-glance, .li-titlecard, .li-inlinesvg { box-sizing: border-box; }
.li-glance__list li, .li-revcard__by { box-sizing: border-box; }

/* ── The First Draft signup form (v1.14.0, 2026-07-28) ────────────────────
   MailerLite raised its prices, so LI's email moved to self-hosted Listmonk
   and the JS embed became a plain form posting to /subscription/form.

   Net effect on this page: one fewer third-party script, no render-blocking
   external request, and the form works with JavaScript disabled — which is
   why the old <noscript> escape hatch could be deleted rather than ported.

   `.screen-reader-text` is defined here because block themes do not inherit
   it from core. Without it the visually-hidden label renders as visible text
   above the field.
   ------------------------------------------------------------------------ */
.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;
}

.li-signup__form {
  display: flex; flex-wrap: wrap; gap: .7rem;
  align-items: stretch; margin: 0 auto; max-width: 34rem;
}
.li-signup__email {
  flex: 1 1 16rem; min-width: 0;
  padding: .85rem 1.1rem;
  font: inherit; font-size: 1rem; color: var(--li-ink, #1e2019);
  background: #fff;
  border: 2px solid var(--li-ink, #1e2019);
  border-radius: 999px;
}
.li-signup__email::placeholder { color: rgba(30,32,25,.55); }
.li-signup__email:focus-visible {
  outline: 3px solid var(--li-chartreuse, #c9d64f); outline-offset: 2px;
}
.li-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;
}
.li-signup__button:hover { filter: brightness(1.06); }
.li-signup__button:focus-visible {
  outline: 3px solid var(--li-ink, #1e2019); outline-offset: 3px;
}
/* Listmonk honeypot — must exist, must stay empty, must never be seen. */
.li-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;
}

/* ==========================================================
   §S3 · PAGE REBUILDS (2026-08-02)
   Meg's per-page fix list for the go-live weekend. Everything
   in this block is a named item from FINAL_POLISH_BRIEF_2026-07-31.
   ========================================================== */

/* --- S3·1 · The beige stripe above the footer -------------
   Meg flagged it on the single blog post ("kill the beige space between last
   section and footer"), but the cause is sitewide and structural, not a
   post-template quirk. `<main>` and `<footer>` are siblings inside
   `.wp-site-blocks`, and WordPress gives every one of those siblings
   `margin-block-start: var(--wp--style--block-gap)` — measured on live dev:
   20px. The page ground is cream, so on any page whose last band is dark that
   20px paints as a beige stripe between the CTA and the ink footer. On pages
   ending in a cream read-more it was simply invisible, which is why it only
   ever got reported on single posts.
   Killing it on the wrapper's children fixes every page at once. Safe on the
   leading edge too: the heroes carry their own `calc(var(--li-head-h) + …)`
   top padding for the fixed header, so <main>'s 20px was pure surplus there. */
.wp-site-blocks > * { margin-block-start: 0; }

/* --- S3·2 · Single post: headings in the dark green --------
   Meg: "In-post headings → the dark green shade." Body copy stays ink; only
   the headings take forest, so the hierarchy reads at a glance down a long
   post. Scoped to `.li-prose` so it cannot leak into the read-more accordions,
   which sit on their own surfaces and are already resolved. */
.li-prose h2, .li-prose h3, .li-prose h4 { color: var(--li-forest); }

/* --- S3·3 · Single post: categories as individual pills ----
   Was one long chip wrapping every category and the ", " separators, so a post
   in three categories rendered as a single sausage. The chip styling moves off
   the wrapper and onto each `a`; the block's separator is set to a space in
   the template and the separator span is hidden outright, since a gap does the
   same job without a stray comma inside the flex row. */
.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: .8rem; letter-spacing: .06em;
  padding: .45rem 1rem; border-radius: 999px;
  background: transparent; color: var(--li-cream);
  border: 1.5px dashed var(--li-cream);
  text-decoration: none; transform: rotate(1.5deg);
  transition: background .25s ease, color .25s ease;
}
.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; }

/* --- S3·4 · Single post: "Back to the blog" as a button ----
   It was a `.li-footnote` paragraph — italic, 65% opacity, 0.85rem — which is
   the styling for a caption, not for the one control that gets a reader back
   out of a post. It is now a real button on the cream prose surface, so S1's
   inverted CTA default applies to it unchanged (dark pill, no new colour
   decision) and it clears the 44px tap target the standalone-control rule
   already asks for. */
.li-backblog { margin-top: 2rem; }

/* The blog card's date rules are now unreachable — `wp:post-date` is out of
   page-blog, index and search per Meg's "remove the date from the card
   display". Left defined deliberately, same discipline as `.li-timeline` and
   `li_rotor_badge_markup()`: if she ever wants the date back it is a one-line
   template change, not a restyle. Do not tidy them away.
   (`.li-postcard .wp-block-post-date`, `.li-postcard--tc .wp-block-post-date`) */

/* --- S3·5 · About Chapter 05 on the glance component -------
   Two glance cards, yes and no, in place of the one-off `.li-fit` device.
   The card, the tape, the paper and the box are the sitewide standard already;
   the only thing this adds is the negative state, because a fit test that
   ticks its "probably not you" list would read as a promise.
   The × is drawn with gradients rather than a ✗ glyph, for the same reason the
   tick above is drawn and not a ✓: glyph weight swings wildly by fallback font
   and would not match the 2.5px border beside it. */
.li-fitcards .wp-block-column { display: flex; }
.li-fitcards .li-glance { width: 100%; }
/* `.li-glance__list` goes two-up at a 900px VIEWPORT, which is the right call
   for a full-width band and the wrong one here: these cards sit in a 50:50, so
   each list had ~250px per cell and "You want someone to run ads at a book that
   isn't finished yet." broke over five lines. Measured in Chrome, not guessed.
   A container query would be the modern fix, but nothing else in this stylesheet
   declares a container and adding one contract for a single band is worse than
   one honest override. */
.li-fitcards .li-glance__list { grid-template-columns: 1fr; }
.li-glance--no .li-glance__box { background: var(--li-lilac); }
.li-glance--no .li-glance__box::after {
  left: 50%; top: 50%; width: 15px; height: 15px; margin: -7.5px 0 0 -7.5px;
  border: 0; transform: none;
  background:
    linear-gradient(45deg,  transparent 43%, var(--li-ink) 43%, var(--li-ink) 57%, transparent 57%),
    linear-gradient(-45deg, transparent 43%, var(--li-ink) 43%, var(--li-ink) 57%, transparent 57%);
}
/* Two cards side by side, each ~540px, so the list stays single-column and the
   titles keep their measure. Below the columns breakpoint they stack and the
   second card needs its own breathing room from the first. */
@media (max-width: 781px) { .li-fitcards .li-glance { margin-top: clamp(2rem, 5vw, 3rem); } }

/* `.li-fit`, `.li-fit__col`, `.li-fit__list`, `.li-fit__label`, `.li-fit__after`
   are now unreachable — About Chapter 05 was their only caller. Left defined
   deliberately (same discipline as `.li-timeline`). NOTE for the CTA contrast
   allowlist: `.li-fit__col--yes` is still enumerated there as a dark surface;
   it is harmless while unused and must NOT be removed from that list without
   checking nothing else has adopted the class. */

/* --- S3·6 · LINK CONTRAST INSIDE A LIGHT CARD ON A DARK BAND ------
   Meg, on Home Chapter 03 and on the Services hub: the "read more" / "start
   there" / "explore …" CTAs are "all chartreuse and lost".

   MEASURED on live dev before touching anything — this is a real failure, not
   a taste call, and the worst case is not a near-miss:
     Services ch02, "Explore Digital Strategy →"   1.00:1  (chartreuse text on
                                                            a chartreuse card —
                                                            literally invisible)
     Services ch02, the other six "Explore …" CTAs 1.51:1  (chartreuse on paper)
   For contrast, the same CTAs in Chapter 01, which sits on the page ground,
   measure 7.11–15.65:1. The links were only failing where the SECTION is dark.

   Cause: the dark-band link rule (`.has-forest-*-background-color a`) colours
   every non-button anchor chartreuse, which is right for a link sitting on the
   band itself and wrong for one sitting inside a card that carries its own pale
   fill. The follow-up `.li-card a` rule swapped the underline for a chartreuse
   border and left the text colour alone, so the bug survived a pass that was
   looking straight at it.

   The principle, matching S1's CTA block: a link is coloured by the surface it
   is PAINTED ON, not by the band its section happens to have. Cards that are
   themselves dark (li-card--forest, li-card--ink, li-principle) are excluded
   and keep chartreuse, because for them the band colour and the card colour
   agree. Enumerated by component rather than blanket-`:not()` so a new card
   type cannot silently inherit the wrong half of this. */
:is(.has-forest-background-color, .has-forest-deep-background-color)
:is(.li-card, .li-mcard, .li-pcard, .li-step, .li-tool, .li-revcard, .li-glance):not(.li-card--forest):not(.li-card--ink)
a:not(.wp-block-button__link) {
  color: var(--li-ink);
  border-bottom-color: var(--li-lavender-deep);
  text-decoration: none;
}
:is(.has-forest-background-color, .has-forest-deep-background-color)
:is(.li-card, .li-mcard, .li-pcard, .li-step, .li-tool, .li-revcard, .li-glance):not(.li-card--forest):not(.li-card--ink)
a:not(.wp-block-button__link):hover {
  color: var(--li-lavender-deep);
}

/* --- S3·7 · HOME: the book covers under the testimonials -----
   Meg: "Book covers under testimonials: remove the washing-out overlay."

   There is no overlay. The covers are `cite::before` background images, and
   the cite carries `opacity: .7` for its own small-caps attribution line —
   opacity applies to the whole element including its pseudo-elements, and a
   child cannot opt out of a parent's opacity. So every cover on the homepage
   has been rendering at 70% strength over whatever card it sits on, which is
   exactly what "washed out" looks like. Real client covers, deliberately
   included as proof, quietly desaturated by a rule aimed at the text beside
   them.
   Fixed by expressing the muted attribution as a colour instead of an opacity.
   Every quote variant on this site (paper, chartreuse, lavender) carries ink
   text, so one rgba value covers all three and the cover paints at full
   saturation. Do not put `opacity` back on this element. */
.li-quotes .wp-block-quote cite,
.li-quote cite { opacity: 1; color: rgba(30, 32, 25, .72); }

/* --- S3·8 · HOME: the rotating banner's top padding ----------
   Meg: "Rotating green banner: reduce top padding."

   MEASURED on live dev, JS running, which is the state she sees:
     band box            101px   (the 128px bounding rect is a red herring —
                                  li-marquee--tilt rotates 1.2deg, and a
                                  rotated box's bounding rect gains
                                  width x sin(angle) = ~27px of pure geometry.
                                  Measure offsetHeight on a tilted band, never
                                  getBoundingClientRect.)
     space above text     34px
     space below text     17px
   Twice as much room above the line as below it. That imbalance is what reads
   as "too much top padding" — the padding VALUE was never the problem, and
   changing it alone would have moved the whole line down and made it worse.

   Cause 1, real and fixed: li-motion.js hides the source <p> and APPENDS a
   `.li-marquee__track`, so the track is a second child of a flow-layout group
   and picks up WordPress's `> * + *` block gap — a stray 20px margin-top that
   only exists with JS on. JS off, the <p> renders without it, so the two
   states did not even agree with each other.

   Cause 2: the track's own box measures ~100px for a single 24.8px line. I
   first blamed the ✦ separator falling back to a font with inflated metrics
   (the same failure the drawn ✓ and ✗ in the glance card exist to avoid).
   TESTED IT — swapping every ✦ for a middot changed the span from 77px to
   75px. NOT the cause; the box is simply tall, and an explicit line-height
   does not shrink it. So the band's height is now stated rather than derived:
   a fixed 4rem, with the content centred by flex, which is deterministic
   whatever the font metrics do.

   AFTER, measured the same way: band box 66px, 7px above the line and 8px
   below. The marquee still scrolls (animation name checked, not assumed) and
   the track keeps its full 1742px span width, so the seamless loop is intact —
   `flex: 0 0 auto` is what prevents the flex container from shrinking it.
   Verified in both states: JS on, and with the track hidden so the <p>
   fallback renders. */
.li-marquee { display: flex; align-items: center; height: 4rem; padding: 0; }
.li-marquee > * { margin-block-start: 0 !important; flex: 0 0 auto; }
.li-marquee__track { height: 100%; align-items: center; }
.li-marquee p { line-height: 1.2; }

/* --- S3·9 · Link in Bio: the real lockup --------------------
   The page now carries `logo-square-light.svg`, the stacked lockup, instead of
   the icon plus a typeset wordmark. It needs breathing room under it where the
   wordmark paragraph used to provide the gap, and a cap so it never outgrows
   the 420px column on a narrow phone.
   `.li-linkbio__wordmark` above is deliberately left defined and unused. */
.li-linkbio__lockup { margin-bottom: 1.2rem !important; }
.li-linkbio__lockup img { width: min(260px, 66%) !important; height: auto; }

/* --- S3·10 · The phone steps ONE 3×3 grid at a time ---------
   Meg: "must step ONE 3×3 grid at a time (a grid is one cohesive look).
   Currently showing 4.5×3 — a mess."

   The viewport is now pinned to the grid file's own aspect ratio (850×1063 —
   three columns of Instagram's 4:5 portrait tile, so one file is exactly one
   3×3), which makes each rest state exactly one grid. The animation was
   already stepping one image per step and is untouched.

   The height that used to spill into a second grid now builds out the profile
   header, which is where an Instagram profile keeps it — see the note in
   li_phone_scroll_markup(). Everything in it is an abstract bar: no handle, no
   follower count, no logo. */
.li-phone__viewport { flex: none; aspect-ratio: 850 / 1063; }
.li-phone__chrome--top {
  flex: 1; min-height: 0;
  flex-direction: column; align-items: stretch; justify-content: flex-start;
  gap: clamp(5px, 1.6cqh, 10px); padding: 10px 10px 8px;
}
.li-phone__prow { display: flex; align-items: center; gap: 12px; }
.li-phone__stats { flex: 1; display: flex; justify-content: space-around; gap: 8px; }
.li-phone__stat { display: grid; gap: 3px; justify-items: center; width: 34px; }
.li-phone__stat i { display: block; height: 6px; width: 22px; border-radius: 3px; background: rgba(30,32,25,.30); }
.li-phone__stat i.li-phone__stat-sub { height: 4px; width: 30px; background: rgba(30,32,25,.16); }
.li-phone__pbtns { display: flex; align-items: center; gap: 6px; }
.li-phone__pbtns > span:not(.li-phone__dots) {
  flex: 1; height: 22px; border-radius: 7px; background: rgba(30,32,25,.10);
  border: 1px solid rgba(30,32,25,.16);
}
/* The first action button is the filled one, as it is on a real profile. */
.li-phone__pbtns > span:first-child { background: var(--li-lavender); border-color: var(--li-lavender); }
.li-phone__pbtns .li-phone__dots { flex: none; }
.li-phone__hl { display: flex; gap: 10px; overflow: hidden; }
.li-phone__hl > span {
  flex: none; width: 40px; height: 40px; border-radius: 50%;
  background: rgba(30,32,25,.08); box-shadow: 0 0 0 1.5px rgba(30,32,25,.18);
}
.li-phone__tabs { display: flex; margin-top: auto; border-top: 1px solid rgba(30,32,25,.14); }
.li-phone__tabs > span { flex: 1; height: 3px; margin-top: 7px; border-radius: 2px; background: transparent; }
.li-phone__tabs > span.is-on { background: var(--li-ink); }
/* Below the columns breakpoint the phone narrows, so the header has less room;
   the highlights row is the first thing a real profile pushes off screen. */
@media (max-width: 780px) { .li-phone__hl { display: none; } }

/* ==========================================================
   MOBILE READABILITY FLOOR (2026-08-04, device pass)
   ==========================================================
   Measured at 375px on the live Pricing and ARC Starter Kit
   pages: `.li-pcard__tag` rendered at 10.24px and
   `.li-pcard__note` at 11.52px. Both are uppercase with wide
   tracking, which is the hardest combination to read small,
   and both sit on the cards that carry the prices.
   12px is the floor these get on a phone. Desktop is
   unchanged — the labels are meant to be quiet there.
   ========================================================== */
@media (max-width: 700px) {
  .li-pcard__tag  { font-size: .78rem; letter-spacing: .12em; }
  .li-pcard__note { font-size: .78rem; }
}

/* ---------- Related posts band (single blog post) ---------- */
.li-related__head { text-align: center; margin: 0 auto 1.8rem; }
.li-related__head .wp-block-heading { margin: .15rem 0 0; }
.li-related .li-grid--3 { margin-top: 0; }

/* ============================================================
   2026-08-17 fixes (Meg feedback round)
   ============================================================ */
/* Client logo marquee was rendering too small again */
.li-logos .li-logotrack__img img { height: 132px !important; }
@media (max-width: 640px) { .li-logos .li-logotrack__img img { height: 92px !important; } }

/* Hide the "Keep reading" SEO read-more sections (kept in DOM, not displayed) */
.li-readmore { display: none !important; }

/* Harden inline-SVG box so it can't collapse/clip in WebKit */
.li-inlinesvg svg { display: block; width: 100%; height: auto; max-width: 100%; }

/* ==========================================================
   §D · THE DOODLE LAYER (v1.40.0)
   ----------------------------------------------------------
   The graphic layer is Meg's own Creative Fabrica doodle packs, recoloured to
   the palette (CSS mask + a brand-colour background) and gently animated. Not
   clean icons, nothing drawn by Claude. The mask silhouettes live in
   assets/img/doodles/*.png; recolour is what makes packs from different sources
   read as one family. Approved set + technique: the "Your Doodles, Recoloured"
   brand-guide page. Motion stills under prefers-reduced-motion.
   ========================================================== */
.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);              /* the fill; the mask cuts the shape */
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center;  mask-position: center;
  -webkit-mask-size: contain;     mask-size: contain;
  /* NOTE: mask-image is set per-mark below with a real url(), NOT via a custom
     property. A url() stored in a CSS variable resolves against the DOCUMENT
     URL, not the stylesheet, so on a live page it would 404. Regular
     mask-image resolves relative to style.css, which is what we need. */
}
/* Size modifiers */
.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); }
/* On dark bands a plain forest mark would disappear: lift the default to chartreuse. */
.has-forest-background-color .li-dood,
.has-forest-deep-background-color .li-dood { background: var(--li-chartreuse); }
/* Colour modifiers (fill). Compounded with .li-dood so an explicit colour beats
   the dark-band auto-lift above, on any band, and never collides with a mark
   name (laurel/book/clock share letters with lavender/butter/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); }
/* The mark set — each points mask-image at one approved file (stylesheet-relative). */
.li-dood--star       { -webkit-mask-image: url(assets/img/doodles/star.png);        mask-image: url(assets/img/doodles/star.png); }
.li-dood--sparkle    { -webkit-mask-image: url(assets/img/doodles/sparkle.png);     mask-image: url(assets/img/doodles/sparkle.png); }
.li-dood--stars5     { -webkit-mask-image: url(assets/img/doodles/stars5.png);      mask-image: url(assets/img/doodles/stars5.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--laurel     { -webkit-mask-image: url(assets/img/doodles/laurel.png);      mask-image: url(assets/img/doodles/laurel.png); }
.li-dood--medal      { -webkit-mask-image: url(assets/img/doodles/medal.png);       mask-image: url(assets/img/doodles/medal.png); }
.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--camera     { -webkit-mask-image: url(assets/img/doodles/camera.png);      mask-image: url(assets/img/doodles/camera.png); }
.li-dood--clock      { -webkit-mask-image: url(assets/img/doodles/clock.png);       mask-image: url(assets/img/doodles/clock.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); }
.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--megaphone  { -webkit-mask-image: url(assets/img/doodles/megaphone.png);   mask-image: url(assets/img/doodles/megaphone.png); }
.li-dood--schedule   { -webkit-mask-image: url(assets/img/doodles/schedule.png);    mask-image: url(assets/img/doodles/schedule.png); }
/* aspect-honest marks: the wide ones must not be squeezed into a square box */
.li-dood--stars5      { width: calc(var(--li-dood-size, 2.4rem) * 6); }
.li-dood--star-bubble { width: calc(var(--li-dood-size, 2.4rem) * 1.75); }
.li-dood--book        { width: calc(var(--li-dood-size, 2.4rem) * 2.7); }

/* Gentle float. Two phases so a row of marks does not bob in lockstep. */
@keyframes li-bob  { 0%,100% { transform: translateY(0) rotate(-2deg); } 50% { transform: translateY(-7px) rotate(2deg); } }
@keyframes li-bob2 { 0%,100% { transform: translateY(0) rotate(2deg);  } 50% { transform: translateY(-6px) 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; } }

/* Section mark: a doodle set beside a chapter chip / eyebrow. Baseline-safe. */
.li-secmark { --li-dood-size: 1.7rem; align-self: center; }

/* Doodle bullets — an opt-in variant of the What-You-Get checklist. Replaces the
   glyph bullet with a small recoloured star, kept off the drawn-tick glance list. */
.li-getlist--dood li::before {
  content: ""; position: absolute; left: 0; top: .12em;
  width: 1.4rem; height: 1.4rem;
  background: var(--li-lavender-deep);
  -webkit-mask: url(assets/img/doodles/star.png) center / contain no-repeat;
          mask: url(assets/img/doodles/star.png) center / contain no-repeat;
}
.has-forest-background-color .li-getlist--dood li::before,
.has-forest-deep-background-color .li-getlist--dood li::before { background: var(--li-chartreuse); }

/* Sticker — a doodle in a chartreuse seal. */
.li-sticker {
  display: inline-grid; place-items: center; width: 6rem; height: 6rem;
  background: var(--li-chartreuse); border: 2.5px solid var(--li-ink);
  border-radius: 50%; box-shadow: var(--li-shadow); transform: rotate(-6deg);
}
.li-sticker .li-dood { --li-dood-size: 3rem; background: var(--li-forest-deep); }

/* Faint doodle scatter — a texture for a dark band. Sits behind content. */
.li-scatter { position: relative; }
.li-scatter > * { position: relative; z-index: 1; }
.li-scatter::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: var(--li-chartreuse);
  -webkit-mask: url(assets/img/doodles/scatter.png) 0 0 / 300px repeat;
          mask: url(assets/img/doodles/scatter.png) 0 0 / 300px repeat;
  opacity: .10;
}

/* ==========================================================
   §D2 · THE PROOF BELT (v1.40.0)
   ----------------------------------------------------------
   Built once, dropped on every service + pricing page (audit §5: the proof
   lived only on the homepage while buyers land on service pages from search).
   One rating badge, up to three numbers, one quote. Reuses the card shell,
   the stat type and the doodle marks — no new shapes.
   ========================================================== */
.li-proofbelt { display: grid; gap: clamp(1rem, 2.4vw, 1.6rem); grid-template-columns: minmax(0, 1fr); align-items: stretch; }
@media (min-width: 860px) { .li-proofbelt { grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); } }
.li-proofbelt__stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .9rem; }
.li-proofbelt__stat {
  background: var(--li-paper); color: var(--li-ink);
  border: 2px solid var(--li-ink); border-radius: var(--li-radius);
  box-shadow: var(--li-shadow); padding: 1.1rem .7rem; text-align: center;
  display: flex; flex-direction: column; justify-content: center; align-items: center; gap: .35rem;
  min-width: 0; /* let the 3 grid cells shrink on mobile instead of overflowing */
}
.li-proofbelt__stat:nth-child(odd)  { transform: rotate(-1deg); }
.li-proofbelt__stat:nth-child(even) { transform: rotate(1deg); }
.li-proofbelt__n { display: block; font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 570; font-size: clamp(1.6rem, 3.4vw, 2.3rem); line-height: 1; color: var(--li-forest); }
.li-proofbelt__l { display: block; font-size: .68rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--li-ink); opacity: .7; margin-top: 0; }
.li-proofbelt__quote {
  background: var(--li-forest); color: var(--li-cream);
  border: 2px solid var(--li-ink); border-radius: var(--li-radius);
  box-shadow: var(--li-shadow); padding: clamp(1.3rem, 3vw, 1.8rem);
  display: flex; flex-direction: column; justify-content: center; gap: .7rem;
}
.li-proofbelt__badge { display: flex; align-items: center; gap: .6rem; }
.li-proofbelt__badge .li-dood { --li-dood-size: 1.5rem; }
.li-proofbelt__badge b { font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; font-weight: 560; font-size: 1.25rem; color: var(--li-chartreuse); }
.li-proofbelt__badge span { font-size: .72rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--li-cream); opacity: .72; }
.li-proofbelt__q { font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1; font-style: italic; font-weight: 460; font-size: clamp(1.05rem, 2vw, 1.25rem); line-height: 1.35; margin: 0 !important; color: var(--li-cream); max-width: none; }
.li-proofbelt__cite { font-size: .74rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--li-chartreuse); }
/* Mobile: the three stat cards must fit a phone width, not overflow (mobile QA, v1.43.0).
   The real fix is min-width:0 on the grid ITEMS of .li-proofbelt (they otherwise take
   their content's min-content width and force the whole belt wider than the screen). */
@media (max-width: 560px) {
  .li-proofbelt > * { min-width: 0; max-width: 100%; }
  .li-proofbelt__stats { display: flex; flex-wrap: nowrap; gap: .4rem; min-width: 0; }
  .li-proofbelt__stat { flex: 1 1 0; min-width: 0; padding: .8rem .25rem; border-radius: 14px; box-shadow: 3px 3px 0 var(--li-ink); }
  .li-proofbelt__n { font-size: clamp(1.2rem, 6vw, 1.7rem); }
  .li-proofbelt__l { font-size: .54rem; letter-spacing: .01em; }
  .li-proofbelt__quote { min-width: 0; padding: 1.2rem 1.1rem; }
  .li-proofbelt__badge { flex-wrap: wrap; }
  .li-proofbelt__badge .li-dood--stars5 { --li-dood-size: 1.05rem; }
  .li-proofbelt__q, .li-proofbelt__cite, .li-proofbelt__badge span { overflow-wrap: anywhere; }
}

/* Contact form embedded in the final CTA (a light paper card on the forest-deep
   band, so the FluentForm fields stay legible). v1.41.0. */
.li-cta-form { max-width: 620px; margin: clamp(1.8rem, 3vw, 2.4rem) auto 0; text-align: left; }
.li-cta-form h3 { color: var(--li-forest); }
.li-cta-form p { color: var(--li-ink); opacity: .8; margin-bottom: 1rem; }
.li-cta-form .fluentform, .li-cta-form form { margin: 0; }
.li-cta-form input, .li-cta-form textarea, .li-cta-form select { background: #fff; }

/* ==========================================================
   §D3 · THE ARC JOURNEY GRAPHIC (v1.42.0)
   ----------------------------------------------------------
   The ARC process as a branded, animated strip: Meg's own doodles (calendar,
   megaphone, book, five-stars) recoloured inside branded node cards on a
   branded line. The MegaMoose treatment, LI palette. Replaces the cramped
   week-by-week SVG. Motion stills under reduced-motion.
   ========================================================== */
.li-arcjourney { background: var(--li-paper); border: 2px solid var(--li-ink); border-radius: var(--li-radius); box-shadow: var(--li-shadow); padding: clamp(1.3rem,3vw,1.8rem) clamp(1.2rem,3vw,1.8rem) clamp(1.5rem,3vw,1.9rem); }
.li-arcjourney__eye { font-family: var(--li-sans); font-weight: 800; font-size: .72rem; letter-spacing: .22em; text-transform: uppercase; color: var(--li-lavender-deep); margin: 0 0 .5rem !important; }
.li-arcjourney__title { font-family: var(--li-display); font-variation-settings: "SOFT" 100,"WONK" 1; font-weight: 560; font-size: clamp(1.4rem,2.6vw,1.9rem) !important; line-height: 1.05; color: var(--li-forest); margin: 0 0 1.6rem !important; }
.li-arcjourney__title em { color: var(--li-lavender-deep); font-style: italic; }
.li-arcjourney__track { position: relative; display: grid; grid-template-columns: repeat(4,1fr); align-items: end; }
.li-arcjourney__track::before, .li-arcjourney__track::after { content: ""; position: absolute; left: 12.5%; right: 12.5%; top: 34px; height: 4px; border-radius: 4px; }
.li-arcjourney__track::before { background: var(--li-ink); }
.li-arcjourney__track::after { background: repeating-linear-gradient(90deg, var(--li-lavender-deep) 0 9px, transparent 9px 20px); }
.li-arcjourney__col { display: flex; flex-direction: column; align-items: center; text-align: center; position: relative; z-index: 1; }
.li-arcjourney__node { width: 72px; height: 72px; border: 3px solid var(--li-ink); border-radius: 18px; box-shadow: var(--li-shadow); display: grid; place-items: center; animation: li-bob 3.6s ease-in-out infinite; }
.li-arcjourney__node.n2 { animation-delay: .45s; } .li-arcjourney__node.n3 { animation-delay: .9s; } .li-arcjourney__node.n4 { animation-delay: 1.35s; }
.li-arcjourney__node.n1 { background: var(--li-butter); } .li-arcjourney__node.n2 { background: var(--li-lavender); } .li-arcjourney__node.n3 { background: var(--li-chartreuse); } .li-arcjourney__node.n4 { background: var(--li-forest); }
.li-arcjourney__node .li-dood { --li-dood-size: 38px; }
.li-arcjourney__node .li-dood--book-open { width: 44px; height: 36px; }
.li-arcjourney__node .li-dood--stars5 { width: 52px; height: 22px; }
.li-arcjourney__t { font-family: var(--li-sans); font-weight: 800; font-size: .86rem; color: var(--li-ink); margin: 1rem 0 0 !important; }
.li-arcjourney__w { font-family: var(--li-hand); font-weight: 700; font-size: 1.15rem; color: var(--li-lavender-deep); margin: .1rem 0 0 !important; line-height: 1; }
@media (prefers-reduced-motion: reduce) { .li-arcjourney__node { animation: none; } }
@media (max-width: 600px) { .li-arcjourney__track { grid-template-columns: 1fr 1fr; gap: 1.6rem 0; } .li-arcjourney__track::before, .li-arcjourney__track::after { display: none; } }

/* ==========================================================
   §D4 · BOOK SHELF CARDS (v1.42.0)
   ----------------------------------------------------------
   The Reading Room style card, ported to LI (Meg 2026-08-24: "shelf covers use
   the same style as the RR style cards"). Cover fills to the card border,
   anti-crop (contain on a 2/3 frame, so an author's title band is never sliced),
   title + author + buy link. 5-across responsive shelf, short rows never orphaned.
   ========================================================== */
.li-shelf { --cols: 5; --gap: clamp(.9rem,2vw,1.3rem); display: flex; flex-wrap: wrap; gap: var(--gap); justify-content: flex-start; align-items: stretch; margin-top: 2rem; }
.li-shelf > * { flex: 0 1 calc((100% - (var(--cols) - 1) * var(--gap)) / var(--cols)); max-width: calc((100% - (var(--cols) - 1) * var(--gap)) / var(--cols)); min-width: 0; box-sizing: border-box; }
@media (max-width: 1100px) { .li-shelf { --cols: 3; } }
@media (max-width: 900px)  { .li-shelf { --cols: 2; } }
.li-bookcard { --pad: .9rem; background: var(--li-paper); border: 2px solid var(--li-ink); border-radius: 16px; box-shadow: var(--li-shadow); overflow: hidden; padding: var(--pad); display: flex; flex-direction: column; gap: .35rem; color: var(--li-ink); height: 100%; text-decoration: none; transition: box-shadow .3s ease, transform .3s var(--li-pop); }
.li-bookcard:hover { box-shadow: 7px 9px 0 rgba(30,32,25,.16); transform: translateY(-4px) rotate(-.5deg); }
.li-bookcard__img { margin: calc(-1 * var(--pad)) calc(-1 * var(--pad)) .55rem; }
.li-bookcard__img img { display: block; 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); }
.li-bookcard__title { font-family: var(--li-display); font-variation-settings: "SOFT" 100,"WONK" 1; font-weight: 560; font-size: 1.02rem !important; line-height: 1.12; margin: 0 !important; }
.li-bookcard__author { font-family: var(--li-display); font-style: italic; font-weight: 460; font-size: .82rem !important; opacity: .8; margin: 0 !important; }
.li-bookcard__buy { margin-top: auto; padding-top: .5rem; font-weight: 800; font-size: .66rem; letter-spacing: .1em; text-transform: uppercase; }
/* Force legible card colours even on the forest shelf band (beats the dark-band link rule). */
.li-covers-band .li-bookcard, .li-covers-band .li-bookcard__title { color: var(--li-forest) !important; }
.li-covers-band .li-bookcard__author { color: var(--li-ink) !important; opacity: .78; }
.li-covers-band .li-bookcard__buy { color: var(--li-lavender-deep) !important; }
.li-covers-band .li-bookcard:hover .li-bookcard__buy { color: var(--li-ink) !important; }


/* ==========================================================
   LI-Final-01 - 2026-08-27 - Meg feedback batches 1 and 2
   Mirrored into Additional CSS (custom_css post 167610250) in the
   same pass, so the two layers do not fork on the next zip.
   ========================================================== */
/* ===== LI-Final-01 · 2026-08-27 · Meg's 08-27 feedback batches ===== */

/* Item 1 · The services marquee runs in the branded display face.
   The theme's font rule only ever named `.li-marquee p` and
   `.li-marquee__track span`. The live strip is `.li-mqtrack > .li-mqset`,
   which matched neither, so it fell through to the body face. */
.li-marquee .li-mqtrack,.li-marquee .li-mqset{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.2}
.li-marquee .li-mqsep{font-style:normal}

/* Items 3, 6, 22 · The end-CTA form sits inside its column.
   Fluent Forms ships its controls content-box, so `width:100%` made every
   input the card's inner width PLUS its own padding and border: the fields
   ran to the card edge and past it. Border-box puts them back inside. */
.li-cta .li-cta-form,.li-cta .li-cta-form *{box-sizing:border-box}
.li-cta>.li-cta-form{padding:clamp(1.5rem,2.2vw,2rem) clamp(1.4rem,2vw,1.8rem) clamp(1.5rem,2.2vw,2rem)!important}
.li-cta .li-cta-form .ff-el-form-control,.li-cta .li-cta-form textarea,.li-cta .li-cta-form input:not([type=checkbox]):not([type=radio]),.li-cta .li-cta-form select{width:100%;max-width:100%}
/* ...but a checkbox is not a text field. Sizing it to 100% is what turned the
   service list into one very tall column of stranded ticks. */
.li-cta .li-cta-form input[type=checkbox],.li-cta .li-cta-form input[type=radio]{width:auto!important;max-width:none;flex:none;margin-right:.5rem}
.li-cta .li-cta-form .ff-el-form-check-label{display:flex;align-items:flex-start;gap:.1rem}
/* Fluent Forms' own two-column row CSS is stripped by LiteSpeed UCSS on this
   page, so the two service columns stack. Restated here (same fix the Reading
   Room contact form needed on 08-27). */
.li-cta .li-cta-form .ff-t-container{display:flex;flex-wrap:wrap;gap:0 1rem}
.li-cta .li-cta-form .ff-t-container>.ff-t-cell{flex:1 1 calc(50% - .5rem);min-width:0}
@media(max-width:520px){.li-cta .li-cta-form .ff-t-container>.ff-t-cell{flex:1 1 100%}}
/* Labels were inheriting the dark band's cream and disappearing on the paper card. */
.li-cta .li-cta-form label,.li-cta .li-cta-form .ff-el-input--label label,.li-cta .li-cta-form .ff-el-form-check-label{color:var(--li-ink)!important;opacity:1}
.li-cta .li-cta-form .ff-el-input--label label{font-size:.82rem;letter-spacing:.01em}
/* And it is no longer twice the height of the message beside it. */
.li-cta .li-cta-form h3{font-size:1.3rem!important;margin-bottom:.3rem}
.li-cta .li-cta-form>p{font-size:.88rem;margin-bottom:.85rem}
.li-cta .li-cta-form .fluentform .ff-el-group{margin-bottom:.75rem}
.li-cta .li-cta-form .fluentform textarea.ff-el-form-control{min-height:84px}
.li-cta .li-cta-form .ff-el-form-check{margin-bottom:.05rem}
.li-cta .li-cta-form .ff-el-form-check-label{font-size:.84rem;line-height:1.35}
.li-cta .li-cta-form .ff_submit_btn_wrapper{margin-bottom:0}

/* Item 7 · ARC chapter marks read as marks. At 1.7rem beside a chip they
   measured 27px and registered as nothing. */
.li-chapter .li-secmark{--li-dood-size:2.5rem;margin-left:.2rem}

/* Items 12, 14, 16, 18 · Diagrams get breathing room in their column and stop
   reading as sliced. The figure was taller than the centre-aligned column it
   sits in, so the tilt pushed its bottom corner out of the visual frame. */
.wp-block-column>.li-inlinesvg{align-self:center;margin-block:.8rem}
.li-inlinesvg{overflow:visible}
.li-inlinesvg svg{overflow:visible}

/* Items 13, 15, 17 · The diagrams get their real size back.
   Every anatomy diagram except SmarterQueue's sat in a 44% column, so an
   800-to-1000-unit drawing was delivered at about 490px. That is why the KDP
   captions vanished ("too small, the font gets lost") and why the Brand Assets
   heading read as shouting: at that scale the small type had disappeared and
   only the heading survived. Nothing inside the drawings changed. The row that
   holds one now stacks, so the diagram is delivered at up to 860px and the
   whole type range lands legible. */
.wp-block-columns:has(> .wp-block-column > .li-inlinesvg--band){flex-wrap:wrap!important}
.wp-block-columns:has(> .wp-block-column > .li-inlinesvg--band)>.wp-block-column{flex-basis:100%!important;max-width:100%}
.li-inlinesvg--band{max-width:860px;margin-inline:auto}

/* Item 9 · The ARC shelf reads as a shelf instead of a row of thumbnails.
   Alternating tilt, the hard offset shadow the rest of the site uses, and a
   butter tape strip across every third cover, all from the existing kit. */
.li-shelf--kit>*{position:relative;transition:transform .3s var(--li-pop)}
.li-shelf--kit>*:nth-child(odd){transform:rotate(-1.7deg)}
.li-shelf--kit>*:nth-child(even){transform:rotate(1.4deg)}
.li-shelf--kit>*:hover{transform:rotate(0) translateY(-5px)}
.li-shelf--kit img{border:2px solid var(--li-ink);border-radius:6px;box-shadow:5px 5px 0 var(--li-ink)}
.li-shelf--kit>*:nth-child(3n+1)::before{content:"";position:absolute;top:-11px;left:50%;z-index:2;transform:translateX(-50%) rotate(-3deg);width:76px;height:22px;background:var(--li-butter);border:1px solid rgba(30,32,25,.18);border-radius:2px;opacity:.94}
.li-shelf--kit>*:nth-child(3n)::before{content:"";position:absolute;top:-9px;left:22%;z-index:2;transform:rotate(4deg);width:58px;height:18px;background:var(--li-chartreuse);border:1px solid rgba(30,32,25,.16);border-radius:2px;opacity:.9}
@media(prefers-reduced-motion:reduce){.li-shelf--kit>*{transform:none!important}}

/* Item 20 · The blog cards stop being nine identical stamps.
   The variety rules counted `.li-postcard--tc:nth-child(...)`, but WordPress
   wraps every card in its own `li.wp-block-post`, so the card is always
   nth-child(1): every card took the odd tilt, every card took the 4n+1 tape,
   and the per-position asterisk never fired at all. Counting the wrapper is
   the fix. (Same defect RR-Final-02 found on the Reading Room book club.) */
.li-postcard--tc,.li-postcard--tc:nth-child(odd),.li-postcard--tc:nth-child(even){transform:none}
.li-postcard--tc:nth-child(4n+1)::before,.li-postcard--tc:nth-child(6n+4)::before{content:none}
li.wp-block-post:nth-child(odd) .li-postcard--tc{transform:rotate(-1.5deg)}
li.wp-block-post:nth-child(even) .li-postcard--tc{transform:rotate(1.5deg)}
li.wp-block-post .li-postcard--tc:hover{transform:rotate(0) translateY(-4px)}
li.wp-block-post:nth-child(4n+1) .li-postcard--tc::before,
li.wp-block-post:nth-child(6n+4) .li-postcard--tc::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:var(--li-tape);border:var(--li-tape-edge);border-radius:1px}
li.wp-block-post:nth-child(6n+4) .li-postcard--tc::before{transform:translateX(-50%) rotate(2.6deg);left:46%}
li.wp-block-post:nth-child(3n+2) .li-titlecard::after{left:-.5rem;right:auto;top:auto;bottom:-.4rem;font-size:3.2rem}
li.wp-block-post:nth-child(3n) .li-titlecard::after{left:auto;right:-.4rem;top:auto;bottom:-.6rem;font-size:4.2rem}
@media(prefers-reduced-motion:reduce){li.wp-block-post .li-postcard--tc{transform:none!important}}

/* Item 20 · and the dates come off the cards. Meg has asked twice. */
.li-postcard--tc .wp-block-post-date{display:none}

/* Item 22 · A CTA with no form beside it centres again.
   The 50:50 grid was applied to every `.li-cta`, so the three bands that carry
   a newsletter push instead of a contact form (blog, services, SmarterQueue)
   rendered jammed into the left half with a dead right half. They get the
   single-column CTA back; the form pages keep the 50:50. */
.li-cta:not(:has(> .li-cta-form)){display:block!important;text-align:center!important}
.li-cta:not(:has(> .li-cta-form))>*{text-align:center!important;margin-left:auto!important;margin-right:auto!important}
.li-cta:not(:has(> .li-cta-form)) h2{max-width:22ch}
.li-cta:not(:has(> .li-cta-form)) .li-cta__sub{max-width:52ch}
.li-cta:not(:has(> .li-cta-form)) .li-chapter{justify-content:center!important}
.li-cta:not(:has(> .li-cta-form)) .li-btn-big{justify-content:center!important}

/* Item 21 · The related-posts row: three cards, the tape back, no dates,
   and the dead space above it closed.
   Two separate faults. The count is a PHP bug (the shortcode passed its empty
   atts string in as $count, so posts_per_page went to 0 and WordPress served
   its default ten); that is fixed in functions.php and needs the next zip, so
   the fourth card onward is also capped here for the live page today.
   The tape and tilt were lost because these cards are direct children of the
   grid, not wrapped in li.wp-block-post like the blog index cards. */
.li-related .li-grid--3>.li-postcard--tc:nth-child(n+4){display:none}
.li-related .li-grid--3>.li-postcard--tc:nth-child(odd){transform:rotate(-1.5deg)}
.li-related .li-grid--3>.li-postcard--tc:nth-child(even){transform:rotate(1.5deg)}
.li-related .li-grid--3>.li-postcard--tc:hover{transform:rotate(0) translateY(-4px)}
.li-related .li-grid--3>.li-postcard--tc:nth-child(2)::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:var(--li-tape);border:var(--li-tape-edge);border-radius:1px}
.li-related .wp-block-post-date{display:none}
.li-related__head{margin-bottom:1.4rem}
.li-related-band{padding-top:clamp(1.6rem,3vw,2.4rem)!important}
@media(prefers-reduced-motion:reduce){.li-related .li-grid--3>.li-postcard--tc{transform:none!important}}
/* The "Keep reading" chip is a block-level <p> in the related head, so the
   dashed chapter pill stretched the full content width. */
.li-related__head .li-chapter__num{display:inline-block}

/* Item 8 · Cards are the same height, including across grid rows.
   `align-items:stretch` only equalises cards WITHIN a row; a grid that wraps
   sizes each row independently, which is why the ARC steps grid ran 274px in
   row one and 190px in row two. `grid-auto-rows:1fr` is the part that was
   missing. The shelf gets the same treatment so a two-line title does not make
   one cover card taller than the four beside it. */
.li-grid--4,.li-grid--3,.li-mcards,.li-offset,.li-pcards{grid-auto-rows:1fr}
.li-grid--4>*,.li-grid--3>*,.li-mcards>*,.li-offset>*,.li-pcards>*{height:100%}
.li-shelf>*{align-self:stretch}
.li-shelf>*>*{height:100%}
/* The one card whose title wraps to two lines was 19px taller than the four
   beside it. Reserving the second line evens the row. */
.li-shelf .li-bookcard{height:100%;display:flex;flex-direction:column}
.li-shelf .li-bookcard__title{min-height:2.5em}

/* ==========================================================================
   LI-Final-02 · 2026-08-28 · the blog visual pass, the numbers band, the
   single-post CTA. Session 4 of 5 in the approved final-fix program.
   ==========================================================================

   READ THIS FIRST, IT EXPLAINS WHY EVERY RULE BELOW LOOKS OVER-SPECIFIED.

   The Additional CSS on this site is printed inside `global-styles-inline-css`,
   which WordPress emits at position 19 in the head. The theme stylesheet is
   the LINK at position 22. So the Additional CSS is read BEFORE style.css, and
   any rule here that ties a theme rule on specificity LOSES.

   That is not theory. LI-Final-01 wrote
       .li-postcard--tc:nth-child(4n+1)::before { content: none }
   to strip the tape off every blog card before re-adding it per position, and
   style.css line 3216 carries that identical selector with `content:""`. Same
   specificity, later in the document, so the reset never happened: measured on
   the live blog index, all nine cards wear an identical 108x28 chartreuse-soft
   strip, which is exactly the "consistent tape treatment" note Meg raised.
   LI-Final-01 also mirrored its block into style.css, where it WOULD have won,
   but no zip was cut, so the server is still serving 1.43.1 without it.

   Rules here therefore carry `!important` or a `body`-anchored selector
   wherever they contend with a theme rule, so the live page is correct from
   the Additional CSS alone, whether or not the zip has been uploaded yet.
   ========================================================================== */


/* ==========================================================================
   1 · "THE NUMBERS SO FAR" — rebuilt, not nudged (Meg's item 2, third reject)
   ==========================================================================

   Two faults were MEASURED on the live band before anything was redrawn.

   (a) THE NUMERALS REALLY DO SPILL THEIR CARDS. The previous rule laid the six
       stats out as `display:flex` with `flex:1 1 140px; min-width:132px` and a
       numeral at 2.3rem. "4,000+" measures 111.3px at that size; add the card's
       11px of padding on each side and it needs 133.3px inside a card pinned at
       132px. `scrollWidth - clientWidth` came back at 8px on "4,000+" and 3px on
       "5,500+". That overflow IS the "number font overlaps the card element"
       Meg has now reported three times, and no amount of re-tilting the cards
       was ever going to touch it.

   (b) THE CARDS WERE NOT EQUAL HEIGHT. 130.6px next to 113.8px in the same row,
       because the two-line labels each sized their own box. Equal-height cards
       are a standing standard, so that is a second failure in the same band.

   The rebuild. A real grid with `1fr` tracks: `1fr` resolves to
   `minmax(auto, 1fr)`, and an `auto` minimum is the item's min-content, so a
   track can never be narrower than the numeral sitting in it. `min-width:
   min-content` on the card is the second belt, and the numeral is held on one
   line so its min-content is its true width. Column counts are stated per
   breakpoint rather than auto-fit, so there is nothing to compute wrong at an
   in-between width. `grid-auto-rows:1fr` gives the equal heights across rows,
   the same declaration that fixed the ARC grids in LI-Final-01.

   The kit: taped paper notes on the lavender band, three tape variants so six
   cards do not read as a stamp, hard offset shadows, alternating tilt. The
   head is a Caveat line, a doodle, and a real Fraunces heading, because the old
   8px uppercase label was what made the band read as a corporate stat belt.
   Heading copy is new: Meg called the old line ridiculous.
   ========================================================================== */

.li-numbers { padding-top: clamp(2.4rem, 4.4vw, 3.6rem); padding-bottom: clamp(2.6rem, 4.8vw, 3.8rem); }

.li-numbers .li-numbers__head {
  display: flex; align-items: center; gap: clamp(.8rem, 1.6vw, 1.3rem);
  flex-wrap: wrap; margin: 0 0 clamp(1.5rem, 2.8vw, 2.3rem);
}
.li-numbers .li-numbers__head .li-dood { --li-dood-size: 2.8rem; background: var(--li-forest-deep); }
.li-numbers .li-numbers__copy { flex: 1 1 300px; min-width: 0; }
.li-numbers .li-numbers__kicker {
  margin: 0 0 .15rem !important;
  font-family: var(--li-hand) !important;
  font-size: clamp(1.15rem, 1.9vw, 1.4rem) !important;
  line-height: 1.1; color: var(--li-forest-deep); opacity: .92;
}
.li-numbers h2.li-numbers__title {
  margin: 0 !important;
  font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1;
  font-weight: 520; letter-spacing: -.015em;
  font-size: clamp(1.85rem, 3.2vw, 2.7rem) !important;
  line-height: 1.05; color: var(--li-forest-deep); max-width: 20ch;
}
/* On a lavender band the house lavender-deep `em` would sit at roughly 2.6:1,
   so the emphasis is carried by the italic plus a chartreuse highlight and the
   ink stays put. Same device as the `mark` on the pull quote above it. */
.li-numbers h2.li-numbers__title em {
  font-style: italic; color: inherit;
  background: linear-gradient(transparent 62%, var(--li-chartreuse) 62%);
  padding: 0 .06em;
}

.li-numbers .li-statwall {
  display: grid !important;
  grid-template-columns: repeat(3, 1fr) !important;
  grid-auto-rows: 1fr;
  align-items: stretch;
  gap: clamp(1rem, 1.9vw, 1.6rem) !important;
  justify-content: stretch;
}
.li-numbers .li-statwall > .li-stat {
  box-sizing: border-box;
  height: 100%; min-width: min-content;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  background: var(--li-paper);
  border: 2px solid var(--li-ink); border-radius: 16px;
  box-shadow: 5px 5px 0 var(--li-ink);
  padding: clamp(1.6rem, 2.6vw, 2.15rem) clamp(1.05rem, 1.9vw, 1.6rem) clamp(1.2rem, 2.1vw, 1.6rem);
  text-align: center; position: relative;
  max-width: none;
  transition: transform .3s var(--li-pop), box-shadow .3s ease;
}
/* Tape. Three variants across the six notes so the row reads hand-stuck. */
.li-numbers .li-statwall > .li-stat::before {
  content: ""; position: absolute; z-index: 2; pointer-events: none;
  top: -12px; left: 50%; width: 88px; height: 25px;
  transform: translateX(-50%) rotate(-3.2deg);
  background: var(--li-tape); border: var(--li-tape-edge); border-radius: 2px;
}
.li-numbers .li-statwall > .li-stat:nth-child(3n+2)::before {
  left: 44%; width: 72px; transform: translateX(-50%) rotate(2.9deg);
}
.li-numbers .li-statwall > .li-stat:nth-child(3n)::before {
  left: 57%; width: 64px; transform: translateX(-50%) rotate(-1.4deg);
  background: var(--li-butter);
}
.li-numbers .li-statwall > .li-stat:nth-child(odd)  { transform: rotate(-1.1deg); }
.li-numbers .li-statwall > .li-stat:nth-child(even) { transform: rotate(1.1deg); }
.li-numbers .li-statwall > .li-stat:hover {
  transform: rotate(0) translateY(-5px); box-shadow: 7px 9px 0 var(--li-forest);
}
.li-numbers .li-statwall .li-stat__num {
  margin: 0 !important;
  font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1;
  font-weight: 570; letter-spacing: -.02em; line-height: .98;
  color: var(--li-forest); white-space: nowrap;
  font-size: clamp(2.1rem, 3.4vw, 3.2rem) !important;
}
.li-numbers .li-statwall .li-stat__label {
  margin: .5rem 0 0 !important;
  font-family: var(--li-sans);
  font-weight: 600; font-size: .86rem !important; line-height: 1.26;
  color: var(--li-ink); opacity: .8; max-width: 19ch;
  /* Two lines reserved. Without it the one-line labels let their numerals ride
     higher than the two-line ones and the row loses its shared baseline. */
  min-height: 2.52em;
}
@media (max-width: 1000px) {
  .li-numbers .li-statwall { grid-template-columns: repeat(2, 1fr) !important; }
}
@media (max-width: 560px) {
  .li-numbers .li-statwall { grid-template-columns: repeat(2, 1fr) !important; gap: .8rem !important; }
  .li-numbers .li-statwall > .li-stat { padding: 1.35rem .7rem 1.05rem; border-radius: 13px; box-shadow: 4px 4px 0 var(--li-ink); }
  .li-numbers .li-statwall > .li-stat::before { width: 62px; height: 20px; top: -10px; }
  .li-numbers .li-statwall > .li-stat:nth-child(3n+2)::before,
  .li-numbers .li-statwall > .li-stat:nth-child(3n)::before { width: 54px; }
  .li-numbers .li-statwall .li-stat__num { font-size: clamp(1.65rem, 7.2vw, 2.25rem) !important; }
  .li-numbers .li-statwall .li-stat__label { font-size: .75rem !important; margin-top: .38rem !important; }
}
@media (prefers-reduced-motion: reduce) {
  .li-numbers .li-statwall > .li-stat,
  .li-numbers .li-statwall > .li-stat:hover { transform: none !important; }
}


/* ==========================================================================
   2 · BLOG TITLE CARDS — the Reading Room doodle system, ported (Meg approved
       the direction 2026-08-28)
   ==========================================================================

   The Reading Room's Book Club cards cycle three card colours and six
   recoloured doodle watermarks; the LI blog index was still painting one
   forest block and one ✱ glyph on all nine cards. Same components, one look
   across both sites, which is the cohesion standard.

   Two implementation notes, both learned the hard way on the other site:

   - The doodle is a mask-image stated DIRECTLY per position, not fed through a
     `--li-tc-dood` custom property. A url() held in a custom property resolves
     against the document URL rather than the stylesheet, and LiteSpeed's UCSS
     pass cannot see a custom property being consumed and drops the rule. Both
     traps disappear if the url() is written out, root-relative.
   - The counting happens on `li.wp-block-post`, never on the card. WordPress
     wraps every post in its own `<li>`, so a `:nth-child` on the card inside
     always evaluates to 1. That was LI-Final-01's finding and it still governs.
   ========================================================================== */

/* The card colour cycle. */
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 .li-related .li-grid--3 > .li-postcard--tc:nth-child(3n+1) .li-titlecard { background: var(--li-forest) !important; }
body .li-related .li-grid--3 > .li-postcard--tc:nth-child(3n+2) .li-titlecard { background: var(--li-lavender-deep) !important; }
body .li-related .li-grid--3 > .li-postcard--tc:nth-child(3n)   .li-titlecard { background: var(--li-forest-deep) !important; }

/* The watermark. Replaces the ✱ glyph, and re-states the three positions
   LI-Final-01 nudged, so nothing is left pointing at the old glyph geometry. */
body .li-postcard--tc .li-titlecard::after,
body li.wp-block-post:nth-child(3n+2) .li-titlecard::after,
body li.wp-block-post:nth-child(3n)   .li-titlecard::after {
  content: "" !important;
  position: absolute; z-index: 1; pointer-events: none;
  top: 1rem !important; right: 1.05rem !important; left: auto !important; bottom: auto !important;
  width: 4.6rem; height: 4.6rem;
  font-size: 0 !important; line-height: 0;
  opacity: .5;
  background: var(--li-chartreuse);
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center;  mask-position: center;
  -webkit-mask-size: contain;     mask-size: contain;
  animation: li-tc-spin 9s ease-in-out infinite alternate;
}
/* Watermark tint follows the card colour so the mark never sits flat on it. */
body li.wp-block-post:nth-child(3n+2) .li-titlecard::after { background: var(--li-chartreuse-soft); opacity: .42; }
body li.wp-block-post:nth-child(3n)   .li-titlecard::after { background: var(--li-lavender); opacity: .46; }
body .li-related .li-grid--3 > .li-postcard--tc:nth-child(3n+2) .li-titlecard::after { background: var(--li-chartreuse-soft); opacity: .42; }
body .li-related .li-grid--3 > .li-postcard--tc:nth-child(3n)   .li-titlecard::after { background: var(--li-lavender); opacity: .46; }

/* The six-mark rotation. Widths follow the artwork so a wide doodle is shown
   whole rather than letterboxed into a square — the standing "never crop a
   doodle" rule, applied by fitting the box to the drawing. */
body li.wp-block-post:nth-child(6n+1) .li-titlecard::after,
body .li-related .li-grid--3 > .li-postcard--tc:nth-child(6n+1) .li-titlecard::after {
  -webkit-mask-image: url(/wp-content/themes/literary-inspired/assets/img/doodles/book.png);
          mask-image: url(/wp-content/themes/literary-inspired/assets/img/doodles/book.png);
  width: 7rem;
}
body li.wp-block-post:nth-child(6n+2) .li-titlecard::after,
body .li-related .li-grid--3 > .li-postcard--tc:nth-child(6n+2) .li-titlecard::after {
  -webkit-mask-image: url(/wp-content/themes/literary-inspired/assets/img/doodles/pencil.png);
          mask-image: url(/wp-content/themes/literary-inspired/assets/img/doodles/pencil.png);
}
body li.wp-block-post:nth-child(6n+3) .li-titlecard::after,
body .li-related .li-grid--3 > .li-postcard--tc:nth-child(6n+3) .li-titlecard::after {
  -webkit-mask-image: url(/wp-content/themes/literary-inspired/assets/img/doodles/star.png);
          mask-image: url(/wp-content/themes/literary-inspired/assets/img/doodles/star.png);
}
body li.wp-block-post:nth-child(6n+4) .li-titlecard::after,
body .li-related .li-grid--3 > .li-postcard--tc:nth-child(6n+4) .li-titlecard::after {
  -webkit-mask-image: url(/wp-content/themes/literary-inspired/assets/img/doodles/megaphone.png);
          mask-image: url(/wp-content/themes/literary-inspired/assets/img/doodles/megaphone.png);
}
body li.wp-block-post:nth-child(6n+5) .li-titlecard::after,
body .li-related .li-grid--3 > .li-postcard--tc:nth-child(6n+5) .li-titlecard::after {
  -webkit-mask-image: url(/wp-content/themes/literary-inspired/assets/img/doodles/book-open.png);
          mask-image: url(/wp-content/themes/literary-inspired/assets/img/doodles/book-open.png);
  width: 6rem;
}
body li.wp-block-post:nth-child(6n)   .li-titlecard::after,
body .li-related .li-grid--3 > .li-postcard--tc:nth-child(6n)   .li-titlecard::after {
  -webkit-mask-image: url(/wp-content/themes/literary-inspired/assets/img/doodles/mug.png);
          mask-image: url(/wp-content/themes/literary-inspired/assets/img/doodles/mug.png);
}
@media (prefers-reduced-motion: reduce) {
  body .li-postcard--tc .li-titlecard::after { animation: none !important; }
}

/* The title has to clear the watermark, and the card has to fill its row so the
   grid's equal heights actually show as equal cards.

   The excerpt is clamped to three lines and the coloured block is given the
   slack. Without that, a four-line excerpt and a two-line excerpt end their
   coloured blocks at different heights, so a row of equal-height cards still
   reads ragged: the cards match but the component inside them does not, which
   is the cohesion standard rather than the equal-height one. */
body li.wp-block-post > .li-postcard--tc { height: 100%; }
body .li-postcard--tc .li-titlecard { min-height: 200px; flex: 1 1 auto; }
body .li-postcard--tc .li-titlecard .wp-block-post-title { max-width: 22ch; }
body .li-postcard--tc .wp-block-post-excerpt__excerpt {
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden; margin: 0;
}
/* Dates off the cards. Meg has asked twice, LI-Final-01 wrote the rule, and it
   is restated with !important here for the ordering reason at the top. */
body .li-postcard--tc .wp-block-post-date,
body .li-related .wp-block-post-date { display: none !important; }


/* ==========================================================================
   3 · TAPE, ONE RULE FOR BOTH SURFACES
   ==========================================================================
   Live measurement: all nine index cards carried an identical 108x28 strip,
   because LI-Final-01's `content:none` reset lost the ordering fight described
   at the top of this block. The reset is restated here with `!important` so it
   wins from the Additional CSS, and the related row is put on the SAME
   positional rule as the index instead of its own one-off `nth-child(2)`, which
   is what "consistent tape treatment" has to mean if it means anything.
   ========================================================================== */
body .li-postcard--tc::before { content: none !important; }
body li.wp-block-post:nth-child(4n+1) .li-postcard--tc::before,
body li.wp-block-post:nth-child(6n+4) .li-postcard--tc::before,
body .li-related .li-grid--3 > .li-postcard--tc:nth-child(4n+1)::before,
body .li-related .li-grid--3 > .li-postcard--tc:nth-child(6n+4)::before {
  content: "" !important;
  position: absolute; z-index: 4; pointer-events: none;
  top: -12px; left: 50%; width: 108px; height: 28px;
  transform: translateX(-50%) rotate(-3.5deg);
  background: var(--li-tape); border: var(--li-tape-edge); border-radius: 1px;
}
body li.wp-block-post:nth-child(6n+4) .li-postcard--tc::before,
body .li-related .li-grid--3 > .li-postcard--tc:nth-child(6n+4)::before {
  left: 46%; transform: translateX(-50%) rotate(2.6deg);
}


/* ==========================================================================
   4 · BLOG PAGINATION
   ==========================================================================
   It was rendering as WordPress's bare "1 2 3 … 15 Next Page" links, the only
   unstyled component left on the page. Same pill vocabulary as the category
   filter row directly above it, so the two rows read as one control surface.
   ========================================================================== */
body .wp-block-query-pagination {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: .5rem; margin-top: clamp(2rem, 3.6vw, 3rem);
}
body .wp-block-query-pagination-numbers { display: inline-flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
body .wp-block-query-pagination a.page-numbers,
body .wp-block-query-pagination span.page-numbers,
body .wp-block-query-pagination .wp-block-query-pagination-previous,
body .wp-block-query-pagination .wp-block-query-pagination-next {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 2.6rem; padding: .5rem .9rem;
  font-family: var(--li-sans); font-weight: 600; font-size: .86rem;
  line-height: 1; text-decoration: none; color: var(--li-ink);
  background: var(--li-paper);
  border: 2px solid var(--li-ink); border-radius: 999px;
  box-shadow: 3px 3px 0 var(--li-ink);
  transition: transform .2s var(--li-pop), box-shadow .2s ease, background .2s ease;
}
body .wp-block-query-pagination a.page-numbers:hover,
body .wp-block-query-pagination .wp-block-query-pagination-previous:hover,
body .wp-block-query-pagination .wp-block-query-pagination-next:hover {
  background: var(--li-chartreuse-soft);
  transform: translate(-1px, -1px); box-shadow: 4px 5px 0 var(--li-ink);
  text-decoration: none;
}
body .wp-block-query-pagination span.page-numbers.current {
  background: var(--li-chartreuse); box-shadow: 3px 3px 0 var(--li-ink);
}
body .wp-block-query-pagination .page-numbers.dots {
  border-color: transparent; background: none; box-shadow: none;
  min-width: 1.2rem; padding: .5rem .15rem; opacity: .6;
}
body .wp-block-query-pagination .wp-block-query-pagination-next,
body .wp-block-query-pagination .wp-block-query-pagination-previous {
  font-family: var(--li-display); font-variation-settings: "SOFT" 100, "WONK" 1;
  font-style: italic; font-weight: 500; font-size: .95rem; padding: .5rem 1.15rem;
}
@media (prefers-reduced-motion: reduce) {
  body .wp-block-query-pagination a.page-numbers:hover { transform: none; }
}


/* ==========================================================================
   5 · THE SINGLE-POST END CTA
   ==========================================================================
   Meg: "this CTA looks horrendous sitewide." LI-Final-01 rebuilt the nine
   page-level CTAs but could not reach this one: it lives in the block TEMPLATE
   `templates/single.html`, not in page content, so it still carried the
   redundant second button that was stripped everywhere else, and none of the
   handwritten closer the other newsletter-push bands end on.

   The template is corrected at source for the zip. Until that lands, the
   redundant button is capped here so every post matches the blog index band
   today. The gap above "More from the blog" measured 150px against a 38.4px
   band padding; it is closed to the section rhythm.
   ========================================================================== */
body.single .li-cta .wp-block-button.is-style-li-ghost-light { display: none !important; }
/* The gap measured 183.8px from the post-nav buttons to the related row: the
   prose section's own 130px padding-bottom, plus the band's 20px margin-top,
   plus the band's 33.8px padding-top. LI-Final-01 trimmed only the last of the
   three, which is why it still read as a hole. All three are cut here, and the
   measurement afterwards was 62.4px. */
body.single .li-prose.li-section { padding-bottom: clamp(1.2rem, 2.2vw, 2rem) !important; }
body.single .li-related-band { margin-top: 0 !important; padding-top: clamp(1.4rem, 2.6vw, 2.2rem) !important; }
body.single .li-prose .li-postnav { margin-bottom: 0 !important; padding-bottom: 0 !important; }
body.single .li-related .li-related__head { margin-bottom: 1.4rem; }

/* ===== LI-Final-03 · 2026-08-28 · Meg's consistency round =====
   R1 to R4 are regressions this program introduced, fixed at the cause. */

/* R1 · CARDS AND BUTTONS OVERLAPPING. LI-Final-01 added a blanket
   `.li-pcards > * { height:100% }` to equalise card heights, but `.li-pcard` is
   content-box with 1.6rem/1.4rem padding and a 2px border. With height:100% the
   CONTENT box takes the row height and padding plus border are added on top, so
   every card rendered exactly 52px taller than its grid row and hung over the
   button below it. Measured on Digital Strategy: grid bottom 4578.6, card bottom
   4630.6, button top 4598.6, so the cards covered the button by 32px. */
.li-pcards > .li-pcard,
.li-pcards > .li-pcard * { box-sizing: border-box; }
.li-glance, .li-glance * { box-sizing: border-box; }

/* R2 · The tilted services scroller crosses the hero edge again. It had been
   pushed to margin-top:20px, clearing the hero by 5.6px, so it read as a
   separate stripe instead of an overlap. */
.li-marquee--tilt {
  position: relative; z-index: 3;
  margin-top: -38px !important; margin-bottom: -6px;
}
@media (max-width: 640px) { .li-marquee--tilt { margin-top: -26px !important; } }

/* R3 · No doodles in section headings. Added to the ARC chapter chips by
   LI-Final-01; no other page marks its chips this way, so the ARC page was the
   outlier and the rest of the site was right. */
.li-chapter .li-secmark, .li-chapter .li-dood { display: none !important; }
.li-numbers__head .li-dood { display: none !important; }

/* R4 · The service diagrams stop being full-width. LI-Final-01 over-corrected
   an earlier "too small" note and let these run to 860px, which delivered the
   Digital Strategy drawing at 838x874. */
.li-inlinesvg--band { max-width: 620px !important; }
@media (max-width: 700px) { .li-inlinesvg--band { max-width: 100% !important; } }

/* C1 · Buttons are Title Case sitewide. The labels were mixed, but the reason
   the site LOOKED shouty is that `.wp-block-button__link` carried
   text-transform:uppercase while the pricing-card buttons carried none, so
   "SEE HOW I CAN HELP" sat beside "Book this". Retyping labels alone would have
   changed nothing on screen. */
.wp-block-button .wp-block-button__link,
.li-pcards__btn,
.fluentform button[type="submit"],
.li-head .wp-block-button__link { text-transform: capitalize !important; letter-spacing: .01em; }

/* C1b · The pricing row keeps real clearance under it. Every `.li-pcard`
   carries a deliberate `translateY(14px)`, so even with R1's border-box the
   cards end 14px below their grid box and the button under them was landing
   6px away. */
.li-pcards { margin-bottom: clamp(2.2rem, 3.6vw, 3.2rem); }
.li-pcards + .wp-block-buttons, .li-pcards + * { margin-top: 1.2rem; }

/* C2 · The contact-form service list runs in two columns, as Meg built it in
   Fluent Forms. Scoped with :has() to option lists of four or more, so the
   Yes/No and other short choice groups are left alone. */
/* Correction after measuring: the two columns already exist as Fluent Forms'
   own `ff-t-cell` pair, four options each. The list read as one stack because
   the cells were wrapping. So the fix is to hold the pair side by side rather
   than impose a second grid on top, which would have produced FOUR columns on
   the pages where it matched and none where it did not. */
.li-cta-form .ff-t-container, .li-formcard .ff-t-container { display: flex; flex-wrap: wrap; gap: 0 1.4rem; }
.li-cta-form .ff-t-container > .ff-t-cell,
.li-formcard .ff-t-container > .ff-t-cell { flex: 1 1 calc(50% - .7rem); min-width: 190px; }
@media (max-width: 460px) {
  .li-cta-form .ff-t-container > .ff-t-cell,
  .li-formcard .ff-t-container > .ff-t-cell { flex: 1 1 100%; }
}

/* C3 · The numbers tape alternates green, orange, green across the three
   columns, so the pattern reads down the grid instead of wandering. */
.li-numbers .li-statwall > .li-stat::before { background: var(--li-tape) !important; }
.li-numbers .li-statwall > .li-stat:nth-child(3n)::before { background: var(--li-tape) !important; }
.li-numbers .li-statwall > .li-stat:nth-child(3n+1)::before { background: var(--li-tape) !important; }
.li-numbers .li-statwall > .li-stat:nth-child(3n+2)::before { background: var(--li-butter) !important; }

/* C4 · Cards sitting next to each other are the same height. The About
   "Who this is for" pair are two separate `.li-glance` cards inside a columns
   block, so nothing was equalising them. */
/* The blocker was `are-vertically-aligned-top`, which puts `align-self:flex-start`
   on each COLUMN, and align-self on the item beats align-items on the container.
   The columns carry a dedicated `li-fitcards` class, so both are named. */
.li-fitcards, .li-glance__cols,
.wp-block-columns:has(> .wp-block-column > .li-glance) { align-items: stretch !important; }
.li-fitcards > .wp-block-column, .li-glance__cols > .wp-block-column,
.wp-block-columns:has(> .wp-block-column > .li-glance) > .wp-block-column {
  align-self: stretch !important; display: flex !important;
}
.li-fitcards > .wp-block-column > .li-glance,
.li-glance__cols > .wp-block-column > .li-glance { width: 100%; }
.wp-block-columns:has(> .wp-block-column > .li-glance) > .wp-block-column > .li-glance {
  width: 100%; margin-top: 0; margin-bottom: 0;
}
.li-glance + p, .li-glance + .wp-block-paragraph { margin-top: clamp(1.6rem, 3vw, 2.4rem) !important; }

/* ===== LI-Final-04 · 2026-08-29 · regression batch (audit items 7, 13, 14) =====
   Mirrors the live Additional CSS. The header toggle already exists above
   (search .li-head__cta--short); restated here with !important because UCSS was
   stripping the plain rule and rendering both booking pills. */
.li-head__cta > .li-head__cta--short { display: none !important; }
@media (max-width: 900px) {
  .li-head__cta > .li-head__cta--full  { display: none !important; }
  .li-head__cta > .li-head__cta--short { display: inline-block !important; }
}
/* Item 13 · a little air under the About fit grid before the pull line. */
.li-fitcards + p, .li-fitcards + .li-pull { margin-top: clamp(1.8rem, 3.2vw, 2.6rem) !important; }
/* Item 14 · the Newsletter example-doc row reads even: equal-height columns with
   the transparent mockup vertically centred (align-items:center was UCSS-stripped). */
.li-exdoc__cols { align-items: stretch !important; }
.li-exdoc__cols > .wp-block-column { align-self: stretch !important; display: flex; flex-direction: column; justify-content: center; }
@media (max-width: 780px) { .li-exdoc__cols > .wp-block-column { justify-content: flex-start; } }


/* ==========================================================================
   li-audit-design-kit · 2026-08-29 · three standing design items (mirrors the
   live Additional CSS post 167610250). Item 2 delivery-notes (flat-DOM nth-child),
   Item 3 social doodle cards, Item 4b ARC statwall, Item 4a one bullet everywhere.
   Doodle masks are stylesheet-relative here (theme convention); the live copy in
   Additional CSS uses absolute URLs.
   ========================================================================== */

/* Item 2 · Digital Strategy (16) Chapter 04 delivery notes. Three cards kept in
   DOM order; the container class is li-deliv (was li-grid--3). Grid placement
   makes the chartreuse walk-away card the big-type feature and the two paper
   cards a tilted stack with tape, doodles and one designed corner overlap. */
.li-deliv{ display:grid; grid-template-columns:1.12fr .88fr; grid-template-rows:auto auto;
  gap:clamp(1.3rem,2.6vw,2.4rem); align-items:start; margin-top:clamp(1.4rem,2.6vw,2.2rem); }
.li-deliv>.li-card:nth-child(2){ grid-column:1; grid-row:1 / span 2; align-self:stretch;
  display:flex; flex-direction:column; justify-content:center; transform:rotate(-1.15deg);
  position:relative; z-index:1;
  padding:clamp(2rem,2.7vw,2.7rem) clamp(1.7rem,2.4vw,2.3rem) clamp(2rem,2.8vw,2.7rem); }
.li-deliv>.li-card:nth-child(2) h3{ font-family:var(--li-display); font-variation-settings:"SOFT" 100,"WONK" 1;
  font-weight:560; letter-spacing:-.015em; line-height:1.03; font-size:clamp(1.85rem,3.1vw,2.6rem); margin-bottom:.7rem; }
.li-deliv>.li-card:nth-child(2) p{ font-size:1.02rem; opacity:1; max-width:34ch; }
.li-deliv>.li-card:nth-child(1){ grid-column:2; grid-row:1; transform:rotate(1.5deg); margin-left:-3rem; position:relative; z-index:2; }
.li-deliv>.li-card:nth-child(3){ grid-column:2; grid-row:2; transform:rotate(-1.3deg); position:relative; z-index:2; }
.li-deliv>.li-card:nth-child(1) h3,.li-deliv>.li-card:nth-child(3) h3{ font-size:1.35rem; }
.li-deliv>.li-card:hover{ transform:rotate(0) translateY(-4px); }
.li-deliv>.li-card::before{ content:""; display:block; height:3rem; margin:0 0 .75rem; background:var(--li-ink);
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat; -webkit-mask-position:left center;mask-position:left center;
  -webkit-mask-size:contain;mask-size:contain; }
.li-deliv>.li-card:nth-child(2)::before{ width:3.6rem; -webkit-mask-image:url(assets/img/doodles/book-open.png);mask-image:url(assets/img/doodles/book-open.png); }
.li-deliv>.li-card:nth-child(1)::before{ width:3rem; -webkit-mask-image:url(assets/img/doodles/clock.png);mask-image:url(assets/img/doodles/clock.png); }
.li-deliv>.li-card:nth-child(3)::before{ width:3rem; -webkit-mask-image:url(assets/img/doodles/medal.png);mask-image:url(assets/img/doodles/medal.png); }
.li-deliv>.li-card::after{ content:""; position:absolute; z-index:3; pointer-events:none; top:-12px; width:82px; height:24px;
  background:var(--li-tape); border:var(--li-tape-edge); border-radius:2px; }
.li-deliv>.li-card:nth-child(2)::after{ left:50%; transform:translateX(-50%) rotate(-2.4deg); width:106px; background:var(--li-butter); }
.li-deliv>.li-card:nth-child(1)::after{ left:1.8rem; transform:rotate(-3deg); }
.li-deliv>.li-card:nth-child(3)::after{ right:1.6rem; transform:rotate(2.6deg); }
@media(prefers-reduced-motion:reduce){ .li-deliv>.li-card{transform:none !important;} }
@media(max-width:820px){ .li-deliv{ grid-template-columns:1fr; grid-template-rows:none; }
  .li-deliv>.li-card:nth-child(1),.li-deliv>.li-card:nth-child(2),.li-deliv>.li-card:nth-child(3){ grid-column:1; grid-row:auto; transform:none; margin-left:0; }
  .li-deliv>.li-card:nth-child(2){ order:-1; } }

/* Item 3 · Social (18) "what you can book" cards get the homepage li-card doodle
   treatment. Opt-in grid class li-grid--dood; heights already equalised by li-grid--3. */
.li-grid--dood>.li-card{ position:relative; }
.li-grid--dood>.li-card::before{ content:""; display:block; width:52px; height:52px; margin:0 0 .6rem; background:var(--li-ink);
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat; -webkit-mask-position:left center;mask-position:left center;
  -webkit-mask-size:contain;mask-size:contain; }
.li-grid--dood>.li-card:nth-child(1)::before{ -webkit-mask-image:url(assets/img/doodles/calendar.png);mask-image:url(assets/img/doodles/calendar.png); }
.li-grid--dood>.li-card:nth-child(2)::before{ -webkit-mask-image:url(assets/img/doodles/schedule.png);mask-image:url(assets/img/doodles/schedule.png); }
.li-grid--dood>.li-card:nth-child(3)::before{ -webkit-mask-image:url(assets/img/doodles/camera.png);mask-image:url(assets/img/doodles/camera.png); }
.li-grid--dood>.li-card:nth-child(4)::before{ -webkit-mask-image:url(assets/img/doodles/megaphone.png);mask-image:url(assets/img/doodles/megaphone.png); }
.li-grid--dood>.li-card:nth-child(5)::before{ -webkit-mask-image:url(assets/img/doodles/mug.png);mask-image:url(assets/img/doodles/mug.png); }

/* Item 4b · ARC (17) Reading Room: homepage counter cards placed right, carrying
   the metrics that matter (also evens the li-rr-cols row, audit item 14). */
.li-rr-statwall{ display:grid; grid-template-columns:repeat(2,1fr); grid-auto-rows:1fr;
  gap:clamp(.8rem,1.6vw,1.2rem); margin-top:1.3rem; align-items:stretch; max-width:460px; }
.li-rr-statwall>.li-stat{ box-sizing:border-box; height:100%; max-width:none; margin:0;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  background:var(--li-paper); border:2px solid var(--li-ink); border-radius:16px; box-shadow:5px 5px 0 var(--li-ink);
  padding:clamp(1.15rem,2vw,1.6rem) clamp(.8rem,1.5vw,1.15rem); text-align:center; position:relative;
  transition:transform .3s var(--li-pop), box-shadow .3s ease; }
.li-rr-statwall>.li-stat::before{ content:""; position:absolute; z-index:2; pointer-events:none; top:-11px; left:50%;
  width:70px; height:21px; transform:translateX(-50%) rotate(-3deg); background:var(--li-tape); border:var(--li-tape-edge); border-radius:2px; }
.li-rr-statwall>.li-stat:nth-child(2)::before{ background:var(--li-butter); transform:translateX(-50%) rotate(2.6deg); width:60px; }
.li-rr-statwall>.li-stat:nth-child(3)::before{ transform:translateX(-50%) rotate(2.2deg); width:58px; }
.li-rr-statwall>.li-stat:nth-child(4)::before{ background:var(--li-butter); transform:translateX(-50%) rotate(-2deg); width:66px; }
.li-rr-statwall>.li-stat:nth-child(odd){ transform:rotate(-1.1deg); }
.li-rr-statwall>.li-stat:nth-child(even){ transform:rotate(1.1deg); }
.li-rr-statwall>.li-stat:hover{ transform:rotate(0) translateY(-4px); box-shadow:7px 9px 0 var(--li-forest); }
.li-rr-statwall .li-stat__num{ margin:0 !important; font-family:var(--li-display); font-variation-settings:"SOFT" 100,"WONK" 1;
  font-weight:570; letter-spacing:-.02em; line-height:.98; color:var(--li-forest); white-space:nowrap; font-size:clamp(1.7rem,2.5vw,2.3rem) !important; }
.li-rr-statwall .li-stat__label{ margin:.45rem 0 0 !important; font-family:var(--li-sans); font-weight:600;
  font-size:.8rem !important; line-height:1.25; color:var(--li-ink); opacity:.82; max-width:18ch; min-height:2.5em; }
@media(prefers-reduced-motion:reduce){ .li-rr-statwall>.li-stat,.li-rr-statwall>.li-stat:hover{transform:none !important;} }
@media(max-width:781px){ .li-rr-statwall{ margin-inline:auto; } }

/* Item 4a · One bullet everywhere. The Reading Room doodle-star becomes the
   standard for the plain gutter-bullet lists (li-getlist and the example-doc
   gains list). Lists already on --dood are unchanged; the li-glance__list
   checkbox tiles are a different component and keep their drawn checkbox. */
.li-getlist li::before,
.li-exdoc__gains li::before{ content:"" !important; left:0; top:.12em; width:1.4rem; height:1.4rem;
  background:var(--li-lavender-deep); font-size:0 !important;
  -webkit-mask:url(assets/img/doodles/star.png) center/contain no-repeat; mask:url(assets/img/doodles/star.png) center/contain no-repeat; }
.li-exdoc__gains li::before{ top:.06em; width:1.15rem; height:1.15rem; }
.has-forest-background-color .li-getlist li::before,
.has-forest-deep-background-color .li-getlist li::before,
.has-forest-background-color .li-exdoc__gains li::before,
.has-forest-deep-background-color .li-exdoc__gains li::before{ background:var(--li-chartreuse) !important; }

/* 2026-09-05 Branded service graphics (Meg-approved polished set): side accent, tape suppressed. A7 is now dead once no element carries .xx-gfx */
figure.li-inlinesvg:has(.li-svcgfx)::before,figure.li-inlinesvg:has(.li-svcgfx)::after,.wp-block-column:has(.li-svcgfx)::before,.wp-block-column:has(.li-svcgfx)::after{display:none!important;content:none!important;background:none!important}
.li-svcgfx{max-width:440px!important;height:auto}
@media(max-width:782px){.li-svcgfx{max-width:360px!important}}
