/* ==========================================================================
   MOTION & LOOK — the animated layer for the whole website.
   Loaded last on every page (after styles.css / games.css) so it can add new
   life and gently upgrade the existing components without touching them.
   Sections:
     1. Tokens, aurora backdrop and page transitions
     2. Scroll progress, cursor aura, sound switch
     3. Hero: 3D world, entrance choreography, headline shine
     4. Scroll reveals with stagger
     5. Cards, tilts and shine sweeps
     6. Buttons: ripples, shine, magnetism
     7. Marquee band + section flourishes
     8. Games room: cards, stage, mode switch, board feel
     9. Game feedback: pieces, captures, dice, flips, banners
    10. Motion preferences
   ========================================================================== */

/* ---------------------------------------------------------------- 1. tokens */
:root{
  --fx-ease:cubic-bezier(.22,1,.36,1);
  --fx-spring:cubic-bezier(.34,1.56,.64,1);
  --fx-glow:0 0 0 1px rgba(255,255,255,.7), 0 30px 60px -34px rgba(42,37,48,.65);
}

html{scroll-padding-top:120px}

/* Slow drifting colour clouds behind everything. */
.fx-aurora{
  position:fixed;inset:-10vh -10vw;z-index:0;pointer-events:none;overflow:hidden;
  opacity:.85;
}
.fx-aurora i{
  position:absolute;display:block;border-radius:50%;filter:blur(70px);
  animation:fxDrift 22s ease-in-out infinite;
}
.fx-aurora i:nth-child(1){width:46vw;height:46vw;left:-6vw;top:-6vh;background:rgba(230,57,70,.22)}
.fx-aurora i:nth-child(2){width:40vw;height:40vw;right:-6vw;top:14vh;background:rgba(58,166,232,.2);animation-delay:-6s}
.fx-aurora i:nth-child(3){width:38vw;height:38vw;left:26vw;bottom:-12vh;background:rgba(255,201,60,.22);animation-delay:-12s}
.fx-aurora i:nth-child(4){width:30vw;height:30vw;right:18vw;bottom:-6vh;background:rgba(63,169,110,.16);animation-delay:-17s}
body[data-person="himu"] .fx-aurora i:nth-child(1){background:rgba(47,127,209,.24)}
body[data-person="himu"] .fx-aurora i:nth-child(3){background:rgba(53,208,192,.2)}

@keyframes fxDrift{
  0%,100%{transform:translate3d(0,0,0) scale(1)}
  33%{transform:translate3d(6vw,-4vh,0) scale(1.12)}
  66%{transform:translate3d(-5vw,5vh,0) scale(.94)}
}

main,.site-footer{position:relative;z-index:1}

/* Page-to-page soft fade. */
.fx-leaving body,body.fx-leaving{opacity:0;transform:translateY(-6px) scale(.995)}
body{transition:opacity .22s ease, transform .22s ease}
body.fx-enter{animation:fxPageIn .5s var(--fx-ease) both}
@keyframes fxPageIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}

/* --------------------------------------------------- 2. progress + controls */
.fx-progress{
  position:fixed;top:0;left:0;right:0;height:4px;z-index:80;pointer-events:none;
  background:rgba(42,37,48,.06);
}
.fx-progress i{
  display:block;height:100%;width:100%;transform-origin:0 50%;transform:scaleX(0);
  background:linear-gradient(90deg,var(--yellow),var(--red) 45%,var(--blue));
  box-shadow:0 0 14px rgba(230,57,70,.55);
}

.fx-aura{
  position:fixed;top:0;left:0;width:320px;height:320px;border-radius:50%;
  z-index:70;pointer-events:none;opacity:0;
  background:radial-gradient(circle, rgba(255,201,60,.5), rgba(230,57,70,.22) 45%, transparent 70%);
  transition:opacity .4s ease, width .3s ease, height .3s ease;
  mix-blend-mode:multiply;
}
.fx-aura-on{opacity:.55}
.fx-aura-pop{width:400px;height:400px}

.fx-sound{
  position:fixed;left:20px;bottom:20px;z-index:75;
  width:52px;height:52px;border-radius:50%;border:3px solid #fff;
  background:#fff;font-size:1.3rem;cursor:pointer;
  box-shadow:0 16px 28px -16px rgba(42,37,48,.85);
  transition:transform .2s var(--fx-spring), background .2s ease;
}
.fx-sound:hover{transform:translateY(-3px) scale(1.06)}
.fx-sound.is-off{background:#f2eef6;opacity:.85}
/* sfx.js also flags the whole document, so the muted look holds even before the
   button repaints. */
html.sfx-off .fx-sound{background:#f2eef6;opacity:.85}
@media (max-width:620px){.fx-sound{left:14px;bottom:14px;width:46px;height:46px;font-size:1.1rem}}

/* Sticky header shrinks a touch once you scroll. */
.site-header{transition:padding .3s ease, box-shadow .3s ease}
.header-inner{transition:padding .3s var(--fx-ease)}
.site-header.fx-compact{box-shadow:0 14px 30px -24px rgba(42,37,48,.9)}
.site-header.fx-compact .header-inner{padding-block:5px}
.site-header.fx-compact .brand{font-size:1rem}

/* ------------------------------------------------------------ 3. the hero */
.fx-hero{position:relative;isolation:isolate}
.fx-hero > *{position:relative;z-index:1}

/* Hidden until three.js has actually taken it over, so the page is safe
   even with JavaScript switched off. */
canvas.hero-3d{display:none}
/* Sizing is explicit (not auto) so three.js can put its drawing buffer behind
   the same box the CSS gives the canvas. */
html.has-3d canvas.hero-3d{
  display:block;position:absolute;top:-24px;left:-10px;
  width:calc(100% + 20px);height:calc(100% + 24px);z-index:0;
  pointer-events:none;opacity:.85;
  -webkit-mask-image:radial-gradient(75% 70% at 50% 42%, #000 45%, transparent 92%);
  mask-image:radial-gradient(75% 70% at 50% 42%, #000 45%, transparent 92%);
}
html.has-3d canvas.hero-3d.fx-3d-off{display:none}

/* Soft cream behind the headline so the 3D world never fights the text. */
.fx-hero::before{
  content:'';position:absolute;inset:0;z-index:0;pointer-events:none;
  background:radial-gradient(58% 78% at 20% 46%, rgba(255,252,247,.94) 0%, rgba(255,252,247,.66) 48%, rgba(255,252,247,0) 78%);
}
.no-3d .fx-hero::before{display:none}

/* Hero entrance: each child rises in turn.
   fill-mode is 'backwards' on purpose — once an item has finished animating it
   drops back to its own styles, so pointer tilt on the art panel still works. */
.fx .fx-hero > * > *{opacity:0;transform:translateY(16px)}
.fx.fx-ready .fx-hero > * > *{animation:fxRise .72s var(--fx-ease) backwards}
.fx.fx-ready .fx-hero > * > *:nth-child(1){animation-delay:.04s}
.fx.fx-ready .fx-hero > * > *:nth-child(2){animation-delay:.12s}
.fx.fx-ready .fx-hero > * > *:nth-child(3){animation-delay:.2s}
.fx.fx-ready .fx-hero > * > *:nth-child(4){animation-delay:.28s}
.fx.fx-ready .fx-hero > * > *:nth-child(5){animation-delay:.36s}
.fx.fx-ready .fx-hero > * > *:nth-child(6){animation-delay:.44s}
@keyframes fxRise{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}
.fx.fx-settled .fx-hero > * > *{opacity:1;transform:none}

/* Hero art panel: a glassier card with a slow shine. */
.fx-hero .hero-art,.fx-hero .games-hero-art{
  position:relative;overflow:hidden;
  box-shadow:0 34px 60px -34px rgba(42,37,48,.7), inset 0 1px 0 rgba(255,255,255,.9);
}
.fx-hero .hero-art::after,.fx-hero .games-hero-art::after{
  content:'';position:absolute;top:-60%;left:-30%;width:60%;height:220%;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.75),transparent);
  transform:rotate(18deg);animation:fxSheen 6.5s ease-in-out infinite;
}
@keyframes fxSheen{0%{left:-40%}55%,100%{left:130%}}

/* The highlight behind a word in the headline gets a soft breathing glow. */
.pop{transition:background-size .5s ease}
.fx .pop{background-size:100% 100%;animation:fxPopPulse 4s ease-in-out infinite}
@keyframes fxPopPulse{0%,100%{background-size:100% 100%}50%{background-size:100% 118%}}

/* Floating stickers drift a little more playfully on their own timings. */
.sticker{animation-duration:5.2s}
.sticker.s2{animation-duration:6.1s}
.sticker.s3{animation-duration:4.6s}
.sticker.s4{animation-duration:5.8s}

/* Dream bars keep their 1.3s growth; add a glow tip. */
.dream-bar{position:relative}
.dream-bar i{position:relative}
.dream-bar i::after{
  content:'';position:absolute;right:0;top:-3px;bottom:-3px;width:8px;border-radius:999px;
  background:rgba(255,255,255,.9);filter:blur(2px);
}

/* ------------------------------------------------------- 4. scroll reveals */
.fx .reveal{opacity:0;transform:translateY(26px)}
.fx .reveal.in{
  opacity:1;transform:none;
  transition:opacity .7s var(--fx-ease), transform .7s var(--fx-ease);
  transition-delay:calc(var(--i,0) * 60ms);
}
.fx .stagger > *{opacity:0;transform:translateY(22px)}
.fx .stagger > *.in{
  opacity:1;transform:none;
  transition:opacity .62s var(--fx-ease), transform .62s var(--fx-ease);
  transition-delay:calc(var(--i,0) * 80ms);
}
/* Every section eyebrow gets a little marker. */
.eyebrow{position:relative;padding-left:22px}
.eyebrow::before{
  content:'';position:absolute;left:0;top:50%;width:14px;height:3px;border-radius:999px;
  background:var(--red);transform:translateY(-50%);
}
body[data-person="himu"] .eyebrow::before{background:var(--red)}

/* Stat numbers are big and count themselves up. */
.stat{transition:transform .28s var(--fx-spring), box-shadow .28s ease}
.stat:hover{transform:translateY(-5px) scale(1.02);box-shadow:var(--fx-glow)}
.stat b{font-size:clamp(1.5rem,3.4vw,2rem)}

/* --------------------------------------------------------- 5. cards + tilt */
.fx-tilt{will-change:transform;transition:box-shadow .3s ease}
.card.fx-tilt,.game-card.fx-tilt,.sib.fx-tilt{transition:box-shadow .3s ease}
/* overflow:hidden keeps the pointer shine and ripples inside each card.
   The gallery doodles are left out on purpose — their washi tape sits outside
   the box and would be clipped away. */
.card,.game-card,.sib,.facts li,.dream,.subject{position:relative;overflow:hidden}
.card::after,.game-card::after,.sib::after,.dream::after{
  content:'';position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background:radial-gradient(220px circle at var(--mx,50%) var(--my,50%), rgba(255,255,255,.65), transparent 65%);
  opacity:0;transition:opacity .3s ease;
}
.card:hover::after,.game-card:hover::after,.sib:hover::after,.dream:hover::after{opacity:1}
.card:hover,.facts li:hover,.dream:hover{box-shadow:var(--fx-glow)}
.card-icon{transition:transform .35s var(--fx-spring), background .3s ease}
.card:hover .card-icon{transform:translateY(-4px) rotate(-7deg) scale(1.08)}

/* Gallery doodles come alive when you hover them. */
.art .canvas{transition:transform .4s var(--fx-spring)}
.art:hover .canvas{transform:scale(1.06) rotate(-1.5deg)}
.art:hover::before,.art:hover::after{background:rgba(255,201,60,.95)}

.facts li{transition:transform .25s var(--fx-ease), box-shadow .25s ease}
.facts li:hover{transform:translateX(6px)}
.facts .emoji{transition:transform .3s var(--fx-spring)}
.facts li:hover .emoji{transform:scale(1.25) rotate(-8deg)}

.subject{transition:transform .25s var(--fx-ease), box-shadow .25s ease}
.subject:hover{transform:translateY(-3px);box-shadow:0 20px 34px -26px rgba(42,37,48,.9)}
.stars{display:inline-block;transition:transform .3s var(--fx-spring), filter .3s ease}
.subject:hover .stars,.card:hover .stars{transform:scale(1.08);filter:drop-shadow(0 3px 6px rgba(201,154,0,.5))}

/* Keeps the "now typing" fact lively. */
.pop-anim{animation:fxPop .4s var(--fx-spring)}
@keyframes fxPop{from{transform:scale(.9);opacity:.2}60%{transform:scale(1.03)}to{transform:scale(1);opacity:1}}

/* ------------------------------------------------------------- 6. buttons */
.btn,.gk-btn{position:relative;overflow:hidden;isolation:isolate}
.btn::before,.gk-btn::before{
  content:'';position:absolute;top:0;bottom:0;left:-70%;width:45%;z-index:-1;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.55),transparent);
  transform:skewX(-18deg);
}
.btn:hover::before,.gk-btn:hover::before{animation:fxSweep .7s ease}
@keyframes fxSweep{to{left:130%}}

.fx-ripple{
  position:absolute;border-radius:50%;pointer-events:none;
  background:radial-gradient(circle, rgba(255,255,255,.85), rgba(255,255,255,0) 70%);
  transform:scale(.2);opacity:.9;animation:fxRipple .6s ease-out forwards;
  mix-blend-mode:screen;
}
@keyframes fxRipple{to{transform:scale(1);opacity:0}}

.btn:active,.gk-btn:active{transform:scale(.97)}

/* -------------------------------------------------------------- 7. marquee */
.fx-marquee{
  display:flex;overflow:hidden;margin:8px 0 4px;padding-block:10px;
  border-block:3px dashed rgba(230,57,70,.18);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent);
}
.fx-marquee-track{
  display:flex;flex:none;align-items:center;gap:34px;padding-right:34px;
  animation:fxSlide 30s linear infinite;
}
.fx-marquee:hover .fx-marquee-track{animation-play-state:paused}
.fx-marquee-track span{
  font-family:var(--font-head);font-weight:800;font-size:.95rem;color:var(--muted);
  white-space:nowrap;display:inline-flex;align-items:center;gap:8px;
}
.fx-marquee-track b{color:var(--red)}
body[data-person="himu"] .fx-marquee-track b{color:var(--red-dark)}
@keyframes fxSlide{to{transform:translateX(-100%)}}

/* Section heads get a soft coloured hairline. */
.section-head{position:relative}
.section-head::after{
  content:'';display:block;width:88px;height:5px;border-radius:999px;margin-top:16px;
  background:linear-gradient(90deg,var(--red),var(--yellow));
}

/* ============================================================ 8. GAMES ROOM */

/* The games hero keeps the same 3D world but a slightly stronger card. */
.games-hero{position:relative}
.games-hero .smiley{filter:drop-shadow(0 12px 18px rgba(42,37,48,.25))}

.game-grid{gap:20px}
.game-card{
  border-radius:26px;
  background:linear-gradient(160deg,#fff,#fffdf9);
  transition:transform .3s var(--fx-ease), box-shadow .3s ease, border-color .3s ease;
  transform-style:preserve-3d;
}
.game-card:hover{box-shadow:0 34px 54px -30px rgba(42,37,48,.75), 0 0 0 3px rgba(230,57,70,.16)}
.game-card .game-emoji{
  transition:transform .4s var(--fx-spring), background .3s ease;
  background:linear-gradient(140deg,#fff3e6,#e8f4ff);
}
.game-card:hover .game-emoji{transform:rotate(-8deg) scale(1.12)}
.game-card[data-id="chess"] .game-emoji{background:linear-gradient(140deg,#f7efe4,#e9dcc8)}
.game-card[data-id="ludo"] .game-emoji{background:linear-gradient(140deg,#ffe6ea,#fff3d6)}
.game-card[data-id="pong"] .game-emoji{background:linear-gradient(140deg,#e6f0ff,#101a2b);color:#fff}
.game-card .game-tag{transition:background .3s ease, color .3s ease, transform .3s var(--fx-spring)}
.game-card:hover .game-tag{transform:translateY(-2px)}

/* Cards fade in as a group when the list is drawn. */
.game-card{animation:fxCardIn .5s var(--fx-ease) backwards;animation-delay:calc(var(--i,0) * 45ms)}
@keyframes fxCardIn{from{opacity:0;transform:translateY(18px) scale(.97)}to{opacity:1;transform:none}}

/* The game screen slides up when it opens. */
.fx-stage-in .stage-head{animation:fxRise .45s var(--fx-ease) both}
.fx-stage-in .gk-status{animation:fxRise .5s var(--fx-ease) .05s both}
.fx-stage-in .gk-root{animation:fxStageIn .55s var(--fx-ease) .1s both}
@keyframes fxStageIn{from{opacity:0;transform:translateY(22px) scale(.985)}to{opacity:1;transform:none}}

.stage-head{
  background:linear-gradient(120deg,#fff,#fffaf4);
  border:3px solid #fff;
}
.gk-mode-btn{transition:color .25s ease, transform .2s var(--fx-spring)}
.gk-mode-btn:hover{color:var(--ink)}

/* A sliding thumb behind the 2-Players / vs-Computer switch. polish.js measures
   the active button and positions the thumb, so the two labels can be any length. */
.fx-sport-switch{position:relative}
.fx-sport-thumb{
  position:absolute;top:4px;left:0;height:calc(100% - 8px);width:50%;
  border-radius:999px;background:#fff;pointer-events:none;
  box-shadow:0 6px 14px -10px rgba(0,0,0,.7);
  transition:transform .34s var(--fx-spring), width .34s var(--fx-spring);
}
.fx-sport-switch .gk-mode-btn{position:relative;z-index:1}
.fx-sport-switch .gk-mode-on{background:transparent;box-shadow:none}

.gk-filter{transition:transform .22s var(--fx-spring), background .25s ease, color .25s ease}
.gk-filter-on{box-shadow:0 14px 22px -16px var(--red)}

/* Boards sit on a felt table. */
.gk-root{
  background:
    radial-gradient(120% 90% at 50% 0%, #ffffff 40%, #fdf7f1 100%);
  border:3px solid #fff;
}
.gk-root .gk-grid{border-radius:14px}

/* The status line flashes whenever it changes. */
.gk-status{transition:transform .25s var(--fx-spring), background .3s ease}
.gk-status.fx-flash{animation:fxFlash .6s ease}
@keyframes fxFlash{
  0%{background:#fff0c8;transform:scale(1.015)}
  100%{background:#fff6dd;transform:scale(1)}
}

/* -------------------------------------------------- 9. in-game feedback */
@keyframes fxPopPiece{
  0%{transform:scale(.2) rotate(-18deg);opacity:0}
  62%{transform:scale(1.18) rotate(4deg);opacity:1}
  100%{transform:scale(1) rotate(0)}
}
@keyframes fxDrop{from{transform:translateY(-42px) scale(.85);opacity:0}to{transform:none;opacity:1}}
@keyframes fxGone{0%{transform:scale(1)}45%{transform:scale(1.35) rotate(12deg)}100%{transform:scale(0);opacity:0}}
@keyframes fxShake{0%,100%{transform:translateX(0)}18%{transform:translateX(-7px) rotate(-3deg)}38%{transform:translateX(6px) rotate(3deg)}58%{transform:translateX(-4px)}78%{transform:translateX(3px)}}
@keyframes fxGlowPulse{0%,100%{box-shadow:inset 0 0 0 4px var(--yellow)}50%{box-shadow:inset 0 0 0 6px var(--yellow), 0 0 22px rgba(255,201,60,.7)}}
@keyframes fxHintPulse{0%,100%{transform:scale(1);opacity:.85}50%{transform:scale(1.09);opacity:1}}
@keyframes fxRoll{0%{transform:rotate(0) scale(1)}25%{transform:rotate(-24deg) scale(1.22)}50%{transform:rotate(20deg) scale(1.08)}75%{transform:rotate(-10deg) scale(1.16)}100%{transform:rotate(0) scale(1)}}
@keyframes fxFlipUp{0%{transform:perspective(700px) rotateY(-88deg) scale(.9)}70%{transform:perspective(700px) rotateY(8deg)}100%{transform:perspective(700px) rotateY(0) scale(1)}}
@keyframes fxWinPulse{0%{transform:scale(1)}40%{transform:scale(1.12) rotate(3deg)}70%{transform:scale(1.04) rotate(-2deg)}100%{transform:scale(1)}}
@keyframes fxCrown{0%{transform:translateY(0) scale(1)}35%{transform:translateY(-16px) scale(1.3)}70%{transform:translateY(0) scale(1.06)}100%{transform:translateY(0) scale(1)}}
@keyframes fxBannerIn{0%{opacity:0;transform:translateY(26px) scale(.94)}60%{opacity:1;transform:translateY(-4px) scale(1.02)}100%{opacity:1;transform:none}}
@keyframes fxGlint{0%,100%{filter:brightness(1)}50%{filter:brightness(1.5) drop-shadow(0 0 8px rgba(255,201,60,.9))}}

.fx-pop{animation:fxPop .5s var(--fx-spring)}
.fx-shake{animation:fxShake .5s ease}
.fx-glow{animation:fxGlowPulse 1.1s ease-in-out 2}
.fx-hint{animation:fxHintPulse 1.15s ease-in-out infinite}
.fx-roll{animation:fxRoll .55s var(--fx-spring)}
.fx-flip-up{animation:fxFlipUp .45s var(--fx-ease)}
.fx-win{animation:fxWinPulse .8s var(--fx-spring) 2}
.fx-crown{animation:fxCrown .7s var(--fx-spring)}
.fx-glint{animation:fxGlint .8s ease 2}
.fx-place .gk-chk,.fx-place .gk-taint{animation:none}
.fx-place{animation:fxPopPiece .42s var(--fx-spring)}
.fx-drop{animation:fxDrop .38s var(--fx-ease)}
.fx-capture{animation:fxShake .4s ease}
.fx-gone{animation:fxGone .35s ease forwards}
.fx-piece-in{animation:fxPopPiece .45s var(--fx-spring)}
.fx-flash{animation:fxFlash .6s ease}

/* Chess / checkers / reversi pieces get real depth and shadow. */
.gk-sq{transition:transform .18s var(--fx-ease), filter .2s ease, background .2s ease}
.gk-chess,.gk-checkers,.gk-reversi{
  box-shadow:0 30px 50px -26px rgba(42,37,48,.85), 0 0 0 5px #fff;
  background:#fff;
}
.gk-chess .gk-chk,.gk-checkers .gk-chk{
  filter:drop-shadow(0 3px 3px rgba(0,0,0,.35));
  transition:transform .2s var(--fx-spring);
}
.gk-chess .gk-sq:hover .gk-chk{transform:translateY(-3px) scale(1.06)}
.gk-can-go::after{transition:transform .2s var(--fx-spring);animation:fxHintPulse 1.2s ease-in-out infinite}
.gk-can-take{animation:fxGlowPulse 1.1s ease-in-out infinite}
.gk-disc{transition:transform .45s var(--fx-ease), background .3s ease}
.gk-reversi .gk-cell:hover .gk-disc{transform:scale(1.04)}

/* Ludo: tokens slide between squares, dice tumbles, safe stars twinkle. */
.gk-token{transition:left .3s var(--fx-ease), top .3s var(--fx-ease), transform .25s var(--fx-spring)}
.gk-token-move{animation:fxHintPulse 1.05s ease-in-out infinite}
.gk-ludo{border:5px solid #fff;box-shadow:0 30px 50px -26px rgba(42,37,48,.85)}
.gk-dice{display:inline-block;filter:drop-shadow(0 4px 6px rgba(42,37,48,.3))}
.gk-ludo-safe::after{
  content:'★';position:absolute;inset:0;display:grid;place-items:center;
  font-size:9px;opacity:.55;animation:fxGlint 3s ease-in-out infinite;
}
.gk-ludo-cell{position:relative}

/* Memory: a proper 3D card flip. */
.gk-mem-card{
  transform-style:preserve-3d;
  transition:transform .35s var(--fx-ease), background .3s ease, box-shadow .3s ease;
}
.gk-mem-card:hover{transform:translateY(-4px) scale(1.03)}
.gk-mem-card.gk-matched{
  animation:fxWinPulse .7s var(--fx-spring);
  box-shadow:0 0 0 4px rgba(63,169,110,.5);
}

/* Connect four discs drop in; tic-tac-toe letters bounce. */
.gk-c4-cell{transition:background .3s ease, transform .25s var(--fx-spring)}
.gk-c4-cell.gk-p1,.gk-c4-cell.gk-p2{box-shadow:inset 0 -4px 10px -4px rgba(0,0,0,.35)}
.gk-ttt-cell{transition:transform .25s var(--fx-spring), background .3s ease}
.gk-ttt-cell:hover{transform:translateY(-3px)}
.gk-ttt-cell.gk-X,.gk-ttt-cell.gk-O{animation:fxPopPiece .38s var(--fx-spring)}
.gk-ttt-cell.gk-win{animation:fxWinPulse .8s var(--fx-spring) 3}

/* Simon pads, RPS hands, reaction pads and battleship all get a wobble. */
.gk-pad{transition:transform .12s ease, box-shadow .18s ease, filter .2s ease}
.gk-pad:hover{filter:brightness(1.06)}
.gk-pad.gk-lit{animation:fxWinPulse .5s var(--fx-spring)}
.gk-hand{transition:transform .3s var(--fx-spring), filter .3s ease}
.gk-rps-btn:hover ~ .gk-hands .gk-hand{transform:translateY(-6px) scale(1.1)}
.gk-rpad{transition:background .25s ease, transform .15s ease, box-shadow .25s ease}
.gk-arena.gk-go .gk-rpad{box-shadow:0 0 0 4px rgba(63,169,110,.5), 0 24px 40px -26px rgba(63,169,110,.9);animation:fxHintPulse 1s ease-in-out infinite}
.gk-arena.gk-done .gk-rpad{animation:fxWinPulse .6s var(--fx-spring)}
.gk-bs-cell,.gk-hex-cell,.gk-pit,.gk-mm-color,.gk-key,.gk-padbtn{transition:transform .2s var(--fx-spring), background .25s ease, box-shadow .25s ease}
.gk-bs-cell:hover,.gk-hex-cell:hover,.gk-mm-color:hover,.gk-key:hover{transform:translateY(-3px)}
.gk-pit-live{animation:fxHintPulse 1.3s ease-in-out infinite}
.gk-boom{animation:fxShake .45s ease}
.gk-mine-hit{animation:fxShake .5s ease}
.gk-snakecell{position:relative}
.gk-mpoint{transition:transform .3s var(--fx-spring)}
.gk-mp-take{animation:fxHintPulse 1.1s ease-in-out infinite}
.gk-word{transition:letter-spacing .3s ease}
.gk-scramble{animation:fxGlint 2.4s ease-in-out infinite}

/* Reaction duel pads while a round is live. */
.gk-live{box-shadow:0 0 0 4px rgba(230,57,70,.35)}
.gk-arena.gk-go .gk-rpad.gk-live{animation:fxHintPulse 1s ease-in-out infinite}

/* Ludo's four starting yards. */
.gk-ludo-yard{border-radius:6px;box-shadow:inset 0 0 0 2px rgba(42,37,48,.08)}

/* Cover screen for "pass the device" games. */
.gk-cover{backdrop-filter:blur(4px);animation:fxCardIn .4s var(--fx-ease)}
.gk-cover-card{animation:fxBannerIn .45s var(--fx-spring)}

/* Pong gets a glow and a soft vignette frame. */
.gk-canvas{
  box-shadow:0 0 0 4px #fff, 0 30px 54px -28px rgba(16,26,43,.95), inset 0 0 60px rgba(58,166,232,.25);
  background:radial-gradient(120% 100% at 50% 0%, #16233b, #0b1322 70%);
}
.gk-padbtn{transition:transform .15s var(--fx-spring), background .2s ease}
.gk-padbtn:active{transform:scale(.94)}

/* The winner banner rolls in with a trophy. */
.gk-result{
  background:linear-gradient(140deg,#fff,#fff7ef);
  border-style:solid;border-width:3px;border-color:rgba(230,57,70,.35);
  box-shadow:0 30px 54px -30px rgba(230,57,70,.85);
}
.gk-result.fx-banner-in{animation:fxBannerIn .6s var(--fx-spring)}
.gk-result p{display:flex;align-items:center;justify-content:center;gap:10px}
.gk-result p::before{content:'🏆';font-size:1.4rem;animation:fxCrown 1.4s var(--fx-spring) infinite}

.gk-rules{transition:box-shadow .3s ease}
.gk-rules[open]{box-shadow:inset 0 0 0 2px rgba(58,166,232,.25)}

/* ------------------------------------------------ 10. motion preferences */
@media (prefers-reduced-motion: reduce){
  .fx-aurora{display:none}
  .fx-aura,.fx-progress{display:none}
  canvas.hero-3d{display:none}
  .fx .fx-hero > * > *{opacity:1;transform:none}
  .fx .reveal,.fx .stagger > *{opacity:1;transform:none}
  .fx-marquee-track{animation:none}
}

/* ==========================================================================
   THE COLOUR PASS
   One crayon colour per card, chip, fact, subject and dream, cycling through
   the four house colours. Every grid on the site stops looking flat, and the
   games room can borrow the same variables for its own colours.
   ========================================================================== */
.grid > *:nth-child(4n+1),.facts li:nth-child(4n+1),.stats > *:nth-child(4n+1),.sib-row > *:nth-child(4n+1),.chip:nth-child(4n+1){
  --card-hue:#e63946;--card-soft:#fce7e9;--card-deep:#a62932
}
.grid > *:nth-child(4n+2),.facts li:nth-child(4n+2),.stats > *:nth-child(4n+2),.sib-row > *:nth-child(4n+2),.chip:nth-child(4n+2){
  --card-hue:#2f7fd1;--card-soft:#e6f0f9;--card-deep:#225b96
}
.grid > *:nth-child(4n+3),.facts li:nth-child(4n+3),.stats > *:nth-child(4n+3),.sib-row > *:nth-child(4n+3),.chip:nth-child(4n+3){
  --card-hue:#2f9e63;--card-soft:#e6f6ee;--card-deep:#1f7346
}
.grid > *:nth-child(4n+4),.facts li:nth-child(4n+4),.stats > *:nth-child(4n+4),.sib-row > *:nth-child(4n+4),.chip:nth-child(4n+4){
  --card-hue:#f4801a;--card-soft:#fef0e2;--card-deep:#b45c08
}

/* A crayon stripe along the top of every card. */
.card::before{
  content:'';position:absolute;top:0;left:0;right:0;height:7px;z-index:1;
  background:linear-gradient(90deg,var(--card-hue,#e63946),transparent 94%);
}
.card:hover::before{height:9px}

/* Stats, facts and dream bars each get their own colour too. */
.stat{position:relative;overflow:hidden}
.stat::before{content:'';position:absolute;top:0;left:0;right:0;height:6px;background:var(--card-hue,#e63946)}
.stat b{color:var(--card-deep,#e63946)}

.facts li{padding-left:20px}
.facts li::before{
  content:'';position:absolute;left:0;top:0;bottom:0;width:7px;background:var(--card-hue,#e63946);
}

.subject{box-shadow:var(--shadow), inset 7px 0 0 var(--card-hue,#e63946)}

.sib{padding-left:22px}
.sib::before{content:'';position:absolute;left:0;top:0;bottom:0;width:7px;background:var(--card-hue,#e63946)}

.dream .dream-bar i{background:linear-gradient(90deg,var(--card-hue,#ffc93c),var(--card-deep,#e63946))}
.dream .dream-top span{color:var(--card-deep,#e63946)}

/* Chips become a handful of coloured sweets. */
.chip{background:var(--card-soft,#fff);border-color:var(--card-hue,#e63946);color:var(--card-deep,#6d6577)}

/* The marquee and the footer get a rainbow edging. */
.fx-marquee-track span:nth-child(3n+1) b{color:#e63946}
.fx-marquee-track span:nth-child(3n+2) b{color:#2f7fd1}
.fx-marquee-track span:nth-child(3n+3) b{color:#2f9e63}
.site-footer{
  border-top:6px solid;
  border-image:linear-gradient(90deg,#e63946,#f4801a,#e8a300,#2f9e63,#2f7fd1,#8b5cf6) 1;
}

/* The games-room shelf and the brother cards keep their own accents. */
.game-card::before{display:none}
