/* Tic Tac Toe */

:root {
  --bg: #0b0b16;
  --panel: #15152a;
  --panel-2: #1c1c36;
  --line: #2a2a4a;
  --text: #eceaf6;
  --muted: #9a9ac0;
  --accent: #5858FD;
  --amber: #ffb703;
  --x: #6f6fff;
  --o: #ffb703;
  --win: #2ec4b6;
}

* { box-sizing: border-box; }

/* A class that sets `display` beats the browser's own `[hidden]` rule, so an
   element hidden from JavaScript with `el.hidden = true` stays on screen and
   the code looks correct while doing nothing. That is exactly how the Fire
   button stayed visible without a blaster: `.tbtn` sets `display: grid`. This
   reset settles it for every element, now and later. */
[hidden] { display: none !important; }


body {
  margin: 0;
  min-height: 100vh;
  background:
    radial-gradient(800px 400px at 15% -10%, rgba(88, 88, 253, 0.16), transparent 60%),
    radial-gradient(700px 400px at 90% 0%, rgba(255, 183, 3, 0.08), transparent 60%),
    var(--bg);
  color: var(--text);
  font-family: "Segoe UI", system-ui, -apple-system, Roboto, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}

/* Topbar */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px 26px;
  border-bottom: 1px solid var(--line);
  background: rgba(11, 11, 22, 0.7);
  backdrop-filter: blur(8px);
  position: sticky;
  top: 0;
  z-index: 10;
}
.topbar h1 { margin: 0; font-size: 19px; letter-spacing: -0.3px; }
.back { color: var(--muted); text-decoration: none; font-size: 14px; }
.back:hover { color: var(--text); }
.back::before { content: "< "; }
.ghost-btn {
  padding: 8px 16px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 13.5px;
  cursor: pointer;
}
.ghost-btn:hover { color: var(--text); border-color: var(--accent); }
.topbar-actions { display: flex; gap: 10px; align-items: center; }
.icon-only { min-width: 96px; }
.ghost-btn .sound-off { display: none; }
.ghost-btn[aria-pressed="true"] .sound-on { display: none; }
.ghost-btn[aria-pressed="true"] .sound-off { display: inline; }
.ghost-btn[aria-pressed="true"] { color: #ff8c8c; border-color: rgba(255,140,140,0.35); }

/* Layout */
.layout {
  max-width: 1080px;
  margin: 0 auto;
  padding: 34px 24px 60px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: 36px;
  align-items: start;
}

.board-side { display: flex; flex-direction: column; align-items: center; gap: 20px; }

.status-wrap { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.turn-chip {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin: 0;
  padding: 6px 15px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--panel);
  font-size: 13px;
  color: var(--muted);
  transition: opacity .2s ease;
}
.turn-chip[hidden] { display: none; }
.turn-dot {
  width: 11px; height: 11px;
  border-radius: 50%;
  background: var(--x);
  box-shadow: 0 0 0 4px rgba(111,111,255,0.16);
  transition: background .2s ease, box-shadow .2s ease;
}
.turn-dot.is-o { background: var(--o); box-shadow: 0 0 0 4px rgba(255,183,3,0.16); }
.turn-dot.is-thinking { animation: pulse 1s ease-in-out infinite; }
@keyframes pulse { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(0.75); opacity: 0.55; } }

.status {
  margin: 0;
  min-height: 26px;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.2px;
  text-align: center;
}
.status.is-win { color: var(--win); }
.status.is-lose { color: #ff6b6b; }
.status.is-draw { color: var(--muted); }

/* Board */
.board-wrap { position: relative; width: min(430px, 88vw); aspect-ratio: 1; }
.board {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  gap: 10px;
}
.cell {
  position: relative;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--panel);
  cursor: pointer;
  padding: 0;
  display: grid;
  place-items: center;
  transition: background .15s ease, border-color .15s ease, transform .1s ease;
}
.cell:hover:not(.is-taken):not(:disabled) { background: var(--panel-2); border-color: var(--accent); }
.cell:active:not(.is-taken) { transform: scale(0.98); }
.cell:disabled { cursor: default; }
.cell:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.cell.is-taken { cursor: default; }
.cell.is-winner { border-color: var(--win); background: rgba(46, 196, 182, 0.10); }

.cell svg { width: 56%; height: 56%; display: block; overflow: visible; }
/* The mark is decoration. Letting it take pointer events makes the cursor leave
   the button the instant a hover preview appears, which flickers the preview and
   makes cells genuinely hard to click. The button is the only hit target. */
.cell > * { pointer-events: none; }
.cell .mark-x line, .cell .mark-o circle {
  fill: none;
  stroke-linecap: round;
  stroke-width: 9;
  stroke-dasharray: 200;
  stroke-dashoffset: 200;
  animation: draw .28s ease-out forwards;
}
.cell .mark-x line { stroke: var(--x); }
.cell .mark-x line:nth-child(2) { animation-delay: .12s; }
.cell .mark-o circle { stroke: var(--o); stroke-dasharray: 290; stroke-dashoffset: 290; }
@keyframes draw { to { stroke-dashoffset: 0; } }

/* Hover preview of the mark that would be placed */
.cell.is-preview svg { opacity: 0.2; }
.cell.is-preview .mark-x line, .cell.is-preview .mark-o circle { animation: none; stroke-dashoffset: 0; }

@media (prefers-reduced-motion: reduce) {
  .cell .mark-x line, .cell .mark-o circle { animation-duration: .01s; }
  .winline.is-on line { animation-duration: .01s; }
  .turn-dot.is-thinking { animation: none; }
}

.winline {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.winline line {
  stroke: var(--win);
  stroke-width: 8;
  stroke-linecap: round;
  stroke-dasharray: 460;
  stroke-dashoffset: 460;
}
.winline.is-on line { animation: draw .4s .1s ease-out forwards; }

.board-actions { display: flex; gap: 12px; flex-wrap: wrap; justify-content: center; }

/* Side panel */
.panel-side { display: flex; flex-direction: column; gap: 18px; }
.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 18px 20px 20px;
}
.card h2 {
  margin: 0 0 14px;
  font-size: 11px;
  letter-spacing: 1.8px;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 700;
}
.card h2.sub { margin-top: 20px; }

.score { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; text-align: center; }
.score-item {
  padding: 12px 6px;
  border-radius: 11px;
  background: var(--panel-2);
  border: 1px solid var(--line);
}
.score-name { display: block; font-size: 11.5px; color: var(--muted); margin-bottom: 5px; }
.score-value { display: block; font-size: 26px; font-weight: 800; letter-spacing: -1px; }
.score-item:first-child .score-value { color: var(--x); }
.score-item:last-child .score-value { color: var(--o); }
.score-draw .score-value { color: var(--muted); }
.round-note { margin: 14px 0 0; font-size: 13px; color: var(--muted); text-align: center; }
.mini-stats {
  margin: 14px 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  text-align: center;
}
.mini-stats div { display: flex; flex-direction: column; gap: 3px; }
.mini-stats dt { font-size: 10.5px; letter-spacing: 1px; text-transform: uppercase; color: var(--muted); }
.mini-stats dd { margin: 0; font-size: 15px; font-weight: 700; }

.segmented {
  display: flex;
  padding: 4px;
  gap: 4px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel-2);
}
.segmented button {
  flex: 1;
  padding: 9px 10px;
  border: none;
  border-radius: 7px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 13.5px;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.segmented button:hover { color: var(--text); }
.segmented button.is-on { background: var(--accent); color: #fff; font-weight: 600; }

.hint { margin: 12px 0 0; font-size: 12.5px; line-height: 1.6; color: var(--muted); }

.card-keys ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 11px; }
.card-keys li { display: flex; align-items: baseline; gap: 10px; font-size: 13px; color: var(--muted); }
kbd {
  display: inline-block;
  min-width: 24px;
  padding: 3px 7px;
  border: 1px solid var(--line);
  border-bottom-width: 2px;
  border-radius: 6px;
  background: var(--panel-2);
  color: var(--text);
  font-family: inherit;
  font-size: 11.5px;
  text-align: center;
  flex-shrink: 0;
}

/* Buttons */
.btn {
  padding: 11px 24px;
  border-radius: 10px;
  border: 1px solid transparent;
  font: inherit;
  font-size: 14.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease, transform .12s ease;
}
.btn:hover { transform: translateY(-1px); }
.btn-primary { background: var(--accent); color: #fff; }
.btn-primary:hover { background: #4646e0; }
.btn-ghost { background: transparent; border-color: var(--line); color: var(--text); }
.btn-ghost:hover { border-color: var(--accent); }

/* Help modal: head / scrolling body / foot, so the close button never scrolls away */
.overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  place-items: center;
  padding: 24px;
  background: rgba(4, 4, 12, 0.8);
  backdrop-filter: blur(6px);
}
.overlay[hidden] { display: none; }
.modal {
  width: min(560px, 100%);
  max-height: 86vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6);
}
.modal-head {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px 24px 14px;
  border-bottom: 1px solid var(--line);
}
.modal-head h2 { margin: 0; font-size: 20px; }
.icon-btn {
  width: 32px; height: 32px;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--muted);
  font: inherit;
  cursor: pointer;
}
.icon-btn:hover { color: var(--text); border-color: var(--accent); }
.modal-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 18px 24px 22px;
  color: var(--muted);
  font-size: 14.5px;
  line-height: 1.7;
}
.modal-body h3 { margin: 22px 0 8px; font-size: 14px; color: var(--text); }
.modal-body p { margin: 0 0 12px; }
.modal-body strong { color: var(--text); }
.modal-foot {
  flex-shrink: 0;
  display: flex;
  justify-content: flex-end;
  padding: 14px 24px;
  border-top: 1px solid var(--line);
  background: var(--panel-2);
}

@media (max-width: 900px) {
  .layout { grid-template-columns: 1fr; gap: 28px; }
  .panel-side { max-width: 430px; width: 100%; margin: 0 auto; }
}
@media (max-width: 520px) {
  .topbar {
    padding: 12px max(16px, env(safe-area-inset-right)) 12px max(16px, env(safe-area-inset-left));
  }
  .topbar h1 { font-size: 16px; }
  .layout {
    padding: 16px max(14px, env(safe-area-inset-right))
             calc(28px + env(safe-area-inset-bottom)) max(14px, env(safe-area-inset-left));
    gap: 18px;
  }
  .board-side { gap: 14px; }
  /* The board is the point of the page, so it gets whatever width is going. */
  .board-wrap { width: min(430px, 92vw); }
}

/* A landscape phone is wide and very short. Side by side again, and the whole
   thing pinned to the viewport so the board is never half below the fold: sizing
   the board off the height is the only way it stays fully visible at 360px tall. */
@media (max-height: 560px) and (orientation: landscape) {
  html, body { height: 100%; overflow: hidden; }
  .topbar { padding: 7px 16px; }
  .topbar h1 { font-size: 15px; }
  .layout {
    grid-template-columns: minmax(0, 1fr) min(300px, 42vw);
    gap: 18px;
    padding: 10px 16px;
    height: calc(100% - 46px);
    align-items: stretch;
  }
  .board-side {
    justify-content: center;
    gap: 8px;
    min-height: 0;
  }
  /* The column has to hold the status line, the board and the two action
     buttons. Sizing the board off the height alone overshot and pushed New game
     and Reset off the bottom, where nothing could scroll to reach them, so the
     subtraction has to account for everything stacked with it. */
  .board-wrap { width: min(430px, calc(100vh - 172px)); }
  .status { font-size: 14.5px; }
  .board-actions { gap: 10px; }
  .board-actions .btn { padding: 8px 16px; font-size: 13.5px; }
  /* The panel scrolls inside its own column rather than stretching the page. */
  .panel-side {
    max-width: none;
    margin: 0;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
}


/* A 19px-tall text link is not a comfortable tap target on a phone. */
.topbar-actions a, .topbar-actions button { min-height: 34px; display: inline-flex; align-items: center; }
