/* sticky-pitch-1 (R90 amends R46 e for this surface only): the book pitch card and bar
   (src/components/book/BookPitchCard.astro). Linked by the component itself, so only a page that renders the pitch
   loads it, and the switch off (src/config/book-pitch.ts) changes no page and no CSS chunk. Design E tokens only
   (check:tokens); the ticket's mockup values map to the nearest tokens. CLS 0 by design: the card sits in an absolute
   rail in the gutter beside a fixed-width text column (the column's layout never depends on this sheet), its states
   switch visibility in fixed cells, and the bar is fixed (never pushes content). No animation. Every rule that needs
   :has() sits inside @supports selector(:has(*)); an engine without it (Safari < 15.4, Chrome < 105, Firefox < 121) gets no pitch at all
   (the island returns early there, the bar stays hidden and the rail and card keep display none). */

/* The hidden attribute wins over the display of .btn, the bar and the card. */
[data-book-pitch][hidden], [data-book-pitch] [hidden] { display: none; }

/* Focus: the dismiss buttons and the print, sample and buy links take the site ring (base.css `:focus-visible`,
   --focus); nothing here sets an outline on them. After a keyboard dismiss the island focuses <main> (tabindex -1,
   removed on blur): no ring around the whole page content then, as the consent banner does for its own target. */
main[data-pitch-focus]:focus, main[data-pitch-focus]:focus-visible { outline: none; }

/* The bar's start line: a sentinel box over the first quarter of the article (placed by the island), so a jump past the
   line (deep link, anchor, restored scroll) still flips it from intersecting to not; a zero-height line at 25 % that
   goes from below the viewport to above it in one jump never reports a change. */
.book-pitch-sentinel { position: absolute; top: 0; left: 0; width: 1px; height: 25%; pointer-events: none; }
@supports selector(:has(*)) {
  :has(> .book-pitch-sentinel) { position: relative; }
}

/* ---- Card: >= 1200 px only, beside the 680 px text column, sticky inside the article wrapper (place `gutter`) ----
   The card sits in a rail placed absolutely over the right gutter of `.content` (top to bottom, with the wrapper's own
   block and right padding), and sticks inside that rail. The text column is never re-laid out: no flex or grid on
   `.content`, so a paint before this stylesheet (it is linked in the body, after the column) and the paint after it
   place the column identically (a flex item stops the first paragraph's top margin collapsing through the column, which
   moved it 17 px: e2e round 2). */
.book-pitch-rail, .book-pitch { display: none; }
@supports selector(:has(*)) {
@media (min-width: 1200px) {
  .content:has(> .book-pitch-rail) { position: relative; }
  .book-pitch-rail {
    display: block; position: absolute; top: 0; bottom: 0; right: 0; width: 300px; box-sizing: content-box;
    padding-block: inherit; padding-right: inherit; pointer-events: none;
  }
  .book-pitch {
    display: block; box-sizing: border-box; width: 300px; pointer-events: auto;
    position: sticky; top: 110px;
    padding: 20px; background: var(--c-paper-card); border: 1px solid var(--c-line); border-radius: var(--r-14);
    box-shadow: var(--sh-soft); color: var(--c-ink); font-family: var(--f-sans); font-size: var(--fs-15); line-height: 1.45;
  }

  /* pitch-more-1, place `side` (src/config/book-pitch.ts): the rail is the last flex item of the page's own side
     column (a flex column under a short note box) and fills the rest of it, so the card sticks alone, down to the end
     of the text column, at the column's width. The page releases its side column from sticking as a whole in its own
     stylesheet (`.side-col--pitch`, inside `@supports selector(:has(*))` like every rule here that needs :has(): an
     engine without it keeps the sticky column and shows no card), never here: this sheet arrives after the column was
     painted. The column is a <div> there, never an <aside>. */
  .book-pitch-rail--side { position: static; flex: 1 1 auto; width: auto; padding: 0; }
  .book-pitch-rail--side .book-pitch { width: 100%; }

  /* Place `outer` and `outer-narrow`: the page fills its frame (tables, a map, a sticky list) or is a narrow centred
     column, so the rail hangs outside the frame's right edge, in the page margin, and shows only from the width where
     that margin holds the card (below). Nothing in the frame moves. The margin is forced: a page's own
     `.content > * + *` spacing rule would otherwise push the rail's top down. */
  :has(> .book-pitch-rail--outer) { position: relative; }
  .book-pitch-rail--outer { display: none; right: auto; left: 100%; padding-right: 0; margin: 0 0 0 24px !important; }
}
/* 46rem column + 2 x 40 px padding = 816 px; (1520 - 17 scrollbar - 816) / 2 = 343 px >= 24 + 300 + 16. */
@media (min-width: 1520px) { .book-pitch-rail--outer-narrow { display: block; } }
/* 1100 px frame + 2 x 40 px padding = 1180 px; (1880 - 17 - 1180) / 2 = 341 px >= 24 + 300 + 16. */
@media (min-width: 1880px) { .book-pitch-rail--outer { display: block; } }
}
.book-pitch p { margin: 0; }
/* R103 c: the island sets this while the page's book block is in view, so the card is never seen beside the block (the
   recipe page's block sits inside its own article, below the rail's frame, where the sticky card would still show
   above it). Visibility only: no layout shift, and a dismiss (`hidden`) is never undone by it. */
.book-pitch[data-block-in-view], .book-pitch[data-block-in-view] * { visibility: hidden !important; }
/* (the descendants too: the state cells below set `visibility: visible` on their own, which beats an inherited hidden) */
/* The dismiss track is fixed (the button's margin box, 44 - 10 px), not auto: the island unhides the button after the
   first paint, and an auto track would then narrow the title column and push the card's rows down (a layout shift). */
.book-pitch__head { display: grid; grid-template-columns: 48px minmax(0, 1fr) calc(var(--tap) - 10px); gap: 12px; align-items: start; }
.book-pitch__cover { display: block; width: 48px; height: auto; box-shadow: var(--sh-polaroid); }
.book-pitch__names { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.book-pitch__kicker { font-size: var(--fs-13); font-weight: var(--fw-semibold); text-transform: uppercase; letter-spacing: .08em; color: var(--c-wine); }
.book-pitch__title { font-family: var(--f-serif); font-size: var(--fs-18); line-height: 1.2; color: var(--c-ink); }
.book-pitch__dismiss {
  display: inline-flex; align-items: center; justify-content: center; width: var(--tap); height: var(--tap);
  margin: -10px -10px 0 0; padding: 0; border: 0; border-radius: var(--r-pill); background: transparent;
  color: var(--c-slate); cursor: pointer;
}
.book-pitch__dismiss:hover { background: var(--c-paper-2); color: var(--c-ink); }
/* `.book-pitch .book-pitch__headline`, not the bare class: `.book-pitch p { margin: 0 }` above is more specific and
   ate the 16 px gap, so the full-width headline sat right under the head's title column and read as its misaligned
   continuation (STOP 2 screenshots). With the gap it opens the body column (headline, sentence, rows, button). */
.book-pitch .book-pitch__headline { margin-top: 16px; font-family: var(--f-serif); font-size: var(--fs-20); line-height: 1.25; color: var(--c-ink); }
.book-pitch .book-pitch__sentence { margin-top: 6px; color: var(--c-slate); }
.book-pitch__rows { list-style: none; margin: 16px 0 0; padding: 0; border-top: 1px solid var(--c-line); }
.book-pitch__row {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 12px; align-items: baseline;
  padding: 10px 0; border-bottom: 1px solid var(--c-line);
}
.book-pitch__label { font-weight: var(--fw-semibold); }
.book-pitch__price { font-weight: var(--fw-bold); white-space: nowrap; justify-self: end; }
/* Wider than the site's 6.5ch slot (components.css): a real bold price of 7 or 8 characters ("26,90 €", "1 290 Kč")
   would outgrow 6.5ch and move the row's right column when it fills in; 9ch holds it in place. */
.book-pitch .live-price { min-inline-size: 9ch; text-align: end; }
.book-pitch__detail { grid-column: 1; font-size: var(--fs-14); color: var(--c-slate); }
.book-pitch__print-link { grid-column: 2; justify-self: end; font-size: var(--fs-14); }
.book-pitch__print-link a { display: inline-block; padding: 4px 0; color: var(--c-wine); font-weight: var(--fw-semibold); white-space: nowrap; }
/* border-box: the site has no global box-sizing reset, so width 100 % plus the .btn--sm side padding (2 x 18 px) ran
   36 px past the card's content box and over its border (STOP 2 screenshots). A long label wraps inside the box. */
.book-pitch__cta { box-sizing: border-box; width: 100%; max-width: 100%; margin-top: 16px; white-space: normal; padding-block: 8px; }
.book-pitch__sample { display: flex; align-items: center; justify-content: center; min-height: var(--tap); margin-top: 4px; font-size: var(--fs-14); color: var(--c-wine); }

/* States (the island sets data-stock and data-ebook): a line and its alternate share one cell, visibility only. */
.book-pitch__slot { display: grid; }
.book-pitch__slot > * { grid-area: 1 / 1; }
.book-pitch__slot > [data-when] { visibility: hidden; }
[data-stock="unknown"] .book-pitch__slot > [data-when~="unknown"],
[data-stock="in-stock"] .book-pitch__slot > [data-when~="in-stock"],
[data-stock="sold-out"] .book-pitch__slot > [data-when~="sold-out"] { visibility: visible; }
[data-ebook="off"] [data-pitch-eb-action] { visibility: hidden; }

/* ---- Bar: below the page's card width (R103 a), fixed at the bottom, shown by the island; the cookie banner wins ---- */
.book-pitch-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 45;
  display: flex; align-items: center; gap: 12px; box-sizing: border-box; min-height: 76px;
  padding: 10px max(12px, env(safe-area-inset-right)) calc(10px + env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left));
  background: var(--c-paper-card); border-top: 1px solid var(--c-line); box-shadow: var(--sh-soft);
  color: var(--c-ink); font-family: var(--f-sans);
}
/* R103 a: the bar yields at exactly the width where this page's card starts (`data-card-from`, written from
   PITCH_CARD_FROM in src/config/book-pitch.ts; one rule per value, a unit test keeps both lists equal), so a page never
   has a width with neither. A bar-only page (the guide hub) carries 1200: the R90 behaviour, bar below 1200 px and nothing above. */
@media (min-width: 1200px) { .book-pitch-bar[data-card-from="1200"] { display: none; } }
@media (min-width: 1520px) { .book-pitch-bar[data-card-from="1520"] { display: none; } }
@media (min-width: 1880px) { .book-pitch-bar[data-card-from="1880"] { display: none; } }
@supports selector(:has(*)) {
  html:has(#pv-consent:not([hidden])) .book-pitch-bar { display: none; }
  /* The open mobile menu (SiteHeader's <details class="menu">, z-index 40) is never painted over either. */
  html:has(.site-top details.menu[open]) .book-pitch-bar { display: none; }
  /* WCAG 2.2 2.4.11: a focused element is scrolled clear of the bar while it shows. */
  html:has(.book-pitch-bar:not([hidden])) { scroll-padding-bottom: calc(76px + env(safe-area-inset-bottom)); }
}
.book-pitch-bar p { margin: 0; }
.book-pitch-bar__cover { flex: 0 0 auto; display: block; width: 40px; height: 56px; object-fit: contain; }
.book-pitch-bar__text { flex: 1 1 auto; min-width: 0; }
.book-pitch-bar__title { font-family: var(--f-serif); font-size: var(--fs-15); line-height: 1.25; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Clipped with an ellipsis like the title: a long label plus the price never runs under the Buy button (round 4). */
.book-pitch-bar__line { font-size: var(--fs-14); color: var(--c-slate); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.book-pitch-bar__price:not([data-state="ok"]) { visibility: hidden; }
.book-pitch-bar__buy { flex: 0 0 auto; }
.book-pitch-bar .book-pitch__dismiss { flex: 0 0 auto; margin: 0; }

@media print { [data-book-pitch] { display: none; } }
