/* The opening: the first thing anyone sees. The Codex painting rises out of
   the dark, the name is brushed and gilded over it, fireflies drift on the
   water, and Enter carries you into the picture. Then Home and the front door
   arrive the same way: painted cards settling, seals stamped, a glint of gold
   leaf. Loaded last; only transform, opacity and filter move. */

/* ------------------------------------------------------------ the gate */
.gate {
  background: #030509;
  isolation: isolate;
}
.gate__art {
  position: absolute; inset: -2%; z-index: -3;
  background: url('/img/kakure/art/home-hero.webp?v=20261011edo') 62% center / cover no-repeat;
  animation: gate-dawn 3.2s cubic-bezier(.2, .7, .2, 1) both, gate-breath 26s 3.2s ease-in-out 2 alternate;
  transform-origin: 62% 46%;
  will-change: transform, opacity, filter;
}
@keyframes gate-dawn {
  from { opacity: 0; transform: scale(1.14); filter: brightness(.35) saturate(.6) blur(6px); }
  55% { opacity: 1; filter: brightness(.8) saturate(.85) blur(0); }
  to { opacity: 1; transform: scale(1); filter: none; }
}
@keyframes gate-breath { to { transform: scale(1.045); } }
/* Ink at the edges, and a pool of shadow behind the words so they read on the painting. */
.gate__veil {
  position: absolute; inset: 0; z-index: -2; pointer-events: none;
  background:
    radial-gradient(ellipse 70% 42% at 50% 52%, rgba(3, 5, 10, .62), rgba(3, 5, 10, 0) 72%),
    radial-gradient(ellipse 120% 90% at 50% 45%, rgba(3, 5, 10, 0) 55%, rgba(3, 5, 10, .78) 100%),
    linear-gradient(180deg, rgba(3, 5, 10, .55), rgba(3, 5, 10, 0) 22%, rgba(3, 5, 10, 0) 78%, rgba(3, 5, 10, .6));
  animation: rise-in 2s .4s ease both;
}
.gate__flies { position: absolute; inset: 0; z-index: -1; pointer-events: none; }
.gate__flies i {
  position: absolute; left: var(--x); top: var(--y); width: 6px; height: 6px; border-radius: 50%;
  background: #fff3b0; box-shadow: 0 0 6px 2px rgba(255, 226, 120, .85), 0 0 18px 6px rgba(255, 200, 90, .35);
  opacity: 0;
  animation: gate-fly var(--t) calc(var(--d) + 2.2s) ease-in-out infinite;
}
@keyframes gate-fly {
  0% { opacity: 0; transform: translate(0, 0) scale(.6); }
  20% { opacity: 1; }
  50% { opacity: .35; transform: translate(14px, -26px) scale(1); }
  70% { opacity: .95; }
  100% { opacity: 0; transform: translate(-8px, -54px) scale(.7); }
}

.gate__inner { position: relative; gap: clamp(8px, 1.8vh, 16px); }
.gate__title { font-size: clamp(32px, 8.4vw, 64px); }
.gate__kanji {
  text-shadow: 0 0 40px rgba(255, 220, 150, .35), 0 0 2px rgba(255, 245, 225, .6), 0 8px 30px rgba(0, 0, 0, .7);
  animation: brush-in 2.4s .9s var(--ease-ink) both;
}
/* The name in gold leaf, with a glint that runs across it now and then. */
.gate__title {
  background:
    linear-gradient(105deg, rgba(255, 255, 255, 0) 40%, rgba(255, 252, 235, .95) 50%, rgba(255, 255, 255, 0) 60%) -150% 0 / 250% 100% no-repeat,
    linear-gradient(180deg, #fff3cf 0%, #e8c06a 40%, #b98a35 62%, #f0d38a 78%, #8f6a26 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 2px 0 rgba(60, 35, 5, .55)) drop-shadow(0 6px 18px rgba(0, 0, 0, .65));
  animation: rise-in 1.8s 1.9s var(--ease-ink) both, gold-glint 7s 3.4s ease-in-out 2;
}
@keyframes gold-glint {
  0% { background-position: -150% 0, 0 0; }
  22%, 100% { background-position: 250% 0, 0 0; }
}
/* A gold rule drawn out from a vermilion seal. */
.gate__rule { position: relative; width: min(360px, 72vw); height: 12px; display: grid; place-items: center; }
.gate__rule::before {
  content: ''; position: absolute; left: 0; right: 0; top: 50%; height: 1px;
  background: linear-gradient(90deg, rgba(217, 173, 85, 0), #e8c06a 30%, #f6dfa0 50%, #e8c06a 70%, rgba(217, 173, 85, 0));
  transform: scaleX(0); animation: rule-draw 1.6s 2.3s cubic-bezier(.2, .7, .2, 1) forwards;
}
.gate__rule i {
  position: relative; width: 10px; height: 10px; transform: rotate(45deg) scale(0);
  background: radial-gradient(circle at 35% 30%, #ec6a48, #a12a17);
  box-shadow: 0 0 0 2px rgba(3, 5, 10, .9), 0 0 0 3px rgba(232, 192, 106, .9), 0 0 12px rgba(236, 106, 72, .6);
  animation: seal-pop .7s 2.2s cubic-bezier(.3, 1.6, .5, 1) forwards;
}
@keyframes rule-draw { to { transform: scaleX(1); } }
@keyframes seal-pop { to { transform: rotate(45deg) scale(1); } }
.gate__sub {
  color: #efe4cb; text-shadow: 0 1px 2px rgba(0, 0, 0, .9), 0 0 18px rgba(3, 5, 10, .9);
  animation: rise-in 1.8s 2.6s var(--ease-ink) both;
}
.gate__year { color: #e8c06a; text-shadow: 0 1px 2px rgba(0, 0, 0, .9); animation: rise-in 1.6s 2.8s var(--ease-ink) both; }
.gate__enter { position: relative; animation: rise-in 1.4s 2.9s var(--ease-ink) both; }
/* Enter: lacquer with a sheen that passes, and rings of light spreading on the water. */
.gate__enter::before, .gate__enter::after {
  content: ''; position: absolute; inset: 0; margin: auto; border-radius: 16px; pointer-events: none;
  border: 1px solid rgba(240, 205, 130, .7);
  animation: enter-ring 3.6s 4.6s ease-out infinite; opacity: 0;
}
.gate__enter::after { animation-delay: 6.4s; }
@keyframes enter-ring {
  0% { opacity: .8; transform: scale(1); }
  100% { opacity: 0; transform: scale(1.45, 1.9); }
}
.gate__enter .btn {
  position: relative; overflow: hidden; padding: 16px 46px; font-size: 17px; letter-spacing: .3em; text-indent: .3em;
  border-radius: 16px;
  box-shadow: inset 0 0 0 1px rgba(255, 214, 150, .65), 0 0 0 1px rgba(232, 192, 106, .35), 0 10px 30px rgba(140, 35, 12, .55), 0 0 40px rgba(236, 106, 72, .25);
}
.gate__enter .btn::after {
  content: ''; position: absolute; top: 0; bottom: 0; left: -60%; width: 40%; pointer-events: none;
  background: linear-gradient(100deg, rgba(255, 240, 210, 0), rgba(255, 240, 210, .55), rgba(255, 240, 210, 0));
  transform: skewX(-18deg); animation: lacquer-sheen 5s 4.2s ease-in-out 3;
}
@keyframes lacquer-sheen { 0% { transform: translateX(0) skewX(-18deg); } 30%, 100% { transform: translateX(475%) skewX(-18deg); } }

/* Entering: you walk into the painting while the words lift away. */
.gate.is-leaving { animation: gate-out 1.4s .2s cubic-bezier(.6, 0, .4, 1) forwards; }
.gate.is-leaving .gate__art { animation: gate-into 1.6s cubic-bezier(.55, 0, .3, 1) forwards; }
.gate.is-leaving .gate__inner { animation: gate-lift .9s cubic-bezier(.5, 0, .7, 1) forwards; }
.gate.is-leaving .gate__flies { animation: gate-out .6s forwards; }
@keyframes gate-into { from { transform: scale(1.02); } to { transform: scale(1.5); filter: brightness(1.25) blur(3px); } }
@keyframes gate-lift { to { transform: translateY(-40px) scale(1.04); filter: blur(8px); opacity: 0; } }

/* ------------------------------------------------------------ the front door */
.signin {
  background: linear-gradient(180deg, rgba(3, 5, 10, .3), rgba(3, 5, 10, .7)),
    url('/img/kakure/art/home-hero.webp?v=20261011edo') 62% center / cover no-repeat, #0a0f1c;
}
/* The scroll unrolls from its middle, its rods meeting and parting. */
.signin__card {
  background:
    linear-gradient(180deg, #f8efdb, #e6d5b0);
  box-shadow: 0 40px 90px rgba(0, 0, 0, .75), inset 0 0 0 6px rgba(255, 250, 238, .35), inset 0 0 0 7px rgba(176, 141, 63, .35);
  animation: scroll-unroll .9s 0s cubic-bezier(.2, .8, .2, 1) both;
}
@keyframes scroll-unroll {
  from { clip-path: inset(50% -20px 50% -20px); opacity: .3; transform: translateY(14px); }
  to { clip-path: inset(-20px -20px -20px -20px); opacity: 1; transform: none; }
}
.signin__card::before, .signin__card::after {
  background: linear-gradient(180deg, #2a1a0e, #6b4222 35%, #a8743f 50%, #5a3519 70%, #1f1309);
  box-shadow: 0 4px 12px rgba(0, 0, 0, .55), inset 0 1px 0 rgba(255, 220, 170, .25);
}
.signin__kanji {
  color: #1d1712;
  animation: brush-in 1.2s .2s var(--ease-ink) both;
}
.signin.is-front h2 { animation: rise-in .8s .3s var(--ease-ink) both; }
.signin.is-front .signin__card > p.muted { animation: rise-in .8s .4s var(--ease-ink) both; }
.signin.is-front .signin__play { animation: rise-in .8s .5s var(--ease-ink) both; }
.signin__play .btn--primary { position: relative; overflow: hidden; }
.signin__play .btn--primary::after {
  content: ''; position: absolute; top: 0; bottom: 0; left: -60%; width: 40%; pointer-events: none;
  background: linear-gradient(100deg, rgba(255, 240, 210, 0), rgba(255, 240, 210, .55), rgba(255, 240, 210, 0));
  transform: skewX(-18deg); animation: lacquer-sheen 5s 2.4s ease-in-out 3;
}

/* ------------------------------------------------------------ Home arriving */
.way { isolation: isolate; }
.way__art { animation: art-settle 2.4s cubic-bezier(.2, .7, .2, 1) both; }
@keyframes art-settle { from { transform: scale(1.12); filter: brightness(.5) blur(3px); } to { transform: none; filter: none; } }
/* A glint of gold leaf crosses each painted card once as it arrives. */
.way::before {
  content: ''; position: absolute; top: -10%; bottom: -10%; left: -50%; width: 35%; z-index: 2; pointer-events: none;
  background: linear-gradient(100deg, rgba(255, 230, 170, 0), rgba(255, 230, 170, .28), rgba(255, 230, 170, 0));
  transform: skewX(-18deg); opacity: 0;
  animation: card-glint 1.6s .9s ease-in-out both;
}
@keyframes card-glint { 0% { transform: translateX(0) skewX(-18deg); opacity: 1; } 99% { opacity: 1; } 100% { transform: translateX(515%) skewX(-18deg); opacity: 0; } }
.way__seal { animation: seal-stamp .55s .7s cubic-bezier(.3, 1.5, .5, 1) both; }
@keyframes seal-stamp {
  from { transform: rotate(-16deg) scale(1.9); opacity: 0; filter: blur(2px); }
  to { transform: rotate(-6deg) scale(1); opacity: 1; filter: none; }
}
.way--friends::before, .way--friends .way__seal { animation-delay: 1.05s, .85s; }
.way--bots::before, .way--bots .way__seal { animation-delay: 1.2s, 1s; }
.way--friends .way__art { animation-delay: .1s; }
.way--bots .way__art { animation-delay: .2s; }

/* Touch a card: it leans toward your finger and the gold catches the light. */
:has(> .way) { perspective: 900px; }
.way { transition: rotate .45s cubic-bezier(.2, .8, .3, 1), scale .3s; }
.way.is-touched { transition: rotate .08s linear, scale .15s; scale: .985; }
.way__art::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(circle at var(--gx, 50%) var(--gy, 50%), rgba(255, 228, 160, .45), rgba(255, 228, 160, 0) 50%);
  opacity: 0; transition: opacity .4s;
}
.way.is-touched .way__art::after { opacity: 1; transition: opacity .1s; }

@media (max-width: 600px) {
  .way { animation: home-rise .8s cubic-bezier(.2, .7, .2, 1) both; }
  .way--friends { animation-delay: .08s; }
  .way--bots { animation-delay: .16s; }
  .way--classic { animation-delay: .22s; }
  .home-tabs { animation: home-rise .8s .3s cubic-bezier(.2, .7, .2, 1) both; }
  .lobby .game-list > *, .lobby #alerts { animation: home-rise .7s .4s cubic-bezier(.2, .7, .2, 1) both; }
  .lobby .game-list > :nth-child(2) { animation-delay: .48s; }
  .lobby .game-list > :nth-child(3) { animation-delay: .56s; }
  .lobby .game-list > :nth-child(n+4) { animation-delay: .64s; }
}
@keyframes home-rise { from { opacity: 0; transform: translateY(18px) scale(.98); } to { opacity: 1; transform: none; } }

/* The top bar's seal catches the light once. */
.topbar__home img { animation: seal-stamp .6s .2s cubic-bezier(.3, 1.5, .5, 1) both; }
@keyframes seal-stamp-flat { from { transform: scale(1.6); opacity: 0; } to { transform: none; opacity: 1; } }
.topbar__home img { animation-name: seal-stamp-flat; }

/* ------------------------------------------------------------ the island arrives */
/* Opening a game: the shore washes in, lands rise from the middle outward like
   tiles laid on a table, numbers are stamped on, then ports and pieces. */
#board-host svg.is-arriving .layer-shore { animation: island-fade 1s calc(0ms - var(--since, 0ms)) ease-out both; }
#board-host svg.is-arriving .hexcell {
  transform-box: fill-box; transform-origin: center;
  animation: hex-arrive .8s cubic-bezier(.2, .8, .25, 1.12) both;
  animation-delay: calc(var(--ring, 0) * 140ms + 120ms - var(--since, 0ms));
}
@keyframes hex-arrive {
  from { opacity: 0; transform: translateY(-.35px) scale(.55) rotate(-10deg); }
  60% { opacity: 1; }
  to { opacity: 1; transform: none; }
}
#board-host svg.is-arriving .layer-tokens > g {
  transform-box: fill-box; transform-origin: center;
  animation: tok-stamp .45s cubic-bezier(.3, 1.6, .5, 1) both;
  animation-delay: calc(var(--ring, 0) * 140ms + 760ms - var(--since, 0ms));
}
@keyframes tok-stamp { from { opacity: 0; transform: scale(2.1); } to { opacity: 1; transform: none; } }
#board-host svg.is-arriving .layer-ports { animation: island-fade .8s calc(1300ms - var(--since, 0ms)) ease-out both; }
#board-host svg.is-arriving .layer-roads, #board-host svg.is-arriving .layer-buildings,
#board-host svg.is-arriving .layer-robber, #board-host svg.is-arriving .layer-lights {
  animation: pieces-drop .7s calc(1550ms - var(--since, 0ms)) cubic-bezier(.2, .8, .2, 1) both;
}
@keyframes island-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes pieces-drop { from { opacity: 0; transform: translateY(-.4px); } to { opacity: 1; transform: none; } }

/* ------------------------------------------------------------ the Act card */
/* Each Act opens like the title: its painting settles out of the dark, the
   season's kanji is brushed, the title is gilded over a drawn rule. A tap
   lifts it away and the island builds itself beneath. */
.fx-act { isolation: isolate; overflow: hidden; background: #02040a; }
.fx-act::before {
  content: ''; position: absolute; inset: -3%; z-index: -1;
  background-image: linear-gradient(180deg, rgba(2, 4, 10, .4), rgba(2, 4, 10, .72)), var(--moment-art, none), radial-gradient(ellipse, #14203a, #02040a);
  background-size: cover; background-position: center;
  animation: act-art 9s cubic-bezier(.2, .7, .2, 1) both;
}
@keyframes act-art {
  from { transform: scale(1.16); filter: brightness(.4) blur(5px); }
  30% { filter: none; }
  to { transform: scale(1.02); filter: none; }
}
.fx-act__season { text-shadow: 0 0 40px rgba(255, 220, 150, .35), 0 8px 30px rgba(0, 0, 0, .7); }
.fx-act__title {
  position: relative; padding-bottom: 14px;
  background:
    linear-gradient(105deg, rgba(255, 255, 255, 0) 40%, rgba(255, 252, 235, .95) 50%, rgba(255, 255, 255, 0) 60%) -150% 0 / 250% 100% no-repeat,
    linear-gradient(180deg, #fff3cf 0%, #e8c06a 40%, #b98a35 62%, #f0d38a 78%, #8f6a26 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 2px 0 rgba(60, 35, 5, .55)) drop-shadow(0 6px 18px rgba(0, 0, 0, .7));
  animation: rise-in 1.2s .9s var(--ease-ink) both, gold-glint 6s 2s ease-in-out 1;
}
.fx-act__title::after {
  content: ''; position: absolute; left: 10%; right: 10%; bottom: 0; height: 1px;
  background: linear-gradient(90deg, rgba(217, 173, 85, 0), #e8c06a 30%, #f6dfa0 50%, #e8c06a 70%, rgba(217, 173, 85, 0));
  transform: scaleX(0); animation: rule-draw 1.4s 1.3s cubic-bezier(.2, .7, .2, 1) forwards;
}
.fx-act__ine { border-radius: 18px; box-shadow: 0 18px 44px rgba(0, 0, 0, .6), inset 0 0 0 5px rgba(255, 250, 238, .3), inset 0 0 0 6px rgba(176, 141, 63, .4); }
.fx-act.is-leaving { animation: act-leave .7s cubic-bezier(.5, 0, .7, 1) forwards; }
.fx-act.is-leaving::before { animation: act-into .7s cubic-bezier(.5, 0, .7, 1) forwards; }
.fx-act.is-leaving .fx-act__inner { animation: gate-lift .6s cubic-bezier(.5, 0, .7, 1) forwards; }
@keyframes act-leave { from { opacity: 1; } to { opacity: 0; } }
@keyframes act-into { from { transform: scale(1.02); } to { transform: scale(1.3); filter: brightness(1.2) blur(3px); } }

@media (prefers-reduced-motion: reduce) {
  .gate__art, .gate__flies i, .gate__title, .gate__enter::before, .gate__enter::after, .gate__enter .btn::after,
  .signin__card, .way, .way::before, .way__art, .way__seal, .home-tabs, .lobby .game-list > *,
  .signin__play .btn--primary::after, .topbar__home img, .signin__kanji, .signin.is-front h2,
  .signin.is-front .signin__card > p.muted, .signin.is-front .signin__play,
  .fx-act::before, .fx-act__title, .fx-act__title::after { animation: none !important; }
  .fx-act__title::after { transform: none; }
  .way::before { display: none; }
}

/* ------------------------------------------------------------ the board, made solid */
.island-cast { fill: #000; opacity: .55; pointer-events: none; }
.island-cliff { fill: url(#cliffSide); pointer-events: none; }
.hex-bevel { pointer-events: none; }
:root[data-game="kakure"] .tok-circle { stroke: #a8823c; stroke-width: .032; }
.tok-rim { fill: none; stroke: rgba(107, 74, 34, .32); stroke-width: .012; pointer-events: none; }

/* ------------------------------------------------------------ the hand, held */
/* Your five cards are held in a gentle fan, like a real hand of cards; a card
   you press lifts out of it. Individual rotate/translate leave the card's own
   bump and loss animations (transform) untouched. */
#view-game #hand { align-items: flex-end; }
#view-game #hand .rescard { transform-origin: 50% 120%; transition: translate .25s cubic-bezier(.2, .8, .3, 1), rotate .25s cubic-bezier(.2, .8, .3, 1); }
#view-game #hand .rescard:nth-child(3) { translate: 0 -2px; }
#view-game #hand .rescard:nth-child(1) { rotate: -6deg; translate: 0 3px; }
#view-game #hand .rescard:nth-child(2) { rotate: -3deg; translate: 0 0; }
#view-game #hand .rescard:nth-child(4) { rotate: 3deg; translate: 0 0; }
#view-game #hand .rescard:nth-child(5) { rotate: 6deg; translate: 0 3px; }
#view-game #hand .rescard:not(.is-zero):active { translate: 0 -10px; rotate: 0deg; }
@media (max-width: 360px) {
  #view-game #hand .rescard:nth-child(1) { rotate: -3deg; translate: 2px 2px; }
  #view-game #hand .rescard:nth-child(2) { rotate: -1.5deg; }
  #view-game #hand .rescard:nth-child(4) { rotate: 1.5deg; }
  #view-game #hand .rescard:nth-child(5) { rotate: 3deg; translate: -2px 2px; }
}
@media (prefers-reduced-motion: reduce) { #view-game #hand .rescard { transition: none; } }

/* ------------------------------------------------------------ a point scored */
#view-game .mobile-player.is-scored {
  position: relative; overflow: hidden; isolation: isolate;
  animation: chip-score .9s calc(0ms - var(--since, 0ms)) cubic-bezier(.3, 1.6, .5, 1) both;
}
#view-game .mobile-player.is-scored::after {
  content: ''; position: absolute; top: -20%; bottom: -20%; left: -40%; width: 40%; z-index: 2; pointer-events: none;
  background: linear-gradient(100deg, rgba(255, 226, 150, 0), rgba(255, 226, 150, .75), rgba(255, 226, 150, 0));
  transform: skewX(-18deg); opacity: 0;
  animation: chip-glint 1.1s calc(150ms - var(--since, 0ms)) ease-out both;
}
@keyframes chip-score { 0% { scale: 1; } 35% { scale: 1.1; } 100% { scale: 1; } }
@keyframes chip-glint { 0% { transform: translateX(0) skewX(-18deg); opacity: 1; } 99% { opacity: 1; } 100% { transform: translateX(420%) skewX(-18deg); opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  #view-game .mobile-player.is-scored, #view-game .mobile-player.is-scored::after { animation: none; }
}
