.gp-grid{display:grid;grid-template-columns:minmax(320px,420px) 1fr;gap:28px;align-items:start}

.gp-controls{display:flex;flex-direction:column;gap:16px;min-width:0}

.gp-row{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.gp-row-3{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
@media (max-width:380px){.gp-row-3{grid-template-columns:1fr 1fr}}

.gp-check{display:flex;align-items:center;gap:10px;font-size:.88rem;color:var(--text);cursor:pointer;line-height:1.4}
.gp-check input{flex:none;width:18px;height:18px}

.gp-hint{font-size:.8rem;color:var(--muted-2);margin-top:2px}

.gp-summary{font-size:.88rem;color:var(--muted);background:var(--card-2);border:1px solid var(--line);border-radius:10px;padding:10px 14px}

.gp-actions{display:flex;gap:10px;flex-wrap:wrap}
.gp-actions .btn{flex:1 1 auto;min-width:140px}

.gp-stage{display:flex;align-items:center;justify-content:center;min-height:320px;min-width:0;
  background:var(--card);border:1px solid var(--line);border-radius:14px;padding:20px;
  box-shadow:var(--shadow-lg,0 20px 50px -20px rgba(0,0,0,.6))}

/* A <canvas> is a replaced element: its `width`/`height` attributes (the drawing-buffer size,
   which render() sets to CSS-size × devicePixelRatio for crisp HiDPI output) count as intrinsic
   size for grid/flex layout, independent of `style.width`. Without min-width:0 + max-width:100%
   here, a phone's devicePixelRatio (often 2-3x) inflates that intrinsic size enough to push this
   grid item — and the whole single-column mobile layout — wider than the viewport. */
.gp-stage canvas{display:block;min-width:0;max-width:100%;height:auto;
  border-radius:4px;box-shadow:0 10px 30px -12px rgba(0,0,0,.5);background:#fff}

/* Mobile: this block is deliberately AFTER every base .gp-stage/.gp-controls rule above so its
   overrides actually win the cascade (same specificity + later source order) instead of being
   silently clobbered back by the base rules. An A4/Letter preview at full mobile width is ~1.4x
   taller than it is wide — left uncapped, the sticky preview alone was consuming an entire phone
   screen (confirmed via screenshot: ~700px of preview before a single control was reachable),
   forcing a "scroll past a full page of blank grid paper to find the settings" experience. Capping
   both the sticky stage AND the canvas's own max-height makes the browser's standard replaced-
   element auto-sizing (width/height both auto + max-width/max-height) shrink the page preview to
   fit a small letterboxed strip instead, so controls are one short scroll away. */
@media (max-width:860px){
  .gp-grid{grid-template-columns:1fr;gap:0}
  .gp-controls{padding-top:16px}
  .gp-stage{order:-1;position:sticky;top:66px;z-index:5;min-height:0;max-height:38vh;
    background:var(--bg);padding:14px 12px 16px;border-bottom:1px solid var(--line);
    border-left:none;border-right:none;border-top:none;border-radius:0;box-shadow:none}
  .gp-stage canvas{max-height:calc(38vh - 30px)}
}
