/* The player shared by the films in examples/: the theater around the 16:9 stage, the transport, the score
   drawer. A film brings its own stylesheet for what is inside #frame and can recolour the chrome through the
   --ui-* properties. */
:root {
  --theater: #0c0b09;
  --mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Consolas, "Liberation Mono", monospace;
  --ui-fg: #F1ECE1;       /* the played part of the bar, the knob, the play button, the clock */
  --ui-ink: #16130F;      /* the icon on the play button */
  --ui-hot: #F0421C;      /* the knob's ring, the drawer's title, the score line that is playing */
  --ui-accent: #FFB81C;   /* focus rings, switched-on buttons, the drawer's times */
}
* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; background: var(--theater); color: #d9d3c6; font-family: var(--mono); }
body { overflow: hidden; }
#theater { height: 100%; display: flex; align-items: center; justify-content: center; padding: 10px 14px; transition: padding .25s; }
#deck { --chrome: 118px; width: min(100%, calc((100vh - var(--chrome)) * 16 / 9)); width: min(100%, calc((100dvh - var(--chrome)) * 16 / 9)); flex: none; }   /* vh first: a browser without dvh keeps it */

/* the 16:9 stage; #frame is a fixed 1920x1080 world scaled to fit (--k set from JS) */
#stage { position: relative; width: 100%; aspect-ratio: 16 / 9; cursor: pointer; overflow: hidden; border-radius: 4px; box-shadow: 0 30px 80px #000a, 0 0 0 1px #ffffff10; flex: none; }
#frame { position: absolute; left: 0; top: 0; width: 1920px; height: 1080px; transform-origin: 0 0; transform: scale(var(--k, .5)); overflow: hidden; }

/* ── the player ───────────────────────────────────────────────────────────── */
#player { margin-top: 8px; user-select: none; }
#scrub { position: relative; height: 22px; cursor: pointer; touch-action: none; outline: none; }
#scrub .chapters { position: absolute; left: 0; right: 0; top: 8px; height: 5px; display: flex; background: #2b2823; border-radius: 3px; overflow: hidden; transition: top .12s, height .12s; }
#scrub:hover .chapters, #scrub.drag .chapters, #scrub:focus-visible .chapters { top: 6px; height: 9px; }
#scrub .chapters i { display: block; height: 100%; border-right: 2px solid var(--theater); position: relative; z-index: 2; }
#scrub .chapters i:last-child { border-right: 0; }
#scrub .played { will-change: transform; position: absolute; left: 0; right: 0; top: 8px; height: 5px; transform-origin: 0 50%; transform: scaleX(0); background: var(--ui-fg); border-radius: 3px; transition: top .12s, height .12s; z-index: 1; }
#scrub:hover .played, #scrub.drag .played, #scrub:focus-visible .played { top: 6px; height: 9px; }
#scrub .head { will-change: transform; position: absolute; inset: 0; pointer-events: none; z-index: 3; }   /* moves the knob by its own width: 100% = the bar */
#scrub .knob { position: absolute; left: -7px; top: 3px; width: 14px; height: 14px; border-radius: 50%; background: var(--ui-fg); box-shadow: 0 0 0 3px var(--ui-hot); scale: 0; transition: scale .12s; }
#scrub:hover .knob, #scrub.drag .knob, #scrub:focus-visible .knob { scale: 1; }
#scrub .tip { position: absolute; bottom: 26px; left: 0; padding: 4px 8px; background: #000c; border-radius: 4px; font-size: 12px; white-space: pre; opacity: 0; pointer-events: none; transition: opacity .12s; }
#scrub:hover .tip { opacity: 1; }
#controls { display: flex; align-items: center; gap: 2px; padding-top: 2px; }
#controls button { flex: none; appearance: none; border: 0; background: transparent; color: #cfc9bc; width: 38px; height: 38px; border-radius: 8px; display: grid; place-items: center; cursor: pointer; font: 600 13px var(--mono); }
#controls button:hover { background: #ffffff14; color: #fff; }
#controls button:focus-visible, #scrub:focus-visible { outline: 2px solid var(--ui-accent); outline-offset: 2px; }
#controls button.main { background: var(--ui-fg); color: var(--ui-ink); width: 42px; height: 42px; border-radius: 50%; margin: 0 4px; }
#controls button.main:hover { background: #fff; }
#controls button.txt { width: auto; padding: 0 10px; }
#controls button.on { color: var(--ui-accent); }
#time { font: 500 14px var(--mono); margin-left: 10px; color: var(--ui-fg); white-space: nowrap; }
#time em { font-style: normal; opacity: .5; }
#chap { white-space: nowrap; margin-left: 14px; font: 500 12px var(--mono); letter-spacing: .1em; text-transform: uppercase; opacity: .55; }
.grow { flex: 1; }
/* The keys hint reads at about 6:1 on the night (WCAG AA 4.5): .38 was 3.3. */
#hint { margin: 6px 0 0; text-align: center; font: 12px var(--mono); opacity: .6; letter-spacing: .04em; }
kbd { font: inherit; padding: 0 5px; border: 1px solid #ffffff30; border-radius: 3px; margin: 0 2px; }

/* the score drawer */
#source { position: fixed; right: 0; top: 0; bottom: 0; width: 400px; padding: 22px 22px 40px; overflow: auto; background: #141210; border-left: 1px solid #ffffff14; transform: translateX(100%); transition: transform .25s; font-size: 13px; line-height: 1.5; z-index: 5; }
body.source-open #source { transform: none; }
body.source-open #theater { padding-right: 420px; }
#source .close { position: sticky; top: 0; z-index: 1; display: grid; place-items: center; width: 38px; height: 38px; margin: -10px -10px -28px auto; border: 0; border-radius: 8px; background: #141210; color: #cfc9bc; cursor: pointer; }
#source .close:hover { background: #ffffff14; color: #fff; }
#source .close:focus-visible { outline: 2px solid var(--ui-accent); outline-offset: 2px; }
#source h2 { margin: 0 0 8px; font: 600 12px var(--mono); letter-spacing: .18em; text-transform: uppercase; color: var(--ui-hot); }
#source .lede { margin: 0 0 16px; opacity: .7; }
#source ol { list-style: none; margin: 0; padding: 0; }
#source li { display: flex; gap: 12px; padding: 7px 8px 7px 10px; border-left: 2px solid transparent; cursor: pointer; opacity: .55; }
#source li:hover { opacity: .9; background: #ffffff08; }
#source li.now { opacity: 1; border-left-color: var(--ui-hot); background: #ffffff0c; }
#source time { flex: none; width: 44px; color: var(--ui-accent); font-variant-numeric: tabular-nums; }
#source time small { opacity: .6; }
@media (max-width: 900px) { body.source-open #theater { padding-right: 14px; } #source { width: min(92vw, 400px); } }
/* a phone: the frame stays as large as it can be, the controls keep only what a thumb needs */
@media (max-width: 640px) {
  #theater { padding: 8px; }
  #deck { --chrome: 96px; }
  #controls [data-a=prev], #controls [data-a=next], #controls [data-a=back], #controls [data-a=fwd], #controls [data-a=loop], #chap, #hint { display: none; }
  #controls button.main { margin-left: 0; }
}
@media (hover: none) { #hint { display: none; } }
@media (prefers-reduced-motion: reduce) { * { transition: none !important; } }

.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* DECK: what is inside #frame. The theater, the transport and the score drawer come from ../reel/player.css. */
:root {
  --theater: #060808;
  --ui-fg: #F3EBDD;
  --ui-ink: #140F0C;
  --ui-hot: #C9243A;
  --ui-accent: #D8B464;
  --serif: "Palatino Linotype", Palatino, "Book Antiqua", P052, "URW Palladio L", "Noto Serif", Georgia, serif;
}
#stage, #frame { background: #040605; }
#bg, #shake, #view, #vignette, #titles, #flash, #dark { position: absolute; left: 0; top: 0; width: 1920px; height: 1080px; pointer-events: none; }
#bg { background: radial-gradient(ellipse 72% 85% at 50% 56%, #12281f 0%, #0a1712 50%, #030504 100%); }

/* the camera: #view holds the lens (perspective), #table is the world it turns */
#view { perspective: 1500px; perspective-origin: 50% 50%; }
#table, #lift { position: absolute; inset: 0; transform-style: preserve-3d; transform-origin: 50% 50%; }
/* the ace's own layer: it is never under another card, so it is drawn over the table instead of being depth
   sorted with it (Firefox mis-sorted the fan's end cards while the ace stood tilted above them) */
#lift { pointer-events: none; }
/* the table's surface: a lit patch of felt, and the cards' shadows drawn on it. It stays small and fades out
   inside its own box: WebKit stops painting a large plane tilted this far at a straight line across it. */
#felt {
  position: absolute; left: 50%; top: 50%; width: 1800px; height: 1800px; margin: -900px 0 0 -900px;
  background: radial-gradient(closest-side, #2e6a4b8c 0%, #1b4a3466 36%, #0f2e2130 68%, #0000 100%);
}
.shade { position: absolute; left: 50%; top: 50%; width: 280px; height: 376px; margin: -188px 0 0 -140px; background: var(--card-shade) center / 100% 100% no-repeat; opacity: 0; }
#ghost {
  position: absolute; left: 50%; top: 50%; width: 240px; height: 336px; margin: -168px 0 0 -120px; border-radius: 16px;
  border: 5px dashed #D8B464cc; box-shadow: 0 0 40px #D8B46455, inset 0 0 30px #D8B46433; opacity: 0;
}

/* a card: a 3D node with a face on each side */
.card { position: absolute; left: 50%; top: 50%; width: 240px; height: 336px; margin: -168px 0 0 -120px; transform-style: preserve-3d; }
/* will-change keeps each face on a layer rasterized once: without it Chromium re-rasterized the cards whenever
   their size on screen changed (the spring lifts 51 of them toward the camera), and a frame with a face still
   rasterizing is held back, 60-70 ms at a time. Measured: 35-57 dropped frames in the riffle and spring -> 6-8. */
.face { position: absolute; inset: 0; border-radius: 14px; overflow: hidden; backface-visibility: hidden; -webkit-backface-visibility: hidden; will-change: transform; }
.face svg { display: block; width: 100%; height: 100%; }
.back { background: var(--card-back) center / 100% 100% no-repeat; }
.tilt { position: absolute; inset: 0; transform-style: preserve-3d; }
.front { transform: rotateY(180deg); }
.gloss { position: absolute; left: 50%; top: -30%; width: 90px; height: 160%; margin-left: -45px; background: linear-gradient(90deg, #fff0 0%, #fffbeecc 50%, #fff0 100%); mix-blend-mode: soft-light; }

/* lights and titles, in front of the camera */
#vignette { left: -960px; top: -540px; width: 3840px; height: 2160px; background: radial-gradient(ellipse 50% 50% at 50% 50%, #0000 36%, #00000080 58%, #000000e6 82%); }
.title {
  position: absolute; left: 0; width: 100%; margin: 0; text-align: center; white-space: nowrap;
  font: italic 400 84px/1.1 var(--serif); letter-spacing: .01em; color: #F4EAD6;
  text-shadow: 0 0 30px #D8B46459, 0 2px 4px #000c;
}
#t-pick { top: 858px; }
#t-this { top: 884px; }
.caption { position: absolute; left: 0; width: 100%; top: 1004px; margin: 0; text-align: center; font: 400 21px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; color: #F4EAD6; }
#flash { background: radial-gradient(circle at 50% 50%, #FFFDF6 0%, #FFF4DCf2 30%, #FFE3B899 58%, #FFD9A022 100%); opacity: 0; }
#dark { background: #000; }
#grain { position: absolute; width: 2200px; height: 1400px; left: -140px; top: -160px; pointer-events: none; opacity: .32; background-size: 256px 256px; }

#veil { position: absolute; inset: 0; display: grid; place-items: center; background: #040605; color: #F3EBDD66; font: italic 18px var(--serif); letter-spacing: .08em; transition: opacity .3s; }
#veil.gone { opacity: 0; pointer-events: none; }
