/* Slide: a walnut frame, painted wooden blocks and a gold key block. */

:root {
  --frame: #6b4a2e;
  --frame-edge: #4a3120;
  --tray: #eadcc2;
  --cell-line: rgba(90, 58, 24, 0.12);
  --block-edge: rgba(60, 36, 12, 0.28);
  --block-text: #3b2a18;
  --key-a: #ffd257;
  --key-b: #e08a00;
  --t0: #c7d9b7;
  --t1: #b9d3e3;
  --t2: #e6c3a5;
  --t3: #d8c7e6;
  --t4: #efd9a0;
  --t5: #c3e0d6;
  --t6: #e7bcbc;
  --home: #1f9d57;
  --hint: #e08a00;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --frame: #3a2818;
    --frame-edge: #22170d;
    --tray: #221e1a;
    --cell-line: rgba(255, 230, 200, 0.06);
    --block-edge: rgba(0, 0, 0, 0.45);
    --block-text: #f2ead9;
    --t0: #5d7550;
    --t1: #4d6c80;
    --t2: #86604a;
    --t3: #6c5a86;
    --t4: #8a7640;
    --t5: #4e7a6c;
    --t6: #8a5252;
    --home: #3fb77a;
  }
}
:root[data-theme='dark'] {
  --frame: #3a2818;
  --frame-edge: #22170d;
  --tray: #221e1a;
  --cell-line: rgba(255, 230, 200, 0.06);
  --block-edge: rgba(0, 0, 0, 0.45);
  --block-text: #f2ead9;
  --t0: #5d7550;
  --t1: #4d6c80;
  --t2: #86604a;
  --t3: #6c5a86;
  --t4: #8a7640;
  --t5: #4e7a6c;
  --t6: #8a5252;
  --home: #3fb77a;
}
/* Hallows: carved stone in a castle wall, and a glowing pumpkin-gold key. */
:root[data-theme='hallows'] {
  --frame: #1c1330;
  --frame-edge: #0d0818;
  --tray: #2a2140;
  --cell-line: rgba(232, 176, 74, 0.08);
  --block-edge: rgba(0, 0, 0, 0.5);
  --block-text: #f4e8cc;
  --key-a: #ffc27a;
  --key-b: #d8650a;
  --t0: #4a4260;
  --t1: #3e4a66;
  --t2: #5a4658;
  --t3: #544070;
  --t4: #5e5240;
  --t5: #3f5552;
  --t6: #633e4c;
  --home: #e8b04a;
  --hint: #ffc27a;
}
:root[data-theme='hallows'] .hw-candle {
  display: none;
}
:root[data-theme='hallows'] .title-main {
  font-family: var(--font-display);
  letter-spacing: 0;
}

body {
  min-height: var(--app-height);
  padding: var(--safe-top) var(--safe-right) var(--safe-bottom) var(--safe-left);
}
#announce {
  margin: 0;
  top: 0;
}
.app {
  display: flex;
  flex-direction: column;
  height: calc(var(--app-height) - var(--safe-top) - var(--safe-bottom));
  min-height: 460px;
  max-width: 640px;
  margin: 0 auto;
}

/* ---------- Top bar ---------- */

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px 6px;
}
.title-btn {
  appearance: none;
  border: 0;
  background: none;
  text-align: left;
  cursor: pointer;
  padding: 4px 6px;
  border-radius: 12px;
  color: var(--text);
  min-width: 0;
}
.title-btn:hover {
  background: var(--accent-soft);
}
.title-btn:focus-visible {
  outline: 3px solid var(--accent);
}
.title-main {
  display: block;
  font-size: 1.35rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.1;
}
.title-main::after {
  content: ' ▾';
  font-size: 0.7em;
  color: var(--text-muted);
}
.title-sub {
  display: block;
  color: var(--text-muted);
  font-weight: 600;
  font-size: 0.8rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.score {
  display: flex;
  gap: 8px;
}
.chip {
  min-width: 64px;
  text-align: center;
  padding: 6px 12px;
  border-radius: 14px;
  background: var(--surface);
  border: 1px solid var(--border);
}
.chip small {
  display: block;
  font-size: 0.66rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
}
.chip b {
  display: block;
  font-size: 1.3rem;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.chip.bump b {
  animation: bump 0.25s ease;
}
.chip.over b {
  color: var(--danger);
}
@keyframes bump {
  40% {
    transform: scale(1.25);
  }
}
.challenge {
  margin: 2px auto 0;
  padding: 6px 14px;
  border-radius: 999px;
  background: var(--surface);
  border: 1px solid var(--border);
  font-weight: 700;
  font-size: 0.85rem;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  align-self: center;
}
.challenge[hidden] {
  display: none;
}
.status {
  margin: 2px 16px 0;
  min-height: 2.6em;
  font-size: 0.9rem;
  color: var(--text-muted);
  text-align: center;
  display: flex;
  align-items: center;
  justify-content: center;
  text-wrap: balance;
}

/* ---------- Stage ---------- */

.stage {
  flex: 1 1 0;
  position: relative;
  display: grid;
  place-items: center;
  padding: 4px 14px;
  min-height: 240px;
  container-type: size;
}
.board-host {
  display: contents;
}
.ub-wrap {
  width: min(100cqw, 100cqh, 560px);
  aspect-ratio: 1;
}
.mixing {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 10px;
  font-weight: 700;
  color: var(--text-muted);
}
.mixing[hidden] {
  display: none;
}
.mixing-dots {
  display: flex;
  gap: 6px;
}
.mixing-dots i {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--accent);
  animation: dot 0.9s ease-in-out infinite;
}
.mixing-dots i:nth-child(2) {
  animation-delay: 0.15s;
}
.mixing-dots i:nth-child(3) {
  animation-delay: 0.3s;
}
@keyframes dot {
  50% {
    transform: translateY(-10px);
    opacity: 0.5;
  }
}

/* ---------- Frame and tray ---------- */

.ub-frame {
  --pad: clamp(10px, 3.2cqmin, 18px);
  width: 100%;
  height: 100%;
  padding: var(--pad);
  border-radius: 22px;
  background: linear-gradient(145deg, color-mix(in srgb, var(--frame) 88%, #fff), var(--frame) 40%, var(--frame-edge));
  box-shadow: 0 18px 36px -16px rgba(30, 15, 0, 0.55), inset 0 2px 0 rgba(255, 255, 255, 0.12);
}
.ub-board,
.tiles-board {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 12px;
  background: var(--tray);
  box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.25);
}
.ub-board {
  display: grid;
  grid-template-columns: repeat(var(--n), 1fr);
  grid-template-rows: repeat(var(--n), 1fr);
}
.ub-cell {
  border-right: 1px solid var(--cell-line);
  border-bottom: 1px solid var(--cell-line);
}
/* The gap in the frame where the key block leaves. */
.ub-exit {
  position: absolute;
  right: 0;
  width: var(--pad);
  top: calc(var(--pad) + var(--row) * (100% - 2 * var(--pad)) / 6);
  height: calc((100% - 2 * var(--pad)) / 6);
  background: var(--tray);
  box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.25);
}
.ub-exit::after {
  content: '';
  position: absolute;
  inset: 32% 22% 32% 18%;
  background: var(--key-b);
  clip-path: polygon(0 0, 100% 50%, 0 100%);
  opacity: 0.75;
}
.ub-frame {
  position: relative;
}

/* ---------- Blocks ---------- */

.ub-block,
.ub-dot,
.ub-ghost,
.tile {
  --cell: calc(100% / var(--n));
  position: absolute;
  left: calc(var(--x) * 100% / var(--n) + 3px);
  top: calc(var(--y) * 100% / var(--n) + 3px);
  width: calc(var(--w, 1) * 100% / var(--n) - 6px);
  height: calc(var(--h, 1) * 100% / var(--n) - 6px);
  border-radius: 12px;
}
.ub-block {
  appearance: none;
  border: 0;
  padding: 0;
  cursor: grab;
  background: linear-gradient(160deg, color-mix(in srgb, var(--tone) 70%, #fff), var(--tone) 45%, color-mix(in srgb, var(--tone) 80%, #000));
  box-shadow: inset 0 -4px 0 var(--block-edge), inset 0 2px 0 rgba(255, 255, 255, 0.35), 0 4px 8px -3px rgba(0, 0, 0, 0.4);
  transition: left 0.2s cubic-bezier(0.3, 0.9, 0.4, 1), top 0.2s cubic-bezier(0.3, 0.9, 0.4, 1), transform 0.2s ease, box-shadow 0.15s ease;
  touch-action: none;
  z-index: 1;
}
/* Wood grain along the block. */
.ub-block::before {
  content: '';
  position: absolute;
  inset: 18%;
  border-radius: 8px;
  opacity: 0.18;
  background: repeating-linear-gradient(var(--grain, 90deg), transparent 0 7px, var(--block-edge) 7px 8px);
}
.ub-block.vert {
  --grain: 0deg;
}
.ub-block.dragging {
  transition: none;
  cursor: grabbing;
  z-index: 3;
  box-shadow: inset 0 -4px 0 var(--block-edge), 0 12px 20px -6px rgba(0, 0, 0, 0.5);
}
.ub-block.selected {
  z-index: 2;
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}
.ub-block:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}
.ub-block.hinted {
  animation: hinted 1.1s ease-in-out infinite;
}
@keyframes hinted {
  50% {
    box-shadow: 0 0 0 5px var(--hint), 0 0 18px var(--hint);
  }
}
.tone-0 { --tone: var(--t0); }
.tone-1 { --tone: var(--t1); }
.tone-2 { --tone: var(--t2); }
.tone-3 { --tone: var(--t3); }
.tone-4 { --tone: var(--t4); }
.tone-5 { --tone: var(--t5); }
.tone-6 { --tone: var(--t6); }
.ub-block.key {
  background: linear-gradient(160deg, #fff3c4, var(--key-a) 30%, var(--key-b));
  box-shadow: inset 0 -4px 0 rgba(120, 60, 0, 0.35), inset 0 2px 0 rgba(255, 255, 255, 0.6), 0 6px 14px -4px color-mix(in srgb, var(--key-b) 80%, transparent);
}
.ub-block.key::before {
  display: none;
}
.key-mark {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 26%;
  aspect-ratio: 1;
  translate: -50% -50%;
  border-radius: 50%;
  border: 3px solid rgba(110, 55, 0, 0.55);
}
.key-mark::after {
  content: '';
  position: absolute;
  left: 100%;
  top: 50%;
  width: 90%;
  height: 3px;
  translate: 0 -50%;
  background: rgba(110, 55, 0, 0.55);
}
.ub-block.key.exiting {
  transition: transform 0.6s cubic-bezier(0.5, 0, 0.9, 0.6), opacity 0.6s ease;
  transform: translateX(160%);
  opacity: 0;
}
.ub-dot {
  appearance: none;
  border: 0;
  background: transparent;
  cursor: pointer;
  z-index: 2;
  padding: 0;
}
.ub-dot::after {
  content: '';
  position: absolute;
  inset: 34%;
  border-radius: 50%;
  background: var(--accent);
  opacity: 0.55;
  animation: pop 0.2s ease;
}
@keyframes pop {
  from {
    transform: scale(0.3);
  }
}
.ub-dot:focus-visible {
  outline: 3px solid var(--accent);
}
.ub-ghost {
  border: 3px dashed var(--hint);
  background: color-mix(in srgb, var(--hint) 18%, transparent);
  pointer-events: none;
}
.ub-ghost[hidden] {
  display: none;
}

/* ---------- Tiles ---------- */

.tiles-board {
  container-type: size;
}
.tile {
  appearance: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  font: inherit;
  font-weight: 800;
  font-size: calc(46cqmin / var(--n));
  font-variant-numeric: tabular-nums;
  color: var(--block-text);
  background: linear-gradient(160deg, color-mix(in srgb, var(--tone) 70%, #fff), var(--tone) 45%, color-mix(in srgb, var(--tone) 85%, #000));
  box-shadow: inset 0 -4px 0 var(--block-edge), inset 0 2px 0 rgba(255, 255, 255, 0.35), 0 4px 8px -3px rgba(0, 0, 0, 0.4);
  transition: left 0.14s ease-out, top 0.14s ease-out, box-shadow 0.2s ease;
  touch-action: manipulation;
}
.tile:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}
.show-home .tile.home {
  box-shadow: inset 0 -4px 0 var(--block-edge), inset 0 0 0 3px color-mix(in srgb, var(--home) 75%, transparent), 0 4px 8px -3px rgba(0, 0, 0, 0.4);
}
.tile.hinted {
  animation: hinted 1.1s ease-in-out infinite;
  z-index: 2;
}
.tile.nope {
  animation: nope 0.25s ease;
}
@keyframes nope {
  25% {
    translate: -3px 0;
  }
  75% {
    translate: 3px 0;
  }
}
.tile.wave {
  animation: wave 0.5s ease var(--delay) both;
}
@keyframes wave {
  40% {
    transform: translateY(-10%) scale(1.06);
    box-shadow: 0 0 0 4px var(--home), 0 10px 18px -6px rgba(0, 0, 0, 0.4);
  }
}

@media (prefers-reduced-motion: reduce) {
  .ub-block,
  .tile {
    transition: none;
  }
  .ub-block.hinted,
  .tile.hinted {
    animation: none;
    box-shadow: 0 0 0 5px var(--hint);
  }
}

/* ---------- Toolbar ---------- */

.toolbar {
  display: flex;
  justify-content: center;
  gap: 6px;
  padding: 8px 8px 12px;
}
.tool {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--text);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  min-width: 64px;
  min-height: 52px;
  padding: 6px 8px;
  border-radius: 14px;
  font-size: 0.76rem;
  font-weight: 600;
  cursor: pointer;
}
.tool svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.tool:hover:not(:disabled) {
  background: var(--accent-soft);
}
.tool:disabled {
  opacity: 0.38;
  cursor: default;
}
.tool:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 1px;
}

/* ---------- Menus ---------- */

.menu-list {
  display: grid;
  gap: 10px;
}
.menu-card {
  appearance: none;
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  text-align: left;
  padding: 14px;
  border-radius: 16px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text);
  cursor: pointer;
  transition: transform 0.12s ease;
}
.menu-card:active {
  transform: scale(0.98);
}
.menu-card:focus-visible {
  outline: 3px solid var(--accent);
}
.menu-card .menu-icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: 12px;
  background: var(--accent-soft);
  color: var(--accent);
}
.menu-card b {
  display: block;
  font-size: 1.05rem;
}
.menu-card small {
  color: var(--text-muted);
}
.menu-row {
  display: flex;
  gap: 8px;
  margin-top: 10px;
}
.menu-row .btn {
  flex: 1;
  padding-inline: 0.8em;
  white-space: nowrap;
}
.level-picker {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-top: 6px;
}
.level-picker input {
  flex: 1;
  min-width: 0;
  font: inherit;
  font-size: 1.1rem;
  padding: 10px 12px;
  border-radius: 12px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
}
.help ul {
  padding-left: 1.2em;
}

/* Landscape phones: controls beside the board. */
@media (orientation: landscape) and (max-height: 560px) {
  .app {
    max-width: none;
    display: grid;
    grid-template-columns: minmax(220px, 1fr) auto;
    grid-template-rows: min-content min-content 1fr min-content;
    column-gap: 16px;
    min-height: 0;
  }
  .topbar,
  .challenge,
  .status,
  .toolbar {
    grid-column: 1;
  }
  .toolbar {
    flex-wrap: wrap;
    align-self: end;
  }
  .stage {
    grid-column: 2;
    grid-row: 1 / span 4;
    container-type: normal;
    min-height: 0;
  }
  .ub-wrap {
    /* As tall as the screen allows, but never wider than the room beside the side panel. */
    width: min(calc(var(--app-height) - var(--safe-top) - var(--safe-bottom) - 20px), calc(100vw - var(--safe-left) - var(--safe-right) - 264px));
  }
}
