/* The card reel, shared by /batfi and /vetero (reel.py, reel.js): how it
   works, never how it looks. Each page sets its look in its own stylesheet,
   linked after this one:

     --mp-reel-card   a card's width (required)
     --mp-reel-gap    the space between cards (20px)
     --mp-reel-fade   the width of the right edge's fade (120px)

   all three on the frame (.mp-reel-frame, the page's own class beside it),
   so the fade's box sees them too; and the cards, the buttons' size,
   colours and focus rings, and the space round the reel. The page's section round it clips sideways overflow, since
   the reel is a window wide.

   No snapping. Snap resolves percentages against the scrollport while padding
   resolves them against the containing block, so the same max(20px, 50vw -
   50%) was 232px of padding and 20px of scroll padding on /batfi, and the reel
   came to rest 212px past its own left edge. The reference (raycast.com) does
   not snap either. */

/* The frame is the text column's width, and a container, so the reel inside
   it can still find the column's left edge (50cqw is half the column) from
   inside the full-bleed box. */
.mp-reel-frame {
  container-type: inline-size;
}

/* The full-bleed box the edges fade in. It does not scroll. The fade used to
   be a mask on .mp-reel, the scroller, and on an iPhone Safari drew that
   scroller blank, every card gone and only the buttons under it left
   (/batfi, 2026-10-04): a mask on an overflow scroller is the case iOS
   composites differently, while Chrome and desktop WebKit both drew it fine.
   So the mask never goes on the scroller; this box is the same full-bleed
   box it was, so nothing on a desktop moved.

   The reel is not cut off at the window, it dissolves into it: a hard
   vertical edge through a card reads as broken rather than as "there is
   more this way". The left ramp is 20px, the narrowest the start padding
   ever is, so at rest it lies over empty space. (It was written as the
   padding, but a percentage inside a gradient is a share of the gradient
   line, the window here, so it always came to 20px.) The right one is
   --mp-reel-end wide: the whole fade while there is more to scroll to,
   none at the end, where it would only fade the last card. */
.mp-reel-mask {
  /* full bleed both ways; bleeding left too is what lets the mask fade that
     edge once the reel is scrolled without touching it at rest */
  margin-inline: calc(50% - 50vw);
  --mp-reel-end: var(--mp-reel-fade, 120px);
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 20px,
      #000 calc(100% - var(--mp-reel-end)), transparent 100%);
  mask-image: linear-gradient(to right, transparent 0, #000 20px,
      #000 calc(100% - var(--mp-reel-end)), transparent 100%);
  /* the reel's scroll, which draws the fade's end below, named so this box,
     its parent, can follow it */
  timeline-scope: --mp-reel;
}

.mp-reel {
  /* the start padding puts the first card back on the text's left edge:
     half of what the window has beyond the column (the frame), never under
     20px */
  --mp-reel-pad: max(20px, calc(50vw - 50cqw));
  display: flex;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  /* the start only: Safari leaves a scroller's end padding out of what it
     scrolls to, so the space after the last card is the list's (below) */
  padding-inline: var(--mp-reel-pad) 0;
  scroll-timeline: --mp-reel inline;
  scrollbar-width: none;
}

.mp-reel::-webkit-scrollbar {
  display: none;
}

/* The right fade goes at the end of the reel and comes back on scrolling
   back. Where the browser has scroll-driven animations and lets the fade's
   box follow the scroller inside it (timeline-scope), the reel's own scroll
   draws it, with no script: over the last stretch of scroll the fade narrows
   with what is left to come, and at the end it is gone. Elsewhere reel.js
   marks the fade's box (.mp-reel-mask--js) and marks it again at the end,
   and the fade goes in a quick change (none under reduced motion). With
   neither, the fade stays, as it always was.

   Safari 26 parses timeline-scope but does not follow it: the animation is
   left with no timeline at all (checked in WebKit 26.6). So the animation
   has a duration, not auto: a timeline that never comes then holds it at its
   start, the whole fade, instead of finishing it at once to none, and
   reel.js, which finds no timeline on it, takes the animation off and works
   the end by hand. Chrome stretches a duration over the scroll range all the
   same. */
@property --mp-reel-end {
  syntax: '<length>';
  inherits: false;
  initial-value: 0px;
}

@keyframes mp-reel-end {
  from { --mp-reel-end: var(--mp-reel-fade, 120px); }
  to { --mp-reel-end: 0px; }
}

@supports (animation-timeline: scroll()) and (timeline-scope: --mp-reel) {
  .mp-reel-mask:not(.mp-reel-mask--js) {
    animation: mp-reel-end 1s linear both;
    animation-timeline: --mp-reel;
    animation-range: calc(100% - var(--mp-reel-fade, 120px)) 100%;
  }
}

.mp-reel-mask.mp-reel-mask--js {
  transition: --mp-reel-end 0.15s ease-out;
}

.mp-reel-mask.mp-reel-mask--js.mp-reel--end {
  --mp-reel-end: 0px;
}

@media (prefers-reduced-motion: reduce) {
  .mp-reel-mask.mp-reel-mask--js {
    transition: none;
  }
}

.mp-reel > ul.mp-reel-cards {
  flex: none;
  display: flex;
  gap: var(--mp-reel-gap, 20px);
  list-style: none;
  margin: 0;
  /* At the end the last card stands off the window's right edge by the
     reel's start padding, as the first card stands off its left at the
     start. The 100% is the reel's content box, the window less that start
     padding, so the difference is exactly it. */
  padding: 0 calc(100vw - 100%) 0 0;
}

.mp-reel > ul.mp-reel-cards > li {
  /* the width too, not only the basis: Safari sizes the list from its cards'
     widths, and with the basis alone they ran out past its end */
  flex: none;
  width: var(--mp-reel-card);
  margin: 0;
}

/* The buttons, under the reel's right-hand end: `hidden` until reel.js shows
   them, since without it they could scroll nothing, and hidden again where
   there is nothing to scroll. The page draws them. */
.mp-reel-nav {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

.mp-reel-nav[hidden] {
  display: none;
}

.mp-reel-nav > button {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  padding: 0;
  cursor: pointer;
}

.mp-reel-nav > button > svg {
  display: block;
  width: 16px;
  height: 16px;
}

.mp-reel-nav > button:active:not(:disabled) {
  transform: translateY(1px);
}

.mp-reel-nav > button:disabled {
  cursor: default;
}

@media (prefers-reduced-motion: reduce) {
  .mp-reel-nav > button.mp-reel-prev,
  .mp-reel-nav > button.mp-reel-next {
    transition: none;
  }
}
