.workbench {
  --wb-cols: 272px minmax(0, 1.15fr) minmax(0, 1fr);
  --wb-cols-lg: 256px minmax(0, 1.1fr) minmax(0, 1fr);
  --wb-cols-md: minmax(0, 1fr) minmax(0, 1fr);
}

/* Meshes: each drop names its file on one line and its first problem on the next. */
.drop-copy small.mesh-file { padding-bottom: 0; }
.drop-copy small.mesh-health { min-height: 1.35em; color: var(--dim); }
.drop.has-file .drop-copy small.mesh-health { color: var(--ok); }
.drop.has-file .drop-copy small.mesh-health.is-note { color: var(--muted); }
.drop.has-file .drop-copy small.mesh-health.is-error { color: var(--error); }
.drop .mono-label { margin-left: 4px; }
.drop:has(input:disabled) { cursor: not-allowed; opacity: .55; }
.drop:has(input:disabled) input[type="file"] { cursor: not-allowed; }
.test-pair { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--sp-3); margin-top: var(--sp-3); }
.test-pair select { min-width: 0; }

/* Maps: a check per map; the encoding and ray groups show only when a map that uses them is ticked. */
.check-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px 10px; padding-bottom: var(--sp-3); }
.check-list .check { min-width: 0; }
.check-list .check > span { overflow: hidden; text-overflow: ellipsis; }
.map-list:not(:has(input[name="map"]:is([value="normal"], [value="bent"]):checked)) #encodingGroup,
.map-list:not(:has(input[name="map"]:is([value="ao"], [value="thickness"], [value="bent"]):checked)) #rayGroup { display: none; }
/* Object space has no Y convention. */
#encodingGroup:has(input[name="space"][value="object"]:checked) #conventionRow { opacity: .45; pointer-events: none; }
.atten { --cols: 3; margin-top: var(--sp-2); }
.atten + .note { margin: var(--sp-2) 0 var(--sp-3); }
.downloads { margin-top: var(--sp-2); }
.note code { color: var(--muted); font-family: var(--font-mono); }
.downloads > :last-child:nth-child(odd) { grid-column: 1 / -1; }

/* Pane A: the map at its own aspect, and the coverage overlay the Misses check shows. */
.map-stage > canvas { position: absolute; inset: 0; object-fit: contain; }
.map-stage:not(.is-ready) > canvas, #missCanvas { display: none; }
.pane:has(#showMisses:checked) .map-stage.is-ready #missCanvas { display: block; }
.stage.is-stale > canvas { opacity: .45; }
.pane-head > .check { flex: none; }
/* A tab whose map was not baked. */
.tabs input:disabled + span { opacity: .35; }

/* Pane B: one stage, two canvases; the tabs pick the canvas and its controls. */
.view3d { touch-action: none; }
.view3d > canvas { position: absolute; inset: 0; display: none; }
.view3d:not(.is-ready) > canvas { visibility: hidden; }
.pane:has(input[name="view3d"][value="preview"]:checked) #previewCanvas,
.pane:has(input[name="view3d"][value="cage"]:checked) #cageCanvas { display: block; }
.pane:has(input[name="view3d"][value="preview"]:checked) .cage-controls,
.pane:has(input[name="view3d"][value="cage"]:checked) .preview-controls { display: none; }
#cageCanvas:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.pane-head > select { flex: none; }
.cage-controls > .toggle-row:first-child { border-top: 0; padding-top: 0; }
.cage-buttons { --cols: 3; margin: var(--sp-3) 0; }
.preview-controls > .toggle-row.is-stacked { border-top: 0; padding-top: 0; }
@supports not selector(:has(*)) {
  #previewCanvas { display: block; }
  .cage-controls { display: none; }
}

/* check.html: the backends table. */
.check .shell { padding: 24px; }
.check h1 { margin-bottom: 8px; font-size: var(--fs-2xl); }
.check #status { margin: 12px 0; color: var(--muted); font-family: var(--font-mono); font-size: var(--fs-sm); }
.check-table { border-collapse: collapse; font-family: var(--font-mono); font-size: var(--fs-xs); }
.check-table :is(td, th) { padding: 4px 10px; border-bottom: 1px solid var(--line); text-align: left; }
.check-table th { color: var(--muted); }
.check-table tr.is-error td { color: var(--error); }
