/* Wordfall board. Loaded after assets/css/game-base.css.

   Geometry is one number: --cw, the width of a tile in pixels, written onto
   #stage by ui.js after it measures the card. Everything else — the stage box,
   each tile's position, the type size — is derived from it, so one assignment
   resizes the whole board and the layout never disagrees with itself.

   Tiles are absolutely positioned rather than laid out in a CSS grid, because
   position is what has to animate: a new letter starts one row above the board
   and transitions down, and after a word clears the survivors transition into
   the gap. A grid would snap.

   Every colour here is a token from game-base.css, so both themes track. */

  /* ---------------- how full the board is ---------------- */
  .wf-fill{
    height:4px; border-radius:99px; background:var(--surface-2);
    border:1px solid var(--border); overflow:hidden; margin:-6px 0 16px;
  }
  .wf-fill-bar{
    height:100%; width:0%; border-radius:99px;
    background:linear-gradient(90deg,var(--c1),var(--c2));
    transition:width .35s ease, background .35s ease;
  }
  .wf-fill-bar.warn{background:linear-gradient(90deg,var(--c2),var(--c3))}
  .wf-fill-bar.danger{background:var(--c3)}

  /* ---------------- the stage ---------------- */
  .wf-wrap{position:relative; display:flex; justify-content:center}

  .wf-stage{
    --cw:46px; --gap:6px; --cols:7; --rows:9;
    position:relative;
    width:calc(var(--cols) * var(--cw) + (var(--cols) - 1) * var(--gap));
    height:calc(var(--rows) * var(--cw) + (var(--rows) - 1) * var(--gap));
    margin:0 auto;
    touch-action:none;                 /* a drag across tiles must not scroll the page */
    user-select:none; -webkit-user-select:none;
  }

  /* One inert div per cell, drawn once, showing the empty grid behind the
     tiles. Cheap at 63 nodes, and guaranteed to line up with the tiles because
     it is positioned by exactly the same expression. */
  .wf-hole{
    position:absolute; pointer-events:none;
    width:var(--cw); height:var(--cw);
    left:calc(var(--c) * (var(--cw) + var(--gap)));
    top:calc(var(--r) * (var(--cw) + var(--gap)));
    border-radius:calc(var(--cw) * 0.24);
    background:var(--surface-2); opacity:.55;
    box-shadow:inset 0 0 0 1px var(--border);
  }

  /* In the light theme the card is pure white and --surface-2 is only a shade
     off it, so the relationship has to invert: the empty grid becomes the grey
     one and the tiles sit on top of it in white. */
  html[data-theme="light"] .wf-hole{opacity:1}
  /* :not() keeps this off the selected and clearing states, which paint their
     own background — without it this rule would out-specify them */
  html[data-theme="light"] .wf:not(.pick):not(.gone){
    background:var(--surface); box-shadow:0 1px 2px var(--border);
  }

  /* the top two rows are the danger zone — a quiet warning, not a klaxon */
  .wf-stage::after{
    content:''; position:absolute; left:0; right:0; top:0; pointer-events:none;
    height:calc(2 * var(--cw) + var(--gap));
    border-radius:12px 12px 4px 4px;
    background:var(--c3); opacity:0; transition:opacity .4s ease;
  }
  .wf-stage.tight::after{opacity:.09}
  .wf-stage.critical::after{opacity:.18}

  /* ---------------- a tile ---------------- */
  .wf{
    position:absolute; margin:0; padding:0;
    width:var(--cw); height:var(--cw);
    left:calc(var(--c) * (var(--cw) + var(--gap)));
    top:calc(var(--r) * (var(--cw) + var(--gap)));
    border:1px solid var(--border); border-radius:calc(var(--cw) * 0.24);
    background:var(--surface-2); color:var(--text);
    font-weight:700; letter-spacing:.01em;
    font-size:calc(var(--cw) * 0.46); line-height:1;
    display:grid; place-items:center;
    -webkit-tap-highlight-color:transparent; touch-action:none;
    box-shadow:0 1px 0 var(--border);
    transition:top .19s cubic-bezier(.3,.85,.4,1), left .19s cubic-bezier(.3,.85,.4,1),
               background .14s ease, border-color .14s ease, color .14s ease,
               transform .14s ease, opacity .18s ease;
  }
  .wf-stage.instant .wf{transition:background .14s ease, border-color .14s ease, color .14s ease}

  .wf .ch{pointer-events:none; display:block}

  /* A spawning tile starts one row above the board and fades in as it falls,
     so the moment it spends outside the stage box is invisible. */
  .wf.spawn{opacity:0}

  /* the letter's Scrabble value, tucked into the corner */
  .wf .pip{
    position:absolute; right:calc(var(--cw) * 0.11); bottom:calc(var(--cw) * 0.06);
    font-size:calc(var(--cw) * 0.22); font-weight:600; color:var(--muted);
    line-height:1; pointer-events:none;
  }
  .wf.rare .pip{color:var(--c3)}
  .wf.rare{border-color:var(--c3)}

  .wf:hover{border-color:var(--accent)}
  .wf:focus{outline:none}
  .wf:focus-visible{
    outline:2px solid var(--accent); outline-offset:2px; border-color:var(--accent);
  }

  /* ---------------- selection ---------------- */
  .wf.pick{
    background:var(--accent); border-color:var(--accent); color:#fff;
    transform:scale(1.04); z-index:3;
  }
  .wf.pick .pip{color:#fff; opacity:.75}
  /* the tile the trace is currently on — scale rather than a ring, because a
     ring would have to be a different colour in each of the three pick states */
  .wf.pick.head{transform:scale(1.13); z-index:5}
  .wf-stage.good .wf.pick{background:var(--ok); border-color:var(--ok)}
  .wf-stage.dead .wf.pick{background:var(--c3); border-color:var(--c3)}

  /* a hinted word flashes without being selected for you */
  .wf.hinted{animation:wf-hint 1.4s ease}
  @keyframes wf-hint{
    0%,100%{background:var(--surface-2); border-color:var(--border)}
    18%,62%{background:var(--accent-soft); border-color:var(--accent); color:var(--accent)}
  }

  /* a landing tile lands, a cleared tile leaves */
  .wf.drop{animation:wf-land .22s ease}
  @keyframes wf-land{from{transform:scale(.86)}to{transform:none}}
  .wf.gone{
    background:var(--ok); border-color:var(--ok); color:#fff;
    transform:scale(.35); opacity:0; z-index:4; pointer-events:none;
  }

  .wf-stage.frozen .wf{pointer-events:none}

  /* ---------------- pause veil ---------------- */
  .wf-veil{position:absolute; inset:0; display:grid; place-items:center; z-index:10; border-radius:12px}
  .wf-veil[hidden]{display:none}
  .wf-veil::before{
    content:''; position:absolute; inset:-8px; border-radius:14px;
    background:var(--surface); opacity:.9; backdrop-filter:blur(3px);
  }
  .wf-veil-inner{position:relative; text-align:center; padding:10px 18px}
  .wf-veil-title{margin:0 0 4px; font-size:17px; font-weight:660; letter-spacing:-.01em}
  .wf-veil-note{margin:0 0 14px; font-size:12.5px; color:var(--muted)}
  .wf-veil-inner .btn{flex:none; min-width:130px}

  /* ---------------- the word bar ---------------- */
  .wf-bar{
    margin-top:16px; padding:12px; border-radius:14px;
    background:var(--surface-2); border:1px solid var(--border);
    display:grid; gap:10px;
    grid-template-columns:minmax(0,1fr) auto;
    grid-template-areas:"chips actions" "status actions";
    align-items:center;
  }
  .wf-chips{grid-area:chips; display:flex; gap:4px; flex-wrap:wrap; min-height:26px; align-items:center}
  .wf-chip{
    min-width:24px; height:26px; padding:0 5px; border-radius:7px;
    background:var(--surface); border:1px solid var(--border);
    display:grid; place-items:center; font-size:14px; font-weight:700;
    animation:wf-pop .16s ease;
  }
  @keyframes wf-pop{from{transform:translateY(-4px); opacity:0}to{transform:none; opacity:1}}
  .wf-chips.good .wf-chip{border-color:var(--ok); color:var(--ok)}
  .wf-chips.dead .wf-chip{border-color:var(--c3); color:var(--c3)}
  .wf-hollow{
    color:var(--muted); font-size:12.5px; font-weight:500; letter-spacing:.02em;
  }
  .wf-status{grid-area:status; font-size:12.5px; color:var(--muted); min-height:18px}
  .wf-status.good{color:var(--ok); font-weight:600}
  .wf-status.dead{color:var(--c3)}
  .wf-bar-actions{grid-area:actions; display:flex; gap:6px}
  .wf-bar-actions .btn{flex:none; min-width:76px; padding:8px 10px}
  .wf-bar.shake{animation:wf-shake .3s ease}
  @keyframes wf-shake{
    0%,100%{transform:none} 25%{transform:translateX(-5px)}
    50%{transform:translateX(4px)} 75%{transform:translateX(-2px)}
  }

  /* ---------------- side panels ---------------- */
  .wf-found{display:flex; flex-wrap:wrap; gap:5px; max-height:190px; overflow-y:auto}
  .wf-word{
    display:inline-flex; align-items:baseline; gap:5px;
    padding:3px 8px; border-radius:8px; font-size:12px; font-weight:600;
    background:var(--surface-2); border:1px solid var(--border);
  }
  .wf-word b{font-weight:700; letter-spacing:.02em}
  .wf-word small{color:var(--muted); font-weight:600; font-variant-numeric:tabular-nums}
  .wf-word.big{border-color:var(--accent); color:var(--accent)}
  .wf-word.big small{color:var(--accent)}
  .wf-empty{margin:0; font-size:12.5px; color:var(--muted)}
  #foundCount{text-transform:none; letter-spacing:0}

  .wf-summary{margin:-8px 0 16px}
  .wf-summary .kv{padding:4px 0}

  .stat .v.small{font-size:15px; letter-spacing:.02em}
  .stat .sub{
    font-size:10.5px; color:var(--muted); font-weight:600; letter-spacing:.04em;
    margin-top:1px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  }
  #levelStat.up .v{color:var(--c3)}

  /* the legend under "How it works" */
  .wf-key{display:flex; align-items:center; gap:8px; width:100%}
  .wf-key .chip{
    width:22px; height:22px; border-radius:7px; display:grid; place-items:center;
    font-size:11px; font-weight:700; background:var(--surface-2);
    border:1px solid var(--border); color:var(--text); flex:none;
  }
  .wf-key .chip.pick{background:var(--accent); border-color:var(--accent); color:#fff}
  .wf-key .chip.good{background:var(--ok); border-color:var(--ok); color:#fff}
  .wf-key .chip.rare{border-color:var(--c3); color:var(--c3)}

  @media(max-width:480px){
    .wf-bar{grid-template-columns:minmax(0,1fr); grid-template-areas:"chips" "status" "actions"}
    .wf-bar-actions{width:100%}
    .wf-bar-actions .btn{flex:1}
    /* four stats will not sit in one row at this width; two by two beats
       three-then-one-stretched-across */
    .hud{display:grid; grid-template-columns:1fr 1fr}
    .hud .stat{min-width:0}
  }
