.board-loading-text { font-size: 13px; font-weight: 700; color: var(--muted); }
  @media (prefers-reduced-motion: reduce) { .board-spinner { animation: none; } }


  .arrow-board {
    display: grid; box-sizing: content-box;
    background: linear-gradient(135deg, #fdf1ff 0%, #eef9ff 45%, #f0fffa 100%);
    border-radius: 22px;
    box-shadow:
      inset 0 0 0 2px rgba(255,255,255,.85),
      inset 0 0 0 4px rgba(168,85,247,.14),
      0 10px 26px rgba(124,58,237,.14),
      0 3px 10px rgba(0,0,0,.07);
  }

  /* Gap comes from each tile's own margin, not CSS grid `gap` — that way the
     grid's total pixel size stays exactly cols×cellPx / rows×cellPx (what
     fitBoard() budgeted for the arena), regardless of spacing. */
  .arrow-tile {
    position: relative;
    appearance: none; border: none; padding: 0; cursor: pointer;
    margin: max(2px, calc(var(--cell, 30px) * .06));
    display: flex; align-items: center; justify-content: center;
    border-radius: 26%;
    background: linear-gradient(155deg, var(--c1, #fff) 0%, var(--c2, var(--color, #7444e8)) 82%);
    box-shadow:
      inset 0 -7px 9px rgba(0,0,0,.22),
      inset 0 7px 8px rgba(255,255,255,.7),
      inset 0 0 0 1.5px rgba(255,255,255,.4),
      0 4px 0 rgba(0,0,0,.15),
      0 7px 11px rgba(0,0,0,.2);
    transition: transform .14s cubic-bezier(.34,1.56,.64,1), box-shadow .14s ease, opacity .3s;
    touch-action: none;
    overflow: hidden;
  }
  /* Full-surface sheen (bright top, faint shade at the very bottom edge only)
     makes the tile read as a glossy 3D gumdrop instead of a flat swatch —
     kept light so the base color stays vivid rather than muddy; the ::after
     layer stacks a bold primary shine with a smaller secondary glint for a
     "toy plastic" gloss read. */
  .arrow-tile::before {
    content: ''; position: absolute; inset: 0; pointer-events: none;
    background: linear-gradient(160deg, rgba(255,255,255,.6) 0%, rgba(255,255,255,.16) 32%, rgba(255,255,255,0) 55%, rgba(0,0,0,.12) 100%);
  }
  .arrow-tile::after {
    content: ''; position: absolute; inset: 0; pointer-events: none; z-index: 2;
    background:
      radial-gradient(ellipse at 30% 24%, rgba(255,255,255,.95) 0%, rgba(255,255,255,0) 34%),
      radial-gradient(ellipse at 70% 64%, rgba(255,255,255,.4) 0%, rgba(255,255,255,0) 22%);
  }
  .arrow-tile:active {
    transform: scale(.88) translateY(2px);
    box-shadow:
      inset 0 -3px 5px rgba(0,0,0,.22),
      inset 0 3px 3px rgba(255,255,255,.55),
      inset 0 0 0 1.5px rgba(255,255,255,.35),
      0 1px 0 rgba(0,0,0,.15),
      0 2px 4px rgba(0,0,0,.14);
  }
  /* Layered drop-shadows act as a thin dark outline so the white glyph stays
     readable even on the palette's lighter candy tones (lemon, mint,
     lavender…), on top of the soft drop shadow for depth. */
  .arrow-tile-glyph {
    width: 56%; height: 56%; fill: #fff; transform: rotate(var(--rot, 0deg));
    filter:
      drop-shadow(0 1.4px 0 rgba(0,0,0,.35)) drop-shadow(0 -1.4px 0 rgba(0,0,0,.35))
      drop-shadow(1.4px 0 0 rgba(0,0,0,.35)) drop-shadow(-1.4px 0 0 rgba(0,0,0,.35))
      drop-shadow(0 2px 2px rgba(0,0,0,.3));
    pointer-events: none; position: relative; z-index: 3;
  }

  .arrow-tile.flying { transform: translate(var(--tx,0), var(--ty,0)); opacity: 0; pointer-events: none; z-index: 5; }

  .arrow-tile.blocked { animation: arrowBump .3s ease; background: var(--danger) !important; }
  @keyframes arrowBump { 30% { transform: translate(var(--bx,0px), var(--by,0px)); } 60% { transform: translate(calc(var(--bx,0px) * -.4), calc(var(--by,0px) * -.4)); } 100% { transform: translate(0,0); } }

  .arrow-board.spotlight .arrow-tile:not(.spotlighted) { opacity: .3; transition: opacity .2s; }
  .arrow-tile.spotlighted {
    box-shadow:
      inset 0 -7px 9px rgba(0,0,0,.22),
      inset 0 7px 8px rgba(255,255,255,.7),
      inset 0 0 0 1.5px rgba(255,255,255,.4),
      0 0 0 3px #38bdf8, 0 0 14px #38bdf8;
  }
  .arrow-tile.spotlighted.pulse { animation: spotPulse 1s ease-in-out infinite; }
  .arrow-board.debug .arrow-tile.debug-safe { outline: 2px solid #16a34a; outline-offset: -2px; }
  .arrow-board.debug .arrow-tile.debug-blocked { outline: 2px solid #dc2626; outline-offset: -2px; }
  @keyframes spotPulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.08); } }

  /* ── Result overlay (shared with level-complete / final win / game over) ── */
  .result {
    display: none; position: absolute; inset: 0;
    background: rgba(255,255,255,.94); border-radius: 16px;
    flex-direction: column; align-items: center; justify-content: center;
    gap: 10px; z-index: 20; backdrop-filter: blur(4px); padding: 16px; text-align: center;
  }
  .result.show { display: flex; }
  .result-emoji { font-size: 3.5rem; }
  .result-title { font-size: 20px; font-weight: 800; color: var(--success); letter-spacing: -.02em; }
  .result-sub { font-size: 13px; color: var(--muted); }
  .result-best { font-size: 12px; font-weight: 700; color: var(--muted); }
  .lose-taunt { font-size: 13px; color: var(--muted); line-height: 1.4; max-width: 300px; margin-top: 2px; }
  .next-level-info {
    margin-top: 4px; padding: 10px 16px; border-radius: 12px;
    background: linear-gradient(120deg, var(--accent), var(--accent2));
    font-size: 13px; font-weight: 700; color: #fff; text-align: center; line-height: 1.5;
    box-shadow: 0 4px 14px rgba(245,158,11,.35);
  }
  .result-btn {
    margin-top: 6px; padding: 10px 28px;
    background: linear-gradient(120deg, var(--accent), var(--accent2));
    color: #fff; border: none; border-radius: 10px;
    font-family: 'Sora', sans-serif; font-size: 13px; font-weight: 700;
    cursor: pointer; letter-spacing: .5px; text-transform: uppercase;
    box-shadow: 0 4px 14px rgba(245,158,11,.3); transition: filter .15s;
  }
  .result-btn:hover { filter: saturate(1.1); }
  .result-btn:active { transform: scale(.9); }
  .result-btn:focus-visible { outline:3px solid rgba(56,189,248,.55); outline-offset:3px; }
  .result-btn:disabled { opacity:.55; cursor:wait; }
  .wof-share-row { display: flex; align-items: center; justify-content: center; gap: 10px; margin-top: 4px; }
  .wof-thumb { width: 46px; height: 46px; border-radius: 8px; object-fit: cover; border: 1.5px solid var(--line); }
  .btn-share { background: linear-gradient(120deg, #38bdf8, #6366f1); color: #fff; border: none; }

  /* ── Confetti ── */
  .confetti-layer { position: fixed; inset: 0; pointer-events: none; z-index: 200; overflow: hidden; }
  .confetti-piece { position: absolute; top: -10px; width: 8px; height: 14px; opacity: .9; animation: confettiFall linear forwards; }
  @keyframes confettiFall { to { transform: translateY(110vh) rotate(540deg); opacity: 0; } }

  /* ── Level progress ── */
  .level-bar { position:relative; display:flex; align-items:center; justify-content:center; min-height:28px; margin:0 0 10px; flex-shrink:0; }
  .level-core { display:flex; flex-direction:column; align-items:center; gap:7px; }
  .timer-badge { display:none; position:absolute; right:0; top:50%; transform:translateY(-50%); min-width:78px; padding:5px 9px; border-radius:999px; background:#e0f2fe; color:#075985; font-size:12px; font-weight:800; font-variant-numeric:tabular-nums; text-align:center; }

/* Candy tile material system. Kept after the legacy rules so interaction and
   game code remain untouched while the complete visual layer is replaceable. */
.arrow-tile {
  --tile-depth: clamp(1px, calc(var(--cell, 30px) * .025), 2.25px);
  --tile-gap: clamp(1.5px, calc(var(--cell, 30px) * .038), 3px);
  margin: var(--tile-gap); border: 1px solid rgba(255,255,255,.38); border-radius: clamp(9px, 25%, 21px); isolation: isolate;
  background:
    radial-gradient(ellipse 78% 46% at 50% 18%, rgba(255,255,255,.28) 0%, transparent 72%),
    radial-gradient(ellipse 72% 52% at 50% 58%, color-mix(in srgb, var(--tile-accent) 32%, transparent) 0%, transparent 74%),
    radial-gradient(ellipse 105% 48% at 50% 104%, color-mix(in srgb, var(--tile-bottom) 76%, transparent) 0%, transparent 72%),
    linear-gradient(165deg, color-mix(in srgb, var(--tile-top) 80%, white) 0%, var(--tile-top) 20%, var(--tile-main) 58%, color-mix(in srgb, var(--tile-main) 74%, var(--tile-bottom)) 84%, var(--tile-bottom) 100%);
  box-shadow:
    inset 0 2px 2px rgba(255,255,255,.72),
    inset 2px 1px 3px rgba(255,255,255,.25),
    inset -2px -1px 3px color-mix(in srgb, var(--tile-edge) 18%, transparent),
    inset 0 -4px 5px color-mix(in srgb, var(--tile-edge) 20%, transparent),
    0 var(--tile-depth) 1px color-mix(in srgb, var(--tile-edge) 50%, transparent),
    0 calc(var(--tile-depth) + 2px) 5px color-mix(in srgb, var(--tile-shadow) 24%, transparent);
  transition: transform 105ms cubic-bezier(.2,.8,.2,1), box-shadow 105ms ease, opacity 260ms ease;
  -webkit-tap-highlight-color: transparent;
}
.arrow-tile::before {
  inset: 0; height: auto; z-index: 1; border-radius: inherit;
  background:
    radial-gradient(circle at 13% 13%, rgba(255,255,255,.92) 0 calc(var(--cell) * .025), transparent calc(var(--cell) * .038)),
    radial-gradient(ellipse 7% 3.2% at 25% 11%, rgba(255,255,255,.68) 0 82%, transparent 100%),
    radial-gradient(ellipse 66% 23% at 48% 7%, rgba(255,255,255,.48), rgba(255,255,255,.12) 48%, transparent 72%),
    linear-gradient(155deg, rgba(255,255,255,.20), transparent 40%);
  filter: none; transform: none;
}
.arrow-tile::after {
  content: '✦'; inset: auto 8% 7% auto; width: auto; height: auto; color: rgba(255,255,255,.72);
  border: 0; background: none; font-size: clamp(5px, calc(var(--cell) * .105), 10px); line-height: 1; text-shadow: -.65em .35em 0 rgba(255,255,255,.42);
}
.arrow-tile[data-gloss="1"]::before { inset: 0; transform: scaleX(-1); opacity: .88; }
.arrow-tile[data-gloss="2"]::before { inset: 0; transform: none; opacity: .72; }
.arrow-tile:active {
  transform: translateY(calc(var(--tile-depth) * .58)) scale(.975);
  box-shadow: inset 0 1px 1px rgba(255,255,255,.52), inset 0 -1px 0 rgba(55,35,75,.1), 0 calc(var(--tile-depth) * .25) 0 color-mix(in srgb, var(--tile-edge) 76%, white), 0 2px 3px color-mix(in srgb, var(--tile-shadow) 40%, transparent);
}
.arrow-tile-glyph {
  width: 60%; height: 60%; overflow: visible;
  filter: drop-shadow(.6px 1px 0 rgba(255,255,255,.46));
}
.arrow-tile-recess {
  fill: color-mix(in srgb, var(--tile-main) 58%, white);
  stroke: color-mix(in srgb, var(--tile-edge) 78%, transparent);
  stroke-width: 2.05px; stroke-linejoin: round; paint-order: stroke fill;
  transform: translate(-.35px,-.45px);
}
.arrow-tile-face {
  fill: rgba(255,255,255,.93);
  stroke: rgba(255,255,255,.7); stroke-width: .42px; stroke-linejoin: round; paint-order: stroke fill;
  transform: translate(.2px,.35px);
  filter: drop-shadow(-.55px -.7px .15px color-mix(in srgb, var(--tile-edge) 55%, transparent));
}
.arrow-tile.blocked {
  background:
    radial-gradient(ellipse 78% 46% at 50% 18%, rgba(255,255,255,.28) 0%, transparent 72%),
    radial-gradient(ellipse 72% 52% at 50% 58%, color-mix(in srgb, var(--tile-accent) 32%, transparent) 0%, transparent 74%),
    radial-gradient(ellipse 105% 48% at 50% 104%, color-mix(in srgb, var(--tile-bottom) 76%, transparent) 0%, transparent 72%),
    linear-gradient(165deg, color-mix(in srgb, var(--tile-top) 80%, white) 0%, var(--tile-top) 20%, var(--tile-main) 58%, color-mix(in srgb, var(--tile-main) 74%, var(--tile-bottom)) 84%, var(--tile-bottom) 100%) !important;
  animation: arrowCandyBump 220ms cubic-bezier(.2,.8,.25,1);
}
@keyframes arrowCandyBump { 38% { transform: translate(var(--bx,0px),var(--by,0px)) scale(.965); } 72% { transform: translate(calc(var(--bx,0px) * -.18),calc(var(--by,0px) * -.18)) scale(1.01); } }
.arrow-tile.spotlighted { box-shadow: inset 0 1px 1px rgba(255,255,255,.68), 0 var(--tile-depth) 0 color-mix(in srgb, var(--tile-edge) 82%, white), 0 0 0 2px #fff, 0 0 0 4px #5dd7f7, 0 3px 9px rgba(56,189,248,.32); }
.arrow-board[data-grid-size="8"] .arrow-tile, .arrow-board[data-grid-size="9"] .arrow-tile, .arrow-board[data-grid-size="10"] .arrow-tile { --tile-gap: max(1.25px, calc(var(--cell) * .037)); }
.arrow-board[data-grid-size="9"] .arrow-tile::after, .arrow-board[data-grid-size="10"] .arrow-tile::after { display: none; }
.arrow-board[data-grid-size="10"] .arrow-tile::before { height: 25%; opacity: .62; filter: none; }
.arrow-board[data-grid-size="9"] .arrow-tile-glyph, .arrow-board[data-grid-size="10"] .arrow-tile-glyph { width: 64%; height: 64%; }
@media (hover:hover) { .arrow-tile:hover:not(:active):not(.flying):not(.blocked) { transform: translateY(-1px) scale(1.015); filter: saturate(1.035); } }
@media (prefers-reduced-motion: reduce) { .arrow-tile { transition-duration: 1ms; } .arrow-tile.blocked { animation-duration: 1ms; } }

/* Successful move: the physical tile must win over hover/press selectors and
   travel completely beyond the clipped board before it is removed. */
.arrow-tile.flying {
  transform: translate(var(--tx,0), var(--ty,0)) !important;
  opacity: 1;
  filter: none;
  pointer-events: none;
  z-index: 5;
}

.arrow-board {
  padding: 0; border-radius: 0; background: transparent; box-shadow: none;
}

.board-wrap {
  flex: 0 0 auto; width: min(100%, 380px); height: min(380px, calc(100vw - 24px));
  min-height: min(380px, calc(100vw - 24px)); align-items: center;
}
