/**
 * App shell layout.
 *
 * Viewport height is declared three times, last-valid-wins:
 *   100vh   legacy fallback
 *   100svh  small viewport — never taller than the visible area, so the layout
 *           cannot overflow behind mobile browser chrome
 *   100dvh  dynamic viewport — fills the height actually available right now,
 *           tracking the address bar as it collapses so no dead gap is left
 * The net effect on modern mobile browsers is a game that always fills the
 * screen exactly, with no scrollbar and no dead space (spec §11).
 *
 * The "touch layout" (stacked panels + bottom control bar) is used for narrow
 * OR portrait OR coarse-pointer viewports, so a landscape tablet still gets
 * on-screen controls rather than a keyboard-only desktop layout it can't drive.
 */

.app {
  height: 100vh;
  height: 100svh;
  height: 100dvh;
  padding: var(--sp-4);
  gap: var(--sp-4);
  display: grid;
  container-type: inline-size;
  align-items: center;
  justify-content: center;

  /* Wide default: hold | field | next over stats. */
  grid-template-columns: var(--panel-w) auto var(--panel-w);
  grid-template-rows: auto auto;
  grid-template-areas:
    "hold field next"
    "hold field stats";
}

.panel--hold  { grid-area: hold;  align-self: start; }
.panel--next  { grid-area: next;  align-self: start; }
.panel--stats { grid-area: stats; align-self: start; }
.field        { grid-area: field; }

/* Hidden on desktop; the touch layout below reveals it. */
.controls { display: none; }

/* The playfield drives the whole layout: it takes whatever vertical room is
   left, and its 1:2 aspect ratio decides how wide everything else may be. */
.field {
  height: 100%;
  min-height: 0;
  display: grid;
  place-items: center;
}

.field__slab {
  height: 100%;
  aspect-ratio: 1 / 2;
  padding: var(--sp-2);
  background: var(--slab-bg);
  border: 1px solid var(--border-subtle);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-3), var(--shadow-glow);
  backdrop-filter: blur(2px);
}

/* All three canvases occupy the same grid cell, z-ordered by DOM order. */
.field__stack {
  position: relative;
  height: 100%;
  display: grid;
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--well-bg);
  touch-action: none;   /* scoped here so dialogs stay scrollable */
}

.field__stack > .layer {
  grid-area: 1 / 1;
  width: 100%;
  height: 100%;
}

/* Touch layout: panels collapse to a top bar, controls pin to the bottom.
   Field takes the remaining row (minmax(0,1fr)) so nothing ever scrolls. */
@media (max-width: 900px), (orientation: portrait), (pointer: coarse) {
  .app {
    /* Three columns in the top row so hold / stats / next sit side by side.
       Previously all three shared one "topbar" cell and overlapped. */
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-rows: auto minmax(0, 1fr) auto;
    grid-template-areas:
      "hold     stats    next"
      "field    field    field"
      "controls controls controls";
    padding: var(--sp-2);
    gap: var(--sp-2);
  }

  /* Panels keep their base grid-area names (hold/stats/next), which now map to
     the three top-row columns. */

  /* Compact preview sizing and panel overrides live in components.css, after the desktop default,
     so source order lets it win — a media query adds no specificity. */

  .controls { grid-area: controls; display: flex; }

  .field__slab { padding: var(--sp-1); }
}

/* Very short viewports (landscape phones): reclaim every vertical pixel. */
@media (max-height: 520px) {
  .app { padding: var(--sp-1); gap: var(--sp-1); }
  .panel__label { display: none; }
}
