@layer layout {
  /* ---- Page ------------------------------------------------------------
     The ground is flat colour. There is no full-viewport texture overlay here —
     machined metal's character is edges and light, not noise, and a fixed overlay
     would cost a full-screen composite on every frame of the race, which is the
     one moment frames matter. Depth comes from the bevels instead. */
  body {
    margin: 0;
    background: var(--ground);
    color: var(--bone);
    font-family: var(--font-body);
    font-weight: 450;
    font-stretch: var(--wdth-body);
    font-size: var(--text-base);
  }

  .shell {
    display: flex;
    flex-direction: column;
    min-height: 100svh;
    max-width: var(--shell-max);
    margin-inline: auto;
    padding: var(--space-3) var(--gutter) var(--space-5);
  }

  /* Screens all live in the DOM at once and are toggled with [hidden], so nothing
     has to be rebuilt when the phase changes. */
  .screen {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: var(--space-4);
    min-height: 0;
  }

  /* ---- Masthead -------------------------------------------------------- */

  .masthead {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-2) var(--space-4);
    padding-bottom: var(--space-3);
    border-bottom: var(--hair) solid var(--edge);
  }

  .masthead__meta {
    display: flex;
    align-items: baseline;
    gap: var(--space-4);
    font-family: var(--font-data);
    font-size: var(--text-2xs);
    letter-spacing: var(--track-caps);
    text-transform: uppercase;
    color: var(--bone-label);
  }

  /* ---- The board ------------------------------------------------------
     Two columns: the display block on the left, the console on the right. That
     is how a bench instrument is actually laid out, and it is why the landscape
     phone case needs no third layout — a phone on its side is this shape at a
     smaller scale.

     A single centred column in a 1440px window is the clearest tell of a mobile
     game that was never designed for a desktop, so the split is the default at
     width, not an enhancement. */
  .board {
    display: grid;
    flex: 1;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-4);
    align-content: start;
    min-height: 0;
  }

  @media (width >= 64rem), (height <= 32rem) and (orientation: landscape) {
    .board {
      grid-template-columns: minmax(0, 1.6fr) minmax(15rem, 0.8fr);
      align-items: start;
    }
  }

  @media (width >= 64rem) {
    .board {
      grid-template-columns: minmax(0, 1.6fr) minmax(17rem, 0.8fr);
    }
  }

  .board__console {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    align-items: center;
  }

  /* ---- Keeping the controls on screen --------------------------------
     On a phone the whole board is a single column, and anything at the bottom of it
     is below the fold. Two rules keep what a player has to reach reachable without
     scrolling — which matters most in the two moments they are under time pressure
     or waiting on somebody. */

  /* 1. The lobby's ready/start/leave row sticks to the bottom of the viewport. Six
        seat plates and six settings rows sit above it, so it would otherwise be a
        scroll away from the moment somebody wants to press it. */
  @media (width < 60rem) {
    .action-bar {
      position: sticky;
      bottom: 0;
      z-index: var(--z-sticky);
      margin-top: var(--space-2);
      padding-bottom: max(var(--space-3), env(safe-area-inset-bottom));
      /* Opaque, not translucent: the roster scrolls underneath it. */
      background: var(--panel);
      box-shadow:
        var(--bevel-raised),
        0 -14px 24px -18px rgb(0 0 0 / 90%);
    }
  }

  /* 2. The board tightens up on a phone so the dial, the readout, the keypad and the
        host's controls fit in one view rather than nearly fitting. The rule that
        hides the keypad once a round is settled lives in the components layer with
        the keypad itself — `.keypad { display: grid }` is declared there, and a
        later layer always wins regardless of selector specificity. */
  @media (width < 64rem) {
    .board__console {
      gap: var(--space-2);
    }

    .instrument {
      padding: var(--space-3) var(--space-3) var(--space-4);
      gap: var(--space-2);
    }

    /* Trimmed at both ends. The board is budgeted to the pixel on a 375x812 phone —
       dial, readout, keypad, rail — and the default page padding is the difference
       between fitting and an 8px scroll. */
    .shell {
      padding-top: var(--space-2);
      padding-bottom: var(--space-2);
    }
  }

  /* A short portrait phone needs another ~200px, and it comes from everything that
     explains rather than plays. The dial, the readout, the keys and the scores stay;
     the prose, the keyboard legend and half the masthead go. Losing the pick note on
     a 568px screen is a fair trade for being able to reach the zero key. */
  @media (height <= 40rem) and (orientation: portrait) {
    .shell {
      gap: var(--space-2);
      padding: var(--space-1) var(--space-3) var(--space-1);
    }

    .masthead {
      padding-bottom: var(--space-1);
    }

    .masthead__meta {
      gap: var(--space-2);
    }

    /* Round and target are nice to know; the room code is the one anybody needs. */
    .masthead__meta > span:not(:last-child) {
      display: none;
    }

    .instrument {
      padding: var(--space-2);
      gap: var(--space-1);
    }

    .board {
      gap: var(--space-2);
    }
  }

  /* ---- The instrument plate ------------------------------------------- */

  .instrument {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-4) var(--space-4) var(--space-5);
    background: var(--panel);
    background-image: var(--panel-brush);
    border-radius: var(--radius-lg);
    box-shadow: var(--bevel-raised);
  }

  /* ---- Lobby ----------------------------------------------------------- */

  .lobby {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-4);
    align-content: start;
  }

  @media (width >= 60rem) {
    .lobby {
      grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
    }

    .lobby__wide {
      grid-column: 1 / -1;
    }
  }

  .panel {
    padding: var(--space-4);
    background: var(--panel);
    border-radius: var(--radius-md);
    box-shadow: var(--bevel-raised);
  }

  .panel__title {
    display: block;
    margin-bottom: var(--space-3);
    font-family: var(--font-data);
    font-size: var(--text-2xs);
    font-weight: 500;
    letter-spacing: var(--track-caps);
    text-transform: uppercase;
    color: var(--bone-label);
  }

  /* ---- Centred screens (connecting, error) ---------------------------- */

  .stage {
    display: flex;
    flex: 1;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-4);
    padding-block: var(--space-6);
    text-align: center;
  }

  .stage p {
    max-width: var(--measure);
    color: var(--bone-label);
  }

  /* ---- Overlays -------------------------------------------------------- */

  .overlay {
    position: fixed;
    inset: 0;
    z-index: var(--z-overlay);
    display: grid;
    place-items: center;
    background: rgb(13 17 25 / 82%);
    backdrop-filter: blur(2px);
  }

  .toasts {
    position: fixed;
    inset-inline: 0;
    bottom: max(var(--space-4), env(safe-area-inset-bottom));
    z-index: var(--z-toast);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-2);
    padding-inline: var(--gutter);
    pointer-events: none;
  }

  /* In landscape the console occupies the bottom of the screen, so a toast
     anchored there would land on the keypad. */
  @media (height <= 32rem) and (orientation: landscape) {
    .toasts {
      top: var(--space-2);
      bottom: auto;
    }

    .masthead {
      padding-bottom: var(--space-2);
    }

    .shell {
      padding-block: var(--space-2);
      gap: var(--space-2);
    }

    .instrument {
      padding: var(--space-2) var(--space-3) var(--space-3);
      gap: var(--space-2);
    }
  }

  /* ---- Utilities ------------------------------------------------------- */

  .row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
  }

  .row--end {
    justify-content: flex-end;
  }

  .row--between {
    justify-content: space-between;
  }

  .stack {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
  }

  .push {
    margin-top: auto;
  }

  /* Anything that can overflow horizontally scrolls inside its own box. The page
     body must never scroll sideways. */
  .scroll-x {
    max-width: 100%;
    overflow-x: auto;
    overscroll-behavior-x: contain;
  }
}
