/* The card stack: each film as a full-art trading card (in the spirit of a Lorcana Enchanted),
   its poster edge to edge under a gold frame, with a holographic foil that follows the light.
   Sizes inside a card are in container units (cqw), so a card looks the same at any size. */

/* Inter in two parts. The first, cut down to the characters the site uses (static/fonts: see the
   README), is what's normally fetched. The rest of Inter, the full fonts, is fetched only for a page
   that has a character outside it, e.g. a cast's "Nguyễn", "Ștefan" or "Ελένη": in Inter, as before,
   not misdrawn from the cut-down one's parts, nor in a stand-in font. */
@font-face { font-family: "Inter"; src: url("/static/fonts/Inter-Regular.woff") format("woff"); font-weight: 400; font-display: swap;
  unicode-range: U+0000-017F, U+0237, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0300-0308, U+2000-206F, U+20AC, U+2122, U+2190-2193, U+21BA, U+2212, U+25CB, U+25CF, U+FEFF, U+FFFD; }
@font-face { font-family: "Inter"; src: url("/static/fonts/Inter-Medium.woff") format("woff"); font-weight: 500; font-display: swap;
  unicode-range: U+0000-017F, U+0237, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0300-0308, U+2000-206F, U+20AC, U+2122, U+2190-2193, U+21BA, U+2212, U+25CB, U+25CF, U+FEFF, U+FFFD; }
@font-face { font-family: "Inter"; src: url("/static/fonts/Inter-SemiBold.woff") format("woff"); font-weight: 600 800; font-display: swap;
  unicode-range: U+0000-017F, U+0237, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0300-0308, U+2000-206F, U+20AC, U+2122, U+2190-2193, U+21BA, U+2212, U+25CB, U+25CF, U+FEFF, U+FFFD; }
/* the rest: what Inter has that the above leaves out (Latin, Greek and Cyrillic beyond, and its
   symbols; read from the full fonts' character maps), and nothing it hasn't: Arabic or Hindi text
   would otherwise fetch a full font that can't draw it */
@font-face { font-family: "Inter"; src: url("/fonts/Inter-Regular.ttf") format("truetype"); font-weight: 400; font-display: swap;
  unicode-range: U+0180-0236, U+0238-02BA, U+02BD-02C5, U+02C7-02D9, U+02DB, U+02DD-02FF, U+0309-052F, U+0E3F, U+1D00-1DFF,U+1E00-1FFF, U+2070-20AB, U+20AD-20C0, U+20DB-2121, U+2123-213B, U+214D-218F, U+2194-21B9, U+21BB, U+21D0-21EA, U+2202-2211, U+2213-23CF, U+2423, U+2460-24EA, U+25A0-25CA, U+25CC-25CE, U+25D0-25EF, U+2600-2606, U+263C, U+2661-266B, U+26A0, U+2713-2717, U+2756-2788, U+27EF-27FA, U+2913, U+2A38, U+2B06-2B24, U+2C7C-2C7F, U+2DFF, U+2E18, U+A69F, U+A7FF, U+A92E, U+1F12F-1F16B, U+1F850-1F852; }
@font-face { font-family: "Inter"; src: url("/fonts/Inter-Medium.ttf") format("truetype"); font-weight: 500; font-display: swap;
  unicode-range: U+0180-0236, U+0238-02BA, U+02BD-02C5, U+02C7-02D9, U+02DB, U+02DD-02FF, U+0309-052F, U+0E3F, U+1D00-1DFF,U+1E00-1FFF, U+2070-20AB, U+20AD-20C0, U+20DB-2121, U+2123-213B, U+214D-218F, U+2194-21B9, U+21BB, U+21D0-21EA, U+2202-2211, U+2213-23CF, U+2423, U+2460-24EA, U+25A0-25CA, U+25CC-25CE, U+25D0-25EF, U+2600-2606, U+263C, U+2661-266B, U+26A0, U+2713-2717, U+2756-2788, U+27EF-27FA, U+2913, U+2A38, U+2B06-2B24, U+2C7C-2C7F, U+2DFF, U+2E18, U+A69F, U+A7FF, U+A92E, U+1F12F-1F16B, U+1F850-1F852; }
@font-face { font-family: "Inter"; src: url("/fonts/Inter-SemiBold.ttf") format("truetype"); font-weight: 600 800; font-display: swap;
  unicode-range: U+0180-0236, U+0238-02BA, U+02BD-02C5, U+02C7-02D9, U+02DB, U+02DD-02FF, U+0309-052F, U+0E3F, U+1D00-1DFF,U+1E00-1FFF, U+2070-20AB, U+20AD-20C0, U+20DB-2121, U+2123-213B, U+214D-218F, U+2194-21B9, U+21BB, U+21D0-21EA, U+2202-2211, U+2213-23CF, U+2423, U+2460-24EA, U+25A0-25CA, U+25CC-25CE, U+25D0-25EF, U+2600-2606, U+263C, U+2661-266B, U+26A0, U+2713-2717, U+2756-2788, U+27EF-27FA, U+2913, U+2A38, U+2B06-2B24, U+2C7C-2C7F, U+2DFF, U+2E18, U+A69F, U+A7FF, U+A92E, U+1F12F-1F16B, U+1F850-1F852; }

:root {
  --bg: #07070a;
  --gold: #e9cf8e;      /* the cards' own gold: frame, seals, details */
  --gold-deep: #9c7632;
  /* the site's accent, for its controls (buttons, filters, highlights): deep indigo into blue
     for fills, and a lighter tint of it for text, outlines and washes, so they read on the dark */
  --accent: #a996ff;    /* text, outlines, washes */
  --accent-grad: linear-gradient(135deg, #6847d8, #2f5cc4); /* fills */
  --on-accent: #fff;    /* text on the fills */
  --ink: #f4f1ea;
  --ink-soft: rgba(244, 241, 234, 0.78);
  --ink-faint: rgba(244, 241, 234, 0.5);
  --soon: #3ddc84; /* starting within 2 hours */
  --now: #ff5c5c;  /* just started */
  --full-low: #7fd69a;  /* a show checked under half full (.st-full) */
  --full-mid: #7cb8f5;  /* half full or more */
  --full-most: #ef7a6e; /* 70% full or more */

  /* a card is 63 × 88, like a real one, as big as fits (and, where the buttons at the top left
     reach over it, smaller and lower by --bar-room: cards.js's clearOfBar) */
  --card-h: calc(min(72svh, 740px, calc(90vw * 88 / 63)) - var(--bar-room, 0px)); /* leaving room for the controls below */
  --card-w: calc(var(--card-h) * 63 / 88);
  --times-w: calc(100vw - 32px); /* the showtimes view taking the screen, a margin either side; beside the card, placeTimes sets it */
  --times-gap: 36px;
  --ease: cubic-bezier(.2, .8, .2, 1);
  /* for big moves that start from rest: --ease is at full speed from the first frame, which on a
     long move reads as a jump, then it's mostly over; this sets off, then settles the same way */
  --set-off: cubic-bezier(.4, 0, .2, 1);
  color-scheme: dark;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
html {
  -webkit-text-size-adjust: 100%; text-size-adjust: 100%; /* iOS: no bigger text on turning sideways */
  -webkit-tap-highlight-color: transparent; /* iOS: no grey flash on every tap */
}
body {
  margin: 0; overflow: hidden;
  overscroll-behavior: none; /* iOS: the page doesn't bounce when swiped */
  background: var(--bg); color: var(--ink);
  font: 400 16px/1.45 "Inter", system-ui, -apple-system, sans-serif;
  -webkit-font-smoothing: antialiased;
}
img { display: block; }
/* manipulation: quick taps are taps, not iOS's double-tap zoom (spamming next and back) */
button { font: inherit; color: inherit; touch-action: manipulation; }
[hidden] { display: none !important; }
/* for a screen reader only: there, unseen (the page's heading, what's announced: cards.js's announce) */
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
/* the keyboard's focus: one ring, the accent's, on every control (the browsers' own differ, and
   Chrome's was a faint blue on the dark). Only from the keyboard: :focus-visible. */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
:is(h2, h3)[tabindex="-1"]:focus { outline: none; } /* a heading focused as its panel opens, just so it starts there (see cards.js's focusIn) */

/* ——— The room: the top card's poster, blurred into light ——— */
.ambient { position: fixed; inset: 0; z-index: 0; pointer-events: none; }
.ambient img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  transform: scale(1.3); opacity: 0; /* blurred and saturated on the server (?glow=1): no filter here */
  transition: opacity 1.2s var(--ease);
  will-change: opacity; /* (see .tcg's will-change: made as each fade started, it held up the cards' moves) */
}
.ambient img.on { opacity: 0.42; }
.ambient::after { content: ""; position: absolute; inset: 0; background: radial-gradient(ellipse at 50% 45%, transparent 20%, rgba(7, 7, 10, 0.85) 80%); }

.table {
  position: relative; z-index: 1; height: 100%;
  --gap: clamp(18px, 3.5svh, 34px); /* between the cards and the buttons below */
  --line-room: 0px; /* and more, for the filter's line under the cards (.timed: see .next-show) */
  display: grid; place-content: center; justify-items: center; gap: var(--gap);
  padding-top: calc(26px + var(--bar-room, 0px)); /* room for the cards peeking out behind */
  /* nothing reaches past the screen: a phone's browser sizes the page to all of it, body's
     overflow: hidden or not, so the showtimes waiting off to the right made it three screens wide,
     with Preferences, the trailer and the sheets placed by that width, out of sight */
  overflow: clip;
}
/* On a phone, the buttons in the top corners have the top of the screen to themselves: the cards
   start below them, leaving room for the filter's times line (.next-show), and are as big as fits
   from there down to the controls, clear of a home bar. (As tall as on a wider screen, they ran
   under the buttons in Safari, whose own bars take a good part of the screen.) On its side, the
   same, from the top: see below. */
@media (max-width: 740px), (orientation: landscape) and (max-height: 499px) {
  .table {
    --top: calc(max(18px, env(safe-area-inset-top)) + 96px); /* the buttons (40px), the next show, the cards peeking out behind */
    --bottom: calc(36px + env(safe-area-inset-bottom)); /* (room for "Back to the start", under the arrows) */
    --gap: clamp(14px, 2.4svh, 34px);
    padding: var(--top) 0 var(--bottom);
    /* the controls below: Trailer and Showtimes (44px) and the arrows (38px, 6px closer) */
    --card-h: min(calc(90vw * 88 / 63), calc(100svh - var(--top) - var(--bottom) - 2 * var(--gap) - 76px));
    --card-w: calc(var(--card-h) * 63 / 88);
  }
}

/* ——— The stack ——— */
.stack {
  position: relative; width: var(--card-w); height: var(--card-h);
  transition: transform .6s var(--set-off); will-change: transform; /* moved aside for the showtimes (see below; and .tcg's will-change) */
}
/* a card's place in the stack (transform, opacity, z-index) is set on it by cards.js, directly:
   not through inherited variables, which would have the browser recheck everything inside it */
.tcg {
  position: absolute; inset: 0;
  transition: transform .6s var(--ease), opacity .5s var(--ease); /* (a tuck times its own: see glide) */
  touch-action: none; user-select: none; -webkit-user-select: none;
}
/* Anything that animates is kept on its own layer for good (will-change), not just while it
   moves: a layer made as an animation starts means redrawing it, and what's under it, before the
   first frame, and Safari runs the clock meanwhile, so animations seemed to start most of the way
   through. Here: each card drawn, and its veil (below). */
.tcg:not(.deep) { will-change: transform; }
.tcg:not(.deep) .tcg-veil { will-change: opacity; }
.tcg.dragging, .tcg.jump, .deck.jump .tcg { transition: none; } /* (.deck.jump: all of them, put in place at once: cards.js's jumpTo) */
.opening * { transition: none !important; } /* the page opening in the grid (cards.js) */
/* too far back to see: not drawn at all, nor laid out, so its lazy posters wait until it's drawn
   (hidden alone, they'd all load at once: they're in view, under the top card) */
.tcg.deep { visibility: hidden; content-visibility: hidden; }
.deck .tcg:first-child { z-index: 1; } /* before cards.js has stacked them: the first on top, not the last */
.tcg:not(.top) { pointer-events: none; }
.tcg.top { cursor: grab; }
.tcg.dragging { z-index: 1001 !important; cursor: grabbing; } /* held: above the rest (and after .top, which it is too) */

.tcg-tilt {
  container-type: inline-size; /* cqw is the card's width, for the card itself too */
  width: 100%; height: 100%;
  /* tilted toward the light by cards.js, with the perspective in its transform: one flat card
     needs no 3D scene (preserve-3d), which Safari is known to flicker and misorder */
  /* the card's shadow, here as the face's clip-path would cut it off; its corners are the face's
     (4.6cqw: this can't use cqw, being the container, so as a share of its width and height) */
  border-radius: 4.6% / calc(4.6% * 63 / 88);
  box-shadow:
    0 0 0 1px rgba(255, 240, 200, 0.16),
    0 2px 3px rgba(0, 0, 0, 0.5),
    0 40px 80px -20px rgba(0, 0, 0, 0.85);
}

/* ——— The card ——— */
.tcg-face {
  --corner: 4.6cqw;      /* the card's corner radius */
  --frame-inset: 2.6cqw; /* how far in the gold frame sits */
  position: relative; width: 100%; height: 100%; overflow: hidden;
  border-radius: var(--corner);
  /* rounded with clip-path too: Safari's overflow clip leaves the corners of layers moved on the
     graphics chip (the light's) square, and a clip-path clips everything inside */
  clip-path: inset(0 round var(--corner));
  background: #111;
  contain: layout; /* nothing inside reaches out, so changes inside stay inside */
}
/* the cards behind are darker: a black veil (its opacity set by cards.js), since fading that is
   cheap where a filter repaints the whole card every frame */
.tcg-veil {
  position: absolute; inset: 0; z-index: 5; pointer-events: none;
  background: #000; opacity: 0;
  transition: opacity .6s var(--ease);
}
.tcg-art, .tcg-backing {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 20%;
  pointer-events: none;
}
/* the art is sharp inside the gold frame; beyond it, the server's pre-blurred copy shows
   (blurred once on the server, so nothing is blurred live as the card moves) */
.tcg-art { clip-path: inset(var(--frame-inset) round calc(var(--corner) - var(--frame-inset))); }

/* the gold line around the art, following the card's outline: its corners are the card's,
   less the inset, so the two curves run parallel */
.tcg-frame {
  position: absolute; inset: var(--frame-inset); border-radius: calc(var(--corner) - var(--frame-inset));
  padding: 0.35cqw; pointer-events: none;
  /* its gold, 2.2 times its size; on the top card it catches the light (cardlight.js) */
  background: linear-gradient(135deg, #fff2c6, var(--gold-deep) 22%, #f6e2a8 40%, #8a6526 58%, #fbe6ad 76%, var(--gold-deep));
  background-size: 220% 220%;
  background-position: 50% 50%;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  opacity: 0.9;
}

/* ——— Corners: the scores, as gems ——— */
.tcg-corner { position: absolute; top: 5.2cqw; display: grid; gap: 1.6cqw; z-index: 4; } /* above the foil */
.tcg-corner-left { left: 5.2cqw; justify-items: start; }
.tcg-corner-right { right: 5.2cqw; justify-items: end; }
.gem {
  display: inline-flex; align-items: center; gap: 1.3cqw;
  padding: 1.25cqw 2.4cqw 1.25cqw 1.5cqw; border-radius: 99px;
  background: rgba(10, 9, 14, 0.72); /* no blur behind: redone every frame as cards move */
  box-shadow: inset 0 0 0 1px rgba(233, 207, 142, 0.45), 0 4px 14px rgba(0, 0, 0, 0.35);
  font-size: 3.4cqw; font-weight: 700; letter-spacing: -0.01em; font-variant-numeric: tabular-nums;
}
.gem img { width: 4.6cqw; height: 4.6cqw; object-fit: contain; }
.tcg.top .gem { cursor: pointer; } /* a tap opens the showtimes, which name the scores (cards.js) */
/* an IMDb rating from too few votes to count (rating.go): quieter, as beside the film's details */
.gem[data-few] { color: var(--ink-faint); }
.gem[data-few] img { opacity: 0.55; }

/* an award's gem gets a ring in the award's colour */
.gem-fresh { box-shadow: inset 0 0 0 1px rgba(250, 50, 10, 0.9), 0 0 3cqw rgba(250, 50, 10, 0.35), 0 4px 14px rgba(0, 0, 0, 0.35); }
.gem-hot { box-shadow: inset 0 0 0 1px rgba(255, 138, 0, 0.9), 0 0 3cqw rgba(255, 138, 0, 0.35), 0 4px 14px rgba(0, 0, 0, 0.35); }

/* ——— Seals: Certified Fresh and Verified Hot, stamped on the art like a rare card's mark ——— */
.seals { position: absolute; right: 6.5cqw; top: 33%; z-index: 4; display: flex; align-items: center; }
.seal {
  --seal: #fa320a; /* the award's colour */
  position: relative; width: 21cqw; aspect-ratio: 1; border-radius: 50%;
  display: grid; place-items: center;
  background: radial-gradient(circle at 50% 35%, rgba(42, 26, 22, 0.94), rgba(10, 8, 12, 0.96) 70%);
  box-shadow:
    inset 0 0 0 0.45cqw var(--seal),
    inset 0 0 0 4.2cqw rgba(0, 0, 0, 0.22),
    0 0 4cqw color-mix(in srgb, var(--seal) 45%, transparent),
    0 1.6cqw 4cqw rgba(0, 0, 0, 0.6);
  transform: rotate(-9deg);
}
.seal-hot { --seal: #ff8a00; transform: rotate(8deg); }
.seal + .seal { margin-left: -3.5cqw; }
/* the gold rim, catching the same light as the foil */
.seal-shine {
  position: absolute; inset: 0.9cqw; border-radius: 50%;
  /* just a thin line at the edge; the lettering sits on the dark band inside it */
  -webkit-mask: radial-gradient(circle closest-side, transparent calc(100% - 0.6cqw), #000 calc(100% - 0.45cqw));
  mask: radial-gradient(circle closest-side, transparent calc(100% - 0.6cqw), #000 calc(100% - 0.45cqw));
}
/* its gold, catching the light: a gradient 2.6 times the rim's size, slid so the light's spot
   (--lx, --ly: 0 to 1, from cards.js) is where background-position would put it. Small, so
   moving it whole costs little. */
.seal-shine::before {
  content: ""; position: absolute; left: 0; top: 0;
  background: linear-gradient(135deg, #fff2c6, var(--gold-deep) 22%, #f6e2a8 40%, #8a6526 58%, #fbe6ad 76%, var(--gold-deep));
  width: 260%; height: 260%;
  transform: translate(calc(var(--lx, 0.5) * -1.6 / 2.6 * 100%), calc(var(--ly, 0.5) * -1.6 / 2.6 * 100%));
}
/* and an inner gold line around the icon */
.seal::after {
  content: ""; position: absolute; inset: 4.6cqw; border-radius: 50%;
  box-shadow: 0 0 0 0.22cqw rgba(233, 207, 142, 0.75), 0 0 2cqw color-mix(in srgb, var(--seal) 50%, transparent);
}
.seal-rim { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.seal-rim text {
  fill: var(--gold); font-size: 8.2px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase;
}
.seal img { position: relative; width: 8.6cqw; height: 8.6cqw; object-fit: contain; filter: drop-shadow(0 0 1.5cqw color-mix(in srgb, var(--seal) 70%, transparent)); }

/* ——— The text box, over the lower half of the art ——— */
.tcg-info {
  position: absolute; inset: 44% 0 0 0; z-index: 4; /* above the foil, so the words stay crisp */
  display: flex; flex-direction: column; justify-content: flex-end; gap: 2.4cqw;
  padding: 0 7.4cqw 8.6cqw; /* clear of the age rating at the bottom */
  background: linear-gradient(to bottom,
    rgba(9, 8, 12, 0) 0%, rgba(9, 8, 12, 0.55) 22%, rgba(9, 8, 12, 0.88) 46%, rgba(9, 8, 12, 0.96) 100%);
}
.tcg-title {
  position: relative; margin: 0; padding-bottom: 3.6cqw;
  font-size: 7.4cqw; font-weight: 800; line-height: 1.02; letter-spacing: -0.035em;
  text-wrap: balance; text-shadow: 0 2px 18px rgba(0, 0, 0, 0.6);
}
/* a gold rule with a diamond, under the name */
.tcg-title::before {
  content: ""; position: absolute; left: 0.2cqw; bottom: 0.05cqw; width: 1.5cqw; height: 1.5cqw;
  transform: rotate(45deg); background: var(--gold); box-shadow: 0 0 2cqw rgba(233, 207, 142, 0.6);
}
.tcg-title::after {
  content: ""; position: absolute; left: 3.2cqw; right: 0; bottom: 0.65cqw; height: 0.28cqw;
  background: linear-gradient(90deg, var(--gold), rgba(233, 207, 142, 0.3) 50%, transparent);
}
.tcg-meta {
  margin: 0; display: flex; align-items: center; flex-wrap: wrap; gap: 1cqw 2.6cqw;
  font-size: 2.55cqw; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--gold);
}
/* the age rating, on the gold frame at the bottom right, like a card's set symbol */
.tcg-age {
  position: absolute; right: 6cqw; bottom: 1.4cqw; z-index: 4; /* across the frame line, above the foil */
  display: grid; place-items: center; padding: 0.6cqw; border-radius: 1.2cqw;
  background: rgba(10, 9, 14, 0.92); /* just enough to break the frame line around it */
}
.tcg-age .age { display: block; height: 3.4cqw; width: auto; }
.tcg-age .age-text {
  font-size: 2.1cqw; font-weight: 700; letter-spacing: 0.06em; color: var(--gold); padding: 0 0.6cqw;
}
.tcg-meta span + span::before { content: "·"; margin-right: 2.6cqw; color: var(--ink-faint); }
.tcg-summary {
  margin: 0; font-size: 3.25cqw; line-height: 1.5; color: var(--ink-soft);
  display: -webkit-box; -webkit-line-clamp: 5; -webkit-box-orient: vertical; overflow: hidden;
}
.tcg-credits { margin: 0.6cqw 0 0; display: grid; gap: 1cqw; font-size: 2.8cqw; line-height: 1.35; }
.tcg-credits div { display: grid; grid-template-columns: 15cqw 1fr; gap: 2cqw; }
.tcg-credits dt { color: var(--ink-faint); font-size: 2.3cqw; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; padding-top: 0.3cqw; }
.tcg-credits dd { margin: 0; color: var(--ink); font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* the cast gets two lines, a little smaller, and breaks only between names */
.tcg-cast dd {
  white-space: normal; font-size: 2.45cqw; line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.tcg-cast .name { white-space: nowrap; }

/* ——— Holographic foil: rainbow bands, glitter and a glare, moving with the light ——— */
/* These are the light at rest, in the middle, as the cards behind show it: painted once with
   the card. The top card's light moves, drawn with WebGL in canvases over these (cardlight.js,
   which works out the same gradients and masks per pixel; keep the two in step). */
.tcg-foil, .tcg-glare { position: absolute; inset: 0; pointer-events: none; z-index: 3; border-radius: inherit; }
/* the foil: rainbow bands, 2.2 times the card so they slide with the light, shown where the light
   falls and faintly elsewhere, barely over the words. Their colours have the foil's look baked
   in: brightness(0.62) contrast(1.4) saturate(1.3) of hsl(350 95% 70%), hsl(40 95% 66%),
   hsl(110 85% 64%), hsl(185 95% 64%), hsl(235 95% 74%), hsl(295 90% 72%), so there's no filter */
.tcg-foil {
  background: repeating-linear-gradient(115deg,
    #c4203c 0%, #b47600 1.6%, #16a900 3.2%, #00a2b3 4.8%, #3642c4 6.4%, #b12cbd 8%, #c4203c 9.6%);
  background-size: 220% 220%;
  background-position: 50% 50%;
  mix-blend-mode: color-dodge;
  opacity: 0.25;
  -webkit-mask-image:
    radial-gradient(farthest-corner circle at 50% 50%, #000 0%, rgba(0, 0, 0, 0.5) 30%, rgba(0, 0, 0, 0.08) 65%),
    linear-gradient(to bottom, #000 35%, rgba(0, 0, 0, 0.35) 60%, rgba(0, 0, 0, 0.12));
  -webkit-mask-composite: source-in;
  mask-image:
    radial-gradient(farthest-corner circle at 50% 50%, #000 0%, rgba(0, 0, 0, 0.5) 30%, rgba(0, 0, 0, 0.08) 65%),
    linear-gradient(to bottom, #000 35%, rgba(0, 0, 0, 0.35) 60%, rgba(0, 0, 0, 0.12));
  mask-composite: intersect;
}
/* (the glitter shows only as the light moves: it's in cardlight.js alone) */
.tcg-glare {
  background: radial-gradient(farthest-corner circle at 50% 50%,
    rgba(255, 255, 255, 0.55) 0%, rgba(255, 255, 255, 0.16) 22%, rgba(0, 0, 0, 0.28) 90%);
  mix-blend-mode: overlay;
  opacity: 0.25;
}

/* the top card's light, from cardlight.js: canvases in the card, in place of its layers above */
.light-gl { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.light-foil, .light-glitter { z-index: 3; mix-blend-mode: color-dodge; }
.light-glare { z-index: 3; mix-blend-mode: overlay; }
.tcg.gl :is(.tcg-foil, .tcg-glare, .tcg-frame) { visibility: hidden; }
.tcg.lit .tcg-tilt, .tcg.lit .seal-shine::before { will-change: transform; } /* moved as the light moves */

/* ——— Below the stack ——— */
/* the arrows and the count, under the buttons (a little closer to them: -6px); "Back to the start"
   is placed from here (.deck-lap) */
.deck-nav {
  position: relative; margin-top: -6px;
  display: flex; flex-direction: column; align-items: center; gap: 8px; color: var(--ink-faint); font-size: 0.85rem; font-weight: 500; font-variant-numeric: tabular-nums;
}
/* with the showtimes taking the screen, the controls go (keeping their room, so nothing moves):
   their close button brings the cards back */
.deck-nav, .deck-actions { transition: opacity .3s var(--ease), visibility 0s, translate .45s var(--set-off); will-change: opacity; } /* (see .tcg's will-change; translate: the filter's line, see .next-show) */
.times-cover.showing-times :is(.deck-nav, .deck-actions) { opacity: 0; visibility: hidden; transition: opacity .3s var(--ease), visibility 0s .3s, translate .45s var(--set-off); }
.deck-button {
  display: grid; place-items: center; padding: 0;
  width: 38px; height: 38px; border-radius: 50%; cursor: pointer;
  border: 1px solid rgba(255, 255, 255, 0.14); background: rgba(255, 255, 255, 0.04);
  color: var(--ink-soft);
  transition: background .2s, border-color .2s, color .2s, transform .2s var(--ease);
}
/* the arrows: a square's two sides, turned to a point. Turned, the drawn shape sits to one side of
   the square's middle, so it's moved back by --shift to sit in the button's centre, by its shape
   rather than its box (measured, with the lines' thickness: about 0.28 of its size) */
.chevron {
  --size: 9px;
  --shift: calc(var(--size) * 0.28);
  width: var(--size); height: var(--size);
  border-left: 1.8px solid currentColor; border-bottom: 1.8px solid currentColor;
  transform: translateX(var(--shift)) rotate(45deg);
}
.chevron-next { transform: translateX(calc(-1 * var(--shift))) rotate(-135deg); }
/* (hovers only where there's a pointer to hover: on a phone, a tapped button would keep it) */
@media (hover: hover) { .deck-button:hover { background: rgba(255, 255, 255, 0.1); border-color: rgba(255, 255, 255, 0.28); color: var(--ink); } }
.deck-count { min-width: 64px; text-align: center; }
.deck-sort { display: none; color: var(--ink-soft); white-space: nowrap; } /* (wider, its own button says it in words, at the top) */
@media (max-width: 740px), (orientation: landscape) and (max-height: 499px) { .deck-sort:not([hidden]) { display: inline; } }
.deck-count:has([data-total]:empty), .own-picks .deck-count { visibility: hidden; } /* until cards.js has counted your films (with your own preferences, the served count may not be yours) */

/* ——— Actions under the controls: Trailer and Showtimes ———
   Quiet glass, with Showtimes filled: it's what you're here for. Colour is left to the icons
   (YouTube's red), which a tinted button fought. */
.deck-actions { position: relative; display: flex; gap: 10px; } /* (relative: your shortlist's bookmark beside them, .deck-save) */
/* round from the last film to the first: said a moment under the count, taking no room */
.deck-lap {
  position: absolute; top: calc(100% + 10px); left: 50%; translate: -50% -4px;
  display: flex; align-items: center; gap: 6px; white-space: nowrap;
  padding: 5px 12px 5px 10px; border-radius: 99px;
  background: rgba(255, 255, 255, 0.07); color: var(--ink-soft); font-size: 0.78rem; font-weight: 600;
  opacity: 0; pointer-events: none;
  transition: opacity .4s var(--ease), translate .4s var(--ease);
  will-change: opacity; /* (see .tcg's will-change) */
}
.deck-lap.shown { opacity: 1; translate: -50% 0; transition-duration: .25s; }
.icon-lap { font-size: 0.95rem; line-height: 1; color: var(--accent); }
.deck-action {
  display: inline-flex; align-items: center; gap: 10px; cursor: pointer;
  padding: 10px 20px 10px 16px; border-radius: 99px;
  border: 1px solid rgba(255, 255, 255, 0.16); background: rgba(255, 255, 255, 0.06);
  color: var(--ink); font-size: 0.88rem; font-weight: 600;
  transition: background .2s, border-color .2s, color .2s, opacity .3s, box-shadow .2s, filter .2s, transform .2s var(--ease);
}
.deck-action[data-showtimes-open] {
  border-color: transparent; background: var(--accent-grad); color: var(--on-accent);
  box-shadow: 0 8px 24px -10px color-mix(in srgb, var(--accent) 70%, transparent);
}
@media (hover: hover) {
  .deck-action:hover { background: rgba(255, 255, 255, 0.1); border-color: rgba(255, 255, 255, 0.26); }
  .deck-action[data-showtimes-open]:hover { background: var(--accent-grad); filter: brightness(1.1); }
}
.deck-action.none { opacity: 0; pointer-events: none; } /* nothing to show: gone, without moving anything */
.yt { flex: none; width: 19px; height: 13.5px; } /* YouTube's mark, as is: its red and white */
/* a clapperboard, in the text's colour: the image is just its shape (a mask), 96 × 92 */
.clapper {
  flex: none; width: 16px; height: 15.3px; background: currentColor;
  -webkit-mask: url("/static/clapper.png") center / contain no-repeat;
  mask: url("/static/clapper.png") center / contain no-repeat;
}

/* ——— Showtimes: the cards move left and this view slides in beside them, as tall as a card; the
   controls stay where they are. On a narrow screen, the cards go out of sight and this has the
   screen (see placeTimes). ——— */
.showing-times .stack { transform: translateX(calc(-1 * var(--shift, 0px))); } /* see placeTimes */
/* the cards, which beside the showtimes shrink toward them where the room's short (--deck-scale,
   from placeTimes), in step with the stack's slide: toward their bottom right corner, so their foot
   stays above the buttons below and their top comes down (clear of the corner's buttons, if need
   be). Above the showtimes (a card dragged over them stays on top), but under them where they take
   the screen. */
.deck {
  position: absolute; inset: 0; z-index: 1001; transform-origin: 100% 100%;
  transition: transform .6s var(--set-off), opacity .4s var(--ease); will-change: transform; /* (see .tcg's will-change) */
}
.showing-times .deck { transform: translateY(calc(-1 * var(--deck-lift, 0px))) scale(var(--deck-scale, 1)); } /* (lifted back up to the middle where there's room: placeTimes) */
/* under the card (cards.html's .deck-nav): the arrows either side of where you are among the films
   (.deck-place), the top card's group's heading under it (cards.js's sayGroup), the grid's own,
   smaller; then the count. All of it as wide as the card, moved aside with it for the showtimes */
.deck-place-row { display: flex; align-items: center; gap: 12px; width: var(--card-w); }
.table:not(.grid-mode) .deck-nav { margin-top: -27px; gap: 0; } /* (the bar 26px under the card, the heading 12px under the bar, the count 4px under that) */
.deck-nav .deck-count { margin-top: 4px; }
.deck-group { display: flex; justify-content: center; min-height: 1.6em; margin-top: -4px; } /* (close under the bar, its label: the arrows' row is taller than the bar) */
.grid-mode .deck-group, .table.empty .deck-group { display: none; }
.deck-group .grid-group { position: static; margin: 0; padding: 0; clip-path: none; animation: none; font-size: 1rem; white-space: nowrap; }
.deck-group .grid-group::after { display: none; }
/* where the top card is among those showing (cards.js's sayPlace): a bar of the sort's groups, each
   as long as it's large, the top card's lit (What's Hot's top band in its fire), a dot at its
   place; as wide as the card, under it, moved aside with it for the showtimes */
.deck-place { position: relative; flex: 1; display: flex; gap: 3px; height: 6px; }
.grid-mode .deck-place, .table.empty .deck-place { display: none; }
.deck-place-group { height: 100%; border-radius: 3px; background: rgba(255, 255, 255, 0.14); transition: background .25s; }
.deck-place-group.on { background: rgba(255, 255, 255, 0.42); }
.deck-place-group.on.on-fire { background: linear-gradient(90deg, #ff7a2f, #ffc24a); }
.deck-place-group.on.on-soon { background: var(--soon); box-shadow: 0 0 8px color-mix(in srgb, var(--soon) 60%, transparent); } /* (Up Next's Starting soon, in its green) */
.deck-place-group.on.on-gold { background: linear-gradient(90deg, #c99a3c, #fff0c2, #e9cf8e); } /* (Top Rated's top tier, in its gold) */
.deck-place-dot {
  position: absolute; top: 50%; width: 12px; height: 12px; margin: -6px 0 0 -6px; border-radius: 50%;
  background: var(--ink); box-shadow: 0 0 0 2.5px rgba(10, 9, 12, 0.95), 0 1px 5px rgba(0, 0, 0, 0.6);
  transition: left .35s var(--ease);
}
/* a press jumps, a drag runs through the films (cards.js's placeAt): answering a little above and
   below its line, a finger's drag not scrolling the page; the dot bigger on it, and quick to follow
   a drag */
.deck-place { cursor: pointer; touch-action: none; }
.deck-place::before { content: ""; position: absolute; inset: -10px 0; }
.deck-place-dot { pointer-events: none; transition: left .35s var(--ease), scale .15s var(--ease); }
@media (hover: hover) { .deck-place:hover .deck-place-dot { scale: 1.25; } }
.deck-place.dragging .deck-place-dot { scale: 1.35; transition: scale .15s var(--ease); } /* (dragged, right under the pointer: no easing behind it) */
@media (prefers-reduced-motion: reduce) { .deck-place-dot { transition: none; } }
.times-cover .deck { z-index: 999; }
.times-cover.showing-times .deck { opacity: 0; } /* (gone for the showtimes: a phone on its side, its card narrow, didn't slide far enough) */
/* just text beside the card, on the page itself: no panel */
.times-view {
  position: absolute; top: 0; left: calc(100% + var(--times-gap)); z-index: 1000; /* above any card (cards.js's Z_LIMIT) */
  width: var(--times-w); height: 100%;
  display: flex; flex-direction: column;
  transform: translateX(100vw); opacity: 0;
  transition: transform .6s var(--set-off), opacity .45s var(--ease);
  contain: layout style; /* redrawing the times doesn't touch the page around them (not paint: seat tips reach out) */
  will-change: transform, opacity; /* (see .tcg's will-change) */
}
.showing-times .times-view { transform: none; opacity: 1; }
.table:not(.times-cover) .times-view { top: var(--times-drop, 0px); height: calc(100% - var(--times-drop, 0px)); } /* (clear of the top right buttons: placeTimes) */
/* taking the screen (narrow): from a margin below the top to one above the bottom, clear of any
   notch or home bar (--times-top, --times-h: see placeTimes) */
.times-cover .times-view {
  top: calc(var(--times-top, 0px) + env(safe-area-inset-top));
  height: calc(var(--times-h, 100%) - env(safe-area-inset-top) - env(safe-area-inset-bottom));
  transition: transform .6s var(--set-off), opacity .45s var(--ease), translate .45s var(--set-off); /* (translate: moved down under the grid's trailer, docked at the top: see .screen) */
}
/* two pages side by side: the times, then a show's seat map, sliding across */
/* they reach 10px past each side, padded back in, so a time's highlight isn't clipped at the edge */
.times-pages { position: relative; flex: 1; min-height: 0; display: flex; overflow: clip; margin: 0 -10px; will-change: transform, opacity; } /* clip: can't be scrolled sideways, e.g. by focus; will-change: turned like a page (pageTimes; see .tcg's will-change) */
.times-body {
  position: relative; /* for the touch screens' bounce, below */
  will-change: transform; /* slides aside for a seat map (see .tcg's will-change) */
  flex: 0 0 100%; min-width: 0; /* exactly the view's width, whatever's inside */
  overflow-y: auto; scrollbar-width: none;
  padding: 6px 12px 48px; /* room to scroll the last row clear of the fade */
  display: grid; align-content: start; gap: 20px;
  grid-auto-rows: max-content; /* each part its full height, even when the list overflows */
  transition: transform .45s var(--set-off); /* a seat map slides in, the times out: a big move from rest */
  /* fades out at the bottom, so it's clear there's more to scroll to */
  -webkit-mask-image: linear-gradient(#000 calc(100% - 48px), transparent);
  mask-image: linear-gradient(#000 calc(100% - 48px), transparent);
}
.times-body::-webkit-scrollbar { display: none; }
/* the showtimes' page (a film's, or your shortlist's): its head stays, its name, scores and days
   (.st-head), and the rest scrolls under it (.st-scroll: cards.js's layTimes), so another day's a
   tap away however far down, and nothing passes under the panel's buttons; scrolled, the times
   fade out under the days. (The seat page scrolls whole, as before.) */
.times-body:not(.seat-page) { overflow: hidden; display: flex; flex-direction: column; padding-bottom: 0; -webkit-mask-image: none; mask-image: none; }
.st-head { flex: none; display: grid; gap: 20px; }
.st-scroll {
  position: relative; flex: 1; min-height: 0; overflow-y: auto; scrollbar-width: none;
  margin: 0 -12px; padding: 0 12px 48px; /* (the page's sides, for a time's highlight; room to scroll the last row clear of the fade) */
  display: grid; align-content: start; gap: 20px; grid-auto-rows: max-content;
  --fade-end: 48px;
  -webkit-mask-image: linear-gradient(#000 calc(100% - var(--fade-end)), transparent);
  mask-image: linear-gradient(#000 calc(100% - var(--fade-end)), transparent);
}
.st-scroll.scrolled {
  -webkit-mask-image: linear-gradient(transparent, #000 20px, #000 calc(100% - var(--fade-end)), transparent);
  mask-image: linear-gradient(transparent, #000 20px, #000 calc(100% - var(--fade-end)), transparent);
}
.st-scroll::-webkit-scrollbar { display: none; }
/* on a touch screen, a short list still moves under your finger and springs back, like a phone's
   own lists: Safari only bounces what overflows, so it's always a pixel taller than its box */
@media (pointer: coarse) {
  :is(.times-body, .st-scroll)::before { content: ""; position: absolute; top: 0; left: 0; width: 1px; height: calc(100% + 1px); pointer-events: none; }
}
.seat-mode .times-body { transform: translateX(-100%); }
.times-view.jump .times-body { transition: none; } /* turning to another film's times (cards.js) */
/* round icon buttons (close ×), their icons drawn as lines so they sit dead centre */
.times-close, .trailer-close {
  display: grid; place-items: center; padding: 0; width: 34px; height: 34px; border-radius: 50%; cursor: pointer;
  border: 1px solid rgba(255, 255, 255, 0.16); background: rgba(255, 255, 255, 0.05); color: var(--ink-soft);
  transition: background .2s, color .2s, transform .2s var(--ease);
}
@media (hover: hover) { .times-close:hover, .trailer-close:hover { background: rgba(255, 255, 255, 0.14); color: var(--ink); } }
.icon-back.icon-forward { transform: rotate(-135deg); margin: 0 3px 0 0; } /* the back chevron, turned to point right */
.times-close { position: absolute; top: calc(6px + (1.5rem * 1.1 - 34px) / 2); right: 0; z-index: 1; } /* centred on the title's line (the times' 6px top padding, then its 1.5rem × 1.1 line) */
.icon-close { position: relative; width: 14px; height: 14px; }
.icon-close::before, .icon-close::after {
  content: ""; position: absolute; left: 0; top: calc(50% - 0.8px); width: 100%; height: 1.6px;
  border-radius: 1px; background: currentColor; transform: rotate(45deg);
}
.icon-close::after { transform: rotate(-45deg); }
.icon-back { /* a chevron, nudged right so it looks centred */
  width: 8px; height: 8px; margin-left: 3px;
  border-left: 1.7px solid currentColor; border-bottom: 1.7px solid currentColor; transform: rotate(45deg);
}
/* open: a ring around Showtimes (it's always filled) */
.deck-action[aria-expanded="true"] {
  box-shadow: 0 0 0 2px var(--bg), 0 0 0 3.5px color-mix(in srgb, var(--accent) 80%, transparent), 0 8px 24px -10px color-mix(in srgb, var(--accent) 70%, transparent);
}

.st-title { margin: 0; padding-right: 44px; font-size: 1.5rem; font-weight: 800; letter-spacing: -0.03em; line-height: 1.1; }

/* the days: just their names, the chosen one underlined in the accent */
/* the days as a strip, a short name over the day of the month ("Tmrw" over "15"), sharing the
   width: a week listed fits across a phone with nothing out of sight. (A row of "Fri 16 Oct"s
   ran past the edge from the fifth day on.) */
.st-days { display: flex; gap: 4px; overflow-x: auto; scrollbar-width: none; border-bottom: 1px solid rgba(255, 255, 255, 0.08); }
.st-days::-webkit-scrollbar { display: none; }
.st-day {
  flex: 1 1 0; min-width: 44px; max-width: 76px; cursor: pointer; padding: 4px 0 9px; margin-bottom: -1px;
  display: grid; justify-items: center; gap: 1px;
  border: 0; border-bottom: 2px solid transparent; background: none;
  color: var(--ink-faint); font-weight: 600;
  transition: color .2s, border-color .2s;
}
.st-day-name { font-size: 0.64rem; letter-spacing: 0.1em; text-transform: uppercase; }
.st-day-num { font-size: 1.1rem; line-height: 1.2; font-variant-numeric: tabular-nums; }
.st-days.single .st-day { flex: none; padding-inline: 4px; cursor: default; pointer-events: none; } /* the only day: just its own width, and a label, nothing to switch to */
@media (hover: hover) { .st-day:hover { color: var(--ink); } }
.st-day[aria-selected="true"] { color: var(--ink); border-image: var(--accent-grad) 1; border-bottom-color: var(--accent); }
.st-panel { display: grid; animation: fade .3s var(--ease); }
/* each format in bold, then its times, one to a row */
.st-row { display: grid; gap: 6px; padding: 10px 0 1px; border-top: 1px solid rgba(255, 255, 255, 0.07); } /* (1px under: the last time has its own 9px under it, for its highlight, so it's as far above the next line as the heading's below its own) */
.st-cinema-name + .st-row { border-top: 0; padding-top: 4px; }
/* each cinema's showtimes under its name, with more than one cinema picked; with one, no names */
.st-cinema-name {
  margin: 0 0 6px; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink-soft); /* (a label, as the grid's headings are; the gold's for what the film is) */
}
.one-cinema .st-cinema-name { display: none; }
/* each cinema's chain's logo before its name, in the name's colour: the images are just their
   shapes (masks), VOX's letters (176 × 67) and Reel's R (102 × 84) */
.st-chain {
  display: inline-block; margin-right: 0.6em; vertical-align: -1px; background: currentColor;
  -webkit-mask: var(--logo) left center / contain no-repeat;
  mask: var(--logo) left center / contain no-repeat;
}
.st-chain-vox { --logo: url("/static/chain-vox.png"); width: 26.3px; height: 10px; }
.st-chain-reel { --logo: url("/static/chain-reel.png"); width: 13.4px; height: 11px; }
.st-cinema:not([hidden]) ~ .st-cinema:not([hidden]) { margin-top: 4px; padding-top: 14px; border-top: 1px solid rgba(255, 255, 255, 0.14); }
.st-format { margin: 0; font-size: 1rem; font-weight: 700; color: var(--ink); letter-spacing: -0.01em; }
/* THEATRE, our own take on VOX's mark (it has no logo file): its geometric capitals, spaced, with
   the "EAT" (a dine-in cinema) stressed: semi-bold and a little brighter than the rest (halfway
   to white from the text's colour: on a chosen time, a lighter purple). A device's own geometric
   face: Avenir Next (Apple), Futura, Century Gothic (Windows); else the site's. (span.theatre: so a
   bold line it's in, as the seat page's, doesn't make its EAT bolder) */
.theatre { font-family: "Avenir Next", "Futura", "Century Gothic", "Inter", sans-serif; font-weight: 400; letter-spacing: 0.1em; }
span.theatre b { font-weight: 600; color: color-mix(in srgb, currentColor 50%, var(--ink)); }
/* THEATRE PODS: "IMAX (THEATRE)", THEATRE's seats within the IMAX show, its brackets faint */
.pods::before { content: "("; opacity: 0.6; }
.pods::after { content: ")"; opacity: 0.6; }
/* the IMAX logo in place of the word, as tall as capital letters */
.imax-logo { display: inline-block; height: 0.78em; width: auto; vertical-align: baseline; }
/* Dolby Cinema's one-line logo (1897 × 252, its "y" below the line: lowered by as much), in the
   text's colour: the image is just its shape (a mask) */
.dolby-cinema { white-space: nowrap; }
.dolby-logo {
  display: inline-block; height: 0.95em; width: calc(0.95em * 1897 / 252); vertical-align: -0.2em; background: currentColor;
  -webkit-mask: url("/static/dolby-cinema.svg") left center / contain no-repeat;
  mask: url("/static/dolby-cinema.svg") left center / contain no-repeat;
}
/* ScreenX's logo (227.6 × 32.3, all capitals: as tall as the text's) and 4DX's (1000 × 399.5, its X
   above the 4D: a little taller), in the text's colour, as Dolby's */
.room-logo { white-space: nowrap; }
.screenx-logo, .fourdx-logo { display: inline-block; background: currentColor; }
.screenx-logo {
  height: 0.68em; width: calc(0.68em * 227.63 / 32.32); vertical-align: 0;
  -webkit-mask: url("/static/screenx.svg") left center / contain no-repeat;
  mask: url("/static/screenx.svg") left center / contain no-repeat;
}
.fourdx-logo {
  height: 0.9em; width: calc(0.9em * 1000 / 399.48); vertical-align: -0.12em;
  -webkit-mask: url("/static/4dx.svg") left center / contain no-repeat;
  mask: url("/static/4dx.svg") left center / contain no-repeat;
}
.st-times { display: grid; font-variant-numeric: tabular-nums; }
/* the two orders of a film's showtimes, under the days (cards.js's orderSwitch): small pills, as the filter's chips */
.st-order { display: flex; gap: 6px; margin-top: -8px; }
.st-order-pick {
  padding: 5px 12px; border-radius: 99px; border: 1px solid rgba(255, 255, 255, 0.12); background: none; cursor: pointer;
  font: inherit; font-size: 0.78rem; font-weight: 600; color: var(--ink-soft); transition: background .15s, color .15s;
}
@media (hover: hover) { .st-order-pick:hover { background: rgba(255, 255, 255, 0.06); } }
.st-order-pick[aria-pressed="true"] { border-color: transparent; background: var(--ink); color: rgb(18, 17, 24); }
/* By time: a row a time, no headings: the time and how soon on its first line, its room and
   (with several picked) its cinema small under the time: "Premier · VOX MOE" (each its own cinema
   and room: cards.js's flatten) */
.st-one { margin: 0 !important; padding: 0 !important; border: 0 !important; } /* (not as a cinema of its own) */
.st-one .st-row { padding: 0; border: 0; gap: 0; }
.st-one, .st-one :is(.st-row, .st-times) { min-width: 0; } /* (the panel's width, not their content's: the room and cinema give way) */
.st-one .st-format { display: none; } /* (there for what reads a time's format: said under its time) */
.st-one:not([hidden]) ~ .st-one .st-time { box-shadow: 0 -1px 0 rgba(255, 255, 255, 0.04); } /* (a line between, as between a room's times) */
.st-one .st-time { flex-wrap: wrap; row-gap: 1px; padding-block: 8px 9px; }
/* the second line: last, the row's width, and in by the dot and its gap, so it starts under the time */
.st-where {
  order: 1; flex: 0 0 100%; min-width: 0; padding-left: calc(9px + 10px); box-sizing: border-box;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 0.8rem; line-height: 1.3; color: var(--ink-faint);
}
.st-where .imax-logo { opacity: 0.7; }
/* how a checked show suited you takes the room left on the first line, with an "…" if it needs more:
   the countdown stays at its end (sized from 0, the line never wraps for it) */
.st-one .st-fit { flex: 1 1 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.st-one .st-when { flex: none; }
.one-cinema .st-where-cinema { display: none; }
@media (max-width: 420px) { .st-where { padding-left: calc(9px + 8px); } } /* (a phone's narrower gap) */
/* a row: the time on the left, its countdown (if any) on the right; the whole row is the button */
.st-time {
  display: flex; align-items: center; gap: 10px; padding: 9px 10px; margin: 0 -10px; width: calc(100% + 20px); /* its highlight reaches past the text */
  border: 0; border-radius: 8px; background: none; cursor: pointer; text-align: left;
  font: inherit; font-size: 0.98rem; color: rgba(244, 241, 234, 0.9);
  transition: background .15s, color .15s;
}
.st-time + .st-time { box-shadow: 0 -1px 0 rgba(255, 255, 255, 0.04); }
.st-time:focus-visible { background: color-mix(in srgb, var(--accent) 12%, transparent); color: var(--accent); outline-offset: -2px; } /* (the ring inside: the panel's edge would cut it) */
@media (hover: hover) { .st-time:hover { background: color-mix(in srgb, var(--accent) 12%, transparent); color: var(--accent); } }
.st-time.chosen { background: color-mix(in srgb, var(--accent) 20%, transparent); color: var(--accent); }
/* back from its seat map, the time it was: lit as it was, a moment, then fading (cards.js's showWhere) */
.st-time.was-here { animation: was-here 1.6s ease-out; }
@keyframes was-here { 0%, 35% { background: color-mix(in srgb, var(--accent) 20%, transparent); } }
/* the next show and any just started get a dot and a countdown (see cards.js); the dot keeps
   its place on every row, so the times line up */
.st-dot { position: relative; flex: none; width: 9px; height: 9px; border-radius: 50%; opacity: 0; pointer-events: none; background: var(--pulse); }
.st-when { margin-left: auto; font-size: 0.82rem; color: var(--ink-soft); } /* how soon, as the grid's preview says it: "in 20 min", "trailers playing" */
/* a rough how soon, another day ("in 3 days"), in a chip, like Discord's timestamps: the plain ones are to the minute */
:is(.st-when, .info-show-when) code {
  padding: 1px 5px; border-radius: 4px; background: rgba(255, 255, 255, 0.08);
  font: inherit; color: rgba(244, 241, 234, 0.72);
}
/* about when it lets out, after the start: quieter, so the starts still read down the list */
.st-end { margin-left: -4px; color: rgba(244, 241, 234, 0.55); font-size: 0.88rem; } /* (0.55: AA's 4.5:1 on the dark) */
.st-end, .st-when { white-space: nowrap; } /* each whole, never split over two lines */
@media (max-width: 420px) { /* a phone: a show just started has its end and its countdown too */
  .st-time { gap: 8px; }
  .st-end { margin-left: -3px; font-size: 0.8rem; }
  .st-when { font-size: 0.78rem; }
}
.st-time.soon .st-dot { --pulse: var(--soon); }
.st-time.now .st-dot { --pulse: var(--now); }
.st-time.soon .st-dot, .st-time.now .st-dot { opacity: 1; }
/* a late show (starting after midnight, or out at 1AM or later: funcs.go's lateNight) without a
   pulse: a crescent moon in its dot's place, quiet; so in the preview's, and by a seat map's time */
:root { --moon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20.5 14.6A8.5 8.5 0 0 1 9.4 3.5a8.5 8.5 0 1 0 11.1 11.1Z'/%3E%3C/svg%3E"); --moon-ink: #9fb3d9; }
.st-time[data-night]:not(.soon, .now) .st-dot, .info-show.night .info-show-dot, .seat-time.night::before {
  background: var(--moon-ink); box-shadow: none; border-radius: 0;
  -webkit-mask: var(--moon) center / contain no-repeat; mask: var(--moon) center / contain no-repeat;
}
.st-time[data-night]:not(.soon, .now) .st-dot { opacity: 1; scale: 1.35; }
.info-show.night .info-show-dot { opacity: 1; scale: 1.5; }
.seat-time.night::before { content: ""; display: inline-block; width: 0.5em; height: 0.5em; margin-right: 0.3em; vertical-align: 0.3em; }
/* an early show (before 11AM: funcs.go's earlyBird) without a pulse: a sunrise, a half sun on the
   horizon, in the morning's warm colour, as the moon is */
:root { --sunrise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6.5 17a5.5 5.5 0 0 1 11 0Z'/%3E%3Cpath d='M2.5 19.5h19' stroke='black' stroke-width='1.9' stroke-linecap='round'/%3E%3Cpath d='M12 8.2V5.6M6.1 10.6 4.3 8.8M17.9 10.6l1.8-1.8M3.4 15.2H1.8M20.6 15.2h1.6' stroke='black' stroke-width='1.9' stroke-linecap='round'/%3E%3C/svg%3E"); --sunrise-ink: #e8c48a; }
.st-time[data-early]:not(.soon, .now) .st-dot, .info-show.early .info-show-dot, .seat-time.early::before {
  background: var(--sunrise-ink); box-shadow: none; border-radius: 0;
  -webkit-mask: var(--sunrise) center / contain no-repeat; mask: var(--sunrise) center / contain no-repeat;
}
.st-time[data-early]:not(.soon, .now) .st-dot { opacity: 1; scale: 1.5; }
.info-show.early .info-show-dot { opacity: 1; scale: 1.7; }
.seat-time.early::before { content: ""; display: inline-block; width: 0.55em; height: 0.55em; margin-right: 0.3em; vertical-align: 0.25em; }
/* (shown by opacity, not visibility: a visible dot in a hidden page, as under a seat map or a
   film's preview, would still take a click; and none takes one: it's the row's) */
/* the pulse: a ring of the dot's colour, growing and fading; scaled and faded rather than drawn
   bigger, so the graphics chip does it without repainting */
.st-dot::after {
  content: ""; position: absolute; left: 0; top: 0; width: 100%; height: 100%; border-radius: 50%;
  background: var(--pulse); opacity: 0;
}
.st-time:is(.soon, .now) .st-dot::after { animation: pulse 1.8s ease-out infinite; }
/* the other green and red dots (a grid caption's, the line under a card), each its
   line's ::before, first in it, pulse as these do: a ring over the dot (::after, placed where the dot
   is: --dot, its size), growing and fading (the preview's, .info-show-dot, as the showtimes' do) */
:is(.tile-when, .next-show):is(.soon, .now) { position: relative; --pulse: var(--soon); }
:is(.tile-when, .next-show).now { --pulse: var(--now); }
:is(.tile-when, .next-show):is(.soon, .now)::after {
  content: ""; position: absolute; left: var(--dot-x, 0px); top: 50%; width: var(--dot); height: var(--dot);
  margin-top: calc(var(--dot) / -2); border-radius: 50%; background: var(--pulse); opacity: 0; pointer-events: none;
  animation: pulse 1.8s ease-out infinite;
}
/* a small seat after a time whose seat map you've looked at: a cushion with its backrest, as on the maps */
/* checked within the hour, how it suited your party, after the seat: "Good seats" in the accent,
   the rest quieter; with none together, the seat's an outline, as a taken one is on the maps */
.st-fit { margin-left: -3px; font-size: 0.8rem; color: var(--ink-faint); white-space: nowrap; }
.st-fit { display: none; } /* (for now the rows say how full a show is instead: .st-full; how it suits your party is still on its seat map) */
/* how full a show was when you checked it, within the hour (cards.js's sayFull): a chip after its
   end time, green under half full, blue, then red from 70% */
.st-full {
  flex: none; padding: 2px 6px; border-radius: 5px; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.16);
  font-size: 0.68rem; font-weight: 500; letter-spacing: 0.02em; line-height: 1.25; color: var(--ink-soft);
  white-space: nowrap; font-variant-numeric: tabular-nums;
}
.st-time[data-full="low"] .st-full { color: var(--full-low); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--full-low) 42%, transparent); }
.st-time[data-full="mid"] .st-full { color: var(--full-mid); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--full-mid) 42%, transparent); }
.st-time[data-full="most"] .st-full { color: var(--full-most); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--full-most) 45%, transparent); }
/* By time: on the second line, under the countdown; the room and cinema stop short of it */
.st-one .st-time[data-full] { position: relative; }
.st-one .st-full { position: absolute; right: 10px; bottom: 9px; }
.st-one .st-time:not(:has(.st-when)) .st-full { bottom: auto; top: 50%; translate: 0 -50%; } /* (no countdown above it: in the middle of the row) */
.st-one .st-time[data-full] .st-where { padding-right: calc(19px + 6.5em); }
.st-time.full-old .st-full { opacity: 0.5; } /* (checked over an hour ago: "was 81% full") */
.st-screens { font-size: 0.8rem; color: var(--ink-faint); white-space: nowrap; } /* (one time in several screens: its seat map steps through them) */
.st-time[data-fit="good"] .st-fit { color: color-mix(in srgb, var(--accent) 85%, transparent); }

/* ——— A show's seat map, the second page ——— */
/* the head: "‹ Showtimes" (back) on the first line, beside the close button; then the format and
   day; then the time, with chevrons either side to step to the show before or after */
.seat-head { display: grid; justify-items: start; gap: 4px; }
.seat-back {
  display: inline-flex; align-items: center; gap: 8px; min-height: 34px; margin-bottom: 6px; padding: 0 4px 0 0;
  border: 0; background: none; cursor: pointer; color: var(--accent); font: inherit; font-size: 0.86rem; font-weight: 600;
}
.seat-back .icon-back { margin-left: 2px; }
/* back to the films: on a phone, where the showtimes have the screen, in place of the × (a phone's
   way back is at the top left) */
.times-back { display: none; align-self: flex-start; }
.times-cover .times-back { display: inline-flex; }
/* one back link in one place: it says where it goes, and the seat map's own goes */
.times-back .to-times, .seat-mode .times-back .to-films { display: none; }
.seat-mode .times-back .to-times { display: inline; }
.times-cover [data-seat-back] { display: none; }
.times-cover .times-close { display: none; }
@media (hover: hover) { .seat-back:hover { color: var(--ink); } }
.seat-when { margin: 0; font-size: 0.82rem; color: rgba(244, 241, 234, 0.72); }
.seat-when b { font-weight: 800; }
/* in smaller text than a heading's (the seat page's line, a time's room and cinema, the preview's),
   centred on the capitals beside it (Inter's are 0.727em tall), as each logo is a little taller */
:is(.seat-when, .st-where, .info-show-format) .st-chain-vox { vertical-align: calc((0.727em - 10px) / 2); }
:is(.seat-when, .st-where, .info-show-format) .st-chain-reel { vertical-align: calc((0.727em - 11px) / 2); }
.seat-pick { display: flex; align-items: center; gap: 2px; margin-left: -8px; }
.seat-time { margin: 0; min-width: 5.2ch; text-align: center; font-size: 1.6rem; font-weight: 800; letter-spacing: -0.03em; line-height: 1.1; font-variant-numeric: tabular-nums; }
.seat-step { /* a quiet chevron in the time's colour */
  display: grid; place-items: center; width: 30px; height: 34px; padding: 0; border: 0; border-radius: 8px;
  background: none; color: rgba(244, 241, 234, 0.75); cursor: pointer; transition: background .15s, color .15s, opacity .2s, transform .2s var(--ease);
}
@media (hover: hover) { .seat-step:hover:not(:disabled) { background: rgba(255, 255, 255, 0.08); color: var(--ink); } }
.seat-step .icon-back { width: 10px; height: 10px; border-width: 2px; }
.seat-step:disabled { opacity: 0.2; cursor: default; } /* no earlier or later show that day */
/* under the time, how the show suits your party, and where they'd sit ("Good seats" / "F7–8");
   beside it, how many you are */
.seat-fit { display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%; margin-top: 4px; }
.seat-verdict { margin: 0; min-height: 2.6em; font-size: 0.86rem; line-height: 1.3; color: rgba(244, 241, 234, 0.6); transition: opacity .2s; }
.seat-verdict b { display: block; font-size: 0.95rem; font-weight: 700; color: var(--ink); }
.seat-verdict.fit-good b { color: var(--accent); }
.seat-also { display: block; margin-top: 2px; color: var(--ink-faint); } /* (a THEATRE's Group seat: sayFit) */
.seat-fit.loading .seat-verdict { opacity: 0.35; }
.seat-party {
  flex: none; display: inline-flex; align-items: center; padding: 2px; border-radius: 99px;
  border: 1px solid rgba(255, 255, 255, 0.14); background: rgba(255, 255, 255, 0.04);
}
.seat-party-count { min-width: 3.4em; text-align: center; font-size: 0.82rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.seat-party-step {
  display: grid; place-items: center; width: 36px; height: 36px; padding: 0; border: 0; border-radius: 50%;
  background: none; color: rgba(244, 241, 234, 0.75); cursor: pointer; transition: background .15s, color .15s, opacity .2s, transform .2s var(--ease);
}
@media (hover: hover) { .seat-party-step:hover:not(:disabled) { background: rgba(255, 255, 255, 0.08); color: var(--ink); } }
.seat-party-step:disabled { opacity: 0.25; cursor: default; }
.icon-minus, .icon-plus { position: relative; width: 11px; height: 11px; }
.icon-minus::before, .icon-plus::before, .icon-plus::after {
  content: ""; position: absolute; left: 0; top: calc(50% - 0.8px); width: 100%; height: 1.6px; border-radius: 1px; background: currentColor;
}
.icon-plus::after { transform: rotate(90deg); }
.seat-full-head .seat-verdict { min-height: 0; margin-top: 4px; }
/* a Reel show: no seat map (the site asks only VOX), but in its place its seats left, as the
   listings had them, and when that was (cards.js's sayLeft) */
.seat-page.no-map :is(.seat-map, .seat-legend) { display: none; }
.seat-left { padding: 18px 18px 16px; border-radius: 12px; background: rgba(8, 8, 12, 0.42); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.07); }
.seat-left-count { margin: 0; font-size: 0.95rem; font-weight: 600; color: var(--ink); }
.seat-left-count b { font-size: 1.6rem; font-weight: 800; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; color: var(--accent); }
.seat-left-note { margin: 6px 0 0; font-size: 0.82rem; line-height: 1.4; color: rgba(244, 241, 234, 0.6); }
/* the seat map, drawn as SVG by seatmap.js: on a dark glass panel, tinted warm for THEATRE */
.seat-map {
  position: relative; min-height: 180px; padding: 14px 10px 16px; border-radius: 12px; overflow: hidden;
  background: rgba(8, 8, 12, 0.42); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.07);
}
.seat-map-dining { background: rgba(28, 20, 14, 0.5); box-shadow: inset 0 0 0 1px rgba(255, 233, 196, 0.1); }
/* the usual look: straight on the page, no panel, in the cards' gold (not the controls' accent) */
.seat-map-standard { padding: 4px 0 0; background: none; box-shadow: none; border-radius: 0; overflow: visible; }
.seats-standard .seats-screen-word { fill: rgba(233, 207, 142, 0.6); letter-spacing: 0.4em; }
.seats-standard .seats-row { fill: rgba(233, 207, 142, 0.55); } /* (readable: see .seats-row) */
.seats-standard .seat { cursor: pointer; }
@media (hover: hover) { .seats-standard .seat:hover { opacity: 1; filter: brightness(1.18); } }
.seat-map:is(.loading, .stepping) { cursor: progress; }
.seat-map.stepping .seats-svg { opacity: 0.35; transition: opacity .2s; } /* the show stepped from, until this one's in */
/* the best seats together for your party: a soft tile under them, ringed */
.seats-best { fill: rgba(255, 255, 255, 0.1); stroke: rgba(255, 255, 255, 0.8); stroke-width: 1.4; animation: fade .3s var(--ease); }
.seats-svg { display: block; width: 100%; height: auto; max-height: 52svh; animation: fade .4s var(--ease); }
.seats-svg text { font-family: "Inter", system-ui, sans-serif; }
.seats-screen-word { font-size: 7.5px; font-weight: 600; letter-spacing: 0.3em; fill: rgba(244, 241, 234, 0.5); }
.seats-zone { font-size: 7.5px; font-weight: 600; letter-spacing: 0.4em; opacity: 0.75; } /* a Reel room's area, over its rows: in its colour (seatmap.js) */
.seats-row { font-size: 9px; font-weight: 600; fill: rgba(244, 241, 234, 0.55); } /* (the rows' letters say where the seats are: readable, 4.5:1) */
.seats-pod { fill: rgba(255, 255, 255, 0.045); }
.seats-food { font-family: "Noto Emoji", sans-serif !important; font-size: 13.5px; fill: rgba(255, 255, 255, 0.19); }
.seat { transition: opacity .15s; }
@media (hover: hover) { .seat:hover { opacity: 0.8; } }
@font-face { font-family: "Noto Emoji"; src: url("/static/fonts/NotoEmoji-food.woff") format("woff"); font-display: swap; }

/* its legend: each area with its price, and taken */
.seat-legend { display: flex; align-items: center; gap: 6px 12px; margin-top: -8px; } /* (its text centred on the expand button, beside it however many lines it takes) */
.seat-legend .seats-legend-text { flex: 1 1 0; min-width: 0; }
.seats-price { font-weight: 500; color: rgba(244, 241, 234, 0.6); }
/* a line of text, like the showtimes, its keys spaced apart (every look's: THEATRE's and Kids' too) */
.seats-legend-text { margin: 0; display: flex; flex-wrap: wrap; align-items: center; column-gap: 18px; font-size: 0.86rem; line-height: 1.8; color: rgba(244, 241, 234, 0.85); }
.seats-key { white-space: nowrap; }
.seats-dot { display: inline-block; width: 9px; height: 9px; margin-right: 7px; border-radius: 50%; vertical-align: 0; }
.seats-dot.taken { box-shadow: inset 0 0 0 1.5px rgba(233, 207, 142, 0.35); }
.seats-wheelchair-key { width: 13px; height: 13px; margin-right: 6px; vertical-align: -2px; overflow: visible; }

/* the expand button, at the end of the legend's line (cards.js: on the map, it covered seats) */
.seat-expand {
  position: relative; margin-left: auto;
  display: grid; place-items: center; width: 30px; height: 30px; padding: 0; border-radius: 50%; cursor: pointer;
  border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent); background: rgba(12, 11, 14, 0.7); color: var(--accent);
  transition: background .2s, border-color .2s, transform .2s var(--ease);
}
@media (hover: hover) { .seat-expand:hover { background: color-mix(in srgb, var(--accent) 18%, transparent); border-color: var(--accent); } }
.icon-expand { /* four corners, pointing out */
  width: 12px; height: 12px;
  --c: currentColor;
  background:
    linear-gradient(var(--c), var(--c)) 0 0 / 4.5px 1.6px, linear-gradient(var(--c), var(--c)) 0 0 / 1.6px 4.5px,
    linear-gradient(var(--c), var(--c)) 100% 0 / 4.5px 1.6px, linear-gradient(var(--c), var(--c)) 100% 0 / 1.6px 4.5px,
    linear-gradient(var(--c), var(--c)) 0 100% / 4.5px 1.6px, linear-gradient(var(--c), var(--c)) 0 100% / 1.6px 4.5px,
    linear-gradient(var(--c), var(--c)) 100% 100% / 4.5px 1.6px, linear-gradient(var(--c), var(--c)) 100% 100% / 1.6px 4.5px;
  background-repeat: no-repeat;
}

/* the seat map, large */
.seat-full {
  width: min(1240px, 96vw); height: min(920px, 92svh); max-width: none; max-height: none;
  padding: 0; border: 0; border-radius: 22px; color: var(--ink);
  background: radial-gradient(100% 50% at 50% 0%, color-mix(in srgb, var(--accent) 9%, transparent), transparent 60%), linear-gradient(rgba(17, 16, 24, 0.98), rgba(9, 9, 13, 0.99));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 25%, transparent), 0 50px 140px rgba(0, 0, 0, 0.85);
}
.seat-full[open] { display: flex; flex-direction: column; animation: rise .35s var(--ease); }
.seat-full::backdrop { background: rgba(4, 4, 6, 0.7); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
.seat-full-head { position: relative; padding: 22px 26px 6px; padding-right: 70px; }
.seat-full-head .times-close { top: 20px; right: 22px; }
.seat-full-head .seat-time { min-width: 0; text-align: left; } /* no arrows here, so no need to centre it */
.seat-full-map { position: relative; flex: 1; min-height: 0; overflow: auto; padding: 8px 26px; display: grid; place-items: center; }
.seat-full-map .seats-svg { width: 100%; height: 100%; max-height: none; }
.seat-full-map.seat-map-dining { background: none; box-shadow: none; }
.seat-full-legend { display: flex; flex-wrap: wrap; gap: 6px; padding: 8px 26px 22px; }

/* a seat's label, over it on hover or tap: "E-6  Regular · 50 AED" (on the seat page, or the large view) */
.seat-page { position: relative; gap: 14px; } /* (closer than the times: a THEATRE's map and Book fit beside the cards at 1280×800) */
.seat-tip {
  position: absolute; z-index: 5; transform: translate(-50%, -100%); pointer-events: none; white-space: nowrap;
  padding: 6px 10px; border-radius: 8px;
  background: rgba(16, 15, 22, 0.96); box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 45%, transparent), 0 8px 24px rgba(0, 0, 0, 0.5);
  font-size: 0.78rem; color: rgba(244, 241, 234, 0.75);
}
.seat-tip b { color: var(--accent); font-weight: 700; }
.seat-map.loading::after { /* a soft shimmer while VOX is asked */
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(100deg, transparent 30%, rgba(255, 255, 255, 0.07) 50%, transparent 70%) 0 0 / 250% 100%;
  animation: shimmer 1.3s linear infinite;
}
.seat-status { margin: 0; font-size: 0.8rem; color: var(--ink-faint); font-variant-numeric: tabular-nums; } /* under the map: when its seats were checked; in its place, why there are none */
.seat-status.problem { font-size: 0.86rem; color: var(--now); }
.seat-book {
  justify-self: start; padding: 11px 22px; border-radius: 99px; text-decoration: none;
  background: var(--accent-grad); color: var(--on-accent); font-size: 0.78rem; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase;
  box-shadow: 0 8px 24px -10px color-mix(in srgb, var(--accent) 70%, transparent);
  transition: filter .2s, transform .2s var(--ease);
}
@media (hover: hover) { .seat-book:hover { filter: brightness(1.1); } }
/* Book, and beside it Share: the same shape, in glass, as it's the lesser of the two */
.seat-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.seat-share {
  display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
  padding: 10px 18px 10px 15px; border-radius: 99px;
  border: 1px solid rgba(255, 255, 255, 0.16); background: rgba(255, 255, 255, 0.06);
  color: var(--ink); font: inherit; font-size: 0.78rem; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase;
  transition: background .2s, border-color .2s, transform .2s var(--ease);
}
@media (hover: hover) { .seat-share:hover { background: rgba(255, 255, 255, 0.1); border-color: rgba(255, 255, 255, 0.26); } }
.seat-share:active { background: rgba(255, 255, 255, 0.16); transform: scale(0.92); transition-duration: .06s; }
.icon-share { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.seat-note { margin: 0; font-size: 0.8rem; color: var(--ink-faint); }
.seat-guide { margin: 0; font-size: 0.8rem; line-height: 1.5; color: var(--ink-faint); } /* a Reel show: "Reel can't link to a show. On its page, pick Fri 16 · Dubai Marina Mall · Reel Standard · 10:40am" */
.seat-guide b { font-weight: 600; color: var(--ink); }
.seat-guide :is(b, span) { white-space: nowrap; } /* (each part whole: a line breaks only between them) */
@keyframes shimmer { from { background-position: 100% 0; } to { background-position: -150% 0; } }

@keyframes pulse { from { transform: scale(1); opacity: 0.6; } to { transform: scale(2.6); opacity: 0; } }
.st-hint { margin: 0; color: var(--ink-faint); font-size: 0.8rem; }
@keyframes fade { from { opacity: 0; } }

/* ——— Preferences: which films and showtimes are shown ——— */
.prefs-open { /* (first in the top left corner, before Sort) */
  display: inline-flex; align-items: center; gap: 9px; cursor: pointer;
  padding: 9px 16px 9px 13px; border-radius: 99px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  background: rgba(12, 11, 14, 0.62); /* no blur behind: it'd be redone whenever the glow changes */
  color: var(--ink-soft); font-size: 0.8rem; font-weight: 600;
  transition: background .2s, color .2s, border-color .2s, transform .2s var(--ease), opacity .3s var(--ease), visibility 0s;
}
@media (hover: hover) { .prefs-open:hover { background: rgba(255, 255, 255, 0.1); color: var(--ink); border-color: rgba(255, 255, 255, 0.24); } }
/* on a narrow screen, just its icon, round */
@media (max-width: 740px) {
  .prefs-open { width: 40px; height: 40px; padding: 0; justify-content: center; }
  .prefs-label { display: none; }
}
/* the corner's buttons gone while the showtimes have the screen, whose back link is in the corner
   then */
body:has(.times-cover.showing-times) .corner-left { opacity: 0; visibility: hidden; transition: opacity .3s var(--ease), visibility 0s .3s; }

/* ——— The search bar: the search, in the top row after the corner's buttons, out to the right
   edge (cards.js places it); filled, with its ×, while a search's results are shown. Pressed, the
   search opens with its field where the bar is (.from-bar), beside the films, nothing dimmed; on a
   phone, over them, as ever. ——— */
/* Taller than the buttons beside it (--bar-h, centred on their 40px), a rounded rectangle as
   the search is once it's open, its words the size of what's typed there; lit softly from within
   (the accent, a sheen from the top) to say it's there to use. */
.page-find {
  --bar-h: 50px;
  position: fixed; top: calc(max(18px, env(safe-area-inset-top)) - (var(--bar-h) - 40px) / 2); z-index: 60; height: var(--bar-h);
  right: 20px; width: min(460px, calc(100vw - 440px)); /* (where it'll be, near enough, till cards.js places it: placeFindBar) */
  display: flex; align-items: center; border-radius: 15px; overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.16);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0.03)), rgba(12, 11, 14, 0.7);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.04), inset 0 0 22px rgba(169, 150, 255, 0.14), inset 0 1px 0 rgba(255, 255, 255, 0.08);
  transition: background .2s, border-color .2s, box-shadow .2s, opacity .3s var(--ease), visibility 0s;
}
.page-find-open {
  flex: 1; min-width: 0; height: 100%; display: flex; align-items: center; gap: 12px; padding: 0 18px; border: 0; cursor: text;
  background: none; color: rgba(244, 241, 234, 0.62); font: inherit; font-size: 1.05rem; text-align: left; /* (the search's field's size) */
}
.page-find-open .icon-find { width: 16px; height: 16px; }
.page-find-words { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (hover: hover) {
  .page-find:not(.on):hover {
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.05)), rgba(12, 11, 14, 0.7); border-color: rgba(255, 255, 255, 0.26);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.05), inset 0 0 26px rgba(169, 150, 255, 0.22), inset 0 1px 0 rgba(255, 255, 255, 0.1);
  }
  .page-find:not(.on):hover .page-find-open { color: var(--ink-soft); }
}
/* a search's results shown: the bar as the search had it, its chips as they were in its field (the
   same pill, find-token), what was typed after them, and how many films, faint; its × quiet, a
   grey round (to let go of it all: a chip's own × is the open search's) */
.page-find.on .page-find-open { padding-right: 6px; color: var(--ink); }
.page-find.on .page-find-words { display: flex; align-items: center; gap: 6px; min-width: 0; }
.page-find-words .find-token { flex: none; padding: 0 11px; } /* (no × of its own here) */
.page-find-typed { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.page-find-count { flex: none; margin-left: 4px; color: var(--ink-faint); font-size: 0.84rem; white-space: nowrap; }
@media (max-width: 740px) { .page-find-count { display: none; } } /* (on a phone, the films are under it) */
@media (max-width: 740px) { .page-find { right: 16px; width: calc(100vw - 128px); } } /* (on a phone, till it's placed: after Preferences' and Sort's icons) */
.page-find-words.clipped { mask-image: linear-gradient(to right, #000 calc(100% - 22px), transparent); } /* (more than fit: fading out at its end, as the field's start does, cards.js) */
.page-find.on .page-find-clear { width: 28px; height: 28px; margin-right: 11px; background: rgba(255, 255, 255, 0.08); color: var(--ink-soft); }
@media (hover: hover) { .page-find.on .page-find-clear:hover { background: rgba(255, 255, 255, 0.16); color: var(--ink); } }
.page-find.narrow .page-find-open { justify-content: center; padding: 0; }
.page-find.narrow .page-find-words, .page-find.narrow .page-find-clear { display: none; }
body:has(.times-cover.showing-times) .page-find { opacity: 0; visibility: hidden; transition: opacity .3s var(--ease), visibility 0s .3s; }
/* beside the films (a wide screen): the bar, opened. Its field is the bar, just where it is (as
   tall, as round, lit the same: placeFind), and the rest grows down from it, so it's the bar that
   opens, not another thing over it; over the right of the page, the films clear to see as they
   change under what's typed (no shade: it's not modal, cards.js's findLive). Closing, it draws
   back up into the bar. */
.find.from-bar {
  position: fixed; inset: 0 auto auto 0; z-index: 70; width: var(--find-w); margin: var(--find-top) 0 0 var(--find-left);
  border-radius: 14px; box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.16), 0 50px 140px rgba(0, 0, 0, 0.85); /* (its line outside it: the bar's 15px, outside to out) */
}
.find.from-bar[open] { animation: find-grow .28s var(--set-off); }
.find.from-bar.closing { animation: find-shrink .18s cubic-bezier(.4, 0, 1, 1) forwards; }
.find.from-bar .find-bar {
  height: var(--find-bar-h, 50px);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0.03));
  box-shadow: inset 0 0 22px rgba(169, 150, 255, 0.14), inset 0 1px 0 rgba(255, 255, 255, 0.08); /* (the bar's glow) */
}
.find.from-bar .find-bar .icon-find { width: 16px; height: 16px; }
.find.from-bar .find-input::placeholder { color: rgba(244, 241, 234, 0.62); } /* (the bar's words) */
/* (the clip from the bar's own shape to all of it, and on past its edges, for its shadow) */
@keyframes find-grow { from { clip-path: inset(-1px -1px calc(100% - var(--find-bar-h, 48px) - 1px) -1px round 15px); } to { clip-path: inset(-160px round 15px); } }
@keyframes find-shrink { from { clip-path: inset(-160px round 15px); } to { clip-path: inset(-1px -1px calc(100% - var(--find-bar-h, 48px) - 1px) -1px round 15px); } }
body:has(.find.from-bar[open]) .page-find { visibility: hidden; } /* (opened: it's the field now) */

/* ——— Find: the search itself, a panel from the bar (on a phone, at the top, clear of the
   keyboard: --find-room, from cards.js) ——— */
.icon-find { /* a magnifying glass: a ring, and its handle out to the bottom right */
  position: relative; flex: none; width: 14px; height: 14px;
}
.icon-find::before {
  content: ""; position: absolute; left: 0; top: 0; width: 10.5px; height: 10.5px; border-radius: 50%;
  box-shadow: inset 0 0 0 1.6px currentColor;
}
.icon-find::after {
  content: ""; position: absolute; left: 8.4px; top: 8.2px; width: 1.7px; height: 5.6px; border-radius: 1px;
  background: currentColor; transform: rotate(-45deg); transform-origin: 50% 0;
}

.find {
  /* lower down with room to spare; near the top when a keyboard leaves little (a tablet held
     sideways keeps ~330px): what's in sight is --find-room */
  --find-top: clamp(10px, calc((var(--find-room, 100svh) - 420px) / 2), 14svh);
  width: min(560px, calc(100vw - 24px)); max-width: none; margin: var(--find-top) auto auto; padding: 0; border: 0; border-radius: 18px;
  max-height: calc(var(--find-room, 100svh) - var(--find-top) - 24px); overflow: hidden;
  background: rgba(18, 17, 24, 0.98); color: var(--ink);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 50px 140px rgba(0, 0, 0, 0.85);
}
.find[open] { display: flex; flex-direction: column; animation: find-in .3s var(--ease); }
.find::backdrop { background: rgba(4, 4, 6, 0.55); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
.find[open]::backdrop { animation: fade .25s var(--ease); }
.find.closing { animation: find-out .18s cubic-bezier(.4, 0, 1, 1) forwards; }
.find.closing::backdrop { animation: fade-out .22s ease-in forwards; }
@keyframes find-in { from { opacity: 0; transform: translateY(-10px) scale(0.98); } }
@keyframes find-out { to { opacity: 0; transform: translateY(-10px) scale(0.98); } }
@media (max-width: 740px) {
  .find { --find-top: max(10px, env(safe-area-inset-top)); width: calc(100vw - 20px); border-radius: 16px; }
}
/* the field, with any chips before what's typed, on one line that scrolls sideways as they add
   up: the panel never grows taller with them, so what's under it stays where it was */
.find-bar { flex: none; display: flex; align-items: center; gap: 12px; height: 58px; padding: 0 18px; color: var(--ink-faint); }
.find-field {
  flex: 1; min-width: 0; height: 100%; display: flex; align-items: center; gap: 6px;
  overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none;
}
.find-field::-webkit-scrollbar { display: none; }
.find-field.clipped { mask-image: linear-gradient(to right, transparent, #000 22px); } /* (chips scrolled out at its start: cards.js's clipField) */
.find-tokens { flex: none; display: flex; gap: 6px; }
.find-tokens:empty { display: none; }
.find-token {
  display: inline-flex; align-items: center; gap: 2px; height: 30px; padding: 0 3px 0 11px; border-radius: 99px;
  background: color-mix(in srgb, var(--accent) 22%, transparent); color: var(--ink); font-size: 0.84rem; font-weight: 600; white-space: nowrap;
}
.find-token-x {
  display: grid; place-items: center; width: 24px; height: 24px; padding: 0; border: 0; border-radius: 50%; cursor: pointer;
  background: none; color: var(--ink-soft);
}
.find-token-x .icon-close { width: 9px; height: 9px; }
@media (hover: hover) { .find-token-x:hover { background: rgba(255, 255, 255, 0.14); color: var(--ink); } }
@media (max-width: 740px) { .find-token-x { width: 30px; height: 30px; margin-right: -3px; } } /* (a finger's) */
.find-input {
  flex: 1; min-width: 7em; height: 100%; padding: 0; border: 0; outline: none; background: none;
  color: var(--ink); font: inherit; font-size: 1.05rem; /* (16px or more: iOS zooms in on smaller) */
  -webkit-appearance: none; appearance: none;
}
.find-input::placeholder { color: var(--ink-faint); }
.find-input::-webkit-search-cancel-button { display: none; }
.find-cancel {
  flex: none; margin-right: -8px; padding: 8px; border: 0; background: none; cursor: pointer;
  color: var(--accent); font-size: 0.9rem; font-weight: 600;
}
@media (hover: hover) and (pointer: fine) { .find-cancel { display: none; } } /* (Escape, or a click outside) */
.find-results {
  /* min-height: 0 lets it shrink to the panel and scroll: without it, a flex item stays as tall as
     its results, cut off by the panel, with nothing to scroll (and a finger scrolled the page) */
  flex: 1 1 auto; min-height: 0;
  margin: 0; padding: 6px; list-style: none; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: none;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.find-results::-webkit-scrollbar { display: none; }
.find-results:empty { display: none; }
/* a film found: its poster, small, as the grid's little cards; its name, and under it who matched
   or its next show; for one your preferences hide, what turning it on does */
.find-hit {
  display: grid; grid-template-columns: 32px minmax(0, 1fr) auto; align-items: center; gap: 14px;
  padding: 7px 12px 7px 8px; border-radius: 10px; cursor: pointer;
}
.find-hit[aria-selected="true"] { background: color-mix(in srgb, var(--accent) 14%, transparent); }
.find-hit:active { background: color-mix(in srgb, var(--accent) 20%, transparent); }
.find-art {
  display: block; width: 32px; aspect-ratio: 63 / 88; overflow: hidden; border-radius: 3px; background: #15131b;
  box-shadow: 0 0 0 1px rgba(255, 240, 200, 0.16);
}
.find-art img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 20%; }
.find-words { display: grid; gap: 2px; min-width: 0; }
.find-title, .find-note, .find-why { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.find-why { font-size: 0.76rem; color: color-mix(in srgb, var(--accent) 80%, transparent); } /* (left out by your shortlist: choosing it shows it) */
.find-title { font-size: 0.98rem; font-weight: 600; color: var(--ink); }
.find-note { font-size: 0.8rem; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.find-hit mark { background: none; color: var(--accent); }
.find-hit.hidden-film :is(.find-art, .find-title) { opacity: 0.55; }
/* what hides it, whole: on two lines if it needs them (on a phone, with who matched) */
.find-hit.hidden-film .find-note {
  white-space: normal; text-wrap: pretty;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
/* the note (the site's one: what finding a hidden film changed, with Undo, a few seconds). It's
   kept off every control: centred just under the top corners, over the top of the cards or the
   grid (a heading, not a control), and taps beside Undo reach what's under it (the card's scores, a
   heading); while the showtimes have the screen (the corners gone), at the top right, in their
   place, between the back link and the bookmark there, wrapping if it must. Never at the foot,
   where the arrows and showtimes are. */
.undo-note {
  position: fixed; top: calc(max(18px, env(safe-area-inset-top)) + 52px); left: 50%; z-index: 70;
  width: max-content; max-width: calc(100vw - 32px); margin: 0; padding: 9px 16px; border-radius: 19px; /* (max-content: else, from the middle, it'd wrap at half the screen) */
  border: 1px solid rgba(255, 255, 255, 0.14); background: rgba(12, 11, 14, 0.86);
  color: var(--ink-soft); font-size: 0.82rem; font-weight: 600; line-height: 18px; text-align: center; text-wrap: balance;
  --x: -50%; translate: var(--x) -6px; opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .3s var(--ease), translate .3s var(--ease), visibility 0s .3s;
}
.undo-note.shown { translate: var(--x) 0; opacity: 1; visibility: visible; transition: opacity .3s var(--ease), translate .3s var(--ease), visibility 0s; }
.undo-note .link { font-weight: 600; pointer-events: auto; outline-offset: 0; } /* (its ring kept clear of the "·" and the note's edge) */
body:has(.times-cover.showing-times) .undo-note {
  --x: 0; left: auto; right: 62px; top: max(16px, env(safe-area-inset-top)); max-width: calc(100vw - 170px); text-align: right;
}
.find-act { font-size: 0.7rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--accent); white-space: nowrap; }
/* how a search by what's on was taken, over its films ("IMAX · Tonight · 4 films"); or, bigger,
   that nothing matches */
.find-sum {
  margin: 0; padding: 9px 20px; border-top: 1px solid rgba(255, 255, 255, 0.08);
  font-size: 0.78rem; font-weight: 600; color: var(--ink-faint); font-variant-numeric: tabular-nums;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.find-sum.none { padding: 16px 20px 18px; font-size: 0.88rem; font-weight: 400; white-space: normal; }
/* the ideas under the field: searches to try (with a line over them), or words to finish one
   with; a row of small pills, as the filter's, wrapping */
.find-ideas { flex: none; padding: 10px 16px 14px; border-top: 1px solid rgba(255, 255, 255, 0.08); }
.find-ideas[hidden] { display: none; }
.find-lead { margin: 2px 2px 10px; font-size: 0.8rem; color: var(--ink-faint); text-wrap: pretty; }
.find-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.find-chip {
  height: 34px; padding: 0 13px; border-radius: 99px; border: 1px solid rgba(255, 255, 255, 0.12); cursor: pointer;
  background: rgba(255, 255, 255, 0.04); color: var(--ink-soft); font: inherit; font-size: 0.84rem; font-weight: 600; white-space: nowrap;
  transition: background .2s, border-color .2s, color .2s, transform .2s var(--ease);
}
@media (hover: hover) { .find-chip:hover { background: rgba(255, 255, 255, 0.1); color: var(--ink); } }
.find-chip:active { transform: scale(0.94); transition-duration: .06s; }
@media (max-width: 740px) { .find-chip { height: 38px; } } /* (a finger's) */
/* the quick picks: a row each, scrolling sideways, fading out at its ends; the picked filled, as
   the filter's chips are */
.find-picks { flex: none; display: grid; gap: 8px; padding: 12px 0; border-top: 1px solid rgba(255, 255, 255, 0.08); }
.find-picks[hidden] { display: none; }
.find-row {
  display: flex; gap: 8px; padding: 0 16px; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none;
  mask-image: linear-gradient(to right, transparent, #000 14px, #000 calc(100% - 22px), transparent);
}
.find-row::-webkit-scrollbar { display: none; }
.find-pick { flex: none; display: inline-flex; align-items: center; gap: 6px; }
.find-pick[aria-disabled="true"] { opacity: 0.32; cursor: default; } /* (would find nothing beside the chips: dimmed in place, so nothing moves) */
.find-pick { transition: background .2s, border-color .2s, color .2s, opacity .2s, transform .2s var(--ease); }
@media (hover: hover) { .find-pick[aria-disabled="true"]:hover { background: rgba(255, 255, 255, 0.04); color: var(--ink-soft); } }
.find-pick[aria-disabled="true"]:active { transform: none; }
.find-pick.refused { animation: refuse .4s ease; }
@media (prefers-reduced-motion: reduce) { .find-pick.refused { animation: none; } }
.find-pick[aria-pressed="true"] { border-color: transparent; background: var(--ink); color: rgb(18, 17, 24); }
/* the Times row: "Times", and the stretch chosen ("7PM – 11:30PM"), over a track from 9AM to 3AM
   with two knobs, the stretch between them in the accent; behind it, faint bars, how many shows
   start in each half hour (those of the stretch a little brighter); under it, a few hours to go by.
   The knobs' 22px with a 44px reach (a finger's); the track takes the drag, not the panel */
.find-times { padding: 0 20px; }
.find-times-head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; font-size: 0.78rem; }
.find-times-name { color: var(--ink-faint); font-weight: 600; }
.find-times-said { color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.find-times.on .find-times-said { color: var(--ink); font-weight: 600; }
.find-track { position: relative; height: 40px; margin: 0 4px; touch-action: none; cursor: pointer; user-select: none; -webkit-user-select: none; }
.find-hist { position: absolute; left: 0; right: 0; top: 2px; height: 17px; display: flex; align-items: flex-end; gap: 1px; pointer-events: none; }
.find-hist i { flex: 1; height: 0; border-radius: 1px 1px 0 0; background: rgba(255, 255, 255, 0.08); transition: height .3s var(--ease), background .2s; }
.find-times.on .find-hist i.in { background: color-mix(in srgb, var(--accent) 30%, transparent); } /* (a stretch chosen: its shows) */
.find-track-line, .find-track-fill { position: absolute; top: 19px; height: 2px; border-radius: 1px; pointer-events: none; }
.find-track-line { left: 0; right: 0; background: rgba(255, 255, 255, 0.14); }
.find-track-fill { background: var(--accent); }
.find-times:not(.on) .find-track-fill { opacity: 0; } /* (the whole day: nothing chosen) */
.find-knob {
  position: absolute; top: 20px; width: 20px; height: 20px; margin: -10px 0 0 -10px; border-radius: 50%; cursor: grab;
  background: var(--ink); box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5); outline: none;
  transition: transform .15s var(--ease), box-shadow .15s;
}
.find-knob::before { content: ""; position: absolute; inset: -12px; border-radius: 50%; } /* (a 44px reach) */
.find-knob:focus-visible { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 70%, transparent), 0 1px 4px rgba(0, 0, 0, 0.5); }
.find-times.dragging .find-knob:focus { transform: scale(1.15); cursor: grabbing; }
.find-times:not(.on) .find-knob { background: var(--ink-soft); }
.find-times-scale { position: relative; height: 14px; margin: 0 4px; font-size: 0.66rem; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.find-times-scale span { position: absolute; top: 0; translate: -50% 0; white-space: nowrap; }
.find-times-scale span:first-child { translate: 0 0; }
.find-times-scale span:last-child { translate: -100% 0; }
@media (prefers-reduced-motion: reduce) { .find-hist i, .find-knob { transition: none; } }
.find-pick-icon { width: 16px; height: 16px; object-fit: contain; }
.find-soon-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--soon); box-shadow: 0 0 6px var(--soon); } /* (Soon: the showtimes' green, still) */
.find-pick[aria-pressed="true"] .find-soon-dot { box-shadow: none; }
.find-picks:not([hidden]) + .find-ideas { border-top: 0; padding-top: 2px; } /* (the examples under them: one panel) */
/* the search's Show button, under its films, always in sight (the panel's foot): its results in
   the grid or the cards, as a filter that's on is filled */
.find-foot { flex: none; padding: 10px 12px 12px; border-top: 1px solid rgba(255, 255, 255, 0.08); }
.find-foot[hidden] { display: none; }
.find-show {
  display: block; width: 100%; height: 44px; border: 0; border-radius: 12px; cursor: pointer;
  background: var(--accent-grad); color: var(--on-accent); font: inherit; font-size: 0.92rem; font-weight: 600;
  transition: filter .2s, transform .2s var(--ease);
}
@media (hover: hover) { .find-show:hover { filter: brightness(1.12); } }
.find-show:active { transform: scale(0.98); transition-duration: .06s; }
.find-sum:not([hidden], .none) + .find-results { border-top: 0; padding-top: 0; } /* (the line over them is the sum's) */

/* ——— Sort: after Preferences, top left, its own pill, opening its panel. It says the order the
   films come in; never filled: it's how they're laid out, not which (the one rule for colour
   across the bar: the accent for a search's results shown). ——— */
.sort-open {
  display: inline-flex; align-items: center; gap: 9px; padding: 9px 15px 9px 13px; border-radius: 99px; cursor: pointer;
  border: 1px solid rgba(255, 255, 255, 0.14); background: rgba(12, 11, 14, 0.62);
  color: var(--ink-soft); font-size: 0.8rem; font-weight: 600; white-space: nowrap;
  transition: background .2s, color .2s, border-color .2s, transform .2s var(--ease);
}
@media (hover: hover) { .sort-open:hover { background: rgba(255, 255, 255, 0.1); border-color: rgba(255, 255, 255, 0.24); color: var(--ink); } }
.when-short { display: none; }
/* a phone (upright, or on its side): Sort, its icon alone (the cards' count says the sort: "3 / 15
   · Top Rated"); the search bar's words, in short ("Search films…"; a search's results, without
   their count). On its side with your shortlist's button, the view toggle is just the other
   view's button. */
@media (max-width: 740px), (orientation: landscape) and (max-height: 499px) {
  .when-long { display: none; }
  .when-short { display: inline; }
  .sort-open { width: 40px; height: 40px; padding: 0; justify-content: center; }
  .sort-open :is(.sort-label, .when-caret) { display: none; }
}
@media (orientation: landscape) and (max-height: 499px) { /* (on its side: clear of the card, between the corners) */
  .corner-left:has(.short-toggle:not([hidden])) .view-toggle button[aria-pressed="true"] { display: none; }
}
.when-caret { width: 6px; height: 6px; margin: -3px 0 0 -1px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg); opacity: 0.7; }
.when-clear {
  display: grid; place-items: center; flex: none; width: 26px; height: 26px; margin-right: 6px; padding: 0; border: 0; border-radius: 50%; cursor: pointer;
  background: rgba(255, 255, 255, 0.18); color: var(--on-accent); transition: background .2s, transform .2s var(--ease);
}
.when-clear .icon-close { width: 10px; height: 10px; }
@media (hover: hover) { .when-clear:hover { background: rgba(255, 255, 255, 0.3); } }

/* its panel: Preferences' look (below), and a sheet on a phone as that is; on a wider screen,
   dropped from its button (--drop-left, from cards.js), with no shade behind: the films change
   behind it as you choose */
@media (min-width: 741px) {
  .prefs.drop {
    position: fixed; inset: calc(max(18px, env(safe-area-inset-top)) + 44px) auto auto var(--drop-left, 20px); z-index: 70; width: 400px; margin: 0; /* (clear of the card's scores, at 1280) */
    background: rgb(18, 17, 24); /* (solid: no card's lettering showing through, with no shade behind) */
  }
  .prefs.sort { width: 280px; }
}
/* the sorts: a row each, just its name, its tick filled in the light ink when it's the one, where
   a switch's knob would be */
.prefs.sort form { padding-bottom: 14px; } /* (just the three rows: no note under them) */
.prefs.sort .pref { grid-template-columns: minmax(0, 1fr) auto; min-height: 54px; }
.prefs.sort .pref:not(:has(input:checked)) .pref-name { color: var(--ink-soft); }
.tick {
  flex: none; width: 24px; height: 24px; margin-right: 4px; border-radius: 50%;
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.22); transition: box-shadow .2s var(--ease), background .2s;
}
.pref:has(input:checked) .tick { background: rgb(18, 17, 24); box-shadow: inset 0 0 0 7px var(--ink); }
.pref:has(input:focus-visible) .tick { outline: 2px solid var(--accent); outline-offset: 3px; }
/* in the showtimes: the times a search's results leave out are left out, and it says so */
.st-from { margin: -6px 0 -4px; font-size: 0.8rem; color: var(--ink-faint); }

/* Sort's mark: a list sorted longest first, drawn in lines: an order, not a favourite */
.icon-ranked {
  flex: none; width: 13px; height: 11px;
  background:
    linear-gradient(currentColor, currentColor) 0 0 / 100% 1.6px no-repeat,
    linear-gradient(currentColor, currentColor) 0 4.7px / 70% 1.6px no-repeat,
    linear-gradient(currentColor, currentColor) 0 9.4px / 40% 1.6px no-repeat;
}
/* a time or a room chosen (the filter): the top film's times that suit, under the card, so you
   needn't open its showtimes to see them. The buttons below move down a little to give it room
   (.timed, from cards.js); it moves with the stack, and goes while the showtimes are open, which
   say it all. The first has a green dot within two hours (red: started). */
/* (20px where there's room; on a short window, less, down to none by 660px tall, so the arrows keep
   a margin at the foot: the line then sits in the gap as it is. Without the line, none: .table) */
.table.timed { --line-room: clamp(0px, (100svh - 660px) / 3, 20px); }
.table.timed.showing-times:not(.grid-mode) { --line-room: 0px; } /* (beside the showtimes, which say it all, the line's never there: no room kept for it) */
.deck-actions { translate: 0 var(--line-room); }
.deck-nav { translate: calc(-1 * var(--nav-shift, 0px)) var(--line-room); transition: opacity .3s var(--ease), visibility 0s, translate .6s var(--set-off); } /* (moved aside with the card for the showtimes, in step) */
.showing-times:not(.grid-mode) .deck-nav { --nav-shift: var(--shift, 0px); }
.next-show {
  position: absolute; top: calc(100% + (var(--gap) + var(--line-room)) / 2); left: 50%; translate: -50% -50%;
  margin: 0; display: flex; align-items: center; gap: 10px; white-space: nowrap;
  color: var(--ink-soft); font-size: 0.8rem; font-weight: 500; font-variant-numeric: tabular-nums;
  transition: opacity .3s var(--ease);
}
.showing-times .next-show { opacity: 0; }
.next-show { --dot: 7px; }
.next-show:is(.soon, .now)::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--soon); box-shadow: 0 0 8px var(--soon); }
.next-show.now::before { background: var(--now); box-shadow: 0 0 8px var(--now); }
.next-show b { color: var(--ink); font-weight: 700; }
.next-day { font-size: 0.7rem; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-soft); }
.next-in, .next-more { margin-left: -4px; color: var(--ink-faint); }
/* a phone: above the cards instead, in the room the phone's layout keeps between the buttons and
   the cards (see .table), so the controls below stay put */
@media (max-width: 740px) {
  .table.timed { --line-room: 0px; }
  .next-show { top: auto; bottom: calc(100% + 26px); translate: -50% 0; } /* (clear of the buttons on a short phone, the cards behind just showing under it) */
}
/* A phone on its side (the height SHORT in cards.js): the buttons in the top corners are clear of
   the card, narrow between them, so the cards go up to the top, the times line beside them, and
   the corners keep clear of the notch. The showtimes and the grid take the screen, as upright
   (cards.js). The trailer leaves room above it for its ×. */
@media (orientation: landscape) and (max-height: 499px) {
  .table { --top: 26px; }
  .table.timed { --line-room: 0px; }
  .next-show { /* (as wide as there's room beside the card: the day over its times, which wrap) */
    left: calc(100% + 28px); bottom: auto; top: 50%; translate: 0 -50%;
    width: max-content; max-width: calc((100vw - var(--card-w)) / 2 - 44px); flex-wrap: wrap; row-gap: 4px;
  }
  .next-day { flex-basis: 100%; }
  .corner-left { left: max(20px, env(safe-area-inset-left)); }
  .prefs.drop { max-height: calc(100svh - max(18px, env(safe-area-inset-top)) - 56px); } /* (Sort, dropped from its button: scrolls, to the foot) */
}
.icon-sliders { /* two sliders */
  position: relative; width: 14px; height: 11px;
  background: linear-gradient(currentColor, currentColor) 0 2px / 100% 1.5px no-repeat, linear-gradient(currentColor, currentColor) 0 8px / 100% 1.5px no-repeat;
}
.icon-sliders::before, .icon-sliders::after {
  content: ""; position: absolute; width: 5px; height: 5px; border-radius: 50%;
  background: var(--bg); box-shadow: inset 0 0 0 1.5px currentColor;
}
.icon-sliders::before { left: 2px; top: 0; }
.icon-sliders::after { right: 2px; top: 6px; }

/* like a phone's settings: a title (Preferences', with a × to close), then grouped rows of switches. A centred panel; on
   a phone, a sheet up from the bottom. */
.prefs {
  width: min(440px, calc(100vw - 24px)); max-width: none; max-height: 88svh; padding: 0; border: 0; border-radius: 20px; overflow: auto;
  background: rgba(18, 17, 24, 0.98); color: var(--ink);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 50px 140px rgba(0, 0, 0, 0.85);
  scrollbar-width: none;
  overscroll-behavior: contain; /* its scrolling stays in it, not the page behind */
}
.prefs::backdrop { background: rgba(4, 4, 6, 0.6); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
.prefs[open] { animation: rise .4s var(--ease); }
.prefs[open]::backdrop { animation: fade .3s var(--ease); }
@media (max-width: 740px) {
  .prefs { width: 100%; margin: auto 0 0; border-radius: 20px 20px 0 0; padding-bottom: env(safe-area-inset-bottom); }
  .prefs[open] { animation: sheet .45s var(--set-off); }
}
@keyframes sheet { from { transform: translateY(100%); } }
/* closing (closePrefs): the way it came, in reverse, setting off gently and speeding away, since
   it's leaving from rest */
.prefs.closing { animation: rise-out .22s cubic-bezier(.4, 0, 1, 1) forwards; }
.prefs.closing::backdrop { animation: fade-out .25s ease-in forwards; }
@media (max-width: 740px) { .prefs.closing { animation: sheet-out .3s cubic-bezier(.4, 0, 1, 1) forwards; } }
@keyframes rise-out { to { opacity: 0; transform: translateY(14px) scale(0.98); } }
@keyframes sheet-out { to { transform: translateY(100%); } }
@keyframes sheet-glass { from { transform: translateY(calc(100% - var(--sheet-under))); } } /* (a sheet's: from just under the screen, not its glass's foot) */
@keyframes sheet-glass-out { to { transform: translateY(calc(100% - var(--sheet-under))); } }
@keyframes fade-out { to { opacity: 0; } }
/* a sheet (makeSheet, in cards.js), on a phone: frosted glass up from the bottom, rounder, with a
   grabber to drag it by, over a light shade (the films clear behind it, not blurred). Its quieter
   words, rows not chosen and anything .sheet-quiet, are vibrant, as iOS's: lit by the colours
   behind (plus-lighter); its title and what's chosen stay plain white, to read the same over any.
   Its glass goes on under the foot of the screen (--sheet-under, more than cards.js's SHEET_GIVE
   and the spring's overshoot), so pulled up it shows more of itself, never the page beneath; its
   rows stay where they were, clear of the home bar. The shade lightens as it's pulled down
   (--sheet-shade, from cards.js), and a sheet let go on its way (--sheet-out and its curve) goes
   at the finger's speed. */
@media (max-width: 740px) {
  dialog.sheet {
    --sheet-under: 96px;
    border-radius: 28px 28px 0 0; touch-action: pan-y; /* (its rows scroll, if it has more than fit; a drag that's the sheet's, cards.js holds the scroll off) */
    max-height: calc(88svh + var(--sheet-under)); margin-bottom: calc(-1 * var(--sheet-under)); padding-bottom: calc(env(safe-area-inset-bottom) + var(--sheet-under));
    background: rgba(30, 28, 38, 0.42); backdrop-filter: blur(28px) saturate(1.8); -webkit-backdrop-filter: blur(28px) saturate(1.8);
  }
  dialog.sheet::backdrop { background: rgba(4, 4, 6, 0.35); backdrop-filter: none; -webkit-backdrop-filter: none; opacity: var(--sheet-shade, 1); }
  dialog.sheet[open] { animation-name: sheet-glass; }
  dialog.sheet[open]::backdrop { animation: fade .45s var(--set-off); } /* (in step with it: caught as it comes up, the shade's where it'd be) */
  dialog.sheet.dragging .pref:active { background: transparent; } /* (a drag, not a press: as iOS, the row's let go) */
  dialog.sheet.dragging .pref:active::before, dialog.sheet.dragging .pref:active + .pref::before { opacity: 1; }
  dialog.sheet.closing { animation: sheet-glass-out var(--sheet-out, .3s) var(--sheet-out-curve, cubic-bezier(.4, 0, 1, 1)) forwards; }
  dialog.sheet.closing::backdrop { animation: fade-out var(--sheet-out, .25s) ease-in forwards; } /* (over its [open] fade, just above) */
  /* the grabber, iOS's: 36 by 5, clear of the edge (a little more than iOS's 5, with no hard edge
     here to sit under, and rounder corners), the title well below it (some 20px) */
  dialog.sheet::before {
    content: ""; position: absolute; z-index: 2; left: 50%; top: 8px; width: 36px; height: 5px; margin-left: -18px; border-radius: 3px;
    background: rgba(255, 255, 255, 0.32); mix-blend-mode: plus-lighter;
  }
  dialog.sheet .prefs-head { padding-top: 28px; background: transparent; touch-action: none; transition: background-color .2s, box-shadow .2s; } /* (room for the grabber; dragged by, always) */
  dialog.sheet.scrolled .prefs-head { background: rgb(26, 24, 33); } /* (rows under it: solid, in the glass's tint; a blur of its own can't see through the sheet's, and any see-through lets the vibrant rows show) */
  dialog.sheet.prefs :is(.sheet-quiet, .pref:not(:has(input:checked)) .pref-name) { color: rgba(255, 255, 255, 0.62); mix-blend-mode: plus-lighter; } /* (.prefs: over Sort's own quieter rows) */
  dialog.sheet.prefs :is(legend, .prefs-note) { mix-blend-mode: plus-lighter; } /* (Preferences' headings and notes: vibrant, as faint as they were) */
  dialog.sheet.prefs .pref + .pref::before { mix-blend-mode: plus-lighter; } /* (the hairlines too: their own rule, a pseudo-element can't go in :is) */
  dialog.sheet.prefs .pref:has(input:checked) .pref-name { color: #fff; }
}
.prefs form { display: grid; gap: 30px; padding: 0 20px 28px; }
/* the title (and Preferences' ×) stay put at the top as the rows scroll under them, as in a phone's sheets,
   with a hairline beneath once there's something under it (.scrolled, from cards.js) */
.prefs-head {
  position: sticky; top: 0; z-index: 1;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  margin: 0 -20px -12px; padding: 22px 20px 14px 24px;
  background: rgb(18, 17, 24); box-shadow: 0 1px 0 transparent;
  transition: box-shadow .2s;
}
.prefs.scrolled .prefs-head { box-shadow: 0 1px 0 rgba(255, 255, 255, 0.08); }
.prefs h2 { margin: 0; font-size: 1.2rem; font-weight: 700; letter-spacing: -0.02em; line-height: 1.2; }
.prefs h2:focus { outline: none; } /* focused on opening, just so it starts there (see cards.html) */
.prefs fieldset { margin: 0; padding: 0; border: 0; min-width: 0; }
/* each part's name in the site's small capitals (the cards' DIRECTOR and CAST, the days), over
   its rows; what it does in a line beneath them */
.prefs legend {
  padding: 0 4px 10px; font-size: 0.68rem; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink-faint);
}
/* the cinemas' and languages' marks, before their names: a line drawing in the name's colour,
   the size of its capitals' line */
.prefs legend:has(.prefs-icon) { display: flex; align-items: center; gap: 7px; }
.prefs-icon { flex: none; width: 13px; height: 13px; margin-top: -1px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linejoin: round; }
.prefs-note { margin: 8px 4px 0; font-size: 0.76rem; line-height: 1.45; color: rgba(244, 241, 234, 0.4); }

/* a preference: a row with its name and what it covers, how many films, and a switch. Rows sit
   on the panel itself, divided by hairlines, as the showtimes' are (no boxes); lit softly, to the
   rounded edge, under a pointer or a finger. One that's off is a shade quieter, so what's on
   reads at a glance. */
.prefs-group { margin: 0 -10px; }
.pref {
  position: relative; display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: 14px; align-items: center;
  min-height: 62px; padding: 11px 14px; border-radius: 12px; cursor: pointer;
  transition: background .2s;
}
.pref + .pref::before { content: ""; position: absolute; top: 0; left: 14px; right: 14px; height: 1px; background: rgba(255, 255, 255, 0.07); }
/* (the hairlines either side of a lit row give way to it) */
@media (hover: hover) { .pref:hover { background: rgba(255, 255, 255, 0.035); } .pref:hover::before, .pref:hover + .pref::before { opacity: 0; } }
.pref:active { background: rgba(255, 255, 255, 0.06); transition-duration: .06s; } /* pressed */
.pref:active::before, .pref:active + .pref::before { opacity: 0; }
.pref input { position: absolute; opacity: 0; pointer-events: none; }
.pref-text { display: grid; gap: 2px; }
.pref-name { font-weight: 600; font-size: 0.94rem; letter-spacing: -0.005em; color: var(--ink); transition: color .2s; }
.pref:not(:has(input:checked)) .pref-name { color: var(--ink-soft); }
.pref-name b { font-weight: 800; }
.pref-blurb { font-size: 0.76rem; line-height: 1.35; color: var(--ink-faint); }
.pref-count { font-size: 0.78rem; color: var(--ink-faint); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* the switch: a track with a knob, sliding over when on, a little wider than a phone's, its knob
   stretching while it's held, as a phone's does. On, it's the page's own light ink with a dark
   knob: no colour, as the view toggle has none when on; it's a setting, not a
   filter of the moment (the filter's, in the accent). */
.switch {
  position: relative; flex: none; width: 56px; height: 32px; border-radius: 99px;
  background: rgba(255, 255, 255, 0.12); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.04);
  transition: background .3s var(--ease);
}
.switch::after {
  content: ""; position: absolute; left: 3px; top: 3px; width: 26px; height: 26px; border-radius: 99px;
  background: var(--ink); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 2px 6px rgba(0, 0, 0, 0.25);
  transition: transform .3s var(--ease), width .2s var(--ease), background .3s var(--ease);
}
.pref:active .switch::after { width: 32px; }
.pref:has(input:checked) .switch { background: var(--ink); }
.pref:has(input:checked) .switch::after { background: rgb(18, 17, 24); box-shadow: none; transform: translateX(24px); }
.pref:has(input:checked):active .switch::after { transform: translateX(18px); } /* (stretching from the right) */
.pref:has(input:focus-visible) .switch { outline: 2px solid var(--accent); outline-offset: 3px; }
.pref.refused .switch { animation: refuse .4s ease; } /* the last language, which has to stay */
@keyframes refuse { 20%, 60% { transform: translateX(-4px); } 40%, 80% { transform: translateX(4px); } }

.prefs-showing { margin: 3px 0 0; font-size: 0.8rem; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.prefs-showing.note { color: var(--accent); }
.prefs-close { flex: none; } /* the round ×, as the showtimes' and the trailer's (no Done: it closes as you go) */

/* ——— The view toggle: cards or grid (and your shortlist), after Preferences and Sort, top left ——— */
.corner-left {
  position: fixed; top: max(18px, env(safe-area-inset-top)); left: 20px; z-index: 60;
  display: flex; align-items: center; gap: 10px;
  transition: opacity .3s var(--ease), visibility 0s;
}
/* on a phone, the corner a little closer in and to the edge, the 16px gutter (the search bar
   after it, as far in from the right) */
@media (max-width: 740px) {
  .corner-left { left: 16px; gap: 8px; }
}
.view-toggle {
  display: flex; padding: 3px; border-radius: 99px;
  border: 1px solid rgba(255, 255, 255, 0.14); background: rgba(12, 11, 14, 0.62);
}
.view-toggle button {
  display: grid; place-items: center; width: 34px; height: 32px; padding: 0; border: 0; border-radius: 99px; cursor: pointer;
  background: none; color: var(--ink-faint); transition: background .2s, color .2s, transform .2s var(--ease);
}
.view-toggle button[aria-pressed="true"] { background: rgba(255, 255, 255, 0.14); color: var(--ink); }
@media (hover: hover) { .view-toggle button:not([aria-pressed="true"]):hover { color: var(--ink); } }
.view-toggle button:active { transform: scale(0.9); transition-duration: .06s; }
/* the two as a pair: solid, 14px, the same weight (a card and the one tilted behind it: the
   template's SVG; four little squares on whole pixels, 6 + 2 + 6, each rounded alike) */
.icon-cards { display: block; width: 14px; height: 14px; fill: currentColor; }
.icon-grid { position: relative; width: 14px; height: 14px; }
.icon-grid::before {
  content: ""; position: absolute; left: 0; top: 0; width: 6px; height: 6px; border-radius: 1.5px;
  background: currentColor; box-shadow: 8px 0 currentColor, 0 8px currentColor, 8px 8px currentColor;
}

/* ——— Your shortlist (cards.js): a bookmark on each film, and once there's one on it, a button for
   just those: round, after the view toggle (a filter on the films, not a way to lay them out), with
   how many on its corner; filled in the accent while it's on, as the filter's pill is ——— */
.icon-save { flex: none; width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linejoin: round; }
[aria-pressed="true"] > .icon-save { fill: currentColor; }
.short-toggle {
  position: relative; display: grid; place-items: center; flex: none; width: 38px; height: 38px; padding: 0; border-radius: 50%; cursor: pointer;
  border: 1px solid rgba(255, 255, 255, 0.14); background: rgba(12, 11, 14, 0.62); color: var(--ink-soft);
  transition: background .2s, color .2s, border-color .2s, transform .2s var(--ease);
  animation: fade .3s var(--ease); /* (coming into the corner: the first film saved) */
}
@media (hover: hover) { .short-toggle:not([aria-pressed="true"]):hover { background: rgba(255, 255, 255, 0.1); color: var(--ink); border-color: rgba(255, 255, 255, 0.24); } }
.short-toggle[aria-pressed="true"] { border-color: transparent; background: var(--accent-grad); color: var(--on-accent); }
.short-count { /* light on the dark glass, dark on the accent: the digit always reads */
  position: absolute; top: -4px; right: -5px; min-width: 17px; height: 17px; padding: 0 4px; border-radius: 99px;
  background: var(--ink); color: rgb(18, 17, 24); font-size: 0.66rem; font-weight: 700; line-height: 17px; text-align: center;
  font-variant-numeric: tabular-nums;
}
.short-toggle[aria-pressed="true"] .short-count { background: rgb(18, 17, 24); color: var(--ink); }
@media (max-width: 740px), (orientation: landscape) and (max-height: 499px) { .short-toggle { width: 40px; height: 40px; } } /* (as search and Preferences there) */
@media (max-width: 359px) { .view-toggle button { width: 31px; } } /* (320px: room for a time's × and your shortlist) */
/* under the cards, after Showtimes: the top film's, round, in the pills' glass; on the shortlist,
   filled in the accent. Beside the pair rather than in their row, so they stay centred over the
   arrows. */
.deck-save {
  position: absolute; top: 0; left: calc(100% + 8px);
  display: grid; place-items: center; width: 42px; height: 42px; padding: 0; border-radius: 50%; cursor: pointer;
  border: 1px solid rgba(255, 255, 255, 0.16); background: rgba(255, 255, 255, 0.06); color: var(--ink-soft);
  transition: background .2s, border-color .2s, color .2s, transform .2s var(--ease);
}
/* on a narrow phone, in the row after all (the pair a little off centre), keeping the side gutters */
@media (max-width: 420px) { .deck-save { position: static; flex: none; } }
@media (max-width: 359px) { /* (the smallest: all three a little tighter) */
  .deck-actions { gap: 8px; }
  .deck-action { gap: 8px; padding: 10px 16px 10px 13px; }
  .deck-save { width: 40px; height: 40px; align-self: center; }
}
.deck-save .icon-save { width: 17px; height: 17px; }
.deck-save[aria-pressed="true"], .times-save[aria-pressed="true"] { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
@media (hover: hover) {
  .deck-save:hover { background: rgba(255, 255, 255, 0.1); border-color: rgba(255, 255, 255, 0.26); color: var(--ink); }
  :is(.deck-save, .times-save)[aria-pressed="true"]:hover { color: var(--accent); border-color: var(--accent); }
}
.deck-save:active { background: rgba(255, 255, 255, 0.16); }
/* by a film's showtimes where the one under the cards isn't to hand: in the grid, beside the ×,
   and on a phone, in the ×'s place at the top right */
.times-save {
  position: absolute; top: calc(6px + (1.5rem * 1.1 - 34px) / 2); right: 44px; z-index: 1;
  display: grid; place-items: center; width: 34px; height: 34px; padding: 0; border-radius: 50%; cursor: pointer;
  border: 1px solid rgba(255, 255, 255, 0.16); background: rgba(255, 255, 255, 0.05); color: var(--ink-soft);
  transition: background .2s, color .2s, border-color .2s, opacity .3s var(--ease), visibility 0s, transform .2s var(--ease);
}
@media (hover: hover) { .times-save:hover { background: rgba(255, 255, 255, 0.14); color: var(--ink); } }
.times-save:active { background: rgba(255, 255, 255, 0.18); }
/* beside the cards (only on a wide screen: cards.js's cardsFit), the showtimes always there: no ×,
   the bookmark in its place and the trailer by it, as on a phone; the buttons under the card gone */
.table:not(.times-cover, .grid-mode) .times-save { right: 0; }
.table:not(.times-cover, .grid-mode) [data-showtimes-close] { display: none; }
.table:not(.grid-mode) .deck-actions { display: none; }
.grid-mode:not(.times-cover) .times-body .st-title { padding-right: 88px; } /* (clear of both) */
.times-cover .times-save { right: 0; }
.list-mode .times-save, .info-mode .times-save { opacity: 0; visibility: hidden; } /* (several films, or one in brief) */
.grid-mode .list-mode .times-close { opacity: 0; visibility: hidden; } /* (beside the grid, they're the panel's own: nothing to close) */

/* your shortlist's showtimes together, a day at a time: each film once, its poster and name, then
   its times as small tiles side by side, under its format (and cinema, with several); a time's
   dot says it's next within 2 hours, or just started */
.list-mode .st-panel { gap: 14px; }
.list-film { display: grid; gap: 6px; }
.list-film + .list-film { padding-top: 14px; border-top: 1px solid rgba(255, 255, 255, 0.08); }
.list-head { display: flex; align-items: center; gap: 10px; margin: 0; font-size: 1.05rem; font-weight: 700; letter-spacing: -0.01em; }
.list-art {
  flex: none; width: 24px; aspect-ratio: 63 / 88; border-radius: 3px; object-fit: cover; object-position: 50% 20%;
  background: #15131b; box-shadow: 0 0 0 1px rgba(255, 240, 200, 0.16);
}
.list-film .st-cinema:not([hidden]) ~ .st-cinema:not([hidden]) { margin-top: 0; padding-top: 4px; border-top: 0; }
.list-film .st-cinema-name { margin: 2px 0 6px; font-size: 0.66rem; color: var(--ink-faint); }
.list-film .st-row, .list-film .st-cinema-name + .st-row { gap: 5px; padding: 0 0 4px; border-top: 0; }
.list-film .st-format { font-size: 0.76rem; font-weight: 600; color: var(--ink-faint); }
.list-film .st-format .imax-logo { opacity: 0.75; }
.list-film .st-times { display: flex; flex-wrap: wrap; gap: 5px; }
.list-film .st-time {
  width: auto; margin: 0; padding: 5px 9px; gap: 5px; border-radius: 7px;
  background: rgba(255, 255, 255, 0.06); box-shadow: none; font-size: 0.86rem;
}
.list-film :is(.st-end, .st-when) { display: none; } /* (the times alone, to compare; and how a show you've checked suits you) */
.list-film .st-time:not(.soon, .now) .st-dot { display: none; }
.list-film .st-dot { width: 7px; height: 7px; }
/* the grid's way to them on a phone (beside it, they're in the panel): quiet glass, as Trailer */
.grid-list {
  grid-column: 1 / -1; justify-self: start; display: none; align-items: center; gap: 10px; cursor: pointer;
  padding: 9px 18px 9px 15px; border-radius: 99px; border: 1px solid rgba(255, 255, 255, 0.16);
  background: rgba(255, 255, 255, 0.06); color: var(--ink); font-size: 0.88rem; font-weight: 600;
  transition: background .2s, transform .2s var(--ease);
}
.times-cover .grid-list { display: inline-flex; }
.grid-list:active { transform: scale(0.94); background: rgba(255, 255, 255, 0.16); transition-duration: .06s; }

/* ——— Grid view: the little cards laid out on the table, reaching left from the stack's right edge
   and down to the foot of the screen, 2 to 5 columns as the room allows (--grid-*, --cols:
   placeGrid), the stack and its controls hidden meanwhile; and in the showtimes' place, the
   details of the film pointed at (cards.js). ——— */
.grid-view {
  position: absolute; z-index: 1000; /* (under the deck, when it's on its way out: a card grows over it) */
  left: var(--grid-left, 0px); width: var(--grid-w, 100%); top: var(--grid-top, 0px); bottom: var(--grid-bottom, 0px);
  display: grid; grid-template-columns: repeat(var(--cols, 3), minmax(0, 1fr)); gap: 22px 14px; align-content: start;
  padding: 8px 20px 72px; overflow-y: auto; /* (20px beside: room for a little card to tilt into, not cut off: cards.js's GRID_SIDE) */ overscroll-behavior: contain; scrollbar-width: none;
  -webkit-mask-image: linear-gradient(transparent, #000 8px, #000 calc(100% - 64px), transparent);
  mask-image: linear-gradient(transparent, #000 8px, #000 calc(100% - 64px), transparent);
  opacity: 0; visibility: hidden; transition: opacity .3s var(--ease), visibility 0s .3s;
}
.grid-view::-webkit-scrollbar { display: none; }
.grid-mode .grid-view { z-index: 1002; opacity: 1; visibility: visible; transition: opacity .3s var(--ease), visibility 0s; }
/* a film taking the screen from it: gone, as the cards go for the showtimes (its scroll kept) */
.grid-mode.times-cover.showing-times .grid-view { opacity: 0; visibility: hidden; transition: opacity .3s var(--ease), visibility 0s .3s; }
.grid-mode .deck, .grid-mode :is(.deck-nav, .deck-actions, .next-show) { visibility: hidden; }
.opens-grid :is(.deck, .deck-nav, .deck-actions, .next-show) { visibility: hidden; } /* (the page opening in the grid, before it's drawn: cards.html) */
@media (max-width: 740px) { .grid-view { gap: 18px 12px; } }
/* the panel beside the grid: down to the foot of the screen, as the grid is, fading out where it does */
.grid-mode:not(.times-cover) .times-view { top: var(--grid-drop, 0px); height: auto; bottom: var(--grid-bottom, 0px); } /* (level with the grid: placeGrid) */
.grid-mode:not(.times-cover) .times-body {
  padding-bottom: 72px;
  -webkit-mask-image: linear-gradient(#000 calc(100% - 64px), transparent); mask-image: linear-gradient(#000 calc(100% - 64px), transparent);
}
.grid-mode:not(.times-cover) .times-body:not(.seat-page) { padding-bottom: 0; -webkit-mask-image: none; mask-image: none; }
.grid-mode:not(.times-cover) .st-scroll { padding-bottom: 72px; --fade-end: 64px; }
/* a film only pointed at: in brief, plain text in the showtimes' place (the times faded out
   meanwhile); a click on it chooses it (previewOf, cards.js) */
.film-info { /* (out 10px to the left, its text where it was: the room its rows' pulsing dots need, as it scrolls, so clips) */
  position: absolute; inset: 0 0 0 -10px; z-index: 2; overflow-y: auto; scrollbar-width: none; cursor: pointer;
  display: grid; align-content: start; gap: 16px; padding: 6px 2px 40px 12px;
  opacity: 0; visibility: hidden; transition: opacity .3s var(--ease), visibility 0s .3s;
}
.film-info::-webkit-scrollbar { display: none; }
.info-mode .film-info { opacity: 1; visibility: visible; transition: opacity .3s var(--ease) .1s, visibility 0s; }
.info-mode :is(.times-pages, .times-close, .times-back) { opacity: 0; visibility: hidden; }
.times-pages, .times-close { transition: opacity .3s var(--ease), visibility 0s; }
.film-info p { margin: 0; }
.film-info .st-title { padding-right: 0; }
/* its lead: the next few shows, as a short list in the showtimes' own type, each with its format
   quietly beside it; the first says how soon */
.info-next { display: grid; gap: 10px; }
.info-next-day { margin: 0; font-size: 0.7rem; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-faint); }
.info-next-list { margin: 0; padding: 0; list-style: none; display: grid; }
.info-show {
  display: grid; grid-template-columns: 7px 5.6rem minmax(0, 1fr) auto; align-items: baseline; gap: 10px; /* (wide enough for "12:45PM") */
  padding: 9px 0; border-top: 1px solid rgba(255, 255, 255, 0.06); font-variant-numeric: tabular-nums;
}
.info-show:first-child { border-top: 0; padding-top: 2px; }
.info-show-time { font-size: 1.1rem; font-weight: 700; letter-spacing: -0.01em; color: var(--ink); }
.info-show-format { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.8rem; color: var(--ink-faint); }
.info-show-format .imax-logo { opacity: 0.7; }
.info-show-when { white-space: nowrap; font-size: 0.82rem; color: var(--ink-soft); }
/* a started or soon show's dot, before its time as in the showtimes; its place kept on every row,
   so the times line up */
.info-show-dot { position: relative; align-self: center; width: 7px; height: 7px; border-radius: 50%; opacity: 0; pointer-events: none; background: var(--pulse); box-shadow: 0 0 8px var(--pulse); }
.info-show.soon .info-show-dot { --pulse: var(--soon); opacity: 1; }
.info-show.now .info-show-dot { --pulse: var(--now); opacity: 1; }
.info-show-dot::after { content: ""; position: absolute; inset: 0; border-radius: 50%; background: var(--pulse); opacity: 0; }
.info-show:is(.soon, .now) .info-show-dot::after { animation: pulse 1.8s ease-out infinite; }
.info-next-more, .info-next-none { font-size: 0.8rem; color: var(--ink-faint); }
.info-next-none { font-size: 0.95rem; }
/* then, secondary: what it is, in a line, and a little of its story */
.info-brief { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; padding-top: 14px; border-top: 1px solid rgba(255, 255, 255, 0.08); }
.info-summary.brief { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; font-size: 0.88rem; }
.info-hint { font-size: 0.76rem; color: var(--ink-faint); }

/* the scores, on their own line under what it is, each named in a quiet word ("94% critics") */
.info-scores { display: flex; flex-wrap: wrap; gap: 6px 16px; width: 100%; }
.info-score { display: inline-flex; align-items: center; gap: 5px; font-size: 0.86rem; font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
.info-score img { width: 15px; height: 15px; object-fit: contain; }
.info-score-label { font-size: 0.8rem; font-weight: 500; color: var(--ink-faint); }
.info-score.few { color: var(--ink-faint); } /* an IMDb rating from too few votes to count */
.st-head > .info-scores { margin-top: -8px; } /* the cards' showtimes: just under the film's name */
/* what it is and its scores, in a line, with its story under them */
.info-line { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; }
.info-meta { margin: 0; font-size: 0.72rem; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--gold); }
/* after its showtimes, what it is: runtime, genres and scores, its story, director and cast */
.info-about { display: grid; gap: 12px; margin-top: -16px; padding-top: 14px; border-top: 1px solid rgba(255, 255, 255, 0.08); } /* (-16px: with the panel's 20px gap, its line's as far below the last time as a cinema's is, and as far above its text) */
.info-summary { margin: 0; font-size: 0.92rem; line-height: 1.6; color: var(--ink-soft); text-wrap: pretty; }
.info-credits { margin: 0; display: grid; gap: 10px; font-size: 0.86rem; line-height: 1.45; }
.info-credits div { display: grid; grid-template-columns: 74px 1fr; gap: 12px; }
.info-credits dt { padding-top: 2px; font-size: 0.7rem; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-faint); }
.info-credits dd { margin: 0; color: var(--ink-soft); }
/* a name linked to its Rotten Tomatoes page: as the text, underlined when pointed at */
.info-credit { color: inherit; text-decoration: none; text-underline-offset: 3px; text-decoration-color: rgba(244, 241, 234, 0.4); }
@media (hover: hover) { .info-credit:hover { color: var(--ink); text-decoration-line: underline; } }
.info-credit:focus-visible { color: var(--ink); text-decoration-line: underline; }
/* the film chosen's trailer (grid view), up by its name beside the bookmark, as tall as it: there
   from its showtimes or a seat map alike; lit in the accent while it plays */
.times-trailer {
  position: absolute; top: calc(6px + (1.5rem * 1.1 - 34px) / 2); right: 88px; z-index: 1; height: 34px;
  display: inline-flex; align-items: center; gap: 7px; padding: 0 13px 0 10px; border-radius: 99px; cursor: pointer;
  border: 1px solid rgba(255, 255, 255, 0.16); background: rgba(255, 255, 255, 0.06); color: var(--ink);
  font: inherit; font-size: 0.8rem; font-weight: 600;
  transition: background .15s, border-color .15s, color .15s, opacity .3s var(--ease), visibility 0s, transform .2s var(--ease);
}
.times-trailer .yt { width: 16px; height: 11.5px; }
@media (hover: hover) { .times-trailer:hover { background: rgba(255, 255, 255, 0.12); border-color: rgba(255, 255, 255, 0.26); } }
.times-trailer:active { transform: scale(0.93); transition-duration: .06s; }
.playing .times-trailer { border-color: color-mix(in srgb, var(--accent) 70%, transparent); color: var(--accent); }
.table:not(.times-cover, .grid-mode) .times-trailer { right: 44px; } /* (beside the cards: the bookmark's in the ×'s place) */
.table:not(.times-cover, .grid-mode) .times-view:has(.times-trailer:not([hidden])) .times-body .st-title { padding-right: 152px; } /* (clear of both) */
.list-mode .times-trailer, .info-mode .times-trailer { opacity: 0; visibility: hidden; } /* (several films, or one in brief: as the bookmark) */
.times-cover .times-trailer { right: 44px; } /* (a phone: the bookmark's in the ×'s place) */
.times-cover.playing .times-trailer { opacity: 0; visibility: hidden; } /* (the video's × in its place) */
.grid-mode:not(.times-cover) .times-view:has(.times-trailer:not([hidden])) .times-body .st-title { padding-right: 196px; } /* (clear of all three) */
.times-cover .times-body .st-title { padding-right: 0; }
/* a name that would wrap beside the panel's buttons: under them instead, the panel's width its own
   (cards.js's placeTitle) */
.times-body .st-title.below { padding-right: 0 !important; padding-top: 40px; } /* (the screen's: its buttons are on the row above, by the way back, not beside it) */

/* each heading with its films: a section across the grid, on the grid's own columns */
.grid-section {
  grid-column: 1 / -1; display: grid; gap: inherit;
  grid-template-columns: repeat(var(--cols, 3), minmax(0, 1fr)); /* (without subgrid: the same columns) */
  grid-template-columns: subgrid;
}
.grid-section + .grid-section { margin-top: 14px; }
/* the grid's headings: when the films under them next show, big enough to catch the eye between
   the posters, with a hairline on to the edge. Scrolled, a heading stays at the top over its
   films, their bookmarks too, until the next one pushes it out; right across the grid, its room
   beside the cards too (one lifted and tilted there is under it). A card pointed at that's clear
   of it, lifted, rises over it instead (.risen: see cards.js's rise). */
.grid-group {
  grid-column: 1 / -1; display: flex; align-items: center; gap: 10px; margin: -8px -20px; padding: 12px 20px;
  position: sticky; top: -8px; z-index: 4; /* (over the grid's own 8px padding, its text just clear of the fade at the top; above a little card pointed at, its 1) */
  clip-path: inset(0); /* (its copy of the room, below, only within it) */
  font-size: 1.2rem; font-weight: 750; letter-spacing: -0.01em; color: var(--ink);
}
.grid-group::after { content: ""; flex: 1; height: 1px; background: rgba(255, 255, 255, 0.16); }
/* what it stands on: a copy of the room (.ambient: fixed, so just what's behind it), the films
   scrolled up under it hidden as if it were the grid's top (see cards.js's roomBehind) */
.room-behind {
  z-index: -1; background: var(--bg);
  inset: auto; left: var(--room-x, 0px); top: var(--room-y, 0px); width: var(--room-w, 100vw); height: var(--room-h, 100vh); /* (see cards.js's fitRooms) */
  transition: translate .6s var(--set-off); /* (the stack's slide, undone: below) */
}
/* the stack slid aside for the showtimes carries the copies with it (they're fixed to it: see
   fitRooms); slid back the other way with it, in step, they stay where the room is all along */
.showing-times .room-behind { translate: var(--shift, 0px) 0; }
.grid-group-note { font-size: 0.85rem; font-weight: 500; letter-spacing: 0; color: var(--ink-faint); }
/* a Top Rated heading's ⓘ, and what it says (cards.js's sayTier): how its films are put there */
.tier-info {
  position: relative; flex: none; display: grid; place-items: center; width: 20px; height: 20px; margin-left: -2px; padding: 0; border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.28); background: none; color: var(--ink-soft); cursor: pointer;
  transition: color .15s, border-color .15s, background .15s, transform .15s var(--ease);
}
.tier-info::after { content: ""; position: absolute; inset: -6px; border-radius: 50%; } /* (a little more than it's drawn, to a pointer too) */
.tier-info svg { display: block; width: 18px; height: 18px; fill: currentColor; } /* (an "i" drawn, the circle's middle its own: a letter's would sit as the font has it) */
/* pointed at, a purple wash; pressed, it dips; open, solid purple, so it's plain whose card it is */
@media (hover: hover) { .tier-info:hover { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 18%, transparent); color: var(--accent); } }
.tier-info:active { transform: scale(0.88); }
.tier-info:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tier-info[aria-expanded="true"] { border-color: var(--accent); background: var(--accent); color: rgb(18, 17, 24); }
.tier-pop {
  position: fixed; inset: auto; margin: 0; width: min(320px, calc(100vw - 24px)); padding: 16px 18px; box-sizing: border-box;
  border-radius: 14px; border: 1px solid rgba(255, 255, 255, 0.14); background: rgba(20, 18, 24, 0.97);
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.55); color: var(--ink); font-size: 0.86rem; line-height: 1.45;
}
.tier-pop h4 { margin: 0 0 4px; font-size: 1rem; }
.tier-pop p { margin: 0 0 10px; color: var(--ink-soft); }
.tier-pop .tier-pop-calc { font-size: 0.76rem; color: var(--ink-faint); }
.tier-pop .tier-pop-film { margin-bottom: 4px; font-size: 0.8rem; color: var(--ink-faint); }
.tier-pop-film b { font-weight: 600; color: var(--ink-soft); }
.tier-pop .tier-pop-sum { margin-bottom: 12px; color: var(--ink); }
/* each score's scale: poor, in between and good, as rounded pills, the cut-offs under the gaps;
   the example's score a dot on it, its part lit and the rest dim, its score at the end in its
   colour; a score that doesn't count (none yet, or IMDb's from too few votes), the scale faded */
.tier-pop-scales { display: grid; gap: 12px; padding-top: 12px; border-top: 1px solid rgba(255, 255, 255, 0.1); }
.tier-pop-scales { --poor: var(--full-most); --between: rgba(255, 255, 255, 0.55); --good: var(--full-low); }
.tier-key { display: flex; gap: 12px; font-size: 0.68rem; color: var(--ink-faint); }
.tier-key span { display: inline-flex; align-items: center; gap: 5px; }
.tier-key span::before { content: ""; width: 14px; height: 5px; border-radius: 3px; }
.tier-key .poor::before, .tier-scale-track .poor { background: var(--poor); }
.tier-key .between::before, .tier-scale-track .between { background: var(--between); }
.tier-key .good::before, .tier-scale-track .good { background: var(--good); }
.tier-scale { display: grid; grid-template-columns: 56px 1fr 34px; align-items: center; gap: 10px; padding-bottom: 13px; } /* (the cut-offs' room under the whole row: its name, scale and score on one line) */
.tier-scale-name { font-size: 0.74rem; color: var(--ink-soft); }
.tier-scale-track { position: relative; display: flex; gap: 3px; height: 7px; }
.tier-scale-track > i { height: 100%; border-radius: 4px; opacity: 0.35; }
.tier-scale-track > i.on { opacity: 1; box-shadow: 0 0 10px color-mix(in srgb, currentColor 45%, transparent); }
.tier-scale-track > i.poor { color: var(--poor); }
.tier-scale-track > i.between { color: var(--between); }
.tier-scale-track > i.good { color: var(--good); }
.tier-scale-track b { position: absolute; top: 100%; margin-top: 4px; translate: -50% 0; font-size: 0.64rem; font-weight: 400; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.tier-scale-dot {
  position: absolute; top: 50%; width: 11px; height: 11px; margin: -5.5px 0 0 -5.5px; border-radius: 50%;
  background: var(--ink); box-shadow: 0 0 0 2.5px rgba(20, 18, 24, 0.97), 0 1px 4px rgba(0, 0, 0, 0.6);
}
.tier-scale-value { font-size: 0.8rem; font-weight: 650; text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--ink-soft); }
.tier-scale-value.good { color: var(--good); }
.tier-scale-value.poor { color: var(--poor); }
.tier-scale.uncounted .tier-scale-track { opacity: 0.45; }
.tier-pop .tier-pop-foot { margin: 0; font-size: 0.7rem; color: var(--ink-faint); }
/* What's Hot's top band (150+ screenings), on fire: a flame before it, flickering, its tip
   swaying from its base, and the words themselves burning, a fire's colours drifting up through
   them under a warm glow. Still, for reduced motion. */
.flame { flex: none; width: 30px; height: 30px; margin: -6px -6px -6px -4px; overflow: visible; filter: drop-shadow(0 0 4px rgba(255, 110, 30, 0.6)); }
.flame-outer { fill: #ff6b1f; transform-origin: 50% 95%; animation: flicker 1.7s ease-in-out infinite; }
.flame-core { fill: #ffc94d; transform-origin: 50% 95%; animation: flicker 1.3s ease-in-out infinite reverse; }
@keyframes flicker {
  0%, 100% { transform: scale(1, 1) skewX(0deg); }
  25% { transform: scale(0.97, 1.06) skewX(-3deg); }
  50% { transform: scale(1.02, 0.95) skewX(2deg); }
  75% { transform: scale(0.98, 1.04) skewX(-1.5deg); }
}
.fire-words {
  background: linear-gradient(0deg, #ff4d1a, #ff8a1f 35%, #ffc94d 60%, #ff8a1f 85%, #ff4d1a) 0 0 / 100% 300%;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 0 6px rgba(255, 100, 30, 0.45));
  animation: burn 2.4s linear infinite;
}
@keyframes burn { to { background-position: 0 -300%; } }
@media (prefers-reduced-motion: reduce) { :is(.flame-outer, .flame-core, .fire-words) { animation: none; } }
@media (forced-colors: active) { .fire-words { color: CanvasText; background: none; } }
/* Top Rated's top tier (Rated highly), in gold: sparkles before it (rated-highly-icons.js's, mocked
   with the others), a glint twinkling at their top right, and the words in the cards' gold, a sheen
   sweeping across them now and then under a soft glow. Still, for reduced motion. */
.defs { position: absolute; }
.tier-mark { flex: none; width: 24px; height: 24px; margin: -4px -4px -4px -2px; overflow: visible; filter: drop-shadow(0 0 5px rgba(233, 207, 142, 0.55)); }
.tier-mark-fill { fill: url(#tier-gold); }
.tier-mark-glint { fill: #fff; transform-origin: 20px 4px; animation: twinkle 2.6s ease-in-out infinite; }
@keyframes twinkle {
  0%, 60%, 100% { transform: scale(0) rotate(0); opacity: 0; }
  75% { transform: scale(1.2) rotate(45deg); opacity: 1; }
  90% { transform: scale(0.6) rotate(90deg); opacity: 0.6; }
}
.gold-words {
  background: linear-gradient(100deg, #c99a3c 0%, #e9cf8e 35%, #fff6d6 50%, #e9cf8e 65%, #c99a3c 100%) 0 0 / 250% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 0 6px rgba(233, 207, 142, 0.35));
  animation: sheen 3.2s ease-in-out infinite;
}
@keyframes sheen { 0% { background-position: 100% 0; } 60%, 100% { background-position: -50% 0; } }
@media (prefers-reduced-motion: reduce) { :is(.tier-mark-glint, .gold-words) { animation: none; } .tier-mark-glint { opacity: 0; } }
@media (forced-colors: active) { .gold-words { color: CanvasText; background: none; } }
/* Up Next's Starting soon: the showtimes' own pulsing green dot before it (what that green means
   everywhere: within two hours), and the words in the green, glowing in time with the pulse */
.soon-dot { position: relative; flex: none; width: 10px; height: 10px; border-radius: 50%; background: var(--soon); box-shadow: 0 0 8px var(--soon); }
.soon-dot::after { content: ""; position: absolute; inset: 0; border-radius: 50%; background: var(--soon); opacity: 0; animation: pulse 1.8s ease-out infinite; }
.soon-words { color: #bff5d4; animation: soon-glow 1.8s ease-in-out infinite; }
@keyframes soon-glow { 0%, 100% { text-shadow: 0 0 0 rgba(61, 220, 132, 0); } 50% { text-shadow: 0 0 12px rgba(61, 220, 132, 0.55); } }
@media (prefers-reduced-motion: reduce) { .soon-dot::after, .soon-words { animation: none; } }

/* a little card (as the big ones: 63 × 88, the corners, the shade behind the name), then its next
   show under it. Pointed at, it lifts and tilts toward the pointer, a soft light under it; pressed,
   it dips, and let go, springs back up; the one chosen is ringed, and stays lifted (cards.js: lean,
   pickUp). Only the layer it's on moves (.tile-lift: the card and its bookmark), by its transform. */
.film-tile {
  position: relative; display: grid; align-content: start; min-width: 0;
  transition: z-index 0s .5s; /* let go: kept over the rest till it's back down (.tile-lift's .5s) */
}
.film-tile.pointed { z-index: 1; transition-delay: 0s; } /* (over its neighbours, as it grows: still under the headings' 4) */
/* lifted clear of its heading (not scrolled under it): over it, not cut off by it as it grows up
   toward it (cards.js's rise) */
.film-tile.risen:is(.tracking, .chosen) { z-index: 5; transition-delay: 0s; }
.film-tile.chosen { transition: none; } /* (it stays lifted: scrolled under its heading, under it at once) */
.tile-lift {
  position: relative;
  transform-origin: 50% 60%; /* (it tilts round a point a little below its middle, as a card held there would) */
  transition: transform .5s var(--ease); /* let go: back down on the table */
}
.film-tile.tracking .tile-lift { transition: transform .16s cubic-bezier(.2, .8, .4, 1); } /* following the pointer, a moment behind it */
.film-tile.tracking.pressed .tile-lift { transition: transform .09s cubic-bezier(.2, .8, .4, 1); } /* pressed: down at once */
/* let go of a press: up on a spring, overshooting a little, back, and settling (a damped spring:
   ζ 0.45; cards.js's springUp, for SPRING_TIME). (Where linear() isn't known, a curve that
   overshoots once.) */
.film-tile.springing .tile-lift {
  transition: transform .45s cubic-bezier(.3, 1.6, .5, 1);
  transition: transform .72s linear(0, 0.11, 0.361, 0.65, 0.904, 1.084, 1.181, 1.205, 1.178, 1.125, 1.066, 1.015, 0.98, 0.962, 0.958, 0.964, 0.976, 0.988, 0.998, 1.005, 1.008, 1.009, 1.007, 1.005, 1);
}
/* the one chosen, let go of: lifted as it was pointed at, level (the same functions as lean's, so
   it goes between them smoothly) */
.film-tile.chosen:not(.tracking) .tile-lift { transform: perspective(700px) translateY(-7px) scale(1.05) rotateX(0deg) rotateY(0deg); }
/* lifted: a deeper shadow under it, faded in (not a box-shadow redrawn as it moves) */
.tile-lift::before {
  content: ""; position: absolute; inset: 0; border-radius: 4.6% / calc(4.6% * 63 / 88); pointer-events: none;
  box-shadow: 0 0 0 1px rgba(255, 240, 200, 0.36), 0 28px 42px -20px rgba(0, 0, 0, 0.95);
  opacity: 0; transition: opacity .3s var(--ease);
}
.film-tile:is(.pointed, .chosen) .tile-lift::before { opacity: 1; }
.film-tile.pressed .tile-lift::before { opacity: 0.35; transition-duration: .09s; } /* (down on the table: hardly any) */
.tile-card {
  position: relative; display: block; width: 100%; aspect-ratio: 63 / 88; overflow: hidden; padding: 0; border: 0; cursor: pointer;
  isolation: isolate; /* (its layers stay inside it: all of it under a heading stuck at the top) */
  border-radius: 4.6% / calc(4.6% * 63 / 88); background: #15131b; color: var(--ink); font: inherit; text-align: left;
  box-shadow: 0 0 0 1px rgba(255, 240, 200, 0.16), 0 10px 22px -12px rgba(0, 0, 0, 0.9);
  container-type: inline-size; /* (its seals sized by it: cqw) */
  /* held down on a touch screen: no iOS callout (the poster's "Save Image") or text selection */
  -webkit-touch-callout: none; -webkit-user-select: none; user-select: none;
}
/* the light (as the grid's design D had it): a glare, always on, a bright spot falling off into
   shade (overlay: the poster's own lights lifted and its darks deepened, as a glossy card catches
   the light). At rest, in the middle; pointed at, much brighter, its spot under the pointer (slid
   there by cards.js's lean: it's twice the card's size, its middle on the spot); pressed, down out
   of the light a little. */
.tile-glare {
  position: absolute; left: 0; top: 0; z-index: 4; width: 200%; height: 200%; pointer-events: none;
  background: radial-gradient(circle at 50% 50%, rgba(255, 255, 255, 0.75) 0%, rgba(255, 255, 255, 0.2) 18%, rgba(0, 0, 0, 0.3) 48%);
  mix-blend-mode: overlay;
  opacity: 0.3; transform: translate(-25%, -25%);
  transition: opacity .35s var(--ease), transform .6s var(--ease);
}
.film-tile.tracking .tile-glare { transition: opacity .35s var(--ease), transform .16s cubic-bezier(.2, .8, .4, 1); } /* (following the pointer) */
.film-tile:is(.tracking, .chosen) .tile-glare { opacity: 0.85; }
.film-tile.tracking.pressed .tile-glare { opacity: 0.5; transition-duration: .09s, .16s; }
/* picked up (chosen): a sheen sweeps across it, a soft band, skewed as a reflection would be
   (cards.js's pickUp moves it; at rest, off past its right edge). Overlay too: the poster's own
   colours lit up as it passes, not white laid over them. */
.tile-sheen {
  position: absolute; top: -10%; bottom: -10%; left: 0; z-index: 5; width: 45%; pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4) 50%, transparent);
  mix-blend-mode: overlay;
  transform: translateX(270%);
}
.tile-art { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 20%; }
/* the name, only on a film with no poster */
.tile-name {
  position: absolute; left: 10%; right: 10%; bottom: 9%; z-index: 3;
  font-size: 0.86rem; font-weight: 800; line-height: 1.12; letter-spacing: -0.02em; text-wrap: balance;
  text-shadow: 0 1px 10px rgba(0, 0, 0, 0.7);
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
/* its awards' seals (cards.js's tileSeals), the card's made small: each award's icon on a dark
   disc in a gold rim, a coin more than a stamp, with no name round it (at this size, a few pixels
   high). Bottom left: over a poster's small print (its credits, its date), clear of the bookmark,
   and over its title less often than any other corner (tried on all of them). Two overlap, as on
   the card. They lift with the card, as they're on it. */
.tile-seals {
  position: absolute; left: 3.5cqw; bottom: 3.5cqw; z-index: 2; display: flex; pointer-events: none;
  --d: max(22cqw, 34px); /* (each one across: never smaller than its icon can be made out) */
}
.tile-name ~ .tile-seals { top: 3.5cqw; bottom: auto; } /* (no poster: the name's at the bottom) */
.tile-seal {
  --seal: #fa320a; /* the award's colour, a glow from within */
  display: grid; place-items: center; width: var(--d); aspect-ratio: 1; border-radius: 50%;
  border: calc(var(--d) * 0.06) solid transparent; /* the rim: the gold's drawn under it */
  background:
    radial-gradient(circle at 50% 30%, #33211b, #0b090d 75%) padding-box,
    conic-gradient(from 210deg, #fff4cf, #c99a45, #f8e6b0, #7d5a22, #fbe6ad, #a77a33, #fff4cf) border-box;
  box-shadow:
    inset 0 0 0 calc(var(--d) * 0.02) rgba(0, 0, 0, 0.55), /* (the rim's inner edge) */
    inset 0 0 calc(var(--d) * 0.11) color-mix(in srgb, var(--seal) 35%, transparent),
    0 0 0 1px rgba(0, 0, 0, 0.35), 0 calc(var(--d) * 0.05) calc(var(--d) * 0.12) rgba(0, 0, 0, 0.7);
}
.tile-seal.seal-hot { --seal: #ff8a00; }
.tile-seal + .tile-seal { margin-left: calc(var(--d) * -0.18); }
.tile-seal img {
  width: 57%; height: 57%; object-fit: contain;
  filter: drop-shadow(0 0 calc(var(--d) * 0.05) color-mix(in srgb, var(--seal) 70%, transparent));
}
/* the film chosen: ringed, as the toggles show what's on */
.film-tile.chosen .tile-card, .film-tile.chosen.pointed .tile-card {
  box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--accent), 0 14px 28px -12px rgba(0, 0, 0, 0.95);
}
/* its next show: its time, and starting soon, how soon, with a green dot (red: just started, as
   the showtimes' dots) */
.tile-when {
  display: flex; align-items: center; gap: 7px; margin-top: 9px; min-width: 0; white-space: nowrap; overflow: hidden;
  font-size: 0.78rem; color: var(--ink-faint); font-variant-numeric: tabular-nums;
}
.tile-when b { font-weight: 600; color: var(--ink-soft); }
.tile-when span { overflow: hidden; text-overflow: ellipsis; }
.tile-when:is(.soon, .now) b { color: var(--ink); }
/* (room on its left for its dot's pulse, as it clips what's outside it, for its "…": the text where it was) */
.tile-when { --dot: 6px; --dot-x: 6px; padding-left: 6px; margin-left: -6px; }
.tile-when:is(.soon, .now)::before { content: ""; flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--soon); box-shadow: 0 0 6px var(--soon); }
.tile-when.now::before { background: var(--now); box-shadow: 0 0 6px var(--now); }
/* its bookmark: a ribbon tucked in at the top edge, there while it's on your shortlist, and on a
   little card pointed at, to put it on; it lifts and tilts with the card, on its layer (.tile-lift).
   Pressed, it's the bookmark that's pressed, not the card under it. (On a touch screen, just a mark:
   a tap near it is for the film, and the film's panel has its own.) */
.tile-save {
  position: absolute; top: 0; right: 7%; z-index: 3; width: 28px; height: 30px; padding: 0; border: 0;
  background: none; cursor: pointer; overflow: hidden; /* (cut straight along the card's top) */
  opacity: 0; transition: opacity .2s var(--ease);
}
.tile-save .icon-save {
  position: absolute; left: -1px; top: -7px; width: 30px; height: 30px;
  fill: rgba(10, 9, 14, 0.78); stroke: rgba(255, 255, 255, 0.85); stroke-width: 1.4;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.6));
  transition: fill .2s, stroke .2s;
}
.tile-save[aria-pressed="true"] .icon-save { fill: var(--accent); stroke: none; }
/* (shown by .pointed, which only a mouse sets, never by :hover: iOS Safari takes a first tap on
   anything a :hover would reveal as just the hover, so the film needed a second tap to open) */
.film-tile.pointed .tile-save, .tile-save[aria-pressed="true"] { opacity: 1; }
@media (hover: hover) { .tile-save:hover .icon-save { stroke: #fff; fill: color-mix(in srgb, var(--accent) 35%, rgba(10, 9, 14, 0.78)); } }
@media (hover: hover) { .tile-save[aria-pressed="true"]:hover .icon-save { fill: color-mix(in srgb, var(--accent) 80%, #fff); } }
@media (hover: none) { .tile-save { pointer-events: none; } }
/* switching to the grid: the little cards laid out one after another, like a hand of cards (--n:
   its place, from cards.js) */
.grid-mode :is(.film-tile, .grid-group) { animation: tile-in .34s var(--ease) backwards; animation-delay: calc(40ms + var(--n, 0) * 22ms); }
.grid-mode .grid-group { animation-name: fade; }
.grid-mode .dealt :is(.film-tile, .grid-group) { animation: fade .3s var(--ease); } /* moved round as the clock goes on: just fade in place */
@keyframes tile-in { from { opacity: 0; transform: translateY(12px) scale(0.97); } }
@media (prefers-reduced-motion: reduce) {
  .grid-mode :is(.film-tile, .grid-group) { animation: none !important; }
  /* still: no lift, tilt or spring (cards.js draws none), just the shadow and the ring, and the
     glare at rest in the middle (a light, not a move) */
  .tile-lift, .film-tile.chosen:not(.tracking) .tile-lift { transform: none; transition: none; }
  .tile-glare { transition: none; }
  .tile-sheen { display: none; }
}

/* ——— The screen: the chosen film's trailer, in the grid's place (placed by cards.js: from the
   left margin to the grid's right edge), as big as fits there, its showtimes still beside it; the
   grid fades out from under it, and the lights go down. On a phone, docked at the top, full width,
   the showtimes moved down under it, so you can still find a time and seats as it plays. ——— */
.screen {
  position: fixed; z-index: 1100; display: grid; place-items: center; container-type: size;
  opacity: 0; visibility: hidden; transition: opacity .4s var(--ease), visibility 0s .4s;
}
.playing .screen { opacity: 1; visibility: visible; transition: opacity .5s var(--ease) .12s, visibility 0s; }
.grid-mode.playing .grid-view { opacity: 0; visibility: hidden; transition: opacity .35s var(--ease), visibility 0s .35s; }
body:has(.table.playing) .ambient img.on { opacity: 0.3; }
.screen-video {
  position: relative; width: min(100cqw, calc((100cqh - 100px) * 16 / 9)); aspect-ratio: 16 / 9; border-radius: 12px; background: #000;
  box-shadow: 0 0 0 1px rgba(255, 240, 200, 0.14), 0 40px 100px -30px rgba(0, 0, 0, 0.95);
  transform: scale(0.96); transition: transform .7s var(--set-off);
}
.playing .screen-video { transform: none; }
.screen-video iframe { display: block; width: 100%; height: 100%; border: 0; border-radius: inherit; background: #000; }
/* beside the panel, its top level with the film's name (placeScreen), its × on its corner */
.table:not(.times-cover) .screen { place-items: start center; }
.table:not(.times-cover) .screen-video { width: min(100cqw, calc(100cqh * 16 / 9)); }
.times-close.screen-close { display: grid; top: -13px; right: -13px; background: rgba(22, 20, 28, 0.96); border-color: rgba(255, 255, 255, 0.22); }
/* a phone: docked at the top (below its notch), the showtimes moved down under it, its × in the
   Trailer button's place beside the bookmark */
.times-cover .screen {
  inset: 0 0 auto 0; height: calc(100vw * 9 / 16 + env(safe-area-inset-top));
  padding: env(safe-area-inset-top) 0 0; place-items: stretch; background: #000;
}
.times-cover .screen-video { width: 100%; height: 100%; border-radius: 0; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.7); transform: none; }
.times-cover .times-close.screen-close { top: auto; bottom: -60px; right: 60px; z-index: 2; } /* (level with the bookmark) */
.screen-close-label { display: none; }
/* there, in the Trailer button's place, it says what it closes: "× Trailer", a pill as that button is */
.times-cover .times-close.screen-close {
  display: inline-flex; align-items: center; gap: 7px; width: auto; padding: 0 13px 0 11px; border-radius: 99px;
  font: inherit; font-size: 0.8rem; font-weight: 600; color: var(--ink);
}
.times-cover .screen-close-label { display: inline; }
.times-cover.playing .times-view { /* (moved down: its transition, with .times-cover .times-view's) */
  translate: 0 calc(100vw * 9 / 16 + 8px);
  height: calc(var(--times-h, 100%) - env(safe-area-inset-top) - env(safe-area-inset-bottom) - 100vw * 9 / 16 - 8px);
}
@media (prefers-reduced-motion: reduce) {
  .screen-video { transform: none; transition: none; }
  .times-cover .times-view { transition: none; } /* (as without the trailer: below) */
}

.tcg.out { display: none; } /* not in your preferences */
.table.empty .stack, .table.empty .deck-nav, .table.empty .deck-actions { display: none; }
.deck-empty { margin: 0; max-width: 340px; text-align: center; color: var(--ink-soft); line-height: 1.6; }
.link { border: 0; background: none; padding: 0; color: var(--accent); font: inherit; cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }

/* ——— Trailer: the video over everything ——— */

.trailer {
  width: min(92vw, 1120px, calc(86svh * 16 / 9)); max-width: none; padding: 0; border: 0; overflow: visible;
  background: transparent;
}
.trailer::backdrop { background: rgba(4, 4, 6, 0.82); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); }
.trailer[open] { animation: rise .35s var(--ease); }
.trailer-video {
  position: relative; aspect-ratio: 16 / 9; overflow: hidden; border-radius: 14px; background: #000;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 30%, transparent), 0 40px 120px rgba(0, 0, 0, 0.8);
}
.trailer-video iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.trailer form { position: absolute; top: -48px; right: 0; margin: 0; }
/* a phone on its side: short enough for its × above it */
@media (orientation: landscape) and (max-height: 499px) { .trailer { width: min(92vw, calc((100svh - 110px) * 16 / 9)); } }
@keyframes rise { from { opacity: 0; transform: translateY(14px) scale(0.98); } }

/* ——— A finger's reach: on a touch screen every control takes a tap about 44px across (Apple's
   guide), more than a pointer needs. The small round ones and the links answer a little beyond
   what's drawn, so they look the same; rows and pills just grow a little. ——— */
@media (pointer: coarse) {
  :is(.times-close, .trailer-close, .seat-expand, .seat-back, .view-toggle button, .deck-button, .prefs-open, .when-clear, .sort-open, .short-toggle, .times-save, .seat-party-step)::after {
    content: ""; position: absolute; inset: -5px;
  }
  .trailer-close, .seat-back, .view-toggle button, .deck-button, .prefs-open, .when-clear, .sort-open, .seat-party-step { position: relative; }
  .seat-party-step::after { inset: -4px; } /* (36px drawn: tapped again and again) */
  .seat-expand::after { inset: -7px; }
  .tier-info::after { inset: -12px; } /* (20px drawn: 44px to a finger) */
  .view-toggle button::after { inset: -6px 0; } /* (side by side: only up and down) */
  .when-clear::after { inset: -9px -6px; }
  .seat-back::after { inset: -5px -10px -5px -8px; }
  .deck-button::after, .prefs-open::after, .sort-open::after, .short-toggle::after { inset: -3px; }
  /* the chevrons either side of a seat map's time: stepping to the next show is what you do there */
  .seat-step { width: 44px; height: 44px; }
  .seat-pick { margin-left: -15px; } /* (the chevron where it was) */
  .st-time { padding-block: 11px; }
  .st-day { padding: 8px 0 12px; }
  .deck-action { padding-block: 11px; }
  .seat-book { padding-block: 13px; }
  .seat-share { padding-block: 12px; }
}

/* ——— Pressed: every button answers a touch, down and up (a phone has no hover to show it). It
   sinks quickly while held and springs back over its own transition. (iOS only applies :active
   with a touch listener on the page: see cards.js.) ——— */
:is(.deck-button, .deck-action, .deck-save, .times-close, .times-save, .trailer-close, .prefs-open, .sort-open, .short-toggle, .seat-step, .seat-party-step, .seat-expand, .seat-book):active:not(:disabled) {
  transform: scale(0.92); transition-duration: .06s;
}
.when-clear:active { transform: scale(0.85); transition-duration: .06s; }
.deck-button:active { background: rgba(255, 255, 255, 0.16); border-color: rgba(255, 255, 255, 0.3); color: var(--ink); }
.deck-action:active { background: rgba(255, 255, 255, 0.16); }
.seat-expand:active { background: color-mix(in srgb, var(--accent) 26%, transparent); }
.deck-action[data-showtimes-open]:active { background: var(--accent-grad); }
.deck-action[data-showtimes-open]:active, .seat-book:active { filter: brightness(1.15); }
.times-close:active, .trailer-close:active, .prefs-open:active, .sort-open:active, .short-toggle:active:not([aria-pressed="true"]) { background: rgba(255, 255, 255, 0.18); color: var(--ink); }
:is(.seat-step, .seat-party-step):active:not(:disabled) { background: rgba(255, 255, 255, 0.12); color: var(--ink); }
/* rows and words light up rather than shrink */
.st-time:active { background: color-mix(in srgb, var(--accent) 20%, transparent); color: var(--accent); transition-duration: .06s; }
.st-day:active, .seat-back:active { color: var(--ink); }
.link:active { opacity: 0.7; }

@media (prefers-reduced-motion: reduce) {
  .tcg, .tcg-face, .ambient img { transition: none; }
  .trailer[open], .st-panel, :is(.st-dot, .info-show-dot)::after, :is(.tile-when, .next-show)::after { animation: none !important; }
  .stack, .deck, .times-view, .times-body { transition: none; }
  .seat-map.loading::after { animation: none; }
  /* the panels fade in, rather than rise or slide up; the notes come and go in place */
  :is(.prefs, .find, .seat-full, dialog.sheet)[open], .find.from-bar[open] { animation-name: fade; } /* (dialog.sheet: over its own, sheet-glass; the bar's, over its growing) */
  .find.from-bar.closing { animation-name: fade-out; }
  .pref.refused .switch { animation: none; } /* (its words say why: "Keep at least one language") */
  .undo-note, .undo-note.shown { translate: var(--x) 0; }
  .deck-lap, .deck-lap.shown { translate: -50% 0; }
}

/* Windows' high contrast (forced colours) takes away backgrounds and shadows: the icons drawn with
   them, and the switches, keep theirs, in its colours (the system's: light or dark); what's pressed
   or chosen is its highlight */
@media (forced-colors: active) {
  [class^="icon-"], [class*=" icon-"], .clapper, .switch { forced-color-adjust: none; color: ButtonText; }
  :is(.view-toggle button, .short-toggle)[aria-pressed="true"] :is([class^="icon-"], [class*=" icon-"]) { color: HighlightText; }
  .icon-sliders::before, .icon-sliders::after { background: ButtonFace; }
  .switch { border: 1px solid CanvasText; background: Canvas; }
  .switch::after { background: CanvasText; }
  .pref:has(input:checked) .switch { background: Highlight; }
  .pref:has(input:checked) .switch::after { background: HighlightText; }
  :is(.view-toggle button, .short-toggle)[aria-pressed="true"], .st-day[aria-selected="true"] { forced-color-adjust: none; background: Highlight; color: HighlightText; }
  .tick { forced-color-adjust: none; box-shadow: inset 0 0 0 2px CanvasText; }
  .pref:has(input:checked) .tick { background: HighlightText; box-shadow: inset 0 0 0 7px Highlight; }
  .film-tile.chosen .tile-card { outline: 2px solid Highlight; outline-offset: 2px; }
  .tile-seal { border-color: CanvasText; } /* (the gold gone: a plain ring round each award's icon) */
}
