/* ==========================================================================
   My Cookbook: the recipe page's clip controls, the cookbook page and the
   collection page. The cookbook is the reader's own recipe box, in full
   colour: their saved recipes are the site's photo cards, each filed
   behind its category (its tab and stripe), standing behind a strip of
   dividers. "Saved recipes" is the front divider, in plain card stock;
   each collection is one of the cook's own dividers, labelled by hand, so
   its tab is the pale blue of the founder's journal with its name in the
   cook's pen (category colours belong to the categories, never to
   anything else). The cook's private notes are written in pen on ruled
   lines under each card. A collection's page holds its name, the cook's
   description in pen and a hand of its first cards, then the recipes
   numbered in their printed order, each photo mounted on its category's
   fill. No washes: the cards and the dividers carry the colour.

   Builds on styles.css: the tokens, .btn, .clip, the divider tabs
   (.pills / .pill, .cat-tab), the photo cards and their grid, the status
   marks and figures, .menu-panel, .field, the drawn checkboxes, .ruled
   and .empty-state. Only what these pages need beyond it lives here, and
   every colour is a token.

   Contents
   01  Recipe page: Clip, the collections menu, Print
   02  Page layout: the title line, the dividers, a new collection
   03  Saved recipes: the cards, the cook's note, Remove
   04  Print mode: tick boxes and the print bar
   05  Collection page: its face, the hand of cards, the edit slip
   06  Collection page: the numbered list, adding a recipe
   07  Notices and empty states
   08  Small screens
   09  Touch, forced colours, print

   Right to left: spacing, borders and offsets are logical, so they mirror
   under <html dir="rtl">; the hand of cards' turns mirror beside it.
   ========================================================================== */

/* 01  Recipe page: Clip, the collections menu, Print ------------------------ */

/* The panel's parts join the page's action row, so the wrapper (kept for
   htmx swaps) generates no box of its own. */
.clip-panel {
    display: contents;
}

.clip-save-form,
.clip-menu-list,
.clip-menu-new {
    margin: 0;
}

form.htmx-request .clip {
    opacity: 0.6;
    cursor: progress;
}

/* Print sits at the end of the row (the left in right-to-left pages),
   followed by Download. */
.clip-print {
    margin-inline-start: auto;
}

.clip-panel:has(.clip-print) + .push {
    margin-inline-start: 0;
}

/* "Add to collection": a <details> menu, so it works without JavaScript.
   Its panel is the site's menu slip (.menu-panel: card stock, a control
   edge, the red line on top) hanging under the summary. */
.clip-menu {
    position: relative;
}

.clip-menu > summary {
    list-style: none;
}

.clip-menu > summary::-webkit-details-marker {
    display: none;
}

.clip-menu[open] > summary {
    background: var(--paper-2);
}

.clip-menu-pop {
    width: min(20rem, calc(100vw - 2 * var(--gutter)));
}

/* "Added to Weeknight dinners": a notice line (bar, glyph, words). */
.clip-menu-status {
    display: flex;
    align-items: flex-start;
    gap: var(--s-2);
    margin: var(--s-2) var(--s-4) var(--s-3);
    padding-inline-start: var(--s-3);
    border-inline-start: 2px solid var(--ink);
    font-size: var(--t-s);
    font-weight: 600;
    line-height: 1.4;
    color: var(--ink);
}

.clip-menu-status .icon {
    width: 16px;
    height: 16px;
    margin-top: 0.15em;
}

.clip-menu-pop > .field-error {
    margin: var(--s-2) var(--s-4) var(--s-3);
}

.clip-menu-list ul {
    max-height: min(20rem, 50vh);
    overflow-y: auto;
    list-style: none;
}

/* Each collection is a line on the slip, written on a ruled line like
   the other menus' items. */
.clip-menu-item {
    display: flex;
    align-items: center;
    gap: var(--s-3);
    width: 100%;
    min-height: 44px;
    padding: var(--s-2) var(--s-4);
    border: 0;
    border-bottom: 1px solid var(--rule);
    background: none;
    color: var(--ink);
    font-size: var(--t-s);
    line-height: 1.3;
    text-align: start;
}

.clip-menu-list li:last-child .clip-menu-item {
    border-bottom: 0;
}

.clip-menu-item:hover {
    background: var(--paper-2);
}

/* A tick box drawn like the site's checkboxes (styles.css section 07): a
   1.5px control edge on card stock; when the collection holds the recipe
   it fills with ink and a card-stock tick is knocked out of it. The
   sprite's tick inside is only for forced colours (section 08). */
.clip-menu-check {
    flex: none;
    width: 20px;
    height: 20px;
    border: 1.5px solid var(--control);
    border-radius: var(--corner);
    background: var(--card);
}

.clip-menu-check .icon {
    display: none;
}

.clip-menu-item:hover .clip-menu-check {
    border-color: var(--ink);
}

.clip-menu-item[aria-pressed="true"] {
    font-weight: 600;
}

.clip-menu-item[aria-pressed="true"] .clip-menu-check {
    border-color: var(--ink);
    background: var(--ink) var(--tick-mark) center / 78% no-repeat;
}

.clip-menu-name {
    flex: 1;
    min-width: 0;
    overflow-wrap: anywhere;
}

/* Text the reader typed (a collection's name or description, a note) has
   no language to tag it with, so it takes its direction from its own
   words, line by line, but lines up with the page like the titles around
   it. A note's pen rule and padding stay on its <p>, and the words go in
   an inner block: Safari lays the padding and the border of a plaintext
   box out in the words' direction, so the rule would run through them. */
.clip-menu-name,
.shelf-name,
.collection-face h1,
.collection-desc,
.clip-note-body {
    unicode-bidi: plaintext;
}

.clip-note-body {
    display: block;
}

[dir="ltr"] :is(.clip-menu-name, .shelf-name, .collection-face h1, .collection-desc, .clip-note-body) { text-align: left; }
[dir="rtl"] :is(.clip-menu-name, .shelf-name, .collection-face h1, .collection-desc, .clip-note-body) { text-align: right; }

.clip-menu-meta {
    font-size: var(--t-xs);
    font-weight: 400;
    color: var(--ink-3);
    font-variant-numeric: tabular-nums lining-nums;
}

.clip-menu-empty {
    padding: var(--s-2) var(--s-4);
    font-size: var(--t-s);
    color: var(--ink-2);
}

/* The new-collection field and "Open my cookbook" close the slip, each
   under its own ruled line. */
.clip-menu-new {
    display: flex;
    gap: var(--s-2);
    padding: var(--s-3) var(--s-4);
    border-top: 1px solid var(--rule);
}

.clip-menu-new .input {
    flex: 1;
    min-width: 0;
    min-height: 44px;
    padding-block: 8px;
    font-size: var(--t-s);
}

.clip-menu-link {
    display: flex;
    align-items: center;
    min-height: 44px;
    padding: 0 var(--s-4);
    border-top: 1px solid var(--rule);
    font-size: var(--t-s);
    font-weight: 600;
}


/* 02  Page layout: the title line, the dividers, a new collection ------------ */
.cookbook-page {
    padding-bottom: var(--section);
}

/* The cookbook's title line: "My Cookbook" on the red line, with the print
   switch and (in print mode) Select all and Clear at its end, on the
   title's baseline, as a section opener carries its meta. The tools are
   centred on their own line, so the words share one line whatever box
   holds them (a label's baseline would come from its checkbox); the group
   still meets the h1 on its first item's baseline.

   The red line is the title's, as on every page: drawn under the h1 (its
   usual 12px below the words) but across the whole row. Where the tools
   don't fit beside the title (phones, or a long language in print mode
   at any width) they wrap under the line instead of pushing it down, so
   the title always sits on its line. The line is the h1's ::after, out of
   flow at its static place under the title's last line and stretched to
   the row (the containing block); a border, so forced colours keep it. */
.cookbook-head-row {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--s-2) var(--s-5);
}

.cookbook-head-row h1 {
    padding-bottom: calc(var(--s-3) + var(--head-line));
    border-bottom: 0;
}

.cookbook-head-row h1::after {
    content: "";
    position: absolute;
    display: block;
    inset-inline: 0;
    margin-top: var(--s-3);
    border-top: var(--head-line) solid var(--card-red);
}

.cookbook-tools {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0 var(--s-5);
}

/* The dividers: the strip of tabs (.pills, on its 1.5px ink edge) and,
   after it, the blank dashed tab for a new collection. The strip draws its
   own edge, which scrolls with it; the shelf draws the same edge under
   the whole row, so the blank tab stands on it too and the cards below
   are filed behind the lot. */
.cookbook-shelf {
    position: relative;
    display: flex;
    align-items: flex-end;
    gap: 0 3px;
    background: linear-gradient(var(--ink), var(--ink)) left bottom / 100% 1.5px no-repeat;
}

.cookbook-shelf > .shelf {
    flex: 0 1 auto;
    min-width: 0;
}

/* Inside a tab: the name, then its count in ink-3 figures (.pill-count).
   A name longer than a tab holds ends in an ellipsis (its own page has it
   whole). */
.shelf-name {
    min-width: 0;
    max-width: 16rem;
    overflow: hidden;
    text-overflow: ellipsis;
}

.shelf-count {
    flex: none;
    font-variant-numeric: tabular-nums lining-nums;
}

/* The cook's own dividers: the journal's pale blue with a ruled-blue edge
   (the shape is carried by the edge and the words, never the fill), the
   name in the cook's pen (pen on the journal's tint 9.6:1). "Saved
   recipes" keeps the plain card stock of the All tab. */
.shelf-own {
    --tab-fill: var(--journal-tint);
    --tab-edge: var(--rule-2);
}

.shelf-own .shelf-name {
    color: var(--pen);
}

/* A new collection: the next blank divider, its tab dashed in the darker
   ruled blue (a space still to fill, as an empty state is), standing on
   the shelf's edge like the others. Open, it stands forward as a chosen
   tab does (taller, ink outline, card stock covering the edge under it)
   and its slip hangs from it: the site's menu slip (.menu-panel) holding
   one field. */
.shelf-new {
    position: relative;
    flex: none;
}

.shelf-new-tab {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 42px;
    margin-bottom: 1.5px;
    padding: 0 14px;
    border: 1px dashed var(--rule-2);
    border-bottom: 0;
    border-radius: var(--tab-corner) var(--tab-corner) 0 0;
    color: var(--ink-2);
    font-size: var(--t-s);
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
    transition: min-height var(--dur) var(--ease);
}

.shelf-new-tab .icon {
    width: 16px;
    height: 16px;
}

.shelf-new-tab:hover {
    min-height: 45px;
    color: var(--ink);
}

.shelf-new[open] > .shelf-new-tab {
    position: relative;
    z-index: 1;
    min-height: 48px;
    margin-bottom: 0;
    padding-bottom: 1.5px;
    border: 1.5px solid var(--ink);
    border-bottom: 0;
    background: var(--card);
    color: var(--ink);
}

.shelf-new-form.menu-panel {
    inset-inline-start: 0;
    inset-inline-end: auto;
    top: calc(100% + 6px);
    display: grid;
    gap: var(--s-2);
    width: min(22rem, calc(100vw - 2 * var(--gutter)));
    margin: 0;
    padding: var(--s-4);
}

.shelf-new-row {
    display: flex;
    gap: var(--s-2);
}

.shelf-new-row .input {
    flex: 1;
    min-width: 0;
}

.shelf-new-form .textarea {
    min-height: 72px;
}

/* 03  Saved recipes -------------------------------------------------------------
   The saved recipes are the site's photo-card grid (styles.css section
   09): each card filed behind its category, the card's clip square left
   empty (Remove is under the card). Each <li> spans two rows of the grid
   by subgrid: its card in the first, so the cards in a row line up top
   and bottom, and its foot in the second (the cook's note in pen, "Add a
   note" and Remove), so the feet start on one line. The grid's own row
   gap is the foot's bottom padding instead (room for the next row's
   tabs). The <li> is not a size container (containment would scope the
   print counter that counts its tick); the card's box is, so the card
   still reads its own width. Without subgrid each <li> simply stacks its
   card and foot. */
.cookbook-clips {
    margin-top: var(--s-2);
}

.cookbook-index .recipe-list {
    row-gap: 0;
    counter-reset: picked list-item;
}

.cookbook-index .recipe-list > .cookbook-clip {
    container-type: normal;
    display: grid;
    grid-row: span 2;
    grid-template-rows: subgrid;
}

.cookbook-clip-card {
    position: relative;
    display: flex;
    flex-direction: column;
    min-width: 0;
    container-type: inline-size;
}

.cookbook-clip-card > .recipe-card {
    flex: 1 0 auto;
}

.cookbook-clip-foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    align-content: flex-start;
    gap: 0 var(--s-3);
    min-width: 0;
    padding: var(--s-2) 0 48px;
    container-type: inline-size;
    font-size: var(--t-s);
    line-height: 1.35;
}

/* The note's parts join the foot's line (clip_note, cookbook.html): the
   note on a line of its own, then "Add a note" and Remove, then the editor
   when it is open, in place of the note. */
.cookbook-clip-foot .clip-note {
    display: contents;
}

/* The cook's own note: handwriting, so it is the pen (blue-black) on
   ruled lines (.ruled: the line-height and the lines share one pitch),
   with a 2px pen rule at its start like the testers' notes on the recipe
   page. Upright: a note can run to a paragraph. A line of its own; no
   vertical padding, so the lines start at its top. */
.clip-note-text {
    order: 1;
    flex: 0 0 100%;
    margin-block: var(--s-1) var(--s-2);
    padding-inline-start: var(--s-3);
    border-inline-start: 2px solid var(--pen);
    color: var(--pen);
    font-size: var(--t-m);
    white-space: pre-line;
}

.clip-note-saved {
    order: 2;
    flex: 0 0 100%;
    display: flex;
    align-items: center;
    gap: 6px;
    margin-bottom: var(--s-1);
    font-weight: 600;
    color: var(--ink);
}

.clip-note-saved .icon {
    width: 16px;
    height: 16px;
}

/* "Add a note" and Remove: words with their glyphs, on the ruled blue
   underline the site's quiet links use; Remove at the far end. */
.clip-note-edit {
    order: 3;
    min-width: 0;
}

.clip-note-edit > summary,
.cookbook-clip-remove .link-button {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 36px;
    color: var(--ink);
    font-weight: 600;
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-decoration-color: var(--rule-2);
    text-underline-offset: 0.2em;
    cursor: pointer;
}

.clip-note-edit > summary {
    list-style: none;
}

.clip-note-edit > summary::-webkit-details-marker {
    display: none;
}

.clip-note-edit > summary .icon,
.cookbook-clip-remove .icon {
    flex: none;
    width: 16px;
    height: 16px;
    color: var(--ink-2);
}

.clip-note-edit > summary:hover,
.clip-note-edit[open] > summary,
.cookbook-clip-remove .link-button:hover {
    text-decoration-color: currentColor;
}

.cookbook-clip-remove {
    order: 4;
    margin: 0;
    margin-inline-start: auto;
}

.cookbook-clip-remove .link-button {
    color: var(--ink-2);
    white-space: nowrap;
}

.cookbook-clip-remove .link-button:hover {
    color: var(--ink);
}

/* Under a phone's narrow card, Remove is its glyph alone (its words are
   still read), a 44px target, so it shares the line with "Add a note". */
@container (width < 15rem) {
    .cookbook-clip-remove .link-button {
        justify-content: center;
        min-width: 44px;
    }

    .cookbook-clip-remove .link-button > span:not(.visually-hidden) {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }

    .cookbook-clip-remove .icon {
        width: 18px;
        height: 18px;
    }
}

/* The editor shows while "Add a note" is open (always, without CSS), in
   place of the note it holds. */
.clip-note:has(> .clip-note-edit:not([open])) > .clip-note-form,
.clip-note:has(> .clip-note-edit[open]) > .clip-note-text {
    display: none;
}

.clip-note-form {
    order: 5;
    flex: 0 0 100%;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--s-2);
    margin: var(--s-1) 0 0;
}

.clip-note-form .textarea {
    min-height: 96px;
    font-size: var(--t-s);
}

.clip-note-form .btn {
    justify-self: start;
}

/* 04  Print mode ------------------------------------------------------------------
   "Print a selection" is a checkbox (#print-mode) at the end of the title
   line. While it is ticked, every card shows a tick box on its photo's
   corner (the whole card ticks it), its photo fades until it is picked,
   Select all and Clear appear beside the switch, and the print bar sticks
   to the foot of the window. A CSS counter counts the ticks: the list
   resets it and the bar follows the list, so the bar can read it (each
   <li> counts its own tick, so no <li> may be a size container, which
   would scope the count to itself). */
.print-mode-switch {
    gap: 10px;
    padding-block: 0;
    align-items: center;
    color: var(--ink);
    font-size: var(--t-s);
    font-weight: 600;
    line-height: 1.3;
}

.print-mode-switch input {
    margin-top: 0;
}

/* Select all and Clear, after the switch; each shows only when it would
   change something. */
.selection-top {
    display: none;
    gap: 0 var(--s-1);
    margin-inline-start: calc(-1 * var(--s-3));
}

.cookbook-page:has(.print-mode-toggle:checked) .selection-top {
    display: flex;
}

.cookbook-page:not(:has(.cookbook-pick input:not(:checked):not(:disabled))) .selection-all,
.cookbook-page:not(:has(.cookbook-pick input:checked)) .selection-clear {
    display: none;
}

/* The tick box: a 44px square of card stock on the photo's corner, where
   the clip square stands on other pages, holding a 24px drawn tick box.
   The label itself covers the whole card (in print mode only: the card's
   title is a link otherwise), so a tap anywhere on the card ticks it. */
.cookbook-pick {
    position: absolute;
    inset: 0;
    z-index: 3;
    display: none;
    cursor: pointer;
}

.cookbook-pick::before {
    content: "";
    position: absolute;
    top: calc(var(--stripe) + 8px);
    inset-inline-end: 9px;
    width: 44px;
    height: 44px;
    border: 1px solid var(--control);
    border-radius: var(--corner);
    background: var(--card);
}

.cookbook-pick input {
    position: absolute;
    top: calc(var(--stripe) + 18px);
    inset-inline-end: 19px;
    width: 24px;
    height: 24px;
    margin: 0;
}

.cookbook-pick input:focus-visible {
    outline: none;
}

/* A recipe the reader can't print (members only) shows the lock in its
   square instead of a tick box; the card's own mark says why. */
.cookbook-clip.is-locked .cookbook-pick {
    cursor: not-allowed;
}

.cookbook-pick-lock {
    position: absolute;
    top: calc(var(--stripe) + 19px);
    inset-inline-end: 20px;
    width: 22px;
    height: 22px;
    color: var(--ink-2);
}

.cookbook-clip.is-locked .cookbook-pick input {
    opacity: 0;
}

.cookbook-page:has(.print-mode-toggle:checked) .cookbook-pick {
    display: block;
}

/* While picking, a card's photo waits faded and greyed until it is
   ticked, so the chosen cards stand out in their colours; a picked card
   also takes an ink edge. The tick box says which are picked, so colour
   never says it alone. The note's controls and "Cook it" step aside. */
.cookbook-page:has(.print-mode-toggle:checked) .cookbook-clip:not(:has(.cookbook-pick input:checked)) .recipe-card-photo img {
    opacity: 0.45;
    filter: grayscale(0.7);
}

.cookbook-page:has(.print-mode-toggle:checked) .cookbook-clip:has(.cookbook-pick input:checked) .recipe-card {
    border-inline-color: var(--ink);
    border-bottom-color: var(--ink);
}

.cookbook-page:has(.print-mode-toggle:checked) :is(.clip-note-edit, .clip-note-form, .clip-note-saved, .cookbook-clip-remove, .recipe-card-action) {
    display: none;
}

.cookbook-clip:has(.cookbook-pick input:focus-visible) .recipe-card {
    outline: var(--focus-width) solid var(--focus);
    outline-offset: 2px;
}

.cookbook-page:has(.print-mode-toggle:checked) .cookbook-clip:has(.cookbook-pick input:checked) {
    counter-increment: picked;
}

/* The print bar: the count, Cancel and Print. It stands at the foot of
   the window on the 1.5px ink edge the dividers stand on, paper behind it
   so the cards pass under it. */
.selection-bar {
    display: none;
    align-items: center;
    gap: var(--s-2) var(--s-4);
    margin: 0;
    padding-block: var(--s-3);
    border-top: 1.5px solid var(--ink);
    background: var(--paper);
}

.cookbook-page:has(.print-mode-toggle:checked) .selection-bar {
    position: sticky;
    bottom: 0;
    z-index: 20;
    display: flex;
}

/* While the bar stands at the foot of the window, the band it covers
   doesn't count as in view: a tick box that Tab reaches there would sit
   inside the window, so the browser wouldn't scroll, and the bar would
   hide it. The bar is 62px tall on phones and 70px from 721px (in every
   language measured); this reserves the taller, plus room for the focus
   ring, so focus (and Page Down) brings a card up above the bar. */
html:has(.print-mode-toggle:checked) {
    scroll-padding-bottom: calc(70px + var(--s-3));
}

.selection-status {
    flex: 1 1 0;
    min-width: 0;
    font-size: var(--t-s);
    line-height: 1.35;
    color: var(--ink-2);
}

/* "3 selected": the figure in Besley, like the other counts. */
.selection-count {
    font-size: var(--t-m);
    font-weight: 700;
    color: var(--ink);
    white-space: nowrap;
}

/* The live count replaces the server's (the fallback without CSS; app.js
   keeps the words current for screen readers) where the sentence puts
   it. Screen readers read the span's own words, so the drawn count has
   empty alt text; browsers without the alt syntax keep the plain
   declaration. */
.selection-n {
    font-size: 0;
}

.selection-n::after {
    content: counter(picked);
    content: counter(picked) / "";
    font-family: var(--latin-serif);
    font-size: var(--t-xl);
    font-weight: 600;
    font-variant-numeric: lining-nums proportional-nums;
}

.selection-cancel,
.selection-print {
    flex: none;
}

/* Nothing ticked yet: Print reads as an outline until there's a choice
   (pressing it anyway explains, from the server). */
.cookbook-page:not(:has(.cookbook-pick input:checked)) .selection-print {
    border-color: var(--control);
    background: var(--card);
    color: var(--ink-2);
}

/* Browsers without :has() show the tick boxes, Select all, Clear and the
   bar all the time, without the live count. The label is then the square
   alone, so the card's title stays a link, and the focus ring is the tick
   box's own. */
@supports not selector(:has(*)) {
    .print-mode-switch,
    .selection-cancel,
    .selection-count {
        display: none;
    }

    .cookbook-pick {
        display: block;
        inset: auto;
        inset-block-start: calc(var(--stripe) + 8px);
        inset-inline-end: 9px;
        width: 44px;
        height: 44px;
    }

    .cookbook-pick::before {
        top: 0;
        inset-inline-end: 0;
    }

    .cookbook-pick input {
        top: 10px;
        inset-inline-end: 10px;
    }

    .cookbook-pick-lock {
        top: 11px;
        inset-inline-end: 11px;
    }

    .cookbook-pick input:focus-visible {
        outline: var(--focus-width) solid var(--focus);
        outline-offset: 2px;
    }

    .selection-top,
    .selection-bar {
        display: flex;
    }
}

/* 05  Collection page: its face, the hand of cards, the edit slip ------------- */
/* The divider's face: the name on the red line, the cook's description in
   their pen (Besley 400, a standfirst in their hand), then Print and Edit.
   Beside it, a hand of its first cards (smaller below 1100px; phones keep
   to the list, whose rows carry the photos). */
.collection-head {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    align-items: end;
    gap: var(--s-5) var(--s-8);
}

.collection-face {
    min-width: 0;
}

.collection-desc {
    max-width: 46ch;
    margin-top: var(--s-4);
    font-family: var(--serif);
    font-size: var(--t-l);
    font-weight: 400;
    line-height: 1.45;
    color: var(--pen);
    white-space: pre-line;
}

.collection-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: var(--s-3);
    margin-top: var(--s-5);
}

.collection-print {
    margin: 0;
}

/* The print button keeps its block class (tests and the out-of-band swap
   use it) but sits in a row here. */
.collection-print .btn-block {
    display: inline-flex;
    width: auto;
}

.collection-edit {
    position: relative;
}

.collection-edit > summary {
    list-style: none;
}

.collection-edit > summary::-webkit-details-marker {
    display: none;
}

.collection-edit[open] > summary {
    background: var(--hover);
}

/* The edit slip opens like a menu: card stock with a control edge and
   the red line on top (the site's .menu-panel), holding a small form. */
.collection-edit-panel {
    position: absolute;
    top: calc(100% + 6px);
    inset-inline-start: 0;
    z-index: 30;
    display: grid;
    gap: var(--s-5);
    width: min(26rem, calc(100vw - 2 * var(--gutter)));
    padding: var(--s-4);
    border: 1px solid var(--control);
    border-top: var(--head-line) solid var(--card-red);
    border-radius: 0 0 var(--corner) var(--corner);
    background: var(--card);
}

.collection-edit-form {
    display: grid;
    gap: var(--s-4);
    margin: 0;
}

.collection-edit-form .textarea {
    min-height: 96px;
}

.collection-edit-form .btn {
    justify-self: start;
}

.collection-delete {
    margin: 0;
    padding-top: var(--s-4);
    border-top: 1px solid var(--rule);
}

/* The hand of cards: up to three of the collection's photos, each mounted
   on its category's fill with the category's tab on its top edge, held
   like a hand round a pivot below them (the first card in front, the
   others fanned behind it), as the home page's hero holds its cards. The
   tabs are cut at stepped places so each word shows. Sized in one unit
   (--u) so the hand scales as a whole. A picture of the list below:
   aria-hidden, and gone when no recipe in it has a photo. */
.collection-fan {
    --u: 1px;
    position: relative;
    justify-self: center;
    width: calc(400 * var(--u));
    height: calc(236 * var(--u));
    pointer-events: none;
}

.collection-fan:not(:has(.collection-fan-card)) {
    display: none;
}

.collection-fan-card {
    --x: 0;
    --rot: 0deg;
    position: absolute;
    left: 50%;
    bottom: calc(6 * var(--u));
    width: calc(200 * var(--u));
    padding: calc(8 * var(--u));
    border: 1px solid var(--c-edge, var(--card-edge));
    border-radius: var(--corner);
    border-start-start-radius: 0;
    background: var(--c, var(--card));
    transform-origin: 50% 150%;
    transform: translateX(-50%) translateX(calc(var(--x) * var(--u))) rotate(var(--rot));
}

.collection-fan-card img {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    border: 1px solid var(--c-edge, var(--card-edge));
    border-radius: var(--photo-corner);
    background: var(--paper-3);
}

.collection-fan-card .cat-tab {
    position: absolute;
    bottom: 100%;
    inset-inline-start: -1px;
    max-width: calc(100% + 2px);
    min-height: calc(28 * var(--u));
    padding-inline: calc(10 * var(--u));
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Front to back: the first card in front, turned a little; the second and
   third fanned out behind it and to its start, so each shows its tab at
   its top-start corner (the front card's tab stands at its end). Right to
   left the hand turns the other way. */
.collection-fan-card:nth-child(1) { --x: 58; --rot: 5deg; z-index: 3; }
.collection-fan-card:nth-child(2) { --x: -4; --rot: -6deg; z-index: 2; }
.collection-fan-card:nth-child(3) { --x: -62; --rot: -17deg; z-index: 1; }
.collection-fan-card:only-child { --x: 0; --rot: -3deg; }
.collection-fan-card:nth-child(1):nth-last-child(2) { --x: 34; }
.collection-fan-card:nth-child(2):last-child { --x: -34; --rot: -8deg; }

.collection-fan-card:nth-child(1):not(:only-child) .cat-tab {
    inset-inline-start: auto;
    inset-inline-end: -1px;
}

[dir="rtl"] .collection-fan-card:nth-child(1) { --x: -58; --rot: -5deg; }
[dir="rtl"] .collection-fan-card:nth-child(2) { --x: 4; --rot: 6deg; }
[dir="rtl"] .collection-fan-card:nth-child(3) { --x: 62; --rot: 17deg; }
[dir="rtl"] .collection-fan-card:only-child { --x: 0; --rot: 3deg; }
[dir="rtl"] .collection-fan-card:nth-child(1):nth-last-child(2) { --x: -34; }
[dir="rtl"] .collection-fan-card:nth-child(2):last-child { --x: 34; --rot: 8deg; }

@media (min-width: 721px) {
    .collection-head:has(.collection-fan-card) {
        grid-template-columns: minmax(0, 1fr) auto;
    }

    .collection-head .collection-fan {
        --u: 0.72px;
        justify-self: end;
        margin-bottom: calc(-1 * var(--s-3));
    }
}

@media (min-width: 1100px) {
    .collection-head .collection-fan {
        --u: 1px;
    }
}

/* 06  Collection page: the numbered list, adding a recipe ------------------------ */
/* The list's head, under the dividers: how many recipes, about how many
   printed pages, and the figures' legend at its end. */
.cookbook-items-section {
    margin-top: var(--s-5);
}

.cookbook-items-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--s-1) var(--s-4);
    padding-bottom: var(--s-3);
    border-bottom: 1px solid var(--rule);
}

.cookbook-items-title {
    font-size: var(--t-l);
    line-height: 1.2;
}

.cookbook-items-meta {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: var(--t-s);
    color: var(--ink-2);
    font-variant-numeric: tabular-nums lining-nums;
}

.cookbook-items-meta .icon {
    width: 16px;
    height: 16px;
}

.cookbook-items-head .figures-legend {
    margin-inline-start: auto;
}

/* The numbered list: each recipe written on a ruled line, its number its
   place in the printed book (Besley, like the step numbers), its photo
   mounted on its category's fill (the photo mount, small), then the title,
   its category's tab and word, its status mark and the testers' figures.
   Hover picks the line out and underlines the title. */
.cookbook-items {
    list-style: none;
}

.cookbook-item {
    position: relative;
    display: grid;
    grid-template-columns: 2.5rem 136px minmax(0, 1fr) auto;
    grid-template-areas: "pos thumb body actions";
    align-items: center;
    column-gap: var(--s-5);
    padding-block: var(--s-4);
    border-bottom: 1px solid var(--rule);
    transition: background-color var(--dur) var(--ease);
}

.cookbook-item:hover {
    background: var(--paper-2);
}

.cookbook-item:has(.cookbook-item-title:focus-visible) {
    outline: var(--focus-width) solid var(--focus);
    outline-offset: 2px;
}

.cookbook-item-pos {
    grid-area: pos;
    font-family: var(--latin-serif);
    font-size: var(--t-xl);
    font-weight: 600;
    line-height: 1;
    color: var(--ink);
    text-align: end;
    font-variant-numeric: lining-nums proportional-nums;
}

.cookbook-item-thumb {
    grid-area: thumb;
    padding: 6px;
    border: 1px solid var(--c-edge, var(--card-edge));
    border-radius: var(--corner);
    background: var(--c, var(--paper-3));
}

.cookbook-item-thumb img,
.cookbook-item-thumb .no-photo {
    display: grid;
    width: 100%;
    height: auto;
    aspect-ratio: 4 / 3;
    border-radius: var(--photo-corner);
}

.cookbook-item-thumb img {
    object-fit: cover;
    border: 1px solid var(--c-edge, var(--card-edge));
    background: var(--paper-3);
}

.cookbook-item-thumb .no-photo {
    background: var(--card);
}

/* The body's one track is held to the column: an auto track grows to its
   widest unbreakable line and pushed the row past a phone's edge. */
.cookbook-item-body {
    grid-area: body;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 6px;
    min-width: 0;
}

.cookbook-item-heading {
    font-size: var(--t-l);
    line-height: 1.2;
}

[dir="ltr"] .cookbook-item-heading { text-align: left; }
[dir="rtl"] .cookbook-item-heading { text-align: right; }

.cookbook-item-title {
    color: inherit;
    text-decoration: none;
}

/* The title link covers the row; the controls sit above it. */
.cookbook-item-title::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
}

.cookbook-item-title:focus-visible {
    outline: none;
}

.cookbook-item:hover .cookbook-item-title {
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
}

.cookbook-item-meta {
    font-size: var(--t-xs);
    color: var(--ink-2);
}

/* A long category ("Accompagnements et salades", wider than a 320px
   phone's body column) wraps between its words instead of running past
   the screen. */
.cookbook-item-meta .cat {
    white-space: normal;
}

/* The record: the one status mark, then the testers' figures, on a line. */
.cookbook-item-record {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px var(--s-4);
    margin-top: 2px;
}

.cookbook-item-actions {
    grid-area: actions;
    position: relative;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: var(--s-2);
}

.cookbook-item-actions form {
    margin: 0;
}

/* Move up and down: square card-stock buttons with a control edge. */
.cookbook-move {
    display: inline-grid;
    place-items: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 1px solid var(--control);
    border-radius: var(--corner);
    background: var(--card);
    color: var(--ink);
    transition: border-color var(--dur) var(--ease);
}

.cookbook-move:hover:not(:disabled) {
    border-color: var(--ink);
}

.cookbook-move:disabled {
    opacity: 0.35;
    cursor: default;
}

.cookbook-move .icon {
    width: 18px;
    height: 18px;
}

.icon-up {
    transform: rotate(180deg);
}

.cookbook-item-remove {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 40px;
    margin-inline-start: var(--s-2);
    color: var(--ink-2);
    font-size: var(--t-s);
}

.cookbook-item-remove:hover {
    color: var(--ink);
}

.cookbook-item-remove .icon {
    width: 16px;
    height: 16px;
}

form.htmx-request .cookbook-move,
form.htmx-request .link-button {
    opacity: 0.5;
    cursor: progress;
}

/* Adding one of the cook's saved recipes: a label, the list and Add. */
.cookbook-add-form {
    display: grid;
    gap: 6px;
    width: 100%;
    max-width: 34rem;
    margin: var(--s-6) 0 0;
}

.cookbook-empty .cookbook-add-form {
    margin-top: var(--s-1);
}

.cookbook-inline {
    display: flex;
    gap: var(--s-2);
}

.cookbook-inline .select {
    flex: 1;
    min-width: 0;
}

/* 07  Notices and empty states --------------------------------------------------- */
/* A plain line with a glyph: an unavailable recipe, a full collection, the
   most collections a cook may have. */
.cookbook-note {
    display: flex;
    align-items: flex-start;
    gap: var(--s-2);
    max-width: 62ch;
    margin-block: var(--s-3) var(--s-4);
    font-size: var(--t-s);
    line-height: 1.45;
    color: var(--ink-2);
}

.cookbook-note .icon {
    flex: none;
    width: 16px;
    height: 16px;
    margin-top: 0.2em;
    color: var(--ink-3);
}

/* An empty cookbook or collection: the site's empty card (a dashed edge,
   a space still to fill), filed right behind the dividers: one line and
   one action. The cookbook's line says how to fill it, with the clip's
   glyph before it. */
.cookbook-empty {
    margin-top: var(--s-5);
}

.cookbook-empty-line {
    display: flex;
    align-items: center;
    gap: var(--s-2);
}

.cookbook-empty-line .icon {
    flex: none;
    width: 20px;
    height: 20px;
}

/* 08  Small screens ---------------------------------------------------------------- */
@media (max-width: 720px) {
    /* The recipe page's action row: each part takes a fair share of a
       line, and the collections menu opens in the flow instead of
       floating, so it never runs off the screen. */
    .clip-save-form,
    .clip-menu {
        flex: 1 1 auto;
    }

    .clip-save-form .btn,
    .clip-menu > summary {
        width: 100%;
    }

    .clip-print {
        margin-inline-start: 0;
    }

    .clip-menu[open] {
        flex-basis: 100%;
    }

    .clip-menu-pop {
        position: static;
        width: auto;
        margin-top: var(--s-2);
    }

    /* The blank divider is its glyph alone (its words are read), and its
       slip hangs from the shelf, the screen's width, rather than from
       the tab at the screen's edge. */
    .shelf-new {
        position: static;
    }

    .shelf-new-tab {
        padding-inline: 12px;
    }

    .shelf-new-word {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }

    .shelf-new-form.menu-panel {
        inset-inline: 0;
        width: auto;
    }

    .shelf-name {
        max-width: 11rem;
    }

    .collection-actions > * {
        flex: 1 1 auto;
    }

    .collection-print .btn-block,
    .collection-edit > summary {
        width: 100%;
    }

    .collection-edit[open] {
        flex-basis: 100%;
    }

    .collection-edit-panel {
        position: static;
        width: auto;
        margin-top: var(--s-2);
    }

    /* A phone keeps to the list: its rows carry the photos. */
    .collection-fan {
        display: none;
    }

    .cookbook-items-head .figures-legend {
        flex-basis: 100%;
        margin-inline-start: 0;
    }

    .cookbook-item {
        grid-template-columns: 1.5rem 96px minmax(0, 1fr);
        grid-template-areas:
            "pos thumb body"
            "pos thumb actions";
        align-items: start;
        row-gap: var(--s-2);
        column-gap: var(--s-3);
    }

    .cookbook-item-pos {
        padding-top: 4px;
        font-size: var(--t-l);
    }

    .cookbook-item-thumb {
        padding: 4px;
    }

    .cookbook-item-heading {
        font-size: 1.0625rem;
    }

    .cookbook-item-record .figures {
        gap: 2px 10px;
        font-size: 0.9375rem;
    }

    /* Remove stands apart from the arrows, at the end of their line. */
    .cookbook-item-actions > form:last-child {
        margin-inline-start: auto;
    }

    /* The print bar is one row: the count and Print (the switch on the
       title line turns print mode off). */
    .selection-cancel {
        display: none;
    }

    .selection-bar {
        gap: var(--s-3);
        padding-block: var(--s-2);
    }

    /* On a phone's narrow cards the foot's two controls share the line
       until a long language needs two. */
    .cookbook-clip-foot {
        gap: 0 var(--s-2);
        padding-bottom: 40px;
    }
}

/* 09  Touch, forced colours, print ------------------------------------------------ */
@media (pointer: coarse) {
    .clip-note-edit > summary,
    .cookbook-clip-remove .link-button,
    .cookbook-item-remove {
        min-height: 44px;
    }

    .cookbook-move {
        width: 44px;
        height: 44px;
    }
}

/* Forced colours: the drawn boxes take system edges, the collection
   menu's tick comes back as the sprite's glyph on Highlight, the dividers'
   edge is drawn in system ink and the open divider's in Highlight; the
   hand of cards keeps system edges. A picked card loses its tint; its
   native tick box says it. */
@media (forced-colors: active) {
    .clip-menu-check,
    .cookbook-move,
    .cookbook-pick::before,
    .shelf-new-tab,
    .collection-fan-card {
        border-color: ButtonText;
    }

    .clip-menu-item[aria-pressed="true"] .clip-menu-check {
        forced-color-adjust: none;
        border-color: Highlight;
        background: Highlight;
        color: HighlightText;
    }

    .clip-menu-item[aria-pressed="true"] .clip-menu-check .icon {
        display: block;
        width: 14px;
        height: 14px;
        margin: 1.5px;
    }

    .cookbook-shelf {
        background: none;
        border-bottom: 1px solid CanvasText;
    }

    .shelf-tab[aria-current="page"],
    .shelf-new[open] > .shelf-new-tab {
        border-color: Highlight;
    }

    .selection-bar {
        border-top-color: CanvasText;
    }
}

/* Printing the cookbook page itself: the cards and the notes, no controls
   and no dividers. */
@media print {
    .cookbook-shelf,
    .cookbook-tools,
    .cookbook-pick,
    .selection-bar,
    .clip-note-edit,
    .clip-note-form,
    .cookbook-clip-remove,
    .collection-actions,
    .collection-fan,
    .cookbook-item-actions,
    .cookbook-add-form {
        display: none !important;
    }

    .cookbook-clip,
    .cookbook-item {
        break-inside: avoid;
    }
}
