@layer board {
  /* The stage holds the WebGL canvas and, underneath it, the CSS fallback board.
     When WebGL runs, the fallback is kept in the DOM but hidden from view. */
  .stage {
    position: relative;
    height: min(84vh, 860px);
    border-radius: var(--radius-lg);
    overflow: hidden;
    touch-action: none;
    user-select: none;
    -webkit-user-select: none;
  }
  @media (max-width: 48rem) { .stage { height: min(62vh, 620px); } }
  .stage__canvas { display: none; width: 100%; height: 100%; cursor: grab; }
  .stage__canvas:active { cursor: grabbing; }
  .stage--webgl .stage__canvas { display: block; }
  .stage--webgl .scene {
    position: absolute !important;
    width: 1px; height: 1px;
    overflow: hidden; clip: rect(0, 0, 0, 0);
    white-space: nowrap;
  }

  /* --------------------------------------------------------------------------
     The scene is the camera. The board is a real box (top plus two visible
     sides) seen from a 3/4 isometric angle. Everything that must read as
     upright (signs, billboards, the pawn) is a panel that stands on the board
     and counter-rotates by --spin so it faces the viewer.
     -------------------------------------------------------------------------- */
  .scene {
    --tilt: 56deg;
    --spin: 45deg;
    --scene-h: min(84vh, 860px);
    @media (max-width: 48rem) { --scene-h: min(62vh, 620px); }
    --board-size: min(calc(100cqw / 1.5), var(--scene-h), 1100px);
    --u: calc(var(--board-size) / 12); /* one side-square width; corners are 1.5u */
    --thickness: calc(var(--u) * 0.28);
    position: relative;
    container-type: inline-size;
    height: var(--scene-h);
    perspective: 2200px;
    perspective-origin: 50% 35%;
    overflow: hidden;
    touch-action: none;
    user-select: none;
    -webkit-user-select: none;
    cursor: grab;
    border-radius: var(--radius-lg);
  }
  .scene:active { cursor: grabbing; }
  .scene.is-gliding .board {
    transition: --pan-x var(--t-camera) var(--ease-glide), --pan-y var(--t-camera) var(--ease-glide), --zoom var(--t-camera) var(--ease-glide);
  }

  .board {
    --pan-x: 0px;
    --pan-y: 0px;
    --zoom: 1;
    position: absolute;
    left: 50%;
    top: 50%;
    width: var(--board-size);
    aspect-ratio: 1;
    margin-left: calc(var(--board-size) / -2);
    margin-top: calc(var(--board-size) / -2);
    transform: translate3d(var(--pan-x), var(--pan-y), 0) scale(var(--zoom)) rotateX(var(--tilt)) rotateZ(var(--spin));
    transform-style: preserve-3d;
    display: grid;
    grid-template-columns: 1.5fr repeat(9, 1fr) 1.5fr;
    grid-template-rows: 1.5fr repeat(9, 1fr) 1.5fr;
    background: var(--board);
    border-radius: 6px;
    box-shadow: calc(var(--u) * 0.5) calc(var(--u) * 0.5) 0 rgb(30 42 68 / 0.22);
  }
  /* Front and right sides of the board box. */
  .board::before, .board::after {
    content: "";
    position: absolute;
    background: var(--board-edge);
    pointer-events: none;
  }
  .board::before {
    left: 0; right: 0; bottom: 0;
    height: var(--thickness);
    transform-origin: 50% 100%;
    transform: rotateX(-90deg);
    background: linear-gradient(180deg, #c9a670, #a97f48);
  }
  .board::after {
    top: 0; bottom: 0; right: 0;
    width: var(--thickness);
    transform-origin: 100% 50%;
    transform: rotateY(90deg);
    background: linear-gradient(90deg, #b8935f, #8f6a3a);
  }

  /* ---- Squares ----------------------------------------------------------- */
  .square {
    position: relative;
    transform-style: preserve-3d;
    background: var(--board);
    outline: 1px solid color-mix(in oklab, var(--ink) 12%, transparent);
    outline-offset: -1px;
  }

  /* Property lots are raised slabs in their district color. */
  .tile {
    --lift: calc(var(--u) * 0.06);
    position: absolute;
    inset: 7%;
    background: color-mix(in oklab, var(--district) 42%, var(--paper));
    border-radius: 3px;
    transform: translateZ(var(--lift));
    transform-style: preserve-3d;
    box-shadow: inset 0 0 0 1px rgb(30 42 68 / 0.25);
  }
  .tile::before, .tile::after {
    content: "";
    position: absolute;
    background: color-mix(in oklab, var(--district) 55%, var(--ink) 20%);
  }
  .tile::before { left: 0; right: 0; bottom: 0; height: var(--lift); transform-origin: 50% 100%; transform: rotateX(-90deg); }
  .tile::after { top: 0; bottom: 0; right: 0; width: var(--lift); transform-origin: 100% 50%; transform: rotateY(90deg); background: color-mix(in oklab, var(--district) 45%, var(--ink) 35%); }

  .tile--empty {
    background:
      radial-gradient(circle, color-mix(in oklab, var(--district) 60%, var(--lawn)) 0 18%, transparent 20%) 0 0 / calc(var(--u) * 0.12) calc(var(--u) * 0.12),
      color-mix(in oklab, var(--district) 28%, #d9efc9);
  }
  .tile--empty::before, .tile--empty::after { background: color-mix(in oklab, var(--district) 40%, var(--lawn-deep)); }

  /* ---- Standing panels: signs, billboards, sprites ------------------------ */
  .stand {
    position: absolute;
    transform-origin: 50% 100%;
    transform-style: preserve-3d;
    pointer-events: none;
  }

  /* Lot names lie flat on the tile, counter-rotated so they read horizontally. */
  .label {
    position: absolute;
    left: 50%;
    top: 50%;
    width: calc(var(--u) * 1.1);
    transform: translate(-50%, -50%) rotateZ(calc(-1 * var(--spin))) translate(calc(var(--u) * 0.12), calc(var(--u) * 0.36)) translateZ(calc(var(--u) * 0.07));
    padding: calc(var(--u) * 0.03) calc(var(--u) * 0.06);
    background: rgb(255 253 247 / 0.9);
    border-radius: calc(var(--u) * 0.04);
    font-family: var(--font-display);
    font-weight: 600;
    font-size: calc(var(--u) * 0.135);
    line-height: 1.05;
    color: var(--ink);
    text-align: center;
    text-decoration: none;
    pointer-events: auto;
  }
  .label:hover { background: var(--sun); color: var(--ink); }
  .square--card .label, .square--rent_due .label { background: none; font-size: calc(var(--u) * 0.12); color: var(--ink-soft); }

  /* Corner names are standing signs behind their landmark. */
  .sign {
    left: 90%;
    top: 74%;
    width: calc(var(--u) * 0.9);
    padding: calc(var(--u) * 0.04) calc(var(--u) * 0.08);
    transform: translate(-50%, -100%) translateZ(calc(var(--u) * 0.02)) rotateZ(calc(-1 * var(--spin))) rotateX(-90deg);
    background: var(--ink);
    color: var(--paper);
    border: calc(var(--u) * 0.02) solid var(--ink);
    border-radius: calc(var(--u) * 0.05);
    box-shadow: calc(var(--u) * 0.03) calc(var(--u) * 0.03) 0 var(--brick);
    font-family: var(--font-display);
    font-weight: 600;
    font-size: calc(var(--u) * 0.17);
    line-height: 1.1;
    text-align: center;
  }
  .sign::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 100%;
    width: calc(var(--u) * 0.05);
    height: calc(var(--u) * 0.16);
    margin-left: calc(var(--u) * -0.025);
    background: var(--ink);
  }

  /* ---- Buildings: an axis-aligned box on the tile, growing with level ------ */
  .building {
    --w: calc(var(--u) * 0.42);
    --d: calc(var(--u) * 0.42);
    --h: calc(var(--u) * 0.32);
    --bb-w: calc(var(--u) * 0.56);
    --bb-h: calc(var(--u) * 0.34);
    position: absolute;
    left: 42%;
    top: 40%;
    width: var(--w);
    height: var(--d);
    margin-left: calc(var(--w) / -2);
    margin-top: calc(var(--d) / -2);
    transform: translateZ(calc(var(--u) * 0.06));
    transform-style: preserve-3d;
    pointer-events: none;
  }
  .building[data-level="2"] { --w: calc(var(--u) * 0.48); --d: calc(var(--u) * 0.48); --h: calc(var(--u) * 0.5); --bb-w: calc(var(--u) * 0.68); --bb-h: calc(var(--u) * 0.42); }
  .building[data-level="3"] { --w: calc(var(--u) * 0.54); --d: calc(var(--u) * 0.54); --h: calc(var(--u) * 0.72); --bb-w: calc(var(--u) * 0.8); --bb-h: calc(var(--u) * 0.5); }
  .building[data-level="4"] { --w: calc(var(--u) * 0.6); --d: calc(var(--u) * 0.6); --h: calc(var(--u) * 1); --bb-w: calc(var(--u) * 0.92); --bb-h: calc(var(--u) * 0.58); }
  .building[data-level="5"] { --w: calc(var(--u) * 0.68); --d: calc(var(--u) * 0.68); --h: calc(var(--u) * 1.5); --bb-w: calc(var(--u) * 1.08); --bb-h: calc(var(--u) * 0.68); }

  .face {
    position: absolute;
    background: var(--district);
    box-shadow: inset 0 0 0 1px rgb(30 42 68 / 0.35);
  }
  .face--top {
    inset: 0;
    transform: translateZ(var(--h));
    background: color-mix(in oklab, var(--district) 70%, white);
  }
  .face--front {
    left: 0; right: 0; bottom: 0;
    height: var(--h);
    transform-origin: 50% 100%;
    transform: rotateX(-90deg);
    background: color-mix(in oklab, var(--district) 88%, var(--ink));
  }
  .face--right {
    top: 0; bottom: 0; right: 0;
    width: var(--h);
    transform-origin: 100% 50%;
    transform: rotateY(90deg);
    background: color-mix(in oklab, var(--district) 70%, var(--ink));
  }
  /* Windows on taller buildings. */
  .building[data-level="3"] .face--front, .building[data-level="4"] .face--front, .building[data-level="5"] .face--front,
  .building[data-level="3"] .face--right, .building[data-level="4"] .face--right, .building[data-level="5"] .face--right {
    background-image: radial-gradient(rgb(255 253 247 / 0.85) 0 30%, transparent 32%);
    background-size: calc(var(--u) * 0.14) calc(var(--u) * 0.14);
    background-position: 50% 30%;
  }
  .building[data-level="5"] .face--top {
    background:
      radial-gradient(circle at 50% 50%, var(--sun) 0 22%, transparent 24%),
      color-mix(in oklab, var(--district) 70%, white);
  }

  /* The billboard is a panel on the roof, facing the viewer, sized by level. */
  .billboard {
    left: 50%;
    top: 50%;
    width: var(--bb-w);
    height: var(--bb-h);
    transform: translate(-50%, -100%) translateZ(var(--h)) rotateZ(calc(-1 * var(--spin))) rotateX(-90deg);
    background: var(--paper);
    border: calc(var(--u) * 0.025) solid var(--ink);
    border-radius: calc(var(--u) * 0.04);
    box-shadow: calc(var(--u) * 0.03) calc(var(--u) * 0.03) 0 var(--ink);
    overflow: hidden;
    pointer-events: auto;
  }
  .billboard img { width: 100%; height: 100%; object-fit: cover; }
  .billboard__placeholder {
    width: 100%;
    height: 100%;
    display: grid;
    place-items: center;
    background: repeating-linear-gradient(-45deg, var(--sun) 0 8%, var(--paper) 8% 16%);
    font-family: var(--font-display);
    font-size: calc(var(--u) * 0.11);
    color: var(--ink);
  }

  /* ---- Cards and Rent is due: flat props on the board ---------------------- */
  .prop-card {
    position: absolute;
    left: 50%;
    top: 46%;
    width: calc(var(--u) * 0.5);
    height: calc(var(--u) * 0.68);
    transform: translate(-50%, -50%) rotateZ(calc(-1 * var(--spin))) translateZ(calc(var(--u) * 0.02));
    background:
      repeating-linear-gradient(45deg, rgb(255 255 255 / 0.35) 0 4px, transparent 4px 8px),
      var(--pool);
    border: calc(var(--u) * 0.025) solid var(--ink);
    border-radius: calc(var(--u) * 0.06);
    box-shadow: calc(var(--u) * 0.04) calc(var(--u) * 0.04) 0 rgb(30 42 68 / 0.35);
  }
  .square--card[data-deck="b"] .prop-card { background: repeating-linear-gradient(45deg, rgb(255 255 255 / 0.35) 0 4px, transparent 4px 8px), var(--sun); }
  .prop-bill {
    position: absolute;
    left: 50%;
    top: 46%;
    width: calc(var(--u) * 0.6);
    height: calc(var(--u) * 0.4);
    transform: translate(-50%, -50%) rotateZ(calc(-1 * var(--spin) + 8deg)) translateZ(calc(var(--u) * 0.02));
    background:
      linear-gradient(var(--brick) 0 0) 12% 30% / 76% 10% no-repeat,
      linear-gradient(var(--ink-faint) 0 0) 12% 55% / 60% 8% no-repeat,
      linear-gradient(var(--ink-faint) 0 0) 12% 72% / 50% 8% no-repeat,
      var(--paper);
    border: calc(var(--u) * 0.02) solid var(--ink);
    box-shadow: calc(var(--u) * 0.03) calc(var(--u) * 0.03) 0 rgb(30 42 68 / 0.35);
  }

  /* ---- Corner landmarks ---------------------------------------------------- */
  .landmark {
    position: absolute;
    left: 50%;
    top: 40%;
    transform-style: preserve-3d;
    pointer-events: none;
  }
  .sprite {
    left: 50%;
    top: 42%;
    transform: translate(-50%, -100%) translateZ(calc(var(--u) * 0.02)) rotateZ(calc(-1 * var(--spin))) rotateX(-90deg);
  }

  /* Launch: a rocket on a pad. */
  .pad {
    position: absolute;
    left: 50%;
    top: 42%;
    width: calc(var(--u) * 0.9);
    height: calc(var(--u) * 0.9);
    transform: translate(-50%, -50%);
    border-radius: 50%;
    background: repeating-radial-gradient(circle, var(--ink) 0 3px, transparent 3px 12px);
    opacity: 0.35;
  }
  .rocket {
    width: calc(var(--u) * 0.34);
    height: calc(var(--u) * 0.9);
  }
  .rocket::before {
    content: "";
    position: absolute;
    left: 20%;
    right: 20%;
    top: 0;
    bottom: 12%;
    background: linear-gradient(90deg, #ffe4dc, var(--brick) 45%, var(--brick-deep));
    border: calc(var(--u) * 0.02) solid var(--ink);
    border-radius: 50% 50% 18% 18% / 40% 40% 10% 10%;
  }
  .rocket::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 34%;
    background: var(--sun);
    border: calc(var(--u) * 0.02) solid var(--ink);
    clip-path: polygon(0 100%, 30% 0, 70% 0, 100% 100%, 75% 70%, 25% 70%);
  }

  /* Timeout: a barred cell block. */
  .cell {
    --w: calc(var(--u) * 0.8);
    --d: calc(var(--u) * 0.8);
    --h: calc(var(--u) * 0.7);
    --district: #9aa3b8;
    left: 50%;
    top: 40%;
    width: var(--w);
    height: var(--d);
    margin-left: calc(var(--w) / -2);
    margin-top: calc(var(--d) / -2);
    transform: none;
  }
  .cell .face--front, .cell .face--right {
    background-image: repeating-linear-gradient(90deg, var(--ink) 0 8%, transparent 8% 24%);
    background-size: 100% 70%;
    background-repeat: no-repeat;
    background-position: 50% 100%;
  }

  /* Open Lot: trees. */
  .tree { width: calc(var(--u) * 0.36); height: calc(var(--u) * 0.6); }
  .tree::before {
    content: "";
    position: absolute;
    left: 42%;
    right: 42%;
    bottom: 0;
    height: 35%;
    background: #8f6a3a;
    border: calc(var(--u) * 0.015) solid var(--ink);
  }
  .tree::after {
    content: "";
    position: absolute;
    inset: 0 0 28%;
    background: radial-gradient(circle at 35% 30%, #a6e69a, var(--lawn) 55%, var(--lawn-deep));
    border: calc(var(--u) * 0.02) solid var(--ink);
    border-radius: 50%;
  }
  .tree--2 { left: 26%; top: 60%; transform: translate(-50%, -100%) translateZ(calc(var(--u) * 0.02)) rotateZ(calc(-1 * var(--spin))) rotateX(-90deg) scale(0.75); }
  .tree--3 { left: 72%; top: 64%; transform: translate(-50%, -100%) translateZ(calc(var(--u) * 0.02)) rotateZ(calc(-1 * var(--spin))) rotateX(-90deg) scale(0.6); }

  /* Busted: a striped barrier with a beacon. */
  .barrier {
    --w: calc(var(--u) * 0.9);
    --d: calc(var(--u) * 0.3);
    --h: calc(var(--u) * 0.5);
    --district: var(--sun);
    left: 50%;
    top: 40%;
    width: var(--w);
    height: var(--d);
    margin-left: calc(var(--w) / -2);
    margin-top: calc(var(--d) / -2);
    transform: rotateZ(calc(-1 * var(--spin)));
  }
  .barrier .face--front { background: repeating-linear-gradient(-45deg, var(--sun) 0 12%, var(--ink) 12% 24%); }
  .beacon {
    width: calc(var(--u) * 0.2);
    height: calc(var(--u) * 0.2);
    top: 20%;
    border-radius: 50%;
    background: radial-gradient(circle at 35% 35%, #ff9b8f, var(--danger));
    border: calc(var(--u) * 0.02) solid var(--ink);
    box-shadow: 0 0 calc(var(--u) * 0.2) var(--danger);
  }

  /* ---- Center ------------------------------------------------------------- */
  .board-center {
    --road: calc(var(--u) * 0.26);
    grid-area: 2 / 2 / 11 / 11;
    position: relative;
    display: grid;
    place-items: center;
    text-align: center;
    padding: 12%;
    transform-style: preserve-3d;
    background:
      radial-gradient(circle, rgb(255 255 255 / 0.5) 0 14%, transparent 16%) 0 0 / calc(var(--u) * 0.2) calc(var(--u) * 0.2),
      #cfe9b8;
    border: var(--road) solid #5b657c;
    box-shadow: inset 0 0 0 calc(var(--u) * 0.05) #b7d89c;
  }
  /* Dashed center line of the road ring. */
  .board-center::before {
    content: "";
    position: absolute;
    inset: calc(var(--road) / -2);
    border: calc(var(--u) * 0.02) dashed rgb(255 253 247 / 0.85);
    pointer-events: none;
  }
  .pond {
    position: absolute;
    left: 14%;
    top: 62%;
    width: 24%;
    height: 16%;
    border-radius: 50%;
    background: radial-gradient(circle at 40% 35%, #bfe6ff, var(--pool) 70%);
    box-shadow: inset 0 0 0 calc(var(--u) * 0.04) #b7d89c;
  }
  .park-tree { position: absolute; }
  .park-tree--1 { left: 78%; top: 24%; }
  .park-tree--2 { left: 86%; top: 40%; transform: translate(-50%, -100%) translateZ(calc(var(--u) * 0.02)) rotateZ(calc(-1 * var(--spin))) rotateX(-90deg) scale(0.8); }
  .park-tree--3 { left: 22%; top: 30%; transform: translate(-50%, -100%) translateZ(calc(var(--u) * 0.02)) rotateZ(calc(-1 * var(--spin))) rotateX(-90deg) scale(0.9); }
  .park-tree--4 { left: 72%; top: 80%; transform: translate(-50%, -100%) translateZ(calc(var(--u) * 0.02)) rotateZ(calc(-1 * var(--spin))) rotateX(-90deg) scale(0.7); }

  .board-center__inner {
    transform: rotateZ(calc(-1 * var(--spin))) translateZ(calc(var(--u) * 0.04));
    background: var(--paper);
    border: calc(var(--u) * 0.03) solid var(--ink);
    border-radius: calc(var(--u) * 0.12);
    box-shadow: calc(var(--u) * 0.06) calc(var(--u) * 0.06) 0 var(--ink);
    padding: calc(var(--u) * 0.3) calc(var(--u) * 0.5);
  }
  .board-center__title {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: calc(var(--u) * 0.5);
    color: var(--ink);
    line-height: 1;
  }
  .board-center__sub {
    font-family: var(--font-display);
    color: var(--ink-soft);
    font-size: calc(var(--u) * 0.17);
    margin: 0.5em auto 0;
    max-width: 24ch;
  }

  /* ---- The shared pawn ------------------------------------------------------ */
  .pawn {
    --x: 0px;
    --y: 0px;
    position: absolute;
    left: 0;
    top: 0;
    width: calc(var(--u) * 0.36);
    height: calc(var(--u) * 0.6);
    transform-origin: 50% 100%;
    transform: translate3d(calc(var(--x) - var(--u) * 0.18), calc(var(--y) - var(--u) * 0.6), calc(var(--u) * 0.07)) rotateZ(calc(-1 * var(--spin))) rotateX(-90deg);
    transform-style: preserve-3d;
    pointer-events: none;
    z-index: 2;
  }
  .pawn::before {
    content: "";
    position: absolute;
    left: 12%;
    right: 12%;
    bottom: 0;
    height: 58%;
    background: linear-gradient(90deg, #ffb3a3, var(--brick) 40%, var(--brick-deep));
    border: calc(var(--u) * 0.025) solid var(--ink);
    border-radius: 40% 40% 12% 12%;
    box-shadow: calc(var(--u) * 0.03) calc(var(--u) * 0.03) 0 var(--ink);
  }
  .pawn::after {
    content: "";
    position: absolute;
    left: 15%;
    right: 15%;
    top: 0;
    aspect-ratio: 1;
    background: radial-gradient(circle at 35% 35%, #ffd0c6, var(--brick) 55%, var(--brick-deep));
    border: calc(var(--u) * 0.025) solid var(--ink);
    border-radius: 50%;
    box-shadow: calc(var(--u) * 0.03) calc(var(--u) * 0.03) 0 var(--ink);
  }
  .pawn__shadow {
    position: absolute;
    left: 0;
    top: 0;
    width: calc(var(--u) * 0.4);
    height: calc(var(--u) * 0.4);
    border-radius: 50%;
    background: radial-gradient(circle, rgb(30 42 68 / 0.35), transparent 70%);
    transform: translate(calc(var(--x) - var(--u) * 0.2), calc(var(--y) - var(--u) * 0.2)) translateZ(calc(var(--u) * 0.065));
    pointer-events: none;
    z-index: 1;
  }

  .camera-controls {
    position: absolute;
    right: var(--space-3);
    bottom: var(--space-3);
    display: flex;
    gap: var(--space-2);
    z-index: 3;
  }
  .stage .scene { height: 100%; }

  .board-stage {
    display: grid;
    gap: var(--space-4);
    padding: 0 var(--space-4) var(--space-4);
  }
  @media (min-width: 64rem) {
    .board-stage { grid-template-columns: minmax(0, 1fr) 22rem; align-items: start; }
  }
}

@layer board {
  .board-center__logo { width: calc(var(--u) * 3); height: calc(var(--u) * 3); object-fit: cover; border-radius: calc(var(--u) * 0.1); }
}
