/* ===================================================== tic tac toe cabinet */
.ttt {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(0.8rem, 2.4vh, 1.4rem);
  --board-size: min(78vw, 56vh, 440px);
}

/* =============================================================== scoreboard */
.ttt__scores {
  display: flex;
  align-items: stretch;
  gap: 0.5rem;
  padding: 0.45rem;
  border-radius: calc(var(--radius) * 0.7);
  background: rgba(0, 0, 0, 0.3);
  border: 1px solid var(--mist);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.ttt__score {
  min-width: 92px;
  padding: 0.45rem 0.9rem;
  border-radius: calc(var(--radius) * 0.5);
  text-align: center;
  transition: background .5s var(--ease-out), box-shadow .5s var(--ease-out);
}
.ttt__score-label {
  display: block;
  font-size: 0.6rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.ttt__score-value {
  display: block;
  font-family: var(--display);
  font-weight: var(--display-weight);
  font-size: 1.7rem;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
}
.ttt__score--x .ttt__score-value { color: var(--x); }
.ttt__score--o .ttt__score-value { color: var(--o); }
.ttt__score--d .ttt__score-value { color: var(--ink-dim); }
/* The 8-bit face runs large for its size; the score digits come back down. */
[data-world='neon'] .ttt__score-value { font-size: 1.05rem; line-height: 1.6; }
.ttt__score.is-turn { background: rgba(255, 255, 255, .05); box-shadow: inset 0 0 0 1px var(--mist-strong); }
.ttt__score--x.is-turn { box-shadow: inset 0 0 0 1px rgba(var(--x-rgb), .4), 0 0 22px -6px rgba(var(--x-rgb), .5); }
.ttt__score--o.is-turn { box-shadow: inset 0 0 0 1px rgba(var(--o-rgb), .4), 0 0 22px -6px rgba(var(--o-rgb), .5); }
.ttt__score-value.is-bumped { animation: ttt-bump .6s var(--ease-spring); }
@keyframes ttt-bump {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.45); filter: brightness(1.5); }
  100% { transform: scale(1); }
}

/* ==================================================================== board */
.ttt__wrap { position: relative; width: var(--board-size); height: var(--board-size); flex: none; }

.ttt__glow {
  position: absolute;
  inset: -16%;
  border-radius: 50%;
  background: var(--glow);
  filter: blur(14px);
  animation: ttt-glow 9s ease-in-out infinite;
  pointer-events: none;
}
@keyframes ttt-glow { 50% { transform: scale(1.07); opacity: .75; } }

.ttt__board {
  position: relative;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  gap: clamp(6px, 1.6vw, 10px);
  width: 100%;
  height: 100%;
  padding: clamp(8px, 2vw, 14px);
  border-radius: var(--radius);
  background: var(--panel-bg);
  border: 1px solid var(--mist-strong);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .07),
    inset 0 -20px 40px -24px rgba(0, 0, 0, .8),
    0 30px 70px -30px rgba(0, 0, 0, .9);
  backdrop-filter: blur(14px) saturate(1.1);
  -webkit-backdrop-filter: blur(14px) saturate(1.1);
  transition: filter .9s var(--ease-out), background .6s var(--ease-out);
}
.ttt__board::after {
  content: '';
  position: absolute; inset: 0;
  border-radius: var(--radius);
  pointer-events: none;
  opacity: .35;
  background: repeating-linear-gradient(102deg,
    transparent 0 7px, rgba(255, 240, 200, .022) 7px 8px,
    transparent 8px 19px, rgba(0, 0, 0, .05) 19px 21px);
  mix-blend-mode: overlay;
}
/* Every world is neon now, so the board wears the neon frame unconditionally. */
.ttt__board {
  border-color: rgba(var(--accent-rgb), .45);
  box-shadow:
    inset 0 0 30px -10px rgba(var(--accent-rgb), .4),
    0 0 40px -14px rgba(var(--accent-rgb), .5),
    0 30px 70px -30px #000;
}
.ttt__board::after { opacity: 0; }

.ttt__row { display: contents; }

/* ==================================================================== cells */
.ttt__cell {
  position: relative;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, .022);
  color: inherit;
  font: inherit;
  cursor: pointer;
  overflow: hidden;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  transition: background .35s var(--ease-out), border-color .35s var(--ease-out),
              transform .4s var(--ease-spring), box-shadow .4s var(--ease-out);
}
.ttt__cell::before {
  content: '';
  position: absolute; inset: 0;
  opacity: 0;
  background: radial-gradient(circle at 50% 50%, rgba(var(--accent-rgb), .16), transparent 68%);
  transition: opacity .35s var(--ease-out);
}
.ttt__cell:hover:not(.is-filled):not(:disabled)::before,
.ttt__cell:focus-visible::before { opacity: 1; }
.ttt__cell:hover:not(.is-filled):not(:disabled) {
  background: rgba(255, 255, 255, .055);
  border-color: rgba(var(--accent-rgb), .3);
  transform: translateY(-2px);
}
.ttt__cell:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.ttt__cell:active:not(.is-filled):not(:disabled) { transform: translateY(0) scale(.97); }
.ttt__cell.is-filled { cursor: default; }
.ttt__cell svg { width: 68%; height: 68%; overflow: visible; }

.ttt__ghost {
  position: absolute;
  inset: 16%;
  opacity: 0;
  transition: opacity .3s var(--ease-out);
  pointer-events: none;
}
.ttt__cell:hover:not(.is-filled):not(:disabled) .ttt__ghost,
.ttt__cell:focus-visible:not(.is-filled) .ttt__ghost { opacity: .14; }

/* ==================================================================== marks */
.mark .stroke {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 9;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: mark-grow .55s var(--ease-out) var(--d, 0s) forwards;
}
.mark .stroke--thin { stroke-width: 4; }
@keyframes mark-grow { to { stroke-dashoffset: 0; } }
.mark .stroke { stroke-linecap: butt; stroke-width: 11; }

.mark--x .stroke { stroke: var(--x); }
.mark--o .stroke { stroke: var(--o); }
.mark--x { filter: drop-shadow(0 0 7px rgba(var(--x-rgb), .6)) drop-shadow(0 0 20px rgba(var(--x-rgb), .28)); }
.mark--o { filter: drop-shadow(0 0 7px rgba(var(--o-rgb), .6)) drop-shadow(0 0 20px rgba(var(--o-rgb), .3)); }

.mark .accent {
  fill: currentColor;
  stroke: none;
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
  animation: mark-accent .5s var(--ease-spring) var(--ad, .52s) forwards;
}
.mark--x .accent { color: var(--accent-x); }
.mark--o .accent { color: var(--accent-o); }
@keyframes mark-accent {
  from { opacity: 0; transform: scale(.2) rotate(-40deg); }
  to   { opacity: .95; transform: scale(1) rotate(0deg); }
}

.ttt__ghost .mark { filter: none; }
.ttt__ghost .stroke { animation: none; stroke-dashoffset: 0; }
.ttt__ghost .accent { animation: none; opacity: .8; }

/* ============================================================== win / draw */
.ttt__cell.is-win {
  background: rgba(var(--accent-rgb), .1);
  border-color: rgba(var(--accent-rgb), .55);
  box-shadow:
    0 0 0 1px rgba(var(--accent-rgb), .3),
    0 0 36px -6px rgba(var(--accent-rgb), .55),
    inset 0 0 28px -8px rgba(var(--accent-rgb), .5);
  animation: ttt-lift 2.4s var(--ease-out) infinite;
  z-index: 1;
}
@keyframes ttt-lift {
  0%, 100% { transform: translateY(0) scale(1); }
  40%      { transform: translateY(-5px) scale(1.035); }
}
.ttt__cell.is-win:nth-child(odd) { animation-delay: .12s; }
.ttt__cell.is-win .mark { filter: drop-shadow(0 0 12px currentColor) drop-shadow(0 0 30px rgba(var(--accent-rgb), .6)); }

.ttt__beam {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  pointer-events: none;
  opacity: 0;
  transition: opacity .5s var(--ease-out);
  filter: drop-shadow(0 0 10px rgba(var(--accent-rgb), .8));
}
.ttt__beam.is-visible { opacity: 1; }
.ttt__beam.is-visible .ttt__beam-line {
  stroke-dasharray: 200;
  stroke-dashoffset: 200;
  animation: beam-in .7s var(--ease-out) .15s forwards, beam-pulse 2.2s ease-in-out .9s infinite;
}
@keyframes beam-in { to { stroke-dashoffset: 0; } }
@keyframes beam-pulse { 50% { stroke-width: 4.5; opacity: .8; } }
.ttt__beam-mid { stop-color: var(--accent-soft); }
.ttt__beam-end { stop-color: var(--accent); }

.ttt__board.is-draw { filter: saturate(.45) brightness(.82); }
.ttt__wrap.is-draw::after {
  content: '';
  position: absolute;
  inset: -4%;
  border-radius: calc(var(--radius) + 4px);
  pointer-events: none;
  background: linear-gradient(100deg, transparent 0%, rgba(205, 230, 215, .22) 45%, rgba(205, 230, 215, .1) 60%, transparent 100%);
  animation: ttt-fog 2.6s var(--ease-out) forwards;
}
@keyframes ttt-fog {
  from { transform: translateX(-100%); opacity: 0; }
  35%  { opacity: 1; }
  to   { transform: translateX(100%); opacity: 0; }
}
.ttt__board.is-thinking {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .07),
    0 0 50px -16px rgba(var(--accent-rgb), .4),
    0 30px 70px -30px rgba(0, 0, 0, .9);
}

/* =================================================================== howto */
.ttt__howto {
  max-width: 48ch;
  padding: 1.1rem 1.3rem;
  border-radius: calc(var(--radius) * .8);
  background: rgba(0, 0, 0, .26);
  border: 1px solid var(--mist);
}
.ttt__howto ul { margin: 0; padding-left: 1.1rem; }
.ttt__howto li { margin-bottom: .4rem; font-size: .85rem; line-height: 1.6; color: var(--ink-dim); }
.ttt__howto strong { color: var(--ink); font-weight: 600; }

@media (max-width: 480px) {
  .ttt { --board-size: min(88vw, 52vh, 400px); }
  .ttt__scores { width: 100%; }
  .ttt__score { min-width: 0; flex: 1; padding: .4rem .35rem; }
}

@media (prefers-reduced-motion: reduce) {
  .mark .stroke { stroke-dashoffset: 0; }
  .mark .accent { opacity: .95; }
  .ttt__cell.is-win { transform: none; }
}

/* The online room panel sits right under the board, above the how-to. */
.ttt__online { display: flex; justify-content: center; }
.ttt__online.is-hidden { display: none; }
