/* Letter Rip theme, "Hot Pop" (design §8): flat colour, hard offset shadows,
   no gradients or glows. Fonts, palette, tiles, the path line, and the effect
   layer's banners, score pops and flashes (client/src/fx/effects.js). Link it
   after style.css and add class="arcade" to <body> for the background.

   Tile markup:
     <div class="tile x2"><span class="tile-letter">A</span><span class="tile-value">1</span></div>
   States are classes on .tile: selected, valid, invalid, hint, popping; kinds:
   x2, x3, wild, qu. Tiles size themselves from --tile-size (px; set it
   on the board or the tile). The theme only uses the `scale` and `translate`
   properties on .tile, so the UI can position tiles with `transform`. */

@font-face {
  font-family: 'Dela Gothic One';
  src: url('../../fonts/dela-gothic-one.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: block;
}
@font-face {
  font-family: 'Rubik';
  src: url('../../fonts/rubik-700.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: block;
}
@font-face {
  font-family: 'Rubik';
  src: url('../../fonts/rubik-800.woff2') format('woff2');
  font-weight: 800;
  font-style: normal;
  font-display: block;
}

:root {
  --wb-font-display: 'Dela Gothic One', 'Arial Black', system-ui, sans-serif;
  --wb-font-ui: 'Rubik', system-ui, sans-serif;

  --wb-bg: #1c1442;
  --wb-panel: #261c57;
  --wb-panel-edge: #3a2f78;
  --wb-slot: #150f36;
  --wb-shadow: #0e0a24;     /* hard shadows and outlines */
  --wb-ink: #ffffff;
  --wb-ink-soft: #b9b2e0;

  --wb-magenta: #ff3d7f;    /* hot pink */
  --wb-gold: #ffd23f;       /* yellow */
  --wb-cyan: #3ddcff;
  --wb-green: #3df59a;      /* "valid" */
  --wb-violet: #7b5cff;
  --wb-blue: #1f5fd1;
  --wb-orange: #ff8a3d;
  --wb-red: #ff4d5e;

  --wb-tile-face: #ffffff;
  --wb-tile-edge: #bdb4e8;
  --wb-tile-ink: #1c1442;
  --wb-tile-depth: 4px;
  --tile-size: 48px;
}

/* ---- background ---------------------------------------------------------- */

body.arcade {
  background: var(--wb-bg);
  color: var(--wb-ink);
  font-family: var(--wb-font-ui);
}

/* ---- type helpers -------------------------------------------------------- */

.wb-display { font-family: var(--wb-font-display); letter-spacing: 0.01em; }
.wb-ui, .hud-num { font-family: var(--wb-font-ui); font-weight: 800; font-variant-numeric: tabular-nums; letter-spacing: 0; }
.hud-num { color: #fff; }
.hud-label { font-family: var(--wb-font-ui); font-weight: 700; font-size: 11px; letter-spacing: 0.14em; color: var(--wb-ink-soft); text-transform: uppercase; }
.pop-text { color: #fff; text-shadow: 0.06em 0.06em 0 var(--pop-shadow, var(--wb-magenta)); }

/* The panel behind the board. */
.board-well {
  padding: 8px;
  border-radius: 18px;
  background: var(--wb-panel);
}

/* ---- tiles --------------------------------------------------------------- */

.tile {
  position: relative;
  width: var(--tile-size);
  height: var(--tile-size);
  border-radius: calc(var(--tile-size) * 0.2);
  display: grid;
  place-items: center;
  color: var(--wb-tile-ink);
  background: var(--wb-tile-face);
  box-shadow: 0 var(--wb-tile-depth) 0 var(--wb-tile-edge);
  font-family: var(--wb-font-ui);
  font-weight: 800;
  user-select: none;
  -webkit-user-select: none;
  transition: scale 90ms ease-out, box-shadow 90ms ease-out, background-color 90ms;
}
.tile-letter {
  font-size: calc(var(--tile-size) * 0.56);
  line-height: 1;
}
.tile-value {
  position: absolute;
  right: calc(var(--tile-size) * 0.1);
  bottom: calc(var(--tile-size) * 0.06);
  font-family: var(--wb-font-ui);
  font-weight: 700;
  font-size: max(7px, calc(var(--tile-size) * 0.19));
  line-height: 1;
  opacity: 0.55;
}

/* ×2 / ×3 badge in the top-right corner (no extra markup needed). */
.tile.x2::before, .tile.x3::before {
  position: absolute;
  top: calc(var(--tile-size) * -0.14);
  right: calc(var(--tile-size) * -0.14);
  padding: calc(var(--tile-size) * 0.05) calc(var(--tile-size) * 0.08);
  border-radius: calc(var(--tile-size) * 0.12);
  font-family: var(--wb-font-ui);
  font-weight: 800;
  font-size: max(8px, calc(var(--tile-size) * 0.22));
  line-height: 1;
  background: var(--wb-shadow);
  z-index: 1;
}

.tile.x2 { --wb-tile-face: var(--wb-cyan); --wb-tile-edge: #1d9ac2; --wb-tile-ink: #1c1442; }
.tile.x2::before { content: '×2'; color: var(--wb-cyan); }

.tile.x3 { --wb-tile-face: var(--wb-magenta); --wb-tile-edge: #c0245a; --wb-tile-ink: #fff; }
.tile.x3::before { content: '×3'; color: var(--wb-magenta); }

/* Wild: flat colour wedges that slowly turn. Render the letter as ★. */
@property --wb-spin { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
.tile.wild {
  --wb-tile-edge: #4b2fb0;
  --wb-tile-ink: #fff;
  background: conic-gradient(from var(--wb-spin),
    var(--wb-magenta) 0 60deg, var(--wb-gold) 0 120deg, var(--wb-green) 0 180deg,
    var(--wb-cyan) 0 240deg, var(--wb-violet) 0 300deg, var(--wb-orange) 0 360deg);
  animation: wb-spin 6s linear infinite;
}
.tile.wild .tile-letter { font-size: calc(var(--tile-size) * 0.62); -webkit-text-stroke: calc(var(--tile-size) * 0.06) var(--wb-shadow); paint-order: stroke fill; }
.tile.wild .tile-value { display: none; }
@keyframes wb-spin { to { --wb-spin: 360deg; } }

/* Qu: two letters on one tile. */
.tile.qu .tile-letter { font-size: calc(var(--tile-size) * 0.46); letter-spacing: -0.02em; }

/* Selected: lifted and yellow. */
.tile.selected {
  scale: 1.08;
  --wb-tile-face: var(--wb-gold);
  --wb-tile-edge: #c99400;
  --wb-tile-ink: #1c1442;
  z-index: 2;
}
/* Valid: the selected path spells a word. */
.tile.valid {
  scale: 1.1;
  --wb-tile-face: var(--wb-green);
  --wb-tile-edge: #17a866;
  --wb-tile-ink: #0b2e1e;
  z-index: 2;
}
/* Bonus kinds keep their face when selected; a ring shows the state. */
.tile.selected.x2 { --wb-tile-face: var(--wb-cyan); --wb-tile-edge: #1d9ac2; }
.tile.selected.x3 { --wb-tile-face: var(--wb-magenta); --wb-tile-edge: #c0245a; --wb-tile-ink: #fff; }
.tile.selected.wild { --wb-tile-ink: #fff; }
.tile.selected:is(.x2, .x3, .wild) { box-shadow: 0 0 0 3px var(--wb-gold), 0 var(--wb-tile-depth) 0 3px var(--wb-gold); }
.tile.valid.x2 { --wb-tile-face: var(--wb-cyan); --wb-tile-edge: #1d9ac2; --wb-tile-ink: #1c1442; }
.tile.valid.x3 { --wb-tile-face: var(--wb-magenta); --wb-tile-edge: #c0245a; --wb-tile-ink: #fff; }
.tile.valid.wild { --wb-tile-ink: #fff; }
.tile.valid:is(.x2, .x3, .wild) { box-shadow: 0 0 0 3px var(--wb-green), 0 var(--wb-tile-depth) 0 3px var(--wb-green); }

/* Let go on a non-word: red ring and a quick shake. */
.tile.invalid {
  box-shadow: 0 0 0 3px var(--wb-red), 0 var(--wb-tile-depth) 0 3px var(--wb-red);
  animation: wb-tile-shake 320ms ease-out;
}
@keyframes wb-tile-shake {
  0%, 100% { translate: 0 0; }
  20% { translate: -5px 0; }
  40% { translate: 5px 0; }
  60% { translate: -3px 0; }
  80% { translate: 2px 0; }
}

/* Endless hint: a slow pulsing ring. */
.tile.hint { animation: wb-hint 1.1s ease-in-out infinite; }
@keyframes wb-hint {
  0%, 100% { box-shadow: 0 var(--wb-tile-depth) 0 var(--wb-tile-edge), 0 0 0 0 var(--wb-gold); }
  50% { box-shadow: 0 var(--wb-tile-depth) 0 var(--wb-tile-edge), 0 0 0 4px var(--wb-gold); }
}

/* A cleared tile's last moment before it bursts (fx.burst on the canvas does the rest). */
.tile.popping { animation: wb-pop 170ms ease-in forwards; pointer-events: none; }
@keyframes wb-pop {
  0% { scale: 1.1; }
  45% { scale: 1.28; }
  100% { scale: 0.2; opacity: 0; }
}

/* ---- the path line (SVG overlay) ----------------------------------------
   <svg class="path-svg"><polyline class="path-line" points="…"/></svg>;
   add .valid to the polyline when the path spells a word. It sits above the
   tiles, thin and translucent enough that the letters read through it. */
.path-svg { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; z-index: 3; }
.path-line {
  fill: none;
  stroke: var(--wb-magenta);
  stroke-width: calc(var(--tile-size) * 0.16);
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.6;
}
.path-line.valid { stroke: #12945a; }

/* ---- effects layer (effects.js) ------------------------------------------ */

.fx-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 50;
  container-type: size;
}
.fx-canvas { position: absolute; inset: 0; width: 100%; height: 100%; }

/* Stacking inside the layer: canvas, flash, score pops, banner on top. */
.fx-flash { position: absolute; inset: 0; z-index: 1; opacity: 0; animation: fx-flash 380ms ease-out forwards; }
.fx-flash.soft { animation-name: fx-flash-soft; animation-duration: 600ms; }
@keyframes fx-flash { 0% { opacity: calc(0.7 * var(--strength, 1)); } 100% { opacity: 0; } }
@keyframes fx-flash-soft { 0% { opacity: calc(0.18 * var(--strength, 1)); } 100% { opacity: 0; } }

/* Score pop: "+450" with an ink outline and a hard drop, rising and fading. */
.fx-scorepop {
  position: absolute;
  z-index: 2;
  translate: -50% -50%;
  font-family: var(--wb-font-ui);
  font-weight: 800;
  font-size: calc(18px + var(--lv, 1) * 3px);
  line-height: 1;
  color: var(--pop-ink, #fff);
  white-space: nowrap;
  -webkit-text-stroke: 0.16em var(--wb-shadow);
  paint-order: stroke fill;
  text-shadow: 0.08em 0.1em 0 var(--wb-shadow);
  animation: fx-pop 1100ms cubic-bezier(0.2, 0.9, 0.3, 1) forwards;
}
.fx-scorepop.lv-0 { --lv: 0; }
.fx-scorepop.lv-1 { --lv: 1; }
.fx-scorepop.lv-2 { --lv: 2; --pop-ink: var(--wb-cyan); }
.fx-scorepop.lv-3 { --lv: 3; --pop-ink: var(--wb-gold); }
.fx-scorepop.lv-4 { --lv: 4; --pop-ink: var(--wb-magenta); animation-duration: 1300ms; }
.fx-scorepop.lv-5 { --lv: 5.5; --pop-ink: var(--wb-gold); animation-duration: 1600ms; }
@keyframes fx-pop {
  0% { scale: 0.3; opacity: 0; transform: translateY(0); }
  18% { scale: 1.35; opacity: 1; }
  32% { scale: 1; transform: translateY(-14px); }
  75% { opacity: 1; }
  100% { opacity: 0; transform: translateY(-64px); }
}

/* Banners: GOOD … LEGENDARY!!!. effects.js stacks two copies of the text in
   .fx-banner-word; the flat style only needs the front one: a solid fill, an
   ink outline, and hard offset shadows that stack up with the level. */
.fx-banner {
  position: absolute;
  z-index: 3;
  left: 0;
  right: 0;
  top: 36%;
  display: grid;
  justify-items: center;
  translate: 0 -50%;
  animation: fx-banner var(--dur, 1000ms) cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
}
.fx-banner-word {
  display: grid;
  font-family: var(--wb-font-display);
  font-size: min(var(--size, 9cqw), var(--max, 52px));
  line-height: 1;
  white-space: nowrap;
  rotate: var(--tilt, -3deg);
}
.fx-banner-word > * { grid-area: 1 / 1; padding: 0.12em 0.22em 0.26em 0.12em; }
.fx-banner-back { visibility: hidden; }
.fx-banner-text {
  color: var(--fill, #fff);
  -webkit-text-stroke: 0.1em var(--wb-shadow);
  paint-order: stroke fill;
  text-shadow: var(--drop, 0.07em 0.07em 0 var(--wb-violet));
}
.fx-banner-sub {
  margin-top: 0.5em;
  font-family: var(--wb-font-ui);
  font-weight: 800;
  font-size: min(4.4cqw, 18px);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #fff;
  -webkit-text-stroke: 0.2em var(--wb-shadow);
  paint-order: stroke fill;
}
@keyframes fx-banner {
  0% { scale: 2.6; opacity: 0; }
  14% { scale: 0.88; opacity: 1; }
  24% { scale: 1.06; }
  34% { scale: 1; }
  80% { scale: 1; opacity: 1; transform: translateY(0); }
  100% { scale: 1.1; opacity: 0; transform: translateY(-40%); }
}

.fx-banner.lv-0, .fx-banner.lv-1 { --dur: 900ms; --size: 7.5cqw; --max: 36px; --tilt: -2deg; }
.fx-banner.lv-1 { --dur: 1000ms; --size: 8cqw; --max: 40px; }
.fx-banner.lv-2 {
  --dur: 1150ms; --size: 9.5cqw; --max: 46px; --tilt: 2deg;
  --fill: var(--wb-cyan); --drop: 0.07em 0.07em 0 var(--wb-blue);
}
.fx-banner.lv-3 {
  --dur: 1450ms; --size: 10.5cqw; --max: 54px;
  --fill: var(--wb-gold); --drop: 0.07em 0.07em 0 var(--wb-magenta);
  --plate: var(--wb-violet); --plate-drop: var(--wb-magenta);
}
.fx-banner.lv-4 {
  --dur: 1700ms; --size: 9.5cqw; --max: 58px;
  --fill: #fff; --drop: 0.07em 0.07em 0 var(--wb-gold);
  --plate: var(--wb-magenta); --plate-drop: var(--wb-gold);
}
/* Full-width flat ribbon behind levels 3+, with its own hard drop. */
.fx-banner.lv-3::before, .fx-banner.lv-4::before, .fx-banner.lv-5::before {
  content: '';
  position: absolute;
  left: -5%;
  right: -5%;
  top: 50%;
  height: calc(100% + 10px);
  min-height: 56px;
  translate: 0 -50%;
  rotate: -4deg;
  z-index: -1;
  background: var(--plate);
  box-shadow: 0 10px 0 var(--plate-drop);
  animation: fx-ribbon var(--dur) cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
}
@keyframes fx-ribbon {
  0% { scale: 0 1; }
  12% { scale: 1.02 1; }
  82% { scale: 1 1; opacity: 1; }
  100% { scale: 1 0; opacity: 0; }
}

/* Level 5: LEGENDARY!!! Flat sun rays turning behind an ink ribbon, letters
   dropping in one by one in slow motion, each its own colour with stacked
   pink and cyan drops, then a long hold. */
.fx-banner.lv-5 {
  --dur: 2600ms; --size: 10cqw; --max: 62px;
  --plate: var(--wb-shadow); --plate-drop: var(--wb-magenta);
  top: 40%;
  animation: fx-banner-5 var(--dur) linear forwards;
}
.fx-banner.lv-5::after { /* sun rays */
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 150cqw;
  height: 150cqw;
  translate: -50% -50%;
  z-index: -2;
  border-radius: 50%;
  background: repeating-conic-gradient(from 0deg, rgba(255, 210, 63, 0.3) 0deg 9deg, transparent 9deg 22.5deg);
  -webkit-mask-image: radial-gradient(closest-side, #000 40%, transparent 100%);
  mask-image: radial-gradient(closest-side, #000 40%, transparent 100%);
  animation: fx-rays var(--dur) linear forwards;
}
.fx-banner.lv-5 .fx-banner-text { text-shadow: none; -webkit-text-stroke: 0; }
/* The letters are spans, each its own colour, dropping in one after another. */
.fx-banner.lv-5 .fx-banner-text span {
  --c: var(--wb-gold);
  display: inline-block;
  color: var(--c);
  -webkit-text-stroke: 0.1em var(--wb-shadow);
  paint-order: stroke fill;
  text-shadow: 0.06em 0.06em 0 var(--wb-magenta), 0.12em 0.12em 0 var(--wb-cyan);
  animation: fx-letter 700ms cubic-bezier(0.25, 1.6, 0.4, 1) both;
  animation-delay: calc(var(--i) * 45ms);
}
.fx-banner.lv-5 .fx-banner-text span:nth-child(3n + 2) { --c: #fff; }
.fx-banner.lv-5 .fx-banner-text span:nth-child(3n) { --c: var(--wb-cyan); }
@keyframes fx-banner-5 {
  0% { scale: 3.2; opacity: 0; }
  8% { scale: 1.3; opacity: 1; }
  /* slow-mo: drifts down toward size over a long stretch */
  28% { scale: 1.12; }
  32% { scale: 0.94; }
  36% { scale: 1.04; }
  40% { scale: 1; }
  86% { scale: 1.03; opacity: 1; transform: translateY(0); }
  100% { scale: 1.25; opacity: 0; transform: translateY(-30%); }
}
@keyframes fx-letter {
  0% { transform: translateY(-1.2em) scale(1.8); opacity: 0; }
  60% { opacity: 1; }
  100% { transform: none; opacity: 1; }
}
@keyframes fx-rays {
  0% { rotate: 0deg; opacity: 0; scale: 0.4; }
  15% { opacity: 1; scale: 1; }
  85% { opacity: 1; }
  100% { rotate: 70deg; opacity: 0; scale: 1.1; }
}

@media (prefers-reduced-motion: reduce) {
  .fx-banner, .fx-banner.lv-5 { animation-name: fx-banner-calm; }
  .fx-banner.lv-5::after, .fx-banner.lv-5 .fx-banner-text span { animation: none; }
  .fx-banner.lv-5::after { opacity: 0.6; }
  .tile.wild { animation: none; }
  .tile.invalid { animation: none; }
  @keyframes fx-banner-calm {
    0% { opacity: 0; scale: 0.92; }
    12% { opacity: 1; scale: 1; }
    85% { opacity: 1; }
    100% { opacity: 0; }
  }
}
