
  /* Node palette (drag-and-drop source) — canvas spec §4: labelled, 172px, single-row
     items (28x16 shape glyph + name), all of Logic and Layout above the fold at 900px. */
  #palette{width:172px; flex-shrink:0; background:var(--surface-canvas); border-right:1px solid var(--border-strong); padding:0 6px 10px; overflow-y:auto;}
  .palette-section-title{font-size:11px; font-weight:600; line-height:14px; font-stretch:var(--stretch-label); text-transform:uppercase; letter-spacing:.08em; color:var(--text-muted); margin:14px 10px 4px;}
  .palette-item{height:32px; display:flex; align-items:center; gap:8px; padding:0 10px; border-radius:var(--r-control); cursor:grab; transition:background-color var(--dur-1) var(--ease-step);}
  .palette-item:hover{background:var(--brand-50);}
  .palette-item:focus-visible{outline:2px solid var(--brand-600); outline-offset:-2px;}
  .palette-item:active{cursor:grabbing;}
  .palette-item.dragging{opacity:.4;}
  .palette-item .pi-g{display:inline-flex; flex:none; pointer-events:none;}
  .palette-item .pi-name{flex:1; min-width:0; font-size:12.5px; font-weight:500; color:var(--text-primary); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}

  /* Canvas spec §4 — #canvasArea holds the scrolling canvas plus the chrome that floats on
     it (zoom cluster, empty-canvas card), so neither scrolls or scales with the graph. */
  #canvasArea{position:relative; flex:1; min-width:0;}
  /* The drafting sheet (Drawing Set §5) — a measured grid: 1px minor lines every --grid,
     major lines every 5 x --grid, in --grid-minor/--grid-major (1.07 / 1.20 : 1 — quiet on
     purpose; #E2E8EF/#CFD8E3 were tested and too loud). background-attachment:local makes
     the grid pan WITH the graph (measured defect 3: it used to stay put while nodes moved);
     applyCanvasZoom() writes --grid (24px x zoom) and the canvas origin, and adds
     .grid-coarse below 10px so the minor layers drop out instead of turning to noise. */
  #canvasWrap{position:absolute; inset:0; overflow:auto; --grid:24px; --grid-ox:0px; --grid-oy:0px;
    background-color:var(--surface-canvas);
    background-image:
      linear-gradient(to right, var(--grid-major) 1px, transparent 1px),
      linear-gradient(to bottom, var(--grid-major) 1px, transparent 1px),
      linear-gradient(to right, var(--grid-minor) 1px, transparent 1px),
      linear-gradient(to bottom, var(--grid-minor) 1px, transparent 1px);
    background-size:calc(var(--grid) * 5) calc(var(--grid) * 5), calc(var(--grid) * 5) calc(var(--grid) * 5), var(--grid) var(--grid), var(--grid) var(--grid);
    background-position:var(--grid-ox) var(--grid-oy);
    background-attachment:local;
  }
  #canvasWrap.grid-coarse{
    background-image:linear-gradient(to right, var(--grid-major) 1px, transparent 1px), linear-gradient(to bottom, var(--grid-major) 1px, transparent 1px);
    background-size:calc(var(--grid) * 5) calc(var(--grid) * 5), calc(var(--grid) * 5) calc(var(--grid) * 5);
  }
  #canvasWrap.drop-hint{outline:2px solid var(--brand-600); outline-offset:-2px;}
  #canvasWrap.space-pan{cursor:grab;}
  #canvasWrap:focus{outline:none;} /* canvas spec §3 — Esc ladder layer 4 parks focus here (tabindex=-1, never a Tab stop) */

  #canvasTools{position:absolute; left:16px; bottom:20px; z-index:10; display:flex; gap:8px;}
  #canvasTools .ct-group{height:32px; display:flex; align-items:stretch; background:var(--surface-default); border:1px solid var(--border-control);
    border-radius:var(--r-control); overflow:hidden;}
  #canvasTools .ct-btn{width:32px; height:30px; padding:0; border:none; border-radius:0; background:transparent; color:var(--text-secondary);}
  #canvasTools .ct-btn + .ct-btn{border-left:1px solid var(--border-control);}
  #canvasTools .ct-btn:hover{background:var(--surface-sunken); color:var(--text-primary); border-color:var(--border-control);}
  #canvasTools .ct-btn:focus-visible{outline:2px solid var(--brand-600); outline-offset:-2px;}
  #canvasTools .ct-readout{width:52px; font-family:var(--font-mono); font-size:12px; font-weight:500; font-variant-numeric:tabular-nums; color:var(--text-secondary);}
  #canvasTools #compareLayerToggleBtn.active{background:var(--brand-50); color:var(--brand-700);}
  /* Empty-canvas card — centred in the visible canvas; only the button takes the pointer. */
  #emptyCanvas{position:absolute; inset:0; display:flex; align-items:center; justify-content:center; pointer-events:none; z-index:9;}
  #emptyCanvas .ec-card{width:360px; background:var(--surface-default); border:1px solid var(--border-strong); border-radius:var(--r-card);
    padding:20px 24px;}
  #emptyCanvas .ec-title{font-size:14px; font-weight:600; color:var(--text-primary);}
  #emptyCanvas .ec-body{font-size:13px; line-height:1.5; color:var(--text-secondary); margin-top:6px;}
  #emptyCanvas .ec-tour{pointer-events:auto; margin-top:14px;}
  #emptyCanvas .ec-card{position:relative;}
  #emptyCanvas .ec-title{padding-right:32px;}
  #emptyCanvas .ec-x{position:absolute; top:10px; right:10px; width:32px; height:32px; padding:0; pointer-events:auto; color:var(--text-secondary);}
