/* Digital twin layer (spec §10) */
/* the 3D views' backdrop and the inventory pictures — the RAILab 3D theme (theme.js PALETTE.background, 2026-10-31) */
:root { --tw-3d-bg: linear-gradient(180deg, #faf9fc 0%, #eeedf3 100%); --tw-thumb-bg: #f5f4f8; --tw-thumb-border: #dcd6e8; }
#tw-left {
  grid-column: 1; min-width: 0; overflow: hidden; display: flex; flex-direction: column;
  min-height: 0; border-right: 1px solid #ddd; background: #fafafa;
}
#tw-left h2 { display: flex; align-items: center; justify-content: space-between; }
#tw-search { margin: 0 10px 6px; padding: 5px 8px; border: 1px solid #ccc; border-radius: 6px; font: inherit; font-size: 12.5px; }
#tw-inventory { flex: 1 1 auto; overflow: auto; margin: 0 10px; }
#tw-inventory h4 { font-size: 11px; text-transform: uppercase; color: #888; margin: 10px 0 4px; letter-spacing: .5px; }
#tw-inventory h5.inv-sub { font-size: 11px; font-weight: 600; color: #6a7f8c; margin: 8px 0 3px 2px; text-transform: capitalize; }
.inv-item {
  display: flex; align-items: center; gap: 8px; padding: 5px 7px; margin: 2px 0;
  background: white; border: 1px solid #e3e3e6; border-radius: 6px; cursor: grab; font-size: 12.5px;
}
.inv-item:hover { border-color: #2f6fdd; background: #f3f7ff; }
.inv-item .sw { width: 22px; height: 22px; border-radius: 5px; flex: 0 0 auto; background: #dfe7f5; border: 1px solid #b9c7e2; display: flex; align-items: center; justify-content: center; font-size: 11px; color: #456; overflow: hidden; }
.inv-item .sw img { width: 100%; height: 100%; object-fit: cover; }
.inv-item .sw.pic, .inv-item.holder .sw.pic { background: var(--tw-thumb-bg); border-color: var(--tw-thumb-border); }
.inv-item.container .sw { border-radius: 50%; background: #fff3e0; border-color: #e6b56a; }
.inv-item.holder .sw { background: #f1eee6; border-color: #b9ae92; }
.inv-item.accessory .sw { background: #eef7ee; border-color: #9ccc9c; }
.inv-item.accessory.sub { margin-left: 22px; font-size: 12px; border-style: dashed; }
.inv-item.accessory.sub[draggable="false"] { cursor: default; opacity: .7; }
.inv-item .nm { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.inv-item .badge { font-size: 10px; color: #2f6fdd; flex: 0 0 auto; white-space: nowrap; }
.inv-item .badge.user { color: #1e9e50; }
#tw-left .hint, .muted { color: #999; font-size: 11.5px; }
#tw-left .hint { margin: 6px 12px 10px; }
.mini { padding: 2px 8px; font-size: 12px; }
#tw-new-type { background: #2f6fdd; color: white; border: none; border-radius: 5px; cursor: pointer; }

#tw-center { grid-column: 3; min-width: 0; min-height: 0; display: flex; flex-direction: column; }
#tw-bar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 5px 10px;
  border-bottom: 1px solid #ddd; background: #f4f5f7; font-size: 12.5px; flex: 0 0 auto;
}
#tw-bar .btn { color: #1a1a1a; background: white; border-color: #ccc; }
#tw-bar .btn:hover { background: #eef3fd; }
#tw-bar .btn.danger { color: #8c2f28; }
#tw-bar input[type=number] { width: 64px; padding: 3px 5px; font: inherit; border: 1px solid #ccc; border-radius: 4px; }
#tw-bar .sep { width: 1px; height: 18px; background: #d6d8dd; }
#tw-step { width: 160px; }
.chip { padding: 2px 9px; border-radius: 10px; font-size: 12px; background: #e3e3e6; color: #444; }
.chip.ok { background: #d9f2e1; color: #1e7b40; }
.chip.fail { background: #fbe0dd; color: #a8382e; }
.chip.warn { background: #fff0cc; color: #8a6200; }
/* a refused plan: why (the joints at fault red), the suggestion (2026-10-26) */
.fail-why { margin: 4px 0 0 0; padding-left: 18px; color: #c0392b; }
.fail-why li { margin: 1px 0; }
.fail-suggest { margin-top: 4px; }
.fail-suggest .btn.mini { margin-left: 6px; }
.fail-suggest input[type=number] { width: 64px; }
.fail-found { margin-top: 3px; color: #1e8449; }
#tw-canvas-wrap, #tw-3d-wrap { flex: 1 1 auto; min-height: 0; overflow: hidden; background: #fbfbfc; position: relative; cursor: default; }
#tw-3d-wrap { background: var(--tw-3d-bg); }
#tw-canvas-wrap[hidden], #tw-3d-wrap[hidden] { display: none; }
#tw-canvas-wrap.dropping, #tw-3d-wrap.dropping { outline: 3px dashed #2f6fdd; outline-offset: -3px; }
#tw-3d-wrap canvas { display: block; touch-action: none; }
#tw-bar .seg { display: inline-flex; }
#tw-bar .seg .btn { border-radius: 0; }
#tw-bar .seg .btn:first-child { border-radius: 5px 0 0 5px; }
#tw-bar .seg .btn:last-child { border-radius: 0 5px 5px 0; }
#tw-bar .seg .btn.active { background: #2f6fdd; color: white; border-color: #2f6fdd; }
/* THE PUBLIC SITE / THE EMBED (operator 2026-11-02, tester 031): the bench / table size shown but greyed (twin.js
   sizeLocked disables the fields; the public server refuses a size change), and Send to Digital twin ▶ = the
   Layout tab's main action in railab.io's purple (a button style only — the 3D PALETTE in theme.js is untouched). */
body.public #tw-bench-size, body.embed #tw-bench-size,
body.public #tw-tables .row.size-locked, body.embed #tw-tables .row.size-locked { color: #9a9ea6; cursor: not-allowed; }
body.public #tw-bar input[type=number]:disabled, body.embed #tw-bar input[type=number]:disabled,
body.public #tw-tables .row.size-locked input:disabled, body.embed #tw-tables .row.size-locked input:disabled {
  background: #eceef1; color: #9a9ea6; border-color: #d6d8dd; cursor: not-allowed;
}
body.public #tw-bar #tw-send-motion, body.embed #tw-bar #tw-send-motion {
  background: #3800B7; border-color: #3800B7; color: #fff; font-weight: 700; font-size: 14.5px;
  padding: 7px 16px; border-radius: 7px; box-shadow: 0 1px 3px rgba(56, 0, 183, 0.35);
}
body.public #tw-bar #tw-send-motion:hover, body.embed #tw-bar #tw-send-motion:hover { background: #4a14d1; border-color: #4a14d1; }
body.public #tw-bar #tw-send-motion:focus-visible, body.embed #tw-bar #tw-send-motion:focus-visible {
  outline: 2px solid #3800B7; outline-offset: 2px;
}
body.public #tw-bar #tw-send-motion:disabled, body.embed #tw-bar #tw-send-motion:disabled {
  background: #b9addf; border-color: #b9addf; color: #f3f0fb; box-shadow: none; cursor: not-allowed;
}
#tw-canvas { width: 100%; height: 100%; display: block; }
#tw-canvas text { font-family: system-ui, "Segoe UI", sans-serif; user-select: none; pointer-events: none; }
#tw-canvas .bench { fill: white; stroke: #b8bcc4; stroke-width: 2; }
#tw-canvas .grid { stroke: #eef0f3; stroke-width: 1; }
#tw-canvas g.pl { cursor: move; }
#tw-canvas g.pl.locked { cursor: pointer; }
#tw-canvas g.pl.locked .body { stroke-dasharray: 8 4; }
#tw-canvas g.pl text.lock { fill: #8a6d00; font-weight: 600; }
#tw-canvas g.pl .body { fill: #e9eef8; stroke: #5b7fbf; stroke-width: 2; }
#tw-canvas g.pl.container .body { fill: #fff3e0; stroke: #e0953a; }
#tw-canvas g.pl.holder .body { fill: #f1eee6; stroke: #9a8f74; }
#tw-canvas g.pl.accessory .body { fill: #eef7ee; stroke: #5aa65a; }
#tw-canvas g.pl.selected .body { stroke: #ff3b30; stroke-width: 3; }
#tw-canvas g.pl.busy .body { fill: #d8e8ff; }
#tw-canvas g.pl.open .body { stroke-dasharray: 8 5; }
#tw-canvas .slot { fill: white; stroke: #5b7fbf; stroke-width: 1.5; stroke-dasharray: 3 3; }
#tw-canvas .slot.full { fill: #fbe9d2; }
#tw-canvas .reach { fill: #2f6fdd; fill-opacity: .035; stroke: #2f6fdd; stroke-opacity: .35; stroke-dasharray: 10 6; }
#tw-canvas .label { font-size: 18px; fill: #1a1a1a; text-anchor: middle; }
#tw-canvas .sub { font-size: 14px; fill: #666; text-anchor: middle; }
#tw-canvas .wf { font-size: 16px; font-weight: 600; fill: #a85f12; text-anchor: middle; }
#tw-canvas .xfer { stroke: #E67E22; stroke-width: 4; fill: none; marker-end: url(#tw-arrow); }
#tw-canvas .badge-fail { fill: #c0392b; }
#tw-canvas g.pl .acc { fill: #eef7ee; stroke: #5aa65a; stroke-width: 2; }
#tw-canvas text.acc { fill: #3b7d3b; font-size: 12px; }
#tw-right .checks label { display: block; font-size: 12px; margin: 2px 0; }
#tw-right .checks input { width: auto; margin-right: 5px; }
#tw-canvas g.pl.fail .body { stroke: #c0392b; }

#tw-right { grid-column: 5; min-width: 0; overflow: hidden; border-left: 1px solid #ddd; display: flex; flex-direction: column; min-height: 0; }
#tw-right h3 { font-size: 14px; margin: 4px 0 8px; }
#tw-right h4 { font-size: 11px; text-transform: uppercase; color: #888; margin: 12px 0 4px; }
#tw-right .row { display: grid; grid-template-columns: 110px 1fr; align-items: center; gap: 8px; margin: 6px 0; font-size: 12.5px; }
#tw-right .row label { color: #666; text-align: right; }
#tw-right input, #tw-right select, #tw-right textarea { width: 100%; padding: 5px 7px; font: inherit; border: 1px solid #ccc; border-radius: 5px; }
#tw-right .pair { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
#tw-right .row.buttons { display: flex; gap: 8px; grid-template-columns: none; margin-top: 12px; flex-wrap: wrap; }
#tw-right .btn { color: #1a1a1a; background: white; border-color: #ccc; }
#tw-right .btn.primary { background: #2f6fdd; color: white; border-color: #2f6fdd; }
#tw-right .btn.danger { background: #8c2f28; color: white; border-color: #8c2f28; }
.caps { font-size: 12px; color: #555; margin: 8px 0; }
.caps li { margin: 2px 0; }
#tw-report { list-style: none; padding: 0; margin: 6px 0; font-size: 12.5px; }
#tw-report li { padding: 5px 8px; border-left: 3px solid #ccc; margin: 3px 0; background: #fafafa; border-radius: 0 5px 5px 0; cursor: pointer; }
#tw-report li.ok { border-color: #1e9e50; }
#tw-report li.warn { border-color: #e6a700; background: #fffbea; }
#tw-report li.fail { border-color: #c0392b; background: #fdf1ef; }
#tw-report li b { font-family: ui-monospace, Consolas, monospace; }
#tw-cp-active { font-family: ui-monospace, Consolas, monospace; font-size: 12px; padding-left: 18px; }
/* the Tables tab (MULTI-TABLE, 2026-10-29): one card per harness table */
#tw-tables .tcard { border: 1px solid #e3e5ea; border-radius: 6px; padding: 4px 8px; margin: 8px 0; }
#tw-tables .tcard .row.buttons { justify-content: space-between; align-items: center; margin-top: 4px; }
#twtab-sim table { width: 100%; border-collapse: collapse; font-size: 12px; }
#twtab-sim th { text-align: left; color: #777; font-size: 11px; text-transform: uppercase; border-bottom: 1px solid #ddd; padding: 3px; }
#twtab-sim td { padding: 3px; border-bottom: 1px solid #f0f0f2; vertical-align: top; }
#tw-lib-3d { width: 100%; height: 300px; background: var(--tw-3d-bg); border: 1px solid #ddd; border-radius: 6px; overflow: hidden; position: relative; }
#tw-lib-3d canvas { display: block; touch-action: none; }
#tw-lib-json { height: 260px; font-family: ui-monospace, Consolas, monospace; font-size: 11.5px; }
#tw-lib-json-wrap summary { cursor: pointer; font-size: 12.5px; margin: 8px 0 4px; }
#tw-up-result { margin: 4px 0 8px; white-space: pre-wrap; }

/* mating-point editor (Library tab, on the type) */
#tw-mate-table { width: 100%; border-collapse: collapse; font-size: 11.5px; }
#tw-mate-table th { text-align: left; color: #777; font-size: 10.5px; text-transform: uppercase; border-bottom: 1px solid #ddd; padding: 2px 3px; }
#tw-mate-table td { padding: 2px 2px; vertical-align: middle; }
#tw-mates-wrap { overflow-x: auto; }                    /* a narrow panel scrolls the table instead of crushing it */
#tw-mate-table { min-width: 360px; }
#tw-mate-table .tripbox { display: grid; grid-template-columns: repeat(3, minmax(48px, 1fr)); gap: 2px; min-width: 150px; }
#tw-mate-table input[type=number]::-webkit-inner-spin-button, #tw-mate-table input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
#tw-mate-table td.idkind { width: 76px; }
#tw-mate-table input[data-f="id"] { width: 74px; }
#tw-mate-table .role { margin-top: 2px; line-height: 1.25; }
#tw-mate-table .role select { width: 74px; }
#tw-mate-table .role { color: #666; font-size: 11px; }
#tw-mate-table td.trip .dir { grid-column: 1 / -1; font-size: 10.5px; color: #666; display: flex; flex-wrap: wrap; gap: 2px 4px; align-items: center; }
#tw-mate-table td.trip .dir button { padding: 0 4px; font-size: 10px; }
#tw-mate-table td.trip .dir .az { color: #1e6fe0; }
#tw-mate-table td.trip .dir .ax { color: #e53935; }
#tw-mate-table tr.sel td { background: #fff4d6; }
#tw-mate-table tr.holds, #tw-mate-table tr.driven, #tw-mate-table tr.aux { cursor: pointer; }
#tw-mate-table td.partners .chip { display: inline-block; margin: 1px 2px 1px 0; font-size: 11px; }
#tw-mate-table td.partners .chip button { border: 0; background: none; padding: 0 2px; cursor: pointer; color: #888; }
#tw-mate-table td.partners .chip input.req { width: 8em; font-size: 11px; padding: 0 3px; margin: 0 2px; }
#tw-mate-table td.partners .partner-add { display: flex; gap: 2px; margin-top: 2px; }
#tw-mate-table td.partners select { min-width: 0; max-width: 100%; font-size: 11px; }
#tw-mate-table tr.driven td.muted, #tw-mate-table tr.held td.muted { font-size: 11px; }
#tw-mate-table tr.held .role { color: #a85f12; font-weight: 600; }
#tw-mate-table input { padding: 3px 4px; font-size: 11.5px; min-width: 0; }
#tw-mate-table input[readonly] { background: #f4f5f7; color: #666; }
#tw-mate-table input[type=number] { -moz-appearance: textfield; }
#tw-mate-table .row-del { border: none; background: none; color: #999; cursor: pointer; font-size: 13px; }
#tw-mate-table .row-del:hover { color: #c0392b; }
#tw-lib-mates .pickbar { align-items: center; margin-top: 8px; }
#tw-lib-mates .pickbar .inline { font-size: 12px; color: #666; display: inline-flex; gap: 4px; align-items: center; }
#tw-lib-mates .pickbar select { width: auto; padding: 3px 4px; font-size: 12px; }
#tw-lib-mates .btn.active { background: #2f6fdd; color: white; border-color: #2f6fdd; }
#tw-pick-hint { min-height: 16px; margin-top: 4px; }
#tw-pick-hint:not(:empty) { color: #2f6fdd; }

/* joint sliders of an articulated type (Library tab, preview) */
#tw-lib-joints { margin: 6px 0 2px; }
#tw-lib-joints .jrow { display: grid; grid-template-columns: 86px 1fr 64px 28px; gap: 6px; align-items: center; font-size: 12px; margin: 3px 0; }
#tw-lib-joints .jrow label { color: #666; text-align: right; }
#tw-lib-joints .jrow input[type=number] { padding: 2px 4px; font-size: 11.5px; }
#tw-lib-joints .pose { margin: 4px 0 8px; padding: 6px 8px; border: 1px solid #e0e0e4; border-radius: 6px; background: #fafbff; }
#tw-lib-joints .posegrid { display: grid; grid-template-columns: repeat(4, 28px 1fr); gap: 4px 6px; align-items: center; font-size: 12px; margin-top: 4px; }
#tw-lib-joints .posegrid label { color: #666; text-align: right; }
#tw-lib-joints .posegrid input { padding: 2px 4px; font-size: 11.5px; min-width: 0; }
#tw-pose-result { margin-top: 4px; font-size: 11.5px; min-height: 14px; }
#tw-pose-result.warn { color: #a8382e; }

/* AprilTag editor (Library tab) + 2D tag squares */
#tw-tag-editor { margin: 6px 0; padding: 6px 8px; border: 1px solid #d9cde8; border-radius: 6px; background: #faf7fd; font-size: 12px; }
#tw-tag-editor .taggrid { display: grid; grid-template-columns: 70px 1fr 70px 1fr; gap: 4px 6px; align-items: center; margin: 4px 0; }
#tw-tag-editor .taggrid label { color: #666; text-align: right; }
#tw-tag-editor .taggrid input, #tw-tag-editor .taggrid select { padding: 2px 4px; font-size: 11.5px; min-width: 0; width: 100%; }
#tw-tag-editor .warn, #tw-mate-table .warn { color: #a8382e; }
#tw-mate-table tr.tag .role { color: #8e44ad; }
#tw-mate-table tr.editing td { background: #f3ecfa; }
#tw-mate-table .row-edit { border: 1px solid #c9b8dc; background: white; border-radius: 4px; cursor: pointer; font-size: 11px; padding: 1px 5px; margin-left: 4px; }
#tw-canvas g.pl .tag { fill: white; stroke: #8e44ad; stroke-width: 1.5; }

/* Library tab sections */
details.libsec { margin: 8px 0; border: 1px solid #e0e0e4; border-radius: 6px; padding: 2px 8px 6px; background: #fcfcfd; }
details.libsec > summary { cursor: pointer; font-size: 12.5px; font-weight: 600; padding: 5px 0; color: #333; }
details.libsec .secnote { margin: 2px 0 6px; }
details.libsec[hidden] { display: none; }

/* ------------------------------------------------ digital twin in motion (spec §10.6) */
#motion-main { grid-template-columns: var(--lw, 320px) 6px 1fr; }
#mo-left { grid-column: 1; overflow: auto; padding: 0 0 12px; border-right: 1px solid #e3e4e8; background: #fafafb; }
#mo-left h2 { margin: 10px 12px; font-size: 15px; }
#mo-left h3 { margin: 0 0 6px; font-size: 13px; }
#mo-left .mo-box { margin: 8px 12px; padding: 10px; border: 1px solid #e3e4e8; border-radius: 6px; background: white; }
#mo-left .mo-box .row.buttons { display: flex; gap: 6px; margin: 8px 0; }
#mo-left label.inline { display: flex; align-items: center; gap: 6px; margin: 6px 0; font-size: 12px; }
#mo-snapshot .lock { color: #8a6d00; font-weight: 600; }
#mo-center { grid-column: 3; min-width: 0; min-height: 0; display: flex; flex-direction: column; }
#mo-bar { display: flex; align-items: center; gap: 10px; padding: 6px 10px; border-bottom: 1px solid #e3e4e8; background: white; }
#mo-3d-wrap { flex: 1 1 auto; min-height: 0; overflow: hidden; background: var(--tw-3d-bg); position: relative; }
#mo-3d-wrap canvas { display: block; }

/* real harness (spec §10.7): link box, control cards, settings modal */
#harness-modal { position: fixed; inset: 0; z-index: 50; background: rgba(0, 0, 0, 0.45); display: flex; align-items: center; justify-content: center; }
#harness-modal[hidden] { display: none; }
#hz-result { min-height: 18px; font-size: 12px; margin-top: 6px; }
#hz-found { font-size: 12px; }
#hz-found .hz-found-row { margin: 4px 0; }
#hz-found .ok { color: #1e9e50; }
#hz-found .err { color: #c0392b; }
#hz-result.ok, .hz-msg.ok, .hz-card .ok { color: #1e9e50; }
#hz-result.err, .hz-msg.err, .hz-card .err { color: #c0392b; }
#mo-harness .warn { color: #b26a00; font-size: 12px; margin-top: 4px; }
.hz-stopall { width: 100%; margin: 6px 0 10px; padding: 12px 0; font-size: 15px; font-weight: 800; letter-spacing: 0.5px; border-radius: 8px; }
.hz-mod { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 4px 0; }
#mo-hz-msg { min-height: 16px; margin-top: 4px; }
.btn.danger { background: #d93025; border-color: #b3261e; color: white; }
.btn.danger:disabled { background: #e8a5a0; border-color: #e8a5a0; }
.chip.hz-control, .hz-state.ok { background: #e3f6e9; color: #1e7e40; }
.chip.hz-view, .hz-state.busy { background: #fff4d6; color: #8a6d00; }
.chip.hz-error, .chip.hz-off, .hz-state.bad { background: #fde8e6; color: #b3261e; }
#mo-cards { position: absolute; inset: 0; pointer-events: none; z-index: 20; }
.hz-card { position: absolute; pointer-events: auto; width: 360px; max-height: calc(100% - 24px); overflow: auto;
  background: white; border: 1px solid #d5d7dd; border-radius: 8px; box-shadow: 0 8px 28px rgba(0, 0, 0, 0.22); padding: 8px 10px; font-size: 12px; }
.hz-head { display: flex; align-items: center; gap: 6px; cursor: move; padding-bottom: 6px; border-bottom: 1px solid #eee; }
.hz-head .hz-state { margin-left: auto; }
.hz-x { border: none; background: none; font-size: 16px; cursor: pointer; color: #777; }
.hz-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 6px 0; }
.hz-row label.inline { display: flex; align-items: center; gap: 4px; }
.hz-bars { width: 100%; border-collapse: collapse; margin: 6px 0; }
.hz-bars td { padding: 2px 3px; white-space: nowrap; }
.hz-bars .hz-bar { width: 190px; }
.hz-bars .hz-val { width: 44px; text-align: right; font-variant-numeric: tabular-nums; }
.hz-joints th { font-weight: normal; color: #888; text-align: left; font-size: 11px; }
.hz-joints td { padding: 1px 3px; }
.hz-joints .hz-sl { width: 150px; }
.hz-joints .hz-num, .hz-card .hz-gap, .hz-card .hz-force, .hz-card .hz-speed, .hz-card .hz-off { width: 58px; }
.hz-card .hz-steps { width: 70px; }
.hz-msg, .hz-why { min-height: 16px; margin: 4px 0; }
.hz-why:empty { display: none; }
.hz-map summary { cursor: pointer; margin: 6px 0; }
.hz-map table td { padding: 2px 4px; }

/* hidden mating points (2026-10-23): greyed row, eye toggle */
#tw-mate-table tr.hidden-pt td:not(.eye) { opacity: 0.45; }
#tw-mate-table .row-eye { min-width: 24px; }
#tw-mate-table td.eye { width: 26px; text-align: center; }   /* eye over remove */
#tw-mate-table td.eye .row-del { display: block; margin: 2px auto 0; }
#tw-mate-table .row-eye.off { color: #999; }
/* grip points (2026-10-23): the gripper + depth editor in a grip point's row; a gripper's derived point is read-only */
#tw-mate-table td.partners .gripedit { display: flex; flex-wrap: wrap; gap: 3px 8px; align-items: center; font-size: 11px; }
#tw-mate-table td.partners .gripedit input { width: 56px; }
#tw-mate-table td.partners .gripedit input[type="checkbox"] { width: auto; margin: 0 3px 0 0; }
#tw-mate-table tr.derived td { color: #555; font-style: italic; }
#tw-mate-table tr.derived .role { color: #d63384; font-style: normal; }

/* find real positions of modules (spec §10.8) */
#mo-teach p { margin: 4px 0 6px; font-size: 12px; }
.tc-mod { margin: 6px 0; font-size: 12px; }
.tc-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 6px; vertical-align: -1px; border: 1px solid #8a8d94; }
.tc-dot.tc-grey { background: #b9babe; }
.tc-dot.tc-rough { background: #a6e39c; }
.tc-dot.tc-fine { background: #2f9e44; }
.tc-dot.tc-failed { background: #f0a04b; }
.tc-tag { display: inline-block; min-width: 16px; padding: 0 5px; margin-left: 3px; border-radius: 8px; font-size: 11px; text-align: center; border: 1px solid #c9cbd0; }
.tc-tag.tc-rough { background: #e3f6df; border-color: #a6e39c; }
.tc-tag.tc-fine { background: #2f9e44; border-color: #2f9e44; color: white; }
.tc-tag.tc-failed { background: #fde3c4; border-color: #f0a04b; }
#mo-teach .warn { color: #b26a00; }
#mo-teach .err { color: #c0392b; }
.tc-say { margin-top: 6px; }
.hz-he { margin-top: 10px; padding-top: 8px; border-top: 1px solid #ececf0; }
.hz-he-res.ok { color: #1e9e50; }
.hz-he-res.err { color: #c0392b; }
.hz-gc { margin-top: 10px; padding-top: 8px; border-top: 1px solid #ececf0; }
.hz-gc-gap { width: 64px; }
.hz-gc-res.ok { color: #1e9e50; }
.hz-gc-res.err { color: #c0392b; }

/* pick & lift on the real arm (spec §10.6) */
#mo-pick-info .pk-now { font-weight: 600; color: #0b5cad; }
#mo-pick-info .pk-done { color: #1e7e40; }
#mo-pick-info .warn { color: #b26a00; }
#mo-pick-info .err { color: #c0392b; }
#tw-mate-table .cappush { display: flex; flex-wrap: wrap; gap: 2px 8px; margin-top: 3px; font-size: 11px; color: #666; }   /* takes N · push in mm */
#tw-mate-table .cappush input { width: 40px; }

/* Workstations (2026-10-25): the hardware this workflow needs, highlighted with on the plate / needed */
.inv-item.need { border-color: #2f6fdd; background: #eef4ff; box-shadow: inset 3px 0 0 #2f6fdd; }
.inv-item.need.done { border-color: #1e9e50; background: #effaf3; box-shadow: inset 3px 0 0 #1e9e50; }
.inv-item .badge.needc { font-weight: 700; color: #2f6fdd; }
.inv-item.alt { border-style: dashed; border-color: #7fa3e6; }
.inv-item.need.done .badge.needc { color: #1e9e50; }
.inv-notes { margin: 10px 0; padding: 6px 8px; font-size: 11.5px; color: #8a5a00; background: #fff8e6; border: 1px solid #f0d9a0; border-radius: 6px; }
.need-why { font-size: 12px; margin: 6px 0; color: #2f4f8f; }
#tw-report li.sec { border: none; background: none; cursor: default; padding: 10px 0 2px; font-size: 11px; text-transform: uppercase; color: #888; }
#tw-report .canon { font-family: ui-monospace, Consolas, monospace; font-size: 11px; color: #777; margin-top: 2px; }
/* Chemicals: reagent -> container in a library, product -> library / trash beaker */
table.chem { width: 100%; border-collapse: collapse; font-size: 12.5px; }
table.chem td, table.chem th { padding: 4px; border-bottom: 1px solid #eee; vertical-align: top; text-align: left; }
table.chem th { font-size: 11px; color: #888; font-weight: normal; }
table.chem td:first-child { width: 45%; }
table.chem tr.todo td:first-child { box-shadow: inset 3px 0 0 #c0392b; padding-left: 7px; }

/* Hardware workshop page (workshop.html): the model large in the middle, the type editor on the right */
body[data-page="workshop"] #tw-center { padding: 8px; gap: 4px; }
body[data-page="workshop"] #tw-lib-3d { flex: 1 1 auto; height: auto; min-height: 240px; }
body[data-page="workshop"] #tw-mate-preview { flex: 0 0 auto; }
#tw-prev-3d { width: 100%; height: 260px; background: var(--tw-3d-bg); border: 1px solid #ddd; border-radius: 6px; overflow: hidden; position: relative; }
#tw-prev-3d canvas { display: block; touch-action: none; }
#tw-mate-preview .row select { max-width: 100%; }
body[data-page="workshop"] #toolbar .muted { color: #aab; font-size: 12px; }
.inv-item.current { border-color: #2f6fdd; background: #e6efff; }
.capcard { border: 1px solid #dfe3ea; border-radius: 6px; padding: 6px 8px; margin: 6px 0; background: white; }
.caphead { display: flex; justify-content: space-between; align-items: center; font-size: 12.5px; margin-bottom: 4px; }
.caprow { display: grid; grid-template-columns: 104px 1fr; gap: 6px; align-items: start; margin: 4px 0; font-size: 12px; }
.caprow > label { color: #666; text-align: right; padding-top: 4px; }
.capval { display: flex; gap: 6px; flex-wrap: wrap; min-width: 0; }
#tw-right .capval select { flex: 1 1 160px; min-width: 0; width: auto; }
#tw-right .capval input[type=number] { width: 80px; }
#tw-right .capval input.unit { width: 70px; }
.capchecks { display: flex; flex-wrap: wrap; gap: 2px 10px; padding-top: 3px; }
.capchecks label { display: inline-flex; align-items: center; gap: 3px; white-space: nowrap; }
#tw-right .capchecks input { width: auto; margin: 0; }
.capwarn { font-size: 11.5px; color: #8a5a00; background: #fff8e6; border-radius: 4px; padding: 3px 6px; margin-top: 4px; }

/* THE LAYERS VIEW (workshop, 2026-10-29; layers.js): categories · verbs · modules · containers · orchestrators */
#layers-main { grid-template-columns: minmax(0, 1fr) 340px; }
#ly-center { grid-column: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; position: relative; }
#ly-bar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 5px 10px;
  border-bottom: 1px solid #ddd; background: #f4f5f7; font-size: 12.5px; flex: 0 0 auto;
}
#ly-bar .btn { color: #1a1a1a; background: white; border-color: #ccc; padding: 3px 10px; font-size: 12.5px; }
#ly-bar .btn:hover { background: #eef3fd; }
#ly-bar label.inline { display: inline-flex; align-items: center; gap: 4px; cursor: pointer; }
#ly-search { width: 260px; padding: 4px 8px; border: 1px solid #ccc; border-radius: 6px; font: inherit; }
#ly-sum { margin-left: auto; }
#ly-heads { position: relative; height: 30px; flex: 0 0 auto; background: white; border-bottom: 1px solid #eceef2; overflow: visible; }
#ly-center { overflow: hidden; }
.ly-head { position: absolute; top: 7px; font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ly-head b { color: #333; text-transform: uppercase; font-size: 11px; letter-spacing: .6px; }
#ly-scroll { flex: 1 1 auto; min-height: 0; overflow: auto; background: #fbfbfc; }
#ly-svg { display: block; }
#ly-svg text { font-family: system-ui, "Segoe UI", sans-serif; font-size: 12px; user-select: none; }
/* nodes: the inventory's colours (module blue, container orange, accessory green) */
.ly-n { cursor: pointer; }
.ly-n rect { fill: white; stroke: #b9c7e2; stroke-width: 1; }
.ly-n .lbl { fill: #1a1a1a; pointer-events: none; }
.ly-n.l-category rect { fill: #e4ecfb; stroke: #5b7fbf; }
.ly-n.l-category.g-transfer rect { fill: #fdeedc; stroke: #e0953a; }
.ly-n.l-category .lbl { font-weight: 600; }
.ly-n.l-verb rect { fill: white; stroke: #9fb2d8; }
.ly-n.l-module rect { fill: #dfe7f5; stroke: #9fb2d8; }
.ly-n.l-container rect { fill: #fff3e0; stroke: #e6b56a; }
.ly-n.l-container.acc rect { fill: #eef7ee; stroke: #9ccc9c; }
.ly-n.l-orchestrator rect { fill: #ece6f7; stroke: #9b8bc9; }
.ly-n.wild rect { fill: white; stroke: #888; stroke-dasharray: 4 3; }
.ly-n.wild .lbl { font-style: italic; }
.ly-n.bad rect { stroke: #c0392b; stroke-width: 1.5; }
.ly-n:hover rect { stroke: #2f6fdd; stroke-width: 1.5; }
.ly-n.on rect { stroke: #2f6fdd; stroke-width: 1.6; }
.ly-n.mark rect { stroke: #e67e22; stroke-width: 2.2; }
.ly-n.sel rect { stroke: #ff3b30; stroke-width: 2.4; }
.ly-n.off { opacity: .3; }
.ly-edit { fill: #8a94a6; font-size: 12px; cursor: pointer; }
.ly-edit:hover { fill: #2f6fdd; }
/* group headers (a closed group stands for its members) */
.ly-g { cursor: pointer; }
.ly-g rect { fill: #f1f2f5; stroke: #cfd3da; stroke-width: 1; }
.ly-g:hover rect { fill: #e6ecf7; stroke: #2f6fdd; }
.ly-g .lbl { fill: #333; font-weight: 600; font-size: 11.5px; pointer-events: none; }
.ly-g .arrow { fill: #777; font-size: 10px; pointer-events: none; }
.ly-g .cnt { fill: #777; font-size: 11px; text-anchor: end; pointer-events: none; }
.ly-g.on rect { stroke: #2f6fdd; fill: #e6efff; }
.ly-g.off { opacity: .35; }
/* edges, by kind (twin/layers.py LEGEND) */
.ly-e { fill: none; stroke-opacity: .55; stroke-linecap: round; }
.ly-edges.lit .ly-e { stroke-opacity: .9; }
.ly-e.off { stroke-opacity: .07; }
.ly-e:hover { stroke-opacity: 1; }
.ly-e.k-code { stroke: #8a94a6; }
.ly-e.k-transfer { stroke: #e67e22; }
.ly-e.k-does { stroke: #2f6fdd; }
.ly-e.k-from { stroke: #1e9e50; }
.ly-e.k-to { stroke: #0f8f8f; }
.ly-e.k-seat { stroke: #8e44ad; }
.ly-e.k-seat.idle { stroke-dasharray: 5 4; }
.ly-e.k-requires { stroke: #5aa65a; stroke-dasharray: 2 3; }
.ly-e.k-grip { stroke: #d63384; }
.ly-e.k-likely { stroke: #d63384; stroke-dasharray: 6 4; stroke-opacity: .35; }
.ly-edges.lit .ly-e.k-likely { stroke-opacity: .6; }
.ly-e.k-carrier { stroke: #b07d00; stroke-dasharray: 1.5 3.5; }
#ly-tip {
  position: absolute; z-index: 30; max-width: 420px; pointer-events: none;
  background: #2b2f36; color: #eef0f3; font-size: 12px; line-height: 1.4; padding: 7px 9px; border-radius: 6px;
  white-space: pre-line; box-shadow: 0 6px 18px rgba(0, 0, 0, .25);
}
#ly-tip[hidden] { display: none; }
/* the side panel: selection, legend, findings */
#ly-right { grid-column: 2; min-width: 0; overflow: auto; border-left: 1px solid #ddd; padding: 8px 10px; font-size: 12.5px; background: #fafafa; }
#ly-right h3 { font-size: 14px; margin: 4px 0 2px; }
#ly-right .btn { color: #1a1a1a; background: white; border-color: #ccc; }
#ly-right .btn.primary { background: #2f6fdd; color: white; border-color: #2f6fdd; }
#ly-sel { border: 1px solid #e0e0e4; border-radius: 6px; padding: 4px 8px 8px; background: white; }
#ly-sel .row.buttons { display: flex; gap: 8px; margin-top: 8px; }
.ly-seltip { white-space: pre-line; color: #444; margin: 6px 0; max-height: 220px; overflow: auto; font-size: 12px; }
.ly-conn { margin-top: 4px; }
.ly-leg { display: grid; grid-template-columns: 38px 1fr; gap: 4px; align-items: start; margin: 5px 0; font-size: 12px; }
.ly-leg svg { margin-top: 4px; }
.ly-find { border-left: 3px solid #e6a700; background: #fffbea; border-radius: 0 5px 5px 0; padding: 4px 7px; margin: 5px 0; font-size: 12px; }
.ly-find.click { cursor: pointer; }
.ly-find.click:hover { background: #fff3cc; }
.ly-find.on { border-color: #e67e22; background: #ffe9d1; }
.ly-find .muted { margin-top: 2px; }
.ly-g.acc rect { fill: #eef7ee; stroke: #b5d9b5; }
.ly-g.acc:hover rect { fill: #e2f2e2; stroke: #2f6fdd; }

/* the Quote tab (2026-10-31) */
.tw-quote { width: 100%; border-collapse: collapse; margin: 6px 0; font-size: 12px; }
.tw-quote th { text-align: left; font-weight: 600; border-bottom: 1px solid #ddd; padding: 3px 4px; }
.tw-quote td { padding: 3px 4px; border-bottom: 1px solid #f0f0f2; }
.tw-quote td:nth-child(3) { white-space: nowrap; }
.tw-quote tr.unpriced td { color: #999; }
#tw-quote-summary { font-size: 14px; margin: 4px 0; }
.tw-quote-note { font-size: 11px; margin: 6px 0; }

/* the Layout tab (2026-10-31) */
.tw-layout-head { font-weight: 600; margin: 6px 0; }
.tw-layout-harness { font-size: 12px; margin: 3px 0; }
.tw-layout-warn { font-size: 12px; margin: 6px 0; color: #8c2f28; }
.tw-layout-warn ul { margin: 2px 0 0 16px; padding: 0; }
.tw-layout-incomplete { color: #8c2f28; font-weight: 600; }
.tw-layout-actions { margin: 8px 0 4px; display: flex; gap: 6px; }

/* THE LAYOUT VIEW (2026-10-31): the co-planner's proposal in the main view — read-only, framed and bannered so it never
   reads as the bench; the card over it carries the status, the harness split, Apply layout / Re-plan */
.bench-only { display: contents; }
#twin-main.plan-mode .bench-only { display: none; }
#tw-plan-wrap { flex: 1 1 auto; min-height: 0; position: relative; overflow: hidden; background: var(--tw-3d-bg);
  outline: 2px dashed #8a6cc0; outline-offset: -6px; }
#tw-plan-wrap[hidden] { display: none; }
#tw-plan-wrap.applied { outline-color: #6fb487; }
#tw-plan-3d { position: absolute; inset: 0; }
#tw-plan-3d canvas { display: block; }
.tw-plan-banner { position: absolute; top: 12px; left: 50%; transform: translateX(-50%); z-index: 5; pointer-events: none;
  padding: 3px 12px; border-radius: 12px; font-size: 12px; font-weight: 600; letter-spacing: 0.02em;
  background: #5b2c94; color: white; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.18); white-space: nowrap; }
.tw-plan-banner.applied { background: #1e7b40; }
.tw-plan-banner.stale { background: #8a6200; }
.tw-plan-card { position: absolute; top: 12px; left: 12px; z-index: 6; width: 290px; max-width: calc(100% - 24px);
  max-height: calc(100% - 24px); overflow: auto; padding: 8px 10px; font-size: 12.5px;
  background: rgba(255, 255, 255, 0.95); border: 1px solid #ddd6ea; border-radius: 6px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12); }
.tw-plan-card h3 { margin: 0 0 4px; font-size: 13px; }
.tw-plan-pick { font-size: 12px; margin: 4px 0; padding-top: 4px; border-top: 1px solid #eee; }
.spin { display: inline-block; width: 10px; height: 10px; border: 2px solid #c9bde0; border-top-color: #5b2c94; border-radius: 50%;
  animation: spin 0.9s linear infinite; vertical-align: -1px; }
/* PLANNING PROGRESS (2026-11-02): "Planning 7 / 19 — T3: …" + a thin bar (twin.js progressHtml) */
.plan-prog-line { overflow-wrap: anywhere; }
.plan-prog { height: 4px; margin: 4px 0 2px; background: #e6e0f0; border-radius: 2px; overflow: hidden; }
.plan-prog > div { height: 100%; background: #5b2c94; transition: width 0.4s ease; }

/* THE RUN PLAYER (2026-10-31): under the Digital twin's view — play / pause, speed, the scrub bar with the worksteps */
.mo-player { flex: 0 0 auto; padding: 6px 10px 6px; border-top: 1px solid #e3e4e8; background: white; font-size: 12.5px; }
.mo-player[hidden] { display: none; }
.mo-pl-row { display: flex; align-items: center; gap: 8px; }
.mo-pl-row label.inline { display: flex; align-items: center; gap: 4px; white-space: nowrap; }
.mo-pl-play { min-width: 34px; }
.mo-pl-time { font-variant-numeric: tabular-nums; white-space: nowrap; color: #444; min-width: 92px; text-align: center; }
.mo-pl-track { position: relative; flex: 1 1 auto; min-width: 80px; height: 26px; border-radius: 4px; background: #efedf4;
  cursor: pointer; touch-action: none; outline: none; }
.mo-pl-track:focus-visible { box-shadow: 0 0 0 2px #8a6cc0; }
.mo-pl-segs { position: absolute; inset: 0; overflow: hidden; border-radius: 4px; }
.mo-pl-seg { position: absolute; top: 0; bottom: 0; overflow: hidden; background: #e2dcee; border-left: 1px solid #b9a9d6; box-sizing: border-box; }
.mo-pl-seg.odd { background: #d6cde8; }
.mo-pl-seg.tail { background: #ebe9ee; border-left-style: dashed; }
.mo-pl-seg.cur { background: #c4b3e3; }
.mo-pl-mark { position: absolute; top: 1px; left: 3px; font-size: 10px; font-weight: 600; color: #4a2a7a; pointer-events: none; white-space: nowrap; }
.mo-pl-track:not(.by-ws) .mo-pl-seg { border-left-color: #c9bde0; }
.mo-pl-fill { position: absolute; left: 0; bottom: 0; height: 4px; width: 0; background: #5b2c94; border-radius: 0 0 0 4px; pointer-events: none; }
.mo-pl-head { position: absolute; top: -3px; bottom: -3px; width: 3px; margin-left: -1.5px; background: #5b2c94; border-radius: 2px;
  pointer-events: none; box-shadow: 0 0 0 1px white; }
.mo-pl-track.scrubbing .mo-pl-head { width: 5px; margin-left: -2.5px; }
.mo-pl-tip { position: absolute; bottom: calc(100% + 6px); transform: translateX(-50%); z-index: 10; pointer-events: none;
  padding: 2px 7px; border-radius: 4px; background: #2b2233; color: white; font-size: 11.5px; white-space: nowrap;
  max-width: 420px; overflow: hidden; text-overflow: ellipsis; }
.mo-pl-tip[hidden] { display: none; }
.mo-pl-now { margin-top: 4px; min-height: 16px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mo-pl-steps-box h4 { margin: 8px 0 4px; font-size: 12px; }
.mo-pl-steps { margin: 0; padding: 0; list-style: none; max-height: 260px; overflow: auto; font-size: 12px; }
.mo-pl-steps li { padding: 2px 4px; border-radius: 3px; cursor: pointer; }
.mo-pl-steps li:hover { background: #f1eef7; }
.mo-pl-steps li.cur { background: #e2dcee; }
.mo-pl-steps li .t { color: #777; font-variant-numeric: tabular-nums; margin-right: 4px; }

/* a gas-tight ENCLOSURE (G2, 2026-11-01): its outline over the whole table, the items inside stay clickable */
#tw-canvas .pl.enclosure .body, .pl.enclosure .body { fill: none; stroke-dasharray: 10 6; pointer-events: stroke; }
