/* Copyright (c) 2026 Ascent. All rights reserved. PRIVATE TABLE — https://poker.ascent-web.jp/terms */
/* 確定演出 — the two tells before a river that has to come.
 *
 * kakutei.js builds two throwaway roots for the river slot: a `.kk-under`
 * inside `.felt`, beneath everything on the table, and a `.kk-over` in
 * #animLayer, above the card's flying copy. Both are *points* at the slot's
 * centre carrying the card's box as `--card-w` / `--card-h`; children place
 * themselves around that point in card units, and the few that cover the
 * whole play area take its box from `--cover-*`.
 *
 * Nothing here moves on its own. Every animation is gated on a phase class
 * kakutei.js puts on #screenTable — `kk-omen` before the card lands,
 * `kk-charge` while it lies face down, `kk-release` from the flip — so a node
 * that outlives its phase is inert, and a skip that strips the classes stops
 * everything at once.
 *
 * Colours are the table's own (tokens.css), written as rgba where an alpha is
 * needed: light is --ink and --lime; the dark is the felt's own night.
 */

.kk {
  position: absolute;
  width: 0;
  height: 0;
  pointer-events: none;
}
/* Inside the felt: above its run-out dim (`::after`, no index) and its strike
   (`::before`, index 1), still inside the felt's own stacking context and so
   still under everything on the table. */
.felt > .kk-under { z-index: 2; }
.kk > * { position: absolute; left: 0; top: 0; }

/* A child the size of the whole play area. */
.kk-cover {
  left: var(--cover-left);
  top: var(--cover-top);
  width: var(--cover-w);
  height: var(--cover-h);
}

/* The seat whose river this is: its percentage breathes in the same light
   the tell uses, from the omen to the end. On the number, wherever the table
   put it — your own panel or an opponent's pod — so the tell reads the same
   from the chair that hit it, the chair it hit and a chair that only
   watched. The text itself is untouched. */
.seat-equity-value.kk-mark { animation: kkMark 640ms ease-in-out infinite alternate; }
@keyframes kkMark {
  from { text-shadow: 0 0 0 rgba(198, 242, 78, 0); }
  to { text-shadow: 0 0 6px rgba(243, 246, 242, .9), 0 0 16px rgba(198, 242, 78, .85); }
}

/* The ring every burst shares: a circle on the slot that grows and fades. */
.kk-ring {
  left: calc(var(--card-w) * -.6);
  top: calc(var(--card-w) * -.6);
  width: calc(var(--card-w) * 1.2);
  height: calc(var(--card-w) * 1.2);
  border-radius: 50%;
  border: 3px solid rgba(243, 246, 242, .9);
  box-shadow: 0 0 18px rgba(198, 242, 78, .55), inset 0 0 12px rgba(198, 242, 78, .35);
  opacity: 0;
}
.kk-release .kk-ring { animation: kkRing 560ms cubic-bezier(.12, .74, .3, 1) both; }
.kk-release .kk-ring--2 { animation-delay: 130ms; animation-duration: 640ms; }
@keyframes kkRing {
  0% { opacity: .95; transform: scale(.35); }
  100% { opacity: 0; transform: scale(3.2); }
}

/* ======================================================================
 * B. strike — a hit from outside.
 * The cloth darkens as the card flies in; while it lies face down the sky
 * flickers and three thin bolts find it. At the half-turn the big one lands:
 * a whiteout, a shockwave ring and the table itself jolts. This is the
 * 「パーン」.
 * ==================================================================== */

.kk--strike .kk-storm {
  background: radial-gradient(circle at calc(-1 * var(--cover-left)) calc(-1 * var(--cover-top)), transparent 8%, rgba(4, 8, 20, .74) 64%);
  opacity: 0;
}
.kk-omen .kk--strike .kk-storm,
.kk-charge .kk--strike .kk-storm { animation: kkStormIn 520ms var(--ease-out) forwards; }
.kk-release .kk--strike .kk-storm { animation: kkStormOut 520ms var(--ease-out) forwards; }
@keyframes kkStormIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes kkStormOut { from { opacity: 1; } to { opacity: 0; } }

.kk--strike .kk-flash {
  background: var(--ink);
  mix-blend-mode: screen;
  opacity: 0;
}
/* Three flickers across the 1,300 ms hold: at 0, ~520 and ~880 ms. */
.kk-charge .kk--strike .kk-flash { animation: kkFlicker 1300ms linear forwards; }
@keyframes kkFlicker {
  0%, 2% { opacity: 0; }
  3% { opacity: .28; }
  6% { opacity: 0; }
  40% { opacity: 0; }
  41% { opacity: .34; }
  43% { opacity: .1; }
  44% { opacity: .3; }
  47% { opacity: 0; }
  68% { opacity: 0; }
  69% { opacity: .4; }
  72% { opacity: 0; }
  100% { opacity: 0; }
}
.kk-release .kk--strike .kk-flash { animation: kkWhiteout 280ms linear forwards; }
@keyframes kkWhiteout {
  0% { opacity: 0; }
  8% { opacity: .98; }
  30% { opacity: .7; }
  100% { opacity: 0; }
}

.kk--strike .kk-bolt {
  overflow: visible;
  opacity: 0;
}
.kk--strike .kk-bolt polyline {
  fill: none;
  stroke: var(--ink);
  stroke-width: 3;
  stroke-linejoin: round;
  stroke-linecap: round;
  filter: drop-shadow(0 0 3px rgba(243, 246, 242, .9)) drop-shadow(0 0 8px rgba(198, 242, 78, .95)) drop-shadow(0 0 18px rgba(198, 242, 78, .6));
}
.kk-charge .kk--strike .kk-bolt {
  animation: kkBolt 150ms linear calc(var(--i) * 440ms) both;
}
/* The fourth bolt is the strike itself: heavier, and only at the release. */
.kk-charge .kk--strike .kk-bolt:nth-child(6) { animation: none; opacity: 0; }
.kk-release .kk--strike .kk-bolt { animation: none; opacity: 0; }
.kk-release .kk--strike .kk-bolt:nth-child(6) { animation: kkBoltBig 260ms linear both; }
.kk-release .kk--strike .kk-bolt:nth-child(6) polyline { stroke-width: 5; }
@keyframes kkBolt {
  0% { opacity: 0; }
  10% { opacity: 1; }
  50% { opacity: .3; }
  60% { opacity: .9; }
  100% { opacity: 0; }
}
@keyframes kkBoltBig {
  0% { opacity: 0; }
  8% { opacity: 1; }
  45% { opacity: 1; }
  100% { opacity: 0; }
}

/* The back lit from above with each bolt. */
.kk--strike .kk-glare {
  left: calc(var(--card-w) * -.5);
  top: calc(var(--card-h) * -.5);
  width: var(--card-w);
  height: var(--card-h);
  border-radius: calc(var(--card-w) * .09);
  background: linear-gradient(to bottom, rgba(243, 246, 242, .85), rgba(198, 242, 78, .3) 45%, transparent 80%);
  mix-blend-mode: screen;
  opacity: 0;
}
.kk-charge .kk--strike .kk-glare { animation: kkFlicker 1300ms linear forwards; }
.kk-release .kk--strike .kk-glare { animation: kkWhiteout 200ms linear forwards; }
.kk--strike.kk-over.kk-off .kk-glare { animation: none; opacity: 0; }

.kk-release .kk--strike .kk-ring { border-color: rgba(243, 246, 242, .95); }
/* Shards off the impact, over the cards, in white. */
.kk--strike .kk-shards b {
  position: absolute;
  --a: calc(var(--i) * 360deg / var(--n) + 9deg);
  left: -1.5px;
  top: -1.5px;
  width: 3px;
  height: 12px;
  border-radius: 1.5px;
  background: var(--ink);
  box-shadow: 0 0 6px rgba(198, 242, 78, .9);
  opacity: 0;
}
.kk-release .kk--strike .kk-shards b {
  animation: kkSpark 620ms cubic-bezier(.1, .8, .3, 1) calc(var(--i) * 7ms) both;
}
@keyframes kkSpark {
  0% { opacity: 1; transform: rotate(var(--a)) translateY(calc(var(--card-h) * -.2)) scale(1); }
  100% { opacity: 0; transform: rotate(var(--a)) translateY(calc(var(--card-h) * -1.9)) scale(.25); }
}
/* The table jolts once. On `.felt-wrap` so the cloth, the pods and the board
   move together — a hit on the table, not on the screen. */
#screenTable[data-kakutei="strike"].kk-release .felt-wrap { animation: kkJolt 340ms cubic-bezier(.2, .7, .3, 1) both; }
@keyframes kkJolt {
  0% { transform: translate3d(0, 0, 0); }
  12% { transform: translate3d(0, 7px, 0); }
  30% { transform: translate3d(-3px, -4px, 0); }
  48% { transform: translate3d(2px, 2px, 0); }
  66% { transform: translate3d(-1px, -1px, 0); }
  100% { transform: translate3d(0, 0, 0); }
}

/* ======================================================================
 * C. gather — the table's light drawn into the slot.
 * Long omen: 1.5 s before the river is even dealt, the cloth dims except for
 * the empty fifth slot and streaks of light start converging on it. Once the
 * card lies there its core pulses, faster and faster. At the half-turn the
 * light collapses to a point and bursts back out as rays.
 * ==================================================================== */

.kk--gather .kk-vignette {
  background: radial-gradient(circle at calc(-1 * var(--cover-left)) calc(-1 * var(--cover-top)),
    transparent calc(var(--card-w) * 1.1),
    rgba(2, 6, 16, .66) calc(var(--card-w) * 4.6));
  opacity: 0;
}
.kk-omen .kk--gather .kk-vignette,
.kk-charge .kk--gather .kk-vignette { animation: kkStormIn 700ms var(--ease-out) forwards; }
/* Held through the peak, then lifted. */
.kk-release .kk--gather .kk-vignette { animation: kkHold 750ms linear forwards, kkStormOut 450ms var(--ease-out) 750ms forwards; }
@keyframes kkHold { from { opacity: 1; } to { opacity: 1; } }

.kk--gather .kk-streaks i {
  position: absolute;
  --a: calc(var(--i) * 360deg / var(--n) + 11deg);
  left: -1px;
  top: calc(var(--card-h) * -.9);
  width: 2px;
  height: calc(var(--card-h) * .9);
  border-radius: 1px;
  background: linear-gradient(to bottom, transparent, rgba(198, 242, 78, .95));
  box-shadow: 0 0 6px rgba(198, 242, 78, .5);
  transform-origin: 50% 100%;
  opacity: 0;
}
.kk-omen .kk--gather .kk-streaks i,
.kk-charge .kk--gather .kk-streaks i {
  animation: kkStreak 900ms cubic-bezier(.3, 0, .8, .4) calc(var(--i) * 71ms) infinite;
}
.kk-release .kk--gather .kk-streaks i { animation: none; opacity: 0; }
@keyframes kkStreak {
  0% { opacity: 0; transform: rotate(var(--a)) translateY(calc(var(--card-h) * -2.8)) scaleY(1); }
  25% { opacity: 1; }
  100% { opacity: 0; transform: rotate(var(--a)) translateY(calc(var(--card-h) * -.25)) scaleY(.25); }
}

.kk--gather .kk-core {
  left: calc(var(--card-w) * -.9);
  top: calc(var(--card-w) * -.9);
  width: calc(var(--card-w) * 1.8);
  height: calc(var(--card-w) * 1.8);
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(243, 246, 242, .9), rgba(198, 242, 78, .55) 35%, transparent 100%);
  mix-blend-mode: screen;
  opacity: 0;
}
.kk-omen .kk--gather .kk-core { animation: kkCoreIdle 1100ms ease-in-out infinite alternate; }
@keyframes kkCoreIdle { from { opacity: .18; transform: scale(.7); } to { opacity: .34; transform: scale(.85); } }
/* The heartbeat, accelerating over the 1,300 ms hold: gaps of 400, 300,
   230, 180, 120 ms. */
.kk-charge .kk--gather .kk-core { animation: kkCoreBeat 1300ms linear forwards; }
@keyframes kkCoreBeat {
  0% { opacity: .3; transform: scale(.75); }
  4% { opacity: .8; transform: scale(1); }
  14% { opacity: .3; transform: scale(.78); }
  31% { opacity: .3; transform: scale(.78); }
  35% { opacity: .85; transform: scale(1.02); }
  44% { opacity: .32; transform: scale(.8); }
  54% { opacity: .32; transform: scale(.8); }
  58% { opacity: .9; transform: scale(1.05); }
  66% { opacity: .35; transform: scale(.82); }
  72% { opacity: .35; transform: scale(.82); }
  76% { opacity: .95; transform: scale(1.08); }
  82% { opacity: .4; transform: scale(.85); }
  86% { opacity: .4; transform: scale(.85); }
  90% { opacity: 1; transform: scale(1.12); }
  95% { opacity: .5; transform: scale(.9); }
  100% { opacity: 1; transform: scale(1.15); }
}
.kk-release .kk--gather .kk-core { animation: kkCoreBurst 520ms cubic-bezier(.12, .74, .3, 1) forwards; }
@keyframes kkCoreBurst {
  0% { opacity: 1; transform: scale(1.15); }
  18% { opacity: 1; transform: scale(.3); }
  40% { opacity: 1; transform: scale(2); }
  100% { opacity: 0; transform: scale(3.4); }
}

/* The rays run from the river to the edges of the play area and hold there:
   the peak frame, 550 ms after the flip (KAKUTEI_TIMELINE.gather.peak). Under
   the cards and the pods, so everything on the table stays readable. */
.kk--gather .kk-rays i {
  position: absolute;
  --a: calc(var(--i) * 360deg / var(--n) + 11deg);
  left: calc(var(--card-w) * -.2);
  top: calc(var(--cover-h) * -1.15);
  width: calc(var(--card-w) * .4);
  height: calc(var(--cover-h) * 1.15);
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
  background: linear-gradient(to top, rgba(243, 246, 242, .95), rgba(198, 242, 78, .7) 30%, rgba(198, 242, 78, .25) 70%, transparent);
  transform-origin: 50% 100%;
  transform: rotate(var(--a)) scaleY(0);
  opacity: 0;
}
.kk-release .kk--gather .kk-rays i {
  animation: kkRay 1000ms cubic-bezier(.1, .8, .3, 1) 90ms both;
}
@keyframes kkRay {
  0% { opacity: 1; transform: rotate(var(--a)) scaleY(0); }
  30% { opacity: 1; transform: rotate(calc(var(--a) + 6deg)) scaleY(1); }
  70% { opacity: .9; transform: rotate(calc(var(--a) + 8deg)) scaleY(1.02); }
  100% { opacity: 0; transform: rotate(calc(var(--a) + 9deg)) scaleY(1.05); }
}
/* One breath of light over the whole cloth at the burst. Under the cards. */
.kk--gather .kk-wash {
  background: var(--lime);
  mix-blend-mode: screen;
  opacity: 0;
}
.kk-release .kk--gather .kk-wash { animation: kkWash 600ms linear forwards; }
@keyframes kkWash { 0% { opacity: 0; } 8% { opacity: .3; } 100% { opacity: 0; } }

.kk--gather .kk-lens {
  left: calc(var(--card-w) * -.5);
  top: calc(var(--card-h) * -.5);
  width: var(--card-w);
  height: var(--card-h);
  border-radius: calc(var(--card-w) * .09);
  box-shadow: inset 0 0 0 1.5px rgba(198, 242, 78, .9), inset 0 0 14px rgba(198, 242, 78, .55);
  opacity: 0;
}
.kk-charge .kk--gather .kk-lens { animation: kkLens 1300ms linear forwards; }
@keyframes kkLens { 0% { opacity: .2; } 60% { opacity: .6; } 100% { opacity: 1; } }
.kk--gather.kk-over.kk-off .kk-lens { animation: none; opacity: 0; }
