/* Mirrors PrintLayout's geometry: US Letter 612x792pt, 54pt margins, a 24pt
   footer band, 660pt body, 11pt/16pt reading text. The domain paginates;
   sheets are fixed height so the browser never chooses a page break. */

@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 Franklin";
    src: url("/fonts/libre-franklin-latin.woff2") format("woff2");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}

:root {
    --bark: #22302a;
    --bark-soft: #3a4a40;
    --sun: #9c7a33;
    --paper: #f3ebda;
    --border: #d8c9b0;
    --border-light: #e3d8c4;
    --muted: #5c5044;
    --muted-soft: #8a7c6d;
    --shadow-md: rgba(50, 44, 36, 0.12);
    --ff-display: "Libre Caslon Display", Georgia, serif;
    --ff-text: "Libre Caslon Text", Georgia, serif;
    --crossword-letter: #FFFFFF;
    --switch-off: #9aa19c;
    --switch-on: #c9a24b;
    --switch-knob: #FFFFFF;
    --switch-shadow: rgba(0, 0, 0, 0.4);
}

/* Browsers print with background graphics off by default, which drops the
   sheet colour and the crossword's blocked cells; exact keeps both inks. */
html {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
}

/* Low ink: a toner-saving palette (white surfaces, neutral accent, no shadow)
   keyed on the checked switch, so the page recolors as it flips. Custom
   properties only, plus the blocked-cell fill on its own selector below:
   low ink moves no geometry, content or pagination. */
html:has(#ink-switch:checked) {
    --crossword-letter: #FFFFFF;
    --bark: #111111;
    --bark-soft: #262626;
    --sun: #333333;
    --paper: #FFFFFF;
    --border: #8A8A8A;
    --border-light: #C8C8C8;
    --muted: #4A4A4A;
    --muted-soft: #5A5A5A;
    --shadow-md: transparent;
}

@page {
    size: letter;
    margin: 0;
}

* {
    box-sizing: border-box;
}

body {
    margin: 0;
    background: var(--paper);
    color: var(--bark);
    font-family: var(--ff-text);
    font-size: 11pt;
    line-height: 16pt;
}

.sheet {
    width: 612pt;
    height: 792pt;
    padding: 54pt 54pt 78pt;
    position: relative;
    overflow: hidden;
    break-after: page;
    background: var(--paper);
}

.sheet .body {
    height: 660pt;
    overflow: hidden;
}

.sheet footer.edition {
    position: absolute;
    left: 54pt;
    right: 54pt;
    bottom: 54pt;
    height: 24pt;
    padding-top: 4pt;
    border-top: 1pt solid var(--border);
    font-size: 8.5pt;
    color: var(--muted-soft);
}

.title {
    margin: 0 0 8pt;
}

.title h1 {
    margin: 0;
    font-family: var(--ff-display);
    font-size: 17pt;
    line-height: 20pt;
}

.title .work,
.title .band {
    margin: 0;
    font-size: 10pt;
    line-height: 14pt;
    color: var(--muted-soft);
}

h2 {
    margin: 6pt 0 8pt;
    font-family: var(--ff-display);
    font-size: 10.5pt;
    line-height: 13pt;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    border-bottom: 1pt solid var(--sun);
    padding-bottom: 2pt;
}

p {
    margin: 0 0 8pt;
}

.verse-line {
    display: block;
}

.label {
    display: block;
    font-size: 8.5pt;
    line-height: 12pt;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--sun);
}

.question .tag {
    font-size: 8pt;
    padding: 0 4pt;
    border: 1pt solid var(--border-light);
    border-radius: 6pt;
    white-space: nowrap;
}

.educator-note {
    margin: 0 0 8pt;
    font-size: 9.5pt;
    line-height: 13pt;
    color: var(--muted);
}

.educator-note .label {
    display: inline;
    margin-right: 4pt;
}

.rules {
    margin: 0 0 8pt;
}

.rule {
    height: var(--rule-h);
    border-bottom: 1pt solid var(--muted-soft);
}

.vocab {
    margin: 0 0 8pt;
}

.vocab .word {
    font-weight: bold;
}

.vocab .context {
    display: block;
    font-style: italic;
    color: var(--muted);
}

.vocab .definition {
    display: block;
}

.bullets {
    margin: 0 0 8pt;
}

.bullets ul {
    margin: 0;
    padding-left: 14pt;
}

/* vocabulary crossword: the page the two younger bands get IN PLACE OF the
   builder entries. Geometry mirrors the domain and the oracle: square cells
   at most 22pt and never wider than 360pt across, shrunk by the domain only
   as far as the one sheet needs, or as far as it takes to share a sheet with
   a thin tail, and never below 16pt (cell size rides inline from the block's
   fit), the table carries the matching inline height (rows * cell) and
   every cell its own inline width/height, so the browser lays out exactly
   the rows*cell points the domain charges — the td line-height only sizes
   the clue-number text inside the cell, never the row. The number sits
   small in the cell corner, the clue columns sit under the grid or beside
   it, and the word list closes the page. Letter cells paint the
   crossword-letter token (oracle white) and are printed EMPTY — the grid is
   solvable, never pre-solved. The clue lists carry the definitions; there
   are no hints.
   Blocked cells paint the bark token; the blocked-cell rule below re-declares
   that one fill to mid-grey #B8B8B8 and nothing else. Geometry, content and
   pagination are identical between variants. */
.crossword {
    margin: 0 0 8pt;
    break-inside: avoid;
    page-break-inside: avoid;
}

.crossword-grid {
    margin: 0 auto 10pt;
    border-collapse: collapse;
    table-layout: fixed;
}

/* the grid with its clues. Under the grid the Across and Down lists sit side
   by side; beside a tall grid they stack in the column next to it, Across
   over Down. The domain picks the arrangement and charges its height. */
.crossword-board.beside {
    display: grid;
    grid-template-columns: max-content 1fr;
    column-gap: 24pt;
    align-items: start;
    margin: 0 0 10pt;
}

.crossword-board.beside .crossword-grid {
    margin: 0;
}

.crossword-board.beside .crossword-clues {
    grid-template-columns: 1fr;
    row-gap: 8pt;
    margin: 0;
}

.crossword-grid td {
    border: 0.5pt solid var(--bark);
    /* the clue-number text metrics only: the row height comes from the
       inline per-cell height the renderer emits (square-cell geometry), so
       this line-height never moves pagination */
    font-size: 11pt;
    line-height: 16pt;
    text-align: center;
    vertical-align: middle;
    background: var(--crossword-letter);
    color: var(--bark);
    padding: 0;
    overflow: hidden;
}

.crossword-grid td.blocked {
    background: var(--bark);
}

/* the oracle's one variant-dependent value: blocked cells print mid-grey
   #B8B8B8 in low ink instead of the bark color. A scoped override, so the
   token-table palette above stays closed and low ink still moves no
   geometry, content, or pagination. */
html:has(#ink-switch:checked) .crossword-grid td.blocked {
    background: #B8B8B8;
}

.crossword-number {
    display: block;
    font-size: 6pt;
    line-height: 8pt;
    text-align: left;
    color: var(--sun);
}

.crossword-clues {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 24pt;
    margin: 0 0 8pt;
    font-size: 10pt;
    line-height: 12pt;
}

.crossword-clues ul {
    margin: 0;
    padding-left: 14pt;
}

/* the word list under the grid, two 240pt columns filled down the first:
   each word, then the sentence the book uses it in directly beneath it, at
   the 10pt/12pt measure the domain charges per column */
.word-list {
    margin: 0 0 8pt;
}

.word-columns {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 24pt;
}

.word-columns ul {
    margin: 0;
    padding: 0;
    list-style: none;
}

.word-columns li {
    margin: 0 0 4pt;
    font-size: 10pt;
    line-height: 12pt;
}

.word-columns .word {
    display: block;
    font-weight: bold;
}

.word-columns .context {
    display: block;
    font-size: 9.5pt;
    font-style: italic;
    color: var(--muted);
    quotes: none;
}

.define-these {
    margin: 0 0 8pt;
}

.define-these ul {
    margin: 0;
    padding-left: 14pt;
}

.vocab-fallback {
    margin: 0 0 8pt;
}

/* one of a companion card's two readings, over the quotes it rests on */
.reading {
    margin: 0 0 8pt;
}

.reading p {
    margin: 0;
}

.reading .evidence {
    margin: 0;
    padding-left: 14pt;
    font-style: italic;
    color: var(--muted);
}

/* drill sheets: three columns spread over the sheet's whole writing area,
   holding the longest sheet a family can ask for */
.drill-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    column-gap: 24pt;
    align-content: space-between;
    height: 580pt;
    margin-top: 12pt;
    font-size: 14pt;
    line-height: 18pt;
}

.drill-grid .problem {
    display: flex;
    align-items: baseline;
    gap: 6pt;
}

.drill-grid .blank {
    flex: 1;
    border-bottom: 1pt solid var(--bark);
    min-width: 36pt;
}

/* no row-gap: `space-between` already spreads the rows over the fixed
   height, and a gap on top of it overflows the sheet at 75 problems */
.drill-grid.answers {
    font-size: 11pt;
    line-height: 15pt;
}

.drill-grid .answer {
    font-weight: bold;
}

/* the worksheet as columns of figures: tabular digits, and each problem a
   subgrid of the sheet's own columns, so every expression in a column sizes
   to the widest and sets flush right. The equals signs, the writing lines,
   and the key's answers then stand in clean columns; rows, height, and
   pagination are the grid's as before. */
.drill-grid {
    font-variant-numeric: tabular-nums;
}

@supports (grid-template-columns: subgrid) {
    .drill-grid {
        grid-template-columns: repeat(3, max-content 1fr);
    }

    .drill-grid .problem {
        display: grid;
        grid-column: span 2;
        grid-template-columns: subgrid;
        column-gap: 6pt;
        align-items: baseline;
    }

    .drill-grid .expr {
        text-align: right;
    }
}

@media screen {
    body {
        background: var(--bark-soft);
        padding: 2rem 0;
    }

    .sheet {
        margin: 0 auto 2rem;
        box-shadow: 0 2pt 10pt var(--shadow-md);
    }

    .print-toolbar {
        width: min(612pt, calc(100% - 32px));
        margin: 0 auto 1rem;
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        justify-content: space-between;
        gap: 12px;
        color: var(--paper);
        font: 14px "Libre Franklin", sans-serif;
    }
    .print-toolbar .print-note {
        flex: 1 1 260px;
        margin: 0;
    }

    /* The ink switch. The whole label is the 44px target, and the words beside
       the track name the state, so it never rests on colour alone. The two
       words share one cell, so the bar keeps its size in either state. */
    .ink-choice {
        display: inline-flex;
        align-items: center;
        gap: 10px;
        min-height: 44px;
        font-weight: 600;
        cursor: pointer;
    }
    .ink-switch {
        appearance: none;
        position: relative;
        flex: none;
        width: 44px;
        height: 26px;
        margin: 0;
        border: 1px solid transparent;
        border-radius: 13px;
        background: var(--switch-off);
        cursor: pointer;
    }
    .ink-switch::before {
        content: "";
        position: absolute;
        top: 2px;
        left: 2px;
        width: 20px;
        height: 20px;
        border-radius: 50%;
        background: var(--switch-knob);
        box-shadow: 0 1px 2px var(--switch-shadow);
    }
    .ink-switch:checked {
        background: var(--switch-on);
    }
    .ink-switch:checked::before {
        transform: translateX(18px);
    }
    .ink-switch:focus-visible {
        outline: 2px solid var(--paper);
        outline-offset: 3px;
    }
    .ink-state {
        display: inline-grid;
    }
    .ink-state > span {
        grid-area: 1 / 1;
    }
    .ink-switch:not(:checked) ~ .ink-state .ink-low,
    .ink-switch:checked ~ .ink-state .ink-full {
        visibility: hidden;
    }
    @media (prefers-reduced-motion: no-preference) {
        .ink-switch,
        .ink-switch::before {
            transition: background-color 160ms ease, transform 160ms ease;
        }
    }
    @media (forced-colors: active) {
        .ink-switch {
            border-color: ButtonText;
            --switch-knob: ButtonText;
        }
        .ink-switch:checked {
            background: Highlight;
            --switch-knob: HighlightText;
        }
    }
}

/* The preview on screen, alive: each sheet is dealt onto the desk as it
   comes up the screen, from a slight skew to square, so scrolling the
   preview reads as leafing through the printed pile. Transform only, so
   nothing on a sheet is ever faint; screen only, so printing lays every
   sheet square; and only when motion is welcome. A browser without
   scroll-driven animation shows the sheets square. The math drills share
   this stylesheet and keep their sheets still. */
@supports (animation-timeline: view()) {
    @media screen and (prefers-reduced-motion: no-preference) {
        .sheet:not(:has(.drill-grid)) {
            animation: sheet-dealt linear both;
            animation-timeline: view();
            animation-range: entry 0% entry 70%;
        }
        .sheet:nth-of-type(even):not(:has(.drill-grid)) {
            animation-name: sheet-dealt-even;
        }
    }
}

@keyframes sheet-dealt {
    from {
        transform: translateY(48pt) rotate(-1.4deg);
    }
    to {
        transform: none;
    }
}

@keyframes sheet-dealt-even {
    from {
        transform: translateY(48pt) rotate(1.1deg);
    }
    to {
        transform: none;
    }
}

/* On screen the drill's two sheets are handed over one after the other: the
   worksheet is laid down, then its answer key lands on the pile a beat later,
   and each problem's writing line is ruled across. Screen only, and only
   when motion is welcome; printed, the sheets are exactly as above. */
@media screen and (prefers-reduced-motion: no-preference) {
    .sheet:has(.drill-grid) {
        animation: drill-sheet-laid 0.8s cubic-bezier(0.22, 1, 0.36, 1) both;
    }

    .sheet:has(.drill-grid) + .sheet:has(.drill-grid) {
        animation-delay: 0.35s;
    }

    .drill-grid .blank {
        transform-origin: left;
        animation: drill-line-ruled 0.5s cubic-bezier(0.22, 1, 0.36, 1) 0.6s both;
    }

    .drill-grid .answer {
        animation: drill-answer-set 0.5s ease-out 0.95s both;
    }
}

@keyframes drill-sheet-laid {
    from {
        opacity: 0;
        transform: translateY(28px) rotate(-1.2deg);
    }
}

@keyframes drill-line-ruled {
    from {
        transform: scaleX(0);
    }
}

@keyframes drill-answer-set {
    from {
        opacity: 0;
    }
}

@media print {
    html,
    body {
        background: var(--paper) !important;
        padding: 0 !important;
    }

    body::after,
    .paper-grain {
        display: none !important;
    }

    .site-header,
    .sidebar-drawer,
    .sidebar-backdrop,
    .app-footer,
    .print-toolbar,
    .print-note,
    .no-print {
        display: none !important;
    }

    /* `@page` has no margin, because a sheet carries its own 54pt. A screen
       page printed from the shell has no sheet around it, so the margin it
       needs is here. */
    .app-main {
        max-width: none;
        padding: 54pt;
    }

    .sheet {
        margin: 0;
        box-shadow: none !important;
        background: var(--paper) !important;
        background-image: none !important;
        break-inside: avoid;
        page-break-inside: avoid;
    }

    .guide-part,
    .questions > li,
    .question,
    .educator-note,
    .vocab,
    .drill-grid .problem,
    table tr {
        break-inside: avoid;
        page-break-inside: avoid;
    }
}
