@layer layout {

  html:has(.viewer),
  html:has(.viewer) body {
    height: 100%;
    overflow: hidden;
    overscroll-behavior: none;
    touch-action: manipulation;
    /* Solid colour first: Safari tints its toolbar / bottom inset from it (white without one). */
    background: var(--color-canvas) radial-gradient(ellipse at 45% 40%, var(--color-canvas-glow), var(--color-canvas)) no-repeat;
  }

  /* Large-viewport height (+ the iOS home-screen shortfall) so the scene also paints
     behind Safari's bottom toolbar area, which a fixed inset: 0 box stops short of. */
  .viewer__stage,
  .viewer__labels {
    position: fixed;
    top: 0;
    left: 0;
    right: var(--panel-width);
    height: 100vh;
    height: 100lvh;
  }

  .viewer__stage canvas {
    display: block;
  }

  .viewer__labels {
    pointer-events: none;

    /* Each label its own compositor layer, sealed off from the rest: three moves every one each frame
       (CSS2DRenderer), which otherwise repaints the lot — on a big house it halved the frame rate. */
    &>* {
      will-change: transform;
      contain: layout style paint;
    }
  }

  /* Over the 3D view (left of the panel), three columns: the side (HUD, tools, rooms) | workspace
     tabs | gizmo. It lets clicks through to the scene; only its controls take them. */
  .viewer__top {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    right: var(--panel-width);
    z-index: 5;
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: start;
    gap: 12px;
    padding: calc(12px + env(safe-area-inset-top)) 12px calc(12px + env(safe-area-inset-bottom)) calc(14px + env(safe-area-inset-left));
    pointer-events: none;

    & button {
      pointer-events: auto;
    }
  }

  /* The left column, top to bottom of the view: HUD, the drawing tools, then (pushed down) the rooms
     and the floor layout. The room list gives way when the screen is short. */
  .viewer__side {
    align-self: stretch;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
    min-height: 0;
  }

  .viewer__side-end {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
    min-height: 0;
    margin-top: auto;

    &>* {
      pointer-events: auto;
    }
  }

  /* Navigation gizmo (and, on phones, the panel button), in the row's right column. */
  .viewer__corner {
    grid-column: 3;
    justify-self: end;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 8px;
  }

  .viewer__hud {
    text-shadow: 0 1px 2px color-mix(in oklch, var(--black) 60%, transparent);
  }

  .viewer__view-name {
    font-size: 14px;
  }

  /* Which room is focused; a click (or / or Esc) goes back to the whole floor. */
  .focus-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: 4px;
    padding: 3px 10px;
    font-size: 12px;
    color: var(--color-ink);
    text-shadow: none;
    background: var(--color-primary-surface);
    border: 1px solid var(--color-primary);
    border-radius: 999px;
    cursor: pointer;
  }

  .focus-chip__exit {
    color: var(--color-ink-muted);
  }

  .viewer__hint {
    margin-top: 2px;
    color: var(--color-ink-muted);
    font-size: 12px;
  }

  @media (max-width: 760px) {
    .viewer__hint {
      display: none;
    }

    .viewer__top {
      right: 0;
      padding: calc(10px + env(safe-area-inset-top)) calc(10px + env(safe-area-inset-right)) 0 calc(14px + env(safe-area-inset-left));
    }

    /* The panel opens full screen over the scene here, so the scene takes the whole width. */
    .viewer__stage,
    .viewer__labels {
      right: 0;
    }
  }
}
