/* ==========================================================================
   /products/uspto-bundle only. Loaded by templates/product_uspto.html through
   the base template's head_extra block; nothing here is linked from any other
   page and every rule is scoped under .up or .up-main.

   The page is a chaptered editorial: a title page, a prologue, five chapters
   and a colophon. Chapters cut hard between two authored grounds rather than
   drifting between them, so the grounds are declared here and not inherited
   from the OS theme; under prefers-color-scheme: dark the paper ground steps
   down to a raised dark instead of glaring. `color` is restated wherever the
   ink token is restated, because `color` inherits as a computed value and
   redefining a variable alone does not re-ink the text under it.

   Two families, both already in the site's stack: the display serif carries
   the folios, chapter titles and plate captions; the system sans carries
   prose. One accent hue at two lightnesses, keyed to the ground family, which
   is the documented escape for a page that hard-cuts between light and dark.
   ========================================================================== */

/* `main.wrap` in style.css is element+class, so it out-specifies a bare
   `.up-main`; matching the element keeps the reset from losing to it. */
main.up-main {
    max-width: none;
    padding: 0;
}

.up {
    /* Paper ground */
    --up-paper-canvas: #f4f3ee;
    --up-paper-surface: #e7e5df;
    --up-paper-ink: #16181d;
    --up-paper-ink-soft: #565f59;
    --up-paper-accent: #8e2f2a;
    --up-paper-line: rgba(22, 24, 27, 0.15);

    /* Ink ground */
    --up-ink-canvas: #14171a;
    --up-ink-surface: #1d2126;
    --up-ink-ink: #edeff1;
    --up-ink-ink-soft: #9aa3ab;
    --up-ink-accent: #e08a80;
    --up-ink-line: rgba(237, 239, 241, 0.17);

    --up-measure: 63ch;
    --up-gutter: clamp(20px, 5vw, 64px);
    --up-section: clamp(76px, 11vh, 136px);
    --up-radius: 6px;
    --up-ease: cubic-bezier(0.23, 1, 0.32, 1);

    font-size: 1rem;
    line-height: 1.6;
}

@media (prefers-color-scheme: dark) {
    .up {
        /* Raised well clear of the ink canvas rather than a shade off it: the
           cut between chapters is this page's structure, and a two-value
           difference reads as a rendering artefact rather than a page turn. */
        --up-paper-canvas: #232830;
        --up-paper-surface: #2c333b;
        --up-paper-ink: #eef0f2;
        --up-paper-ink-soft: #9fa8b0;
        --up-paper-accent: #e08a80;
        --up-paper-line: rgba(238, 240, 242, 0.17);
    }
}

/* ---- Grounds --------------------------------------------------------- */

.up-sec {
    position: relative;
    padding: var(--up-section) 0;
}

.up-sec--paper {
    background: var(--up-paper-canvas);
    --up-c-ink: var(--up-paper-ink);
    --up-c-soft: var(--up-paper-ink-soft);
    --up-c-accent: var(--up-paper-accent);
    --up-c-line: var(--up-paper-line);
    --up-c-surface: var(--up-paper-surface);
    color: var(--up-paper-ink);
}

.up-sec--ink {
    background: var(--up-ink-canvas);
    --up-c-ink: var(--up-ink-ink);
    --up-c-soft: var(--up-ink-ink-soft);
    --up-c-accent: var(--up-ink-accent);
    --up-c-line: var(--up-ink-line);
    --up-c-surface: var(--up-ink-surface);
    color: var(--up-ink-ink);
}

.up-wrap {
    max-width: 1120px;
    margin: 0 auto;
    padding: 0 var(--up-gutter);
}

/* ---- Type ------------------------------------------------------------ */

.up-display {
    font-family: var(--font-display);
    font-weight: 600;
    line-height: 1.06;
    letter-spacing: -0.008em;
    text-wrap: balance;
    margin: 0;
    color: var(--up-c-ink);
}

.up-display--xl { font-size: clamp(2.05rem, 5vw, 3.7rem); }
.up-display--lg { font-size: clamp(1.7rem, 3.4vw, 2.6rem); }
.up-display--md { font-size: clamp(1.3rem, 2.2vw, 1.75rem); line-height: 1.22; }

.up-h3 {
    font-family: var(--font-display);
    font-size: 1.16rem;
    font-weight: 600;
    margin: 0 0 10px;
    color: var(--up-c-ink);
}

.up-lede {
    font-size: clamp(1.04rem, 1.4vw, 1.2rem);
    line-height: 1.58;
    max-width: 52ch;
    color: var(--up-c-soft);
    text-wrap: pretty;
    margin: 22px 0 0;
}

.up-body {
    font-size: 1rem;
    line-height: 1.7;
    max-width: var(--up-measure);
    text-wrap: pretty;
    margin: 0 0 17px;
}

.up-display + .up-body,
.up-display + .up-lede,
.up-h3 + .up-body { margin-top: 20px; }

.up-h3 { margin-top: 34px; }

.up-measure { max-width: var(--up-measure); }
.up-muted { color: var(--up-c-soft); }

/* A margin note, set in the folio face: the editorial page's aside. It is
   the only place a chapter raises its voice, so there is at most one per
   chapter. */
.up-note {
    font-family: var(--font-display);
    font-size: 1.06rem;
    line-height: 1.5;
    color: var(--up-c-accent);
    max-width: 44ch;
    margin: 0;
}

.up-link {
    color: var(--up-c-accent);
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
}

.up-link:hover { text-decoration-thickness: 2px; }

.up ::selection {
    background: var(--up-c-accent);
    color: var(--up-ink-canvas);
}

.up a:focus-visible,
.up button:focus-visible,
.up input:focus-visible,
.up [tabindex]:focus-visible {
    outline: 2px solid var(--up-c-accent);
    outline-offset: 3px;
    border-radius: 3px;
}

/* ---- Buttons --------------------------------------------------------- */

.up-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin: 34px 0 0;
}

.up-btn {
    display: inline-block;
    padding: 12px 22px;
    border-radius: var(--radius-pill);
    font-size: 0.97rem;
    font-weight: 600;
    text-decoration: none;
    border: 1px solid transparent;
    transition: background-color 140ms var(--up-ease),
                color 140ms var(--up-ease),
                border-color 140ms var(--up-ease),
                transform 120ms var(--up-ease);
}

.up-btn--primary {
    background: var(--up-c-accent);
    color: #fbf7f6;
}

.up-btn--primary:hover { background: #6f231f; }

.up-btn--ghost {
    border-color: var(--up-c-line);
    color: var(--up-c-ink);
}

.up-btn--ghost:hover { border-color: var(--up-c-accent); color: var(--up-c-accent); }
.up-btn:active { transform: translateY(1px); }

/* On the ink ground, and on the whole page under an OS dark theme, the accent
   is the light stop of the hue, so the primary button flips its ink. */
.up-sec--ink .up-btn--primary { color: #17110f; }
.up-sec--ink .up-btn--primary:hover { background: #f0aaa1; }

@media (prefers-color-scheme: dark) {
    .up-sec--paper .up-btn--primary { color: #17110f; }
    .up-sec--paper .up-btn--primary:hover { background: #f0aaa1; }
}

/* ---- The folio: chapter numeral, rule, title ------------------------- */

.up-folioline {
    display: flex;
    align-items: baseline;
    gap: 14px;
    margin: 0 0 clamp(22px, 3vw, 38px);
    font-family: var(--font-display);
    color: var(--up-c-soft);
}

.up-folioline__num {
    font-size: 0.9rem;
    letter-spacing: 0.22em;
    text-transform: uppercase;
}

.up-folioline__rule {
    flex: 1 1 auto;
    height: 1px;
    background: var(--up-c-line);
}

.up-folioline__of {
    font-size: 0.82rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
}

/* The margin folio. It is the page's whole navigation, so it only exists
   where there is a margin to put it in; below that width every chapter still
   carries its own printed folio line above the title. */
.up-margin {
    display: none;
}

@media (min-width: 1240px) {
    .up--js .up-margin {
        display: block;
        position: fixed;
        top: 50%;
        left: clamp(16px, 2.4vw, 40px);
        transform: translateY(-50%);
        z-index: 4;
        max-width: 150px;
    }

    .up-margin__list {
        list-style: none;
        margin: 0;
        padding: 0;
        display: grid;
        gap: 9px;
    }

    .up-margin a {
        display: grid;
        grid-template-columns: 2.1rem 1fr;
        gap: 8px;
        align-items: baseline;
        font-family: var(--font-display);
        font-size: 0.8rem;
        line-height: 1.25;
        text-decoration: none;
        color: var(--up-margin-soft);
        opacity: 0.55;
        transition: opacity 220ms var(--up-ease), color 220ms var(--up-ease);
    }

    .up-margin a:hover { opacity: 1; }

    .up-margin li.is-current a {
        opacity: 1;
        color: var(--up-margin-accent);
    }

    .up-margin__num {
        letter-spacing: 0.16em;
        text-transform: uppercase;
        font-size: 0.72rem;
    }
}

/* The folio floats over whichever ground is behind it, so it carries its own
   two-stop colours rather than the section tokens it never inherits. */
.up-margin {
    --up-margin-soft: var(--up-paper-ink-soft);
    --up-margin-accent: var(--up-paper-accent);
}

.up-margin[data-up-ground="ink"] {
    --up-margin-soft: var(--up-ink-ink-soft);
    --up-margin-accent: var(--up-ink-accent);
}

/* ---- The tier toggle --------------------------------------------------
   Two native radios in a fieldset. Selecting USPTO Research dims everything
   carrying data-up-tier="full" (the four Full-only chapters, their folio and
   contents entries, the mentions in running text) to a greyed state. Opacity
   and a desaturation only: no element changes size or position, so nothing
   shifts. The selector is :has() on the root for a page with no script, and
   the data-up-tier-state attribute uspto.js mirrors for a browser without
   :has(). Full is the default and the checked radio. */
.up-tier {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px 14px;
    margin: clamp(22px, 3vw, 34px) 0 0;
    padding: 0;
    border: 0;
    min-inline-size: 0;
}

.up-tier__legend {
    font-family: var(--font-display);
    font-size: 0.74rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--up-c-soft);
    padding: 0;
    margin-bottom: 8px;
    flex-basis: 100%;
}

.up-tier__opt {
    display: inline-grid;
    grid-template-columns: auto auto;
    grid-template-areas: "radio name" "radio price";
    column-gap: 10px;
    align-items: center;
    padding: 8px 14px 8px 10px;
    border: 1px solid var(--up-c-line);
    border-radius: 6px;
    cursor: pointer;
    background: var(--up-c-surface);
}

.up-tier__opt:has(input:checked) { border-color: var(--up-c-accent); }

.up-tier__opt input {
    grid-area: radio;
    margin: 0;
    accent-color: var(--up-c-accent);
}

.up-tier__name {
    grid-area: name;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 0.98rem;
}

.up-tier__price {
    grid-area: price;
    font-size: 0.84rem;
    color: var(--up-c-soft);
    font-variant-numeric: tabular-nums;
}

.up-tier__note {
    flex-basis: 100%;
    margin: 4px 0 0;
    font-size: 0.88rem;
    color: var(--up-c-soft);
    max-width: 56ch;
}

/* The toggle repeats at the end of chapter III and in the colophon (John,
   10 October 2026). Instances 2 and 3 carry data-up-tier-mirror; uspto.js
   keeps the three checked alike and writes the state onto the root. Once
   script runs the root attribute is what dims; the :has() rule on the first
   instance's radio is the fallback for a page with no script. */
.up-tier--mirror { margin-top: clamp(26px, 4vw, 44px); }

[data-up-tier="full"],
[data-up-tier="research-only"] { transition: opacity 260ms var(--up-ease), filter 260ms var(--up-ease); }

.up:not(.up--js):has(#up-tier-research:checked) [data-up-tier="full"],
.up[data-up-tier-state="research"] [data-up-tier="full"],
.up:not(.up--js):has(#up-tier-full:checked) [data-up-tier="research-only"],
.up[data-up-tier-state="full"] [data-up-tier="research-only"],
.up-plan--included {
    opacity: 0.38;
    filter: grayscale(1);
}

/* A dimmed chapter stays readable to a reader who scrolls into it anyway:
   hovering or focusing inside lifts it while the pointer is there. */
.up:not(.up--js):has(#up-tier-research:checked) section[data-up-tier="full"]:is(:hover, :focus-within),
.up[data-up-tier-state="research"] section[data-up-tier="full"]:is(:hover, :focus-within),
.up:not(.up--js):has(#up-tier-full:checked) section[data-up-tier="research-only"]:is(:hover, :focus-within),
.up[data-up-tier-state="full"] section[data-up-tier="research-only"]:is(:hover, :focus-within),
.up-plan--included:is(:hover, :focus-within) {
    opacity: 0.7;
}

@media (prefers-reduced-motion: reduce) {
    [data-up-tier="full"],
    [data-up-tier="research-only"] { transition: none; }
}

/* ---- Title page ------------------------------------------------------ */

.up-title {
    padding-top: clamp(48px, 9vh, 104px);
    padding-bottom: clamp(64px, 10vh, 128px);
}

.up-title__mark {
    font-family: var(--font-display);
    font-size: 0.84rem;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--up-c-soft);
    margin: 0 0 clamp(26px, 4vw, 44px);
}

.up-title .up-display--xl { max-width: 25ch; }

/* The title page's right-hand field. Below 1200px there is no field to fill
   and the figure does not exist, the same rule the margin folio follows. */
.up-title__figure { display: none; }

@media (min-width: 1200px) {
    .up-title__spread {
        display: grid;
        grid-template-columns: minmax(0, 1fr) minmax(264px, 300px);
        gap: clamp(36px, 4.5vw, 72px);
        align-items: start;
    }

    .up-title__figure {
        display: block;
        /* Optically aligned to the eyebrow rather than the box top. */
        padding-top: 4px;
    }
}

/* ---- The title-page loop: the register, swept ------------------------ */

.up-loop {
    margin: 0;
    padding: 18px 20px 16px;
    background: var(--up-c-surface);
    border: 1px solid var(--up-c-line);
    border-radius: var(--up-radius);
}

.up-loop__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    font-family: var(--font-display);
}

.up-loop__label {
    font-size: 0.72rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--up-c-soft);
}

.up-loop__date {
    font-size: 0.94rem;
    font-variant-numeric: tabular-nums;
    color: var(--up-c-accent);
}

.up-loop__track {
    position: relative;
    margin: 18px 0 0;
}

.up-loop__bands {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 11px;
}

/* Each band is a hairline rail the width of the window, carrying one solid
   segment from the month a shift took effect to the month something displaced
   it, or to the end of the window where nothing has. */
.up-loop__band {
    position: relative;
    height: 3px;
}

.up-loop__band::before {
    content: "";
    position: absolute;
    inset: 1px 0;
    background: var(--up-c-line);
}

.up-loop__band::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: var(--up-from);
    width: calc(var(--up-to) - var(--up-from));
    border-radius: 2px;
    background: var(--up-c-soft);
    opacity: 0.4;
    transition: opacity 420ms var(--up-ease), background-color 420ms var(--up-ease);
}

.up-loop__band.is-lit::after {
    background: var(--up-c-accent);
    opacity: 1;
}

/* The date line, and the soft field it carries with it. Both are placed off
   the one custom property the script writes, so a frame is a single style
   write and nothing reflows. */
.up-loop__line {
    position: absolute;
    top: -7px;
    bottom: -7px;
    left: var(--up-sweep);
    width: 1px;
    background: var(--up-c-accent);
}

.up-loop__line::before {
    content: "";
    position: absolute;
    top: 0;
    left: -2px;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--up-c-accent);
}

.up-loop__line::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 50%;
    width: 52px;
    transform: translateX(-50%);
    /* A field around the line rather than a block beside it: hard edges on a
       moving rectangle read as a rendering fault. */
    background: linear-gradient(to right, transparent, currentColor, transparent);
    opacity: 0.07;
}

.up-loop__scale {
    display: flex;
    justify-content: space-between;
    font-size: 0.7rem;
    letter-spacing: 0.08em;
    color: var(--up-c-soft);
    font-variant-numeric: tabular-nums;
    margin: 16px 0 0;
}

.up-loop__note {
    font-family: var(--font-display);
    font-size: 0.84rem;
    line-height: 1.45;
    color: var(--up-c-soft);
    margin: 10px 0 0;
    padding-top: 10px;
    border-top: 1px solid var(--up-c-line);
}

.up-title__rule {
    height: 1px;
    background: var(--up-c-line);
    margin: clamp(40px, 6vw, 72px) 0 clamp(26px, 3vw, 38px);
}

/* The table of contents. On a title page this is not decoration: it is how a
   reader of a chaptered thing decides whether to read it, and it is the only
   navigation a phone gets. */
.up-contents {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
    gap: 0 clamp(24px, 4vw, 56px);
}

.up-contents li {
    border-top: 1px solid var(--up-c-line);
}

.up-contents a {
    display: grid;
    grid-template-columns: 2.6rem 1fr;
    gap: 10px;
    align-items: baseline;
    padding: 12px 0;
    text-decoration: none;
    color: var(--up-c-ink);
}

.up-contents a:hover .up-contents__title { color: var(--up-c-accent); }

.up-contents__num {
    font-family: var(--font-display);
    font-size: 0.78rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--up-c-soft);
}

.up-contents__title {
    font-family: var(--font-display);
    font-size: 1.02rem;
    transition: color 140ms var(--up-ease);
}

.up-contents__gloss {
    grid-column: 2;
    font-size: 0.87rem;
    color: var(--up-c-soft);
    margin: 2px 0 0;
}

/* ---- Prologue -------------------------------------------------------- */

.up-split {
    display: grid;
    grid-template-columns: minmax(0, 0.86fr) minmax(0, 1.14fr);
    gap: clamp(32px, 6vw, 88px);
    align-items: start;
}

/* Sticky parts hold where the design puts them, or 16px under the sticky site
   header (--site-header-h) where that is lower, so they never slide under it
   and a short viewport does not lose the header's height twice. */
.up-split__aside {
    position: sticky;
    top: max(var(--site-header-h) + 16px, clamp(24px, 12vh, 96px));
}

.up-split__aside .up-body { margin-top: 20px; }

.up-fail {
    padding: 32px 0;
    border-top: 1px solid var(--up-c-line);
}

.up-fail:first-child { border-top: 0; padding-top: 0; }

/* The prologue plate. Same object as a chapter plate, one rung quieter: it
   sits under the argument in the sticky column, so it must not compete with
   the chapter plates opposite, and it must not come near the register in
   chapter V, which is the page's peak. Hence no accent, no motion of its own
   beyond the light inside the frame, and a caption in the plate's own voice.

   The poster is a still of the clip's first frame at the same ratio, so the
   box is identical whether or not the clip ever attaches, and the ratio is
   restated here for the same reason the chapter plates restate theirs.

   Chapter IV's plate is the same object placed in a spread: it carries
   .up-plate as well, so the plate rules below (sticky, mirror order, caption
   measure, zero margin) win there and only the media styling comes from
   here. */
.up-glare {
    margin: 34px 0 0;
}

.up-glare__media {
    width: 100%;
    height: auto;
    aspect-ratio: 1008 / 576;
    display: block;
    border-radius: var(--up-radius);
    background: var(--up-c-surface);
    object-fit: cover;
    box-shadow: 0 12px 28px rgba(6, 8, 11, 0.34);
}

.up-glare figcaption {
    font-family: var(--font-display);
    font-size: 0.82rem;
    line-height: 1.45;
    color: var(--up-c-soft);
    margin-top: 12px;
    max-width: 38ch;
}

/* ---- Chapters: the spread -------------------------------------------- */

.up-spread {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
    gap: clamp(30px, 5vw, 72px);
    align-items: start;
}

/* Alternating margin: a spread, not the same page printed twice. */
.up-spread--mirror .up-plate { order: 2; }

/* The plate holds while the chapter's argument runs past it, which is what a
   plate does in a printed book. */
.up-plate {
    margin: 0;
    position: sticky;
    top: max(var(--site-header-h) + 16px, clamp(24px, 14vh, 120px));
}

.up-plate img {
    width: 100%;
    height: auto;
    /* Both dimensions are overridden here, so the attributes no longer reserve
       the box; the ratio has to be restated or a lazy plate arrives into a
       zero-height slot and shoves the chapter under it. */
    aspect-ratio: 1376 / 768;
    display: block;
    border-radius: var(--up-radius);
    /* Offset and blur, tinted to the ground, rather than a halo. */
    box-shadow: 0 12px 28px rgba(12, 16, 20, 0.16);
}

.up-plate figcaption {
    font-family: var(--font-display);
    font-size: 0.85rem;
    line-height: 1.45;
    color: var(--up-c-soft);
    margin-top: 12px;
    max-width: 40ch;
}

.up-plate__label {
    letter-spacing: 0.16em;
    text-transform: uppercase;
    font-size: 0.74rem;
    color: var(--up-c-accent);
    display: block;
    margin-bottom: 3px;
}

.up-chapter__body .up-note { margin-top: 26px; }

/* Chapter I has no plate: its body stands alone at the prose measure. */
.up-chapter__body--solo { max-width: 62ch; }

/* A short dated or definitional aside inside a chapter. A hairline and space,
   not a card: the page has enough boxes in the colophon. */
.up-aside {
    border-left: 1px solid var(--up-c-line);
    padding-left: clamp(16px, 2vw, 24px);
    margin: 26px 0 0;
}

.up-aside .up-body { font-size: 0.94rem; margin-bottom: 10px; }
.up-aside .up-body:last-child { margin-bottom: 0; }

.up-aside__label {
    font-family: var(--font-display);
    font-size: 0.74rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--up-c-soft);
    margin: 0 0 8px;
}

/* ---- The peak: the as-of dial and the register ----------------------- */

.up-peak { padding-bottom: calc(var(--up-section) * 1.15); }

.up-peak__head .up-display--xl { max-width: 16ch; }

.up-dial {
    margin: clamp(36px, 5vw, 60px) 0 clamp(26px, 3vw, 36px);
    padding: clamp(18px, 2.4vw, 26px) clamp(18px, 2.4vw, 28px);
    background: var(--up-c-surface);
    border: 1px solid var(--up-c-line);
    border-radius: var(--up-radius);
    /* Only ever shown once the script is driving it: a range input that
       classifies nothing is worse than no control at all. */
    display: none;
}

.up--js .up-dial { display: block; }

.up-dial__row {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 10px 18px;
}

.up-dial__label {
    font-family: var(--font-display);
    font-size: 0.8rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--up-c-soft);
}

.up-dial__value {
    font-family: var(--font-display);
    font-size: clamp(1.3rem, 2.4vw, 1.75rem);
    font-variant-numeric: tabular-nums;
    color: var(--up-c-accent);
}

.up-dial input[type="range"] {
    width: 100%;
    margin: 16px 0 0;
    accent-color: var(--up-c-accent);
    cursor: pointer;
}

.up-dial__scale {
    display: flex;
    justify-content: space-between;
    font-size: 0.76rem;
    letter-spacing: 0.08em;
    color: var(--up-c-soft);
    margin: 4px 0 0;
}

.up-dial__hint {
    font-size: 0.88rem;
    color: var(--up-c-soft);
    margin: 18px 0 0;
    max-width: 58ch;
}

/* The readout inside the card. The full register below is the document; this
   is the instrument, and it exists so the hand on the slider and the thing it
   changes are in one viewport. Written by the script, which is why nothing
   here has a resting state in the markup. */
.up-dial__readout {
    margin: 18px 0 0;
    padding-top: 15px;
    border-top: 1px solid var(--up-c-line);
}

.up-dial__counts {
    font-family: var(--font-display);
    font-size: 0.82rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    font-variant-numeric: tabular-nums;
    color: var(--up-c-accent);
    margin: 0 0 12px;
}

.up-dial__lines {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 21rem), 1fr));
    gap: 1px clamp(12px, 2vw, 32px);
}

.up-dial__line {
    position: relative;
    display: grid;
    grid-template-columns: 7px minmax(0, 1fr) auto;
    align-items: baseline;
    gap: 10px;
    padding: 5px 7px;
    border-radius: 3px;
    /* Capped rather than filling the column: a status word pushed to the far
       edge of a wide card stops belonging to the name beside it. */
    max-width: 25rem;
    font-size: 0.9rem;
    color: var(--up-c-soft);
    transition: color 260ms var(--up-ease), opacity 260ms var(--up-ease);
}

.up-dial__line::before {
    content: "";
    width: 7px;
    height: 7px;
    border-radius: 1px;
    background: currentColor;
    opacity: 0.45;
    transform: translateY(-1px);
}

/* The wash a row gets on the step where it changes side. It is the only way
   a re-sort reads as a movement rather than as a list that was always so. */
.up-dial__line::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 3px;
    background: currentColor;
    opacity: 0;
    pointer-events: none;
}

.up-dial__line.is-turned::after {
    animation: up-turned 640ms var(--up-ease);
}

@keyframes up-turned {
    from { opacity: 0.14; }
    to { opacity: 0; }
}

.up-dial__line[data-up-status="in-force"] { color: var(--up-c-ink); }

.up-dial__line[data-up-status="in-force"]::before {
    background: var(--up-c-accent);
    opacity: 1;
}

.up-dial__line[data-up-status="future"] { opacity: 0.66; }

.up-dial__line[data-up-status="gone"] .up-dial__short {
    text-decoration: line-through;
    text-decoration-thickness: 1px;
    text-decoration-color: var(--up-c-line);
}

.up-dial__short {
    font-family: var(--font-display);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.up-dial__state {
    font-size: 0.7rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--up-c-soft);
    white-space: nowrap;
}

.up-dial__line[data-up-status="in-force"] .up-dial__state { color: var(--up-c-accent); }

.up-dial__edge {
    font-size: 0.82rem;
    line-height: 1.55;
    color: var(--up-c-soft);
    font-variant-numeric: tabular-nums;
    margin: 13px 0 0;
    max-width: 62ch;
}

/* The register. Three columns once the script is classifying; one dated list
   in chronological order before that, which is a complete and honest reading
   of the same rows. */
.up-register {
    list-style: none;
    margin: 0;
    padding: 0;
    border-top: 1px solid var(--up-c-line);
}

.up-shift {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: baseline;
    gap: 4px 22px;
    padding: 14px 0;
    border-bottom: 1px solid var(--up-c-line);
}

.up-shift__name {
    font-family: var(--font-display);
    font-size: clamp(1rem, 1.5vw, 1.14rem);
    color: var(--up-c-ink);
}

/* The name links to the source the server stores (John, 10 October 2026:
   the address the model would give if asked), in the name's own colour. */
.up-shift__link {
    color: inherit;
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-decoration-color: var(--up-c-line);
    text-underline-offset: 0.2em;
}

.up-shift__link:hover { text-decoration-color: currentColor; }

.up-shift__link:focus-visible {
    outline: 2px solid var(--up-c-accent);
    outline-offset: 3px;
    border-radius: 2px;
}

.up-shift__dates {
    font-size: 0.82rem;
    color: var(--up-c-soft);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.up-shift__gloss {
    grid-column: 1 / -1;
    font-size: 0.9rem;
    color: var(--up-c-soft);
    max-width: 66ch;
    margin: 4px 0 0;
}

.up-shift__status {
    font-family: var(--font-display);
    font-size: 0.74rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--up-c-soft);
    /* Written by the script from the dial's date; without it the row's own
       dates are the whole answer and a fixed status word would be a lie. */
    display: none;
}

.up--js .up-shift__status { display: block; grid-column: 1 / -1; margin-top: 4px; }
.up--js .up-shift[data-up-status="in-force"] .up-shift__status { color: var(--up-c-accent); }

.up--js .up-shift[data-up-status="future"] .up-shift__name,
.up--js .up-shift[data-up-status="gone"] .up-shift__name {
    color: var(--up-c-soft);
}

.up--js .up-shift[data-up-status="gone"] .up-shift__name {
    text-decoration: line-through;
    text-decoration-thickness: 1px;
    text-decoration-color: var(--up-c-line);
}

.up--js .up-shift {
    transition: opacity 260ms var(--up-ease), color 260ms var(--up-ease);
}

.up--js .up-shift[data-up-status="future"] { opacity: 0.62; }

/* Counts only mean something once the dial has a date to count against, so
   the tally does not exist before the script does. */
.up-tally {
    display: none;
    flex-wrap: wrap;
    gap: 10px 28px;
    margin: 22px 0 0;
    padding: 0;
    list-style: none;
    font-family: var(--font-display);
    font-size: 0.86rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--up-c-soft);
}

.up--js .up-tally { display: flex; }

.up-tally b {
    font-variant-numeric: tabular-nums;
    color: var(--up-c-accent);
    font-weight: 600;
}

.up-peak__verdict {
    margin-top: clamp(38px, 5vw, 64px);
    max-width: var(--up-measure);
}

.up-peak__verdict .up-display--md { margin-bottom: 20px; }

/* The verdict set as a spread beside its plate (Plate VI). The spread takes
   the verdict's top margin so the plate and the text start on one line. */
.up-peak__spread { margin-top: clamp(38px, 5vw, 64px); }
.up-peak__spread .up-peak__verdict { margin-top: 0; }

/* ---- Chapter VI: the citations ---------------------------------------- */

/* A tool or field name, set in the prose face on the ground's surface rather
   than in a third, monospaced, family. */
.up-code {
    font-size: 0.92em;
    background: var(--up-c-surface);
    border-radius: 4px;
    padding: 0.08em 0.4em;
    overflow-wrap: anywhere;
}

.up-citations__spread { margin-top: clamp(38px, 5vw, 64px); }

.up-citations__spread .up-lede { margin-bottom: 20px; }

/* The one reference, read from both sides: a lane, then what that lane
   holds of it, then the join. */
.up-union {
    list-style: none;
    margin: 0 0 22px;
    padding: 0;
    max-width: var(--up-measure);
}

.up-union__row {
    display: grid;
    grid-template-columns: minmax(8rem, 11rem) minmax(0, 1fr);
    gap: 4px clamp(12px, 2vw, 24px);
    padding: 12px 0;
    border-top: 1px solid var(--up-c-line);
}

.up-union__row--join {
    border-top: 1px solid var(--up-c-accent);
}

.up-union__lane {
    font-family: var(--font-display);
    font-size: 0.78rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--up-c-soft);
    padding-top: 0.25em;
}

.up-union__row--join .up-union__lane { color: var(--up-c-accent); }

.up-union__fact {
    font-size: 0.98rem;
    line-height: 1.55;
}

.up-contents__door {
    margin: 18px 0 0;
    font-size: 0.94rem;
    color: var(--up-c-soft);
    max-width: var(--up-measure);
}

@media (max-width: 640px) {
    .up-union__row { grid-template-columns: minmax(0, 1fr); gap: 2px; }
}

/* ---- Colophon -------------------------------------------------------- */

.up-colophon .up-display--lg { max-width: 18ch; }

.up-plate--wide {
    position: static;
    margin: 0 0 clamp(34px, 5vw, 60px);
}

/* The two plan sections (John, 10 October 2026), one per paid tier. */
.up-plans {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: clamp(22px, 3vw, 44px);
    margin-top: clamp(20px, 3vw, 32px);
}

.up-plan {
    border-top: 1px solid var(--up-c-line);
    padding-top: 16px;
}

.up-plan__name { margin-top: 0; }

.up-plan__list { margin-top: 14px; }

.up-plan__action { margin-top: 18px; }

.up-plan__action form { margin: 0; }

.up-plan__action button[type="submit"],
.up-plan__action button[type="button"] {
    font-family: var(--font-display);
    font-weight: 600;
}

@media (max-width: 900px) {
    .up-plans { grid-template-columns: minmax(0, 1fr); }
}

.up-colophon__grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: clamp(28px, 5vw, 64px);
    align-items: start;
    margin: clamp(30px, 4vw, 48px) 0 clamp(40px, 6vw, 68px);
    padding-top: clamp(26px, 3vw, 36px);
    border-top: 1px solid var(--up-c-line);
}

.up-price {
    font-family: var(--font-display);
    font-size: clamp(1.75rem, 3.1vw, 2.4rem);
    font-weight: 600;
    margin: 0;
    font-variant-numeric: tabular-nums;
}

.up-price-alt {
    margin: 4px 0 16px;
    color: var(--up-c-soft);
}

.up-colophon__grid .up-body { font-size: 0.92rem; }

.up-colophon__links {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
    gap: clamp(24px, 4vw, 56px);
    padding-bottom: clamp(30px, 4vw, 48px);
}

.up-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.up-list li {
    padding: 9px 0;
    border-top: 1px solid var(--up-c-line);
    font-size: 0.96rem;
}

.up-list li:first-child { border-top: 0; }

/* The ask, set as a line of running text rather than a button island: this is
   a colophon, and the subscribe control beside it is the only affordance the
   ending needs. */
.up-colophon__ask {
    font-family: var(--font-display);
    font-size: clamp(1.05rem, 1.7vw, 1.3rem);
    line-height: 1.5;
    max-width: 46ch;
    margin: 0 0 20px;
}

.up-colophon__action form { margin: 0; }

.up-colophon__action button[type="submit"],
.up-colophon__action button[type="button"] {
    font-size: 0.97rem;
    padding: 12px 22px;
    border-radius: var(--radius-pill);
    cursor: pointer;
}

.up-colophon__action .billing-interval {
    border: 1px solid var(--up-c-line);
    border-radius: 8px;
}

.up-colophon__action .plan-trial-note {
    color: var(--up-c-soft);
    font-size: 0.9rem;
}

.up-imprint {
    font-size: 0.86rem;
    line-height: 1.65;
    color: var(--up-c-soft);
    max-width: 74ch;
    margin: 0;
}

/* ---- Entrances (JS-gated, once, on entry) --------------------------- */

.up--js [data-up-in] {
    opacity: 0;
    transform: translateY(12px);
    transition: opacity 600ms var(--up-ease), transform 600ms var(--up-ease);
}

.up--js [data-up-in].is-in {
    opacity: 1;
    transform: none;
}

/* ---- Responsive ------------------------------------------------------ */

@media (max-width: 900px) {
    .up-split,
    .up-spread,
    .up-colophon__grid {
        grid-template-columns: minmax(0, 1fr);
    }

    .up-split__aside { position: static; }

    .up-glare { margin-bottom: 30px; }

    .up-plate {
        position: static;
        margin-bottom: 26px;
    }

    /* The mirrored spread has nothing to mirror in one column, and leaving the
       order flipped would put chapter II's plate under its own argument while
       every other chapter's sits above it. */
    .up-spread--mirror .up-plate { order: 0; }

    /* The desktop floor on the display ramp wraps the title-page headline to
       six lines on a phone; step it down a rung and give it more measure. */
    .up-title .up-display--xl {
        font-size: clamp(1.8rem, 7.6vw, 2.4rem);
        max-width: 22ch;
    }

    .up-shift { grid-template-columns: minmax(0, 1fr); }
    .up-shift__dates { white-space: normal; }

    /* The folio line is a numeral, a rule and a title, and at this width the
       two labels cannot share a row without the rule collapsing to nothing.
       Break it the way a running head breaks: numeral and rule, title under. */
    .up-folioline {
        flex-wrap: wrap;
        gap: 6px 12px;
    }

    .up-folioline__num { order: 1; }
    .up-folioline__rule { order: 2; min-width: 28px; }
    .up-folioline__of {
        order: 3;
        flex: 1 0 100%;
        letter-spacing: 0.1em;
    }
}

/* ---- Reduced motion: fewer and gentler, not zero. The opacity that
       carries comprehension stays; every position change goes. ---------- */

@media (prefers-reduced-motion: reduce) {
    .up--js [data-up-in] {
        transform: none !important;
    }

    .up * {
        animation-duration: 0.01ms !important;
        transition-duration: 120ms !important;
    }
}
