/* ═══════════════════════════════════════════════════════════════
   CALENDAR CARDS AND CAROUSEL — the inside of #cmp-cards.
   Markup is built by campaign/main.js; the page around it (title, art,
   where #cmp-cards sits) is campaign/main.css.

   Geometry is Figma's own numbers times --k, the card's scale against the
   275x400 desktop card (21:669): 1 on desktop, 0.8 on a phone (21:712,
   220x320). Font sizes are separate px values per breakpoint, so text stays
   real px and browser zoom works.

   Motion (built with the `animate` skill, template rules quoted):
     * the slide is not a CSS transition: main.js § motion moves one number
       per card, --q, under the finger 1:1 and then with a spring that starts
       from the current pose and speed, so nothing restarts or jumps; the
       stacking order comes from the same number
     * the flip: one curve, --ease-out; entry slower than exit -- 420ms to
       the back, 300ms back -- and each face's opacity switches when the
       card is edge-on, so iOS never shows a face's children mirrored
     * transform and opacity only
     * no filter or box-shadow on a node that rotates in 3D: the shadow is a
       filter on the flat <svg> inside a face, never on a face or __inner
     * prefers-reduced-motion degrades: the drag still follows the finger
       (direct manipulation, not decoration), the snap is an instant move, the
       flip a 200ms crossfade, press feedback stays
   ═══════════════════════════════════════════════════════════════ */

/* ══ card palette ══════════════════════════════════════════════
   DEVIATION (owner, 2026-10-17; docs/BRIEF.md): the Halloween card colours
   are not in css/tokens.css. Defined once, here; nothing below names a hex. */
:root {
  --cmp-card-today:   #006aff;   /* 21:670 card fill, Open */
  --cmp-card-past:    #303845;   /* 21:685 card fill, Expired */
  --cmp-card-soon:    #1e3060;   /* 21:700 card fill, Opens tomorrow */
  --cmp-card-shade:   #000000;   /* 21:670 bottom gradient, 0 -> 100% black */
  --cmp-card-drop:    rgba(0, 0, 0, .8);    /* 21:669 drop shadow, desktop */
  --cmp-card-drop-m:  rgba(0, 0, 0, .35);   /* 21:712 drop shadow, mobile */
  /* Pill: Figma draws today's pill #007bff (21:674), 3.98:1 under white
     9.6-12px text. The tomorrow pill's own blue (21:704) passes at 6.64:1
     and is used for both. */
  --cmp-pill-today:   #0155cb;   /* 21:704 */
  --cmp-pill-past:    #3b404a;   /* 21:689 */
  --cmp-gold:         #ffae00;   /* 21:681 offer lines, Open */
  --cmp-grey-ink:     #a6adb8;   /* 21:696 offer text, Expired (5.23:1) */
  --cmp-btn-past:     #292e36;   /* 21:693 */
  --cmp-btn-soon:     #244066;   /* 21:708 */
  --cmp-cta-from:     #ff8c00;   /* 21:678 GET BONUS gradient start; end is --accent */
  --cmp-cta-glow:     rgba(255, 69, 0, .33);  /* 21:678 drop shadow */
  --cmp-cta-rim:      rgba(255, 255, 255, .25); /* 21:678 inner top highlight */
  --cmp-arrow:        #007bff;   /* 21:636 / 21:637 arrows (3.98:1 icon, AA non-text) */
  --cmp-arrow-drop:   rgba(0, 0, 0, .8);    /* 21:636 */
  /* Pager, 21:638: four bars, 40 / 24 / 16 / 8 wide, blue, light blue,
     orange, violet. Figma's violet #7c3aed is 2.9:1 on --cmp-bg, under
     the 3:1 a control needs; violet-500 is the next step up (3.9:1). */
  --cmp-tick-on:      #3b82f6;   /* 21:639 */
  --cmp-tick:         #60a5fa;   /* 21:640 */
  --cmp-tick-mid:     #f97316;   /* 21:641 */
  --cmp-tick-far:     #8b5cf6;   /* 21:642 is #7c3aed, see above */
}

/* ══ carousel ══════════════════════════════════════════════════ */
.cmp-cards {
  --k: 1;
  --card-w: calc(275px * var(--k));
  --card-h: calc(400px * var(--k));
  /* neighbour placement, measured off 21:534 */
  --nb-x: calc(218px * var(--k));
  --nb-y: calc(16px * var(--k));
  --nb-rot: 19deg;
  --nb-scale: .8;
  --arrow: 64px;
  --slide: 300ms;               /* the pager bar only */

  position: relative;
  width: 100%;
  max-width: 754px;            /* arrow edge to arrow edge in 21:534 */
  margin-inline: auto;
  /* No clip here: a clip at this box's edge cut the left neighbour and its
     shadow on a straight line over the hero art (owner, 2026-10-17). The
     hero clips at the screen edge itself (main.css .cmp-hero). */
}

.cmp-car__stage {
  position: relative;
  height: calc(var(--card-h) + 20px);
  touch-action: pan-y;
  perspective: 1400px;
}

/* Typed, non-inheriting: a change to --q on a card restyles that card
   only, not every element inside it. Browsers without @property ignore this
   and fall back to plain inherited custom properties, with the same poses. */
@property --q    { syntax: '<number>'; inherits: false; initial-value: 0; }
@property --aq   { syntax: '<number>'; inherits: false; initial-value: 0; }

/* One continuous position per card instead of five fixed slots: main.js
   writes --q (index minus the fractional position under the centre,
   clamped to -2..2) on each card every frame of a move. Every property
   below is a continuous function of it, with the rest poses unchanged:
     q = 0      centre, Figma 21:534
     q = +-1    neighbour: --nb-x / --nb-y / --nb-rot / --nb-scale, opacity --nb-op
     q = +-2    off-stage, opacity 0, so a card entering slides in from here
   x and the tilt are linear in q, so the centre card moves 1:1 with the
   finger. The drop (y) eases in and out between centre and neighbour
   (3a^2 - 2a^3), so a card leaves the centre sideways, not on a V. The
   size follows a^2(3 - a)/2, the same 0/1/2 at the rest poses but with no
   kink at the centre. Opacity falls with a^2 up to the neighbour, so the
   two cards crossing mid-slide are nearly opaque instead of two ghosts,
   then linearly to 0 at q = +-2. a = |q|; a1 = min(a, 1), a2 = max(a - 1, 0). */
.cmp-card {
  --aq: max(var(--q), -1 * var(--q));
  --a1: min(var(--aq), 1);
  --a2: max(var(--aq) - 1, 0);
  --nb-op: .75;
  position: absolute;
  left: 50%;
  top: 0;
  width: var(--card-w);
  height: var(--card-h);
  margin-left: calc(var(--card-w) / -2);
  transform:
    translate(calc(var(--q) * var(--nb-x)),
              calc(var(--a1) * var(--a1) * (3 - 2 * var(--a1)) * var(--nb-y)))
    rotate(calc(var(--q) * var(--nb-rot)))
    scale(calc(1 - var(--aq) * var(--aq) * (3 - var(--aq)) / 2 * (1 - var(--nb-scale))));
  opacity: calc(1 - (1 - var(--nb-op)) * var(--a1) * var(--a1) - var(--nb-op) * var(--a2));
  perspective: 1400px;
}
/* Figma draws the soon card at half opacity (21:699). */
.cmp-card--next { --nb-op: .5; }
/* z-index and will-change are inline from main.js § motion: the stacking
   follows --q frame by frame, and a layer exists only while cards move. */

.cmp-car__arrow {
  position: absolute;
  top: calc(var(--card-h) / 2 - var(--arrow) / 2 + 26px * var(--k));
  z-index: 4;
  display: grid;
  place-items: center;
  width: var(--arrow);
  height: var(--arrow);
  border: 0;
  border-radius: var(--r-sm);
  background: var(--cmp-arrow);
  color: var(--text);
  box-shadow: 0 4px 25px var(--cmp-arrow-drop);
  cursor: pointer;
  transition: transform 140ms var(--ease-out), opacity 200ms var(--ease-out);
}
.cmp-car__arrow svg { width: 16px; height: 16px; }
.cmp-car__arrow--prev { left: 0; }
.cmp-car__arrow--prev svg { transform: scaleX(-1); }
.cmp-car__arrow--next { right: 0; }
.cmp-car__arrow:active { transform: scale(.94); }
.cmp-car__arrow[aria-disabled="true"] { opacity: .35; cursor: default; }
.cmp-car__arrow[aria-disabled="true"]:active { transform: none; }
.cmp-car__arrow:focus-visible {
  outline: 2px solid var(--text);
  outline-offset: 3px;
}

/* 21:638 draws four 4px bars that shrink away from the current one:
   40 blue, 24 light blue, 16 orange, 8 violet. It is a mock of a shorter
   calendar; this one has nine days, so there are nine bars, and each takes
   Figma's look by its distance from the current card (data-d, set by
   main.js): 0, 1, 2, then 3 for everything further. With today first, the
   row reads exactly as Figma draws it.
   Each bar is a button 16px wider than its bar (24px at least, WCAG 2.5.8),
   so bars stand 16px apart rather than Figma's 4: two 24px targets whose
   centres are 12px apart would overlap. Every colour is 3.9:1 or more on
   the ground under it, so no bar needs dimming. */
.cmp-car__bar {
  display: flex;
  justify-content: center;
  padding: 0 16px;
}
.cmp-car__tick {
  --bar: 8px;
  --bar-c: var(--cmp-tick-far);
  display: grid;
  place-items: center;
  width: max(24px, calc(var(--bar) + 16px));
  height: 24px;
  padding: 0;
  border: 0;
  background: none;
  flex: none;
  cursor: pointer;
  transition: width var(--slide) var(--ease-out);
}
.cmp-car__tick[data-d="2"] { --bar: 16px; --bar-c: var(--cmp-tick-mid); }
.cmp-car__tick[data-d="1"] { --bar: 24px; --bar-c: var(--cmp-tick); }
.cmp-car__tick.is-on       { --bar: 40px; --bar-c: var(--cmp-tick-on); }
.cmp-car__tick::before {
  content: "";
  width: var(--bar);
  height: 4px;
  border-radius: 2px;
  background: var(--bar-c);
  transition: width var(--slide) var(--ease-out), background-color var(--slide) var(--ease-out);
}
.cmp-car__tick:focus-visible { outline: 2px solid var(--text); outline-offset: -2px; border-radius: 6px; }

/* ══ one card ══════════════════════════════════════════════════ */
.cmp-card__inner {
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  transition: transform 300ms var(--ease-out);
}
.cmp-card.is-flipped .cmp-card__inner {
  transform: rotateY(180deg);
  transition-duration: 420ms;
}

.cmp-card__face {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  color: var(--text);
  font-family: var(--font);
  text-align: center;
}
.cmp-card__back { transform: rotateY(180deg); }
/* backface-visibility alone is not enough on iOS Safari: a face's children
   that sit on their own layer (the label, Info, the buttons) show through
   the other face, mirrored. So the hidden face is also transparent, and
   each face switches when the card is edge-on -- 13% into the --ease-out
   curve (rotateY reaches 90deg there): 55ms of the 420ms flip, 40ms of the
   300ms return. Opacity, not visibility, so Back can take focus at once. */
.cmp-card__face { transition: opacity 0s linear 40ms; }
.cmp-card__back,
.cmp-card.is-flipped .cmp-card__front { opacity: 0; }
.cmp-card.is-flipped .cmp-card__back { opacity: 1; }
.cmp-card.is-flipped .cmp-card__face { transition-delay: 55ms; }

/* The silhouette carries the colour and the shadow. It never rotates on its
   own -- its face does -- so the filter does not flatten the 3D flip. */
.cmp-card__shape {
  position: absolute;
  left: 0;
  top: calc(27px * var(--k));
  width: 100%;
  height: calc(343px * var(--k));
  fill: var(--cmp-card-fill, var(--cmp-card-today));
  /* 21:669: 0 8.33 50 at 80% (21:712 on a phone: 0 6.66 33 at 35%). Only
     the flat <svg> carries it; a card is a layer only while it moves. */
  filter: drop-shadow(0 8.33px 50px var(--cmp-card-drop));
}
.cmp-card__shape .cmp-card__fade { fill: url(#cmp-card-fade); }
.cmp-car__defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.cmp-car__defs stop { stop-color: var(--cmp-card-shade); }
.cmp-card--past { --cmp-card-fill: var(--cmp-card-past); }
.cmp-card--next { --cmp-card-fill: var(--cmp-card-soon); }

.cmp-card__label {
  position: absolute;
  z-index: 2;
  left: 50%;
  top: calc(26px * var(--k));
  transform: translateX(-50%);
  /* The UA label is the longest ("СЬОГОДНІШНІЙ БОНУС • 25 ЖОВТНЯ 2026"):
     the pill may overhang the card a little, then wraps to two lines rather
     than cut the date. */
  width: max-content;
  max-width: calc(100% + var(--lbl-over, 16px));
  margin: 0;
  padding: 4.8px var(--lbl-px, 14.4px);   /* 21:674 */
  border-radius: 9.6px;
  background: var(--cmp-pill-today);
  font-size: var(--lbl-fs, 12px);
  font-weight: var(--fw-bold);
  font-stretch: var(--font-stretch-tight);
  line-height: 1.25;
  letter-spacing: .02em;
  text-wrap: balance;
}
.cmp-card--past .cmp-card__label { background: var(--cmp-pill-past); color: var(--cmp-grey-ink); }

.cmp-card__ball,
.cmp-card__lock {
  position: absolute;
  pointer-events: none;
}
.cmp-card__ball img,
.cmp-card__lock img { display: block; width: 100%; height: 100%; }
/* 21:683 -- the ball art is a wide transparent frame, wider than the card */
.cmp-card__ball {
  left: calc(-83px * var(--k));
  top: calc(36px * var(--k));
  width: calc(442.5px * var(--k));
  height: calc(247px * var(--k));
}
/* 21:711, scaled from the 220 card to the 275 one */
.cmp-card__lock {
  left: calc(73px * var(--k));
  top: calc(126px * var(--k));
  width: calc(129px * var(--k));
  height: calc(231px * var(--k));
}
.cmp-card--next .cmp-card__ball { opacity: .85; }

.cmp-card__offer {
  position: absolute;
  left: 8px;
  right: 8px;
  /* Anchored to the button, not the ball: a line that wraps ("Free Bet +
     Cashback 20%" on a phone) grows the block upward over the ball's
     shadow instead of under GET BONUS. 21:681-21:682 end 4px above it. */
  bottom: calc(73px * var(--k));
  font-weight: var(--fw-bold);
}
.cmp-card__offer p { margin: 0; }
.cmp-card__line {
  color: var(--cmp-gold);
  font-size: 18px;
  line-height: 1.2;
  letter-spacing: .2em;
}
.cmp-card__line.is-long { letter-spacing: .06em; }
.cmp-card__amount {
  font-size: 34px;
  line-height: 1.12;
  text-transform: uppercase;
  white-space: nowrap;
}
.cmp-card--past .cmp-card__line,
.cmp-card--past .cmp-card__amount { color: var(--cmp-grey-ink); }

/* Info is not in Figma (the card has no terms there) but it is the way to
   the terms, and step 1 of "How does it work?" names it. It stands at the
   top right, under the date pill (4px below it), where the card is empty
   to the right of the ball. The ball's top-right curve is what limits it:
   in the compact bands the pill is narrow (padding 4-6px) so its bottom-left
   corner stays 4px+ off the ball's alpha edge (measured, ball-orange-884);
   the offer lines below never reach it. The pseudo-element makes the touch
   target at least 44x44 without moving anything. */
.cmp-card__info {
  position: absolute;
  z-index: 2;
  /* 4px under the date pill: its top, its one line and its padding. The
     compact values (a smaller card) come from § the bands. */
  right: var(--info-x, 8px);
  top: calc(26px * var(--k) + var(--lbl-fs, 12px) * 1.25 + 13.6px);
  min-width: var(--info-min, 52px);
  height: var(--info-h, 28px);
  padding: 0 var(--info-pad, 12px);
  border: 1px solid var(--glass-brd);
  border-radius: var(--r-pill);
  background: var(--cmp-pill-today);
  color: var(--text);
  font: var(--fw-bold) var(--info-fs, 14px)/1 var(--font);
  cursor: pointer;
  transition: transform 140ms var(--ease-out);
}
.cmp-card__info::after,
.cmp-card__btn::after {
  content: "";
  position: absolute;
  top: min(0px, calc(50% - 22px));
  bottom: min(0px, calc(50% - 22px));
  left: min(0px, calc(50% - 22px));
  right: min(0px, calc(50% - 22px));
}
.cmp-card--past .cmp-card__info { background: var(--cmp-pill-past); color: var(--cmp-grey-ink); }
.cmp-card__info:active { transform: scale(.94); }

/* GET BONUS / EXPIRED / COMING SOON / Back -- one slot, 21:678 */
.cmp-card__btn {
  position: absolute;
  z-index: 2;
  left: 50%;
  top: calc(331px * var(--k));
  display: flex;
  align-items: center;
  justify-content: center;
  width: calc(218px * var(--k));
  height: calc(52px * var(--k));
  margin-left: calc(-109px * var(--k));
  padding: 0 16px;
  border: 0;
  border-radius: var(--r-pill);
  /* 21:679: 24px. "ОТРИМАТИ БОНУС" at 24px is 212px wide in a 218px
     button, so Ukrainian and Russian take Roboto's condensed width (75%,
     --font-stretch-tight), which brings it to ~180. */
  font: var(--fw-semi) 24px/1 var(--font);
  letter-spacing: -.01em;
  text-decoration: none;
  white-space: nowrap;
}
:lang(uk) .cmp-card__btn,
:lang(ru) .cmp-card__btn { font-stretch: var(--font-stretch-tight); }
.cmp-card--past .cmp-card__btn { background: var(--cmp-btn-past); color: var(--cmp-grey-ink); }
.cmp-card--next .cmp-card__btn { background: var(--cmp-btn-soon); color: var(--text); }

/* Ink is --accent-ink, not Figma's white. 24px is large text, so white
   would need 3:1, and it gets 2.33:1 on the #ff8c00 end, 2.9:1 in the
   middle and 3.44:1 only at the --accent end. Dark ink holds 4.79:1 or
   better across the whole gradient. */
.cmp-card__cta {
  background: linear-gradient(to right, var(--cmp-cta-from), var(--accent));
  color: var(--accent-ink);
  box-shadow: 0 8px 12px var(--cmp-cta-glow), inset 0 1px 0 var(--cmp-cta-rim);
  transition: transform 140ms var(--ease-out);
}
.cmp-card__cta[href] { cursor: pointer; }
.cmp-card__cta:active { transform: scale(.97); }

/* ── the back ── */
.cmp-card__terms {
  position: absolute;
  left: calc(26px * var(--k));
  right: calc(30px * var(--k));
  top: calc(80px * var(--k));
  bottom: calc(84px * var(--k));
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  font-size: 16px;
  font-weight: var(--fw-medium);
  line-height: 1.4;
  overflow-wrap: anywhere;
}
.cmp-card--past .cmp-card__terms { color: var(--cmp-grey-ink); }

.cmp-card__backbtn {
  background: var(--surface-sunken);
  color: var(--text);
  border: 1px solid var(--glass-brd);
  cursor: pointer;
  transition: transform 140ms var(--ease-out);
}
.cmp-card__backbtn:active { transform: scale(.97); }

.cmp-card__info:focus-visible,
.cmp-card__btn:focus-visible {
  outline: 2px solid var(--text);
  outline-offset: 3px;
}

/* ══ the bands ═════════════════════════════════════════════════
   The same three as campaign/main.css § page, word for word: COLUMN (the
   phone comp, 21:587), TABLET (COLUMN from 600px at 1.25x) and WIDE (the
   desktop comp, 21:534, also on a phone held sideways). */

/* ── COLUMN, 21:587 ── */
@media (max-width: 1023.98px) and (orientation: portrait),
       (max-width: 1023.98px) and (min-height: 500.02px),
       (max-width: 559.98px) {
  .cmp-cards {
    --k: .8;
    --nb-x: 104px;
    --nb-y: 85px;
    --nb-rot: 18deg;
    --nb-scale: .7;
    --arrow: 44px;
    --slide: 340ms;
    --lbl-fs: 11px;
    --info-x: 4px;
    --info-min: 0px;
    --info-h: 26px;
    --info-pad: 6px;
    --info-fs: 13px;
  }
  /* The neighbours drop 85px in 21:606; the stage grows to keep them. */
  .cmp-car__stage { height: calc(var(--card-h) + 52px); }
  /* The pager sits BELOW the fisherman painted into the hero plate, which
     hangs from the hero's bottom edge: 21:611 is at y669, the cards at y144
     (21:606), so the 4px bar's top is 525px into this box and its 44px
     button starts 20px above that. Under 364px the title above shrinks
     (main.css: 332px wide, max 100% of a 16px-padded hero, 768:227) and
     lifts this box; the last term puts the same height back so the bar
     stays at y669 of the hero. */
  .cmp-car__bar {
    position: absolute;
    left: 0;
    right: 0;
    padding: 0;
    top: calc(505px + (332px - min(332px, 100vw - 32px)) * 227 / 768);
  }
  .cmp-car__tick { height: 44px; }
  .cmp-cards { height: calc(539px + (332px - min(332px, 100vw - 32px)) * 227 / 768); }
  /* 21:587 draws no arrows. They stay in the tab order and show only while
     the keyboard is inside the carousel (and, on TABLET, for a mouse). */
  .cmp-car__arrow,
  .cmp-car__arrow[aria-disabled="true"] {
    top: calc(var(--card-h) / 2 - var(--arrow) / 2);
    opacity: 0;
    pointer-events: none;
  }
  .cmp-cards:has(:focus-visible) .cmp-car__arrow { opacity: 1; pointer-events: auto; }
  .cmp-cards:has(:focus-visible) .cmp-car__arrow[aria-disabled="true"] { opacity: .35; }
  .cmp-car__arrow--prev { left: 8px; }
  .cmp-car__arrow--next { right: 8px; }

  .cmp-card__shape { filter: drop-shadow(0 6.66px 33.3px var(--cmp-card-drop-m)); }
  .cmp-card__line { font-size: 16px; }
  .cmp-card__amount { font-size: 30px; }
  .cmp-card__btn { font-size: 18px; }
  .cmp-card__terms { font-size: 14px; }
}

/* ── TABLET: COLUMN at 1.25x, the desktop card ── */
@media (min-width: 600px) and (max-width: 1023.98px) and (orientation: portrait),
       (min-width: 600px) and (max-width: 1023.98px) and (min-height: 500.02px) {
  .cmp-cards {
    --k: 1;
    --nb-x: 130px;
    --nb-y: 106px;
    --arrow: 56px;
    --lbl-fs: 12px;
    --info-x: 8px;
    --info-min: 52px;
    --info-h: 28px;
    --info-pad: 12px;
    --info-fs: 14px;
    /* Arrows (for a mouse) just outside the neighbours' inner halves. */
    max-width: 560px;
    /* 539 and 505 times 1.25; the title above is always its full 415px. */
    height: 674px;
  }
  .cmp-car__stage { height: calc(var(--card-h) + 65px); }
  .cmp-car__bar { top: 636px; }
  .cmp-card__line { font-size: 18px; }
  .cmp-card__amount { font-size: 34px; }
  .cmp-card__btn { font-size: 24px; }
  .cmp-card__terms { font-size: 16px; }
}
@media (hover: hover) and (pointer: fine) and (min-width: 600px) and (max-width: 1023.98px) and (orientation: portrait),
       (hover: hover) and (pointer: fine) and (min-width: 600px) and (max-width: 1023.98px) and (min-height: 500.02px) {
  .cmp-car__arrow { opacity: 1; pointer-events: auto; }
  .cmp-car__arrow[aria-disabled="true"] { opacity: .35; pointer-events: auto; }
}

/* ── WIDE, 21:534 ──
   The card scales with the frame, k = width / 1440, but never below the
   phone card (.8). Text sizes stay px: each is the desktop size times k,
   floored at the phone's. The carousel box starts at the column's left
   edge (21:636 at x583, where the column starts), not centred in it. */
@media (min-width: 1024px),
       (min-width: 560px) and (max-height: 500px) and (orientation: landscape) {
  .cmp-cards {
    --k: .8;
    --lbl-fs: max(11px, 12px * var(--k));
    --info-x: 4px;
    --info-min: 0px;
    --info-h: 26px;
    --info-pad: 6px;
    --info-fs: 13px;
    margin-inline: 0;
  }
  @supports (width: calc(1px * tan(atan2(1px, 1px)))) {
    .cmp-cards { --k: clamp(.8, tan(atan2(100vw, 1440px)), 1); }
  }
  /* 21:638's bars are at y564: 427 under the card's top, 3 less than the
     stage's 420 plus half the 24px button. */
  .cmp-car__bar { margin-top: -3px; }
  .cmp-card__line { font-size: max(16px, 18px * var(--k)); }
  .cmp-card__amount { font-size: max(30px, 34px * var(--k)); }
  .cmp-card__btn { font-size: max(18px, 24px * var(--k)); }
  .cmp-card__terms { font-size: max(14px, 16px * var(--k)); }
}
@media (min-width: 1440px) {
  .cmp-cards {
    --k: 1;
    --info-x: 8px;
    --info-min: 52px;
    --info-h: 28px;
    --info-pad: 12px;
    --info-fs: 14px;
  }
}

/* A phone held sideways (main.css): a smaller card, so GET BONUS ends
   inside a 390px screen, and the neighbours a little closer so the left
   one stays off the fisherman's pumpkin. Swipe, as on any phone. */
@media (min-width: 560px) and (max-height: 500px) and (orientation: landscape) and (max-width: 1023.98px) {
  .cmp-cards {
    --k: .75;
    --nb-x: min(120px, 15vw);
    --lbl-px: 10px;
    --lbl-over: 32px;      /* the Ukrainian label, one line on a 206px card */
    --info-x: 3px;
    --info-pad: 4px;
    --info-fs: 12px;
  }
}
@media (hover: none) and (min-width: 560px) and (max-height: 500px) and (orientation: landscape) and (max-width: 1023.98px) {
  .cmp-car__arrow,
  .cmp-car__arrow[aria-disabled="true"] { opacity: 0; pointer-events: none; }
  .cmp-cards:has(:focus-visible) .cmp-car__arrow { opacity: 1; pointer-events: auto; }
  .cmp-cards:has(:focus-visible) .cmp-car__arrow[aria-disabled="true"] { opacity: .35; }
}

/* ══ reduced motion ════════════════════════════════════════════
   Degrade, never remove: the slide jumps (main.js § motion), the flip
   crossfades, the press feedback above is untouched. */
@media (prefers-reduced-motion: reduce) {
  .cmp-car__tick::before { transition: none; }

  .cmp-card__inner,
  .cmp-card.is-flipped .cmp-card__inner {
    transform: none;
    transition: none;
  }
  .cmp-card__back { transform: none; }
  .cmp-card__face {
    backface-visibility: visible;
    -webkit-backface-visibility: visible;
    transition: opacity 200ms var(--ease-out);
  }
  .cmp-card__back,
  .cmp-card.is-flipped .cmp-card__front { opacity: 0; }
  .cmp-card.is-flipped .cmp-card__back { opacity: 1; }
  .cmp-card.is-flipped .cmp-card__face { transition-delay: 0s; }
}
