@layer layout {
  body {
    font-family: var(--font-body);
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--ink);
    background-color: var(--paper);
    /* Three layers: a dot grid that makes the page a printed sheet, then a
       soft off-register wash of each player's ink bled into opposite corners.
       The washes set up the standoff before a single tile is drawn. */
    background-image:
      var(--dot-grid),
      radial-gradient(58rem 40rem at 6% -10%, rgb(255 77 141 / 22%), transparent 62%),
      radial-gradient(56rem 40rem at 98% 2%, rgb(61 90 255 / 18%), transparent 60%),
      radial-gradient(48rem 34rem at 50% 110%, rgb(43 224 168 / 20%), transparent 65%);
    background-size:
      var(--dot-grid-size),
      auto,
      auto,
      auto;
    background-attachment: fixed;
    overflow-x: hidden;
  }

  /* Paper grain, over everything, inert to pointers. */
  .grain {
    position: fixed;
    inset: 0;
    z-index: var(--z-sticky);
    background-image: var(--grain);
    opacity: var(--grain-opacity);
    mix-blend-mode: multiply;
    pointer-events: none;
    transition: opacity var(--dur-slow) var(--ease-out);
  }

  .shell {
    display: grid;
    grid-template-rows: auto 1fr auto;
    min-height: 100svh;
    max-width: var(--shell-max);
    margin-inline: auto;
    padding-inline: var(--gutter);
  }

  .masthead {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    padding-block: var(--space-4);
    min-height: 3.5rem;
  }

  .colophon {
    padding-block: var(--space-4) var(--space-5);
    font-size: var(--text-xs);
    font-weight: 700;
    color: var(--ink-faint);
    text-align: center;
  }

  /* ---- Screens ---------------------------------------------------------
     All screens live in the document at once and are toggled with [hidden],
     so they share a single grid cell. */
  .screens {
    display: grid;
    align-content: center;
    padding-block: var(--space-5) var(--space-6);
  }

  .screen {
    display: grid;
    gap: var(--space-6);
    justify-items: center;
  }

  .stack {
    display: grid;
    gap: var(--space-4);
    width: 100%;
    max-width: var(--measure);
  }

  .stack--tight {
    gap: var(--space-3);
  }

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

  /* ---- Hero -----------------------------------------------------------
     The hero is the game, played once, on loop: two inked letters and the
     word that bridges them. It teaches both rules without a tutorial. */
  .hero {
    display: grid;
    gap: var(--space-5);
    justify-items: center;
    text-align: center;
  }

  .hero__demo {
    display: grid;
    gap: var(--space-4);
    justify-items: center;
    width: 100%;
  }

  /* ---- The standoff ---------------------------------------------------
     The two tiles sit apart and their colour passes reach into the gap, where
     they multiply into the overprint. `isolation` keeps that blend inside this
     element instead of reaching the page background; `position: relative`
     anchors the VS burst over the band. */
  .standoff {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    isolation: isolate;
    width: 100%;
  }

  .standoff__gap {
    width: var(--bridge-gap);
    flex: 0 0 auto;
  }

  /* Geometry for the two overlapping ink bands (see .bridge__ink):
       --bridge-gap     open space between the tiles
       --bridge-tuck    how far each band hides behind its own tile
       --bridge-overlap half the width of the resulting overprint band */
  .standoff--bridge {
    --bridge-gap: clamp(2.5rem, 6vw, 4rem);
    --bridge-tuck: clamp(1rem, 3vw, 1.75rem);
    --bridge-overlap: clamp(0.85rem, 2.2vw, 1.4rem);
  }

  /* Slots sit above the ink bands so the bands read as passing behind the
     tiles. Positioning them is also what keeps the bands from painting over
     the tiles: absolutely-positioned siblings would otherwise win paint order
     against in-flow blocks. */
  .standoff__slot {
    position: relative;
    z-index: 1;
    display: grid;
    place-items: center;
    flex: 0 0 auto;
  }

  /* ---- Game board ------------------------------------------------------ */
  .board {
    display: grid;
    gap: var(--space-5);
    justify-items: center;
    width: 100%;
  }

  .board__rule {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--space-2) var(--space-3);
    text-align: center;
  }

  /* ---- Overlays -------------------------------------------------------- */
  .overlay {
    position: fixed;
    inset: 0;
    z-index: var(--z-overlay);
    display: grid;
    place-items: center;
    padding: var(--gutter);
    background-color: rgb(255 243 247 / 84%);
    backdrop-filter: blur(4px);
  }

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

  /* ---- Wide viewports -------------------------------------------------- */
  @media (width >= 48rem) {
    .screens {
      padding-block: var(--space-7);
    }

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

  /* ---- Short and wide (phone held sideways) ---------------------------
     The shell stops reserving header and footer height. Type and tile sizes
     are handled by the matching query in variables.css, because token
     overrides belong in the tokens layer. */
  @media (height <= 32rem) and (orientation: landscape) {
    .shell {
      min-height: auto;
    }

    .screens,
    .masthead {
      padding-block: var(--space-2);
    }

    .colophon {
      display: none;
    }

    .screen,
    .board,
    .hero {
      gap: var(--space-4);
    }
  }
}
