:root {
  --accent: #70ff7a;
  --accent-soft: rgba(112,255,122,0.14);
  --accent-glow: rgba(112,255,122,0.40);
  --bg: #060c18;
  --line: #244263;
  --text: #d9f7ff;
  --cyan: #3fd8ff;
  --green: #2df6ac;
  --rose: #ff6e9d;
  --board-size: min(calc(100dvh - 150px), calc(100vw - 130px));
  --hex-window-path: polygon(23% 7%, 77% 7%, 96% 50%, 77% 93%, 23% 93%, 4% 50%);
}

/* Language switch, top right. */
.langSel {
  position: fixed;
  top: 12px;
  right: 14px;
  z-index: 9999;
  display: flex;
  gap: 4px;
  padding: 4px;
  border-radius: 999px;
  background: rgba(7, 6, 10, 0.82);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.14);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

.langSel button {
  cursor: pointer;
  border: none;
  background: transparent;
  color: rgba(255, 255, 255, 0.55);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 5px 9px;
  border-radius: 999px;
}

.langSel button:hover {
  color: #fff;
}

.langSel button[aria-pressed="true"] {
  color: #07060a;
  background: #ffd24a;
}

.langSel button:focus-visible {
  outline: 2px solid #ffd24a;
  outline-offset: 1px;
}

/* Read by screen readers only. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  width: 100%;
  height: 100%;
}

body {
  overflow: hidden;
  font-family: "Manrope", "Avenir Next", "Segoe UI", sans-serif;
  background:
    radial-gradient(960px 560px at 7% -18%, rgba(26, 194, 255, 0.16), transparent 62%),
    radial-gradient(760px 560px at 100% -20%, rgba(45, 246, 172, 0.1), transparent 66%),
    var(--bg);
  color: var(--text);
}

/* ---------- page: area on top, the board with its pieces, the board group
   (erase on the left, the camera on the right) right under the board, the
   camera's right edge on the board's and the credit between them, as in the
   other two labs (app.js lays the group on the drawn board) ---------- */

.app-shell {
  width: 100%;
  height: 100dvh;
  padding: 6px 10px;
}

.main-stage {
  width: 100%;
  height: 100%;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  grid-template-columns: minmax(0, 1fr);
  gap: 6px;
  justify-items: center;
}

.toolbar {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 44px;
}

.play-zone {
  width: 100%;
  min-height: 0;
  display: grid;
  place-items: center;
}

.board-wrap {
  width: var(--board-size);
  height: var(--board-size);
  min-height: 0;
  position: relative;
  overflow: visible;
}

#board-canvas {
  width: 100%;
  height: 100%;
  display: block;
  touch-action: none;
}

/* Wide screens: the pieces sit around the board (app.js places them),
   rotate and flip at the top left of the board's square. */
.piece-ring {
  position: absolute;
  inset: 0;
  z-index: 6;
  pointer-events: none;
  transition: opacity 0.18s ease;
}

.piece-chip {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  border: 1px solid var(--line);
  background: #172238;
  display: grid;
  place-items: center;
  padding: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.12s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}

@media (hover: hover) {
  .piece-chip-ring:hover {
    transform: translate(-50%, -50%) translateY(-1px);
    border-color: color-mix(in srgb, var(--cyan) 60%, white);
  }
}

.piece-chip.is-selected {
  border-color: color-mix(in srgb, var(--cyan) 70%, white);
  box-shadow:
    inset 0 0 10px rgba(63, 216, 255, 0.18),
    0 0 14px rgba(63, 216, 255, 0.2);
}

.piece-chip.is-on-board:not(.is-selected) {
  border-color: color-mix(in srgb, var(--green) 55%, white);
  box-shadow: inset 0 0 8px rgba(45, 246, 172, 0.14);
}

.piece-chip svg {
  width: 34px;
  height: 34px;
  overflow: visible;
}

.piece-chip-ring {
  position: absolute;
  left: 0;
  top: 0;
  transform: translate(-50%, -50%);
  pointer-events: auto;
}

.board-actions {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 7;
  display: flex;
  gap: 8px;
  transition: opacity 0.18s ease;
}

/* The camera window covers the board drawing exactly. */
.camera-host {
  position: absolute;
  inset: 0;
  z-index: 5;
}

.camera-host[hidden] {
  display: none !important;
}

/* One column; the credit shares the board group's row. */
.main-stage > * { grid-column: 1; }
.main-stage > .toolbar { grid-row: 1; }
.main-stage > .play-zone { grid-row: 2; }

/* The board group, as wide as the drawn board (app.js), over the board's
   box (its corners outside the drawing) and over the camera window. */
.boardbar {
  grid-row: 3;
  width: var(--board-size);
  min-height: 56px;
  position: relative;
  z-index: 8;
}

.main-stage > .side-brand {
  grid-row: 3;
  align-self: center;
  justify-self: center;
  position: relative;
  z-index: 9;
}

/* Back to the hub and print the kit: in the top strip, left of the
   language switch. */
.lab-nav {
  position: fixed;
  top: 13px;
  right: 180px;
  z-index: 9999;
}


/* ---------- narrow or portrait screens: area on top, then rotate and flip
   (back to the hub and print at the other end of their row), the board, the
   pieces in two rows, erase and the camera right under the pieces, then the
   credit; this group is centred in the room under the area, its rows 10 px
   apart, as in the other two labs ---------- */

@media (max-width: 700px), (max-aspect-ratio: 4/5) {
  :root {
    --board-size: min(calc(100vw - 20px), calc(100dvh - 404px));
  }

  .main-stage {
    grid-template-rows: auto minmax(0, 1fr) auto auto auto minmax(0, 1fr);
    row-gap: 10px;
  }

  .main-stage > .toolbar { grid-row: 1; }
  .main-stage > .play-zone { grid-row: 3; }
  .boardbar { grid-row: 4; }
  .main-stage > .side-brand { grid-row: 5; max-width: 100%; }

  .lab-nav {
    position: static;
  }

  .app-shell {
    padding: 6px 10px max(8px, env(safe-area-inset-bottom));
  }

  /* The area pill shares the top strip with the language switch. */
  .toolbar {
    width: 100%;
    justify-content: flex-start;
    padding-right: 172px;
  }

  .play-zone {
    align-content: center;
  }

  .board-wrap {
    height: auto;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "acts"
      "board"
      "tray";
    column-gap: 8px;
    row-gap: 10px;
    align-items: center;
  }

  #board-canvas {
    grid-area: board;
    height: auto;
    aspect-ratio: 1 / 1;
  }

  /* The camera window covers the board's grid cell exactly. */
  .camera-host {
    grid-area: board;
    inset: 0;
  }

  .piece-ring {
    grid-area: tray;
    position: static;
    inset: auto;
    display: grid;
    grid-template-columns: repeat(var(--cols, 4), minmax(0, 1fr));
    gap: 8px;
    pointer-events: auto;
    /* two rows of chips are kept from the start: filling the tray moves nothing */
    min-height: calc(2 * min(58px, (var(--board-size) - 24px) / 4) + 8px);
  }

  .piece-chip-ring {
    position: static;
    transform: none;
    width: 100%;
    height: auto;
    max-width: 58px;
    aspect-ratio: 1 / 1;
    justify-self: center;
    border-radius: 10px;
  }

  .piece-chip svg {
    width: 90%;
    height: 90%;
  }

  .board-actions {
    grid-area: acts;
    position: static;
    justify-self: stretch;
  }

  .boardbar {
    width: min(100%, var(--board-size));
  }
}


/* ---------- a phone held sideways: rotate and flip, the area and the links
   in a strip along the top; under it the board on the left, and on the
   right the pieces in a grid, erase and the camera under them, then the
   credit; nothing scrolls. app.js sizes the chips (--chip, --chip-cols) and
   moves the area off the middle (--area-shift) only when it lacks room
   there. The same query is in app.js ---------- */

@media (orientation: landscape) and (max-height: 500px) {
  :root {
    --board-size: min(calc(100dvh - 74px), 52vw);
    /* the left edge of the room right of the board */
    --panel-left: calc(var(--board-size) + 26px);
  }

  .toolbar {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 7;
    width: 100%;
    height: 56px;
    padding: 0 max(0px, calc(-2 * var(--area-shift, 0px))) 0 max(0px, calc(2 * var(--area-shift, 0px)));
    justify-content: center;
    align-items: center;
    pointer-events: none;
  }

  .toolbar > .measure {
    align-self: center;
    pointer-events: auto;
  }

  .langSel {
    top: 5px;
  }

  .board-actions {
    position: fixed;
    left: 10px;
    top: 6px;
  }

  .lab-nav {
    position: fixed;
    top: 6px;
    right: 180px;
  }

  .board-wrap {
    position: fixed;
    left: 10px;
    top: 64px;
    display: block;
    width: var(--board-size);
    height: var(--board-size);
  }

  #board-canvas {
    width: 100%;
    height: 100%;
    aspect-ratio: auto;
  }

  .piece-ring {
    position: fixed;
    inset: 64px 10px auto var(--panel-left);
    display: grid;
    grid-template-columns: repeat(var(--chip-cols, 4), var(--chip, 44px));
    gap: 8px;
    justify-content: start;
    align-content: start;
    min-height: 0;
    pointer-events: auto;
  }

  /* no sliding when the phone turns: the chips land in the grid at once */
  .piece-chip-ring {
    position: static;
    transform: none;
    width: var(--chip, 44px);
    height: var(--chip, 44px);
    max-width: none;
    border-radius: 10px;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
  }

  .piece-chip svg {
    width: 90%;
    height: 90%;
  }

  @media (hover: hover) {
    .piece-chip-ring:hover {
      transform: translateY(-1px);
    }
  }

  /* Erase and the camera, 16 px above the credit. */
  .boardbar {
    position: fixed;
    left: var(--panel-left);
    right: 10px;
    bottom: 70px;
    width: auto;
    height: 56px;
  }

  /* The credit, centred under them: one line when it fits, else two. */
  .main-stage > .side-brand {
    position: fixed;
    left: var(--panel-left);
    right: 10px;
    bottom: 10px;
    width: fit-content;
    max-width: none;
    margin: 0 auto;
    white-space: normal;
    text-align: center;
    text-wrap: balance;
  }
}
