:root {



    --turn-time: 520ms;
    --turn-ease: cubic-bezier(0.65, 0, 0.35, 1);
    --press-ease: cubic-bezier(0.23, 1, 0.32, 1);

    /* Entering and settling. The first is the curve iOS sheets use - a long
       decelerating tail that reads as a thing coming to rest rather than a
       thing stopping. Leaving is deliberately quicker than arriving: a
       dismissal that takes as long as an entrance feels like an argument. */
    --settle-ease: cubic-bezier(0.16, 1, 0.3, 1);
    --enter-time: 340ms;
    --leave-time: 200ms;

    /* The floating controls' footprint, in one place. The row positions
       itself from these and every page reserves its bottom margin from the
       same numbers, so a button cannot grow without the paper under it
       growing too. */
    --dock-inset: max(18px, env(safe-area-inset-bottom));
    --dock-arrow: 58px;
    --dock-clearance: calc(var(--dock-arrow) + var(--dock-inset) + 16px);

    /* Elevation for anything floating over the paper, at one value, so a
       button and a capsule never sit at two different heights. */
    --dock-shadow:
        0 10px 30px -12px rgba(0, 0, 0, 0.5),
        0 2px 8px rgba(0, 0, 0, 0.16);

    /* Pressed and hovered, expressed in the control's own foreground rather
       than in white - the same rule has to read on The Club's light controls
       over black paper as on LOV's dark ones over cream. */
    --control-press: rgba(255, 255, 255, 0.13);
    --control-press: color-mix(in srgb, var(--control-ink, #ffffff) 15%, transparent);
}

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

html,
body {
    width: 100%;
    min-height: 100%;
    margin: 0;
    overflow: hidden;
    background: var(--chrome, #0a0a0a);
}

body {
    font-family: Arial, Helvetica, sans-serif;
}

button {
    font: inherit;
}

.visually-hidden,
.skip-link {
    position: fixed;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
}

.skip-link:focus {
    z-index: 100;
    inset: 12px auto auto 12px;
    width: auto;
    height: auto;
    padding: 10px 14px;
    overflow: visible;
    clip: auto;
    clip-path: none;
    background: var(--paper);
    color: var(--chrome, #0a0a0a);
}

.menu-reader,
.book-stage {
    width: 100%;
    height: 100svh;
}

/* Single page at a time, always - clients are mostly mobile, so the
   full-bleed single-column reading mode is the only mode, not just a
   narrow-viewport fallback. */
.book-stage {
    position: relative;
    display: grid;
    place-items: center;
    padding: 0;
    overflow: hidden;
    background: var(--paper);
    perspective: 2600px;
    perspective-origin: center center;
    touch-action: none;
    user-select: none;
    -webkit-user-select: none;
}

.book-frame {
    width: 100%;
    height: 100%;
    display: grid;
    place-items: center;
}

.book {
    position: relative;
    width: 100vw;
    height: 100svh;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    transform-origin: center;
    transform-style: preserve-3d;
    -webkit-transform-style: preserve-3d;
}

.book.is-zoomed {
    cursor: grab;
}

.book.is-resetting {
    transition: transform 380ms cubic-bezier(0.16, 1, 0.3, 1);
}

.book-page {
    position: relative;
    grid-column: 1;
    min-width: 0;
    min-height: 0;
    overflow: hidden;
    background: var(--paper);
}

.book-page-viewport,
.turn-face-viewport {
    /* Full height, on purpose - the .page-arrow buttons float on top
       of the page content (same as they always have over the old
       image pages), not pushed to their own reserved strip below it. */
    width: 100%;
    height: 100%;
    overflow-y: auto;
    overflow-x: hidden;
    overscroll-behavior-y: contain;
    touch-action: pan-y;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
}

/* The buttons still float over content (not a reserved strip - see above),
   but a page's own trailing content shouldn't end up directly under them:
   pad out its last few lines with its own cream background, the same height
   as the controls' footprint. Every control now lives in that one bottom
   row, so nothing has to be reserved at the top of the page.

   Scoped to a .page inside this shell specifically - the standalone page
   files have no floating buttons and are never affected. Both viewports are
   listed: a turning face has to be padded identically to the settled page,
   or its content visibly shifts as the sheet lands. */
.book-page-viewport > .page,
.turn-face-viewport > .page {
    padding-bottom: var(--dock-clearance);
}

.book-page-viewport::-webkit-scrollbar,
.turn-face-viewport::-webkit-scrollbar {
    display: none;
    width: 0;
    height: 0;
}

.book-page-viewport img.is-cover-page,
.turn-face-viewport img.is-cover-page {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
    -webkit-user-drag: none;
}

.page-load-error {
    margin: 20% 24px 0;
    padding: 16px;
    color: var(--ink, #111111);
    text-align: center;
    font-family: Arial, Helvetica, sans-serif;
    font-size: 0.95rem;
    line-height: 1.4;
}

/* FOOD/DRINKS covers: always full-bleed, top-aligned, crop the bottom. */
.book-page img.is-cover-page,
.turn-face img.is-cover-page {
    object-fit: cover;
    object-position: top center;
}

/* Where the guest is in the whole menu, and the only chrome that never
   leaves. Two pixels at the very top: too thin to obscure a line of type, on
   an edge no thumb rests on and no home indicator claims, and it answers
   "how much of this is left" without spending a word on it. It is what makes
   the controls below free to get out of the way. */
.reading-progress {
    position: fixed;
    z-index: 31;
    top: 0;
    left: 0;
    right: 0;
    height: 2px;
    overflow: hidden;
    background: rgba(0, 0, 0, 0.08);
    background: color-mix(in srgb, var(--ink, #111111) 12%, transparent);
    pointer-events: none;
}

.reading-progress-fill {
    display: block;
    width: 100%;
    height: 100%;
    background: var(--accent, #c71624);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 420ms var(--settle-ease);
}

/* One row holding all five controls: turn back, switch halves of the menu,
   the guest's list, share it, turn on. A flex row rather than five separately
   positioned buttons, so the spacing stays even from a 320px phone upwards
   instead of needing a hand-picked offset per button that collides at the
   narrow end. The bar itself is not a target - only the buttons in it are. */
.reader-controls {
    position: fixed;
    z-index: 30;
    left: 0;
    right: 0;
    bottom: var(--dock-inset);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 0 16px;
    pointer-events: none;
    transition:
        transform 280ms var(--settle-ease),
        opacity 180ms ease;
}

/* Out of the way while the guest is reading forward - see menu-chrome.js for
   when. Translated clear of the screen rather than only faded, so a thumb
   travelling down the page cannot press a button it can no longer see.
   Nothing here removes the controls from the tab order or the accessibility
   tree: this is a state of the paper, not of the page, and focus brings the
   row straight back. */
.reader-controls.is-withdrawn {
    opacity: 0;
    transform: translateY(calc(100% + var(--dock-inset)));
}

/* Paper, fading upward, belonging to the row rather than to the page. Without
   it a line of menu text slides out from under a black circle with nothing in
   between, which is what made the controls read as dropped onto the menu
   rather than as part of the reader. Because it withdraws with them, the
   whole page is clear the moment they leave. */
.reader-controls::before {
    content: '';
    position: absolute;
    z-index: -1;
    inset: -44px 0 calc(-1 * var(--dock-inset) - 4px);
    pointer-events: none;
    background: linear-gradient(to top, var(--paper) 34%, transparent);
    background: linear-gradient(
        to top,
        var(--paper) 30%,
        color-mix(in srgb, var(--paper) 60%, transparent) 68%,
        color-mix(in srgb, var(--paper) 0%, transparent) 100%
    );
}

.reader-controls > button,
.control-cluster {
    pointer-events: auto;
}

/* The three occasional controls as one object rather than three loose
   circles. Same surface as the arrows either side, so the row still reads as
   one set of controls - what the capsule adds is that switching halves,
   opening the list and sharing it are visibly the same kind of thing, and
   turning the page is not. Nav at the corners where a thumb already rests,
   tools in the middle. */
.control-cluster {
    display: flex;
    align-items: center;
    gap: 2px;
    padding: 4px;
    border: 1px solid var(--control-border, rgba(255, 255, 255, 0.24));
    border-radius: 999px;
    background: var(--control-bg, rgba(10, 10, 10, 0.84));
    box-shadow: var(--dock-shadow);
    -webkit-backdrop-filter: blur(16px) saturate(160%);
    backdrop-filter: blur(16px) saturate(160%);
}

.section-jump,
.share-button,
.cart-button {
    height: 44px;
    min-width: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    padding: 0;
    border: 0;
    border-radius: 999px;
    background: none;
    color: var(--control-ink, #fff);
    cursor: pointer;
    line-height: 1;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    transition:
        background-color 160ms ease,
        transform 160ms var(--press-ease);
}

.control-icon {
    width: 23px;
    height: 23px;
    display: block;
    flex: none;
}

.control-icon[hidden] {
    display: none;
}

/* The section jump is the one filled glyph in the row - the cart and the QR
   beside it are drawn at a 1.8 stroke. Solid ink reads heavier than outline
   at the same box, so it is set down a little to sit at the same weight; the
   button's own 44px target is untouched. */
.section-jump .control-icon {
    width: 21px;
    height: 21px;
}

.section-jump:focus-visible,
.share-button:focus-visible,
.cart-button:focus-visible {
    outline: 2px solid var(--control-ink, #fff);
    outline-offset: -2px;
}

.section-jump:active,
.share-button:active,
.cart-button:active {
    background: var(--control-press);
    transform: scale(0.94);
}

@media (hover: hover) and (pointer: fine) {
    .section-jump:hover,
    .share-button:hover,
    .cart-button:hover {
        background: var(--control-press);
    }
}

.turn-layer {
    position: absolute;
    z-index: 12;
    inset: 0;
    pointer-events: none;
    transform-style: preserve-3d;
    -webkit-transform-style: preserve-3d;
}

.turn-sheet {
    position: absolute;
    top: 0;
    width: 100%;
    height: 100%;
    transform-style: preserve-3d;
    -webkit-transform-style: preserve-3d;
}

.turn-sheet--next {
    right: 0;
    transform-origin: left center;
    animation: turn-next var(--turn-time) var(--turn-ease) forwards;
}

.turn-sheet--previous {
    left: 0;
    transform-origin: right center;
    animation: turn-previous var(--turn-time) var(--turn-ease) forwards;
}

.turn-sheet.is-interactive {
    animation: none;
    will-change: transform;
}

.turn-sheet.is-settling {
    animation: none;
    transition: transform 280ms cubic-bezier(0.32, 0.72, 0, 1);
}

.turn-face {
    position: absolute;
    inset: 0;
    overflow: clip;
    background: var(--paper);
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
}

.turn-face--front {
    transform: translateZ(0.1px);
}

.turn-face--back {
    transform: rotateY(180deg) translateZ(0.1px);
}

@keyframes turn-next {
    to { transform: rotateY(-180deg); }
}

@keyframes turn-previous {
    to { transform: rotateY(180deg); }
}

/* The two page arrows: the only controls a guest touches on every page, so
   they get the corners, the larger target and a surface of their own. */
.page-arrow {
    width: var(--dock-arrow);
    height: var(--dock-arrow);
    display: grid;
    place-items: center;
    padding: 0;
    border: 1px solid var(--control-border, rgba(255, 255, 255, 0.28));
    border-radius: 50%;
    background: var(--control-bg, rgba(10, 10, 10, 0.84));
    box-shadow: var(--dock-shadow);
    color: var(--control-ink, #fff);
    cursor: pointer;
    font-size: 1.55rem;
    line-height: 1;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    -webkit-backdrop-filter: blur(16px) saturate(160%);
    backdrop-filter: blur(16px) saturate(160%);
    transition:
        opacity 160ms ease,
        background-color 160ms ease,
        box-shadow 160ms ease,
        transform 160ms var(--press-ease);
}

.page-arrow:focus-visible {
    outline: 2px solid var(--control-ink, #fff);
    outline-offset: 2px;
}

/* Pressing shrinks the button and pulls its shadow in with it, so it reads as
   going down into the paper rather than as merely getting smaller. */
.page-arrow:active:not(:disabled) {
    box-shadow: 0 3px 10px -6px rgba(0, 0, 0, 0.5);
    transform: scale(0.93);
}

@media (hover: hover) and (pointer: fine) {
    .page-arrow:hover:not(:disabled) {
        background: var(--control-bg, rgba(10, 10, 10, 0.84));
        border-color: var(--control-ink, #fff);
    }
}

/* Faint, but still legibly a button: an arrow this end of the menu cannot go
   anywhere, and a control that vanishes entirely reads as one that broke. */
.page-arrow:disabled {
    box-shadow: none;
    cursor: default;
    opacity: 0.32;
}

/* The list is the one control in the capsule whose state matters, so it is
   the only one that changes what it shows. Empty, it is its icon - a button
   like its neighbours, saying what it opens. The moment something is in it,
   the count takes the icon's place: how many dishes are on the list is the
   only thing that button has to say once there are any, and an icon beside
   the number is a second reading of a control that now needs one. */
.cart-button:not([data-count="0"]) .control-icon {
    display: none;
}

.cart-count {
    min-width: 26px;
    height: 26px;
    padding: 0 7px;
    display: grid;
    place-items: center;
    border-radius: 999px;
    background: var(--accent, #c71624);
    color: var(--paper, #fbf7ea);
    font-family: var(--font-body, Arial, Helvetica, sans-serif);
    font-size: 0.83rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    line-height: 1;
}

.cart-button[data-count="0"] .cart-count {
    display: none;
}

/* Over the reader, not beside it. The sheet is the guest's list on the same
   cream paper the menu is printed on, so opening the cart reads as turning
   to a page of their own rather than as leaving the menu.

   The backdrop blurs as well as darkens: it is what says the menu behind is
   still there and still where you left it, and that this is a thing to
   dismiss rather than a place you have gone. */
.cart-panel {
    position: fixed;
    z-index: 40;
    inset: 0;
    display: grid;
    align-items: end;
    background: rgba(10, 10, 10, 0.5);
    -webkit-backdrop-filter: blur(5px);
    backdrop-filter: blur(5px);
    animation: scrim-in var(--enter-time) ease both;
}

.cart-panel[hidden] {
    display: none;
}

.cart-panel.is-closing {
    animation: scrim-out var(--leave-time) ease both;
}

/* Rises from the edge it is anchored to, which is the whole of what a sheet
   has to say about where it came from. */
.cart-sheet {
    display: flex;
    flex-direction: column;
    max-height: 86svh;
    padding: 0 20px max(20px, env(safe-area-inset-bottom));
    border-radius: 22px 22px 0 0;
    background: var(--paper);
    box-shadow: 0 -20px 60px -24px rgba(0, 0, 0, 0.55);
    color: var(--ink, #111111);
    font-family: var(--font-body, "IBM Plex Sans", Arial, Helvetica, sans-serif);
    animation: sheet-in var(--enter-time) var(--settle-ease) both;
}

.cart-panel.is-closing .cart-sheet {
    animation: sheet-out var(--leave-time) ease-in both;
}

@keyframes scrim-in {
    from { opacity: 0; }
}

@keyframes scrim-out {
    to { opacity: 0; }
}

@keyframes sheet-in {
    from { transform: translateY(100%); }
}

@keyframes sheet-out {
    to { transform: translateY(100%); }
}

/* The grip every phone user already reads as "this pulls down". It is an
   affordance, not a control: the close button beside the title and a tap on
   the backdrop are the two that actually work, and both are reachable
   without a gesture. */
.sheet-grabber {
    width: 38px;
    height: 4px;
    margin: 10px auto 0;
    display: block;
    border-radius: 999px;
    background: rgba(17, 17, 17, 0.2);
    background: color-mix(in srgb, var(--ink, #111111) 22%, transparent);
}

/* Sticky so the title and the way out stay put while a long list scrolls
   under them. */
.cart-head {
    position: sticky;
    top: 0;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 0 12px;
    background: var(--paper);
}

.cart-head h2 {
    margin: 0;
    color: var(--accent, #c71624);
    font-family: "Cinzel", Georgia, serif;
    font-size: 15.9pt;
    font-weight: 700;
    line-height: 1;
    text-transform: uppercase;
    letter-spacing: -0.23pt;
}

/* A real target rather than a small underlined word. Pulled into the sheet's
   own padding so the glyph still lines up with the right-hand margin the
   prices below it are set to. */
.sheet-close {
    flex: none;
    width: 44px;
    height: 44px;
    margin-right: -10px;
    display: grid;
    place-items: center;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: none;
    color: var(--ink-muted, #5a5a5a);
    cursor: pointer;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    transition:
        background-color 160ms ease,
        color 160ms ease,
        transform 160ms var(--press-ease);
}

.sheet-close:focus-visible {
    outline: 2px solid var(--accent, #c71624);
    outline-offset: -2px;
}

.sheet-close:active {
    background: rgba(17, 17, 17, 0.08);
    background: color-mix(in srgb, var(--ink, #111111) 9%, transparent);
    color: var(--ink, #111111);
    transform: scale(0.92);
}

@media (hover: hover) and (pointer: fine) {
    .sheet-close:hover {
        background: rgba(17, 17, 17, 0.06);
        background: color-mix(in srgb, var(--ink, #111111) 7%, transparent);
        color: var(--ink, #111111);
    }
}

/* Emptying the list is the one destructive thing in here, so it is outlined
   in the warning colour and stands alone under the list rather than sitting
   beside anything it could be mistaken for. */
.cart-clear {
    min-height: 44px;
    padding: 0 18px;
    border: 1px solid rgba(199, 22, 36, 0.4);
    border: 1px solid color-mix(in srgb, var(--accent, #c71624) 42%, transparent);
    border-radius: 999px;
    background: none;
    color: var(--accent, #c71624);
    font: inherit;
    font-size: 0.9rem;
    cursor: pointer;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    transition: background-color 160ms ease;
}

.cart-clear:focus-visible {
    outline: 2px solid var(--accent, #c71624);
    outline-offset: 2px;
}

.cart-clear:active {
    background: rgba(199, 22, 36, 0.1);
    background: color-mix(in srgb, var(--accent, #c71624) 12%, transparent);
}

@media (hover: hover) and (pointer: fine) {
    .cart-clear:hover {
        background: rgba(199, 22, 36, 0.07);
        background: color-mix(in srgb, var(--accent, #c71624) 8%, transparent);
    }
}

.cart-body {
    overflow-y: auto;
    overscroll-behavior: contain;
}

.cart-group + .cart-group {
    margin-top: 7mm;
}

/* Matches .country-heading on the world-wines page: the small left-aligned
   red label that already means "everything below this belongs together". */
.cart-category {
    margin: 0 0 2mm;
}

/* The heading is the way to the page it names, so it is a button - but a
   button that still looks like the label it was. Nothing here draws a
   control: the only thing that says it can be pressed is that it answers to
   being pressed, which is enough for a word that is already the name of
   somewhere you can go. */
.cart-category-button {
    display: inline-block;
    padding: 2px 0;
    border: 0;
    background: none;
    color: var(--accent, #c71624);
    font-family: "Cinzel", Georgia, serif;
    font-size: 0.72rem;
    font-weight: 700;
    line-height: 1;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    text-align: left;
    cursor: pointer;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    transition: opacity 160ms ease;
}

.cart-category-button:focus-visible {
    outline: 2px solid var(--accent, #c71624);
    outline-offset: 3px;
    border-radius: 3px;
}

.cart-category-button:active {
    opacity: 0.55;
}

@media (hover: hover) and (pointer: fine) {
    .cart-category-button:hover {
        text-decoration: underline;
        text-underline-offset: 3px;
    }
}

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

/* The row is two targets, and the split is deliberately lopsided. The name
   fills everything the cross does not, because going to the dish is the
   ordinary act and should be almost impossible to miss; the cross gets a
   fixed 44px at the end, because removing is the act you should have to
   mean. Nothing about the row is destructive by default any more. */
.cart-item {
    display: flex;
    align-items: center;
    gap: 4px;
}

.cart-item-button {
    flex: 1;
    min-width: 0;
    min-height: 44px;
    display: flex;
    align-items: center;
    padding: 6px 0;
    border: 0;
    border-radius: 8px;
    background: none;
    color: inherit;
    font: inherit;
    font-size: 16px;
    line-height: 1.31;
    text-align: left;
    cursor: pointer;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    transition: color 160ms ease, opacity 160ms ease;
}

.cart-item-button:focus-visible {
    outline: 2px solid var(--accent, #c71624);
    outline-offset: 2px;
}

/* Going somewhere, not losing something: the name dims under the finger the
   way a link does, and the red is left to the cross, which is the only thing
   on this row that still takes anything away. */
.cart-item-button:active {
    opacity: 0.55;
}

@media (hover: hover) and (pointer: fine) {
    .cart-item-button:hover .cart-item-name {
        text-decoration: underline;
        text-underline-offset: 3px;
    }
}

.cart-item-remove {
    flex: none;
    width: 44px;
    min-height: 44px;
    display: grid;
    place-items: center;
    padding: 0;
    border: 0;
    border-radius: 8px;
    background: none;
    color: var(--ink-muted, #5a5a5a);
    font: inherit;
    font-size: 1.25rem;
    line-height: 1;
    cursor: pointer;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    transition: color 160ms ease, background-color 160ms ease;
}

.cart-item-remove:focus-visible {
    outline: 2px solid var(--accent, #c71624);
    outline-offset: -2px;
}

.cart-item-remove:active {
    background: rgba(199, 22, 36, 0.09);
    background: color-mix(in srgb, var(--accent, #c71624) 10%, transparent);
    color: var(--accent, #c71624);
}

@media (hover: hover) and (pointer: fine) {
    .cart-item-remove:hover {
        color: var(--accent, #c71624);
    }
}

.cart-empty {
    margin: 0;
    padding: 10px 0 18px;
    color: var(--ink-muted, #5a5a5a);
    font-size: 15px;
    line-height: 1.4;
}

.cart-foot {
    padding-top: 16px;
    text-align: center;
}

/* The QR is drawn as an SVG of unit squares scaled to fit, so it stays crisp
   at any size and at any pixel density - the thing a camera has to resolve
   across a dim table. White quiet zone included in the box, because scanners
   need it and the sheet behind it is cream, not white. */
.share-body {
    padding: 4px 0 22px;
    text-align: center;
}

.share-code {
    width: min(62vw, 260px);
    height: auto;
    margin: 0 auto;
    display: block;
    border-radius: 6px;
    background: #fff;
    image-rendering: pixelated;
}

.share-note {
    margin: 14px 0 0;
    color: var(--ink-muted, #5a5a5a);
    font-size: 15px;
    line-height: 1.4;
}

.share-link {
    margin: 12px 0 0;
    padding: 8px 10px;
    border-radius: 6px;
    background: rgba(17, 17, 17, 0.05);
    color: var(--ink-muted, #5a5a5a);
    font-size: 12px;
    line-height: 1.35;
    word-break: break-all;
}

.pdf-fallback {
    position: fixed;
    inset: 50% auto auto 50%;
    padding: 14px 18px;
    background: #fff;
    color: #000;
    transform: translate(-50%, -50%);
}

@media (min-width: 761px) {
    .book-page img.is-cover-page,
    .turn-face img.is-cover-page {
        height: calc(100% - 72px);
        object-position: top center;
    }
}

@media (max-width: 950px) and (orientation: landscape),
       (max-height: 600px) and (orientation: landscape) and (pointer: coarse) {
    .book-stage {
        display: block;
        overflow-x: hidden;
        overflow-y: auto;
        scrollbar-width: none;
        touch-action: pan-y;
        overscroll-behavior-y: contain;
        -webkit-overflow-scrolling: touch;
    }

    .book-stage::-webkit-scrollbar {
        display: none;
        width: 0;
        height: 0;
    }

    .book-frame {
        display: block;
        height: auto;
    }

    .book {
        width: 100vw;
        height: calc(100vw * 1.4153226);
        min-height: calc(100vw * 1.4153226);
    }
}

/* Everything still happens - the controls still withdraw, the sheets still
   open - it just stops moving to say so. Withdrawing is not decoration: it is
   what keeps the menu readable, so it survives here where the page turn and
   the slide do not. */
@media (prefers-reduced-motion: reduce) {
    :root {
        --turn-time: 1ms;
        --enter-time: 1ms;
        --leave-time: 1ms;
    }

    .reader-controls,
    .reading-progress-fill,
    .page-arrow,
    .cart-button,
    .section-jump,
    .share-button,
    .sheet-close,
    .cart-item-button,
    .cart-item-remove,
    .cart-category-button {
        transition: none;
    }

    .page-arrow:active:not(:disabled),
    .section-jump:active,
    .share-button:active,
    .cart-button:active,
    .sheet-close:active {
        transform: none;
    }
}

@media (prefers-contrast: more) {
    .page-arrow,
    .control-cluster {
        border-color: var(--control-ink, #fff);
        background: #000;
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
    }

    /* The veil is a soft edge by design, and a soft edge is the thing this
       setting is asking for less of. */
    .reader-controls::before {
        background: none;
    }
}
