/* Latin subsets served from wwwroot/fonts; see fonts/OFL.txt. Libre Franklin
   ships as a variable face, so one file covers weights 100–900. */
@font-face {
    font-family: "Libre Franklin";
    src: url("/fonts/libre-franklin-latin.woff2") format("woff2");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Libre Franklin";
    src: url("/fonts/libre-franklin-latin-italic.woff2") format("woff2");
    font-weight: 100 900;
    font-style: italic;
    font-display: swap;
}

/* the wordmark: the TrueType the legacy header shipped, not a woff2 subset */
@font-face {
    font-family: "Young Serif";
    src: url("/fonts/YoungSerif-Regular.ttf") format("truetype");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Libre Caslon Display";
    src: url("/fonts/libre-caslon-display-latin.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Libre Caslon Text";
    src: url("/fonts/libre-caslon-text-latin.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Libre Caslon Text";
    src: url("/fonts/libre-caslon-text-latin-italic.woff2") format("woff2");
    font-weight: 400;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: "Libre Caslon Text";
    src: url("/fonts/libre-caslon-text-latin-700.woff2") format("woff2");
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

:root {
    --bark: #22302a;
    --bark-soft: #3a4a40;
    --leaf: #2e5e45;
    --leaf-light: #3e7458;
    --leaf-pale: #e7ede2;
    --sun: #9c7a33;
    --sun-light: #b08a3e;
    --sun-pale: #f4ead7;
    --paper: #f3ebda;
    --cream: #ebdfc8;
    --muted: #5c5044;
    --muted-soft: #8a7c6d;
    --border: #d8c9b0;
    --border-light: #e3d8c4;
    --gold: #c9a24b;
    --gold-warm: #e5c57e;
    --gold-light: #e6c879;
    --gold-deep: #c29a45;
    --ink: #0b1a13;
    --red: #8b3a2f;
    --shadow-soft: rgba(50, 44, 36, 0.06);
    --shadow-md: rgba(50, 44, 36, 0.12);

    /* shell surfaces */
    --pine: #13291d;
    --forest: #0a1810;
    --spruce: #16382a;
    --moss: #25563f;
    --sand: #c7bca8;
    --rule-dark: rgba(244, 234, 215, 0.22);
    --scrim: rgba(6, 14, 9, 0.62);
    /* the heritage chrome — the header and the drawer — names its own paper,
       so the one drawer resolves to the same colour in both stylesheets */
    --chrome-text: #f4ead7;
    --field: #fcf9f2;
    --red-pale: #f6e7e2;

    /* book card: parchment stock, and the oxblood ribbon lying on it */
    --card: #fdfcfa;
    --parchment-top: #fffdf7;
    --parchment-bottom: #f8f0df;
    --ribbon-edge: #4f111c;
    --ribbon-face: #9c2b31;
    --ribbon-fold: #5e1421;

    --ff: "Libre Franklin", system-ui, sans-serif;
    --ff-display: "Libre Caslon Display", Georgia, serif;
    --ff-text: "Libre Caslon Text", Georgia, serif;
    --ff-brand: "Young Serif", var(--ff-display);
}

*,
*::before,
*::after {
    box-sizing: border-box;
}

/* dark green so an iOS rubber-band pull shows pine, not a beige flash.
   The html element alone is not enough: the body's own background paints
   into the overscroll region at both ends, so the body stays pine and the
   paper moves to a dedicated layer below. */
html {
    background-color: var(--pine);
}

body {
    display: flex;
    flex-direction: column;
    min-height: 100dvh;
    margin: 0;
    position: relative;
    font-family: var(--ff);
    color: var(--bark);
    background-color: var(--pine);
    line-height: 1.6;
    letter-spacing: 0.005em;
    font-kerning: normal;
    font-variant-ligatures: common-ligatures;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}
/* The paper grain over the whole screen, as an element rather than
   body::after. iOS 26 Safari fills the strips under its status bar and
   toolbar from the fixed or sticky box it finds at each screen edge. A
   pseudo-element answers that search as its host, the body, so over
   body::after Safari found no box at either edge and filled both strips with
   the document's colour — one colour for two ends that are not the same
   colour. A fixed box this faint that takes no pointer is one WebKit looks
   straight through (its layout test color-sampling-ignores-transparent-
   pointer-events-none-container), so Safari now finds the pinned header at
   the top.

   While the menu is open the grain moves back onto body::after, where Safari
   reads it as the body again. Then no box at either edge can be the one
   Safari picks — not the panel's spruce top, not a sliver of the page in the
   instant the panel is still sliding — and both strips take the document's
   colour, which the rules further down set to the panel's own at the edge
   the page runs out at. Opening or closing the menu at any scroll position
   lands on that one rule. */
.paper-grain,
body.sidebar-open::after {
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 9999;
    opacity: 0.06;
    mix-blend-mode: multiply;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 600 600'%3E%3Cfilter id='a'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23a)'/%3E%3C/svg%3E");
    background-repeat: repeat;
    background-size: 182px;
}
body.sidebar-open::after {
    content: "";
}
body.sidebar-open .paper-grain {
    display: none;
}

body.sidebar-open {
    overflow: hidden;
}

/* The screen's two edges on an iPhone. The top strip takes the pinned
   header's own pine, which Safari now finds there (see the grain above).
   Where the page runs out at its end, Safari clips what the page paints and
   fills the gap with the document's background colour. So the document
   colour follows the reader: the header's pine while the top is the nearer
   end, the footer's paper once the reader is nearer the end or on a page too
   short to scroll, whose end is on screen at rest. /js/edges.js marks the
   root .at-end.

   Mid-page Safari keeps fixed boxes — the paper layer below among them — out
   of the strip under its toolbar, where the pine body used to show through
   the page as a band. The body's own flow now carries the paper as an image,
   so the page goes on beneath the toolbar in its own colour; as an image it
   leaves the colour to the edge rules here. */
body:not(.auth-page) {
    background-image: linear-gradient(var(--paper), var(--paper));
}
html.at-end body {
    background-color: var(--paper);
}

/* The paper the reader reads on. The body itself stays pine (see above), so
   this fixed layer behind the content paints the paper edge to edge instead:
   overscroll past either end reveals pine, never beige. */
.app-background {
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background-color: var(--paper);
}

h1,
h2,
h3 {
    font-family: var(--ff-display);
    font-weight: 400;
    letter-spacing: -0.02em;
    line-height: 1.2;
}

a {
    color: var(--leaf);
}
a:hover {
    color: var(--leaf-light);
}

/* The heritage header every page but the home page carries: a dark pine bar
   pinned over the paper, the wordmark flush against the bird, and the
   hamburger — the one menu control at every width, because the drawer is the
   whole navigation whatever the screen. */
.site-header {
    position: sticky;
    top: 0;
    z-index: 80;
    background-color: var(--pine);
    background-image: linear-gradient(180deg, var(--pine) 0%, var(--forest) 100%);
    border-bottom: 1px solid rgba(201, 162, 75, 0.24);
    box-shadow: 0 2px 18px rgba(6, 14, 9, 0.4);
}

/* An iOS rubber-band pull can push page text into the band above the header,
   where only the canvas pine paints and, sitting under every layer, masks
   nothing. This carries the header's pine up over the content instead: the
   band above the header paints over page text, never under it. */
.site-header::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 100%;
    height: 100vh;
    background-color: var(--pine);
}

.site-header-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: calc(12px + env(safe-area-inset-top, 0px)) clamp(16px, 4vw, 40px) 12px;
}

.site-brand {
    display: flex;
    align-items: center;
    gap: 0;
    color: var(--chrome-text);
    text-decoration: none;
}
.site-brand img {
    display: block;
    width: 44px;
    height: 44px;
    filter: drop-shadow(1px 2px 4px rgba(0, 0, 0, 0.45));
}
.site-brand span {
    margin-left: -3px;
    font-family: var(--ff-brand);
    font-size: 22px;
    letter-spacing: -0.01em;
}

.site-menu-button {
    display: inline-flex;
    flex: none;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 5px;
    width: 44px;
    height: 44px;
    padding: 0;
    background: transparent;
    border: 1px solid rgba(244, 234, 215, 0.18);
    border-radius: 9px;
    cursor: pointer;
    transition: all 0.2s ease;
}
.site-menu-button:hover,
.site-menu-button:focus-visible {
    border-color: var(--gold);
}
.site-menu-button i {
    width: 20px;
    height: 1.5px;
    border-radius: 1px;
    background: var(--gold-warm);
}

.app-main {
    flex: 1;
    margin: 0 auto;
    max-width: 900px;
    padding: 24px 16px 48px;
    position: relative;
    width: 100%;
    z-index: 1;
}

.app-footer {
    position: relative;
    z-index: 1;
    background-color: var(--paper);
    border-top: 1px solid var(--border-light);
    color: var(--muted-soft);
    font-family: var(--ff-text);
    font-size: 13px;
    font-style: italic;
    padding: 28px 16px calc(28px + env(safe-area-inset-bottom, 0px));
    text-align: center;
}
/* At the page's end iOS 26 Safari's floating toolbar still lies over the
   last ~50px of the page, and the footer's line sat under the toolbar's top
   edge. On a phone the footer keeps that much more room beneath its line. */
@media (max-width: 767px) {
    .app-footer {
        padding-bottom: calc(56px + env(safe-area-inset-bottom, 0px));
    }
}
/* The one global drawer, and the only menu either runtime serves: the legacy
   heritage panel, dark pine behind a gold edge, sliding in from the right over
   a blurred scrim. Every rule from here to the drawer's call to action is the
   same text in site.css and home.css — one menu, not two that resemble each
   other. */
.sidebar-backdrop {
    position: fixed;
    right: 0;
    bottom: -140px;
    left: 0;
    height: calc(100% + 280px);
    z-index: 90;
    background: var(--scrim);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    /* the visibility waits out the fade, so the scrim is gone when it is done
       and never sits invisible over the page catching clicks */
    transition: opacity 0.4s ease, visibility 0s linear 0.4s;
}
.sidebar-backdrop.open {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    cursor: pointer;
    transition: opacity 0.4s ease;
}

/* The panel runs 140px past each screen edge — the reach the scrim beside it
   already has — so it spans the whole physical screen even where iOS 26 keeps
   fixed boxes inside the safe area (WebKit 301108). Both edges get one
   treatment: the box anchors at the bottom reach that holds on iOS and its
   height carries the same reach past the top — no top inset for the engine
   to clamp — and the header's and footer's safe-area padding folds the
   overrun back into the content. No painted band, mask, or shadow covers
   either edge; the panel itself reaches. */
.sidebar-drawer {
    position: fixed;
    right: 0;
    bottom: -140px;
    z-index: 100;
    display: flex;
    flex-direction: column;
    width: min(88vw, 374px);
    height: calc(100% + 280px);
    background-color: var(--pine);
    background-image: linear-gradient(180deg, var(--spruce) 0%, var(--pine) 46%, var(--forest) 100%);
    border-left: 1px solid rgba(201, 162, 75, 0.28);
    transform: translateX(calc(100% + 80px));
    transition: transform 0.42s cubic-bezier(0.4, 0, 0.1, 1);
}
.sidebar-drawer.open {
    transform: translateX(0);
}

/* the pinned top zone: the mark and the wordmark against the close control,
   over the gold rule the legacy ruled under them */
.sidebar-header {
    display: flex;
    flex: none;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: calc(162px + env(safe-area-inset-top, 0px)) 20px 22px;
    border-bottom: 1px solid rgba(201, 162, 75, 0.24);
}
.sidebar-brand {
    display: flex;
    align-items: center;
    gap: 0;
    color: var(--chrome-text);
    text-decoration: none;
}
.sidebar-brand img {
    display: block;
    width: 42px;
    height: 42px;
    filter: drop-shadow(1px 2px 4px rgba(0, 0, 0, 0.45));
}
.sidebar-brand span {
    margin-left: -3px;
    font-family: var(--ff-brand);
    font-size: 23px;
    letter-spacing: -0.01em;
}

.sidebar-close {
    display: inline-flex;
    flex: none;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    padding: 0;
    background: none;
    border: 1px solid rgba(244, 234, 215, 0.18);
    border-radius: 50%;
    color: var(--sand);
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    transition: border-color 0.2s ease, color 0.2s ease;
}
.sidebar-close:hover {
    border-color: var(--gold);
    color: var(--gold-warm);
}

/* the scrolling middle, faded at both edges the way the legacy masked it, so a
   link half past the fold reads as more to come rather than as a cut */
.sidebar-nav {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 18px 16px 10px;
    -webkit-mask-image: linear-gradient(180deg, transparent 0, black 16px, black calc(100% - 16px), transparent 100%);
    mask-image: linear-gradient(180deg, transparent 0, black 16px, black calc(100% - 16px), transparent 100%);
}

.sidebar-section + .sidebar-section {
    margin-top: 24px;
}
.sidebar-section-label {
    margin: 0 0 8px 14px;
    color: var(--sand);
    font-family: var(--ff);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.12em;
    opacity: 0.7;
    text-transform: uppercase;
}

.sidebar-item {
    position: relative;
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    margin-bottom: 2px;
    padding: 11px 14px;
    border: none;
    border-radius: 8px;
    background: transparent;
    color: var(--sand);
    font-family: var(--ff);
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    text-align: left;
    text-decoration: none;
    transition: background-color 150ms ease, color 150ms ease;
}
.sidebar-item:hover {
    background: rgba(244, 234, 215, 0.06);
    color: var(--chrome-text);
}

/* the legacy item reserves a 12px gap for an icon column; this is that column */
.sidebar-icon {
    flex: none;
    width: 18px;
    height: 18px;
    color: inherit;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* the page you are on, marked the way the legacy drawer marked it: a gold bar
   down the item's left edge, and the item itself lit */
.sidebar-item.active {
    background: rgba(201, 162, 75, 0.12);
    color: var(--chrome-text);
    font-weight: 600;
}
.sidebar-item.active::before {
    content: "";
    position: absolute;
    top: 8px;
    bottom: 8px;
    left: 0;
    width: 3px;
    border-radius: 0 2px 2px 0;
    background: var(--gold);
}
.sidebar-item:focus-visible,
.sidebar-close:focus-visible,
.sidebar-cta:focus-visible {
    outline: 2px solid var(--gold);
    outline-offset: 2px;
}

/* the guest zone the legacy pinned to the foot of the drawer */
.sidebar-footer {
    flex: none;
    padding: 14px 16px calc(160px + env(safe-area-inset-bottom, 0px));
    border-top: 1px solid rgba(201, 162, 75, 0.24);
}

/* the drawer's call to action, full width: once at the head of the links and
   again in the guest footer, as the legacy served it */
.sidebar-cta {
    display: block;
    margin: 0 0 16px;
    padding: 14px 18px;
    background-image: linear-gradient(180deg, var(--gold-light), var(--gold-deep));
    border-radius: 5px;
    color: var(--ink);
    font-family: var(--ff);
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.12em;
    line-height: 1;
    text-align: center;
    text-decoration: none;
    text-transform: uppercase;
}

/* the page a dead address lands on, set as a short notice rather than a page
   of its own so the shell and the menu around it carry the weight */
.notice {
    margin: 2rem auto;
    max-width: 34rem;
    text-align: center;
}
.notice p {
    margin-top: 0.75rem;
    color: var(--muted);
    font-family: var(--ff-text);
}
.notice-back {
    display: inline-block;
    margin-top: 1.5rem;
    padding: 0.55rem 1.25rem;
    border: 1px solid var(--leaf);
    border-radius: 999px;
    font-family: var(--ff);
    font-size: 0.9rem;
    text-decoration: none;
}
.notice-back:hover {
    background: var(--leaf-pale);
}
/* the one button on the unsubscribe page, set where the back link would be */
.notice-action {
    margin-top: 1.5rem;
    cursor: pointer;
}

/* the card grid runs wider than the reading column the shell sets for prose.
   Keyed on the filter's swap target, which only the catalogue renders, so the
   page needs nothing from the shell to be wide. */
.app-main:has(> #catalogue) {
    max-width: 1100px;
}
.community-column {
    max-width: 660px;
    margin: 0 auto;
}

.page-head {
    margin-bottom: 1.75rem;
    padding-bottom: 0.6rem;
    border-bottom: 1px solid var(--sun);
}
.page-head h1 {
    margin: 0;
    font-size: clamp(28px, 7vw, 38px);
}

.bands {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 1.5rem;
    font-family: var(--ff);
    font-size: 14px;
}
.bands a {
    padding: 6px 14px;
    border: 1px solid rgba(37, 107, 53, 0.19);
    border-radius: 100px;
    background: var(--leaf-pale);
    font-weight: 500;
    text-decoration: none;
    transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
}
.bands a:hover {
    border-color: var(--leaf);
}
.bands a.active {
    border-color: var(--leaf);
    background: var(--leaf);
    color: var(--paper);
}
.bands small {
    color: inherit;
    font-size: 12px;
    opacity: 0.75;
}
/* on a phone the six pills take touch-sized targets and still close in three
   rows rather than four from 390px up */
@media (max-width: 767px) {
    .bands {
        gap: 6px;
    }
    .bands a {
        padding: 10px 9px;
    }
}

/* the legacy's catalogue search: an input with a focus ring, painted exactly
   as the legacy declared. The form sets it in a row with its button on the
   left edge the heading, pills and cards share; the input's own bottom margin
   is the gap down to the pills. */
.catalog-search-form {
    display: grid;
    grid-template-columns: minmax(0, 420px) auto;
    justify-content: start;
    column-gap: 8px;
    align-items: start;
    margin: 0;
}
.catalog-search-label {
    grid-column: 1 / -1;
    display: block;
    margin-bottom: 8px;
    color: var(--muted);
    font-family: var(--ff);
    font-size: 13px;
    font-weight: 600;
}
.catalog-search {
    display: block;
    width: 100%;
    max-width: 420px;
    margin: 0 auto 32px;
    padding: 12px 18px;
    font-family: var(--ff);
    font-size: 15px;
    color: var(--bark);
    background: var(--field);
    border: 2px solid var(--border-light);
    border-radius: 10px;
    outline: none;
    transition: border-color 0.2s, box-shadow 0.2s;
}
.catalog-search:focus {
    border-color: var(--leaf);
    box-shadow: 0 0 0 3px var(--leaf-pale);
    outline: none;
}
/* on a phone the field is set at 16px, the size under which iOS Safari zooms
   the page into a field on focus; it follows the field's own rule so it
   outranks it */
@media (max-width: 767px) {
    .catalog-search {
        font-size: 16px;
    }
}
.catalog-search-submit {
    display: block;
    height: 46px;
    margin: 0;
    padding: 0 20px;
    font-family: var(--ff);
    font-size: 14px;
    font-weight: 600;
    color: var(--leaf);
    background: var(--leaf-pale);
    border: none;
    border-radius: 10px;
    cursor: pointer;
    transition: background-color 150ms ease, color 150ms ease;
}
.catalog-search-submit:hover {
    background: var(--leaf);
    color: var(--paper);
}
/* the catalog's controls take the site's one focus ring */
.catalog-search-submit:focus-visible,
.bands a:focus-visible,
a.pager-btn:focus-visible {
    outline: 2px solid var(--sun);
    outline-offset: 2px;
}

/* the legacy's catalogue pager: leaf-pale buttons under a hairline */
.catalog-pager {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 16px;
    margin-top: 40px;
    padding-top: 24px;
    border-top: 1px solid var(--border-light);
}
.pager-btn {
    display: inline-block;
    font-family: var(--ff);
    font-size: 13px;
    font-weight: 600;
    color: var(--leaf);
    background: var(--leaf-pale);
    border: none;
    border-radius: 8px;
    padding: 8px 20px;
    cursor: pointer;
    text-decoration: none;
}
a.pager-btn:hover {
    background: var(--leaf);
    color: var(--paper);
    transform: translateY(-1px);
}
span.pager-btn[aria-disabled="true"] {
    color: var(--muted-soft);
    background: var(--border-light);
    cursor: not-allowed;
}
.pager-status {
    font-family: var(--ff);
    font-size: 13px;
    color: var(--muted);
}

ul.works {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 16px;
    list-style: none;
    margin: 0;
    padding: 0;
}
/* My Library is the catalog's shelf holding the reader's own: the same
   parchment cards and pills. A guide in the reader's own version wears a gilt
   ribbon where the catalog's is oxblood; a drill sheet is a leaf of exercise
   paper with its margin rule. The title's link stretches over the card, and
   the card's own tools stand above it. */
.app-main:has(> .my-library) { max-width: 1100px; }
.library-filters small { margin-left: 2px; font-variant-numeric: tabular-nums; }
.book-card.library-card { min-height: 196px; }
.library-card h2, .library-card .book-card-bands, .library-card .library-card-tools { margin: 0; }
.library-card .book-card-bands { margin-top: auto; }
.library-card.is-drill { padding-right: 24px; }
.library-card-link { color: inherit; text-decoration: none; }
.library-card-link::after { content: ""; position: absolute; inset: 0; }
.library-card:has(.library-card-link:focus-visible) { outline: 2px solid var(--sun); outline-offset: 2px; }
.library-card:hover .book-card-title { color: var(--leaf); }
.library-card.is-adapted::before {
    background: linear-gradient(90deg, color-mix(in srgb, var(--parchment-top) 30%, transparent), transparent 40%),
        linear-gradient(112deg, var(--gold-deep), var(--gold-light) 48%, var(--sun));
}
.library-card.is-drill {
    background: linear-gradient(90deg, transparent 15px, color-mix(in srgb, var(--ribbon-face) 34%, transparent) 15px 16px, transparent 16px),
        repeating-linear-gradient(180deg, transparent 0 27px, color-mix(in srgb, var(--leaf) 13%, transparent) 27px 28px),
        linear-gradient(180deg, var(--parchment-top), var(--parchment-bottom));
}
.library-card.is-drill::before { content: none; }
.library-card.is-drill .book-card-bands span { border-color: var(--border); background: var(--field); color: var(--bark-soft); }
.book-card-bands .library-mark {
    border-color: color-mix(in srgb, var(--sun) 45%, transparent);
    background: var(--sun-pale);
    color: color-mix(in srgb, var(--sun) 70%, var(--bark));
}
.library-card-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 12px; margin-top: 14px; }
.library-card-tools { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: 13px; font-weight: 600; }
.library-card-tools a, .library-remove button {
    position: relative; z-index: 1; display: inline-flex; align-items: center; min-height: 32px; text-underline-offset: 3px;
}
.library-remove button { padding: 0; border: 0; background: none; color: var(--muted); font: inherit; font-size: 13px; cursor: pointer; }
.library-remove button:hover { color: var(--red); text-decoration: underline; }
.library-card-tools a:focus-visible, .library-remove button:focus-visible { outline: 2px solid var(--sun); outline-offset: 2px; }
.library-card .library-card-error { margin: 8px 0 0; color: var(--red); font-size: 14px; }
.library-empty { max-width: 34rem; margin: 32px 0 8px; }
.library-empty .empty { font-family: var(--ff-text); font-size: 17px; line-height: 1.6; }
.library-empty-links { display: flex; flex-wrap: wrap; gap: 10px; }
@media (pointer: coarse) {
    .library-card-tools a, .library-remove button { min-height: 44px; }
}

/* the legacy laid a .book-parchment-card over a plain white .book-card; this
   build renders the parchment one only, so the two rules are one */
.book-card {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 154px;
    padding: 26px 64px 22px 24px;
    position: relative;
    overflow: hidden;
    border: 1px solid rgba(184, 117, 8, 0.25);
    border-radius: 8px;
    background:
        linear-gradient(135deg, rgba(255, 255, 255, 0.65), rgba(255, 255, 255, 0) 42%),
        radial-gradient(circle at 18% 12%, rgba(184, 117, 8, 0.08), transparent 30%),
        linear-gradient(180deg, var(--parchment-top) 0%, var(--parchment-bottom) 100%);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.44), 0 1px 2px rgba(58, 54, 50, 0.04),
        0 8px 20px rgba(58, 54, 50, 0.08);
    text-decoration: none;
    transition: transform 200ms cubic-bezier(0.16, 1, 0.3, 1),
        box-shadow 200ms cubic-bezier(0.16, 1, 0.3, 1), border-color 200ms ease;
}
.book-card:hover {
    transform: translateY(-3px);
    border-color: rgba(184, 117, 8, 0.45);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.44), 0 2px 4px rgba(58, 54, 50, 0.04),
        0 8px 16px rgba(58, 54, 50, 0.06), 0 16px 32px rgba(58, 54, 50, 0.08),
        0 24px 48px rgba(46, 63, 94, 0.06);
}
.book-card:focus-visible {
    outline: 2px solid var(--sun);
    outline-offset: 2px;
}

/* the ribbon marker, and the rule it hangs above */
.book-card::before {
    content: "";
    position: absolute;
    top: 0;
    right: 28px;
    width: 48px;
    height: 104px;
    pointer-events: none;
    background:
        linear-gradient(90deg, rgba(255, 253, 247, 0.22) 0%, rgba(255, 253, 247, 0.08) 16%,
            rgba(88, 17, 26, 0) 38%),
        linear-gradient(112deg, var(--ribbon-edge) 0%, var(--ribbon-face) 48%,
            var(--ribbon-fold) 100%);
    box-shadow: inset -5px 0 8px rgba(47, 12, 16, 0.2), 0 3px 4px rgba(61, 37, 18, 0.16);
    clip-path: polygon(0 0, 100% 0, 100% 100%, 64% 88%, 50% 80%, 36% 88%, 0 100%);
    filter: drop-shadow(0 3px 3px rgba(61, 37, 18, 0.14));
}
.book-card::after {
    content: "";
    position: absolute;
    right: 24px;
    bottom: 15px;
    left: 24px;
    height: 1px;
    pointer-events: none;
    background: linear-gradient(90deg, transparent, rgba(61, 37, 18, 0.16), transparent);
}

.book-card-title {
    color: var(--bark);
    font-family: var(--ff-display);
    font-size: 18px;
    font-weight: 600;
    line-height: 1.35;
    letter-spacing: -0.005em;
    transition: color 200ms ease;
}
.book-card:hover .book-card-title {
    color: var(--leaf);
}
.book-card-author {
    margin: 6px 0 0;
    color: var(--muted-soft);
    font-size: 13px;
}
.book-card-bands {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: auto;
    padding-top: 16px;
}
.book-card-bands span {
    padding: 4px 12px;
    border: 1px solid rgba(37, 107, 53, 0.19);
    border-radius: 100px;
    background: var(--leaf-pale);
    color: var(--leaf);
    font-size: 12px;
    font-weight: 500;
}

/* a work is a book, and the legacy set a book's title larger than a page's */
.work h1 {
    color: var(--bark);
    font-family: var(--ff-display);
    font-size: clamp(24px, 4vw, 34px);
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -0.015em;
}
.work .author {
    display: block;
    margin: 6px 0 0;
    color: var(--muted);
    font-family: var(--ff-text);
    font-size: 16px;
}
.work .offered {
    margin: 0.5rem 0 0;
    color: var(--muted-soft);
    font-size: 14px;
}

ul.guides {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 16px;
    list-style: none;
    margin: 1.75rem 0 0;
    padding: 0;
}
ul.guides a {
    display: block;
    padding: 24px;
    border: 1px solid var(--border-light);
    border-radius: 12px;
    background: var(--card);
    box-shadow: 0 1px 2px rgba(50, 44, 36, 0.06), 0 2px 4px rgba(50, 44, 36, 0.05);
    color: var(--bark);
    font-family: var(--ff-display);
    font-size: 18px;
    line-height: 1.35;
    text-decoration: none;
    transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease,
        transform 150ms ease;
}
/* the guide card answers the cursor the way the book card that led here does:
   the title turns leaf */
ul.guides a:hover {
    transform: translateY(-1px);
    border-color: var(--sun);
    background: var(--sun-pale);
    color: var(--leaf);
}

.empty {
    color: var(--muted);
    font-style: italic;
}
/* the catalog's and a work's empty states read as a sentence in the book's
   voice, set off from the controls above rather than tucked under them */
#catalogue > .empty,
.work > .empty {
    margin: 32px 0 0;
    font-family: var(--ff-text);
    font-size: 16px;
}

/* The reduced-motion guard lives at the end, after every hover lift above,
   so document order resolves in its favour: a media query adds no
   specificity, and at equal specificity the later rule wins. Moving rules
   between these two blocks — or adding a hover lift below this block —
   silently re-breaks the guard; the stage 03 gate checks the win in document
   order, not the mere presence of transform: none. */
@media (prefers-reduced-motion: reduce) {
    .sidebar-drawer,
    .sidebar-drawer.open,
    .sidebar-backdrop,
    .sidebar-backdrop.open {
        transition: none;
    }
    .book-card,
    ul.guides a {
        transition: none;
    }
    .book-card:hover,
    ul.guides a:hover,
    a.pager-btn:hover {
        transform: none;
    }
}

footer.edition {
    margin-top: 2rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--border);
    font-size: 14px;
    color: var(--muted);
}

/* ==== Get the book: a work page's edition and print links (begin) ====
   WorkPage.razor's footer: the edition every guide on the page follows, a
   way to get a copy of it, and each guide's print sheets beside it, so a
   reader leaves with the book and the pages to use with it. Every rule here
   is keyed on .get-a-copy, which only the work page renders. The links take
   the catalog's secondary-action face (leaf on leaf-pale, as a guide's own
   tools); only the free ebook, where there is one, is inked solid. Nothing
   here lifts under the pointer, so the reduced-motion guard is not needed.
   It sits beside footer.edition, not with the work page's other rules near
   the end of the file: its first rule extends the edition footer itself, so
   the edition and the ways to get a copy of it stand together. */
.work > footer.edition {
    padding-top: 24px;
}
.get-a-copy {
    display: grid;
    gap: 24px;
    color: var(--muted);
    font-family: var(--ff);
}
.get-a-copy h2 {
    margin: 0;
    color: var(--bark);
    font-size: 21px;
}
.get-a-copy .copy-lead {
    margin: 6px 0 0;
    font-size: 14px;
}
.get-a-copy cite {
    display: block;
    max-width: 34em;
    margin: 4px 0 16px;
    color: var(--bark-soft);
    font-family: var(--ff-text);
    font-size: 15px;
    line-height: 1.55;
}
.get-a-copy .copy-links {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0;
}
.get-a-copy .copy-links a {
    display: inline-flex;
    align-items: center;
    min-height: 40px;
    padding: 0 16px;
    border-radius: 10px;
    background: var(--leaf-pale);
    color: var(--leaf);
    font-size: 14px;
    font-weight: 600;
    text-decoration: none;
    transition: background-color 150ms ease, color 150ms ease;
}
.get-a-copy .copy-links a:hover {
    background: var(--leaf);
    color: var(--paper);
}
.get-a-copy .copy-free a {
    background: var(--leaf);
    color: var(--paper);
}
.get-a-copy .copy-free a:hover {
    background: var(--leaf-light);
}
.get-a-copy .copy-isbn {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 14px;
    align-items: baseline;
    margin: 0 0 6px;
    font-size: 14px;
}
.get-a-copy .copy-isbn span {
    color: var(--bark);
    font-variant-numeric: tabular-nums;
}
.get-a-copy .copy-isbn a {
    display: inline-block;
    padding: 8px 0;
    font-weight: 600;
}
.get-a-copy .copy-shops {
    display: grid;
    gap: 12px;
    margin: 0;
}
.get-a-copy .copy-shops dt {
    margin-bottom: 6px;
    color: var(--muted);
    font-size: 13px;
    font-weight: 600;
}
.get-a-copy .copy-shops dd {
    margin: 0;
}
.get-a-copy .copy-note {
    margin: 12px 0 0;
    color: var(--muted);
    font-size: 13px;
}
.get-a-copy .copy-print {
    padding-top: 20px;
    border-top: 1px solid var(--border-light);
}
.get-a-copy .copy-print h2 {
    margin-bottom: 14px;
}
@media (pointer: coarse) {
    .get-a-copy .copy-links a {
        min-height: 44px;
    }
}
/* from a tablet up the shop labels sit in a column of their own, and the
   print sheets stand beside the book rather than under it */
@media (min-width: 560px) {
    .get-a-copy .copy-shops > div {
        display: grid;
        grid-template-columns: 5.5rem minmax(0, 1fr);
        align-items: center;
    }
    .get-a-copy .copy-shops dt {
        margin-bottom: 0;
    }
}
@media (min-width: 760px) {
    .get-a-copy:has(> .copy-print) {
        grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
        gap: 32px;
    }
    .get-a-copy .copy-print {
        padding: 0 0 0 32px;
        border-top: 0;
        border-left: 1px solid var(--border-light);
    }
}
/* ==== Get the book (end) ==== */

/* the single back link above a title, on the pages that carry no trail */
.work-link {
    margin-bottom: 0;
    font-size: 0.95rem;
}

.breadcrumbs {
    margin-bottom: 24px;
    color: var(--muted-soft);
    font-family: var(--ff);
    font-size: 12px;
}
/* the vertical padding widens each crumb's tap target into the space around
   the trail without moving a line of it */
.breadcrumbs a {
    padding: 12px 0;
    color: var(--muted-soft);
    text-decoration: none;
    transition: color 150ms ease;
}
.breadcrumbs a:hover {
    color: var(--leaf);
}
.breadcrumbs a::after {
    content: " › ";
    color: var(--muted-soft);
}
.breadcrumbs .current {
    color: var(--bark);
}
/* every link on the reading pages takes the site's focus ring */
.guide a:focus-visible,
.work a:focus-visible {
    outline: 2px solid var(--sun);
    outline-offset: 2px;
}

/* the guide opens on a tinted band, the way the legacy hero sat behind a title.
   The negative margin is .app-main's own padding, so the band runs edge to edge
   rather than sitting inside the column as a card. Its text starts on the
   column's edge, where every section below starts: below 1024px the inset
   narrows to the column's, and from 1024px the band steps out past it. */
.guide-head {
    margin: -24px -16px 32px;
    padding: 48px 24px;
    position: relative;
    overflow: hidden;
    background:
        radial-gradient(ellipse at 25% 30%, rgba(47, 76, 122, 0.06) 0%, transparent 60%),
        radial-gradient(ellipse at 75% 60%, rgba(139, 58, 47, 0.05) 0%, transparent 55%),
        radial-gradient(ellipse at 50% 80%, rgba(47, 76, 122, 0.04) 0%, transparent 50%);
}
@media (max-width: 1023px) {
    .guide-head {
        padding-inline: 16px;
    }
}
@media (min-width: 1024px) {
    .guide-head {
        margin-inline: -24px;
    }
}
.guide h1 {
    margin: 0;
    color: var(--bark);
    font-family: var(--ff-display);
    font-size: clamp(22px, 3.5vw, 30px);
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -0.015em;
}
/* below the hero the guide holds to a reading measure, ranged left: 32rem
   keeps its longest lines to 80 characters, where the full 900px column ran
   them to 134. Screen only: a guide printed from the browser keeps the full
   width of the sheet. */
@media screen {
    .guide > :not(.guide-head) {
        max-width: 32rem;
    }
}
.guide .band {
    margin-top: 4px;
    color: var(--muted-soft);
    font-family: var(--ff);
    font-size: 15px;
}
.guide .band small {
    font-size: 13px;
}

.guide-part {
    margin-bottom: 48px;
}
.guide-part h2 {
    margin: 0 0 16px;
    color: var(--bark);
    font-family: var(--ff-display);
    font-size: 19px;
    font-weight: 600;
}

blockquote.passage {
    margin: 1.5rem 0;
    padding-left: 16px;
    border-left: 3px solid var(--sun);
    color: var(--bark);
    font-family: var(--ff-text);
    font-size: 15px;
    font-style: italic;
    line-height: 1.7;
}

.passage .verse-line {
    display: block;
}

/* what the educator says out loud: the talk prompt, the narration opening and
   the connection that closes a discussion */
.guide .prompt {
    font-family: var(--ff-text);
    font-size: 15px;
    line-height: 1.7;
}
.guide .opening,
.guide .closing {
    color: var(--muted);
    font-size: 14px;
    line-height: 1.7;
}

.copy-lines {
    margin: 1.5rem 0;
}

.copy-line {
    height: var(--rule-h, 2rem);
    border-bottom: 1px solid var(--border);
}

.guide-tools {
    display: flex;
    gap: 1rem;
    font-family: var(--ff);
    font-size: 0.85rem;
}
/* in a guide's hero the tools are the page's actions, so they take the
   catalog's secondary-action face (leaf on leaf-pale, as Search and the
   pager); the drill page's own .guide-tools keeps the plain row above */
.guide-head .guide-tools {
    flex-wrap: wrap;
    gap: 8px;
    margin: 20px 0 0;
    font-size: 14px;
}
.guide-head .guide-tools a {
    display: inline-flex;
    align-items: center;
    min-height: 40px;
    padding: 0 16px;
    border-radius: 10px;
    background: var(--leaf-pale);
    color: var(--leaf);
    font-weight: 600;
    text-decoration: none;
    transition: background-color 150ms ease, color 150ms ease;
}
.guide-head .guide-tools a:hover {
    background: var(--leaf);
    color: var(--paper);
}
@media (pointer: coarse) {
    .guide-head .guide-tools a {
        min-height: 44px;
    }
}

/* an educator note is the gold info box: the reader's eye may skip it, and the
   tint is what makes that possible without a rule dividing the page */
.educator-note {
    margin-top: 12px;
    margin-bottom: 16px;
    padding: 16px;
    border-left: 3px solid var(--sun);
    border-radius: 8px;
    background: var(--sun-pale);
    font-size: 14px;
    color: var(--muted);
}

/* the stance a page takes before it starts (the companion's coaching, the
   adapt form's privacy), set as one quiet italic line in the reading face */
.guide .framing {
    margin: 0 0 32px;
    color: var(--muted);
    font-family: var(--ff-text);
    font-size: 15px;
    font-style: italic;
    line-height: 1.7;
}
.companion .strong-answer {
    margin: 12px 0 4px;
}
/* each companion question heads its own block: the prompt in the page's ink,
   its coaching in the muted voice under it, and a hairline between blocks */
.companion ol.questions > li {
    margin-bottom: 1.5rem;
    color: var(--bark);
}
.companion ol.questions > li + li {
    padding-top: 24px;
    border-top: 1px solid var(--border-light);
}
.companion .strong-answer,
.companion ul.coaching-list {
    color: var(--muted);
}
.companion p.label {
    margin: 12px 0 0;
}

ul.coaching-list {
    margin: 0.25rem 0 0;
    padding-left: 1.25rem;
}

.guide .label {
    display: block;
    font-family: var(--ff);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--sun);
}
/* the note's own label runs inline with the sentence it opens, so it states
   what the shared .guide .label above it would otherwise impose */
.educator-note .label {
    display: inline;
    margin-right: 0.35rem;
    color: var(--sun);
    font-family: var(--ff);
    font-size: 14px;
    font-weight: 600;
    letter-spacing: normal;
    text-transform: none;
}

ol.questions {
    padding-left: 20px;
    color: var(--muted);
    font-family: var(--ff);
    font-size: 14px;
    line-height: 1.7;
}
ol.questions li {
    margin-bottom: 8px;
}

.questions .tag,
.adapt-form .tag {
    padding: 4px 12px;
    border-radius: 100px;
    background: var(--leaf-pale);
    color: var(--leaf);
    font-family: var(--ff);
    font-size: 12px;
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
}

/* a vocabulary entry reads in the book's face, the way its printed sheet sets
   it: the word, then the sentence it came from at the passage's measure, and
   a full line of air before the next word */
dl.vocabulary dt {
    color: var(--bark);
    font-family: var(--ff-text);
    font-weight: bold;
}
dl.vocabulary dd {
    margin: 2px 0 24px;
}

.vocabulary .context {
    display: block;
    font-family: var(--ff-text);
    font-size: 15px;
    font-style: italic;
    line-height: 1.7;
    color: var(--muted);
}
.vocabulary .definition {
    color: var(--muted);
    font-size: 14px;
    line-height: 1.7;
}

.adapted-note {
    margin-bottom: 16px;
    padding: 16px;
    border-radius: 8px;
    background: var(--leaf-pale);
    font-size: 14px;
}
/* the note belongs to the page, not to the first section: that section keeps
   the distance it had from the hero */
.adapted-note + .guide-part {
    margin-top: 32px;
}

/* Save to My Library: a toggle in the shape of the drill sheet's actions,
   its ribbon mark filling in once the thing is kept */
.library-save { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin: 14px 0 0; font-family: var(--ff); font-size: 14px; }
.library-save-button {
    display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 16px 0 12px;
    border: 1px solid var(--leaf); border-radius: 1.1rem; background: var(--field); color: var(--leaf);
    font: inherit; font-weight: 600; cursor: pointer;
    transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
}
.library-save-button:hover { background: var(--leaf-pale); }
.library-save-button:focus-visible { outline: 2px solid var(--sun); outline-offset: 2px; }
.library-save-mark { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linejoin: round; }
.library-save-button > span { line-height: 1.2; }
.library-save-button[aria-pressed="true"] { background: var(--leaf); color: var(--paper); }
.library-save-button[aria-pressed="true"] .library-save-mark { fill: var(--gold-light); stroke: var(--gold-light); }
.library-save-status { color: var(--muted); }
.library-save-error { color: var(--red); }
.htmx-request .library-save-button { opacity: 0.7; }

.form-errors {
    padding: 0.5rem 0.75rem 0.5rem 2rem;
    border-left: 3px solid var(--red);
    background: var(--red-pale);
    font-size: 0.9rem;
}

/* the adapt page: a back link, a title, and one form in the guide's four
   parts, each field labelled the way the catalog labels its search */
.adapt .work-link {
    margin: 0 0 12px;
    font-size: 14px;
}
.adapt .form-errors {
    margin: 0 0 32px;
    font-size: 14px;
}
.adapt-form label {
    display: block;
    margin: 0 0 20px;
    font-family: var(--ff);
    font-size: 14px;
    font-weight: 600;
    color: var(--muted);
}
.adapt-form textarea {
    display: block;
    width: 100%;
    margin-top: 6px;
    padding: 10px 12px;
    border: 1px solid var(--border-light);
    border-radius: 4px;
    background: var(--field);
    font-family: var(--ff-text);
    font-size: 1rem;
    font-weight: 400;
    line-height: 1.5;
    color: var(--bark);
    min-height: 4rem;
    resize: vertical;
    transition: border-color 150ms ease, box-shadow 150ms ease;
}
.adapt-form textarea:hover {
    border-color: var(--muted-soft);
}
.adapt-form textarea:focus {
    border-color: var(--leaf);
    box-shadow: 0 0 0 3px var(--leaf-pale);
    outline: none;
}

.adapt-form button,
.adapt-remove button {
    min-height: 44px;
    padding: 10px 20px;
    border: 1px solid var(--leaf);
    border-radius: 1rem;
    background: var(--leaf);
    color: var(--paper);
    font-family: var(--ff);
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
}
.adapt-form button:hover,
.adapt-form button:focus-visible {
    border-color: var(--leaf-light);
    background: var(--leaf-light);
}
.adapt-form button:focus-visible,
.adapt-remove button:focus-visible {
    outline: 2px solid var(--sun);
    outline-offset: 2px;
}
.adapt-remove {
    margin-top: 1.5rem;
}
.adapt-remove button {
    background: none;
    color: var(--leaf);
}
.adapt-remove button:hover {
    border-color: var(--leaf-light);
    background: var(--leaf-pale);
    color: var(--leaf-light);
}

/* The reading pages, alive: the guide, its Teaching Companion and the adapt
   form (article.guide.reading). Each opens on the book's cover, its title
   stamped in a ruled panel, and is read on leaves of paper laid over a
   reading table. The table's light moves through a day as the reader goes
   down: cool morning light round the copywork, warm afternoon round the
   discussion, an oxblood dusk round the lexicon, and lamplight at the foot,
   where the critical-thinking question is set on the table itself and the
   page ends at night. Each leaf is its own paper: a fresh sheet, warm
   parchment, an older cream lexicon.

   Everything below is screen-only, so a guide printed from the browser
   keeps the plain page. Everything that moves or waits to arrive sits under
   prefers-reduced-motion: no-preference behind html.reading-live, a flag
   ReadingMotion.razor sets before the article is parsed, only when motion is
   welcome, and withdraws if /js/reading.js has not taken over within three
   seconds. The scroll-scrubbed layer (pages turning, the cover receding,
   the ribbon) is CSS scroll-driven animation on transform and opacity, so it
   runs on the compositor; a browser without it keeps the leaves flat. This
   section ends at the matching end note. */
.reading-index,
.reading-ribbon {
    display: none;
}

@media screen {
    .app-main:has(> .guide.reading) {
        max-width: none;
        padding: 0;
    }
    /* the page ends at night, so its foot and the strip past it do too */
    .app-main:has(> .guide.reading) + .app-footer {
        border-top-color: var(--rule-dark);
        background-color: var(--forest);
        color: var(--sand);
    }
    html.at-end body:where(:has(> .app-main > .guide.reading)) {
        background-color: var(--forest);
    }

    .guide.reading {
        --ease-set: cubic-bezier(0.22, 1, 0.36, 1);
        --leaf-width: 920px;
        /* the table shows past each leaf's edge: a sliver on a phone, the
           whole margin once the window is wider than a leaf */
        --table-edge: max(clamp(6px, 2vw, 32px), calc((100% - var(--leaf-width)) / 2));
        --leaf-pad: clamp(20px, 5.2vw, 72px);
        --gilt: rgba(229, 197, 126, 0.55);
        /* the kicker gold darkened toward the ink, so small labels on every
           leaf, the cream lexicon's included, clear 4.5:1 where the plain
           --sun does not */
        --gilt-ink: color-mix(in srgb, var(--sun) 60%, var(--bark));
        position: relative;
        overflow-x: clip;
        color: var(--bark);
        /* the day on the table, from the dark of the cover through the
           lighter moss at midday back to night at the foot. The light of
           each hour is cast by the leaves themselves (--hour, below): a
           full-height pool of light here costs the compositor every frame */
        background: linear-gradient(180deg, var(--forest) 0%, var(--spruce) 16%,
            color-mix(in srgb, var(--moss) 80%, var(--spruce)) 42%,
            var(--spruce) 64%, var(--forest) 84%);
    }
    .guide.reading > * {
        max-width: none;
    }

    /* the cover: the site's forest, lit from above the way the homepage and
       the entry pages are, with the title stamped inside a ruled panel */
    .guide.reading .frontispiece {
        display: flex;
        flex-direction: column;
        min-height: clamp(440px, 74svh, 780px);
        margin: 0;
        padding: 20px var(--leaf-pad) clamp(44px, 8vh, 88px);
        overflow: hidden;
        background: radial-gradient(135% 120% at 50% 26%, var(--moss) 0%, var(--spruce) 46%, var(--forest) 100%);
        color: var(--chrome-text);
    }
    .guide.reading.adapt .frontispiece {
        min-height: 0;
    }
    .guide.reading .frontispiece .breadcrumbs,
    .guide.reading .frontispiece .work-link {
        margin: 0 0 clamp(20px, 5vh, 48px);
        color: var(--chrome-text);
        font-size: 14px;
    }
    .guide.reading .frontispiece .breadcrumbs a,
    .guide.reading .frontispiece .work-link a,
    .guide.reading .frontispiece .breadcrumbs a::after {
        color: var(--sand);
    }
    .guide.reading .frontispiece .breadcrumbs a:hover,
    .guide.reading .frontispiece .work-link a:hover {
        color: var(--gold-warm);
    }
    .guide.reading .frontispiece .breadcrumbs .current {
        color: var(--chrome-text);
    }
    .guide.reading .frontispiece a:focus-visible,
    .guide.reading .reading-index a:focus-visible {
        outline-color: var(--gold-warm);
    }

    .guide.reading .frontis {
        position: relative;
        width: 100%;
        max-width: 780px;
        margin: auto;
        padding: clamp(40px, 7vw, 76px) clamp(20px, 6vw, 72px) clamp(36px, 6vw, 64px);
        text-align: center;
    }
    /* the panel's double fillet, the horizontals and the verticals apart so
       each pair can be ruled on its own */
    .guide.reading .frontis::before,
    .guide.reading .frontis::after {
        content: "";
        position: absolute;
        inset: 0;
        pointer-events: none;
    }
    .guide.reading .frontis::before {
        border-top: 3px double var(--gilt);
        border-bottom: 3px double var(--gilt);
    }
    .guide.reading .frontis::after {
        inset: -1px 0;
        border-left: 3px double var(--gilt);
        border-right: 3px double var(--gilt);
    }
    .guide.reading .frontis-work {
        margin: 0;
        color: var(--gold-warm);
        font-family: var(--ff-text);
        font-size: clamp(20px, 2vw, 24px);
        font-style: italic;
        line-height: 1.3;
    }
    .guide.reading .frontis-rule {
        display: block;
        position: relative;
        width: clamp(140px, 38%, 300px);
        height: 1px;
        margin: 18px auto 20px;
        background: linear-gradient(90deg, transparent, var(--gold) 18%, var(--gold-light) 50%, var(--gold) 82%, transparent);
    }
    .guide.reading .frontis-rule::before {
        content: "";
        position: absolute;
        top: 50%;
        left: 50%;
        width: 7px;
        height: 7px;
        background: var(--gold-light);
        translate: -50% -50%;
        rotate: 45deg;
    }
    /* the gilt catches the light once, when the cover is first opened */
    .guide.reading .frontis-rule::after {
        content: "";
        position: absolute;
        inset: -2px 0;
        background: linear-gradient(90deg, transparent, rgba(255, 246, 214, 0.95), transparent) no-repeat;
        background-size: 28% 100%;
        background-position: -40% 0;
        opacity: 0;
    }
    .guide.reading .frontis h1 {
        margin: 0;
        color: var(--chrome-text);
        font-family: var(--ff-display);
        font-size: clamp(54px, 8.4vw, 112px);
        font-weight: 400;
        letter-spacing: -0.02em;
        line-height: 1;
        text-wrap: balance;
    }
    .guide.reading.companion .frontis h1 {
        font-size: clamp(40px, 5.6vw, 76px);
        line-height: 1.04;
    }
    .guide.reading.adapt .frontis h1 {
        font-size: clamp(40px, 4.8vw, 64px);
        line-height: 1.06;
    }
    .guide.reading .frontis .band {
        margin: 18px 0 0;
        color: var(--sand);
        font-size: 14px;
    }
    .guide.reading .frontis .band small {
        font-size: 12px;
    }
    .guide.reading .frontis .framing {
        max-width: 34em;
        margin: 18px auto 0;
        color: var(--sand);
        font-size: 17px;
    }
    .guide.reading .frontis .guide-tools {
        justify-content: center;
        gap: 10px;
        margin: 30px 0 0;
    }
    .guide.reading .frontis .guide-tools a {
        min-height: 44px;
        padding: 0 18px;
        border: 1px solid rgba(244, 234, 215, 0.3);
        background: transparent;
        color: var(--chrome-text);
    }
    .guide.reading .frontis .guide-tools a:hover {
        border-color: var(--gold);
        background: rgba(229, 197, 126, 0.08);
        color: var(--gold-warm);
    }
    /* a reader's own version is marked the way a book is: a plate inside
       the cover */
    .guide.reading .frontis .adapted-note {
        display: inline-block;
        max-width: 32em;
        margin: 26px auto 0;
        padding: 12px 18px;
        border: 1px solid var(--gilt);
        border-radius: 2px;
        background: rgba(10, 24, 16, 0.45);
        color: var(--sand);
        font-size: 14px;
    }
    .guide.reading .frontis .adapted-note a {
        color: var(--gold-warm);
    }

    /* the index of parts, in the table's left margin once there is one */
    .guide.reading .reading-index a {
        display: grid;
        grid-template-columns: 30px 1fr;
        align-items: baseline;
        position: relative;
        min-height: 44px;
        padding: 10px 0 10px 16px;
        color: var(--sand);
        font-family: var(--ff);
        font-size: 14px;
        line-height: 1.35;
        text-decoration: none;
        transition: color 200ms ease;
    }
    .guide.reading .reading-index a span {
        color: var(--gold);
        font-family: var(--ff-display);
        font-size: 17px;
    }
    .guide.reading .reading-index a:hover,
    .guide.reading .reading-index a[aria-current] {
        color: var(--chrome-text);
    }
    /* the drawer's own current marker: a gold bar at the item's edge */
    .guide.reading .reading-index a[aria-current]::before {
        content: "";
        position: absolute;
        top: 11px;
        bottom: 11px;
        left: 0;
        width: 2px;
        background: var(--gold);
    }

    /* the leaves. Each casts the light of its hour onto the table around it:
       pale morning round the copywork, afternoon gold round the discussion,
       a dusk of oxblood round the lexicon */
    .guide.reading .guide-part {
        position: relative;
        isolation: isolate;
        margin: 0 var(--table-edge) clamp(28px, 4.4vw, 56px);
        padding: clamp(40px, 7vw, 92px) var(--leaf-pad) clamp(44px, 7vw, 96px);
        overflow: hidden;
        border-radius: 2px;
        background: var(--paper);
        box-shadow:
            inset 0 0 0 1px rgba(255, 253, 247, 0.4),
            inset 0 0 90px rgba(156, 122, 51, 0.1),
            0 1px 2px rgba(6, 14, 9, 0.3),
            0 26px 50px -22px rgba(6, 14, 9, 0.7),
            0 0 72px -4px var(--hour, transparent);
        scroll-margin-top: 88px;
    }
    .guide.reading .guide-part.copywork,
    .guide.reading .guide-part.shape {
        --hour: rgba(231, 237, 226, 0.26);
        background: linear-gradient(180deg, var(--parchment-top), var(--card));
    }
    .guide.reading .guide-part.discussion,
    .guide.reading .guide-part.way-in {
        --hour: rgba(229, 197, 126, 0.34);
        background: linear-gradient(180deg, var(--parchment-bottom), var(--sun-pale));
    }
    .guide.reading .guide-part.vocabulary {
        --hour: rgba(156, 43, 49, 0.3);
        background: linear-gradient(180deg, color-mix(in srgb, var(--cream) 62%, var(--parchment-top)), var(--cream));
    }

    .guide.reading .guide-part > h2 {
        margin: 0 0 22px;
        color: var(--bark);
        font-family: var(--ff-display);
        font-size: clamp(40px, 4.4vw, 54px);
        font-weight: 400;
        letter-spacing: -0.015em;
        line-height: 1.04;
    }
    .guide.reading .guide-part > h2::after {
        content: "";
        display: block;
        width: 64px;
        height: 1px;
        margin-top: 18px;
        background: var(--sun);
        transform-origin: left;
    }

    /* each part's numeral, blind-stamped under the leaf's type: on the
       leaf's corner, and in the table's right margin once the margin can
       hold it */
    .guide.reading .part-mark {
        position: absolute;
        top: clamp(14px, 3vw, 36px);
        right: clamp(14px, 3vw, 44px);
        z-index: -1;
        color: transparent;
        font-family: var(--ff-display);
        font-size: clamp(84px, 15vw, 170px);
        line-height: 0.8;
        pointer-events: none;
        user-select: none;
        -webkit-text-stroke: 1px rgba(156, 122, 51, 0.3);
    }

    .guide.reading .label,
    .guide.reading .educator-note .label {
        color: var(--gilt-ink);
    }
    .guide.reading .educator-note {
        max-width: 34rem;
        border: 1px solid rgba(156, 122, 51, 0.32);
        border-radius: 2px;
        background: var(--sun-pale);
        color: var(--muted);
        font-size: 14px;
    }

    /* Copywork: the passage as the specimen, the ruled sheet under it with a
       margin line, the way a copybook is ruled */
    .guide.reading .copy-sheet + .copy-sheet {
        margin-top: 44px;
    }
    .guide.reading blockquote.passage {
        max-width: 34em;
        margin: 8px 0 0;
        padding: 0;
        border: 0;
        color: var(--bark);
        font-size: clamp(20px, 2vw, 24px);
        line-height: 1.6;
    }
    .guide.reading .copy-lines {
        position: relative;
        max-width: 42rem;
        margin: 22px 0 30px;
    }
    .guide.reading .copy-lines::before {
        content: "";
        position: absolute;
        top: 0;
        bottom: 0;
        left: 2.25rem;
        width: 1px;
        background: rgba(156, 43, 49, 0.4);
        transform-origin: top;
    }
    .guide.reading .copy-line {
        --n: 0;
        border-bottom-color: color-mix(in srgb, var(--leaf) 26%, var(--border));
        transform-origin: left;
    }
    .guide.reading .guide-part > .prompt,
    .guide.reading .guide-part > p,
    .guide.reading .discussion .opening,
    .guide.reading .discussion .closing {
        max-width: 36rem;
        color: var(--bark);
        font-family: var(--ff-text);
        font-size: 17px;
        line-height: 1.7;
    }

    /* Discussion: the questions are the heart of the guide, so they take the
       reading face at the leaf's larger size, each numbered in the margin
       and ruled off from the next by a hairline */
    .guide.reading ol.questions {
        max-width: 40rem;
        margin: 30px 0;
        padding: 0;
        color: var(--bark);
        font-family: var(--ff-text);
        font-size: clamp(17px, 1.55vw, 20px);
        line-height: 1.6;
        list-style: none;
        counter-reset: question;
    }
    .guide.reading ol.questions > li,
    .guide.reading ol.questions > li + li {
        position: relative;
        margin: 0;
        padding: 22px 0 24px clamp(46px, 6vw, 66px);
        border-top: 0;
        counter-increment: question;
    }
    .guide.reading ol.questions > li::before {
        content: counter(question);
        position: absolute;
        top: 16px;
        left: 0;
        color: var(--sun);
        font-family: var(--ff-display);
        font-size: clamp(30px, 3.6vw, 40px);
        line-height: 1;
    }
    .guide.reading ol.questions > li::after,
    .guide.reading dl.vocabulary .entry::before {
        content: "";
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        height: 1px;
        background: rgba(156, 122, 51, 0.28);
        transform-origin: left;
    }
    .guide.reading ol.questions .tag {
        margin-left: 4px;
        vertical-align: 0.15em;
    }
    .guide.reading ol.questions li p:not(.label),
    .guide.reading ol.questions li ul {
        color: var(--muted);
        font-family: var(--ff);
        font-size: 14px;
        line-height: 1.65;
    }

    /* Vocabulary: a page of the lexicon, two columns under a gutter rule */
    .guide.reading dl.vocabulary {
        position: relative;
        display: grid;
        gap: 0 clamp(36px, 5vw, 72px);
        margin: 30px 0 0;
    }
    .guide.reading dl.vocabulary .entry {
        position: relative;
        padding: 20px 0 22px;
    }
    .guide.reading dl.vocabulary dt {
        color: var(--bark);
        font-family: var(--ff-display);
        font-size: clamp(24px, 2.4vw, 30px);
        font-weight: 400;
        line-height: 1.1;
    }
    .guide.reading dl.vocabulary dt::first-letter {
        color: var(--sun);
    }
    .guide.reading dl.vocabulary dd {
        margin: 10px 0 0;
    }
    .guide.reading .vocabulary .context {
        color: var(--bark-soft);
        font-size: 17px;
    }
    .guide.reading .vocabulary .definition {
        display: block;
        margin-top: 8px;
        color: var(--muted);
        font-size: 14px;
    }

    /* Critical thinking: no leaf. The question is set on the table itself,
       under the lamp, the last thing the reader carries away. Only the
       guide's own section (the article's child): the adapt form's fourth
       part is a field to fill, so it stays on its leaf. */
    .guide.reading > .guide-part.critical-thinking {
        margin: 0;
        padding: clamp(96px, 16vh, 180px) var(--leaf-pad) clamp(48px, 8vh, 96px);
        overflow: visible;
        background: none;
        box-shadow: none;
        color: var(--chrome-text);
        text-align: center;
    }
    .guide.reading > .critical-thinking .lamp {
        position: absolute;
        top: 46%;
        left: 50%;
        width: min(980px, 150vw);
        aspect-ratio: 1;
        background: radial-gradient(closest-side, rgba(229, 197, 126, 0.24), rgba(229, 197, 126, 0.07) 52%, transparent);
        translate: -50% -50%;
        pointer-events: none;
    }
    .guide.reading > .critical-thinking .part-mark {
        position: relative;
        top: auto;
        right: auto;
        display: block;
        margin-bottom: 10px;
        font-size: clamp(72px, 9vw, 120px);
        -webkit-text-stroke-color: var(--gilt);
    }
    .guide.reading > .critical-thinking > h2 {
        position: relative;
        color: var(--gold-light);
    }
    .guide.reading > .critical-thinking > h2::after {
        width: 96px;
        margin-inline: auto;
        background: linear-gradient(90deg, var(--gold) 40%, var(--parchment-top) 50%, var(--gold) 60%) 100% 0 / 300% 100%;
        transform-origin: center;
    }
    .guide.reading > .critical-thinking > .prompt {
        position: relative;
        max-width: 25em;
        margin: 36px auto 0;
        color: var(--chrome-text);
        font-size: clamp(24px, 2.5vw, 30px);
        line-height: 1.45;
        text-wrap: pretty;
    }
    .guide.reading > .critical-thinking .educator-note {
        position: relative;
        margin: 36px auto 0;
        text-align: left;
    }

    /* the colophon: the edition, on the table under the lamp */
    .guide.reading > footer.edition {
        margin: 0;
        padding: 36px var(--leaf-pad) clamp(56px, 9vh, 96px);
        border: 0;
        color: var(--sand);
        font-family: var(--ff-text);
        font-size: 14px;
        font-style: italic;
        text-align: center;
    }
    .guide.reading > footer.edition::before {
        content: "";
        display: block;
        width: 140px;
        height: 1px;
        margin: 0 auto 22px;
        background: linear-gradient(90deg, transparent, var(--gold), transparent);
    }

    /* the adapt form keeps its fields still: its leaves never turn and none
       of its controls wait to arrive; its action sits on the table below */
    .guide.reading.adapt {
        padding-bottom: clamp(56px, 9vh, 96px);
    }
    .guide.reading.adapt > .form-errors {
        margin: 0 var(--table-edge) 24px;
        padding: 16px 20px 16px 40px;
        border: 1px solid var(--red);
        border-radius: 2px;
        background: var(--red-pale);
        color: var(--red);
    }
    .guide.reading .adapt-form label {
        max-width: 40rem;
    }
    .guide.reading .adapt-form > button {
        display: block;
        min-height: 50px;
        margin: 8px auto 0;
        padding: 0 30px;
        border: 0;
        border-radius: 6px;
        background: linear-gradient(180deg, var(--gold-light), var(--gold-deep));
        color: var(--ink);
        font-size: 14px;
        letter-spacing: 0.01em;
    }
    .guide.reading .adapt-form > button:hover,
    .guide.reading .adapt-form > button:focus-visible {
        background: linear-gradient(180deg, var(--gold-warm), var(--gold));
    }
    .guide.reading .adapt-form > button:focus-visible,
    .guide.reading .adapt-remove button:focus-visible {
        outline-color: var(--gold-warm);
        outline-offset: 3px;
    }
    .guide.reading .adapt-remove {
        margin: 18px var(--table-edge) 0;
        text-align: center;
    }
    .guide.reading .adapt-remove button {
        border-color: rgba(244, 234, 215, 0.3);
        border-radius: 6px;
        background: transparent;
        color: var(--chrome-text);
    }
    .guide.reading .adapt-remove button:hover {
        border-color: var(--gold);
        background: rgba(229, 197, 126, 0.08);
        color: var(--gold-warm);
    }

    /* the save toggle on the cover takes the cover's own tools' face, and
       holds the gilt once the guide is kept */
    .guide.reading .frontis .library-save { justify-content: center; }
    .guide.reading .frontis .library-save-button {
        border-color: rgba(244, 234, 215, 0.3); border-radius: 10px; background: transparent; color: var(--chrome-text);
    }
    .guide.reading .frontis .library-save-button:hover { border-color: var(--gold); background: rgba(229, 197, 126, 0.08); color: var(--gold-warm); }
    .guide.reading .frontis .library-save-button[aria-pressed="true"] { border-color: var(--gilt); background: rgba(10, 24, 16, 0.45); color: var(--gold-warm); }
    .guide.reading .frontis .library-save-button:focus-visible { outline-color: var(--gold-warm); }
    .guide.reading .frontis :is(.library-save-status, .library-save-error) { flex-basis: 100%; color: var(--sand); }
    .guide.reading .frontis .library-save-status a { color: var(--gold-warm); }

    /* the compare view: the reader's version beside the published one, on
       the guide's own leaves under the adapt form's shorter cover. Each row
       is one text; a changed one is set as a pair, the words taken out
       struck in oxblood and the words put in inked in leaf */
    .guide.reading.compare { padding-bottom: clamp(56px, 9vh, 96px); }
    .guide.reading.compare .frontispiece { min-height: 0; }
    .guide.reading.compare .frontis h1 { font-size: clamp(38px, 4.8vw, 64px); line-height: 1.06; }
    .guide.reading .compare-filter { margin: 0 var(--table-edge) 22px; color: var(--chrome-text); font-size: 15px; text-align: center; }
    .guide.reading .compare-filter label {
        display: inline-flex; align-items: center; gap: 10px; min-height: 44px; padding: 0 18px;
        border: 1px solid rgba(244, 234, 215, 0.3); border-radius: 10px; cursor: pointer;
    }
    .guide.reading .compare-filter label:has(:checked) { border-color: var(--gilt); color: var(--gold-warm); }
    .guide.reading .compare-filter label:has(:focus-visible) { outline: 2px solid var(--gold-warm); outline-offset: 2px; }
    .guide.reading .compare-filter input { width: 18px; height: 18px; margin: 0; accent-color: var(--gold); }
    /* the margin index lets go of the parts the filter hid, so it never
       points at a leaf that is not there */
    .guide.reading.compare:has(#compare-only-changed:checked) :is(.compare-row:not(.is-changed), .guide-part:not(:has(.is-changed)), .reading-index a.is-unchanged) {
        display: none;
    }
    .guide.reading .compare-rows { max-width: 60rem; margin: 8px 0 0; padding: 0; list-style: none; }
    .guide.reading .compare-row { padding: 22px 0 24px; }
    .guide.reading .compare-row + .compare-row { border-top: 1px solid rgba(156, 122, 51, 0.28); }
    .guide.reading .compare-place {
        margin: 0 0 10px; color: var(--bark); font-family: var(--ff-display); font-size: clamp(19px, 2vw, 23px); font-weight: 400; line-height: 1.2;
    }
    .guide.reading .compare-text { max-width: 36rem; margin: 0; color: var(--bark); font-family: var(--ff-text); font-size: 17px; line-height: 1.7; }
    .guide.reading .compare-row:not(.is-changed) .compare-text { color: var(--muted); }
    .guide.reading .compare-same { margin: 6px 0 0; color: var(--muted); font-size: 13px; }
    .guide.reading .compare-pair { display: grid; gap: 16px; }
    .guide.reading .compare-side .label { margin: 0 0 4px; }
    .guide.reading .compare-side.is-yours {
        padding: 14px 16px 16px; border-left: 3px solid var(--gold); border-radius: 2px;
        background: color-mix(in srgb, var(--parchment-top) 70%, transparent);
    }
    .guide.reading .compare-text :is(del, ins) { padding: 0 2px; border-radius: 2px; box-decoration-break: clone; -webkit-box-decoration-break: clone; }
    .guide.reading .compare-text del { background: var(--red-pale); color: var(--red); text-decoration-color: color-mix(in srgb, var(--red) 70%, transparent); }
    .guide.reading .compare-text ins { background: var(--leaf-pale); color: var(--leaf); text-decoration-color: color-mix(in srgb, var(--leaf) 45%, transparent); text-underline-offset: 4px; }
    @media (min-width: 860px) {
        .guide.reading .compare-pair { grid-template-columns: 1fr 1fr; gap: 28px; align-items: start; }
        .guide.reading .compare-side:not(.is-yours) { padding-top: 14px; }
    }

    /* set type, split by /js/reading.js while it arrives. The letters of a
       word stay inline inside the word's own box, so the word keeps its
       kerning and the letters only fade; the word, a box of its own, is what
       moves, on the compositor. The whole line rides beside the pieces for a
       screen reader until the type has settled and the plain text is put
       back. */
    .guide.reading .type-l {
        --i: 0;
    }
    .guide.reading .type-w {
        --i: 0;
        display: inline-block;
        white-space: nowrap;
    }
    .guide.reading .type-sr {
        position: absolute;
        width: 1px;
        height: 1px;
        margin: -1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }
}

@media screen and (max-width: 699px) {
    .guide.reading .frontis .guide-tools a {
        padding: 0 14px;
    }
    .guide.reading .part-mark {
        -webkit-text-stroke-color: rgba(156, 122, 51, 0.24);
    }
}

@media screen and (min-width: 860px) {
    .guide.reading dl.vocabulary {
        grid-template-columns: 1fr 1fr;
    }
    .guide.reading dl.vocabulary::before {
        content: "";
        position: absolute;
        top: 0;
        bottom: 0;
        left: 50%;
        width: 1px;
        background: rgba(156, 122, 51, 0.3);
        transform-origin: top;
    }
}

/* the ribbon: where there is no margin for the index, a bookmark ribbon
   hangs from under the header and lengthens as the reader goes down. It
   grows only with the scroll it measures, so a browser that cannot tie it to
   the scroll shows none. */
@media screen and (max-width: 1399px) {
    .guide.reading .reading-ribbon {
        display: block;
        position: fixed;
        top: 69px;
        right: clamp(6px, 2.2vw, 26px);
        z-index: 2;
        width: 11px;
        height: 56vh;
        overflow: hidden;
        pointer-events: none;
    }
    .guide.reading .reading-ribbon span {
        display: block;
        height: 100%;
        background: linear-gradient(90deg, var(--ribbon-edge), var(--ribbon-face) 45%, var(--ribbon-fold));
        clip-path: polygon(0 0, 100% 0, 100% 100%, 50% calc(100% - 8px), 0 100%);
        translate: 0 -100%;
    }
}

@media screen and (min-width: 1400px) {
    .guide.reading .reading-index {
        display: block;
        position: fixed;
        top: 50%;
        left: clamp(28px, 3vw, 56px);
        z-index: 2;
        width: calc((100vw - var(--leaf-width)) / 2 - 84px);
        translate: 0 -50%;
    }
    /* the thread the index hangs on, gilded as far as the reader has read */
    .guide.reading .reading-index::before,
    .guide.reading .reading-index::after {
        content: "";
        position: absolute;
        top: 0;
        bottom: 0;
        left: 0;
        width: 1px;
        background: rgba(199, 188, 168, 0.22);
    }
    .guide.reading .reading-index::after {
        background: var(--gold);
        transform-origin: top;
        scale: 1 0;
    }
    .guide.reading .guide-part {
        overflow: visible;
    }
    .guide.reading .guide-part .part-mark {
        top: 30px;
        right: auto;
        left: calc(100% + 34px);
        font-size: 150px;
        -webkit-text-stroke-color: var(--gilt);
    }
    .guide.reading > .critical-thinking .part-mark {
        left: auto;
        font-size: 120px;
    }
}

/* the arrivals, each triggered by the thing arriving. Only under
   html.reading-live and only on screen: print, reduced motion and a page
   without scripts never hide a word. */
@media screen and (prefers-reduced-motion: no-preference) {
    html.reading-live .guide.reading .frontis > *,
    html.reading-live .guide.reading .reading-index {
        opacity: 0;
        translate: 0 12px;
        transition: opacity 0.9s ease-out, translate 1.1s var(--ease-set);
    }
    html.reading-live .guide.reading .frontis > .frontis-rule {
        opacity: 1;
        translate: none;
        scale: 0 1;
        transition: scale 1.2s var(--ease-set) 0.25s;
    }
    html.reading-live .guide.reading .frontis > h1 {
        translate: none;
        transition-duration: 0.3s;
    }
    html.reading-live .guide.reading .frontis.is-in > *,
    html.reading-live .guide.reading .reading-index.is-in,
    html.reading-live .guide.reading .reading-index:focus-within {
        opacity: 1;
        translate: none;
        scale: 1 1;
    }
    html.reading-live .guide.reading .reading-index {
        translate: -50% -50%;
        transition-delay: 1.2s;
    }
    html.reading-live .guide.reading .reading-index.is-in,
    html.reading-live .guide.reading .reading-index:focus-within {
        translate: 0 -50%;
    }
    html.reading-live .guide.reading .frontis.is-in > .band {
        transition-delay: 0.6s;
    }
    html.reading-live .guide.reading .frontis.is-in > .framing {
        transition-delay: 0.7s;
    }
    html.reading-live .guide.reading .frontis.is-in > .guide-tools {
        transition-delay: 0.8s;
    }
    html.reading-live .guide.reading .frontis.is-in > .adapted-note {
        transition-delay: 0.9s;
    }
    html.reading-live .guide.reading .frontis::before {
        scale: 0 1;
        transition: scale 1.3s var(--ease-set) 0.1s;
    }
    html.reading-live .guide.reading .frontis::after {
        scale: 1 0;
        transition: scale 1.3s var(--ease-set) 0.4s;
    }
    html.reading-live .guide.reading .frontis.is-in::before,
    html.reading-live .guide.reading .frontis.is-in::after {
        scale: 1 1;
    }
    html.reading-live .guide.reading .frontis.is-in .frontis-rule::after {
        animation: reading-sheen 1.8s cubic-bezier(0.45, 0, 0.2, 1) 1.4s both;
    }

    /* the letters are set one after another, and each word drops into the
       line as its first letter is set */
    html.reading-live .guide.reading .type-l {
        opacity: 0;
        transition: opacity 0.45s ease-out;
        transition-delay: calc(var(--at, 80ms) + var(--i, 0) * 38ms);
    }
    html.reading-live .guide.reading .frontis h1 .type-w,
    html.reading-live .guide.reading .guide-part > h2 .type-w {
        translate: 0 -0.32em;
        transition: translate 0.9s var(--ease-set);
        transition-delay: calc(var(--at, 80ms) + var(--i, 0) * 38ms);
    }
    html.reading-live .guide.reading .frontis h1 {
        --at: 280ms;
    }
    html.reading-live .guide.reading .frontis.is-in .type-l,
    html.reading-live .guide.reading .guide-part.is-in > h2 .type-l {
        opacity: 1;
    }
    html.reading-live .guide.reading .frontis.is-in h1 .type-w,
    html.reading-live .guide.reading .guide-part.is-in > h2 .type-w {
        translate: none;
    }

    html.reading-live .guide.reading .guide-part > h2 {
        opacity: 0;
        transition: opacity 0.4s ease-out;
    }
    html.reading-live .guide.reading .guide-part > h2::after {
        scale: 0 1;
        transition: scale 1s var(--ease-set) 0.55s;
    }
    html.reading-live .guide.reading .guide-part > .part-mark {
        opacity: 0;
        scale: 0.9;
        transition: opacity 1.4s ease-out 0.15s, scale 1.8s var(--ease-set) 0.15s;
    }
    html.reading-live .guide.reading .guide-part.is-in > h2,
    html.reading-live .guide.reading .guide-part.is-in > .part-mark {
        opacity: 1;
        scale: 1;
    }
    html.reading-live .guide.reading .guide-part.is-in > h2::after {
        scale: 1 1;
    }

    /* the passage is inked across the sheet, then the sheet is ruled line
       by line, and its margin drawn down */
    html.reading-live .guide.reading .copy-sheet blockquote.passage {
        clip-path: inset(-0.3em 100% -0.3em -0.6em);
        transition: clip-path 1.5s cubic-bezier(0.55, 0.1, 0.25, 1) 0.15s;
    }
    html.reading-live .guide.reading .copy-sheet .copy-line {
        scale: 0 1;
        transition: scale 0.9s var(--ease-set);
        transition-delay: calc(0.8s + var(--n, 0) * 90ms);
    }
    html.reading-live .guide.reading .copy-sheet .copy-lines::before {
        scale: 1 0;
        transition: scale 1.1s var(--ease-set) 0.7s;
    }
    html.reading-live .guide.reading .copy-sheet.is-in blockquote.passage {
        clip-path: inset(-0.3em -0.6em -0.3em -0.6em);
    }
    html.reading-live .guide.reading .copy-sheet.is-in .copy-line,
    html.reading-live .guide.reading .copy-sheet.is-in .copy-lines::before {
        scale: 1 1;
    }

    /* each question is ruled off, then its numeral is pressed into the
       margin; each lexicon entry is ruled off the same way. The words
       themselves never wait: text is readable at every scroll position, and
       only thin rules and numerals move */
    html.reading-live .guide.reading ol.questions > li::after,
    html.reading-live .guide.reading dl.vocabulary .entry::before {
        scale: 0 1;
        transition: scale 0.9s var(--ease-set);
    }
    html.reading-live .guide.reading ol.questions > li::before {
        opacity: 0;
        scale: 1.4;
        transition: opacity 0.4s ease-out 0.2s, scale 0.9s var(--ease-set) 0.2s;
    }
    html.reading-live .guide.reading dl.vocabulary .entry:nth-child(even)::before {
        transition-delay: 0.15s;
    }
    html.reading-live .guide.reading dl.vocabulary::before {
        scale: 1 0;
        transition: scale 2.6s var(--ease-set) 0.3s;
    }
    html.reading-live .guide.reading ol.questions > li.is-in::after,
    html.reading-live .guide.reading dl.vocabulary .entry.is-in::before {
        scale: 1 1;
    }
    html.reading-live .guide.reading ol.questions > li.is-in::before {
        opacity: 1;
        scale: 1;
    }
    html.reading-live .guide.reading .guide-part.is-in dl.vocabulary::before {
        scale: 1 1;
    }

    /* whatever the reader has already passed arrives still: a fling to the
       foot, or a link to a part, never leaves a trail of motion running
       above the screen */
    html.reading-live .guide.reading .is-still,
    html.reading-live .guide.reading .is-still *,
    html.reading-live .guide.reading .is-still::before,
    html.reading-live .guide.reading .is-still::after,
    html.reading-live .guide.reading .is-still *::before,
    html.reading-live .guide.reading .is-still *::after {
        transition-duration: 0s !important;
        transition-delay: 0s !important;
    }

    /* at dusk the question is set word by word, and its rule catches the
       lamp once */
    html.reading-live .guide.reading > .critical-thinking > .prompt .type-w {
        opacity: 0;
        translate: 0 0.35em;
        transition: opacity 0.6s ease-out, translate 0.8s var(--ease-set);
        transition-delay: calc(0.35s + var(--i, 0) * 40ms);
    }
    html.reading-live .guide.reading > .critical-thinking.is-in > .prompt .type-w {
        opacity: 1;
        translate: none;
    }
    html.reading-live .guide.reading > .critical-thinking.is-in > h2::after {
        animation: reading-gild 1.6s cubic-bezier(0.45, 0, 0.2, 1) 1.5s both;
    }
}

/* The scroll turns the pages. Each leaf of the guide and the companion
   swings in about its spine as it rises from the foot of the screen, shaded
   on the spine side, and settles flat once three-fifths of it has come up
   (a tall leaf is within 3 degrees of flat by mid-screen; after-motion.json
   has the angles); the cover eases back as the reader leaves it; the ribbon
   and the index's thread follow the scroll. Transform and opacity only. */
@supports (animation-timeline: view()) {
    @media screen and (prefers-reduced-motion: no-preference) {
        html.reading-live .guide.reading:not(.adapt) > .guide-part:not(.critical-thinking) {
            view-timeline: --leaf block, --arrive block;
            transform-origin: 0 50%;
            animation: reading-turn linear both;
            animation-timeline: --leaf;
            animation-range: entry 0% entry 60%;
        }
        html.reading-live .guide.reading:not(.adapt) > .guide-part:not(.critical-thinking)::after {
            content: "";
            position: absolute;
            inset: 0;
            border-radius: inherit;
            background: linear-gradient(90deg, rgba(10, 24, 16, 0.22), rgba(10, 24, 16, 0.05) 55%, transparent);
            pointer-events: none;
            animation: reading-shade linear both;
            animation-timeline: --leaf;
            animation-range: entry 0% entry 60%;
        }
        html.reading-live .guide.reading .frontis {
            animation: reading-recede linear both;
            animation-timeline: view();
            animation-range: exit 0% exit 100%;
        }
        html.reading-live .guide.reading .reading-ribbon span,
        html.reading-live .guide.reading .reading-index::after {
            animation: reading-follow linear both;
            animation-timeline: scroll(root);
        }
        html.reading-live .guide.reading .reading-index::after {
            animation-name: reading-thread;
        }
    }
    /* in the wide margin the numerals drift slower than their leaves, so
       the table has a depth of its own */
    @media screen and (min-width: 1400px) and (prefers-reduced-motion: no-preference) {
        html.reading-live .guide.reading:not(.adapt) > .guide-part:not(.critical-thinking) > .part-mark {
            animation: reading-drift linear both;
            animation-timeline: --leaf;
            animation-range: cover 0% cover 100%;
        }
    }
    /* A fling stands still. While /js/reading.js holds the is-flung flag up
       — the reader is flinging the page — every part-level arrival that has
       not played is brought to its end state by its own view timeline, in
       the band where the observer would have fired it (the thing's top
       crossing 8vh above the foot), so the reveal is a step rather than a
       motion. No class is written while the fling runs: nothing is left
       pending for the next scroll event to flush, which is how the plain
       page under this one scrolls. This is the still path only. The play
       path — a slow scroll, a link jump — is the class change above,
       untouched, its timings the page's own; the observer marks .is-in
       before a thing reaches this band and these rules step aside. The
       cover (it plays at load) and the lamp (at the end) are never here:
       their set-type is time-based and stays a class change. What is here
       is exactly the set /js/reading.js defers: the parts' headings with
       their set type, the hairlines, the numerals, the copybook and the
       lexicon. */
    @media screen and (prefers-reduced-motion: no-preference) {
        /* the thing each arrival reads its position from: the thing itself,
           so a heading and its rule cross the same line together */
        html.reading-live .guide.reading .copy-sheet,
        html.reading-live .guide.reading ol.questions > li,
        html.reading-live .guide.reading dl.vocabulary .entry,
        html.reading-live .guide.reading.adapt .guide-part {
            view-timeline: --arrive block;
        }
        html.reading-live .guide.reading.is-flung > .guide-part:not(.critical-thinking):not(.is-in) > h2,
        html.reading-live .guide.reading.is-flung .adapt-form .guide-part:not(.is-in) > h2,
        html.reading-live .guide.reading.is-flung > .guide-part:not(.critical-thinking):not(.is-in) > h2 .type-l,
        html.reading-live .guide.reading.is-flung .adapt-form .guide-part:not(.is-in) > h2 .type-l {
            animation: reading-arrive-fade linear both;
            animation-timeline: --arrive;
            animation-range: entry 8vh entry 10vh;
        }
        html.reading-live .guide.reading.is-flung > .guide-part:not(.critical-thinking):not(.is-in) > h2 .type-w,
        html.reading-live .guide.reading.is-flung .adapt-form .guide-part:not(.is-in) > h2 .type-w {
            animation: reading-arrive-word linear both;
            animation-timeline: --arrive;
            animation-range: entry 8vh entry 10vh;
        }
        html.reading-live .guide.reading.is-flung > .guide-part:not(.critical-thinking):not(.is-in) > h2::after,
        html.reading-live .guide.reading.is-flung .adapt-form .guide-part:not(.is-in) > h2::after {
            animation: reading-arrive-rule linear both;
            animation-timeline: --arrive;
            animation-range: entry 8vh entry 10vh;
        }
        html.reading-live .guide.reading.is-flung > .guide-part:not(.critical-thinking):not(.is-in) > .part-mark,
        html.reading-live .guide.reading.is-flung .adapt-form .guide-part:not(.is-in) > .part-mark {
            animation: reading-arrive-stamp linear both;
            animation-timeline: --arrive;
            animation-range: entry 8vh entry 10vh;
        }
        html.reading-live .guide.reading.is-flung ol.questions > li:not(.is-in)::after {
            animation: reading-arrive-rule linear both;
            animation-timeline: --arrive;
            animation-range: entry 8vh entry 10vh;
        }
        html.reading-live .guide.reading.is-flung ol.questions > li:not(.is-in)::before {
            animation: reading-arrive-press linear both;
            animation-timeline: --arrive;
            animation-range: entry 8vh entry 10vh;
        }
        html.reading-live .guide.reading.is-flung dl.vocabulary .entry:not(.is-in)::before {
            animation: reading-arrive-rule linear both;
            animation-timeline: --arrive;
            animation-range: entry 8vh entry 10vh;
        }
        html.reading-live .guide.reading.is-flung > .guide-part:not(.critical-thinking):not(.is-in) dl.vocabulary::before,
        html.reading-live .guide.reading.is-flung .adapt-form .guide-part:not(.is-in) dl.vocabulary::before {
            animation: reading-arrive-drop linear both;
            animation-timeline: --arrive;
            animation-range: entry 8vh entry 10vh;
        }
        html.reading-live .guide.reading.is-flung .copy-sheet:not(.is-in) blockquote.passage {
            animation: reading-arrive-ink linear both;
            animation-timeline: --arrive;
            animation-range: entry 8vh entry 10vh;
        }
        html.reading-live .guide.reading.is-flung .copy-sheet:not(.is-in) .copy-line {
            animation: reading-arrive-rule linear both;
            animation-timeline: --arrive;
            animation-range: entry 8vh entry 10vh;
        }
        html.reading-live .guide.reading.is-flung .copy-sheet:not(.is-in) .copy-lines::before {
            animation: reading-arrive-drop linear both;
            animation-timeline: --arrive;
            animation-range: entry 8vh entry 10vh;
        }
    }
    /* the margin numerals keep their drift and take the stamp beside it */
    @media screen and (min-width: 1400px) and (prefers-reduced-motion: no-preference) {
        html.reading-live .guide.reading.is-flung:not(.adapt) > .guide-part:not(.critical-thinking):not(.is-in) > .part-mark {
            animation: reading-drift linear both, reading-arrive-stamp linear both;
            animation-timeline: --leaf, --arrive;
            animation-range: cover 0% cover 100%, entry 8vh entry 10vh;
        }
    }
}

@keyframes reading-drift {
    from {
        transform: translateY(120px);
    }
    to {
        transform: translateY(-120px);
    }
}

@keyframes reading-turn {
    from {
        transform: perspective(1800px) translateY(64px) rotateY(-10deg);
    }
    /* flat is no transform at all, so a leaf that has turned is drawn as a
       plain sheet again rather than as a 3D quad at rest */
    to {
        transform: none;
    }
}

@keyframes reading-shade {
    from {
        opacity: 1;
    }
    to {
        opacity: 0;
    }
}

@keyframes reading-recede {
    to {
        opacity: 0.4;
        transform: translateY(-48px) scale(0.96);
    }
}

@keyframes reading-follow {
    from {
        translate: 0 -100%;
    }
    to {
        translate: 0 0;
    }
}

@keyframes reading-thread {
    from {
        scale: 1 0;
    }
    to {
        scale: 1 1;
    }
}

@keyframes reading-sheen {
    0% {
        background-position: -40% 0;
        opacity: 0;
    }
    18%,
    82% {
        opacity: 1;
    }
    100% {
        background-position: 140% 0;
        opacity: 0;
    }
}

@keyframes reading-gild {
    from {
        background-position: 100% 0;
    }
    to {
        background-position: 0% 0;
    }
}

/* the fling's still reveals: each from the waiting state the class change
   above holds to the very end state it arrives at, so a scrubbed reveal and
   a played arrival end on the same page */
@keyframes reading-arrive-fade {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

@keyframes reading-arrive-word {
    from {
        translate: 0 -0.32em;
    }
    to {
        translate: 0 0;
    }
}

@keyframes reading-arrive-rule {
    from {
        scale: 0 1;
    }
    to {
        scale: 1 1;
    }
}

@keyframes reading-arrive-drop {
    from {
        scale: 1 0;
    }
    to {
        scale: 1 1;
    }
}

@keyframes reading-arrive-press {
    from {
        opacity: 0;
        scale: 1.4;
    }
    to {
        opacity: 1;
        scale: 1;
    }
}

@keyframes reading-arrive-stamp {
    from {
        opacity: 0;
        scale: 0.9;
    }
    to {
        opacity: 1;
        scale: 1;
    }
}

@keyframes reading-arrive-ink {
    from {
        clip-path: inset(-0.3em 100% -0.3em -0.6em);
    }
    to {
        clip-path: inset(-0.3em -0.6em -0.3em -0.6em);
    }
}
/* end of the reading pages, alive */

/* the support page: a reading measure and the standing offer */
/* The support page walks through three worlds of the library, each a band
   the full width of the screen: the title page in daylight, the stacks in the
   warmer afternoon, and the reading room after dark, where the ledger lies
   under the lamp. Every world below is complete as written; /js/support.js
   only carries the reader from one to the next, and the motion here is gated
   on the reader not having asked for less. */
.app-main:has(> .support) {
    max-width: none;
    padding: 0;
}
.support {
    /* the gold small labels are set in: the site's --sun deepened toward the
       ink, so an 11.5px label holds AA contrast on the parchment */
    --gilt-ink: color-mix(in srgb, var(--sun) 72%, var(--bark));
    margin: 0;
}

/* the title page: a leaf of the catalog's parchment on two leaves beneath
   it, framed in a double rule, turning over its spine as the reader leaves */
.support-book {
    padding: clamp(28px, 6vw, 64px) 16px clamp(72px, 11vw, 120px);
    overflow-x: clip;
}
.support-leaves {
    position: relative;
    max-width: 720px;
    margin: 0 auto;
    perspective: 1600px;
}
.support-leaves::before,
.support-leaves::after {
    content: "";
    position: absolute;
    inset: 0;
    border: 1px solid rgba(184, 117, 8, 0.2);
    border-radius: 4px;
    background: var(--parchment-bottom);
}
.support-leaves::before {
    transform: translate(9px, 9px);
    background: var(--cream);
}
.support-leaves::after {
    transform: translate(4px, 4px);
}
.support-title-page {
    position: relative;
    z-index: 1;
    padding: clamp(48px, 9vw, 88px) clamp(28px, 7vw, 80px) clamp(44px, 8vw, 80px);
    border: 1px solid rgba(184, 117, 8, 0.25);
    border-radius: 4px;
    background:
        radial-gradient(circle at 18% 10%, rgba(184, 117, 8, 0.07), transparent 34%),
        linear-gradient(180deg, var(--parchment-top), var(--parchment-bottom));
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.44), 0 14px 32px rgba(58, 54, 50, 0.1);
    text-align: center;
    transform-origin: 0% 50%;
}
.support-rule {
    position: absolute;
    border-color: rgba(156, 122, 51, 0.62);
    border-style: double;
    border-width: 0;
    pointer-events: none;
}
.support-rule-top,
.support-rule-bottom {
    left: 14px;
    right: 14px;
    border-top-width: 3px;
}
.support-rule-right,
.support-rule-left {
    top: 14px;
    bottom: 14px;
    border-left-width: 3px;
}
.support-rule-top {
    top: 14px;
    transform-origin: 0% 50%;
}
.support-rule-right {
    right: 14px;
    transform-origin: 50% 0%;
}
.support-rule-bottom {
    bottom: 14px;
    transform-origin: 100% 50%;
}
.support-rule-left {
    left: 14px;
    transform-origin: 50% 100%;
}
/* the gutter's shadow on the lifting leaf, which the turn deepens */
.support-turn-shade {
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: linear-gradient(90deg, rgba(34, 48, 42, 0.26), rgba(34, 48, 42, 0) 60%);
    opacity: 0;
    pointer-events: none;
}
.support-mark {
    display: block;
    width: 56px;
    height: 56px;
    margin: 0 auto 16px;
    filter: drop-shadow(1px 2px 3px rgba(34, 48, 42, 0.18));
}
.support-kicker {
    margin: 0;
    color: var(--gilt-ink);
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: 0.26em;
    text-transform: uppercase;
}
/* A title page sets its title larger than a page head does. Each letter is
   its own sort, so the title can settle into the line one letter at a time;
   a word is never broken between two of them. */
.support-title {
    margin: 12px 0 0;
    font-size: clamp(44px, 8vw, 68px);
    letter-spacing: -0.01em;
    line-height: 1.04;
}
.support-sr {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}
.support-type {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    column-gap: 0.24em;
}
.support-word {
    display: inline-flex;
}
.support-letter {
    display: inline-block;
}
.support-letter::before {
    content: attr(data-glyph);
}
.support-lede {
    max-width: 34em;
    margin: 22px auto 0;
    font-family: var(--ff-text);
    font-size: 1.05rem;
    line-height: 1.7;
    text-wrap: pretty;
}
.support-onward {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    margin-top: 18px;
    font-family: var(--ff);
    font-size: 15px;
    font-weight: 600;
    text-underline-offset: 5px;
    text-decoration-color: rgba(46, 94, 69, 0.4);
}
.support-onward:hover {
    text-decoration-color: currentColor;
}
.support-onward:focus-visible,
.support-spine:focus-visible {
    outline: 2px solid var(--sun);
    outline-offset: 3px;
}

/* the stacks: the five grade bands shelved as bound books, shortest to
   tallest the way their readers grow, each one the way onto its shelf */
.support-stacks {
    display: grid;
    justify-items: center;
    gap: 40px;
    padding: clamp(64px, 10vw, 112px) 16px;
    border-top: 1px solid var(--border);
    background:
        linear-gradient(180deg, rgba(58, 54, 50, 0.05), rgba(58, 54, 50, 0) 90px),
        var(--cream);
}
.support-stacks-copy {
    max-width: 30em;
    text-align: center;
}
.support-stacks h2 {
    margin: 0;
    font-size: clamp(28px, 4.4vw, 40px);
    line-height: 1.1;
    text-wrap: balance;
}
.support-stacks p {
    margin: 12px 0 0;
    color: var(--muted);
    font-family: var(--ff-text);
    font-size: 1rem;
    line-height: 1.7;
    text-wrap: pretty;
}
.support-shelf {
    display: grid;
    justify-items: center;
}
.support-spines {
    /* each band stands a step taller than the one before it */
    --spine-base: 170px;
    --spine-step: 21px;
    display: flex;
    align-items: flex-end;
    gap: 6px;
    margin: 0;
    padding: 0 14px;
    list-style: none;
}
.support-spines li {
    --cloth: var(--ribbon-fold);
    height: calc(var(--spine-base) + var(--book, 0) * var(--spine-step));
}
.support-spines li:nth-child(2) {
    --cloth: color-mix(in srgb, var(--moss) 82%, var(--ink));
    --book: 1;
}
.support-spines li:nth-child(3) {
    --cloth: color-mix(in srgb, var(--muted) 76%, var(--ink));
    --book: 2;
}
.support-spines li:nth-child(4) {
    --cloth: var(--spruce);
    --book: 3;
}
.support-spines li:nth-child(5) {
    --cloth: var(--ribbon-edge);
    --book: 4;
}
/* the spine sets its title down the cloth, so the flex row runs head to
   foot: the band's name under the head bands, its grades above the foot */
.support-spine {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    width: 58px;
    height: 100%;
    padding: 24px 0 22px;
    border-radius: 3px 3px 1px 1px;
    /* two gilt bands at the head and the foot, over the cloth's roundness */
    background:
        linear-gradient(var(--gold-deep), var(--gold-deep)) 0 10px / 100% 1px no-repeat,
        linear-gradient(var(--gold-deep), var(--gold-deep)) 0 13px / 100% 1px no-repeat,
        linear-gradient(var(--gold-deep), var(--gold-deep)) 0 calc(100% - 10px) / 100% 1px no-repeat,
        linear-gradient(var(--gold-deep), var(--gold-deep)) 0 calc(100% - 13px) / 100% 1px no-repeat,
        linear-gradient(90deg, rgba(0, 0, 0, 0.24), rgba(255, 255, 255, 0.05) 32%, rgba(0, 0, 0, 0.06) 64%, rgba(0, 0, 0, 0.3)),
        var(--cloth);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12), 2px 0 3px rgba(34, 48, 42, 0.18);
    text-decoration: none;
    writing-mode: vertical-rl;
}
.support-spine-name {
    color: var(--gold-warm);
    font-family: var(--ff-display);
    font-size: 16px;
    letter-spacing: 0.02em;
    white-space: nowrap;
}
.support-spine-grades {
    color: var(--chrome-text);
    font-family: var(--ff);
    font-size: 12px;
    font-weight: 500;
    letter-spacing: 0.04em;
    white-space: nowrap;
}
.support-plank {
    width: 100%;
    height: 14px;
    border-radius: 2px;
    background: linear-gradient(180deg, var(--muted), var(--bark));
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14), 0 14px 22px -10px rgba(34, 48, 42, 0.55);
}
@media (min-width: 700px) {
    .support-spines {
        --spine-base: 208px;
        --spine-step: 24px;
        gap: 8px;
    }
    .support-spine {
        width: 70px;
    }
    .support-spine-name {
        font-size: 19px;
    }
}
/* the five spines and the shelf's ends are 342px at their phone size, wider
   than the stacks' column on a phone under 375px: there the row would push
   the whole section 14px past its right gutter. The books stand a little
   closer instead, and the shelf fits the column. */
@media (max-width: 374px) {
    .support-spines {
        gap: 5px;
        padding: 0 8px;
    }
    .support-spine {
        width: 56px;
    }
}
@media (min-width: 960px) {
    .support-stacks {
        grid-template-columns: minmax(0, 380px) auto;
        justify-content: center;
        align-items: center;
        gap: 88px;
    }
    .support-stacks-copy {
        text-align: left;
    }
}

/* The reading room: after dark, the forest the header is cut from, a lamp
   over the desk, and the ledger lying lit beneath it. The room's head is a
   dusk threshold from the stacks' cream into the dark; the script lays the
   afternoon over the whole room and lets it go as the reader crosses that
   threshold, and nothing the reader reads stands in it. */
.support-lamp {
    /* the dusk threshold's depth, which the lamp and the script both read */
    --dusk: clamp(220px, 24vw, 320px);
    position: relative;
    isolation: isolate;
    overflow-x: clip;
    padding: var(--dusk) 16px clamp(120px, 16vw, 180px);
    background:
        linear-gradient(180deg, var(--cream), rgba(235, 223, 200, 0) var(--dusk)),
        linear-gradient(0deg, var(--paper), rgba(243, 235, 218, 0) clamp(96px, 12vw, 140px)),
        radial-gradient(120% 70% at 50% 42%, var(--moss) 0%, var(--spruce) 46%, var(--forest) 100%);
    color: var(--chrome-text);
}
.support-daylight {
    position: absolute;
    inset: 0;
    z-index: -1;
    background: var(--cream);
    opacity: 0;
    pointer-events: none;
    will-change: opacity;
}
.support-glow {
    position: absolute;
    top: calc(var(--dusk) - 120px);
    left: 0;
    right: 0;
    z-index: -1;
    width: min(1180px, 170vw);
    aspect-ratio: 1.25;
    /* centred by its margins, so the lamp's scale is the only transform */
    margin: 0 auto;
    background: radial-gradient(closest-side, rgba(229, 197, 126, 0.3), rgba(229, 197, 126, 0.1) 52%, rgba(229, 197, 126, 0));
    pointer-events: none;
}
/* on a phone the lamp is wider than the room, and auto margins cannot centre
   a box wider than its container: they fall to zero and the light hangs off
   to the right. Margins measured from the room's own width centre it. */
@media (max-width: 767px) {
    .support-glow {
        margin: 0 calc((100% - min(1180px, 170vw)) / 2);
    }
}
.support-ledger {
    max-width: 880px;
    margin: 0 auto;
    scroll-margin-top: 88px;
}

/* the offer, in whichever of its three states the reader arrives in: the
   room's opening line, ruled in the lamp's gold */
.supporter-panel {
    max-width: 640px;
    margin: 0 auto;
    padding: 1.1rem 1.25rem;
    border: 1px solid rgba(201, 162, 75, 0.38);
    border-radius: 8px;
    background: rgba(244, 234, 215, 0.04);
    text-align: center;
}
.supporter-panel.is-supporter {
    border-color: rgba(201, 162, 75, 0.7);
    background: rgba(201, 162, 75, 0.1);
}
.supporter-panel p {
    margin: 0;
}
.supporter-panel p + p {
    margin-top: 0.5rem;
}
/* the panel's link reads in the room's paper with a gold rule under it, so it
   holds its contrast over the lamp's glow; the vertical padding widens its
   tap target into the air around the line without moving the line */
.supporter-panel a {
    padding: 12px 0;
    color: var(--chrome-text);
    text-decoration-color: var(--gold);
    text-underline-offset: 4px;
}
.supporter-panel a:hover {
    color: var(--gold-light);
}
.supporter-panel a:focus-visible {
    outline: 2px solid var(--gold-warm);
    outline-offset: 2px;
}
/* the ledger's own name size, so the page's display labels share one step */
.supporter-status {
    font-family: var(--ff-display);
    font-size: 1.2rem;
}

/* The supporters' ledger: the three yearly contributions are one decision, so
   they share one parchment sheet — the catalogue's book stock — ruled into
   three columns the way a library's subscription ledger rules a page. Each
   entry is a ledger line: name and amount on one baseline, a dotted leader
   carrying the eye between them. The suggested entry is the gilded one — a
   gold gilt along its top edge, a warm wash falling from it, and the page's
   only solid-gold action; the other two actions stay quiet. The sheet lies
   on the reading room's desk, so the owner's message above it is set in the
   lamp's light, and the fineprint closes the page as its colophon. */
.support-promise {
    margin: 3.5rem auto 0;
    max-width: 30em;
    color: var(--chrome-text);
    font-family: var(--ff-display);
    font-size: 1.4rem;
    line-height: 1.45;
    text-align: center;
    text-wrap: balance;
}
.tier-grid {
    display: grid;
    grid-template-columns: 1fr;
    margin: 1.7rem calc(50% - min(440px, 50vw - 16px)) 0;
    padding: 0;
    list-style: none;
    border: 1px solid rgba(184, 117, 8, 0.25);
    border-radius: 8px;
    overflow: hidden;
    background: linear-gradient(180deg, var(--parchment-top), var(--parchment-bottom));
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.44), 0 26px 60px rgba(6, 14, 9, 0.5);
}
.tier {
    position: relative;
    display: grid;
    grid-template-columns: auto 1fr auto;
    grid-template-rows: auto auto 1fr auto;
    padding: 24px 22px 22px;
    /* stacked entries each carry the sheet's own shading, so a row reads as
       its own slip instead of one tall ramp; the shared sheet gradient
       returns at 700px where the entries stand side by side */
    background: linear-gradient(180deg, var(--parchment-top), var(--parchment-bottom));
}
/* the Guide Leaderboard's own .tier sections carry a top margin from an
   unscoped rule later in this sheet; the ledger's entries meet the sheet's
   edges and each other, so they refuse it here */
.tier-grid > .tier {
    --leader: 1;
    margin: 0;
}
.tier + .tier {
    border-top: 1px solid var(--border-light);
}
.tier::before {
    content: "";
    grid-area: 2 / 2;
    align-self: end;
    margin: 0 9px 0.35em;
    border-bottom: 1px dotted var(--border);
    /* the leader is drawn from the name toward the amount: the page's script
       walks --leader from 0 to 1 as the ledger is ruled */
    clip-path: inset(0 calc((1 - var(--leader)) * 100%) 0 0);
}
.tier.is-highlighted {
    background: linear-gradient(180deg, var(--sun-pale), rgba(244, 234, 215, 0) 70%), linear-gradient(180deg, var(--parchment-top), var(--parchment-bottom));
    box-shadow: inset 0 3px 0 var(--gold-deep), inset 0 -1px 0 var(--gold-deep);
}
.tier + .tier.is-highlighted {
    border-top: 0;
}
.tier.is-highlighted + .tier {
    border-top: 0;
}
.tier-flag {
    grid-area: 1 / 1 / 2 / 4;
    margin: 2px 0 10px;
    color: var(--gilt-ink);
    font-family: var(--ff);
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: 0.08em;
}
.tier-name {
    grid-area: 2 / 1;
    align-self: baseline;
    margin: 0;
    color: var(--bark);
    font-family: var(--ff-display);
    font-size: 1.2rem;
}
.tier-price {
    grid-area: 2 / 3;
    align-self: baseline;
    margin: 0;
    color: var(--leaf);
    font-family: var(--ff-display);
    font-size: 1.2rem;
    line-height: 1.2;
}
.tier-copy {
    grid-area: 3 / 1 / 4 / 4;
    align-self: start;
    margin: 10px 0 20px;
    color: var(--muted);
    font-family: var(--ff-text);
    font-size: 0.95rem;
    line-height: 1.65;
}
.tier-choose {
    grid-area: 4 / 1 / 5 / 4;
    justify-self: start;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    padding: 0.45rem 1.2rem;
    border: 1px solid var(--leaf);
    border-radius: 1rem;
    background: none;
    color: var(--leaf);
    font-family: var(--ff);
    font-size: 0.9rem;
    font-weight: 600;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
}
.tier-choose:hover,
.tier-choose:focus-visible {
    border-color: var(--leaf-light);
    background: var(--leaf-pale);
    color: var(--leaf-light);
}
.tier-choose:focus-visible {
    outline: 2px solid var(--sun);
    outline-offset: 2px;
}
.tier.is-highlighted .tier-choose {
    border-color: var(--gold-deep);
    background: linear-gradient(180deg, var(--gold-light), var(--gold-deep));
    color: var(--ink);
}
.tier.is-highlighted .tier-choose:hover,
.tier.is-highlighted .tier-choose:focus-visible {
    border-color: var(--gold);
    background: var(--gold);
    color: var(--ink);
}
/* pressed: the action sinks into the sheet, without moving */
.tier-choose:active {
    box-shadow: inset 0 2px 4px var(--shadow-md);
}
@media (min-width: 700px) {
    .tier-grid {
        grid-template-columns: repeat(3, 1fr);
    }
    .tier {
        padding: 52px 24px 24px;
        background: none;
    }
    .tier + .tier {
        border-top: 0;
        border-left: 1px solid var(--border-light);
    }
    /* stacked rows carry the closing gilt at the seam and their own slip
       shading; side-by-side columns share the sheet and keep the single top
       gilt the owner approved */
    .tier.is-highlighted {
        background: linear-gradient(180deg, var(--sun-pale), rgba(244, 234, 215, 0) 70%);
        box-shadow: inset 0 3px 0 var(--gold-deep);
    }
    /* the gilded entry carries its label in the air every column shares, so
       the three name-and-amount lines hold one baseline across the sheet */
    .tier-flag {
        grid-area: auto;
        position: absolute;
        top: 19px;
        left: 24px;
        margin: 0;
    }
}
/* morning: the page closes on paper again, the fineprint set as the book's
   colophon under a short gold rule */
.support-colophon {
    padding: 8px 16px clamp(56px, 8vw, 88px);
    background: var(--paper);
}
.support-colophon::before {
    content: "";
    display: block;
    width: 64px;
    height: 1px;
    margin: 0 auto;
    background: var(--sun);
    opacity: 0.6;
}
.supporter-fineprint {
    margin: 1.7rem auto 0;
    max-width: 34em;
    color: var(--muted);
    font-family: var(--ff-text);
    font-style: italic;
    font-size: 1rem;
    line-height: 1.7;
    text-align: center;
    text-wrap: balance;
}

/* The load, stated only for a reader who has not asked for less motion; the
   keyframes end on the rules above, so the page they settle into is the page
   as written. The title settles like set type: each sort drops a fraction of
   a line into place and comes up from the paper, the double rule draws
   itself round the page from its top corner, and the rest of the title page
   follows. One sequence, once. */
@media (prefers-reduced-motion: no-preference) {
    .support-letter {
        animation: support-set 700ms cubic-bezier(0.22, 1, 0.36, 1) calc(120ms + var(--letter) * 32ms) both;
    }
    .support-rule-top,
    .support-rule-bottom {
        animation: support-rule-x 560ms cubic-bezier(0.65, 0, 0.35, 1) both;
    }
    .support-rule-right,
    .support-rule-left {
        animation: support-rule-y 560ms cubic-bezier(0.65, 0, 0.35, 1) both;
    }
    .support-rule-right {
        animation-delay: 300ms;
    }
    .support-rule-bottom {
        animation-delay: 600ms;
    }
    .support-rule-left {
        animation-delay: 900ms;
    }
    .support-mark,
    .support-kicker {
        animation: support-rise 700ms cubic-bezier(0.22, 1, 0.36, 1) 60ms both;
    }
    .support-lede,
    .support-onward {
        animation: support-rise 800ms cubic-bezier(0.22, 1, 0.36, 1) 560ms both;
    }
    .support-onward {
        animation-delay: 680ms;
    }
    /* a band's book is drawn half out of the shelf toward the hand */
    .support-spine {
        transition: transform 220ms cubic-bezier(0.22, 1, 0.36, 1);
    }
    .support-spine:hover,
    .support-spine:focus-visible {
        transform: translateY(-10px);
    }
    /* the gilded entry's gilt catches the lamp once, as the ledger is lit */
    .support .tier.is-highlighted::after {
        content: "";
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 3px;
        background: linear-gradient(90deg, rgba(255, 253, 247, 0), rgba(255, 253, 247, 0.95), rgba(255, 253, 247, 0)) -70% 0 / 40% 100% no-repeat;
        pointer-events: none;
    }
    .support .tier-grid.is-lit .tier.is-highlighted::after {
        animation: support-gilt 1300ms cubic-bezier(0.65, 0, 0.35, 1) both;
    }
}
@keyframes support-set {
    from {
        opacity: 0;
        transform: translateY(-0.28em);
    }
}
@keyframes support-rule-x {
    from {
        transform: scaleX(0);
    }
}
@keyframes support-rule-y {
    from {
        transform: scaleY(0);
    }
}
@keyframes support-rise {
    from {
        opacity: 0;
        transform: translateY(14px);
    }
}
@keyframes support-gilt {
    to {
        background-position: 170% 0;
    }
}
/* on paper the room is not dark: its words print in ink, and every sheet
   stands still and square wherever the reader had scrolled to */
@media print {
    .support-title-page,
    .support-spines li,
    .tier-grid {
        transform: none !important;
        opacity: 1 !important;
    }
    .support-daylight,
    .support-glow,
    .support-turn-shade {
        display: none;
    }
    .support-lamp {
        padding-top: 32px;
        background: none;
        color: var(--bark);
    }
    .support-promise {
        color: var(--bark);
    }
    .supporter-panel a {
        color: var(--leaf);
    }
}

/* What We Believe: the repository's statement, set as a book the reader walks
   through. A pine cloth cover opens onto the title leaf; a contents; ten
   chapters on paper, each opened by a gold rule and a drop initial; and the
   rooms the chapters pass through: a night room under a lamp for the question,
   a vellum page for the medieval argument, a ruled copybook sheet for the hand
   and the pencil; then the shelf of the books the notes cite, and a back board.

   Every rule outside `html.believe-js` draws the finished, still book: what a
   reader with reduced motion or no script reads, and what print starts from.
   The page sets `html.believe-js` before it paints, and only where motion is
   welcome; under it the cover starts shut and the two rooms that stay a while
   get the scroll they are read across. /js/believe.js plays the rest.

   One type scale runs through the page, stepped from the body's 16.5px (the
   blog post's reading setting, so the site's two long reads are set alike). */
/* the body's measure as a length: registered, so it is computed once where it
   is declared, in the body face at the body size, and every element that
   reads it gets that column rather than 58ch of its own type */
@property --believe-measure {
    syntax: "<length>";
    inherits: true;
    initial-value: 0px;
}
.believe {
    --believe-measure: 58ch;
    --believe-head: calc(69px + env(safe-area-inset-top, 0px));
    --believe-book-h: min(560px, calc(100svh - var(--believe-head) - 64px));
    --believe-small: 14.5px;
    --believe-body: 16.5px;
    --believe-lead: 20.5px;
    --believe-title: clamp(26px, 3vw, 32px);
    --believe-display: clamp(40px, 4.4vw, 52px);
    --believe-vellum: color-mix(in srgb, var(--sun-pale) 55%, var(--cream));
    --believe-ruling: rgba(46, 94, 69, 0.2);
    --believe-margin-line: rgba(139, 58, 47, 0.45);
    --believe-glow: rgba(229, 197, 126, 0.2);
    --believe-cloth: repeating-linear-gradient(45deg, rgba(244, 234, 215, 0.025) 0 2px, transparent 2px 5px);
    position: relative;
    /* .app-main's top padding, given back so the binding meets the header */
    margin: -24px 0 0;
    color: var(--bark);
    font-family: var(--ff-text);
    font-size: var(--believe-body);
    line-height: 1.8;
}
.believe p {
    margin: 0 0 1em;
    text-wrap: pretty;
}
.believe h2 {
    margin: 0 0 0.7rem;
    font-size: var(--believe-title);
    line-height: 1.15;
    text-wrap: balance;
}
.believe-numeral {
    color: var(--sun);
}
/* a word of a heading the script sets in place, moved without leaving its line */
.believe-set {
    display: inline-block;
}
.believe sup {
    line-height: 0;
}
.believe sup a {
    padding: 0 0.15em;
    text-decoration: none;
}
.believe sup a:hover {
    text-decoration: underline;
}
/* a note marker is a 12px figure a thumb cannot find: on a phone its link
   reaches past the glyph by padding its own negative margin gives straight
   back, so every line keeps its breaks, and it stands on a layer of its own
   so the words beside it never take the tap */
@media (max-width: 899px) {
    .believe sup a {
        position: relative;
        margin: -16px -12px;
        padding: 16px calc(12px + 0.15em);
        outline-offset: -10px;
    }
    /* the epigraph's marker stands alone after a name, in a centred line with
       room either side, so it takes the full width a thumb needs */
    .believe-epigraph-by sup a {
        margin-inline: -18px;
        padding-inline: calc(18px + 0.15em);
        outline-offset: -14px;
    }
}
.believe a:focus-visible {
    outline: 2px solid var(--sun);
    outline-offset: 2px;
}

/* the binding: pine cloth under the book, bled to both screen edges by a
   border image, which paints past the box without widening the page. --turn
   states the cover shut (0) or open (1) for the stylesheet, so each state is
   drawn before any script runs; the script plays the turn between them on the
   same transforms and opacities. --dawn would lay the paper over the cloth;
   the still book leaves it at 0, lying open on the pine. */
.believe-opening {
    --turn: 1;
    --dawn: 0;
    position: relative;
    display: grid;
    align-items: center;
    justify-items: center;
    min-height: calc(100svh - var(--believe-head));
    padding: 32px 0;
    border-image: radial-gradient(135% 110% at 50% 30%, var(--moss) 0%, var(--spruce) 46%, var(--forest) 100%) fill 0 // 0 100vw;
}
.believe-field {
    position: absolute;
    inset: 0;
    border-image: linear-gradient(var(--paper), var(--paper)) fill 0 // 0 100vw;
    opacity: var(--dawn);
    pointer-events: none;
}
/* Every full-bleed ground on the page is a border image, and WebKit does not
   count a border image as painted content when it decides whether a
   composited layer needs a backing store: a layer that paints nothing else,
   with all its children on layers of their own (the night under its scrub,
   the field and the vellum under their fades), is given none, and its ground
   is never drawn. An invisible shadow is a decoration WebKit does count. */
.believe-opening,
.believe-field,
.believe-stage-night,
.believe-conviction > .believe-vellum,
.believe-back {
    box-shadow: 0 0 0 transparent;
}
.believe-book {
    position: relative;
    z-index: 1;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    width: min(100%, 420px);
    min-height: var(--believe-book-h);
    perspective: 2200px;
}
.believe-leaf,
.believe-cover {
    grid-area: 1 / 1;
}
.believe-leaf {
    display: grid;
    align-items: center;
    padding: 44px clamp(24px, 4vw, 44px);
    border-radius: 2px 7px 7px 2px;
    background:
        linear-gradient(90deg, rgba(61, 37, 18, 0.16), rgba(61, 37, 18, 0) 7%),
        linear-gradient(180deg, var(--parchment-top) 0%, var(--parchment-bottom) 100%);
    box-shadow: inset 0 0 0 1px rgba(184, 117, 8, 0.16), 0 22px 48px rgba(6, 14, 9, 0.36);
    text-align: center;
}
.believe-leaf-inner {
    max-width: 26em;
    margin: 0 auto;
}
.believe-title-rule {
    display: block;
    width: 48px;
    height: 1px;
    margin: 0 auto 26px;
    background: var(--sun);
}
.believe h1 {
    margin: 0;
    font-size: var(--believe-display);
    line-height: 1.04;
    text-wrap: balance;
}
.believe p.believe-deck {
    max-width: 20em;
    margin: 16px auto 0;
    color: var(--muted);
    font-size: var(--believe-lead);
    font-style: italic;
    line-height: 1.4;
    text-wrap: balance;
}
/* a gilt lozenge between two hairlines: the binder's tool, used as a divider */
.believe-ornament {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    width: 128px;
    margin: 26px auto;
    color: var(--sun);
}
.believe-ornament::before,
.believe-ornament::after {
    content: "";
    flex: 1;
    height: 1px;
    background: currentColor;
    opacity: 0.55;
}
.believe-ornament i {
    width: 7px;
    height: 7px;
    background: currentColor;
    transform: rotate(45deg);
}
.believe-epigraph {
    margin: 0;
    color: var(--bark-soft);
    line-height: 1.65;
    text-wrap: balance;
}
.believe-epigraph-by {
    display: block;
    margin-top: 10px;
    color: var(--muted);
    font-size: var(--believe-small);
}

/* the cover: the face shows while the book is shut and the inside once it
   has turned, each hiding the side of itself that faces away */
.believe-cover {
    position: relative;
    transform: rotateY(calc(var(--turn) * -180deg));
    transform-origin: left center;
    transform-style: preserve-3d;
}
.believe-cover-face,
.believe-cover-inside {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
    border-radius: 3px 8px 8px 3px;
    color: var(--gold-warm);
    text-align: center;
    box-shadow: inset 0 0 0 1px rgba(201, 162, 75, 0.2), 0 22px 48px rgba(6, 14, 9, 0.46);
}
.believe-cover-face {
    padding: 56px 40px;
    background:
        var(--believe-cloth),
        radial-gradient(120% 90% at 28% 18%, var(--moss) 0%, var(--spruce) 46%, var(--pine) 100%);
}
.believe-cover-inside {
    border-radius: 8px 3px 3px 8px;
    background: var(--believe-cloth), linear-gradient(90deg, var(--forest), var(--pine) 92%, var(--spruce));
    transform: rotateY(180deg);
}
/* a gilt fillet: four hairlines round a panel, each drawn from the corner the
   last one ended at, so the script can run them as one line */
.believe-fillet {
    position: absolute;
    inset: 18px;
    pointer-events: none;
}
.believe-fillet i {
    position: absolute;
    background: var(--gold);
}
.believe-fillet i:nth-child(1) {
    top: 0;
    right: 0;
    left: 0;
    height: 1px;
    transform-origin: left;
}
.believe-fillet i:nth-child(2) {
    top: 0;
    right: 0;
    bottom: 0;
    width: 1px;
    transform-origin: top;
}
.believe-fillet i:nth-child(3) {
    right: 0;
    bottom: 0;
    left: 0;
    height: 1px;
    transform-origin: right;
}
.believe-fillet i:nth-child(4) {
    top: 0;
    bottom: 0;
    left: 0;
    width: 1px;
    transform-origin: bottom;
}
.believe-fillet.is-inner {
    inset: 25px;
    opacity: 0.5;
}
/* blind-tooled: pressed into the cloth rather than gilt */
.believe-fillet.is-blind i {
    background: rgba(6, 14, 9, 0.55);
    box-shadow: 1px 1px 0 rgba(244, 234, 215, 0.06);
}
.believe-cover-face .believe-ornament {
    margin: 22px auto;
    color: var(--gold);
}
.believe p.believe-cover-title {
    margin: 0;
    font-family: var(--ff-display);
    font-size: var(--believe-display);
    line-height: 1.04;
    letter-spacing: -0.01em;
}
.believe-cover-word {
    display: block;
}
.believe p.believe-cover-sub {
    max-width: 16em;
    margin: 0;
    color: var(--sand);
    font-style: italic;
    line-height: 1.5;
}
.believe p.believe-cover-imprint {
    position: absolute;
    bottom: 40px;
    margin: 0;
    font-family: var(--ff-brand);
    font-size: var(--believe-lead);
}
/* the light that runs across the gilt once, when the cover is set. At rest
   its band lies just past the cover's right edge, where the cover clips it */
.believe-sheen {
    position: absolute;
    top: -10%;
    bottom: -10%;
    left: 0;
    width: 220%;
    background: linear-gradient(100deg, transparent 42%, rgba(255, 236, 190, 0.26) 50%, transparent 58%);
    pointer-events: none;
}
.believe-shade {
    position: absolute;
    inset: 0;
    background: var(--forest);
    pointer-events: none;
}
.believe-cover-face .believe-shade {
    opacity: min(0.6, calc(var(--turn) * 1.2));
}
.believe-cover-inside .believe-shade {
    opacity: min(0.6, calc((1 - var(--turn)) * 1.2));
}
.believe-endmark {
    width: 72px;
    height: 72px;
    opacity: 0.5;
}
/* a phone has no room for a spread: the open book is its title leaf, and a
   turning cover fades once it has swung past the spine */
@media (max-width: 899px) {
    html:not(.believe-js) .believe-cover {
        display: none;
    }
    .believe-cover {
        opacity: clamp(0, (1 - var(--turn)) * 4, 1);
    }
}
/* on a wide screen the open book lies as a spread about its spine, the
   cover's inside to the left and the title leaf to the right; shut, the book
   slides left by half a page so the cover sits centred */
@media (min-width: 900px) {
    .believe-book {
        grid-template-columns: 1fr 1fr;
        width: min(100%, 860px);
        transform: translateX(calc((1 - var(--turn)) * -25%));
    }
    .believe-leaf,
    .believe-cover {
        grid-column: 2;
    }
}

/* the contents: the chapters by their numerals, a link to each */
.believe-contents {
    max-width: 880px;
    padding: clamp(56px, 10vh, 104px) 0 0;
}
.believe p.believe-contents-title {
    margin: 0 0 18px;
    font-family: var(--ff-display);
    font-size: var(--believe-title);
    line-height: 1.15;
}
.believe-contents ol {
    display: grid;
    margin: 0;
    padding: 0;
    list-style: none;
    column-gap: 48px;
}
@media (min-width: 900px) {
    .believe-contents ol {
        grid-auto-flow: column;
        grid-template-columns: 1fr 1fr;
        grid-template-rows: repeat(6, auto);
    }
}
.believe-contents a {
    display: grid;
    grid-template-columns: 3.6em 1fr;
    column-gap: 14px;
    align-items: baseline;
    min-height: 44px;
    padding: 6px 0;
    border-bottom: 1px solid var(--border-light);
    color: var(--bark);
    line-height: 1.4;
    text-decoration: none;
    transition: color 150ms ease;
}
.believe-contents a:hover {
    color: var(--leaf);
}
/* set at the chapter-title step, which keeps the gold numerals large text:
   the size their contrast against the paper passes at */
.believe-contents-numeral {
    color: var(--sun);
    font-family: var(--ff-display);
    font-size: var(--believe-title);
    line-height: 1;
    text-align: right;
}

/* a chapter: its gold rule, its title, a drop initial, and on a wide screen
   an engraved numeral in the margin over a line that follows the reading */
.believe-conviction {
    position: relative;
    isolation: isolate;
    padding-top: clamp(72px, 12vh, 124px);
    scroll-margin-top: var(--believe-head);
}
.believe-conviction > * {
    max-width: 58ch;
}
/* a title is set in the column its chapter is read in, and wraps there: 58ch
   of the display face at title size reached past the column and into the
   numeral engraved in the margin */
.believe-conviction > h2 {
    max-width: var(--believe-measure);
}
.believe-rule {
    display: block;
    height: 1px;
    margin-bottom: 26px;
    background: linear-gradient(90deg, var(--sun), rgba(156, 122, 51, 0) 70%);
    transform-origin: left;
}
.believe-open {
    --ink: 1;
}
.believe-open::first-letter {
    float: left;
    margin: 0.07em 0.08em 0 0;
    color: color-mix(in srgb, var(--leaf) calc(var(--ink) * 100%), transparent);
    font-family: var(--ff-display);
    font-size: 3.55em;
    line-height: 0.8;
}
.believe p.believe-coda {
    margin-top: 1.4em;
    font-size: var(--believe-lead);
    font-style: italic;
    line-height: 1.5;
}
.believe-folio {
    display: none;
}
@media (min-width: 1100px) {
    .believe-conviction > .believe-folio {
        --read: 1;
        position: absolute;
        top: clamp(72px, 12vh, 124px);
        right: 0;
        bottom: 0;
        left: calc(58ch + 96px);
        display: block;
        max-width: none;
        pointer-events: none;
    }
    .believe-folio > span {
        position: sticky;
        top: 32vh;
        display: block;
        color: transparent;
        font-family: var(--ff-display);
        font-size: clamp(104px, 9vw, 140px);
        line-height: 0.9;
        -webkit-text-stroke: 1px var(--sun);
    }
    .believe-folio > span::after {
        content: "";
        display: block;
        width: 1px;
        height: 132px;
        margin: 22px 0 0 8px;
        background: var(--sun);
        transform: scaleY(var(--read));
        transform-origin: top;
    }
}

/* the night room: the question alone under a lamp, and the four who asked
   it. The paper copy and the night copy share one grid cell, so as the night
   rises across the question every word stands on a ground it reads against. */
.believe-conviction > .believe-stage {
    max-width: none;
    margin: 48px 0;
}
.believe-stage-frame {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
}
.believe-stage-day,
.believe-stage-night {
    position: relative;
    grid-area: 1 / 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: clamp(24px, 8vh, 112px) 0;
}
.believe-stage-night {
    border-image: radial-gradient(80% 70% at 30% 36%, var(--spruce) 0%, var(--pine) 46%, var(--forest) 100%) fill 0 // 0 100vw;
    color: var(--gold-warm);
}
.believe-stage-day .believe-askers {
    visibility: hidden;
}
.believe-lamp {
    position: absolute;
    inset: -12% 25% -12% -25%;
    background: radial-gradient(closest-side, var(--believe-glow), rgba(229, 197, 126, 0.07) 55%, transparent);
    pointer-events: none;
}
.believe p.believe-question {
    position: relative;
    max-width: 13ch;
    margin: 0;
    font-family: var(--ff-display);
    font-size: clamp(44px, 7vw, 84px);
    line-height: 1.04;
    letter-spacing: -0.015em;
    text-wrap: balance;
}
.believe-question strong {
    font-weight: 400;
}
.believe-askers {
    position: relative;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 150px), 1fr));
    gap: 22px 32px;
    max-width: 980px;
    margin: clamp(28px, 6vh, 56px) 0 0;
    padding: 0;
    list-style: none;
}
.believe-askers li {
    --draw: 1;
    position: relative;
    padding-top: 14px;
    line-height: 1.35;
}
.believe-askers li::before {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    left: 0;
    height: 1px;
    background: rgba(201, 162, 75, 0.5);
    transform: scaleX(var(--draw));
    transform-origin: left;
}
.believe-asker {
    display: block;
    font-family: var(--ff-display);
    font-size: var(--believe-lead);
}
.believe-asker-place {
    display: block;
    margin-top: 4px;
    color: var(--sand);
    font-size: var(--believe-small);
    font-style: italic;
}

/* the two freedoms side by side: one loose and unruled, one framed in gilt */
.believe-diptych {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
    gap: 16px;
    margin: 32px 0 36px;
}
.believe p.believe-freedom {
    position: relative;
    margin: 0;
    padding: 28px 26px;
    border: 1px dashed var(--border);
    line-height: 1.35;
}
.believe p.believe-freedom.is-excellence {
    border: 0;
    background: linear-gradient(180deg, var(--parchment-top) 0%, var(--parchment-bottom) 100%);
    box-shadow: 0 1px 2px rgba(58, 54, 50, 0.05), 0 10px 24px rgba(58, 54, 50, 0.08);
}
.believe-freedom .believe-fillet {
    inset: 7px;
}
.believe-freedom-name {
    display: block;
    color: var(--muted);
    font-size: var(--believe-lead);
    font-style: italic;
}
.is-excellence .believe-freedom-name {
    color: var(--bark);
    font-family: var(--ff-display);
    font-style: normal;
}
.believe-freedom-gloss {
    display: block;
    margin-top: 8px;
    color: var(--muted);
    font-size: var(--believe-small);
}

/* the vellum page: the medieval argument on warmer stock, between the two
   lines a scribe ruled down his page, with soft top and bottom edges */
.believe-conviction > .believe-vellum {
    position: absolute;
    inset: 0 0 -72px;
    z-index: -1;
    max-width: none;
    border-image: linear-gradient(transparent, var(--believe-vellum) 96px,
        var(--believe-vellum) calc(100% - 96px), transparent) fill 0 // 0 100vw;
    pointer-events: none;
}
.believe-vellum i {
    position: absolute;
    top: clamp(72px, 12vh, 124px);
    bottom: 96px;
    left: -10px;
    width: 1px;
    background: var(--believe-margin-line);
    transform-origin: top;
}
.believe-vellum i + i {
    left: calc(min(100%, 58ch) + 10px);
}
#conviction-4 {
    margin-bottom: 72px;
}
.believe-articulus {
    margin: 34px 0 38px;
}
.believe-articulus figcaption {
    margin-bottom: 20px;
    color: var(--muted);
    font-size: var(--believe-small);
    font-style: italic;
}
.believe-articulus ol {
    margin: 0;
    padding: 0;
    list-style: none;
}
.believe-articulus li {
    position: relative;
    padding: 0 0 22px 40px;
}
.believe-mark {
    --fill: 1;
    position: absolute;
    top: 8px;
    left: 0;
    width: 13px;
    height: 13px;
    border: 1px solid var(--sun);
    border-radius: 50%;
    background: color-mix(in srgb, var(--sun) calc(var(--fill) * 100%), transparent);
}
.believe-articulus-line {
    position: absolute;
    top: 27px;
    bottom: 4px;
    left: 6px;
    width: 1px;
    background: var(--sun);
    transform-origin: top;
}
.believe p.believe-incipit {
    margin: 0 0 2px;
    font-size: var(--believe-lead);
    font-style: italic;
    line-height: 1.4;
}
.believe-articulus p:last-child {
    margin: 0;
    color: var(--muted);
    line-height: 1.6;
}

/* the turn in VI: method set aside, courage brought forward */
.believe p.believe-turn {
    margin: 0 0 1.4em;
    font-family: var(--ff-display);
    font-size: var(--believe-title);
    line-height: 1.3;
}
.believe-turn span {
    display: block;
}
.believe-turn span:first-child {
    color: var(--muted);
    font-family: var(--ff-text);
    font-size: var(--believe-lead);
    font-style: italic;
}

/* the copybook sheet: the hand, the place and the pencil, written on ruled
   paper. The rules and the text share one pitch, and a blank rule stands
   between paragraphs the way it would in an exercise book.

   The pitch is a whole pixel, stated once, rather than the page's 1.8
   leading: WebKit resolves a unitless line height to 1/64px (29.7px is laid
   out as 29.6875px) while the gradient keeps 29.7px, and the difference
   gathers line by line down the sheet, rounded again by the phone's pixel
   grid. A whole pixel lands on both grids exactly. iOS text autosizing may
   not resize this text away from its rules, and a run in another face (the
   italic, or a glyph falling back to another font) may not stand taller than
   the line it sits on. */
.believe-copybook {
    --believe-pitch: 30px;
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}
.believe-conviction > .believe-copybook {
    position: relative;
    max-width: calc(58ch + 64px);
    margin: 10px -8px 0;
    padding: var(--believe-pitch) 14px 0 36px;
    border-radius: 2px;
    background: var(--field);
    box-shadow: 0 1px 2px rgba(58, 54, 50, 0.06), 0 14px 34px rgba(58, 54, 50, 0.1);
}
.believe-margin-line {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 26px;
    width: 1px;
    background: var(--believe-margin-line);
    transform-origin: top;
}
.believe-ruling {
    position: absolute;
    inset: var(--believe-pitch) 0 0;
    background: repeating-linear-gradient(180deg, transparent 0 calc(var(--believe-pitch) - 7px),
        var(--believe-ruling) calc(var(--believe-pitch) - 7px) calc(var(--believe-pitch) - 6px),
        transparent calc(var(--believe-pitch) - 6px) var(--believe-pitch));
    transform-origin: left;
    pointer-events: none;
}
.believe-copybook p {
    position: relative;
}
.believe .believe-copybook p {
    margin-bottom: var(--believe-pitch);
    line-height: var(--believe-pitch);
}
.believe-copybook p * {
    line-height: 0;
}
@media (min-width: 768px) {
    .believe-conviction > .believe-copybook {
        margin: 10px -24px 0;
        padding: var(--believe-pitch) 32px 0 64px;
    }
    .believe-margin-line {
        left: 42px;
    }
}

/* the close of X set large, with the gilt rule under it */
.believe p.believe-finale {
    margin: 2em 0 0;
    font-family: var(--ff-display);
    font-size: var(--believe-display);
    line-height: 1.12;
    text-wrap: balance;
}
.believe-finale span {
    display: block;
}
.believe-finale-rule {
    display: block;
    width: 128px;
    height: 2px;
    margin-top: 28px;
    background: linear-gradient(90deg, var(--gold-deep) 0%, var(--gold-deep) 40%, var(--gold-light) 50%,
        var(--gold-deep) 60%, var(--gold-deep) 100%) 100% 0 / 250% 100%;
    transform-origin: left;
}

/* the company we keep: the cited works standing on a shelf, oldest first,
   each spine a link to its note; then the notes themselves */
.believe-company {
    padding-top: clamp(72px, 12vh, 124px);
    scroll-margin-top: var(--believe-head);
}
.believe-company > h2 {
    max-width: var(--believe-measure);
}
.believe-shelf {
    display: flex;
    align-items: flex-end;
    gap: 4px;
    margin: 30px 0 44px;
    padding: 24px 2px 0;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
    border-bottom: 11px solid var(--bark-soft);
    list-style: none;
    box-shadow: 0 12px 16px -12px rgba(34, 48, 42, 0.5);
}
.believe-shelf li {
    flex: none;
    scroll-snap-align: start;
}
/* Each book's slot is set in the spine's own vertical writing, so the shelf
   sizes it from the spine as laid out. Left horizontal, the slot held an
   orthogonal spine, and WebKit sized it from the spine's 44px minimum rather
   than its real width: every spine spilled out of its slot, the one two-line
   title ran 14px into its neighbour, and the row came up short of the shelf.
   Where the shelf is wider than the books, the books share what is left, so
   the row fills it end to end; a phone slides along them as before. */
.believe-shelf li {
    flex-grow: 1;
    display: grid;
    writing-mode: vertical-rl;
}
.believe-shelf li > .believe-spine {
    justify-self: start;
}
/* a spine is set in vertical writing, so its height is its inline size; a
   wide screen stands all twenty in the column, a phone slides along them */
.believe-spine {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 14px;
    min-block-size: 44px;
    inline-size: var(--h);
    padding: 18px 6px;
    border-radius: 3px 3px 1px 1px;
    background-color: var(--pine);
    background-image:
        linear-gradient(var(--gold) 0 0), linear-gradient(var(--gold) 0 0),
        var(--believe-cloth),
        linear-gradient(90deg, rgba(6, 14, 9, 0.35), rgba(6, 14, 9, 0) 38%, rgba(6, 14, 9, 0) 62%, rgba(6, 14, 9, 0.3));
    background-position: 0 8px, 0 calc(100% - 8px), 0 0, 0 0;
    background-size: 100% 1px, 100% 1px, auto, auto;
    background-repeat: no-repeat, no-repeat, repeat, no-repeat;
    color: var(--chrome-text);
    text-decoration: none;
    writing-mode: vertical-rl;
    transition: transform 200ms cubic-bezier(0.16, 1, 0.3, 1);
}
.believe-spine:hover,
.believe-spine:focus-visible {
    color: var(--chrome-text);
    transform: translateY(-9px);
}
.believe-shelf li:nth-child(6n + 2) .believe-spine {
    background-color: var(--ribbon-fold);
}
.believe-shelf li:nth-child(6n + 3) .believe-spine {
    background-color: var(--moss);
}
.believe-shelf li:nth-child(6n + 4) .believe-spine {
    background-color: var(--bark-soft);
}
.believe-shelf li:nth-child(6n + 5) .believe-spine {
    background-color: var(--spruce);
}
/* the green spine is taken a step toward the forest: at --leaf itself its
   gilt lettering would sit right on 4.5:1 before the cloth lightens it */
.believe-shelf li:nth-child(6n) .believe-spine {
    background-color: color-mix(in srgb, var(--leaf) 78%, var(--forest));
}
.believe-spine-text {
    display: flex;
    flex-direction: column;
}
.believe-spine-title {
    font-size: var(--believe-small);
    line-height: 1.15;
}
.believe-spine-author {
    order: 1;
    margin-block-start: 4px;
    color: var(--gold-warm);
    font-family: var(--ff);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.1em;
    line-height: 1.2;
    text-transform: uppercase;
}
.believe-notes {
    margin: 0;
    padding-left: 1.6rem;
    color: var(--muted);
    font-size: var(--believe-small);
    line-height: 1.6;
}
@media (min-width: 900px) {
    .believe-notes {
        columns: 2;
        column-gap: 56px;
    }
}
.believe-notes li {
    margin-bottom: 0.8rem;
    break-inside: avoid;
    /* a note reached from its marker lands clear of the sticky header, and
       is marked as the one the reader asked for */
    scroll-margin-top: calc(96px + env(safe-area-inset-top, 0px));
}
.believe-notes li:target {
    background: var(--sun-pale);
    box-shadow: 0 0 0 0.4em var(--sun-pale);
    color: var(--bark);
}

/* the back board: the book closed again, in the cloth it opened in */
.believe-back {
    position: relative;
    display: grid;
    justify-items: center;
    gap: 22px;
    /* .app-main's foot padding, given back so the board meets the footer */
    margin: clamp(72px, 12vh, 124px) 0 -48px;
    padding: 76px 28px 84px;
    border-image: radial-gradient(120% 120% at 50% 0%, var(--spruce) 0%, var(--pine) 50%, var(--forest) 100%) fill 0 // 0 100vw;
    text-align: center;
}
.believe-back .believe-fillet {
    inset: 24px 0;
}
.believe-back-mark {
    width: 64px;
    height: 64px;
}
.believe p.believe-colophon {
    max-width: 34em;
    margin: 0;
    color: var(--sand);
    text-wrap: balance;
}

/* where motion is welcome: the cover starts shut with its gilt undrawn and
   its title unset, and the two scenes that hold still while they play get the
   scroll they are read across */
html.believe-js .believe-opening {
    --turn: 0;
    align-items: start;
    height: calc(200svh - var(--believe-head));
}
html.believe-js .believe-book {
    position: sticky;
    top: calc(var(--believe-head) + max(16px, (100svh - var(--believe-head) - var(--believe-book-h)) / 2));
}
html.believe-js .believe-cover {
    will-change: transform;
}
html.believe-js .believe-cover-face .believe-fillet i:nth-child(odd) {
    transform: scaleX(0);
}
html.believe-js .believe-cover-face .believe-fillet i:nth-child(even) {
    transform: scaleY(0);
}
html.believe-js .believe-cover-word {
    opacity: 0;
    letter-spacing: 0.08em;
    transform: translateY(-0.35em);
}
html.believe-js .believe-cover-face .believe-ornament,
html.believe-js .believe-cover-sub,
html.believe-js .believe-cover-imprint {
    opacity: 0;
}
html.believe-js .believe-stage {
    height: 220svh;
}
html.believe-js .believe-stage-frame {
    position: sticky;
    top: var(--believe-head);
    height: calc(100svh - var(--believe-head));
}
/* the night rises as a layer clipped at its own top edge while what it holds
   is moved back down by as much, so the words stand still as the dark passes */
html.believe-js .believe-stage-night {
    overflow-x: visible;
    overflow-y: clip;
}
/* what the scroll moves gets a layer of its own, so a scrubbed scene is
   composited frame by frame instead of repainted */
html.believe-js .believe-field,
html.believe-js .believe-shade,
html.believe-js .believe-vellum {
    will-change: opacity;
}
html.believe-js .believe-stage-night,
html.believe-js .believe-stage-night > *,
html.believe-js .believe-vellum i,
html.believe-js .believe-copybook,
html.believe-js .believe-ruling,
html.believe-js .believe-margin-line,
html.believe-js .believe-folio > span::after {
    will-change: transform;
}
@media (min-width: 900px) {
    html.believe-js .believe-book {
        will-change: transform;
    }
}

@media (prefers-reduced-motion: reduce) {
    .believe-spine,
    .believe-contents a {
        transition: none;
    }
    .believe-spine:hover,
    .believe-spine:focus-visible {
        transform: none;
    }
}

/* on paper the book prints as its text: no cloth, no night, no shelf */
@media print {
    .believe-cover,
    .believe-field,
    .believe-folio,
    .believe-stage-night,
    .believe-stage-day .believe-askers,
    .believe-vellum,
    .believe-ruling,
    .believe-shelf {
        display: none !important;
    }
    .believe-opening,
    .believe-stage,
    .believe-stage-frame {
        height: auto !important;
        min-height: 0 !important;
    }
    .believe-book {
        position: static !important;
        min-height: 0;
        transform: none !important;
    }
    .believe-opening,
    .believe-back {
        border-image: none;
    }
    .believe p.believe-colophon {
        color: var(--muted);
    }
}

/* The blog: the legacy reader, carried over declaration by declaration from
   `styles/globals.css` 6189–6430. Where that stylesheet named tokens of its
   own, the approved equivalents stand in — brass is --sun, and the UI face is
   --ff — and every value the component set for itself is kept as written.

   The page paints itself rather than the body, because it sits inside this
   build's shell: the hero and the column are its own, and the header, the
   drawer and the footer around them are the site's. It stands in .app-main's
   own padding, the gutter every community page keeps; the bottom margin
   gives back the shell's foot padding so the paper meets the footer. The
   legacy's `min-height: 100vh` is not carried: it made a short blog page fill
   the screen, which the shell already does with `min-height: 100dvh` on the
   body and `flex: 1` on .app-main. Stating it again here would count the
   header and the footer twice and put a scrollbar under every post. */
.public-blog-page {
    position: relative;
    z-index: 1;
    margin: 0 0 -48px;
    background: var(--paper);
    color: var(--bark);
    font-family: var(--ff);
    line-height: 1.6;
}

/* The page frame the community pages set, shared: the 1100px column the
   shell widens for them, its 16px gutter, the head 36px under the column's
   top (40px on a wide screen), and text hung on the column's left edge in a
   660px column rather than centred in a narrower one. */
.app-main:has(> .public-blog-page),
.app-main:has(> .believe) {
    max-width: 1100px;
}

.public-blog-hero {
    overflow: hidden;
    padding: 36px 0 0;
    position: relative;
}

.public-blog-hero.center {
    text-align: left;
}

.public-blog-hero-inner,
.public-blog-main {
    margin: 0;
    max-width: 660px;
}

.public-blog-main {
    padding: 48px 0;
}

@media (min-width: 1440px) {
    .public-blog-hero {
        padding-top: 40px;
    }
}

/* the hero's text stands on the column's own content box, so a post's
   crumbs, title and date share one left edge with its body */
.public-blog-hero-inner {
    max-width: 660px;
}

.public-blog-kicker {
    color: var(--sun);
    font-family: var(--ff);
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: 0.26em;
    margin: 0 0 16px;
    text-transform: uppercase;
}

.public-blog-title {
    color: var(--bark);
    font-family: var(--ff-display);
    font-size: clamp(38px, 6vw, 58px);
    font-weight: 400;
    letter-spacing: -0.005em;
    line-height: 1.06;
    margin: 0 0 8px;
}

.public-blog-subtitle {
    color: var(--muted);
    font-family: var(--ff-text);
    font-size: clamp(16px, 1.4vw, 18px);
    line-height: 1.7;
    margin: 0;
}

/* the gold rule that closes the index's hero, and only the index's */
.public-blog-hero.center .public-blog-subtitle::after {
    background: var(--sun);
    content: "";
    display: block;
    height: 1px;
    margin: clamp(28px, 4vh, 40px) 0 0;
    opacity: 0.5;
    width: 64px;
}

.public-blog-list-item {
    border-bottom: 1px solid var(--border-light);
    margin-bottom: 32px;
    padding-bottom: 32px;
}

/* the offer card's own border closes the list, so the last entry draws no
   second rule a card's width above it */
.public-blog-list-item:last-of-type {
    border-bottom: 0;
}

.public-blog-post-link {
    display: block;
    text-decoration: none;
}

.public-blog-post-link h2 {
    color: var(--bark);
    font-family: var(--ff-display);
    font-size: clamp(21px, 2.6vw, 26px);
    font-weight: 400;
    line-height: 1.25;
    margin: 0 0 4px;
    text-wrap: balance;
    transition: color 140ms ease;
}

.public-blog-post-link:hover h2,
.public-blog-post-link:focus-visible h2 {
    color: var(--sun);
}

/* the blog's links take the ring the rest of the site's actions wear; the
   ring follows each link's own corners, so the gold button keeps its 5px */
.public-blog-page a:focus-visible {
    outline: 2px solid var(--sun);
    outline-offset: 3px;
}

.public-blog-post-meta {
    color: var(--muted-soft);
    font-family: var(--ff-text);
    font-size: 13px;
    font-style: italic;
    margin: 0 0 8px;
}

.public-blog-post-meta.no-margin {
    font-size: 13px;
    margin: 0;
}

.public-blog-post-description {
    color: var(--muted);
    font-size: 15px;
    line-height: 1.6;
    margin: 0;
    max-width: 58ch;
    text-wrap: pretty;
}

.public-blog-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 10px;
}

.public-blog-tags span {
    border: 1px solid rgba(156, 122, 51, 0.4);
    border-radius: 999px;
    color: var(--sun);
    font-family: var(--ff);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.08em;
    padding: 3px 9px;
    text-transform: uppercase;
}

.public-blog-cta {
    background: var(--sun-pale);
    border: 1px solid var(--border);
    border-radius: 10px;
    margin-top: 32px;
    padding: clamp(32px, 5vh, 48px) 32px;
    text-align: center;
}

/* under a post the offer stands further off, where the reading ended, and
   holds the button alone, so it takes the card's shallow padding at every
   height rather than a slab that grows with the window */
.public-blog-cta.post {
    margin-top: 96px;
    padding-block: 32px;
}

.public-blog-cta-title {
    color: var(--bark);
    font-family: var(--ff-display);
    font-size: clamp(22px, 3vw, 28px);
    font-weight: 400;
    margin: 0 0 8px;
    text-wrap: balance;
}

.public-blog-cta-copy {
    color: var(--muted);
    font-family: var(--ff-text);
    font-size: 15px;
    margin: 0 0 20px;
    text-wrap: balance;
}

.public-blog-cta-button {
    background: linear-gradient(135deg, var(--gold-light) 0%, var(--gold) 55%, var(--gold-deep) 100%);
    border-radius: 5px;
    box-shadow: 0 10px 24px rgba(194, 154, 69, 0.24);
    color: var(--ink);
    display: inline-block;
    font-family: var(--ff);
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.08em;
    padding: 15px 30px;
    text-decoration: none;
    text-transform: uppercase;
}

.public-blog-cta-button.large {
    padding: 12px 32px;
}

/* the gold action keeps its dark ink under the pointer: the shell's link
   hover would otherwise turn the label green on gold. The flat gold is the
   supporter ledger's own gilded hover, so the site's gold actions answer
   alike, and pressed sinks the same way. */
.public-blog-cta-button:hover,
.public-blog-cta-button:focus-visible {
    background: var(--gold);
    color: var(--ink);
}

.public-blog-cta-button:active {
    box-shadow: inset 0 2px 4px var(--shadow-md);
}

.public-blog-footer-note {
    color: var(--muted-soft);
    font-family: var(--ff-text);
    font-size: 13px;
    font-style: italic;
    margin-top: 48px;
    text-align: center;
}

.public-blog-footer-note.post {
    padding-bottom: 32px;
}

.public-blog-breadcrumbs {
    color: var(--muted-soft);
    font-size: 12px;
    margin-bottom: 24px;
}

.public-blog-breadcrumbs a {
    color: var(--muted-soft);
    text-decoration: none;
}

.public-blog-breadcrumbs a:hover {
    color: var(--bark);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.public-blog-breadcrumbs span {
    color: var(--bark);
}

/* on a phone the crumbs and each entry's title are what a thumb reaches for:
   the crumbs' air and the title's own padding widen each to a touch-sized
   target, and the title's negative margin gives its padding back, so no line
   of the page moves */
@media (max-width: 767px) {
    .public-blog-breadcrumbs a {
        margin-inline: -10px;
        padding: 15px 10px;
    }
    .public-blog-post-link {
        margin-block: -9px;
        padding-block: 9px;
    }
}

.public-blog-post-title {
    color: var(--bark);
    font-family: var(--ff-display);
    font-size: clamp(30px, 4.6vw, 44px);
    font-weight: 400;
    letter-spacing: -0.005em;
    line-height: 1.12;
    margin: 0 0 10px;
    text-wrap: balance;
}

/* the post itself: the reading face at the measure the legacy set, and the
   elements a post body may style. The legacy sheet also styled a blockquote;
   that rule is not carried, because the allowed-content boundary drops the
   element and a rule nothing can match is dead style. */
.public-blog-body {
    color: var(--bark);
    font-family: var(--ff-text);
    font-size: 16.5px;
    line-height: 1.8;
    max-width: 58ch;
}

.public-blog-body h2,
.public-blog-body h3 {
    font-family: var(--ff-display);
    font-weight: 400;
    line-height: 1.2;
    margin: 1.6em 0 0.5em;
    text-wrap: balance;
}

/* a post's first line sits as far under its date as the index's first
   entry sits under the hero: the column's own 48px, with no paragraph
   margin stacked on it */
.public-blog-body > :first-child {
    margin-top: 0;
}

.public-blog-body p {
    text-wrap: pretty;
}

/* list markers hang inside a phone-width column rather than taking the
   browser's 40px indent out of it */
.public-blog-body ul,
.public-blog-body ol {
    padding-left: 1.4em;
}

.public-blog-body a {
    color: var(--sun);
}

.public-blog-body a:hover {
    color: var(--bark);
}

/* The living blog. The index and each post are staged as four worlds a
   reader passes through on the way down:

   - the title page, on the house paper: the page head the legacy set and,
     facing it on a wide screen, the frontispiece, the house botanical tipped
     in on its own ruled stock;
   - the letters, on a lighter sheet laid over the title page, which lies
     back and falls into shade as the sheet comes over it;
   - dusk, the pine endpaper where the offer lies between two shelves of the
     library, under the house bird and a lamp. Its head is a horizon: a gold
     rule with the last of the day's light over it, which sets as dusk rises
     into the window. Its foot is the same rule with the dawn under it, and
   - the colophon, back on paper.

   The rules from here to the motion below are the page at rest: complete
   and still, which is what a reader who asked for less motion gets, and what
   a browser without scroll timelines gets. Motion comes in two layers, each
   behind its own guard: a short entrance as the page opens, on the clock, so
   every browser plays it, and the scroll story, on scroll timelines, which
   the browser runs as the reader scrolls without any script. Nothing the
   legacy parity gate pins is animated: the head is still at rest on its
   frame's left edge whenever it is read, and every pinned colour, size and
   space holds from the first frame. What moves on the scroll is transform
   and opacity, which the browser composites without repainting: every rule
   is drawn by a scale, never by its size, so no scroll frame paints.

   The full-bleed grounds are border images painted past the column on both
   sides. They are ink overflow, like a shadow, so no window can scroll
   sideways to them, and the column keeps the shell's frame and its measure.

   Stacking, inside the page: the title page 0, the sheet and the plate 1,
   dusk and the colophon 3. */
.public-blog-page {
    --blog-ease: cubic-bezier(0.22, 1, 0.36, 1);
    --blog-sheet-edge: color-mix(in srgb, var(--gold) 55%, var(--parchment-top));
}

.blog-spread {
    display: flex;
    flex-direction: column;
}

.blog-spread > .public-blog-hero {
    z-index: 0;
}

/* the sheet's own stock, its gold edge, and the shade it casts on the page
   beneath: a band 22px deep above the edge. The foot keeps room for dusk's
   feathered edge to fall across without reaching a word. */
.blog-leaf {
    position: relative;
    z-index: 1;
    margin-top: clamp(40px, 6vh, 64px);
    border-image: linear-gradient(180deg,
            transparent,
            color-mix(in srgb, var(--bark) 8%, transparent) 22px,
            var(--blog-sheet-edge) 22px,
            var(--blog-sheet-edge) 23px,
            var(--parchment-top) 23px,
            var(--parchment-bottom)) 0 fill / 0 / 22px 100vw 0;
}

/* the last letter closes on the sheet's own air, not a second margin */
.blog-leaf .public-blog-list-item:last-of-type {
    margin-bottom: 0;
}

/* the empty sheet: what the letters will be, and where to read meanwhile */
.blog-empty-title {
    margin: 0 0 8px;
    color: var(--bark);
    font-family: var(--ff-display);
    font-size: clamp(21px, 2.6vw, 26px);
    line-height: 1.25;
    text-wrap: balance;
}
.blog-empty-copy {
    max-width: 58ch;
    margin: 0 0 18px;
    color: var(--muted);
    font-family: var(--ff-text);
    font-size: 15px;
    line-height: 1.7;
    text-wrap: pretty;
}
.blog-empty-link {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    color: var(--leaf);
    font-size: 14px;
    font-weight: 600;
    text-decoration: underline;
    text-decoration-color: color-mix(in srgb, var(--leaf) 40%, transparent);
    text-underline-offset: 4px;
}
.blog-empty-link:hover {
    text-decoration-color: currentColor;
}

/* a post's first letter set as a book sets it, two lines deep */
.public-blog-body > p:first-child::first-letter {
    float: left;
    margin: 0.08em 0.12em 0 0;
    color: var(--sun);
    font-family: var(--ff-display);
    font-size: 3.6em;
    line-height: 0.8;
}
@supports (initial-letter: 2) {
    .public-blog-body > p:first-child::first-letter {
        float: none;
        margin: 0 0.14em 0 0;
        font-size: inherit;
        line-height: inherit;
        initial-letter: 2;
    }
}

/* a post's description, set under its title as the deck */
.public-blog-subtitle.blog-deck {
    margin: 0 0 12px;
    max-width: 36em;
    text-wrap: pretty;
}

/* The frontispiece. On a phone it is the tailpiece, closing the sheet; on a
   wide screen it faces the title page (below). It follows the sheet in the
   markup, so it lies over the sheet and the title page at the one depth. */
.blog-margin {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 20px;
    padding: 8px 0 80px;
    border-image: linear-gradient(var(--parchment-bottom), var(--parchment-bottom)) 0 fill / 0 / 0 100vw;
}

.blog-plate {
    position: relative;
    width: min(60%, 208px);
    aspect-ratio: 4 / 5;
    background: linear-gradient(168deg, var(--parchment-top), var(--parchment-bottom));
    border: 1px solid var(--border);
    box-shadow:
        0 24px 44px -28px color-mix(in srgb, var(--bark) 50%, transparent),
        0 2px 6px var(--shadow-soft);
}

/* the plate's inner rule in two strokes, so each can be drawn by a scale
   alone: the head and the foot, then the two sides */
.blog-plate::before,
.blog-plate::after {
    content: "";
    position: absolute;
    z-index: 1;
    inset: 10px;
    pointer-events: none;
    border: 0 solid color-mix(in srgb, var(--sun) 55%, transparent);
}
.blog-plate::before {
    border-width: 1px 0;
}
.blog-plate::after {
    border-width: 0 1px;
    transform-origin: top;
}

/* the sprig stands the plate's full height inside its mount: the image is
   square and the plate upright, so the cover fit trims only the clear
   margins at its sides */
.blog-plate img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    padding: 12%;
    object-fit: cover;
}

/* a post's folio: a gold rule under the plate. Where the browser keeps
   scroll timelines it is the reader's place in the letter, the gold filling
   along a fainter track; elsewhere it stands full. */
.blog-folio {
    position: relative;
    display: block;
    width: min(60%, 208px);
    height: 2px;
    background: color-mix(in srgb, var(--sun) 28%, transparent);
}
.blog-folio::before {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--gold);
    transform-origin: left;
}

@media (min-width: 1000px) {
    /* The title page and its frontispiece as a spread: the page head and the
       sheet on the column's own edge, and the plate on the house paper at
       the frame's right edge, standing beside the reader through the letters
       until dusk takes the page. The sheet is laid in from the left, so its
       right edge shows: a gold hairline and the shade it casts. */
    .blog-spread {
        display: grid;
        grid-template-columns: minmax(0, 660px) minmax(0, 1fr);
        column-gap: clamp(40px, 6vw, 108px);
        align-items: start;
    }
    .blog-spread > .public-blog-hero {
        grid-column: 1;
        grid-row: 1;
    }
    .blog-leaf {
        grid-column: 1;
        grid-row: 2;
        /* the sheet runs to the spread's foot, however short the letter, so
           the title page it covers never shows beneath it */
        align-self: stretch;
        padding-bottom: 24px;
        border-image-outset: 22px 0 0 100vw;
        box-shadow:
            1px 0 0 var(--blog-sheet-edge),
            22px 0 30px -22px color-mix(in srgb, var(--bark) 26%, transparent);
    }
    .blog-margin {
        position: sticky;
        top: calc(101px + env(safe-area-inset-top, 0px));
        grid-column: 2;
        grid-row: 1 / span 2;
        justify-self: end;
        align-items: stretch;
        gap: 18px;
        width: min(100%, 360px);
        margin: 36px 0 88px;
        padding: 0;
        border-image: none;
    }
    .blog-plate,
    .blog-folio {
        width: 100%;
    }
}
@media (min-width: 1440px) {
    .blog-margin {
        margin-top: 40px;
    }
}

/* Dusk: a world of its own, nearly a screen tall. The pine endpaper, under
   a gold horizon, darkest where the sheet above shades it, lit from below by
   a lamp over the offer, with the shelves of the library along its head and
   its foot, and the dawn's gold rule under it. */
.blog-dusk {
    position: relative;
    z-index: 3;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 40px;
    min-height: min(calc(88svh - 69px - env(safe-area-inset-top, 0px)), 820px);
    padding: clamp(40px, 7vh, 72px) 0 clamp(28px, 5vh, 52px);
    text-align: center;
    border-image: linear-gradient(180deg,
            color-mix(in srgb, var(--ink) 70%, var(--forest)),
            var(--forest) 64px,
            var(--pine) 45%,
            var(--spruce) calc(100% - 49px),
            var(--gold) calc(100% - 49px),
            var(--gold) calc(100% - 48px),
            color-mix(in srgb, var(--gold-warm) 30%, transparent) calc(100% - 48px),
            transparent) 0 fill / 0 / 0 100vw 48px;
}
/* the last of the day's light, on the paper above the horizon: it stands
   full at rest and on the way up, and sets as dusk rises (below) */
.blog-dusk::after {
    content: "";
    position: absolute;
    right: 0;
    bottom: 100%;
    left: 0;
    height: clamp(120px, 20vh, 200px);
    pointer-events: none;
    background: radial-gradient(70% 100% at 50% 100%,
            color-mix(in srgb, var(--gold-light) 70%, transparent),
            color-mix(in srgb, var(--gold-warm) 30%, transparent) 45%,
            transparent 100%);
    transform-origin: 50% 100%;
}
.blog-dusk::before {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background:
        radial-gradient(30% 24% at 50% 62%, color-mix(in srgb, var(--gold) 18%, transparent), transparent 72%),
        radial-gradient(60% 50% at 50% 58%, color-mix(in srgb, var(--moss) 90%, transparent), transparent 74%);
}
.blog-dusk > * {
    position: relative;
}

/* the horizon: one gold rule across the whole window, painted past the
   column the way the grounds are, as ink overflow */
.blog-dusk > .blog-horizon {
    position: absolute;
    top: 0;
    right: 0;
    left: 0;
    height: 1px;
    pointer-events: none;
    border-image: linear-gradient(var(--gold), var(--gold)) 0 fill / 0 / 0 100vw;
}

/* the shelves: the homepage's own friezes of names and titles */
.blog-shelf {
    overflow: hidden;
    -webkit-mask-image: linear-gradient(90deg, transparent, black 24%, black 76%, transparent);
    mask-image: linear-gradient(90deg, transparent, black 24%, black 76%, transparent);
}
.blog-shelf-track {
    display: flex;
    width: max-content;
    margin: 0;
    color: color-mix(in srgb, var(--gold-warm) 50%, transparent);
    font-family: var(--ff);
    font-size: clamp(12px, 1.3vw, 15px);
    font-weight: 600;
    letter-spacing: 0.24em;
    line-height: 1.6;
    text-transform: uppercase;
    white-space: nowrap;
}
.blog-shelf-track span::after {
    content: "✦";
    margin: 0 1.4em;
    color: var(--gold);
    font-size: 0.7em;
    opacity: 0.6;
}
.blog-shelf.titles .blog-shelf-track {
    color: color-mix(in srgb, var(--gold-warm) 66%, transparent);
    font-family: var(--ff-text);
    font-size: clamp(15px, 1.5vw, 19px);
    font-style: italic;
    font-weight: 400;
    letter-spacing: 0;
    text-transform: none;
}
.blog-shelf.titles .blog-shelf-track span::after {
    content: "·";
    margin: 0 0.9em;
    font-size: 1em;
}

/* the desk: the bird, and the offer hung from it */
.blog-desk {
    position: relative;
    padding: 0 0 8px;
}
/* the gold cord the offer hangs from, across the gap under the bird, from
   the bird's own feet */
.blog-desk::before {
    content: "";
    position: absolute;
    top: 80px;
    left: calc(50% - 0.5px);
    width: 1px;
    height: 104px;
    background: linear-gradient(180deg, color-mix(in srgb, var(--gold) 10%, transparent), var(--gold));
    transform-origin: top;
}
.blog-desk:has(.public-blog-cta.post)::before {
    height: 136px;
}
.blog-dusk-mark {
    display: block;
    width: 88px;
    height: 88px;
    /* collapses with the offer's own margin: the larger one is the gap, and
       the gold cord hangs across it */
    margin: 0 auto 96px;
    /* the lamp's glow behind the bird, painted as the image's own ground
       rather than a filter, so it costs nothing to scroll over */
    background: radial-gradient(closest-side, color-mix(in srgb, var(--gold) 30%, transparent), transparent);
}

/* the offer lies on the desk under the lamp, hung from the bird on a gold
   cord and ruled inside in gilt */
.blog-dusk .public-blog-cta {
    position: relative;
    max-width: 560px;
    margin-inline: auto;
    box-shadow: 0 30px 60px -30px color-mix(in srgb, var(--ink) 85%, transparent);
}
/* under a post the offer is the button alone, so it hangs lower: the
   bird's margin outweighs the card's pinned 96px and is the gap */
.blog-dusk-mark:has(+ .public-blog-cta.post) {
    margin-bottom: 128px;
}
/* the gilt rule inside the card, in two strokes: the head and the foot,
   drawn out from the cord's point, then the sides */
.blog-dusk .public-blog-cta::before,
.blog-dusk .public-blog-cta::after {
    content: "";
    position: absolute;
    inset: 7px;
    pointer-events: none;
    border: 0 solid color-mix(in srgb, var(--gold) 70%, transparent);
}
.blog-dusk .public-blog-cta::before {
    border-width: 1px 0;
}
.blog-dusk .public-blog-cta::after {
    border-width: 0 1px;
    transform-origin: top;
}
/* the gold button carries a glint that crosses it once, at the lamp, under
   its label: the button isolates a stack of its own, so the glint lies over
   the gilt and beneath the words */
.blog-dusk .public-blog-cta-button {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    vertical-align: top;
}
.blog-dusk .public-blog-cta-button::after {
    content: "";
    position: absolute;
    z-index: -1;
    top: -20%;
    bottom: -20%;
    left: 0;
    width: 40%;
    pointer-events: none;
    background: linear-gradient(100deg, transparent,
            color-mix(in srgb, var(--parchment-top) 60%, transparent) 50%, transparent);
    transform: translateX(-180%) skewX(-18deg);
}

/* The colophon: back on the house paper, under a short rule. */
.blog-dusk + .public-blog-footer-note {
    position: relative;
    z-index: 3;
    margin-bottom: 48px;
}
.blog-dusk + .public-blog-footer-note.post {
    margin-bottom: 16px;
}
.blog-dusk + .public-blog-footer-note::before {
    content: "";
    display: block;
    width: 40px;
    height: 1px;
    margin: 0 auto 18px;
    background: color-mix(in srgb, var(--sun) 55%, transparent);
}

/* The entrance, on the clock: the head is set and its rule drawn, and on a
   wide screen the frontispiece is pulled, ruled and developed beside it.
   Each holds its first frame through its delay and lets go when done, so
   nothing stays on a layer of its own once the page is open. */
@media (prefers-reduced-motion: no-preference) {
    .public-blog-kicker,
    .public-blog-breadcrumbs {
        animation: blog-rise 0.7s var(--blog-ease) 0.05s backwards;
    }
    /* the index's one-word title settles from loose spacing to set, as type
       does in the stick; a post's longer title would rewrap on the way, so it
       comes up out of the ink instead */
    .public-blog-title {
        animation: blog-set 1.2s var(--blog-ease) 0.1s backwards;
    }
    .public-blog-post-title {
        animation: blog-ink 1s var(--blog-ease) 0.12s backwards;
    }
    .public-blog-hero .public-blog-subtitle {
        animation: blog-rise 0.8s var(--blog-ease) 0.3s backwards;
    }
    .public-blog-hero .public-blog-post-meta {
        animation: blog-rise 0.8s var(--blog-ease) 0.42s backwards;
    }
    .public-blog-hero.center .public-blog-subtitle::after {
        transform-origin: left;
        animation: blog-draw 0.9s var(--blog-ease) 0.7s backwards;
    }
    @media (min-width: 1000px) {
        .blog-plate {
            animation: blog-plate 1s var(--blog-ease) 0.2s backwards;
        }
        .blog-plate::before {
            animation: blog-draw 0.8s var(--blog-ease) 0.6s backwards;
        }
        .blog-plate::after {
            animation: blog-drop 0.8s var(--blog-ease) 1.1s backwards;
        }
        .blog-plate img {
            animation: blog-develop 1.8s var(--blog-ease) 0.7s backwards;
        }
    }
}

/* The scroll story, where the browser runs animations on scroll timelines.
   Every reveal completes by the time its element has wholly entered the
   window, a point the page can always scroll to, so nothing is left half
   shown at the page's end; scrolling back plays it back. */
@supports (animation-timeline: view()) {
    /* a post's folio is the reader's place in the letter: the share of the
       sheet that has passed up under the header, so it stands empty when the
       letter opens, however short, and full once the whole letter is behind
       the reader. That is information, not motion, so it fills whatever the
       motion setting. On a phone it rides under the header, the gold alone. */
    .blog-spread {
        timeline-scope: --blog-letter;
    }
    .blog-leaf {
        view-timeline: --blog-letter block;
        view-timeline-inset: calc(69px + env(safe-area-inset-top, 0px)) 0px;
    }
    .blog-folio::before {
        animation: blog-draw linear both;
        animation-timeline: --blog-letter;
        animation-range: exit-crossing 0% exit-crossing 100%;
    }
    @media (max-width: 999px) {
        .blog-folio {
            position: fixed;
            top: calc(69px + env(safe-area-inset-top, 0px));
            left: 0;
            width: 100%;
            background: none;
        }
    }

    @media (prefers-reduced-motion: no-preference) {
        .public-blog-list-item {
            view-timeline: --blog-entry block;
        }
        .blog-plate {
            view-timeline: --blog-plate block;
        }
        .blog-dusk {
            view-timeline: --blog-dusk block;
        }
        .blog-desk {
            view-timeline: --blog-desk block;
        }
        .blog-dusk .public-blog-cta {
            view-timeline: --blog-offer block;
        }
        .blog-dusk + .public-blog-footer-note {
            view-timeline: --blog-colophon block;
        }

        /* the title page lies back and falls into shade as the sheet comes
           over it: pinned under the header, where a window has the height
           to hold it, so the reader watches it go. Every word of it was on
           the first screen before any of this began. */
        .blog-spread > .public-blog-hero {
            transform-origin: 50% 100%;
            animation: blog-recede linear both;
            animation-timeline: scroll(root);
            animation-range: 0 40vh;
        }
        @media (min-height: 640px) {
            .blog-spread > .public-blog-hero {
                position: sticky;
                top: calc(69px + env(safe-area-inset-top, 0px));
            }
        }
        /* a keyboard reader who comes back to the crumbs finds the title
           page standing whole in its own place at the head of the page, not
           pinned in shade under the sheet */
        .blog-spread > .public-blog-hero:has(:focus-visible) {
            position: relative;
            top: auto;
            animation: none;
        }

        /* the horizon is ruled from the middle outward as it comes up the
           window, and the light over it sets as dusk rises */
        .blog-dusk > .blog-horizon {
            animation: blog-horizon linear both;
            animation-timeline: --blog-dusk;
            animation-range: entry 0% entry 35%;
        }
        .blog-dusk::after {
            animation: blog-sunset linear both;
            animation-timeline: --blog-dusk;
            animation-range: entry 55% entry 100%;
        }

        /* each letter's title rises out of its line as the reader reaches
           it, its note and tags follow as they arrive, and the rule under it
           is drawn once the whole letter is in view */
        .blog-leaf .public-blog-post-link h2 {
            animation: blog-set-line linear both;
            animation-timeline: view();
            animation-range: entry 10% entry 100%;
        }
        .blog-leaf .public-blog-list-item > :not(.public-blog-post-link) {
            animation: blog-rise linear both;
            animation-timeline: view();
            animation-range: entry 30% entry 100%;
        }
        .blog-leaf .public-blog-list-item {
            position: relative;
            border-bottom-color: transparent;
        }
        .blog-leaf .public-blog-list-item::after {
            content: "";
            position: absolute;
            right: 0;
            bottom: -1px;
            left: 0;
            height: 1px;
            background: var(--border-light);
            transform-origin: left;
            animation: blog-draw linear both;
            animation-timeline: --blog-entry;
            animation-range: entry 50% entry 100%;
        }
        .blog-leaf .public-blog-list-item:last-of-type::after {
            content: none;
        }

        /* on a phone the tailpiece is pulled, ruled and developed as it
           comes up the sheet */
        @media (max-width: 999px) {
            .blog-plate {
                animation: blog-plate linear both;
                animation-timeline: --blog-plate;
                animation-range: entry 0% entry 70%;
            }
            .blog-plate::before {
                animation: blog-draw linear both;
                animation-timeline: --blog-plate;
                animation-range: entry 30% entry 65%;
            }
            .blog-plate::after {
                animation: blog-drop linear both;
                animation-timeline: --blog-plate;
                animation-range: entry 60% entry 100%;
            }
            .blog-plate img {
                animation: blog-develop linear both;
                animation-timeline: --blog-plate;
                animation-range: entry 20% entry 100%;
            }
        }

        /* dusk: the lamp comes up, the two shelves run past each other, the
           bird alights, the cord drops, the gilt is ruled round the offer,
           and the light crosses the gold once */
        .blog-dusk::before {
            animation: blog-lamp linear both;
            animation-timeline: --blog-dusk;
            animation-range: entry 20% entry 90%;
        }
        .blog-shelf-track {
            animation: blog-shelf linear both;
            animation-timeline: --blog-dusk;
            animation-range: cover 0% cover 100%;
        }
        .blog-shelf.titles .blog-shelf-track {
            animation-name: blog-shelf-back;
        }
        .blog-dusk-mark {
            animation: blog-alight linear both;
            animation-timeline: --blog-dusk;
            animation-range: entry 30% entry 70%;
        }
        .blog-desk::before {
            animation: blog-drop linear both;
            animation-timeline: --blog-desk;
            animation-range: entry 25% entry 60%;
        }
        .blog-dusk .public-blog-cta::before {
            animation: blog-draw linear both;
            animation-timeline: --blog-offer;
            animation-range: entry 35% entry 70%;
        }
        .blog-dusk .public-blog-cta::after {
            animation: blog-drop linear both;
            animation-timeline: --blog-offer;
            animation-range: entry 65% entry 100%;
        }
        .blog-dusk .public-blog-cta-button::after {
            animation: blog-glint linear both;
            animation-timeline: --blog-offer;
            animation-range: contain 0% contain 30%;
        }

        .blog-dusk + .public-blog-footer-note::before {
            transform-origin: center;
            animation: blog-draw linear both;
            animation-timeline: --blog-colophon;
            animation-range: entry 0% entry 100%;
        }
    }
}

@keyframes blog-rise {
    from {
        opacity: 0;
        transform: translateY(10px);
    }
}
@keyframes blog-set {
    from {
        opacity: 0;
        letter-spacing: 0.34em;
        filter: blur(4px);
    }
}
@keyframes blog-ink {
    from {
        opacity: 0;
        transform: translateY(0.3em);
        filter: blur(3px);
    }
}
@keyframes blog-draw {
    from {
        transform: scaleX(0);
    }
}
@keyframes blog-plate {
    from {
        opacity: 0;
        transform: translateY(18px) rotate(-2.5deg);
    }
}
@keyframes blog-develop {
    from {
        opacity: 0.1;
        filter: sepia(1) brightness(1.3) contrast(0.55) blur(1.5px);
    }
}
@keyframes blog-recede {
    to {
        opacity: 0.3;
        transform: perspective(700px) translateY(16vh) rotateX(28deg) scale(0.9);
    }
}
@keyframes blog-horizon {
    from {
        transform: scaleX(0);
    }
}
@keyframes blog-sunset {
    to {
        opacity: 0;
        transform: scaleY(0.25);
    }
}
@keyframes blog-set-line {
    from {
        opacity: 0;
        transform: translateY(0.6em);
    }
}
@keyframes blog-lamp {
    from {
        opacity: 0.1;
    }
}
@keyframes blog-shelf {
    from {
        transform: translateX(0);
    }
    to {
        transform: translateX(-30%);
    }
}
@keyframes blog-shelf-back {
    from {
        transform: translateX(-30%);
    }
    to {
        transform: translateX(0);
    }
}
@keyframes blog-alight {
    from {
        opacity: 0;
        transform: translateY(-28px) scale(0.82);
    }
}
@keyframes blog-drop {
    from {
        transform: scaleY(0);
    }
}
@keyframes blog-glint {
    from {
        transform: translateX(-180%) skewX(-18deg);
    }
    to {
        transform: translateX(360%) skewX(-18deg);
    }
}

/* a printed post is the text: every world at rest and on plain paper, the
   plate, the shelves and the bird left off */
@media print {
    .public-blog-page *,
    .public-blog-page *::before,
    .public-blog-page *::after {
        animation: none !important;
    }
    .blog-dusk::after,
    .blog-horizon,
    .blog-margin,
    .blog-shelf,
    .blog-dusk-mark {
        display: none;
    }
    .blog-leaf,
    .blog-dusk {
        min-height: 0;
        border-image: none;
        box-shadow: none;
    }
}

/* The presets: one tap to a whole sheet, sitting above the settings the way a
   shelf of ready worksheets sits above the drawer you compose one in. Links,
   not buttons — each is an address that draws its sheet without scripting,
   and each wears the settings' own chip. The label takes a line of its own,
   as a legend does, so every row of chips starts on one edge. */
.drill-presets {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 1.5rem 0 0;
}

/* The drill settings: heritage chips a family taps to describe the practice,
   deliberately reading as one sentence of choices rather than a grid of
   cards. The real radio and checkbox stay under each chip, so the keyboard
   and a screen reader get the native control and its grouping. Each group
   wraps its chips on one gap, so the air between groups is the form's gap
   alone. */
.drill-settings {
    display: grid;
    gap: 1.5rem;
    margin: 1.5rem 0 0;
    padding: 1.5rem;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--cream);
    box-shadow: 0 2px 8px var(--shadow-soft);
}
.drill-settings fieldset {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    min-width: 0;
    margin: 0;
    padding: 0;
    border: 0;
}
.drill-settings legend,
.drill-presets-label {
    padding: 0;
    margin-bottom: 0.6rem;
    color: var(--sun);
    font-family: var(--ff);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}
/* the row gap already stands under the label, so it keeps only the rest of
   a legend's margin */
.drill-presets-label {
    flex-basis: 100%;
    margin-bottom: 0.1rem;
}
.drill-settings fieldset > label,
.drill-presets a {
    display: inline-flex;
    flex-direction: column;
    justify-content: center;
    gap: 0.15rem;
    min-height: 44px;
    padding: 0.5rem 0.95rem;
    border: 1px solid var(--border);
    border-radius: 1.1rem;
    background: var(--field);
    cursor: pointer;
    transition: border-color 150ms ease, background-color 150ms ease, color 150ms ease;
}
.drill-settings fieldset > label:hover,
.drill-presets a:hover {
    border-color: var(--leaf);
    background: var(--leaf-pale);
}
.drill-presets a {
    color: var(--bark);
    font-size: 0.875rem;
    text-decoration: none;
}
/* the preset the current settings match, so a tapped one stays named */
.drill-presets a.active {
    border-color: var(--sun);
    background: var(--sun-pale);
}
.drill-presets a:focus-visible {
    outline: 2px solid var(--sun);
    outline-offset: 2px;
}
.drill-settings input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}
.drill-settings .choice-name {
    color: var(--bark);
    font-family: var(--ff-display);
    font-size: 1.125rem;
    line-height: 1.35;
}
.drill-settings .choice-symbol {
    color: var(--sun);
}
.drill-settings .choice-note {
    color: var(--muted);
    font-size: 0.875rem;
    line-height: 1.45;
}
/* the practice note closes its group on a line of its own */
.drill-settings p.choice-note {
    flex-basis: 100%;
    margin: 0.1rem 0 0;
}
/* the chosen chip fills in, so the current settings read at a glance */
.drill-settings label:has(input:checked) {
    border-color: var(--leaf);
    background: var(--leaf);
}
/* a practice chip toggles, so a chosen one still answers the pointer */
.drill-settings label:has(input:checked):hover {
    border-color: var(--leaf-light);
    background: var(--leaf-light);
}
.drill-settings label:has(input:checked) .choice-name,
.drill-settings label:has(input:checked) .choice-note,
.drill-settings label:has(input:checked) .choice-symbol {
    color: var(--paper);
}
.drill-settings label:has(input:focus-visible) {
    outline: 2px solid var(--sun);
    outline-offset: 2px;
}
.drill-settings .drill-length label,
.drill-settings .drill-practice label {
    flex-direction: row;
    align-items: center;
    gap: 0.4rem;
}

.drill-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.9rem;
    margin: 0;
}
.drill-actions button {
    min-height: 44px;
    padding: 0.5rem 1.4rem;
    border: 1px solid var(--leaf);
    border-radius: 1.1rem;
    background: var(--leaf);
    color: var(--paper);
    font-family: var(--ff);
    font-size: 1rem;
    font-weight: 600;
    cursor: pointer;
    transition: background-color 150ms ease, border-color 150ms ease;
}
.drill-actions button:hover {
    border-color: var(--leaf-light);
    background: var(--leaf-light);
}
.drill-actions button:focus-visible {
    outline: 2px solid var(--sun);
    outline-offset: 2px;
}

/* htmx shows the indicator only while a request is in flight */
.drill-working {
    color: var(--muted);
    font-size: 0.875rem;
    opacity: 0;
    transition: opacity 150ms ease;
}
.htmx-request .drill-working,
.htmx-request.drill-working {
    opacity: 1;
}

/* the drawn sheet is a leaf of exercise paper laid on the desk: parchment
   stock and the exercise book's oxblood margin rule, with the problem
   numbers hung between that rule and the work */
.drill-sheet,
.drill-leaf {
    position: relative;
    padding: 2rem 1.25rem 2.25rem 3.75rem;
    border: 1px solid var(--border);
    border-radius: 3px;
    background: linear-gradient(180deg, var(--parchment-top), var(--parchment-bottom));
    box-shadow: 0 1px 0 var(--border-light), 0 30px 54px -30px color-mix(in srgb, var(--ink) 85%, transparent);
    color: var(--bark);
}
.drill-sheet::before,
.drill-leaf::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 1.5rem;
    width: 1px;
    background: color-mix(in srgb, var(--ribbon-face) 38%, transparent);
}
.drill-sheet h2 {
    margin: 0;
    font-family: var(--ff-display);
    font-size: 1.5rem;
}
.drill-sheet h2 small {
    margin-left: 0.25rem;
    color: var(--muted);
    font-family: var(--ff);
    font-size: 0.875rem;
    font-weight: 400;
    letter-spacing: 0;
}
.drill-summary {
    margin: 0.35rem 0 0;
    color: var(--muted);
    font-size: 0.875rem;
}
/* the sheet's two actions in the controls' own shape: printing is the
   payoff and takes the leaf outline, the redraw stays a quiet chip */
.drill-sheet .guide-tools {
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 1.25rem 0 0;
}
.drill-sheet .guide-tools a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0.5rem 1.1rem;
    border: 1px solid var(--border);
    border-radius: 1.1rem;
    background: var(--field);
    color: var(--bark);
    font-size: 0.875rem;
    font-weight: 600;
    text-decoration: none;
    transition: border-color 150ms ease, background-color 150ms ease, color 150ms ease;
}
.drill-sheet .guide-tools a[href^="/drills/print"] {
    border-color: var(--leaf);
    color: var(--leaf);
}
.drill-sheet .guide-tools a:hover {
    border-color: var(--leaf-light);
    background: var(--leaf-pale);
    color: var(--leaf-light);
}
.drill-sheet .guide-tools a:focus-visible {
    outline: 2px solid var(--sun);
    outline-offset: 2px;
}
/* a refusal answers the form, so it opens the desk where the sheet would
   have been laid */
.drill-error {
    margin: 0;
    padding: 0.75rem 1rem;
    border: 1px solid var(--red);
    border-radius: 8px;
    background: var(--red-pale);
    color: var(--bark);
    font-size: 1rem;
}

/* The drills page is four worlds in one scroll, each on its own ground so
   its text is set for the colour under it: the slate (pine, chalk-pale type,
   one gilded rule), the shelf (the paper the settings are composed on), the
   desk (a lamplit green the sheet is laid on as a leaf of exercise paper),
   and the colophon (the forest the sheet's number is struck on). The worlds
   run the full width: the main column gives up its measure and padding to
   them on screen (below, beside the print guard), and each world sets its
   own measure inside. */
.drills {
    display: flex;
    flex-direction: column;
}
.drills > section,
#drill-result > section {
    position: relative;
    overflow: hidden;
    padding: clamp(48px, 9vw, 104px) clamp(20px, 5vw, 56px);
}
.drills-slate-inner,
.drills-shelf-inner,
.drills-desk-inner,
.drills-colophon-inner {
    position: relative;
    max-width: 720px;
    margin: 0 auto;
}

.drills-slate {
    background-color: var(--pine);
    background-image: radial-gradient(120% 90% at 30% 0%, var(--moss) 0%, var(--spruce) 48%, var(--pine) 100%);
    color: var(--chrome-text);
}
/* /js/drills.js sets --drills-stick, so the slate holds while the shelf
   slides over it; at auto (no script, or reduced motion) the slate scrolls
   with the page */
.drills > .drills-slate {
    --drills-stick: auto;
    position: sticky;
    top: var(--drills-stick);
}
/* the shade the slate recedes into as the paper covers it: its own layer
   under the copy, so the script fades it on the compositor without a
   repaint, and the chalk only gains contrast as it deepens */
.drills-shade {
    position: absolute;
    inset: 0;
    background: var(--forest);
    opacity: 0;
    pointer-events: none;
    will-change: opacity;
}
/* the copy and the specimen stand over the shade; the ruled frame, drawn
   after it, already does */
.drills-slate-inner {
    z-index: 1;
}
/* the slate's ruled frame: four hairlines that draw themselves in */
.drills-slate-frame i {
    position: absolute;
    background: color-mix(in srgb, var(--gold) 34%, transparent);
}
.drills-slate-frame i:nth-child(odd) {
    left: clamp(10px, 2.5vw, 24px);
    right: clamp(10px, 2.5vw, 24px);
    height: 1px;
}
.drills-slate-frame i:nth-child(1) {
    top: clamp(10px, 2.5vw, 24px);
    transform-origin: left;
}
.drills-slate-frame i:nth-child(3) {
    bottom: clamp(10px, 2.5vw, 24px);
    transform-origin: right;
}
.drills-slate-frame i:nth-child(even) {
    top: clamp(10px, 2.5vw, 24px);
    bottom: clamp(10px, 2.5vw, 24px);
    width: 1px;
}
.drills-slate-frame i:nth-child(2) {
    right: clamp(10px, 2.5vw, 24px);
    transform-origin: top;
}
.drills-slate-frame i:nth-child(4) {
    left: clamp(10px, 2.5vw, 24px);
    transform-origin: bottom;
}
.drills-slate-inner {
    display: grid;
    gap: clamp(36px, 6vw, 56px);
}
.drills h1 {
    margin: 0;
    color: var(--paper);
    font-size: clamp(44px, 11vw, 72px);
    line-height: 1.02;
}
.drills .band {
    margin: 0.7rem 0 0;
    color: var(--gold-warm);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}
/* the grades read at the band's own size, set apart by weight alone */
.drills .band small {
    font-size: inherit;
    font-weight: 400;
}
/* the one gilded accent: a short rule under the band that catches the light
   once as the slate settles */
.drills-gilt {
    position: relative;
    display: block;
    overflow: hidden;
    width: 88px;
    height: 2px;
    margin: 1.4rem 0 0;
    background: linear-gradient(90deg, var(--gold-deep), var(--gold-light) 50%, var(--gold-deep));
    contain: paint;
}
.drills-gilt::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, transparent, var(--chrome-text), transparent);
    transform: translateX(-110%);
    will-change: transform;
}
.drills-lede {
    max-width: 34ch;
    margin: 1.4rem 0 0;
    color: var(--chrome-text);
    font-family: var(--ff-text);
    font-size: 1.125rem;
    line-height: 1.7;
}

/* the specimen: a fact family chalked up the way a sheet sets it, sign and
   figure in columns, each answer on its own rule */
.drills-specimen {
    margin: 0;
}
.drills-facts {
    display: grid;
    grid-template-columns: repeat(4, auto) minmax(3.4ch, auto);
    justify-content: start;
    column-gap: 0.45em;
    row-gap: 0.3em;
    color: var(--chrome-text);
    font-family: var(--ff-display);
    font-size: clamp(30px, 8.4vw, 44px);
    font-variant-numeric: tabular-nums;
    line-height: 1.3;
}
.drills-fact {
    position: relative;
    display: flex;
    gap: 0.45em;
}
.drills-fact-sign {
    color: var(--gold-warm);
}
.drills-fact-answer {
    min-width: 3.4ch;
    text-align: center;
    color: var(--gold-light);
}
/* each fact a row of the family's own columns, so the signs and figures
   stand in line down the slate */
@supports (grid-template-columns: subgrid) {
    .drills-fact {
        display: grid;
        grid-column: 1 / -1;
        grid-template-columns: subgrid;
        justify-items: end;
    }
    .drills-fact-answer {
        justify-self: stretch;
    }
}
.drills-fact-rule {
    position: absolute;
    right: 0;
    bottom: 0.12em;
    width: calc(3.4ch + 0.4em);
    height: 1px;
    background: color-mix(in srgb, var(--chrome-text) 42%, transparent);
    transform-origin: left;
}
.drills-specimen figcaption {
    max-width: 36ch;
    margin: 1.4rem 0 0;
    color: var(--sand);
    font-family: var(--ff-text);
    font-size: 0.9375rem;
    font-style: italic;
    line-height: 1.6;
}

/* the shelf: the paper the settings are composed on, laid over the slate
   above and the desk below, so it casts onto both */
.drills-shelf {
    z-index: 1;
    background: var(--paper);
    box-shadow: 0 -22px 44px -30px color-mix(in srgb, var(--ink) 80%, transparent),
        0 22px 44px -30px color-mix(in srgb, var(--ink) 80%, transparent);
}
.drills-shelf h2 {
    margin: 0;
    font-size: clamp(30px, 6vw, 40px);
}

/* the desk the sheet is laid on: a lamplit green, darker at its foot */
.drills-desk {
    background-color: var(--spruce);
    background-image: linear-gradient(180deg, var(--spruce) 0%, var(--pine) 100%);
}
.drills-lamp {
    position: absolute;
    left: 50%;
    top: -30%;
    width: min(1200px, 170%);
    aspect-ratio: 1;
    border-radius: 50%;
    background: radial-gradient(closest-side, color-mix(in srgb, var(--gold-warm) 20%, transparent), transparent);
    transform: translateX(-50%);
    pointer-events: none;
    contain: strict;
}

/* before a sheet is drawn the desk holds a blank leaf and says what goes on it */
.drill-leaf p {
    max-width: 44ch;
    margin: 0.6rem 0 0;
    color: var(--muted);
    font-family: var(--ff-text);
    line-height: 1.7;
}
.drill-leaf .drill-leaf-title {
    margin: 0;
    color: var(--bark);
    font-family: var(--ff-display);
    font-size: 1.5rem;
    line-height: 1.2;
}
.drill-leaf-rules {
    display: grid;
    gap: 2rem;
    margin: 2rem 0;
}
.drill-leaf-rules i {
    height: 1px;
    background: var(--border);
}
.drill-leaf .drill-leaf-note {
    font-size: 0.875rem;
    font-style: italic;
}

/* the colophon: the sheet's number struck on the forest, with its address */
.drills-colophon {
    background-color: var(--forest);
    background-image: radial-gradient(90% 120% at 50% 100%, var(--spruce) 0%, var(--forest) 70%);
    color: var(--chrome-text);
    text-align: center;
}
.drills-colophon .drills-gilt {
    margin: 0 auto 1.6rem;
}
.drills-colophon-number {
    margin: 0;
    color: var(--paper);
    font-family: var(--ff-display);
    font-size: clamp(40px, 10vw, 64px);
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}
.drills-colophon-note {
    max-width: 38ch;
    margin: 0.9rem auto 0;
    color: var(--sand);
    font-family: var(--ff-text);
    line-height: 1.7;
}
.drills-colophon-link {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    margin-top: 1.2rem;
    padding: 0 1.3rem;
    border: 1px solid color-mix(in srgb, var(--gold) 55%, transparent);
    border-radius: 1.1rem;
    color: var(--gold-warm);
    font-size: 0.875rem;
    font-weight: 600;
    text-decoration: none;
    transition: border-color 150ms ease, color 150ms ease;
}
.drills-colophon-link:hover {
    border-color: var(--gold-warm);
    color: var(--chrome-text);
}
.drills-colophon-link:focus-visible {
    outline: 2px solid var(--gold-warm);
    outline-offset: 2px;
}

@media (min-width: 900px) {
    .drills-slate-inner {
        grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
        align-items: end;
        max-width: 1040px;
    }
    .drills-shelf-inner,
    .drills-desk-inner {
        max-width: 800px;
    }
}

ol.drill-problems {
    columns: 2;
    column-gap: 3.5rem;
    column-rule: 1px solid var(--border-light);
    margin: 1.75rem 0 0;
    padding-left: 0;
    color: var(--bark);
    font-family: var(--ff-text);
    font-size: 1.125rem;
    font-variant-numeric: tabular-nums;
}
ol.drill-problems li {
    margin-bottom: 0.75rem;
    break-inside: avoid;
}
/* the numbers index the problems without competing with them, hung between
   the margin rule and the work */
ol.drill-problems li::marker {
    color: var(--muted);
    font-family: var(--ff);
    font-size: 0.8125rem;
}
ol.drill-problems .blank {
    display: inline-block;
    width: 3rem;
    margin-left: 0.4rem;
    border-bottom: 1px solid var(--sun);
}

/* the worlds run the full width of the page on screen; main gives up its
   measure and padding here, and each world's inner column takes them back */
@media screen {
    .app-main:has(> .drills) {
        max-width: none;
        padding: 0;
    }
}
/* the slate and the colophon are set pale on dark grounds, so a sheet
   printed from the screen goes out as the title and the worksheet in ink;
   the Save to My Library toggle, on a sheet or a guide's cover, is a screen
   control and never reaches paper */
@media print {
    .drills-slate-frame,
    .drills-shade,
    .drills-gilt,
    .drills-specimen,
    .drills-shelf,
    .drills-lamp,
    .drills-colophon,
    .drill-sheet .guide-tools,
    .drill-sheet .library-save,
    .guide.reading .frontis .library-save {
        display: none;
    }
    .drills > .drills-slate {
        position: static;
    }
    /* a reveal the reader never scrolled to still prints: the stylesheet's
       important wins over the inline start state a waiting reveal holds */
    .drills * {
        opacity: 1 !important;
        transform: none !important;
    }
    .drills > section,
    #drill-result > section {
        padding: 0;
        background: none;
        color: var(--bark);
    }
    .drills h1,
    .drills-lede {
        color: var(--bark);
    }
    .drills .band {
        color: var(--sun);
    }
    .drill-sheet {
        margin-top: 1.5rem;
        border: 0;
        background: none;
        box-shadow: none;
    }
}

/* the gilt catches the light once, when /js/drills.js lights it; under
   reduced motion the script never runs, and the page's own transitions and
   the glint stand still too */
.drills-gilt.is-lit::after {
    animation: drills-glint 1.2s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}
@keyframes drills-glint {
    to {
        transform: translateX(110%);
    }
}
@media (prefers-reduced-motion: reduce) {
    .drills *,
    .drills *::after {
        animation: none !important;
        transition: none !important;
    }
}

/* The account-entry surfaces stand on the homepage's forest rather than the
   library's parchment: arriving at Ashwren, not reading inside it. */
body.auth-page {
    background-color: var(--forest);
    background-image: radial-gradient(135% 120% at 50% 28%, var(--moss) 0%, var(--spruce) 46%, var(--forest) 100%);
}
/* The entry pages stand on the forest, so their overscroll ends are forest
   too; the paper layer above stays out of their way. */
body.auth-page .app-background {
    display: none;
}
.auth-page .app-main {
    max-width: 440px;
    padding: 40px 16px 56px;
    text-align: center;
}
.auth-page .app-footer {
    position: relative;
    z-index: 1;
    background-color: transparent;
    border-top-color: var(--rule-dark);
    color: var(--sand);
}
/* The entry pages' two screen edges: the header's pine above it, and past the
   foot the colour the forest gradient reaches along the page's bottom edge —
   spruce giving way to forest, averaged across the width. */
html:not(.at-end) body.auth-page {
    background-color: var(--pine);
}
html.at-end body.auth-page {
    background-color: color-mix(in srgb, var(--spruce) 68%, var(--forest));
}
/* While the menu is open the grain is back on body::after (see the grain
   above), so Safari finds no box at either edge and both strips take the
   document colour — the panel's own where it meets the edge the page runs
   out at: its spruce top while the top is the nearer end, its forest foot
   once the reader is nearer the end (the panel runs 140px past each screen
   edge, so those are three-quarters of the way along its gradient). The
   page's paper image steps aside beneath the open menu. */
html body.sidebar-open,
html body.auth-page.sidebar-open {
    background-color: color-mix(in srgb, var(--spruce) 73%, var(--pine));
    background-image: none;
}
html.at-end body.sidebar-open,
html.at-end body.auth-page.sidebar-open {
    background-color: color-mix(in srgb, var(--forest) 75%, var(--pine));
}
/* a block, so the mark's line box adds no descender gap above the kicker */
.auth-mark {
    display: block;
    width: 64px;
    height: 64px;
    margin: 0 auto;
    filter: drop-shadow(1px 3px 6px rgba(0, 0, 0, 0.45));
}
.auth-kicker {
    margin: 14px 0 0;
    color: var(--gold-warm);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.3em;
    text-transform: uppercase;
}
/* the page's own heading only: Clerk's titles inside the frame are h1s too */
.auth-page .auth > h1 {
    margin: 8px 0 0;
    color: var(--paper);
    font-size: clamp(30px, 8vw, 38px);
}
.auth-lede {
    margin: 16px auto 0;
    max-width: 36ch;
    color: var(--sand);
    font-family: var(--ff-text);
    font-size: 16px;
    line-height: 1.65;
}

/* The entry pages' one frame: the cream card the Clerk widget sits in flat,
   with no card of its own (clerk-appearance.js), so the frame's padding is
   the widget's margin. */
.auth-card {
    display: flex;
    justify-content: center;
    margin-top: 32px;
    padding: 28px clamp(20px, 6vw, 32px) 24px;
    border: 1px solid var(--border-light);
    border-radius: 10px;
    background: var(--cream);
    box-shadow: 0 8px 24px var(--shadow-md);
    text-align: left;
}
.auth-card > #clerk-widget {
    width: 100%;
}
/* the note is the card's content, set flat on it rather than boxed again */
.auth-note {
    margin: 0;
    padding: 2px 4px;
    color: var(--muted);
    font-family: var(--ff-text);
    font-size: 14px;
    line-height: 1.7;
    text-align: left;
}
.auth-note a {
    color: var(--leaf);
    text-underline-offset: 3px;
}
.auth-note a:hover {
    color: var(--leaf-light);
}
.auth-switch {
    margin: 24px 0 0;
    color: var(--sand);
    font-family: var(--ff-text);
    font-size: 14px;
}
/* the lighter golds hold contrast on the moss; the padding gives the crossing
   a full tap target and the negative margin keeps the line where it was */
.auth-switch a {
    display: inline-block;
    margin: -11px -4px;
    padding: 11px 4px;
    color: var(--gold-warm);
    text-underline-offset: 3px;
}
.auth-switch a:hover {
    color: var(--chrome-text);
}
/* each link's own colour rings it: leaf on the cream card, gold on the moss */
.auth-note a:focus-visible,
.auth-switch a:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 2px;
}

/* Clerk's widgets, wherever they mount (sign in, sign up, the account page,
   the supporter checkout). clerk-appearance.js sets their palette and type
   and puts Clerk's own styles in the clerk cascade layer; these unlayered
   rules take the states Clerk's variant rules would otherwise keep: field and
   button borders, hovers, errors and focus. Fields and buttons match the
   site's own (.adapt-form, .catalog-search, .button--gold). */
/* Clerk sets a --border of its own on every button it draws, which would
   turn var(--border) into its primary colour there; the alias, resolved once
   at the root, carries the site's border into Clerk's buttons. */
:root {
    --clerk-edge: var(--border);
}
.cl-formFieldInput:not([type="checkbox"], [data-variant="unstyled"]),
.cl-otpCodeFieldInput {
    min-height: 44px;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--field);
    box-shadow: none;
    color: var(--bark);
    font-size: 15px;
    transition: border-color 150ms ease, box-shadow 150ms ease;
}
.cl-formFieldInput:not([type="checkbox"], [data-variant="unstyled"]):hover,
.cl-otpCodeFieldInput:hover {
    border-color: var(--muted-soft);
}
/* the leaf border carries focus; the halo, a tint of the same leaf, keeps it
   legible on the cream frame, where the paler leaf would vanish. Each code
   box is a div that Clerk marks as the one the next digit goes in. */
.cl-formFieldInput:not([type="checkbox"], [data-variant="unstyled"]):focus,
.cl-otpCodeFieldInput:focus-within,
.cl-otpCodeFieldInput[data-focus-within="true"] {
    border-color: var(--leaf);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--leaf) 22%, transparent);
    outline: none;
}
.cl-formFieldInput:not([type="checkbox"], [data-variant="unstyled"])[aria-invalid="true"],
.cl-otpCodeFieldInput[aria-invalid="true"] {
    border-color: var(--red);
}
.cl-formFieldInput:not([type="checkbox"], [data-variant="unstyled"])[aria-invalid="true"]:focus,
.cl-otpCodeFieldInput[aria-invalid="true"][data-focus-within="true"] {
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--red) 22%, transparent);
}
/* the code is read digit by digit, so each box is a little taller and the
   digit sits large in it */
.cl-otpCodeFieldInput {
    min-height: 52px;
    font-size: 20px;
    font-weight: 600;
}
/* the site's gold call to action: one per step, the step's way forward */
.cl-formButtonPrimary {
    min-height: 46px;
    border: 1px solid rgba(156, 122, 51, 0.3);
    border-radius: 4px;
    background: linear-gradient(180deg, var(--gold-light), var(--gold-deep));
    box-shadow: 0 2px 3px rgba(34, 48, 42, 0.04);
    color: var(--pine);
}
.cl-formButtonPrimary::after {
    display: none;
}
.cl-formButtonPrimary:hover {
    background: var(--gold-light);
    color: var(--pine);
}
/* Google and the other ways in: quiet, on the field's paper */
.cl-socialButtonsBlockButton,
.cl-alternativeMethodsBlockButton {
    min-height: 46px;
    border: 1px solid var(--clerk-edge);
    border-radius: 4px;
    background: var(--field);
    box-shadow: none;
    color: var(--bark);
}
.cl-socialButtonsBlockButton:hover,
.cl-alternativeMethodsBlockButton:hover {
    border-color: var(--leaf);
    background: var(--leaf-pale);
}
.cl-footerActionLink,
.cl-formFieldAction,
.cl-formResendCodeLink,
.cl-backLink,
.cl-footerPagesLink,
.cl-identityPreviewEditButton,
.cl-profileSectionPrimaryButton {
    color: var(--leaf);
    font-weight: 600;
    text-underline-offset: 3px;
}
.cl-footerActionLink,
.cl-formFieldAction,
.cl-formResendCodeLink,
.cl-backLink,
.cl-footerPagesLink {
    text-decoration: underline;
}
.cl-footerActionLink:hover,
.cl-formFieldAction:hover,
.cl-formResendCodeLink:hover,
.cl-backLink:hover,
.cl-footerPagesLink:hover,
.cl-identityPreviewEditButton:hover {
    color: var(--leaf-light);
}
/* "Resend" counts down before it can be pressed again */
.cl-formResendCodeLink:disabled {
    color: var(--muted);
    text-decoration: none;
}
.cl-profileSectionPrimaryButton:hover {
    background: var(--leaf-pale);
    color: var(--leaf);
}
.cl-formFieldInputShowPasswordButton {
    color: var(--muted);
}
.cl-formFieldInputShowPasswordButton:hover {
    background: transparent;
    color: var(--leaf);
}
.cl-alert {
    border: 1px solid rgba(139, 58, 47, 0.3);
    background: var(--red-pale);
    box-shadow: none;
}
.cl-badge {
    border: none;
    background: var(--leaf-pale);
    box-shadow: none;
    color: var(--leaf);
}
/* every control Clerk draws is ringed the way the entry pages ring theirs:
   leaf, clear of the control, on the cream and the paper alike */
:is(.cl-rootBox, .cl-drawerRoot, .cl-modalContent) :is(a, button):focus-visible {
    outline: 2px solid var(--leaf);
    outline-offset: 2px;
    box-shadow: none;
}
/* under 16px iOS Safari zooms the page into a field on focus */
@media (max-width: 767px) {
    .cl-formFieldInput:not([type="checkbox"], [data-variant="unstyled"]) {
        font-size: 16px;
    }
}

@media (max-width: 560px) {
    ol.drill-problems {
        columns: 1;
        column-rule: 0;
    }

    /* the chips take the width the panel's padding gave back: a described
       chip spans its row, the one-word practice chips pair up, and the three
       sheet lengths share one row, so the draw button stays in reach */
    .drill-settings {
        padding: 1.25rem 1rem;
    }

    .drill-settings fieldset > label {
        flex: 1 1 100%;
    }

    .drill-settings .drill-practice label {
        flex-basis: calc(50% - 0.25rem);
    }

    .drill-settings .drill-length label {
        flex: 1 1 0;
        justify-content: center;
    }

    .drill-actions button {
        width: 100%;
    }
}

/* The community frame: the Guide Leaderboard, the Community Feed, the
   suggestion form, and the surfaces around them read as one editorial room —
   typographic hierarchy, parchment and pine materials, restrained rules.
   The reference is docs/design/northstar; the tokens, fonts, grain, drawer,
   and shell around these rules stay the site's own. Everything below lives
   under the shared #community-space fragment root so no other surface
   shifts. */
.app-main:has(> #community-space) {
    max-width: 1100px;
}

/* The owner's community pages carry this root inside the console frame
   (.hq-page) and keep the console's own type, spacing, wrapping, focus ring
   and icons from admin.css, so the frame's element rules below leave them out. */
#community-space:where(:not(.hq-page)) {
    font-family: var(--ff);
    font-size: 14px;
    line-height: 1.7;
    color: var(--bark);
}
/* the frame's own spacing: every margin below is placed on purpose. The
   reset carries no specificity, so each class rule's designed margin wins
   over it, the way the north star's own element reset lets them */
:where(#community-space:not(.hq-page)) :where(h1, h2, h3, p) {
    margin: 0;
}
:where(#community-space:not(.hq-page)) :where(p) {
    text-wrap: pretty;
}
:where(#community-space:not(.hq-page)) :where(h1, h2, h3, .eyebrow) {
    text-wrap: balance;
}
/* an eyebrow opens its block: a container's paragraph spacing and size
   never reach it */
#community-space .eyebrow:first-child {
    margin-top: 0;
}
/* the shared notice rule opens its paragraph with a top margin; a notice in
   this frame carries its own padding instead */
#community-space .notice p {
    margin: 0;
}
#community-space .work-link {
    margin-top: 18px;
    font-size: 13px;
}
#community-space .work-link a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
}
/* a standalone empty state or rules block under the frame's head stands off
   it like a section, not like a caption */
#community-space > .empty {
    margin-top: 24px;
}
#community-space > .community-rules {
    padding: 22px 0 24px;
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
}
#community-space:where(:not(.hq-page)) h2,
#community-space:where(:not(.hq-page)) h3 {
    font-family: var(--ff-text);
    line-height: 1.3;
    letter-spacing: -0.045em;
}
#community-space:where(:not(.hq-page)) :focus-visible {
    outline: 2px solid var(--sun);
    outline-offset: 5px;
}
#community-space:where(:not(.hq-page)) svg {
    width: 20px;
    height: 20px;
    flex: none;
    vertical-align: middle;
}
.icon {
    fill: none;
    stroke: currentColor;
    stroke-width: 1.5;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* the reading-table head: eyebrow, name, introduction, and the contextual
   cross-link beside it, over the ruled qualification */
.hero {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 28px;
    padding: 36px 0 26px;
}
.hero h1 {
    margin-top: 13px;
    color: var(--pine);
    font-family: var(--ff-display);
    font-size: clamp(48px, 6.1vw, 78px);
    line-height: 1.04;
    letter-spacing: -0.05em;
}
.hero-description {
    max-width: 660px;
    margin-top: 14px;
    color: var(--muted);
    font-size: 14px;
    line-height: 1.8;
}
.hero-actions {
    flex: none;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 4px;
    padding-bottom: 1px;
}
.hero-actions .text-link {
    font-size: 12px;
}
.hero-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 22px;
    min-height: 54px;
    padding: 4px 0;
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
}
.hero-foot p {
    color: var(--muted);
    font: italic 12px/1.7 var(--ff-text);
}
.hero-foot .text-link {
    font-size: 12px;
}

/* the shared text link and the two calls to action */
.text-link {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    min-height: 44px;
    color: var(--leaf);
    font-family: var(--ff);
    font-size: 12px;
    font-weight: 500;
    text-decoration: none;
}
.text-link span {
    border-bottom: 1px solid currentColor;
}
.text-link svg {
    width: 16px;
    height: 16px;
    transition: transform 0.18s ease;
}
.text-link:hover {
    color: var(--leaf-light);
}
.text-link:hover svg {
    transform: translateX(3px);
}
.button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    min-height: 46px;
    padding: 12px 21px;
    border: 1px solid transparent;
    border-radius: 3px;
    font-family: var(--ff);
    font-size: 12px;
    font-weight: 600;
    line-height: 1.5;
    text-decoration: none;
    transition: background 0.18s, border-color 0.18s, transform 0.18s;
}
.button:hover {
    transform: translateY(-1px);
}
.button--gold {
    color: var(--pine);
    background: linear-gradient(180deg, var(--gold-light), var(--gold-deep));
    border-color: rgba(156, 122, 51, 0.3);
    box-shadow: 0 2px 3px rgba(34, 48, 42, 0.04);
}
.button--gold:hover {
    color: var(--pine);
    background: var(--gold-light);
}
.button--green {
    color: var(--chrome-text);
    background: var(--pine);
}
.button--green:hover {
    color: var(--chrome-text);
    background: var(--leaf);
}
.button--outline {
    color: var(--leaf);
    background: transparent;
    border-color: var(--border);
}
.button--outline:hover {
    color: var(--leaf);
    background: var(--leaf-pale);
    border-color: var(--leaf);
}
.button:disabled {
    opacity: 0.55;
    transform: none;
    cursor: not-allowed;
}

/* the material vocabulary: parchment surfaces, grade pills, small kickers,
   and the saved-action notice the one-use flash lands in */
.parchment {
    background: linear-gradient(135deg, var(--parchment-top), var(--parchment-bottom));
    border: 1px solid var(--border);
    border-radius: 4px;
}
.grade {
    display: inline-flex;
    align-items: center;
    padding: 3px 9px;
    border: 1px solid var(--border);
    border-radius: 20px;
    color: var(--bark-soft);
    font-family: var(--ff);
    font-size: 11px;
    font-weight: 500;
    line-height: 1.5;
    white-space: nowrap;
}
.eyebrow {
    color: var(--muted);
    font-family: var(--ff);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.18em;
    line-height: 1.4;
    text-transform: uppercase;
}
#community-space .notice {
    margin: 18px 0 0;
    max-width: none;
    padding: 14px 17px;
    border: 1px solid var(--border);
    border-left: 3px solid var(--sun);
    border-radius: 3px;
    background: var(--sun-pale);
    color: var(--bark);
    font-family: var(--ff);
    font-size: 13px;
    text-align: left;
}
.section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 22px;
    margin-bottom: 22px;
}
.section-head h2 {
    font-size: 25px;
}
.section-head p {
    color: var(--muted);
    font-family: var(--ff);
    font-size: 12px;
}

/* the production shelf: one pine card for Coming soon, one parchment card
   for In production, each carrying a typographic bookplate — code-native
   decoration standing in for no cover art */
.production-section {
    padding-top: 28px;
}
.production-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 22px;
}
.production-card {
    position: relative;
    display: grid;
    grid-template-columns: 105px minmax(0, 1fr);
    column-gap: 25px;
    row-gap: 14px;
    padding: 24px;
    overflow: hidden;
}
.production-card--dark {
    color: var(--chrome-text);
    background: linear-gradient(135deg, var(--spruce), var(--pine));
    border-color: var(--spruce);
}
.production-card--dark::after {
    content: "";
    position: absolute;
    width: 180px;
    height: 180px;
    right: -84px;
    top: -90px;
    border: 1px solid rgba(201, 162, 75, 0.14);
    border-radius: 50%;
    pointer-events: none;
}
.bookplate {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-between;
    width: 105px;
    height: 145px;
    padding: 17px 9px 11px;
    overflow: hidden;
    border: 1px solid rgba(156, 122, 51, 0.48);
    color: var(--pine);
    background: var(--cream);
    box-shadow: inset 5px 0 0 rgba(34, 48, 42, 0.09), 4px 6px 9px rgba(10, 24, 16, 0.04);
    text-align: center;
}
.bookplate::before {
    content: "";
    position: absolute;
    inset: 6px 6px 6px 10px;
    border: 1px solid currentColor;
    opacity: 0.32;
    pointer-events: none;
}
.bookplate small {
    font-family: var(--ff);
    font-size: 6px;
    letter-spacing: 0.19em;
    text-transform: uppercase;
}
.bookplate strong {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 4;
    overflow: hidden;
    font-family: var(--ff-text);
    font-size: 12px;
    font-weight: 400;
    line-height: 1.5;
    text-transform: uppercase;
}
.plate-mark {
    width: 30px;
    height: 30px;
    margin-top: 5px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.bookplate--green {
    color: var(--gold-warm);
    background: var(--leaf);
    border-color: var(--leaf);
}
.bookplate--gold {
    color: var(--pine);
    background: var(--gold-warm);
}
.production-copy {
    min-width: 0;
}
.production-copy .eyebrow {
    letter-spacing: 0.14em;
}
.production-card--dark .eyebrow {
    color: var(--gold-warm);
}
.production-copy h3 {
    margin-top: 9px;
    font-size: 21px;
    overflow-wrap: anywhere;
}
.production-copy .author {
    margin-top: 6px;
    color: var(--muted);
    font-family: var(--ff);
    font-size: 11px;
}
.production-card--dark .author {
    color: var(--sand);
}
.production-copy .grade {
    margin-top: 12px;
}
.production-card--dark .grade {
    color: var(--chrome-text);
    border-color: rgba(244, 234, 215, 0.2);
}
.production-stage {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 16px;
    font-family: var(--ff);
    font-size: 12px;
}
.stage-dot {
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--sun);
}
.owner-note {
    margin-top: 8px;
    color: var(--muted);
    font-family: var(--ff-text);
    font-size: 13px;
    font-style: italic;
}
.production-card--dark .owner-note {
    color: var(--sand);
}
.production-meta {
    grid-column: 1 / -1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-top: -6px;
    padding-top: 13px;
    border-top: 1px solid var(--border);
    color: var(--muted);
    font-family: var(--ff);
    font-size: 11px;
}
.production-meta .text-link {
    font-size: 12px;
}
.production-card--dark .production-meta {
    border-color: rgba(244, 234, 215, 0.15);
    color: var(--sand);
}
.production-card--dark .production-meta .text-link {
    color: var(--gold-warm);
}

/* the queue: every owner tier at once as one compact ranked list, a large
   quiet rank figure per row, and a consistent vote column kept apart from
   the title that opens the book */
.board-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 270px;
    align-items: start;
    gap: 48px;
    margin-top: 36px;
}
.queue-head h2 {
    font-size: 30px;
}
.queue-head p {
    margin-top: 12px;
    max-width: 560px;
    color: var(--muted);
    font-family: var(--ff);
    font-size: 13px;
    line-height: 1.75;
}
.tier {
    margin-top: 25px;
}
/* the support page's supporter ledger names its entries .tier as well; its
   grid, slip shading, padding, column rules, and dotted leader belong to that
   sheet and must not reach the board's priority groups */
.queue-section .tier {
    display: block;
    padding: 0;
    background: none;
    border: 0;
}
.queue-section .tier::before {
    content: none;
}
.tier-head {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-bottom: 7px;
}
#community-space .tier-head h3 {
    flex: none;
    color: var(--leaf);
    font-family: var(--ff);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.13em;
    text-transform: uppercase;
}
.tier-head::after {
    content: "";
    width: 100%;
    border-top: 1px solid var(--border);
}
.queue-list {
    list-style: none;
    margin: 0;
    padding: 0;
}
.queue-row {
    display: grid;
    grid-template-columns: 32px 43px minmax(0, 1fr) 120px;
    align-items: center;
    gap: 18px;
    min-height: 112px;
    border-bottom: 1px solid var(--border-light);
    transition: background 0.2s;
    /* "Show more" without script lands on a row: clear the pinned header */
    scroll-margin-top: 88px;
}
.queue-row:hover {
    background: rgba(252, 249, 242, 0.32);
}
.queue-rank {
    color: var(--sun);
    font-family: var(--ff-display);
    font-size: 32px;
    font-variant-numeric: tabular-nums;
    text-align: center;
}
.book-marker {
    position: relative;
    display: grid;
    place-items: center;
    width: 43px;
    height: 60px;
    border: 1px solid rgba(156, 122, 51, 0.33);
    color: var(--leaf);
    background: var(--cream);
    box-shadow: inset 3px 0 0 rgba(34, 48, 42, 0.05);
    font-family: var(--ff-display);
    font-size: 23px;
}
.book-marker::before {
    content: "";
    position: absolute;
    inset: 5px 4px 5px 7px;
    border: 1px solid currentColor;
    opacity: 0.22;
}
.book-marker--green {
    background: var(--leaf);
    color: var(--gold-warm);
}
.book-marker--gold {
    background: var(--gold-warm);
    color: var(--pine);
}
.book-marker--paper {
    background: var(--parchment-top);
    color: var(--sun);
}
.queue-book {
    min-width: 0;
}
.queue-title {
    display: inline-block;
    min-height: 44px;
    padding: 8px 0;
    color: var(--bark);
    font-family: var(--ff-text);
    font-size: 21px;
    line-height: 1.35;
    letter-spacing: -0.04em;
    text-decoration: none;
    overflow-wrap: anywhere;
}
.queue-title:hover {
    color: var(--leaf);
    text-decoration: underline;
    text-underline-offset: 5px;
    text-decoration-thickness: 1px;
}
.queue-author {
    color: var(--muted);
    font-family: var(--ff);
    font-size: 11px;
}
.queue-info-line {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 8px;
}
.queue-info-line .grade {
    padding: 1px 7px;
}
.queue-status {
    color: var(--muted);
    font-family: var(--ff);
    font-size: 11px;
}
.queue-info-line .queue-talk {
    font-size: 12px;
}
/* a long group's foot: how much of it is showing, and the quiet link that
   brings in the next rows */
.queue-more {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 4px 18px;
}
.queue-more:has(.queue-count, .text-link) {
    padding-top: 10px;
}
.queue-count {
    color: var(--muted);
    font-family: var(--ff);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
}
.queue-more .text-link {
    font-size: 12px;
}
.queue-more .text-link:hover svg {
    transform: translateY(3px);
}

/* the vote column: the total, then the stepper: take back, this month's, add */
.vote {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    width: 120px;
    min-height: 74px;
    padding: 7px 4px;
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--leaf);
    background: rgba(252, 249, 242, 0.35);
    transition: border-color 0.18s, background 0.18s;
}
.vote-total,
.vote-stepper {
    font-family: var(--ff);
    font-size: 14px;
    font-weight: 600;
    line-height: 1.3;
    text-wrap: balance;
    font-variant-numeric: tabular-nums;
    text-align: center;
}
.vote button,
.vote a {
    min-height: 44px;
    padding: 4px 2px;
    border: 0;
    color: inherit;
    background: none;
    font-family: var(--ff);
    font-size: 12px;
    line-height: 1.35;
    text-align: center;
    text-decoration: none;
    text-wrap: balance;
    cursor: pointer;
}
.vote:not(.voted):hover {
    border-color: var(--sun);
    background: var(--sun-pale);
}
.vote.voted {
    color: var(--chrome-text);
    background: var(--leaf);
    border-color: var(--leaf);
}
.vote button:disabled {
    opacity: 0.68;
    cursor: not-allowed;
}
.vote-stepper {
    display: grid;
    grid-template-columns: 44px minmax(20px, 1fr) 44px;
    align-items: center;
    width: 100%;
    font-size: 16px;
}
.vote-stepper button {
    border: 1px solid currentColor;
    border-radius: 4px;
    font-size: 20px;
}
.vote-stepper button:enabled:hover {
    color: var(--leaf);
    background: var(--sun-pale);
}
#community-space .vote-stepper :focus-visible {
    outline-offset: 1px;
}
#community-space .vote.voted :focus-visible {
    outline-color: var(--gold-warm);
}
p.vote-allowance {
    color: var(--leaf);
    font-size: 13px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    line-height: 1.5;
}
.queue-head .vote-allowance {
    margin-top: 10px;
}
.vote-closed {
    color: var(--muted);
    font-family: var(--ff);
    font-size: 12px;
    line-height: 1.7;
}

/* the supporting column: the suggestion invitation, the ordering
   explanation as a native disclosure, and the community invitation */
.board-aside {
    padding-top: 4px;
}
.invitation {
    position: relative;
    padding: 24px 23px;
}
.invitation .eyebrow {
    font-size: 11px;
    line-height: 1.4;
}
.invitation h3 {
    margin-top: 16px;
    max-width: 190px;
    font-size: 25px;
}
.invitation p {
    margin-top: 13px;
    color: var(--muted);
    font-family: var(--ff);
    font-size: 13px;
    line-height: 1.75;
}
.invitation .button {
    width: 100%;
    margin-top: 22px;
}
.invitation .invitation-live {
    margin-top: 18px;
    font-size: 12px;
}
.invitation-history {
    width: 100%;
    justify-content: center;
    margin-top: 10px;
    font-size: 12px;
}
.invitation .invitation-foot {
    margin-top: 12px;
    text-align: center;
    font-size: 11px;
}
.board-explainer {
    margin-top: 24px;
    padding: 0 2px;
    border-top: 1px solid var(--border);
}
.board-explainer summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: 57px;
    list-style: none;
    font-family: var(--ff);
    font-size: 12px;
    font-weight: 500;
    cursor: pointer;
}
.board-explainer summary::-webkit-details-marker {
    display: none;
}
.board-explainer summary svg {
    width: 14px;
    height: 14px;
}
.board-explainer[open] summary svg {
    transform: rotate(180deg);
}
.board-explainer p {
    margin: 0 0 14px;
    color: var(--muted);
    font-family: var(--ff);
    font-size: 13px;
    line-height: 1.75;
}
.board-explainer strong {
    color: var(--bark);
    font-weight: 500;
}
.community-invitation {
    margin-top: 25px;
    padding: 25px 0 0;
    border-top: 1px solid var(--border);
}
.community-invitation h3 {
    max-width: 200px;
    font-size: 21px;
}
.community-invitation p {
    margin-top: 12px;
    color: var(--muted);
    font-family: var(--ff);
    font-size: 13px;
    line-height: 1.75;
}
.community-invitation .text-link {
    margin-top: 7px;
    font-size: 12px;
}

/* published records on the board and in the archive */
.published-section {
    margin-top: 48px;
    padding-top: 32px;
    border-top: 1px solid var(--border);
}
.published-card {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 26px;
    padding: 23px 27px;
}
.published-book {
    display: flex;
    align-items: center;
    gap: 21px;
    min-width: 0;
}
.published-book h3 {
    font-size: 21px;
    overflow-wrap: anywhere;
}
.published-book h3 a {
    display: inline-block;
    padding-block: 11px;
    margin-block: -11px;
    color: inherit;
    text-decoration: none;
}
.published-book h3 a:hover {
    color: var(--leaf);
    text-decoration: underline;
    text-underline-offset: 5px;
    text-decoration-thickness: 1px;
}
.published-book .author {
    margin-top: 5px;
    color: var(--muted);
    font-family: var(--ff);
    font-size: 11px;
}
.published-copy {
    max-width: 34ch;
    color: var(--muted);
    font-family: var(--ff);
    font-size: 12px;
}
.published-card .text-link {
    font-size: 12px;
}
.published-card .eyebrow {
    margin-bottom: 7px;
}

/* one book's detail: the review dialog's primitives on a normal page */
.detail-card {
    margin-top: 28px;
    padding: 30px;
}
.modal-head {
    display: flex;
    align-items: start;
    justify-content: space-between;
    gap: 18px;
}
.detail-card h1 {
    margin-top: 9px;
    font-family: var(--ff-text);
    font-size: 30px;
    line-height: 1.3;
    letter-spacing: -0.045em;
    overflow-wrap: anywhere;
}
.detail-card .author {
    margin-top: 8px;
    color: var(--muted);
    font-family: var(--ff);
    font-size: 12px;
}
.detail-card .grade {
    margin-top: 17px;
}
.modal-description {
    margin-top: 22px;
    color: var(--muted);
    font-family: var(--ff);
    font-size: 13px;
    line-height: 1.85;
}
.modal-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    margin-top: 24px;
}
.modal-footnote {
    margin-top: 20px;
    padding-top: 16px;
    border-top: 1px solid var(--border);
    color: var(--muted);
    font-family: var(--ff);
    font-size: 11px;
}

/* the short forms: the suggestion form, its private receipt, and the shared
   field primitives the report and profile forms stand on */
.narrow {
    width: min(660px, calc(100% - 48px));
    margin-inline: auto;
}
.form-page {
    padding-top: 36px;
}
.form-page h1 {
    margin-top: 17px;
    font-family: var(--ff-display);
    font-size: 62px;
    line-height: 1.08;
    letter-spacing: -0.04em;
}
.form-intro {
    margin-top: 17px;
    color: var(--muted);
    font-family: var(--ff);
    font-size: 13px;
    line-height: 1.9;
}
.form-card {
    margin-top: 28px;
    padding: 30px;
}
.field + .field {
    margin-top: 23px;
}
.field label {
    display: block;
    margin-bottom: 8px;
    font-family: var(--ff);
    font-size: 12px;
    font-weight: 500;
}
.optional {
    margin-left: 6px;
    color: var(--muted);
    font-size: 10px;
    font-weight: 400;
}
.field input,
.field textarea,
.field select {
    width: 100%;
    min-height: 46px;
    padding: 11px 13px;
    border: 1px solid var(--border);
    border-radius: 3px;
    color: var(--bark);
    background: var(--field);
    font-family: var(--ff);
    font-size: 13px;
    line-height: 1.7;
}
.field textarea {
    min-height: 116px;
    resize: vertical;
}
.field input:focus,
.field textarea:focus,
.field select:focus {
    outline: 2px solid var(--sun);
    outline-offset: 2px;
}
.field input:disabled,
.field textarea:disabled,
.field select:disabled {
    opacity: 0.65;
    cursor: not-allowed;
}
.field-help {
    margin-top: 7px;
    color: var(--muted);
    font-family: var(--ff);
    font-size: 10px;
    line-height: 1.75;
}
.form-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    margin-top: 27px;
    padding-top: 24px;
    border-top: 1px solid var(--border);
}
.form-footer p {
    max-width: 245px;
    color: var(--muted);
    font-family: var(--ff);
    font-size: 10px;
}
/* the community pages set their help lines, footnotes, and optional marks
   on the frame's small-text floor; the admin desk keeps its own */
#community-space .optional {
    font-size: 11px;
}
#community-space .field-help,
#community-space .form-footer p {
    font-size: 12px;
}
#community-space .form-footer p {
    max-width: 36ch;
}
.submission-receipt {
    margin-top: 28px;
    padding: 30px;
}
.submission-receipt h2 {
    margin-top: 13px;
    font-size: 25px;
}
.submission-receipt p {
    margin-top: 10px;
    color: var(--muted);
}
.submission-receipt .byline {
    margin-top: 4px;
    font-family: var(--ff);
    font-size: 11px;
}
.submission-receipt .resolved {
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid var(--border);
    color: var(--bark);
    font-family: var(--ff-text);
    font-size: 13px;
}
.submission-receipt .resolved a {
    color: var(--leaf);
}

/* the companion feed: the 660-pixel reading column beside the community
   notes, a plain-text composer, and ruled post rows with one reply level */
.feed-layout {
    display: grid;
    grid-template-columns: minmax(0, 660px) 270px;
    justify-content: space-between;
    gap: 64px;
    align-items: start;
    margin-top: 36px;
}
/* the shared column rule centres a 660px page; as a grid item it would
   shrink to its content and float in the middle of its track, so here it
   fills the track and aligns with the frame's left edge */
.feed-layout > .community-column {
    width: 100%;
    margin: 0;
}
.composer {
    padding: 24px;
}
.composer-title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 20px;
}
.composer-title h2 {
    font-size: 21px;
}
/* a full touch target that does not stretch the title row */
.composer-title .text-link {
    margin-block: -9px;
    font-size: 12px;
}
/* the preview composer wraps its control in the label; the control takes
   the same place under its label text that a live form's field gives it */
#community-space .field label > :is(input, textarea, select) {
    display: block;
    margin-top: 8px;
}
.composer .field textarea {
    min-height: 96px;
    background: rgba(255, 253, 247, 0.58);
}
.composer .field + .field {
    margin-top: 15px;
}
/* The topic and the Share post command share a row while it holds them.
   Neither may be squeezed: the select keeps its width and the command its
   one-line label, so where the composer is narrower than the two together
   (a phone, inside the book's ruled sheet) the command wraps under the
   topic, at the row's right, instead of pushing past the page's edge. */
.composer-bottom {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 15px;
    margin-top: 15px;
}
.composer-bottom > button {
    flex: none;
    margin-left: auto;
    white-space: nowrap;
}
/* the preview composer's disabled command carries no button class (the
   preview contract pins its markup), so it takes the gold button's shape
   here, at the disabled button's rest */
.composer-bottom > button:not(.button) {
    min-height: 46px;
    padding: 12px 21px;
    border: 1px solid rgba(156, 122, 51, 0.3);
    border-radius: 3px;
    color: var(--pine);
    background: linear-gradient(180deg, var(--gold-light), var(--gold-deep));
    font: 600 12px/1.5 var(--ff);
    opacity: 0.55;
    cursor: not-allowed;
}
.composer-topic {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    color: var(--muted);
    font-family: var(--ff);
    font-size: 12px;
}
.composer-topic select {
    width: 156px;
    min-width: 0;
    min-height: 42px;
    padding: 8px;
    border: 1px solid var(--border);
    border-radius: 3px;
    color: var(--muted);
    background: var(--field);
    font-family: var(--ff);
    font-size: 12px;
}
.optional-link summary {
    min-height: 44px;
    margin-top: 6px;
    color: var(--leaf);
    font-family: var(--ff);
    font-size: 12px;
    cursor: pointer;
}
.attached-book {
    display: flex;
    align-items: center;
    gap: 13px;
    margin-top: 18px;
    padding: 13px 15px;
    border: 1px solid var(--border);
    border-radius: 3px;
    color: var(--bark);
    background: var(--sun-pale);
    text-decoration: none;
    transition: border-color 0.18s;
}
.attached-book:hover {
    color: var(--bark);
    border-color: var(--sun);
}
.attached-book svg {
    color: var(--sun);
}
.attached-book strong {
    display: block;
    font-family: var(--ff-text);
    font-size: 13px;
    font-weight: 400;
}
.attached-book span {
    color: var(--muted);
    font-family: var(--ff);
    font-size: 11px;
}
.attach-check {
    margin-top: 10px;
    font-family: var(--ff);
    font-size: 12px;
}
.attach-check input {
    accent-color: var(--leaf);
    margin-right: 8px;
}
.feed-filter {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 15px;
    margin-top: 32px;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--border);
}
.feed-filter label {
    color: var(--muted);
    font-family: var(--ff);
    font-size: 12px;
}
.feed-filter select {
    min-height: 44px;
    margin-left: auto;
    padding: 8px 9px;
    border: 1px solid var(--border);
    border-radius: 3px;
    color: var(--leaf);
    background: transparent;
    font-family: var(--ff);
    font-size: 12px;
}
/* the filter's submit is classed as the text link it reads as; the native
   button chrome stays off it */
.feed-filter .text-link {
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
}
.feed-post {
    padding: 26px 0;
    border-bottom: 1px solid var(--border);
}
.post-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 18px;
}
.member-name {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 10px 0;
    color: var(--bark);
    font-family: var(--ff);
    font-size: 13px;
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 4px;
    text-decoration-color: var(--border);
}
.member-name:hover {
    color: var(--leaf);
}
.post-date {
    color: var(--muted);
    font-family: var(--ff);
    font-size: 11px;
}
.topic {
    padding: 3px 8px;
    color: var(--leaf);
    background: var(--leaf-pale);
    border: 1px solid rgba(46, 94, 69, 0.1);
    border-radius: 20px;
    font-family: var(--ff);
    font-size: 11px;
}
.post-body {
    margin-top: 15px;
    color: var(--bark-soft);
    font-family: var(--ff-text);
    font-size: 16px;
    line-height: 1.75;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}
/* a shared address is one unbroken word; it breaks where it must rather
   than run past a phone's edge */
.feed-post .text-link span {
    min-width: 0;
    overflow-wrap: anywhere;
}
.post-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 18px;
    margin-top: 17px;
}
.post-footer a {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 44px;
    padding: 5px 0;
    border: 0;
    color: var(--leaf);
    background: none;
    font-family: var(--ff);
    font-size: 12px;
    text-decoration: none;
    cursor: pointer;
}
.post-footer .report-link {
    color: var(--muted);
}
.post-footer a:hover,
.reply-actions a:hover,
.reply-actions button:hover {
    text-decoration: underline;
    text-underline-offset: 4px;
}
.reply-count {
    color: var(--muted);
    font-family: var(--ff);
    font-size: 11px;
}
.post-actions {
    display: flex;
    align-items: center;
    gap: 18px;
}
.replies {
    margin-top: 18px;
    padding: 15px 0 0 20px;
    border-top: 1px solid var(--border-light);
    border-left: 1px solid var(--border);
}
.reply {
    margin: 0 0 16px;
}
.reply + .reply {
    padding-top: 16px;
    border-top: 1px solid var(--border-light);
}
.reply-body {
    margin-top: 6px;
    font-family: var(--ff-text);
    font-size: 15px;
    line-height: 1.75;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}
.reply-actions {
    display: flex;
    align-items: center;
    gap: 18px;
}
.reply-actions a,
.reply-actions button {
    min-height: 44px;
    padding: 5px 0;
    border: 0;
    color: var(--muted);
    background: none;
    font-family: var(--ff);
    font-size: 12px;
    text-decoration: none;
    cursor: pointer;
}
.reply-form {
    margin-top: 19px;
}
.reply-form textarea {
    width: 100%;
    min-height: 78px;
    padding: 10px;
    border: 1px solid var(--border);
    border-radius: 3px;
    color: var(--bark);
    background: var(--field);
    font-family: var(--ff);
    font-size: 13px;
    resize: vertical;
}
.reply-form .button {
    margin-top: 8px;
    min-height: 40px;
}
.feed-aside {
    padding-top: 4px;
}
.feed-aside .community-invitation {
    margin-top: 0;
    border-top: 0;
}
.community-rules {
    padding: 24px 0;
    border-bottom: 1px solid var(--border);
}
.community-rules h3 {
    font-size: 21px;
}
.community-rules .eyebrow {
    font-size: 11px;
    line-height: 1.4;
}
.community-rules .eyebrow + h3 {
    margin-top: 16px;
}
.community-rules p {
    margin-top: 13px;
    color: var(--muted);
    font-family: var(--ff);
    font-size: 13px;
    line-height: 1.75;
}
.community-rules .small-rule {
    font-size: 12px;
}
.profile-card {
    padding: 10px 0;
}
.profile-card p {
    margin-top: 15px;
    color: var(--muted);
    font-family: var(--ff);
    font-size: 13px;
}
.member-links {
    list-style: none;
    margin: 15px 0 0;
    padding: 0;
}
.member-links a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    color: var(--leaf);
    font-family: var(--ff);
    font-size: 12px;
    overflow-wrap: anywhere;
}

@media (min-width: 1440px) {
    .hero {
        padding-top: 40px;
    }
}
@media (max-width: 1023px) {
    .board-layout {
        gap: 30px;
        grid-template-columns: minmax(0, 1fr) 235px;
    }
    .production-card {
        grid-template-columns: 85px minmax(0, 1fr);
        gap: 19px;
        padding: 21px;
    }
    .bookplate {
        width: 85px;
        height: 138px;
        padding-inline: 7px;
    }
    .bookplate strong {
        font-size: 10px;
    }
    .bookplate small {
        font-size: 5px;
    }
    .production-stage {
        margin-top: 14px;
    }
    .queue-row {
        grid-template-columns: 25px minmax(0, 1fr) 120px;
        gap: 13px;
    }
    .queue-row .book-marker {
        display: none;
    }
    .vote {
        width: 120px;
    }
    .feed-layout {
        grid-template-columns: minmax(0, 1fr) 235px;
        gap: 30px;
    }
    .hero h1 {
        font-size: 68px;
    }
}
@media (max-width: 767px) {
    .hero {
        flex-direction: column;
        align-items: flex-start;
        gap: 23px;
        padding: 36px 0 27px;
    }
    .hero h1 {
        max-width: 550px;
        font-size: clamp(43px, 9.8vw, 67px);
        letter-spacing: -0.045em;
    }
    .hero-description {
        margin-top: 16px;
        line-height: 1.9;
    }
    .hero-actions {
        flex-direction: row;
        align-items: center;
        gap: 17px;
        width: 100%;
    }
    .hero-actions .button {
        padding-inline: 18px;
    }
    .hero-foot {
        flex-direction: column;
        align-items: flex-start;
        gap: 2px;
        padding: 10px 0;
    }
    .production-section {
        padding-top: 29px;
    }
    .section-head {
        gap: 14px;
        margin-bottom: 18px;
    }
    .section-head p {
        display: none;
    }
    .production-grid {
        grid-template-columns: 1fr;
        gap: 14px;
    }
    .production-card {
        grid-template-columns: 85px minmax(0, 1fr);
        gap: 19px;
        padding: 21px;
    }
    .production-stage {
        margin-top: 15px;
    }
    .production-meta {
        padding-top: 11px;
        margin-top: -3px;
    }
    .board-layout {
        grid-template-columns: minmax(0, 1fr);
        gap: 32px;
        margin-top: 36px;
    }
    .queue-head p {
        margin-top: 12px;
    }
    .tier {
        margin-top: 25px;
    }
    .queue-row {
        grid-template-columns: 25px 37px minmax(0, 1fr) 120px;
        min-height: 118px;
        gap: 12px;
    }
    .queue-row .book-marker {
        display: grid;
        width: 37px;
        height: 52px;
        font-size: 20px;
    }
    .queue-title {
        font-size: 18px;
        letter-spacing: -0.04em;
    }
    .queue-rank {
        font-size: 29px;
    }
    .queue-author {
        font-size: 11px;
    }
    .queue-status {
        display: none;
    }
    .queue-info-line {
        margin-top: 7px;
    }
    .vote {
        min-height: 71px;
    }
    .board-aside {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 22px;
    }
    .invitation {
        grid-row: span 2;
        padding: 22px;
    }
    .invitation h3 {
        max-width: none;
        font-size: 25px;
    }
    .board-explainer {
        margin-top: 0;
    }
    .community-invitation {
        margin-top: 0;
        padding-top: 19px;
    }
    .published-section {
        margin-top: 35px;
        padding-top: 27px;
    }
    .published-card {
        flex-wrap: wrap;
        gap: 17px;
        padding: 21px;
    }
    .published-book {
        gap: 16px;
        width: 100%;
    }
    .published-book h3 {
        font-size: 18px;
    }
    .published-copy {
        max-width: none;
    }
    .form-page {
        padding-top: 22px;
    }
    .form-page h1 {
        font-size: 48px;
    }
    .narrow {
        width: calc(100% - 40px);
    }
    .form-card {
        padding: 23px;
    }
    .form-footer {
        align-items: flex-start;
        flex-direction: column;
    }
    .form-footer .button {
        width: 100%;
    }
    .feed-layout {
        grid-template-columns: minmax(0, 1fr);
        gap: 28px;
        margin-top: 27px;
    }
    .feed-aside {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 26px;
    }
    .composer {
        padding: 21px;
    }
    .composer-title h2 {
        font-size: 18px;
    }
    .feed-post {
        padding: 22px 0;
    }
    .community-rules {
        padding-top: 0;
        border-bottom: 0;
    }
    .detail-card {
        padding: 23px;
    }
    /* a control under 16px makes iOS zoom the page on focus */
    #community-space :is(.field input, .field textarea, .field select,
    .composer-topic select, .feed-filter select, .reply-form textarea) {
        font-size: 16px;
    }
}
@media (max-width: 420px) {
    .hero h1 {
        font-size: 47px;
    }
    .hero-actions {
        gap: 12px;
    }
    .queue-row {
        grid-template-columns: 31px minmax(0, 1fr) 120px;
        gap: 13px;
        min-height: 108px;
    }
    .queue-row .book-marker {
        display: none;
    }
    .queue-title {
        font-size: 18px;
    }
    .board-aside,
    .feed-aside {
        grid-template-columns: minmax(0, 1fr);
    }
    .invitation {
        padding: 24px;
    }
    .invitation h3 {
        max-width: none;
    }
    .invitation .button {
        width: auto;
    }
    .invitation .invitation-foot {
        text-align: left;
    }
    .board-explainer {
        margin-top: 0;
    }
    .published-section .section-head {
        flex-direction: column;
        align-items: flex-start;
        gap: 6px;
    }
    .composer-bottom {
        gap: 10px;
    }
    .composer-bottom select {
        max-width: 138px;
    }
    .composer-bottom .button {
        padding-inline: 14px;
    }
}
/* The notes beside the board and the feed stand in two columns from 421px
   up, but a wide phone's two columns are 140 to 190px each and the
   invitation's copy runs 18 to 21 characters a line. Up to 519px they
   stack the way they do on a smaller phone. */
@media (max-width: 519px) {
    .board-aside,
    .feed-aside {
        grid-template-columns: minmax(0, 1fr);
    }
    .invitation {
        padding: 24px;
    }
    .invitation .button {
        width: auto;
    }
    .invitation .invitation-foot {
        text-align: left;
    }
}

/* the community frame moves only to answer a person or to mark state, so it
   stands still under reduced motion — placed after its own transitions so
   document order resolves in the guard's favour, the way the drawer's guard
   above resolves for the chrome */
@media (prefers-reduced-motion: reduce) {
    #community-space *,
    #community-space *::before,
    #community-space *::after {
        animation: none !important;
        transition: none !important;
    }
    #community-space .text-link:hover svg,
    #community-space .button:hover,
    #community-space .board-explainer[open] summary svg,
    .button:hover,
    .queue-more .text-link:hover svg {
        transform: none;
    }
}

/* The Guide Leaderboard's journey. The board's content root reads as a walk
   through the library: the reading table it opens on, then three worlds
   under it. The pine bindery where guides are made, the ruled ledger where
   the next books are chosen, and the lamp-lit shelf they arrive on. Each
   world lays a ground under its stretch of the page, painted out to the
   screen's edges by a border-image outset (ink, so the page never widens),
   and meets the world above at a gilt seam where the last world's page
   turns away. Every rule from here to the end of this sheet belongs to the
   board: it hangs off .board-journey, the class only the board's own root
   carries, or off the production card's stage track. /js/board-journey.js
   moves these pieces; without it, or with motion reduced, each one stands
   in its finished state. */
.board-world {
    position: relative;
    isolation: isolate;
    padding: 120px 0 72px;
}
.board-journey > .board-world:last-child {
    margin-bottom: -48px;
}
.board-world > .production-section {
    padding-top: 0;
}
.board-world > .board-layout {
    margin-top: 0;
}
.board-world > .published-section {
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
}
.board-ground,
.board-lamp,
.board-seam,
.board-leaf {
    position: absolute;
    z-index: -1;
    pointer-events: none;
}
.board-ground {
    inset: 0;
    border-image-slice: 0 fill;
    border-image-outset: 0 50vw;
}
.board-world--bindery .board-ground {
    border-image-source: linear-gradient(180deg, var(--spruce), var(--pine) 34%, var(--forest));
}
.board-world--ledger .board-ground {
    border-image-source: linear-gradient(180deg, var(--field), var(--parchment-bottom));
}
.board-world--library .board-ground {
    border-image-source: linear-gradient(180deg, var(--cream), var(--sun-pale) 58%, var(--cream));
}
.board-world--bindery .board-lamp {
    top: 24px;
    right: 0;
    width: min(620px, 90%);
    height: 520px;
    background: radial-gradient(closest-side, rgba(229, 197, 126, 0.2), rgba(229, 197, 126, 0.07) 58%, rgba(229, 197, 126, 0));
}
.board-world--library .board-lamp {
    top: 0;
    left: 6%;
    right: 6%;
    height: 440px;
    background: radial-gradient(farthest-side at 50% 0, rgba(229, 197, 126, 0.5), rgba(229, 197, 126, 0.14) 56%, rgba(229, 197, 126, 0));
}

/* the gilt seam: a tooled double rule broken by the bookplate's sprig, its
   two halves drawn outward from the sprig as the world comes up */
.board-seam {
    top: 0;
    left: 0;
    right: 0;
    display: flex;
    align-items: center;
    gap: 18px;
    height: 88px;
    color: rgba(156, 122, 51, 0.62);
}
.board-seam i {
    flex: 1;
    height: 4px;
    border-top: 1px solid currentColor;
    border-bottom: 1px solid currentColor;
}
.board-seam i:first-child {
    transform-origin: right;
}
.board-seam i:last-child {
    transform-origin: left;
}
#community-space .seam-mark {
    width: 26px;
    height: 26px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.board-world--bindery .board-seam {
    color: rgba(229, 197, 126, 0.62);
}
.board-world--bindery .seam-mark {
    color: var(--gold-warm);
}
.board-world--ledger .seam-mark,
.board-world--library .seam-mark {
    color: var(--sun);
}

/* the page that turns: a band in the colour of the world above, lying over
   the seam until the reader reaches it and then lifting away toward them.
   It exists only while the journey script is moving it. */
.board-leaf {
    display: none;
    top: 0;
    left: 0;
    right: 0;
    height: 88px;
    transform-origin: 50% 0;
    backface-visibility: hidden;
    border-image-slice: 0 fill;
    border-image-outset: 0 50vw;
    /* WebKit gives a transformed box painted only by border-image no backing store; a shadow forces one so the page turns on iOS */
    box-shadow: 0 0 0 transparent;
}
.board-journey[data-motion="on"] .board-leaf {
    display: block;
}
.board-world--bindery .board-leaf {
    border-image-source: linear-gradient(180deg, var(--paper) 55%, var(--cream));
}
.board-world--ledger .board-leaf {
    border-image-source: linear-gradient(180deg, var(--forest) 55%, var(--spruce));
}
/* the ledger's own ruled sheet is the page that turns onto the library */
.board-world--library .board-leaf {
    border-image-source: repeating-linear-gradient(180deg, var(--parchment-top) 0 21px, var(--border) 21px 22px);
}

/* the reading table: the gilt rule that closes the introduction, and the
   one gold action's sheen when it first catches the light */
.board-journey .hero-foot {
    position: relative;
}
.board-journey .hero-foot::before {
    content: "";
    position: absolute;
    top: -1px;
    left: 0;
    right: 0;
    height: 1px;
    background: linear-gradient(90deg, var(--gold-deep), var(--gold-light) 50%, var(--gold-deep));
    transform-origin: left;
    transform: scaleX(var(--draw, 1));
}
.board-journey .hero-actions .button--gold {
    position: relative;
    overflow: hidden;
}
.board-journey .hero-actions .button--gold:not(:disabled)::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 45%;
    background: linear-gradient(105deg, rgba(255, 249, 232, 0), rgba(255, 249, 232, 0.62) 50%, rgba(255, 249, 232, 0));
    transform: translateX(calc(var(--sheen, 4) * 100%));
    pointer-events: none;
}

/* the bindery: pine under the shelf of committed work, so its head reads in
   the chrome's own paper and the cards stand on it like objects on a bench */
.board-world--bindery .section-head h2 {
    color: var(--chrome-text);
}
.board-world--bindery .section-head p,
.board-world--bindery .empty {
    color: var(--sand);
}
.board-world--bindery .production-card {
    box-shadow: 0 22px 44px -26px rgba(6, 14, 9, 0.85);
}
/* the pine card would sink into a pine bench: it is lifted a step toward
   moss and edged in gilt, and its sand text still clears 4.5:1 on it */
.board-world--bindery .production-card--dark {
    background: linear-gradient(135deg, color-mix(in oklab, var(--moss) 55%, var(--spruce)), var(--spruce));
    border-color: rgba(229, 197, 126, 0.34);
}

/* the named stages of making a guide, in their one order: the ones behind
   filled in gold, the current one ringed and set in the ink, the rest
   waiting. A stage count, never a percentage or a date. */
.stage-track {
    position: relative;
    margin: 16px 0 0;
    padding: 0;
    list-style: none;
    color: var(--muted);
    font-family: var(--ff);
    font-size: 12px;
    line-height: 1.5;
}
.stage-track::before {
    content: "";
    position: absolute;
    top: 9px;
    bottom: 9px;
    left: 5px;
    width: 1px;
    background: var(--border);
}
.stage-track li {
    position: relative;
    padding: 0 0 4px 20px;
}
.stage-track li:last-child {
    padding-bottom: 0;
}
.stage-track li::before {
    content: "";
    position: absolute;
    top: 5px;
    left: 2px;
    width: 7px;
    height: 7px;
    border: 1px solid var(--border);
    border-radius: 50%;
    background: var(--parchment-top);
}
.stage-track .stage-done::after {
    content: "";
    position: absolute;
    top: 13px;
    bottom: -5px;
    left: 5px;
    width: 1px;
    background: var(--sun);
    transform-origin: top;
    transform: scaleY(var(--draw, 1));
}
.stage-track .stage-done::before {
    border-color: var(--sun);
    background: var(--sun);
}
.stage-track .stage-now {
    color: var(--bark);
    font-weight: 600;
}
.stage-track .stage-now::before {
    border-color: var(--sun);
    background: var(--gold-light);
    box-shadow: 0 0 0 3px rgba(201, 162, 75, 0.24);
}
.production-card--dark .stage-track {
    color: var(--sand);
}
.production-card--dark .stage-track::before {
    background: rgba(244, 234, 215, 0.2);
}
.production-card--dark .stage-track li::before {
    border-color: rgba(244, 234, 215, 0.35);
    background: var(--pine);
}
.production-card--dark .stage-track .stage-done::before,
.production-card--dark .stage-track .stage-now::before {
    border-color: var(--gold-warm);
    background: var(--gold-warm);
}
.production-card--dark .stage-track .stage-done::after {
    background: var(--gold-warm);
}
.production-card--dark .stage-track .stage-now {
    color: var(--chrome-text);
}
.production-card--dark .stage-track .stage-now::before {
    box-shadow: 0 0 0 3px rgba(229, 197, 126, 0.22);
}

/* the ledger's priority groups draw their rules from the label out, and the
   invitation beside them lies on the sheet as a card of its own */
.board-journey .tier-head::after {
    transform-origin: left;
    transform: scaleX(var(--draw, 1));
}
.board-world--ledger .invitation {
    box-shadow: 0 20px 40px -28px rgba(50, 44, 36, 0.45);
}

/* the library: the shelf the published books stand on, pine with a gilt
   edge that catches the lamp once as they arrive */
.board-shelf {
    position: relative;
    display: block;
    height: 12px;
    overflow: hidden;
    border-radius: 0 0 2px 2px;
    background: linear-gradient(180deg, var(--gold-deep) 0 1px, var(--moss) 1px, var(--spruce) 55%, var(--pine));
    box-shadow: 0 14px 22px -12px rgba(19, 41, 29, 0.55);
}
.board-shelf::after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 25%;
    height: 2px;
    background: linear-gradient(90deg, rgba(255, 245, 215, 0), rgba(255, 245, 215, 0.95) 50%, rgba(255, 245, 215, 0));
    transform: translateX(calc(var(--shine, 4) * 100%));
}

@media (max-width: 767px) {
    .board-world {
        padding: 96px 0 52px;
    }
    .board-seam,
    .board-leaf {
        height: 72px;
    }
    .board-seam {
        gap: 12px;
    }
    .board-world--bindery .board-lamp {
        height: 420px;
    }
}

/* Until the journey script takes the board (it marks the root
   data-motion), the parts it will bring in hold back a moment rather than
   flash up and vanish; the hold runs out on its own, so a page whose script
   never arrives shows everything within the second. */
@keyframes board-hold {
    from,
    to {
        opacity: 0;
    }
}
@media (prefers-reduced-motion: no-preference) {
    .board-journey:not([data-motion]) :is(.hero .eyebrow, .hero h1, .hero-description, .hero-actions, .hero-foot > *, .board-seam, .board-world > :not([aria-hidden])),
    .board-journey:not([data-motion]) .hero-foot::before {
        animation: board-hold 0.9s linear;
    }
}
/* The page over each seam is the one piece the script takes away rather
   than brings in, so through the same hold it already lies there, flat, the
   way the script will find it: the world's ground is never seen before the
   page that turns off it. The hold runs out the same way, leaving the seam
   bare for a page whose script never arrives. */
@keyframes board-leaf-hold {
    from,
    to {
        visibility: visible;
    }
}
@media screen and (prefers-reduced-motion: no-preference) {
    .board-journey:not([data-motion]) .board-leaf {
        display: block;
        visibility: hidden;
        animation: board-leaf-hold 0.9s linear;
    }
}

/* a printed board keeps the text and drops the worlds' grounds */
@media print {
    .board-ground,
    .board-lamp,
    .board-seam,
    .board-leaf,
    .board-shelf {
        display: none;
    }
    .board-world {
        padding: 24px 0;
    }
    .board-world--bindery .section-head h2,
    .board-world--bindery .section-head p,
    .board-world--bindery .empty {
        color: inherit;
    }
}

/* A Day at Ashwren (/a-day-at-ashwren): the people who use the library and
   what each of them does with it, told as one day. Every rule from here to
   the next page's block is this page's own, under .day or body.day-page, so
   no shared rule reaches in and no other page shifts.

   Each use case is a scene: its steps beside a reading table that holds what
   Ashwren hands that reader, one thing to a step, built from the product's
   own pieces rather than pictures of them. At rest every scene lies on the
   paper of its hour and every table is laid out finished, so a reader
   without script or motion reads the whole day. Where motion is welcome the
   page marks the root .day-live before it paints (DayAtAshwrenPage.razor):
   the scenes then share one sheet of paper whose light /js/day.js turns hour
   by hour, the sun rises out of the opening and sets over the lamp, and each
   table fills as its steps are read. Everything under that mark is screen
   only, and it dims or lifts a thing, never hides it. */
.app-main:has(> .day) {
    max-width: none;
    padding: 0;
}
.day {
    /* the pinned header's height, which an in-page jump lands under */
    --day-head: calc(69px + env(safe-area-inset-top, 0px));
    --day-gutter: clamp(20px, 5vw, 64px);
    --day-width: min(1160px, 100% - 2 * var(--day-gutter));
    --day-ease: cubic-bezier(0.16, 1, 0.3, 1);
    /* the site's gilt ink, deepened toward bark so the hours and small
       labels set in it hold 4.5:1 on every paper of the day */
    --day-gilt-ink: color-mix(in srgb, var(--sun) 60%, var(--bark));
    /* the light of each hour, on the paper the scenes lie on */
    --day-morning: color-mix(in srgb, var(--sun-pale) 55%, var(--parchment-top));
    --day-forenoon: color-mix(in srgb, var(--leaf-pale) 50%, var(--parchment-top));
    --day-midday: var(--paper);
    --day-afternoon: color-mix(in srgb, var(--cream) 70%, var(--paper));
    --day-evening: color-mix(in srgb, var(--gold-warm) 30%, var(--paper));
    overflow-x: clip;
    color: var(--bark);
    font-family: var(--ff-text);
}
.day-sr {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}
/* how far the slate has opened; only the slate reads it, so scrubbing it
   restyles the slate's own box and nothing inside it */
@property --day-room {
    syntax: "<number>";
    inherits: false;
    initial-value: 1;
}
/* the one sheet of paper the scenes share while the day is played */
.day-paper {
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
}

/* first light: the title set a letter at a time over a dark sky, the sun on
   the horizon, and the day's timetable on the ground below it */
.day-dawn {
    background: radial-gradient(120% 95% at 50% 100%, color-mix(in srgb, var(--gold) 34%, var(--moss)) 0%,
        var(--spruce) 48%, var(--forest) 100%);
    color: var(--chrome-text);
    text-align: center;
}
.day-dawn-copy {
    width: var(--day-width);
    margin: 0 auto;
    padding-top: clamp(40px, 9vh, 104px);
}
.day-title {
    margin: 0;
    color: var(--chrome-text);
    font-family: var(--ff-display);
    font-size: clamp(46px, 9vw, 108px);
    line-height: 1.02;
    letter-spacing: -0.02em;
    text-wrap: balance;
}
.day-type-word {
    display: inline-block;
    white-space: nowrap;
}
.day-type-letter {
    display: inline-block;
}
.day-lede {
    max-width: 34rem;
    margin: 20px auto 0;
    color: var(--cream);
    font-size: 1.125rem;
    line-height: 1.7;
    text-wrap: pretty;
}
.day-horizon {
    --sun-size: clamp(84px, 11vw, 150px);
    position: relative;
    height: calc(var(--sun-size) * 1.3);
    margin-top: clamp(8px, 3vh, 32px);
    overflow: hidden;
}
.day-horizon::after {
    content: "";
    position: absolute;
    right: 0;
    bottom: 0;
    left: 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--gold) 18%, var(--gold-light) 50%, var(--gold) 82%, transparent);
}
/* the sun stands --rise percent of its height above half-risen; the scroll
   raises it at dawn and lowers it at dusk through that one number */
.day-sun {
    --rise: 0;
    position: absolute;
    bottom: 0;
    left: 50%;
    width: var(--sun-size);
    aspect-ratio: 1;
    border-radius: 50%;
    background: radial-gradient(circle at 50% 40%, var(--gold-light), var(--gold) 62%, var(--gold-deep));
    box-shadow: 0 0 60px 22px color-mix(in srgb, var(--gold-warm) 30%, transparent),
        0 0 180px 70px color-mix(in srgb, var(--gold) 14%, transparent);
    translate: -50% calc(50% - var(--rise) * 1%);
}
.day-cast {
    padding: clamp(14px, 3vh, 32px) var(--day-gutter) clamp(36px, 7vh, 72px);
    background: linear-gradient(180deg, var(--pine), var(--forest));
}
.day-cast ol {
    display: grid;
    max-width: 26rem;
    margin: 0 auto;
    padding: 0;
    list-style: none;
}
.day-cast li + li {
    border-top: 1px solid var(--rule-dark);
}
.day-cast a {
    display: grid;
    grid-template-columns: 5.2em minmax(0, 1fr);
    align-items: baseline;
    min-height: 48px;
    padding: 10px 4px;
    color: var(--chrome-text);
    text-align: left;
    text-decoration: none;
}
.day-cast time {
    color: var(--gold-warm);
    font-size: 0.9375rem;
    font-style: italic;
}
.day-cast-who {
    font-family: var(--ff-display);
    font-size: clamp(1.125rem, 1.5vw, 1.3125rem);
    line-height: 1.25;
    transition: color 150ms ease;
}
.day-cast a:hover .day-cast-who {
    color: var(--gold-warm);
}
@media (min-width: 760px) {
    .day-cast ol {
        grid-template-columns: repeat(6, minmax(0, 1fr));
        max-width: 1160px;
    }
    .day-cast li + li {
        border-top: 0;
        border-left: 1px solid var(--rule-dark);
    }
    .day-cast a {
        grid-template-columns: minmax(0, 1fr);
        justify-items: center;
        row-gap: 4px;
        padding: 6px 10px;
        text-align: center;
    }
}

/* the scenes: the steps beside the table they fill, each on its hour's paper */
.day-scene {
    --ground: var(--day-morning);
    display: grid;
    grid-template-areas: "head" "stage" "steps" "actions";
    row-gap: clamp(28px, 6vw, 44px);
    padding: clamp(64px, 11vh, 128px) max(var(--day-gutter), (100% - 1160px) / 2);
    background: var(--ground);
    scroll-margin-top: var(--day-head);
}
.day-scene[data-hour="forenoon"] {
    --ground: var(--day-forenoon);
}
.day-scene[data-hour="midday"] {
    --ground: var(--day-midday);
}
.day-scene[data-hour="afternoon"] {
    --ground: var(--day-afternoon);
}
.day-scene[data-hour="evening"] {
    --ground: var(--day-evening);
}
.day-scene-head {
    grid-area: head;
    max-width: 36rem;
}
.day-stage {
    grid-area: stage;
    margin: 0;
}
.day-scene > .day-steps {
    grid-area: steps;
}
.day-scene > .day-actions {
    grid-area: actions;
    margin: 0;
}
/* side by side, the table holds in view while its steps are read past it */
@media (min-width: 960px) {
    .day-scene {
        grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
        grid-template-rows: auto auto 1fr;
        grid-template-areas: "head stage" "steps stage" "actions stage";
        column-gap: clamp(48px, 6vw, 96px);
        row-gap: 0;
    }
    .day-scene-flip {
        grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
        grid-template-areas: "stage head" "stage steps" "stage actions";
    }
    .day-stage {
        position: sticky;
        top: calc(var(--day-head) + 4vh);
        align-self: start;
    }
    .day-scene > .day-steps {
        --gap: clamp(32px, 7vh, 64px);
        margin-top: 44px;
    }
    .day-scene > .day-actions {
        align-self: start;
        margin-top: 28px;
    }
}
.day-time {
    margin: 0 0 10px;
    color: var(--day-gilt-ink);
    font-size: 1.25rem;
    font-style: italic;
    line-height: 1.2;
}
.day h2 {
    margin: 0;
    font-family: var(--ff-display);
    font-size: clamp(32px, 4.2vw, 52px);
    line-height: 1.08;
    letter-spacing: -0.015em;
    text-wrap: balance;
}
/* the gold rule under a scene's heading, drawn as an element so it can draw
   itself and catch the light once, as the catalog's titles do */
.day-rule {
    position: relative;
    display: block;
    width: 72px;
    height: 3px;
    margin-top: 18px;
    overflow: hidden;
    background: linear-gradient(var(--sun), var(--sun)) 0 50% / 100% 1px no-repeat;
    transform-origin: 0 50%;
}
:is(.day-slate, .day-night) .day-rule {
    background-image: linear-gradient(var(--gold), var(--gold));
}
.day-rule i {
    position: absolute;
    top: 0;
    bottom: 0;
    left: -40%;
    width: 40%;
    background: linear-gradient(90deg, transparent, var(--gold-light) 50%, transparent);
}
.day-summary {
    margin: 16px 0 0;
    color: var(--bark-soft);
    font-size: 1.125rem;
    line-height: 1.65;
    text-wrap: pretty;
}
.day-stage figcaption {
    margin-top: 14px;
    color: var(--muted);
    font-size: 0.875rem;
    font-style: italic;
    line-height: 1.5;
}

/* the steps: a real sequence, so numbered, and threaded numeral to numeral */
.day-steps {
    --gap: 22px;
    display: grid;
    gap: var(--gap);
    max-width: 36rem;
    margin: 0;
    padding: 0;
    list-style: none;
    counter-reset: day-step;
}
.day-steps > li {
    position: relative;
    padding-left: 48px;
    color: var(--bark-soft);
    font-size: 1.0625rem;
    line-height: 1.65;
    counter-increment: day-step;
}
.day-steps > li::before {
    content: counter(day-step);
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1;
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    border: 1px solid color-mix(in srgb, var(--sun) 60%, transparent);
    border-radius: 50%;
    background: var(--parchment-top);
    color: var(--day-gilt-ink);
    font-family: var(--ff-display);
    font-size: 1rem;
    line-height: 1;
}
.day-steps > li:not(:last-child)::after {
    content: "";
    position: absolute;
    top: 36px;
    bottom: calc(4px - var(--gap));
    left: 16px;
    width: 1px;
    background: color-mix(in srgb, var(--sun) 45%, transparent);
    transform-origin: 50% 0;
}
.day-steps strong {
    display: block;
    margin-bottom: 2px;
    color: var(--bark);
    font-family: var(--ff-display);
    font-size: 1.25rem;
    font-weight: 400;
    line-height: 1.3;
}
.day-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0 28px;
    margin: 24px 0 0;
}
.day-actions-centred {
    justify-content: center;
}
.day-link {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    color: var(--leaf);
    font-family: var(--ff);
    font-size: 0.9375rem;
    font-weight: 600;
    text-decoration: underline;
    text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);
    text-decoration-thickness: 1px;
    text-underline-offset: 5px;
    transition: color 150ms ease, text-decoration-color 150ms ease;
}
/* hovered, a link keeps its leaf and firms its underline: the site's lighter
   hover leaf falls under 4.5:1 on the afternoon and evening papers */
.day-link:hover {
    color: var(--leaf);
    text-decoration-color: currentColor;
}
.day a:focus-visible {
    outline: 2px solid var(--sun);
    outline-offset: 3px;
    border-radius: 2px;
}
.day :is(.day-dawn, .day-slate, .day-night, .day-tomorrow) a:focus-visible {
    outline-color: var(--gold-warm);
}

/* The reading table: a blotter in the library's cream, and on it the things
   themselves in the site's own parchment, each laid a little askew. Its type
   is set in em from one size, so a table scales as one piece. */
.day-table {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: start;
    gap: clamp(10px, 1.5vw, 18px);
    padding: clamp(14px, 2.6vw, 30px);
    border-radius: 6px;
    background: linear-gradient(165deg, color-mix(in srgb, var(--border) 40%, var(--cream)),
        color-mix(in srgb, var(--border) 85%, var(--cream)));
    box-shadow: inset 0 0 0 1px rgba(156, 122, 51, 0.22), inset 0 2px 40px rgba(92, 80, 68, 0.14),
        0 26px 44px -30px rgba(34, 48, 42, 0.55);
    color: var(--bark);
    font-family: var(--ff);
    /* the tallest table still stands whole beside its steps on a short screen */
    font-size: clamp(12.5px, min(0.55vw + 7px, 1.5vh), 13.5px);
    line-height: 1.45;
}
.day-table ol,
.day-table ul {
    margin: 0;
    padding: 0;
    list-style: none;
}
.day-table [data-step] {
    outline: 2px solid transparent;
    outline-offset: 3px;
}
.day-obj {
    --tilt: 0deg;
    position: relative;
    display: grid;
    align-content: start;
    gap: 0.2em;
    padding: 1.1em 1.2em;
    border-radius: 3px;
    background: linear-gradient(180deg, var(--parchment-top), var(--parchment-bottom));
    box-shadow: 0 1px 2px rgba(58, 54, 50, 0.14), 0 12px 22px -14px rgba(58, 54, 50, 0.45);
    rotate: var(--tilt);
}
.day-obj:nth-child(3n + 1) {
    --tilt: -0.7deg;
}
.day-obj:nth-child(3n + 2) {
    --tilt: 0.6deg;
}
/* small gilt labels on the tables' papers, a shade deeper again so they hold
   4.5:1 at their size */
.day-label {
    display: block;
    color: color-mix(in srgb, var(--sun) 50%, var(--bark));
    font-size: max(0.85em, 11px);
    font-weight: 600;
    letter-spacing: 0.02em;
}
.day-chip,
.day-topics li {
    justify-self: start;
    padding: 0.15em 0.75em;
    border-radius: 99px;
    background: var(--leaf-pale);
    color: var(--leaf);
    font-size: max(0.85em, 11px);
    font-weight: 600;
}
.day-field {
    display: block;
    padding: 0.45em 0.6em;
    border: 1px solid var(--border);
    border-radius: 3px;
    background: var(--field);
    color: var(--muted);
    font-size: 0.9em;
}
/* a book from the catalog, its oxblood ribbon over the leaf-green head */
.day-card {
    grid-area: card;
    padding-top: 1.3em;
    border-top: 3px solid var(--leaf);
}
.day-card::after {
    content: "";
    position: absolute;
    top: -3px;
    right: 1.1em;
    width: 0.8em;
    height: 2.2em;
    background: var(--ribbon-face);
    clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 78%, 0 100%);
}
.day-card-title,
.day-leaf-title,
.day-part-name,
.day-parts,
.day-sheet,
.day-board li {
    font-family: var(--ff-display);
}
.day-card-title {
    padding-right: 1.4em;
    font-size: 1.45em;
    line-height: 1.1;
}
.day-card-author,
.day-leaf-work {
    color: var(--muted);
    font-family: var(--ff-text);
    font-style: italic;
}
.day-card .day-chip {
    margin-top: 0.6em;
}
.day-slip {
    grid-area: slip;
    background: var(--field);
}
.day-slip-copy {
    color: var(--leaf);
    font-weight: 600;
    text-decoration: underline;
    text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);
    text-underline-offset: 3px;
}
/* a leaf of the student guide, its four parts under their numerals */
.day-leaf {
    grid-area: leaf;
    padding: 1.4em 1.3em;
    border-top: 3px solid var(--sun);
}
.day-leaf-title {
    font-size: 1.9em;
    line-height: 1.05;
}
.day-leaf-band {
    color: var(--day-gilt-ink);
    font-weight: 600;
}
.day-leaf-band small {
    color: var(--muted);
    font-weight: 400;
}
.day-parts {
    display: grid;
    gap: 0.55em;
    margin-top: 0.9em !important;
    padding-top: 0.9em !important;
    border-top: 1px solid var(--border-light);
    font-size: 1.15em;
}
.day-parts span,
.day-part-name span {
    display: inline-block;
    min-width: 1.9em;
    color: var(--day-gilt-ink);
}
/* a printed sheet: ruled at its band's line height (--rule, in points) and
   stacked on the copies under it */
.day-sheet {
    --rule: 36;
    min-height: 6.5em;
    background: repeating-linear-gradient(180deg, transparent 0 calc(var(--rule) * 0.34px - 1px),
            color-mix(in srgb, var(--sun) 35%, var(--border)) 0 calc(var(--rule) * 0.34px))
        0 2.6em / 100% calc(100% - 3.2em) no-repeat,
        linear-gradient(180deg, var(--parchment-top), var(--parchment-bottom));
    box-shadow: 3px 3px 0 -1px var(--parchment-bottom), 3px 3px 0 0 var(--border),
        6px 6px 0 -1px var(--parchment-bottom), 6px 6px 0 0 var(--border),
        0 14px 22px -14px rgba(58, 54, 50, 0.45);
    font-size: 1.1em;
}
.day-print {
    grid-area: print;
    font-size: 1em;
}

/* 9 a.m.: the band ladder, the companion open at its first question, the
   thinking tags, and a set for every desk */
.day-ladder {
    grid-area: ladder;
    gap: 0.35em;
}
.day-ladder li {
    position: relative;
    padding: 0.3em 0.6em 0.3em 1.9em;
    border-radius: 2px;
    color: var(--muted);
}
.day-ladder li::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 0.6em;
    width: 0.7em;
    height: 0.7em;
    margin-top: -0.35em;
    border: 1.5px solid var(--border);
    border-radius: 50%;
    background: var(--paper);
}
.day-ladder .is-offered {
    background: var(--leaf-pale);
    color: var(--bark);
    font-weight: 600;
}
.day-ladder .is-offered::before {
    border-color: var(--leaf);
}
.day-ladder .is-recommended::before {
    border-color: var(--sun);
    background: var(--gold);
}
.day-companion {
    grid-area: companion;
    border-left: 3px solid var(--leaf);
}
.day-companion-q,
.day-companion-a,
.day-part-text {
    font-family: var(--ff-text);
    line-height: 1.55;
}
.day-companion-q {
    margin-bottom: 0.8em;
    font-size: 1.05em;
}
.day-companion-a {
    color: var(--bark-soft);
    font-style: italic;
}
.day-tags {
    grid-area: tags;
    display: flex;
    flex-wrap: wrap;
    gap: 0.4em;
    padding: 0.2em;
}
.day-tags li {
    padding: 0.2em 0.6em;
    border: 1px solid color-mix(in srgb, var(--sun) 45%, transparent);
    border-radius: 2px;
    background: color-mix(in srgb, var(--parchment-top) 60%, transparent);
    color: var(--muted);
    font-size: max(0.9em, 11px);
}
.day-tags .is-asked {
    border-color: var(--sun);
    background: var(--sun-pale);
    color: var(--bark);
    font-weight: 600;
}
.day-stack {
    grid-area: stack;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 1.2em;
    padding-right: 6px;
}

/* 11 a.m.: one book, a sheet for each of its three bands, a meetup */
#day-coop .day-table,
#day-student .day-table {
    grid-template-columns: minmax(0, 1fr);
}
.day-sheets {
    grid-area: sheets;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: clamp(10px, 1.5vw, 18px);
    padding-right: 6px !important;
}
.day-sheets .day-sheet {
    min-height: 10em;
}
.day-composer {
    grid-area: composer;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6em;
}
.day-composer .day-field {
    flex: 1 1 14em;
}

/* 1 p.m.: the student guide itself, a part to each step */
.day-leaf-full {
    padding-block: 0.4em;
}
.day-part {
    padding: 0.9em 0;
}
.day-part + .day-part {
    border-top: 1px solid var(--border-light);
}
.day-part:has(> .day-copy) {
    padding-top: 0;
    border-top: 0;
}
.day-part-name {
    display: block;
    font-size: 1.2em;
}
.day-part-text {
    display: block;
    margin-top: 0.3em;
    color: var(--bark-soft);
}
.day-part-text.is-passage {
    padding-left: 0.8em;
    border-left: 2px solid var(--gold);
    color: var(--bark);
    font-style: italic;
}
.day-part-text b {
    margin-right: 0.3em;
    border-bottom: 1px solid var(--sun);
    color: var(--bark);
    font-family: var(--ff-display);
    font-size: 1.1em;
    font-weight: 400;
}
.day-copy {
    display: block;
    width: 100%;
    max-width: 24em;
    height: auto;
}
.day-copy-rules {
    fill: none;
    stroke: var(--border);
    stroke-width: 0.6;
}
/* the copy is written a word to a stroke, each measured as one unit long
   (pathLength="1"), so one offset draws or undraws it; at rest all drawn */
.day-script {
    fill: none;
    stroke: var(--ink);
    stroke-width: 0.9;
    stroke-linecap: round;
    stroke-linejoin: round;
    stroke-dasharray: 1;
    stroke-dashoffset: 0;
}

/* 4 p.m.: the feed's composer, a suggestion, the board's groups, a guide's
   stages */
#day-community .day-table {
    grid-template-areas: "post suggest" "board board" "track track";
}
#day-family .day-table {
    grid-template-areas: "card leaf" "slip leaf" "print leaf";
}
#day-classroom .day-table {
    grid-template-areas: "ladder companion" "tags companion" "stack stack";
}
/* a phone gives the companion the table's whole width, under the ladder and
   the tags, so its answer is not set a word to a line */
@media (max-width: 599px) {
    #day-classroom .day-table {
        grid-template-areas: "ladder tags" "companion companion" "stack stack";
    }
}
#day-coop .day-table {
    grid-template-areas: "card" "sheets" "composer";
}
#day-student .day-table {
    grid-template-areas: "leaf";
}
.day-post {
    grid-area: post;
}
.day-suggest {
    grid-area: suggest;
    gap: 0.45em;
}
.day-topics {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35em;
    margin-top: 0.5em !important;
}
.day-board {
    grid-area: board;
    gap: 0.5em;
}
.day-board li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1em;
    font-size: 1.1em;
}
.day-books {
    display: flex;
    gap: 0.35em;
}
.day-books i {
    width: 1.5em;
    height: 1.9em;
    border-radius: 2px 3px 3px 2px;
    background: var(--leaf);
}
.day-books i:nth-child(2) {
    background: var(--gold);
}
.day-books i:nth-child(3) {
    background: var(--cream);
    box-shadow: inset 0 0 0 1px var(--border);
}
.day-track {
    grid-area: track;
    grid-template-columns: repeat(4, minmax(0, 1fr));
}
.day-track li {
    position: relative;
    padding: 1.5em 0.4em 0 0;
    color: var(--muted);
    font-size: 0.92em;
    line-height: 1.3;
}
.day-track li::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 0.9em;
    height: 0.9em;
    border: 1.5px solid var(--sun);
    border-radius: 50%;
    background: var(--gold-light);
}
.day-track li:not(:last-child)::after {
    content: "";
    position: absolute;
    top: 0.45em;
    right: 0.3em;
    left: 1.2em;
    height: 1px;
    background: var(--sun);
}

/* 8 a.m.: the slate between the family's breakfast and the teacher's class,
   a sheet's first problems chalked up on it */
.day-slate {
    display: grid;
    gap: clamp(28px, 4vw, 64px);
    align-items: center;
    padding: clamp(56px, 9vh, 104px) max(var(--day-gutter), (100% - 1160px) / 2);
    border-block: 1px solid rgba(201, 162, 75, 0.3);
    background: radial-gradient(120% 140% at 15% 0%, color-mix(in srgb, var(--moss) 55%, var(--spruce)), var(--spruce) 55%, var(--pine));
    color: var(--chrome-text);
    scroll-margin-top: var(--day-head);
}
.day-slate .day-summary {
    color: var(--cream);
}
.day-slate-copy,
.day-night-copy {
    max-width: 36rem;
}
.day-chalk {
    margin: 0;
}
.day-facts {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.25em 1.6em;
    margin: 0;
    padding: 0;
    list-style: none;
    font-family: var(--ff-display);
    font-size: clamp(26px, 3.2vw, 40px);
    line-height: 1.6;
}
.day-facts li {
    display: flex;
    align-items: baseline;
    gap: 0.35em;
    white-space: nowrap;
}
.day-blank {
    flex: 1;
    max-width: 2.2em;
    border-bottom: 2px solid color-mix(in srgb, var(--chrome-text) 55%, transparent);
}
.day-slate figcaption,
.day-note {
    margin-top: 18px;
    color: var(--sand);
    font-size: 0.9375rem;
    font-style: italic;
    line-height: 1.6;
}
@media (min-width: 960px) {
    .day-slate {
        grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    }
}

/* 9 p.m.: the sun goes down over the evening's paper, and the ledger lies
   under the lamp */
.day-night {
    background: linear-gradient(180deg, var(--spruce), var(--pine) 45%, var(--forest));
    color: var(--chrome-text);
    scroll-margin-top: var(--day-head);
}
.day-dusk {
    margin-top: 0;
    background: linear-gradient(180deg, var(--day-evening), color-mix(in srgb, var(--gold-warm) 55%, var(--moss)) 55%,
        color-mix(in srgb, var(--gold) 22%, var(--spruce)));
}
.day-night-inner {
    display: grid;
    gap: clamp(32px, 5vw, 80px);
    width: var(--day-width);
    margin: 0 auto;
    padding: clamp(48px, 8vh, 96px) 0 clamp(72px, 12vh, 128px);
}
@media (min-width: 960px) {
    .day-night-inner {
        grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
        align-items: center;
    }
}
:is(.day-slate, .day-night, .day-tomorrow) .day-time,
:is(.day-slate, .day-night) .day-link {
    color: var(--gold-warm);
}
.day-night .day-summary {
    color: var(--cream);
}
:is(.day-slate, .day-night) .day-link:hover {
    color: var(--chrome-text);
}
.day-desk {
    position: relative;
    padding: clamp(24px, 5vw, 64px) 0 0;
}
.day-lamp {
    position: absolute;
    inset: -20% -10% -10%;
    background: radial-gradient(50% 50% at 50% 35%, color-mix(in srgb, var(--gold-warm) 28%, transparent), transparent 72%);
    pointer-events: none;
}
.day-ledger {
    position: relative;
    margin: 0;
    padding: 0;
    overflow: hidden;
    list-style: none;
    border: 1px solid rgba(184, 117, 8, 0.25);
    border-radius: 8px;
    background: linear-gradient(180deg, var(--parchment-top), var(--parchment-bottom));
    box-shadow: 0 24px 60px rgba(6, 14, 9, 0.45);
    color: var(--bark);
}
.day-ledger li {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding: 18px 22px;
}
.day-ledger li + li {
    border-top: 1px solid var(--border-light);
}
.day-ledger li.is-gilded {
    background: linear-gradient(180deg, var(--sun-pale), rgba(244, 234, 215, 0) 80%);
    box-shadow: inset 0 3px 0 var(--gold-deep), inset 0 -1px 0 var(--gold-deep);
}
.day-ledger-name,
.day-ledger-price {
    font-family: var(--ff-display);
    font-size: 1.3125rem;
}
.day-ledger-price {
    color: var(--leaf);
}
.day-leader {
    flex: 1;
    min-width: 1.5rem;
    border-bottom: 1px dotted var(--border);
    transform-origin: 0 50%;
}

/* tomorrow: the one gold action */
.day-tomorrow {
    padding: clamp(72px, 12vh, 128px) var(--day-gutter) clamp(88px, 14vh, 160px);
    border-top: 1px solid var(--rule-dark);
    background: linear-gradient(180deg, var(--pine), var(--forest));
    color: var(--chrome-text);
    text-align: center;
}
.day-tomorrow .day-link {
    color: var(--sand);
}
.day-tomorrow .day-link:hover {
    color: var(--chrome-text);
}
.day-cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 52px;
    margin-top: 30px;
    padding: 18px 34px;
    border-radius: 5px;
    background: linear-gradient(180deg, var(--gold-light), var(--gold-deep));
    box-shadow: 0 10px 26px rgba(201, 162, 75, 0.32);
    color: var(--ink);
    font-family: var(--ff);
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.12em;
    line-height: 1;
    text-decoration: none;
    text-transform: uppercase;
    transition: translate 200ms ease, box-shadow 200ms ease;
}
.day-cta:hover {
    color: var(--ink);
    translate: 0 -1px;
    box-shadow: 0 14px 30px rgba(201, 162, 75, 0.42);
}
.day-tomorrow .day-actions {
    margin-top: 28px;
}

/* the page ends on night, so the footer and the screen's end are night too */
body.day-page .app-footer {
    border-top-color: var(--rule-dark);
    background-color: var(--forest);
    color: var(--sand);
}
html.at-end body.day-page:not(.sidebar-open) {
    background-color: var(--forest);
}

@media (prefers-reduced-motion: no-preference) {
    /* the one entrance, at load: the title's letters settle into line like
       set type, the horizon is drawn and the sun comes up onto it, then the
       day's timetable is set out below */
    .day-type-letter {
        animation: day-set 900ms var(--day-ease) both;
        animation-delay: calc(160ms + var(--i) * 45ms);
    }
    .day-lede {
        animation: day-rise 900ms var(--day-ease) 700ms both;
    }
    .day-dawn .day-horizon::after {
        animation: day-draw 1.6s var(--day-ease) 400ms both;
    }
    .day-dawn .day-sun {
        animation: day-sunrise 2.4s var(--day-ease) 500ms both;
    }
    .day-cast li {
        animation: day-rise 800ms var(--day-ease) both;
        animation-delay: calc(1100ms + var(--n) * 90ms);
    }
    @keyframes day-set {
        from {
            opacity: 0;
            transform: translateY(-0.32em) rotate(-5deg);
        }
    }
    @keyframes day-rise {
        from {
            opacity: 0;
            translate: 0 12px;
        }
    }
    @keyframes day-draw {
        from {
            scale: 0 1;
        }
    }
    @keyframes day-sunrise {
        from {
            translate: -50% 100%;
        }
    }
}
@media screen and (prefers-reduced-motion: no-preference) {
    /* the day played: one paper under every scene, lit for the hour the
       reader is in */
    html.day-live .day-scene {
        background: transparent;
    }
    html.day-live .day-paper {
        background-color: var(--day-morning);
        transition: background-color 1.1s cubic-bezier(0.25, 1, 0.5, 1);
    }
    html.day-live .day-paper[data-hour="forenoon"] {
        background-color: var(--day-forenoon);
    }
    html.day-live .day-paper[data-hour="midday"] {
        background-color: var(--day-midday);
    }
    html.day-live .day-paper[data-hour="afternoon"] {
        background-color: var(--day-afternoon);
    }
    html.day-live .day-paper[data-hour="evening"] {
        background-color: var(--day-evening);
    }
    /* the slate opens as the reader walks into it, the way the catalog's
       reading room does: its pine starts as a panel inside the column and
       widens to both screen edges, its corners squaring as it goes */
    html.day-live .day-slate {
        --day-room: 1;
        clip-path: inset(0 calc((1 - var(--day-room)) * max(8px, (100% - 1160px) / 2 - 32px))
            round calc((1 - var(--day-room)) * 18px));
    }
    /* a thing waits just above the table, faint, until its step is reached,
       then is laid down; the one just laid is ringed in gold */
    html.day-live .day-table [data-step] {
        transition: opacity 0.6s ease, translate 0.8s var(--day-ease), outline-color 0.5s ease;
    }
    html.day-live .day-table [data-step]:not(.is-laid) {
        opacity: 0.16;
        translate: 0 -14px;
    }
    html.day-live .day-table .is-here {
        outline-color: color-mix(in srgb, var(--gold) 85%, transparent);
    }
    html.day-live .day-script {
        transition: stroke-dashoffset 0.28s linear calc(0.35s + var(--w) * 0.22s);
    }
    html.day-live [data-step]:not(.is-laid) .day-script {
        stroke-dashoffset: 1;
        transition-delay: 0s;
    }
    /* a step reached is gilded, and the thread to it drawn down */
    html.day-live .day-steps > li::before {
        transition: background-color 0.5s ease, border-color 0.5s ease, color 0.5s ease;
    }
    html.day-live .day-steps > li.is-reached::before {
        border-color: var(--gold-deep);
        background: var(--gold-light);
        color: var(--ink);
    }
    html.day-live .day-steps > li:not(:last-child)::after {
        scale: 1 0;
        transition: scale 0.7s var(--day-ease);
    }
    html.day-live .day-steps > li:has(+ li.is-reached)::after {
        scale: 1 1;
    }
}
@media (prefers-reduced-motion: reduce) {
    .day-link,
    .day-cta,
    .day-cast-who {
        transition: none;
    }
    .day-cta:hover {
        translate: none;
    }
}
/* printed, the page is at rest: nothing a scroll had not yet reached is left
   faint or lifted on paper */
@media print {
    .day [style] {
        opacity: 1 !important;
        transform: none !important;
    }
}

/* The library, alive: the catalog and the pages beneath it (/works, a work,
   its guides, their companions and the adapt form), staged as one walk
   through the library. Everything from here to the end of the file belongs to
   those pages alone: each rule is keyed on a class only they render, or on a
   mark one of them sets on a surface only they render (.library-arriving on
   the root for the instant before the entrance, .library-motion while motion
   is on, and data-tone on the page's own paper layer below for the paper the
   reader has walked into). /js/library.js drives the motion. Every rule
   states the page at rest, so reduced motion, a missing script and the
   printer all read it whole. */

/* Before the entrance the page waits unseen, so nothing shows and then
   vanishes. library.js lifts the mark as it takes over; if it never does, the
   release below brings the page in on its own. */
html.library-arriving .app-main > :not(script, link, .library-paper) {
    opacity: 0;
    animation: library-release 0.5s ease 1.8s forwards;
}
@keyframes library-release {
    to {
        opacity: 1;
    }
}

/* The paper warms and cools under the reader as they pass from room to room:
   the page's own paper layer — rendered by LibraryMotion inside the page's
   content — changes colour, and no text is repainted for it. The layer and
   its data-tone mark leave the DOM with the page, so the repaint can never
   reach the shell's shared .app-background or a sibling page when the
   passes merge. */
.library-paper {
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    transition: background-color 1.1s cubic-bezier(0.25, 1, 0.5, 1);
}
.library-paper[data-tone="cream"] {
    background-color: color-mix(in srgb, var(--paper) 45%, var(--cream));
}
.library-paper[data-tone="vellum"] {
    background-color: color-mix(in srgb, var(--paper) 45%, var(--leaf-pale));
}
/* the small gold labels deepen while a tone is under them, so they hold
   4.5:1 on cream and vellum (4.58 and 4.84) where plain sun would drop to
   3.2; on the page's own paper they keep the sun they were set in */
.library-paper ~ .guide :is(.opening, .closing, .strong-answer) > .label,
.library-paper ~ .guide.companion p.label {
    transition: color 1.1s cubic-bezier(0.25, 1, 0.5, 1);
}
.library-paper[data-tone] ~ .guide :is(.opening, .closing, .strong-answer) > .label,
.library-paper[data-tone] ~ .guide.companion p.label {
    color: color-mix(in srgb, var(--sun) 70%, var(--bark));
}

/* How far a room has opened. Only the room itself reads it, so it is
   registered as not inherited: scrubbing it on scroll restyles the room's
   own box, not every line inside it. */
@property --room {
    syntax: "<number>";
    inherits: false;
    initial-value: 1;
}

/* a title's letters settle one by one, and are rejoined into plain text once
   they land, so the heading keeps its kerning at rest */
.set-word {
    display: inline-block;
    white-space: nowrap;
}
.set-letter {
    display: inline-block;
}

/* The gold rule under a title, drawn as an element so it can draw itself and
   catch the light once. On a page head its middle row lies exactly over the
   sun hairline it stands in for; under a guide's hero band it closes the band.
   It is three pixels tall so the glint has room above and below the line, and
   it clips with overflow rather than clip-path, which would still let the
   glint's travel widen the page's scroll. */
.page-head:has(> .library-rule) {
    position: relative;
}
html.library-motion .page-head:has(> .library-rule) {
    border-bottom-color: transparent;
}
.library-rule {
    --line: var(--sun);
    position: absolute;
    right: 0;
    bottom: -2px;
    left: 0;
    height: 3px;
    overflow: hidden;
    background: linear-gradient(var(--line), var(--line)) 0 50% / 100% 1px no-repeat;
    transform-origin: 0 50%;
    pointer-events: none;
}
.guide-head > .library-rule {
    --line: color-mix(in srgb, var(--sun) 55%, transparent);
    bottom: -1px;
}
.library-rule i {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 24%;
    background: linear-gradient(90deg, transparent, var(--gold-light) 50%, transparent);
    opacity: 0;
}
.library-lede {
    max-width: 34rem;
    margin: 10px 0 0;
    color: var(--muted);
    font-family: var(--ff-text);
    font-size: 16px;
    font-style: italic;
    line-height: 1.6;
}

/* the shelf: cards tip up onto it, and each card's ribbon drops into place */
html.library-motion ul.works {
    perspective: 1400px;
}
@media screen {
    html.library-motion .book-card {
        --ribbon: 1;
    }
    html.library-motion .book-card::before {
        transform: scaleY(var(--ribbon));
        transform-origin: 50% 0;
    }
}

/* The band trail: the five bands down one ruled line, each stop ruled at the
   line height its guides print. From 960px the heading stands beside the
   trail and stays in view while the stops pass it. */
.band-trail {
    margin-top: 104px;
}
.band-trail-head h2,
.library-room > h2 {
    margin: 0;
    color: var(--bark);
    font-size: clamp(24px, 4.6vw, 30px);
}
.band-trail-lede {
    max-width: 34rem;
    margin: 12px 0 0;
    color: var(--muted);
    font-family: var(--ff-text);
    font-size: 16px;
    line-height: 1.65;
}
.trail {
    margin: 44px 0 0;
    padding: 0;
    list-style: none;
}
.trail-stop {
    --way: 1;
    position: relative;
    display: grid;
    grid-template-columns: 22px minmax(0, 1fr);
    column-gap: 16px;
    padding-bottom: 44px;
}
.trail-stop:last-child {
    padding-bottom: 0;
}
/* the way down to the next stop: from this marker's middle to the next's */
.trail-stop:not(:last-child)::after {
    content: "";
    position: absolute;
    top: 14px;
    left: 10.25px;
    width: 1.5px;
    height: 100%;
    background: color-mix(in srgb, var(--sun) 70%, transparent);
    transform: scaleY(var(--way));
    transform-origin: 50% 0;
}
.trail-marker {
    position: relative;
    z-index: 1;
    width: 14px;
    height: 14px;
    margin: 7px 0 0 4px;
    border: 1.5px solid var(--sun);
    border-radius: 50%;
    background: var(--paper);
}
.trail-stop.is-current .trail-marker {
    background: var(--gold);
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--gold) 24%, transparent);
}
.trail-body {
    min-width: 0;
}
.trail-body h3 {
    margin: 0;
    font-size: 22px;
    line-height: 1.2;
}
/* the padding widens the link's tap target into the space around it without
   moving a line of the stop */
.trail-body h3 a {
    display: inline-block;
    margin: -10px 0;
    padding: 10px 0;
    color: var(--bark);
    text-decoration: none;
    transition: color 150ms ease;
}
.trail-body h3 a:hover,
.trail-stop.is-current h3 a {
    color: var(--leaf);
}
.trail-body h3 a:focus-visible {
    outline: 2px solid var(--sun);
    outline-offset: 2px;
}
.trail-grades {
    margin: 2px 0 0;
    color: color-mix(in srgb, var(--sun) 70%, var(--bark));
    font-family: var(--ff);
    font-size: 13px;
    font-weight: 600;
}
.trail-facts {
    max-width: 28rem;
    margin: 8px 0 0;
    color: var(--muted);
    font-size: 14px;
    line-height: 1.6;
}
.trail-rules {
    max-width: 16rem;
    margin-top: 4px;
}
.trail-rules i {
    display: block;
    height: var(--rule-h);
    border-bottom: 1px solid color-mix(in srgb, var(--sun) 40%, var(--border));
    transform-origin: 0 50%;
}
@media (min-width: 960px) {
    .band-trail {
        display: grid;
        grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
        column-gap: 64px;
    }
    .band-trail-head {
        position: sticky;
        top: 120px;
        align-self: start;
    }
    .trail {
        margin-top: 8px;
    }
}

/* The reading room: a lamp-lit pine room at the end of the catalog, where the
   four parts of every guide lie open as a book's spread. Its pine reaches past
   the column to both screen edges through a border image, which is ink
   overflow and so adds no sideways scroll. The pine and the room's light text
   are screen only: printed, the room is plain paper. */
.library-room {
    position: relative;
    isolation: isolate;
    margin-top: 112px;
    padding: 88px clamp(20px, 4vw, 40px) 96px;
}
.library-room > h2 {
    text-align: center;
}
.room-book {
    display: grid;
    max-width: 960px;
    margin: 40px auto 0;
    perspective: 1800px;
}
.room-page {
    margin: 0;
    padding: 30px 26px;
    list-style: none;
    background: linear-gradient(180deg, var(--parchment-top), var(--parchment-bottom));
    color: var(--bark);
}
.room-page:first-child {
    border-radius: 6px 6px 0 0;
}
.room-page + .room-page {
    border-top: 1px solid var(--border-light);
    border-radius: 0 0 6px 6px;
}
.room-page li + li {
    margin-top: 26px;
    padding-top: 26px;
    border-top: 1px solid var(--border-light);
}
.room-numeral {
    display: block;
    color: var(--sun);
    font-family: var(--ff-display);
    font-size: 30px;
    line-height: 1;
}
.room-page h3 {
    margin: 10px 0 6px;
    color: var(--bark);
    font-size: 22px;
}
.room-page p {
    margin: 0;
    color: var(--muted);
    font-family: var(--ff-text);
    font-size: 15px;
    line-height: 1.65;
}
.room-close {
    max-width: 34rem;
    margin: 36px auto 0;
    color: var(--muted);
    font-family: var(--ff-text);
    font-size: 16px;
    font-style: italic;
    line-height: 1.6;
    text-align: center;
}
@media (min-width: 768px) {
    .room-book {
        grid-template-columns: 1fr 1fr;
    }
    .room-page {
        padding: 40px 36px;
    }
    /* the spread's gutter: each page shades toward the spine */
    .room-page:first-child {
        border-radius: 6px 0 0 6px;
        box-shadow: inset -18px 0 22px -18px color-mix(in srgb, var(--ribbon-edge) 30%, transparent);
    }
    .room-page + .room-page {
        border-top: none;
        border-radius: 0 6px 6px 0;
        box-shadow: inset 18px 0 22px -18px color-mix(in srgb, var(--ribbon-edge) 30%, transparent);
    }
}

/* A work's place on the trail: the five bands as one scale, the offered
   stretch inked in leaf and the recommended band gilded. Down the page on a
   phone, across it from 640px. */
.band-ladder {
    display: grid;
    gap: 4px;
    margin: 22px 0 0;
    padding: 0;
    list-style: none;
    font-family: var(--ff);
    font-size: 13px;
}
.rung {
    --gilt: 1;
    position: relative;
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: 26px;
    padding-left: 24px;
    color: var(--muted);
}
.rung::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 3px;
    width: 11px;
    height: 11px;
    margin-top: -5.5px;
    border: 1.5px solid var(--border);
    border-radius: 50%;
    background: var(--paper);
}
.rung::after {
    content: "";
    position: absolute;
    top: calc(50% + 6px);
    left: 8px;
    width: 1px;
    height: calc(100% - 8px);
    background: var(--border);
}
.rung:last-child::after {
    display: none;
}
.rung.is-offered {
    color: var(--bark);
    font-weight: 600;
}
.rung.is-offered::before {
    border-color: var(--leaf);
    background: var(--leaf-pale);
}
.rung.joins-next::after {
    left: 7.5px;
    width: 2px;
    background: var(--leaf);
}
.rung.is-recommended::before {
    border-color: var(--sun);
    background: var(--gold);
    box-shadow: 0 0 0 calc(var(--gilt) * 4px) color-mix(in srgb, var(--gold) 28%, transparent);
}
.rung small {
    color: color-mix(in srgb, var(--sun) 70%, var(--bark));
    font-size: 12px;
    font-weight: 600;
}
/* an offered band no guide stands behind yet says so in words */
.rung .rung-soon, .book-card-bands .is-soon small { color: var(--muted); font-size: 11px; font-weight: 500; }
.book-card-bands .is-soon { border-style: dashed; }
@media (min-width: 640px) {
    .band-ladder {
        grid-template-columns: repeat(5, minmax(0, 1fr));
        gap: 0;
        max-width: 40rem;
    }
    .rung {
        flex-direction: column;
        gap: 2px;
        padding: 20px 4px 0;
        text-align: center;
    }
    .rung::before {
        top: 0;
        left: calc(50% - 5.5px);
        margin-top: 0;
    }
    .rung::after,
    .rung.joins-next::after {
        top: 4.5px;
        left: calc(50% + 7px);
        width: calc(100% - 14px);
        height: 1px;
    }
    .rung.joins-next::after {
        top: 4px;
        height: 2px;
    }
}
html.library-motion ul.guides {
    perspective: 1000px;
}

/* the thinking tags are stamped onto their questions as they arrive, so they
   hold a box of their own */
.guide ol.questions .tag {
    display: inline-block;
    line-height: 1.35;
}

/* The reading pages. The student guide's four parts are a sequence, so each
   carries its numeral: before its heading on a phone, hung in the margin once
   the margin can hold it. Beside every part a gold thread draws down the
   margin as the reader works through it; the copywork rules ink themselves in
   over their pencil lines, and each vocabulary word is underlined as it
   arrives. The last part, critical thinking, is the guide's reading room, and
   the page opens onto pine around it. */
@media screen {
    article.guide:not(.companion, .adapt) {
        counter-reset: guide-part;
    }
    article.guide:not(.companion, .adapt) > .guide-part {
        counter-increment: guide-part;
    }
    article.guide:not(.companion, .adapt) > .guide-part > h2::before {
        content: counter(guide-part, upper-roman) "\2002";
        content: counter(guide-part, upper-roman) "\2002" / "";
        color: color-mix(in srgb, var(--sun) 70%, var(--bark));
        font-weight: 400;
    }
    article.guide:not(.adapt) > .guide-part {
        --thread: 1;
        position: relative;
    }

    .guide .copy-line {
        --drawn: 1;
        position: relative;
    }
    .guide .copy-line::after {
        content: "";
        position: absolute;
        right: 0;
        bottom: -1px;
        left: 0;
        height: 1px;
        background: color-mix(in srgb, var(--sun) 50%, transparent);
        transform: scaleX(var(--drawn));
        transform-origin: 0 50%;
    }
    .guide dl.vocabulary dt {
        --drawn: 1;
        width: fit-content;
        padding-bottom: 2px;
        background: linear-gradient(var(--sun), var(--sun)) no-repeat 0 100% / calc(var(--drawn) * 100%) 1px;
    }

    /* the two rooms: the catalog's, and a guide's critical thinking. The pine
       is a border image run out to both screen edges; the lamp hangs over
       the catalog's. */
    .guide > .guide-part.critical-thinking {
        isolation: isolate;
        max-width: none;
        margin: 80px 0 0;
        padding: 64px 0 72px;
        color: var(--chrome-text);
    }
    .guide > .critical-thinking > * {
        max-width: 32rem;
    }
    .guide > .critical-thinking > h2 {
        color: var(--chrome-text);
        font-size: 22px;
    }
    article.guide:not(.companion, .adapt) > .guide-part.critical-thinking > h2::before {
        color: var(--gold-light);
    }
    .guide > .critical-thinking .prompt {
        color: var(--chrome-text);
        font-size: 19px;
    }
    .library-room {
        color: var(--chrome-text);
    }
    .library-room > h2 {
        color: var(--chrome-text);
    }
    .room-close {
        color: var(--sand);
    }
    .library-room::before,
    .library-room::after,
    .guide > .guide-part.critical-thinking::before {
        content: "";
        position: absolute;
        z-index: -1;
        inset: 0;
        pointer-events: none;
    }
    .library-room::before,
    .guide > .guide-part.critical-thinking::before {
        border-image: linear-gradient(180deg, var(--spruce), var(--pine) 55%, var(--forest)) 0 fill / 0 / 0 50vw;
    }
    .library-room::after {
        background: radial-gradient(50% 42% at 50% 0%, color-mix(in srgb, var(--gold) 20%, transparent), transparent);
    }
    /* A room opens as the reader walks into it: its pine starts as a panel
       inside the column and widens to both screen edges, the corners
       squaring as it goes. The room's text stands inside the panel at every
       step, so light type never meets paper. The widening is measured to
       the screen's edge (50vw less half the room's own width), so it runs
       the whole of the approach instead of reaching the edges early. */
    html.library-motion :is(.library-room, .guide > .guide-part.critical-thinking) {
        --room: 1;
        --inset: 8px;
        clip-path: inset(0 calc((1 - var(--room)) * var(--inset) - var(--room) * (50vw - 50% + 1px))
            round calc((1 - var(--room)) * 18px));
    }
    html.library-motion .guide > .guide-part.critical-thinking {
        --inset: -14px;
    }
}
@media screen and (min-width: 1180px) {
    article.guide:not(.companion, .adapt) > .guide-part > h2 {
        position: relative;
    }
    article.guide:not(.companion, .adapt) > .guide-part > h2::before {
        position: absolute;
        top: -6px;
        left: -84px;
        width: 60px;
        color: var(--sun);
        font-size: 30px;
        text-align: right;
    }
    /* the thread down the margin, once there is a margin to hold it */
    article.guide:not(.adapt) > .guide-part:not(.critical-thinking)::after {
        content: "";
        position: absolute;
        top: 44px;
        bottom: 6px;
        left: -46px;
        width: 1px;
        background: linear-gradient(180deg, color-mix(in srgb, var(--sun) 65%, transparent), transparent);
        transform: scaleY(var(--thread));
        transform-origin: 50% 0;
        pointer-events: none;
    }
}

/* Printing and reduced motion both see the pages at rest. The printer gets
   every element the entrance had not yet reached; reduced motion never runs
   the entrance, and the release above is the one animation it could meet. */
@media print {
    html.library-motion .app-main [style] {
        opacity: 1 !important;
        transform: none !important;
    }
    html.library-motion .trail-stop,
    html.library-motion .rung {
        --way: 1 !important;
        --gilt: 1 !important;
    }
}
@media (prefers-reduced-motion: reduce) {
    html.library-arriving .app-main > :not(script, link, .library-paper) {
        opacity: 1;
        animation: none;
    }
    .trail-body h3 a {
        transition: none;
    }
    .library-paper,
    .library-paper ~ .guide :is(.opening, .closing, .strong-answer) > .label,
    .library-paper ~ .guide.companion p.label {
        transition: none;
    }
}

/* The Community Feed family as one book on the reading-room table
   (CommunityBook.razor): the feed, a conversation, the community card editor
   and the report form. The pine cover carries the page's own frame under a
   ruled gilt border; the paper page lies over the cover's lower edge with an
   oxblood ribbon in its ruled margin, and the paper ages from fresh at the
   head to lamp-warm at the foot, the way the feed runs from today back into
   older posts; a tailpiece closes the book on the table. Everything here is
   scoped to the book's own classes, so no other surface shifts. The motion
   lives in the no-preference block below and in /js/community-alive.js;
   without either the book stands complete and still. */
.alive-cover {
    position: relative;
    overflow: clip;
    padding: 8px 44px 50px;
    border-radius: 4px 4px 2px 2px;
    color: var(--chrome-text);
    background:
        radial-gradient(120% 95% at 16% 0%, rgba(62, 116, 88, 0.34), transparent 62%),
        linear-gradient(165deg, var(--spruce) 0%, var(--pine) 56%, var(--forest) 100%);
    box-shadow: inset 0 1px 0 rgba(229, 197, 126, 0.16), 0 22px 44px -30px rgba(10, 24, 16, 0.72);
}
.alive-cover-inner {
    position: relative;
    z-index: 1;
}
/* the gilt frame, a thin inner rule under a bolder outer one; the page lying
   over the cover hides its foot, the way a sheet covers a board */
.alive-frame {
    position: absolute;
    inset: 11px;
    pointer-events: none;
}
.alive-frame::after {
    content: "";
    position: absolute;
    inset: 4px;
    border: 1px solid rgba(229, 197, 126, 0.16);
    border-bottom: 0;
}
.alive-frame i {
    position: absolute;
    background: rgba(229, 197, 126, 0.52);
}
.alive-frame i:nth-child(1) {
    top: 0;
    right: 0;
    left: 0;
    height: 1px;
}
.alive-frame i:nth-child(2),
.alive-frame i:nth-child(3) {
    top: 0;
    bottom: 0;
    width: 1px;
}
.alive-frame i:nth-child(2) {
    left: 0;
}
.alive-frame i:nth-child(3) {
    right: 0;
}
/* the shadow the cover falls into as the page comes over it; the scroll
   story raises it, at rest it is clear */
.alive-shade {
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    background: var(--forest);
    opacity: 0;
}
.alive-cover .hero h1 {
    color: var(--chrome-text);
    text-wrap: balance;
}
.alive-cover .eyebrow {
    color: var(--gold-warm);
}
.alive-cover .hero-description {
    color: rgba(244, 234, 215, 0.8);
}
.alive-cover .hero-foot {
    border-top-color: var(--rule-dark);
    border-bottom: 0;
}
.alive-cover .hero-foot p {
    color: rgba(244, 234, 215, 0.74);
}
.alive-cover .text-link {
    color: var(--gold-light);
}
.alive-cover .text-link:hover {
    color: var(--gold-warm);
}
#community-space .alive-cover :focus-visible {
    outline-color: var(--gold-warm);
}

.alive-sheet {
    position: relative;
    z-index: 1;
    margin-top: -26px;
    padding: 32px 36px 46px 58px;
    border: 1px solid var(--border-light);
    border-radius: 2px;
    background: linear-gradient(180deg, var(--parchment-top) 0%, var(--parchment-bottom) 30%, var(--paper) 66%, var(--cream) 94%, var(--sun-pale) 100%);
    box-shadow: 0 1px 2px rgba(50, 44, 36, 0.05), 0 14px 32px -20px rgba(50, 44, 36, 0.3);
}
/* the ruled margin a ledger keeps, in the ribbon's own oxblood, in the
   page's left gutter where no word is set. The ribbon hangs in it and keeps
   the reader's place: sticky, it rides down the margin at the reader's line
   as they read and stops at the page's foot. It sticks at the pinned
   header's own height (its 44px row, 12px above and below, the safe area
   over it and its 1px rule), so it hangs from the header's foot from the
   moment the page carries it there. The margin paints over the page
   rather than under it: a moving layer beneath the text would have the
   browser lift every line above it onto layers of its own. It starts at the
   sheet's outer edge, over its top rule, so the ribbon meets the header
   with no line of paper between them as it arrives there */
.alive-margin {
    position: absolute;
    top: -1px;
    bottom: 30px;
    left: 26px;
    width: 1px;
    pointer-events: none;
    background: linear-gradient(180deg, rgba(156, 43, 49, 0.3), rgba(156, 43, 49, 0.3) 92%, transparent);
}
.alive-ribbon {
    position: sticky;
    top: calc(69px + env(safe-area-inset-top, 0px));
    display: block;
    margin-left: -7px;
    width: 15px;
    height: 64px;
    background:
        linear-gradient(90deg, rgba(255, 253, 247, 0.2), rgba(255, 253, 247, 0) 40%),
        linear-gradient(112deg, var(--ribbon-edge) 0%, var(--ribbon-face) 48%, var(--ribbon-fold) 100%);
    clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 84%, 0 100%);
}
/* the page's first block opens at the sheet's own padding, whatever its
   usual margin above it */
#community-space .alive-sheet > .alive-margin + * {
    margin-top: 0;
}
.alive-sheet > .empty {
    margin-top: 24px;
}
.alive-sheet > .community-rules {
    padding: 0 0 24px;
}
.alive-sheet > .community-rules + .form-card {
    margin-top: 24px;
}

/* the tailpiece: the Ashwren mark between two rules, where the book closes */
.alive-close {
    display: flex;
    justify-content: center;
    padding: 34px 0 4px;
}
.alive-tailpiece {
    display: inline-flex;
    align-items: center;
    gap: 16px;
}
.alive-tailpiece i {
    width: 92px;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--sun));
    transform-origin: 100% 50%;
}
.alive-tailpiece i:last-child {
    background: linear-gradient(90deg, var(--sun), transparent);
    transform-origin: 0 50%;
}
.alive-tailpiece img {
    display: block;
    width: 40px;
    height: 40px;
    opacity: 0.88;
}
/* on a desktop window tall enough to hold them, the community notes keep
   their place beside the posts the way marginalia keep theirs */
@media (min-width: 1100px) and (min-height: 760px) {
    .alive-sheet .feed-aside {
        position: sticky;
        top: 96px;
    }
}

@media (max-width: 767px) {
    .alive-cover {
        padding: 2px 20px 42px;
    }
    .alive-frame {
        inset: 8px;
    }
    .alive-sheet {
        padding: 22px 12px 30px 24px;
    }
    .alive-margin {
        left: 10px;
    }
    .alive-ribbon {
        margin-left: -4px;
        width: 9px;
        height: 46px;
    }
    .alive-tailpiece i {
        width: 64px;
    }
    /* the ruled margin takes width from the page: the topic filter's label
       sits over its control rather than squeezing into a narrow column */
    .alive-sheet .feed-filter {
        flex-wrap: wrap;
        row-gap: 8px;
    }
    .alive-sheet .feed-filter label {
        flex-basis: 100%;
    }
    .alive-sheet .feed-filter select {
        flex: 1;
        margin-left: 0;
    }
}

/* The motion. On load: the gilt rules draw from the corners, the title's
   letters drop into place one by one like type being set (the book's inline
   script splits them before first paint), and a band of light crosses the
   cover once, as gilt catches a lamp. On scroll (/js/community-alive.js
   marks each moment; every one of them is a single transition, never a
   per-frame scrub, and every one moves only transform and opacity, so the
   compositor runs it): the cover sinks back into shadow once the reader has
   read past it, posts and replies below the fold are laid down like turned
   leaves, a stroke of gilt runs along each arriving post's rule and down a
   conversation's thread line and fades into the ink, and the tailpiece
   draws out from the mark. */
@media screen and (prefers-reduced-motion: no-preference) {
    .alive-frame i:nth-child(1) {
        transform-origin: 0 50%;
        animation: alive-rule-across 1.1s cubic-bezier(0.16, 1, 0.3, 1) 0.1s both;
    }
    .alive-frame i:nth-child(2),
    .alive-frame i:nth-child(3) {
        transform-origin: 50% 0;
        animation: alive-rule-down 1.3s cubic-bezier(0.16, 1, 0.3, 1) 0.35s both;
    }
    .alive-frame i:nth-child(3) {
        animation-delay: 0.55s;
    }
    .alive-frame::after {
        animation: alive-appear 0.9s ease-out 1s both;
    }
    .alive-cover h1[data-setting] > span > span {
        white-space: nowrap;
    }
    .alive-cover h1[data-setting] > span > span > span {
        display: inline-block;
        animation: alive-set 0.72s cubic-bezier(0.16, 1, 0.3, 1) both;
        animation-delay: calc(0.3s + var(--i) * 34ms);
    }
    .alive-cover {
        transition: transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
    }
    .alive-shade {
        transition: opacity 0.9s cubic-bezier(0.16, 1, 0.3, 1);
    }
    .alive-cover[data-closed] {
        transform: translateY(28px);
    }
    .alive-cover[data-closed] .alive-shade {
        opacity: 0.45;
    }
    .alive-cover::before {
        content: "";
        position: absolute;
        inset: -30% -45%;
        z-index: 3;
        pointer-events: none;
        background: linear-gradient(104deg, transparent 42%, rgba(255, 236, 184, 0.1) 47%,
            rgba(255, 240, 200, 0.2) 50%, rgba(255, 236, 184, 0.1) 53%, transparent 58%);
        transform: translateX(-72%);
        animation: alive-glint 1.9s cubic-bezier(0.45, 0, 0.2, 1) 1.45s both;
    }

    /* a post or reply still waiting lies like a leaf not yet turned down */
    .alive-sheet :is(.feed-post, .reply)[data-drawn="no"] {
        opacity: 0;
        transform: perspective(900px) translateY(14px) rotateX(-12deg);
        transform-origin: 50% 0;
    }
    .alive-sheet :is(.feed-post, .reply)[data-drawn="yes"] {
        transform-origin: 50% 0;
        transition: opacity 0.9s cubic-bezier(0.16, 1, 0.3, 1), transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
    }
    /* as a post or a thread arrives, a stroke of gilt runs along its ink rule
       and fades into it: the rule itself is always there */
    .alive-sheet :is(.feed-post, .replies) {
        position: relative;
    }
    .alive-sheet .feed-post::after,
    .alive-sheet .replies::before {
        content: "";
        position: absolute;
        pointer-events: none;
        background: var(--gold);
        opacity: 0;
    }
    .alive-sheet .feed-post::after {
        right: 0;
        bottom: -1px;
        left: 0;
        height: 1px;
        transform-origin: 0 50%;
    }
    .alive-sheet .replies::before {
        top: 0;
        bottom: 0;
        left: -1px;
        width: 1px;
        transform-origin: 50% 0;
    }
    .alive-sheet .feed-post[data-drawn="yes"]::after {
        animation: alive-gild-across 2.3s cubic-bezier(0.16, 1, 0.3, 1) 0.2s both;
    }
    .alive-sheet .replies[data-drawn="yes"]::before {
        animation: alive-gild-down 2.3s cubic-bezier(0.16, 1, 0.3, 1) 0.2s both;
    }
    .alive-close[data-drawn="no"] .alive-tailpiece i {
        transform: scaleX(0);
    }
    .alive-close[data-drawn="no"] .alive-tailpiece img {
        opacity: 0;
        transform: translateY(6px) scale(0.86);
    }
    .alive-close[data-drawn="yes"] .alive-tailpiece i {
        transition: transform 1.2s cubic-bezier(0.16, 1, 0.3, 1) 0.2s;
    }
    .alive-close[data-drawn="yes"] .alive-tailpiece img {
        transition: opacity 0.7s ease, transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
    }
}
@keyframes alive-rule-across {
    from {
        transform: scaleX(0);
    }
}
@keyframes alive-rule-down {
    from {
        transform: scaleY(0);
    }
}
@keyframes alive-appear {
    from {
        opacity: 0;
    }
}
@keyframes alive-gild-across {
    0% {
        opacity: 1;
        transform: scaleX(0);
    }
    45% {
        opacity: 1;
        transform: scaleX(1);
    }
    100% {
        opacity: 0;
        transform: scaleX(1);
    }
}
@keyframes alive-gild-down {
    0% {
        opacity: 1;
        transform: scaleY(0);
    }
    45% {
        opacity: 1;
        transform: scaleY(1);
    }
    100% {
        opacity: 0;
        transform: scaleY(1);
    }
}
@keyframes alive-set {
    from {
        opacity: 0;
        transform: translateY(-0.38em);
    }
}
/* the light has crossed and gone: nothing stays over the cover once it has */
@keyframes alive-glint {
    to {
        transform: translateX(72%);
        visibility: hidden;
    }
}

/* on paper the book is ink on the sheet: no cover cloth, no ribbon, no
   tailpiece, and nothing left mid-motion */
@media print {
    .alive-cover,
    .alive-sheet {
        padding: 0;
        margin: 0;
        border: 0;
        color: var(--bark);
        background: none;
        box-shadow: none;
        transform: none !important;
    }
    .alive-cover .hero h1,
    .alive-cover .hero-description,
    .alive-cover .hero-foot p {
        color: var(--bark);
    }
    .alive-cover .eyebrow {
        color: var(--muted);
    }
    .alive-frame,
    .alive-shade,
    .alive-margin,
    .alive-close {
        display: none;
    }
}

/* Help is a quiet form on paper; the native dialog keeps the reading page
   behind it. The owner inbox uses the same field and parchment vocabulary. */
.help-page {
    width: min(100% - 2rem, 760px);
    margin: clamp(2rem, 5vw, 5rem) auto;
}
.help-content h1, .help-inbox h1 {
    font-family: "Young Serif", serif;
    color: var(--bark);
}
.help-content .form-card { margin-top: 1.5rem; }
.help-content .form-errors { color: var(--red); }
.help-dialog {
    width: min(100% - 2rem, 620px);
    max-height: min(90vh, 800px);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: clamp(1.25rem, 4vw, 2.5rem);
    background: var(--paper);
    color: var(--bark);
    box-shadow: 0 24px 72px rgba(11, 26, 19, .28);
    overflow-y: auto;
}
.help-dialog::backdrop { background: rgba(11, 26, 19, .65); }
.help-close { float: right; }
.help-close button {
    border: 0;
    background: transparent;
    color: var(--bark);
    font-size: 1.75rem;
    cursor: pointer;
}
.help-filters { display: flex; flex-wrap: wrap; align-items: end; gap: .75rem; margin: 1.5rem 0; }
.help-filters label { font-weight: 700; }
.help-filters input, .help-filters select { max-width: 220px; }
.help-item { margin: 1rem 0; padding: 1.5rem; overflow-wrap: anywhere; }
.help-item h2 { margin: .5rem 0; font-family: "Libre Caslon Text", serif; }
.help-item form { margin-top: 1rem; }
.help-message { white-space: pre-wrap; overflow-wrap: anywhere; }
.help-pagination { display: flex; justify-content: space-between; gap: 1rem; margin-top: 1.5rem; }
@media print { .help-dialog { display: none; } }
