Worker Sortable Table
How this example is built
Section titled “How this example is built”This page shows a worker-based sortable table without mocks. The docs page owns the host DOM and pointer hit-testing, while the remote Vue app and row order state run inside a dedicated Web Worker.
The example has three parts:
- a host runtime that mounts
HostedTreeinto the preview area; - a remote worker app that renders table rows and handles
RemoteSortableEvent; - a live snapshot below the table that shows the current remote order after each drop.
How to use it
Section titled “How to use it”- Grab rows only by the
Draghandle in the first column. - Move a row above or below another row to change the order.
- Use
Reset tableto restore the initial queue.
Sortable table running in a dedicated Worker
Drag rows by their handle, reorder the queue inside the same table, and reset the example whenever you want to start over.
Booting dedicated Worker runtime...
This table is wired through the same host/worker transport model used by the library's public runtime APIs.
import type { Channel } from '@omnicajs/vue-remote/host'
import { createEndpoint, fromWebWorker } from '@remote-ui/rpc'import { createApp, h,} from 'vue'
import { HostedTree, createProvider, createReceiver,} from '@omnicajs/vue-remote/host'
interface SandboxWorkerApi { release (): void; run (channel: Channel, labels: SortableTableSandboxLabels): Promise<void>;}
export interface SortableTableSandboxLabels { booting: string; failed: string; ready: string; resetLabel: string; snapshotLabel: string; snapshotUnavailable?: string; unsupported: string;}
export interface SortableTableSandboxElements { rootElement: HTMLElement;}
export interface SortableTableSandboxHandle { destroy (): Promise<void>;}
export const mountSortableTableSandbox = async ( elements: SortableTableSandboxElements, labels: SortableTableSandboxLabels): Promise<SortableTableSandboxHandle> => { const { rootElement } = elements
if (typeof Worker === 'undefined') { rootElement.textContent = labels.unsupported
return { async destroy () {}, } }
rootElement.textContent = labels.booting
const receiver = createReceiver() const provider = createProvider() const host = createApp({ render: () => h(HostedTree, { provider, receiver }), }) const worker = new Worker(new URL('./remote.worker.ts', import.meta.url), { type: 'module', }) const endpoint = createEndpoint<SandboxWorkerApi>(fromWebWorker(worker)) let destroyed = false
const destroy = async () => { if (destroyed) { return }
destroyed = true
try { await endpoint.call.release() } catch { // Worker teardown should not block page cleanup. } finally { endpoint.terminate() worker.terminate() host.unmount() rootElement.innerHTML = '' } }
try { host.mount(rootElement) await endpoint.call.run(receiver.receive, labels) } catch (error) { await destroy() rootElement.textContent = `${labels.failed}: ${error instanceof Error ? error.message : String(error)}` }
return { destroy, }}import type { MessageEndpoint } from '@remote-ui/rpc'import type { Channel } from '@omnicajs/vue-remote/host'import type { RemoteSortableEvent } from '@omnicajs/vue-remote/remote'
import { createEndpoint, release, retain,} from '@remote-ui/rpc'import { RemoteDragHandle, RemoteSortableContainer, RemoteSortableItem, createRemoteRenderer, createRemoteRoot,} from '@omnicajs/vue-remote/remote'import { defineComponent, h, ref,} from 'vue'
interface RoadmapRow { accent: 'amber' | 'blue' | 'mint'; eta: string; id: string; owner: string; status: 'Blocked' | 'In review' | 'Ready'; task: string;}
interface TableSnapshot { lastAction: string; rowIds: string[];}
interface SandboxWorkerApi { release (): void; run (channel: Channel, labels: SandboxUiLabels): Promise<void>;}
interface SandboxUiLabels { booting: string; failed: string; ready: string; resetLabel: string; snapshotLabel: string; snapshotUnavailable?: string; unsupported: string;}
const endpoint = createEndpoint<SandboxWorkerApi>(self as unknown as MessageEndpoint)
const initialRows = (): RoadmapRow[] => ([ { accent: 'mint', eta: 'Today', id: 'row-1', owner: 'Dina', status: 'Ready', task: 'Publish the sortable DnD API guide', }, { accent: 'amber', eta: 'Tomorrow', id: 'row-2', owner: 'Marco', status: 'Blocked', task: 'Validate overlay geometry for table rows', }, { accent: 'blue', eta: 'Mon', id: 'row-3', owner: 'Aya', status: 'In review', task: 'Document worker sandbox behavior end to end', }, { accent: 'mint', eta: 'Wed', id: 'row-4', owner: 'Nora', status: 'Ready', task: 'Wire live examples into the docs navigation', },])
const cloneSnapshot = (rows: RoadmapRow[], lastAction: string): TableSnapshot => ({ lastAction, rowIds: rows.map(row => row.id),})
const rows = ref<RoadmapRow[]>(initialRows())const lastAction = ref('Drag rows by their handle to reorder the release queue.')let uiLabels: SandboxUiLabels = { booting: '', failed: '', ready: '', resetLabel: 'Reset table', snapshotLabel: 'Snapshot', unsupported: '',}
let releaseRemote = () => {}
const moveRow = (event: RemoteSortableEvent) => { if (!event.accepted || event.targetIndex == null) { lastAction.value = `Drop ignored for ${event.itemId}.` return }
const sourceIndex = rows.value.findIndex(row => row.id === event.itemId)
if (sourceIndex < 0) { lastAction.value = `Row ${event.itemId} was not found.` return }
const [row] = rows.value.splice(sourceIndex, 1) const nextIndex = Math.min(Math.max(event.targetIndex, 0), rows.value.length)
rows.value.splice(nextIndex, 0, row) lastAction.value = `"${row.task}" moved to position ${nextIndex + 1}.`}
const setDragStart = (row: RoadmapRow) => { lastAction.value = `Dragging "${row.task}".`}
const setDragCancel = (row: RoadmapRow) => { lastAction.value = `Drag canceled for "${row.task}".`}
const resetTable = () => { rows.value = initialRows() lastAction.value = 'Drag rows by their handle to reorder the release queue.'}
const statusClassName = (status: RoadmapRow['status']) => { switch (status) { case 'Blocked': return 'sandbox-table__status sandbox-table__status--blocked' case 'In review': return 'sandbox-table__status sandbox-table__status--review' default: return 'sandbox-table__status sandbox-table__status--ready' }}
const TableApp = defineComponent({ name: 'WorkerSortableTableSandbox',
setup () { const renderGrip = () => h('svg', { 'aria-hidden': 'true', class: 'sandbox-table__grip', fill: 'none', viewBox: '0 0 8 12', }, [ h('circle', { cx: '1.5', cy: '1.5', fill: 'currentColor', r: '1' }), h('circle', { cx: '6.5', cy: '1.5', fill: 'currentColor', r: '1' }), h('circle', { cx: '1.5', cy: '6', fill: 'currentColor', r: '1' }), h('circle', { cx: '6.5', cy: '6', fill: 'currentColor', r: '1' }), h('circle', { cx: '1.5', cy: '10.5', fill: 'currentColor', r: '1' }), h('circle', { cx: '6.5', cy: '10.5', fill: 'currentColor', r: '1' }), ])
const renderRow = (row: RoadmapRow, index: number) => { return h(RemoteSortableItem, { as: 'tr', class: `sandbox-table__row sandbox-table__row--${row.accent}`, containerId: 'release-table', 'data-testid': `sandbox-row-${row.id}`, index, itemId: row.id, onDragcancel: () => setDragCancel(row), onDragstart: () => setDragStart(row), type: 'release-row', }, { default: () => [ h('td', { class: 'sandbox-table__cell sandbox-table__cell--rank' }, [ h('div', { class: 'sandbox-table__rank-slot' }, [ h('span', { class: 'sandbox-table__rank', 'data-testid': `sandbox-rank-${row.id}`, }, `#${String(index + 1).padStart(2, '0')}`), h(RemoteDragHandle, { as: 'button', 'aria-label': `Drag ${row.task}`, class: 'sandbox-table__handle', 'data-testid': `sandbox-handle-${row.id}`, type: 'button', }, { default: renderGrip, }), ]), ]), h('td', { class: 'sandbox-table__cell' }, [ h('div', { class: 'sandbox-table__task' }, [ h('p', { class: 'sandbox-table__task-title' }, row.task), h('span', { class: 'sandbox-table__task-meta' }, row.id), ]), ]), h('td', { class: 'sandbox-table__cell' }, [ h('span', { class: 'sandbox-table__owner' }, row.owner), ]), h('td', { class: 'sandbox-table__cell' }, [ h('span', { class: 'sandbox-table__eta' }, row.eta), ]), h('td', { class: 'sandbox-table__cell' }, [ h('span', { class: statusClassName(row.status) }, row.status), ]), ], }) }
return () => h('div', { class: 'worker-table-sandbox__runtime' }, [ h('div', { class: 'worker-table-sandbox__toolbar' }, [ h('span', { class: 'worker-table-sandbox__status', 'data-sandbox-status': '', }, uiLabels.ready), h('button', { class: 'worker-table-sandbox__reset', 'data-sandbox-reset': '', onClick: resetTable, type: 'button', }, uiLabels.resetLabel), ]), h('div', { class: 'worker-table-sandbox__preview' }, [ h('div', { class: 'sandbox-table-demo' }, [ h('div', { class: 'sandbox-table-demo__toolbar' }, [ h('p', { class: 'sandbox-table-demo__eyebrow' }, 'Release queue'), h('p', { class: 'sandbox-table-demo__caption' }, lastAction.value), ]), h('div', { class: 'sandbox-table-shell' }, [ h('table', { class: 'sandbox-table', 'data-testid': 'sandbox-table', }, [ h('thead', { class: 'sandbox-table__head' }, [ h('tr', [ h('th', 'Rank'), h('th', 'Task'), h('th', 'Owner'), h('th', 'ETA'), h('th', 'Status'), ]), ]), h(RemoteSortableContainer, { as: 'tbody', accepts: ['release-row'], class: 'sandbox-table__body', containerId: 'release-table', 'data-testid': 'sandbox-table-body', onDrop: moveRow, orientation: 'vertical', }, { default: () => rows.value.map((row, index) => renderRow(row, index)), }), ]), ]), ]), ]), h('div', { class: 'worker-table-sandbox__snapshot', 'data-sandbox-snapshot-wrap': '', }, [ h('div', { class: 'worker-table-sandbox__snapshot-title' }, uiLabels.snapshotLabel), h('pre', { class: 'worker-table-sandbox__snapshot-code', 'data-sandbox-snapshot': '', }, JSON.stringify(cloneSnapshot(rows.value, lastAction.value), null, 2)), ]), ]) },})
endpoint.expose({ async run (channel: Channel, labels: SandboxUiLabels) { uiLabels = labels retain(channel)
const root = createRemoteRoot(channel) await root.mount()
const app = createRemoteRenderer(root).createApp(TableApp) app.mount(root)
releaseRemote = () => { app.unmount() release(channel) } },
release () { releaseRemote() releaseRemote = () => {} },}).worker-table-sandbox { --worker-sandbox-border: color-mix(in srgb, var(--sl-color-hairline-light) 78%, transparent); --worker-sandbox-surface: color-mix(in srgb, var(--sl-color-bg) 92%, var(--sl-color-accent-low)); margin-block: 2rem; width: 100%; max-width: 100%; min-width: 0;}
.worker-table-sandbox__layout { display: grid; gap: 1.5rem; width: 100%; max-width: 100%; min-width: 0;}
.worker-table-sandbox__surface { display: grid; gap: 1rem; width: 100%; max-width: 100%; min-width: 0;}
.worker-table-sandbox__heading { display: grid; gap: 0.45rem; margin-bottom: 1rem;}
.worker-table-sandbox__heading h2 { margin: 0; font-size: clamp(1.3rem, 1.15rem + 0.5vw, 1.7rem);}
.worker-table-sandbox__heading p,.worker-table-sandbox__note { margin: 0; color: var(--sl-color-gray-2);}
.worker-table-sandbox__toolbar { display: flex; gap: 0.75rem; align-items: center; justify-content: space-between; margin-bottom: 1rem;}
.worker-table-sandbox__status { color: var(--sl-color-gray-2); font-size: 0.92rem; font-weight: 600;}
.worker-table-sandbox__reset { border: 1px solid var(--worker-sandbox-border); border-radius: 999px; background: color-mix(in srgb, var(--sl-color-white) 7%, transparent); color: var(--sl-color-text); padding: 0.55rem 0.95rem; font: inherit; font-weight: 700; cursor: pointer; transition: transform 140ms ease, border-color 140ms ease;}
.worker-table-sandbox__reset:hover,.worker-table-sandbox__reset:focus-visible { transform: translateY(-1px); border-color: color-mix(in srgb, var(--sl-color-accent-high) 50%, var(--worker-sandbox-border));}
.worker-table-sandbox__reset:disabled { opacity: 0.55; cursor: progress; transform: none;}
.worker-table-sandbox__runtime-host { min-height: 25rem; width: 100%; max-width: 100%; min-width: 0;}
.worker-table-sandbox__runtime { display: grid; gap: 1rem; width: 100%; max-width: 100%; min-width: 0;}
.worker-table-sandbox__preview { min-height: 25rem; padding: 0; width: 100%; max-width: 100%; min-width: 0;}
.worker-table-sandbox__note { margin-top: 0.85rem; width: min(100%, var(--sl-content-width)); max-width: var(--sl-content-width); justify-self: start;}
.worker-table-sandbox__snapshot { margin-top: 1rem; width: min(100%, var(--sl-content-width)); max-width: var(--sl-content-width); min-width: 0; justify-self: start;}
.worker-table-sandbox__snapshot-title { margin-bottom: 0.45rem; font-size: 0.82rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--sl-color-gray-2);}
.worker-table-sandbox__snapshot-code,.worker-table-sandbox__code .expressive-code { margin: 0;}
.worker-table-sandbox__code { display: grid; gap: 1rem; width: min(100%, var(--sl-content-width)); max-width: var(--sl-content-width); min-width: 0; justify-self: start;}
.worker-table-sandbox__snapshot-code { overflow: auto; padding: 1rem; border-radius: 0.5rem; background: color-mix(in srgb, var(--sl-color-black) 12%, var(--sl-color-bg)); color: var(--sl-color-white); font-size: 0.82rem; line-height: 1.55;}
.worker-table-sandbox__code .tablist-wrapper { margin-bottom: 1rem; max-width: 100%; min-width: 0; overflow-x: auto;}
.worker-table-sandbox__code starlight-tabs,.worker-table-sandbox__code [role='tablist'],.worker-table-sandbox__code [role='tabpanel'] { min-width: 0; max-width: 100%;}
.worker-table-sandbox__code starlight-tabs { display: grid; min-width: 0;}
.worker-table-sandbox__code [role='tabpanel'] { margin-top: 0;}
.worker-table-sandbox__code .expressive-code,.worker-table-sandbox__code .expressive-code pre { max-width: 100%; min-width: 0;}
.worker-table-sandbox .sandbox-table-demo { display: grid; gap: 1rem; padding: 1rem; border: 1px solid var(--worker-sandbox-border); border-radius: 0.5rem; background: radial-gradient(circle at top right, color-mix(in srgb, #0ea5e9 12%, transparent), transparent 32%), linear-gradient(180deg, color-mix(in srgb, var(--worker-sandbox-surface) 96%, transparent), var(--sl-color-bg)); box-shadow: 0 1rem 2rem -1.5rem color-mix(in srgb, var(--sl-color-black) 25%, transparent);}
.worker-table-sandbox .sandbox-table-demo__toolbar { display: grid; gap: 0.4rem;}
.worker-table-sandbox .sandbox-table-demo__eyebrow { margin: 0; color: var(--sl-color-text-accent); font-size: 0.76rem; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase;}
.worker-table-sandbox .sandbox-table-demo__caption { margin: 0; color: var(--sl-color-gray-2); font-size: 0.95rem; font-weight: 600;}
.worker-table-sandbox .sandbox-table-shell { overflow-x: auto; padding-bottom: 0.25rem; border: 1px solid color-mix(in srgb, var(--sl-color-hairline-light) 72%, transparent); border-radius: 0.5rem; background: color-mix(in srgb, var(--sl-color-bg) 96%, var(--sl-color-white)); box-shadow: inset 0 1px 0 color-mix(in srgb, var(--sl-color-white) 20%, transparent);}
.worker-table-sandbox .sandbox-table { width: 100%; min-width: 48rem; border-collapse: collapse; border-spacing: 0; table-layout: fixed;}
.worker-table-sandbox .sandbox-table__head th { padding: 0.85rem; text-align: left; font-size: 0.74rem; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; color: var(--sl-color-gray-2); background: color-mix(in srgb, var(--sl-color-accent-high) 4%, var(--sl-color-bg)); border-bottom: 1px solid color-mix(in srgb, var(--sl-color-hairline-light) 72%, transparent);}
.worker-table-sandbox .sandbox-table__head th:first-child { width: 5.5rem;}
.worker-table-sandbox .sandbox-table__head th:nth-child(2) { width: 20rem;}
.worker-table-sandbox .sandbox-table__head th:nth-child(3),.worker-table-sandbox .sandbox-table__head th:nth-child(4) { width: 9rem;}
.worker-table-sandbox .sandbox-table__body { margin: 0;}
.worker-table-sandbox .sandbox-table__row,[data-dnd-overlay='true'] .sandbox-table__row { margin: 0;}
.worker-table-sandbox .sandbox-table__row--mint,[data-dnd-overlay='true'] .sandbox-table__row--mint { --sandbox-row-accent: color-mix(in srgb, #41b883 55%, transparent);}
.worker-table-sandbox .sandbox-table__row--amber,[data-dnd-overlay='true'] .sandbox-table__row--amber { --sandbox-row-accent: color-mix(in srgb, #f59e0b 55%, transparent);}
.worker-table-sandbox .sandbox-table__row--blue,[data-dnd-overlay='true'] .sandbox-table__row--blue { --sandbox-row-accent: color-mix(in srgb, #38bdf8 55%, transparent);}
.worker-table-sandbox .sandbox-table__cell,[data-dnd-overlay='true'] .sandbox-table__cell { margin: 0; padding: 0.82rem 0.85rem; vertical-align: middle; background: color-mix(in srgb, var(--sl-color-bg) 94%, var(--sl-color-white)); border-bottom: 1px solid color-mix(in srgb, var(--sl-color-hairline-light) 72%, transparent); transition: background-color 160ms ease, border-color 160ms ease, opacity 160ms ease, box-shadow 160ms ease;}
.worker-table-sandbox .sandbox-table__row td:first-child,[data-dnd-overlay='true'] .sandbox-table__row td:first-child { box-shadow: inset 3px 0 0 var(--sandbox-row-accent, transparent);}
.worker-table-sandbox .sandbox-table__body tr:last-child td { border-bottom: 0;}
.worker-table-sandbox .sandbox-table__body tr:hover td { background: color-mix(in srgb, var(--sl-color-accent-high) 3%, var(--sl-color-bg));}
.worker-table-sandbox .sandbox-table__cell--rank,[data-dnd-overlay='true'] .sandbox-table__cell--rank { padding-inline: 0.65rem;}
.worker-table-sandbox .sandbox-table__rank-slot,[data-dnd-overlay='true'] .sandbox-table__rank-slot { position: relative; display: grid; place-items: center; min-height: 2.2rem;}
.worker-table-sandbox .sandbox-table__rank,[data-dnd-overlay='true'] .sandbox-table__rank { display: inline-flex; align-items: center; justify-content: center; min-width: 2.75rem; padding: 0.35rem 0.55rem; border-radius: 999px; background: color-mix(in srgb, var(--sl-color-accent-high) 10%, transparent); color: var(--sl-color-text-accent); font-size: 0.8rem; font-weight: 800; transition: opacity 140ms ease, transform 140ms ease;}
.worker-table-sandbox .sandbox-table__handle,[data-dnd-overlay='true'] .sandbox-table__handle { display: inline-grid; place-items: center; width: 2rem; height: 2rem; padding: 0; border: 0; border-radius: 0.65rem; background: transparent; color: inherit; cursor: grab; transition: background-color 140ms ease, opacity 140ms ease, transform 140ms ease;}
.worker-table-sandbox .sandbox-table__cell--rank .sandbox-table__handle,[data-dnd-overlay='true'] .sandbox-table__cell--rank .sandbox-table__handle { position: absolute; inset: 50% auto auto 50%; opacity: 0; transform: translate(-50%, -50%) scale(0.92);}
.worker-table-sandbox .sandbox-table__row:hover .sandbox-table__rank,.worker-table-sandbox .sandbox-table__row:focus-within .sandbox-table__rank,[data-dnd-overlay='true'] .sandbox-table__rank { opacity: 0; transform: scale(0.92);}
.worker-table-sandbox .sandbox-table__row:hover .sandbox-table__cell--rank .sandbox-table__handle,.worker-table-sandbox .sandbox-table__row:focus-within .sandbox-table__cell--rank .sandbox-table__handle,[data-dnd-overlay='true'] .sandbox-table__cell--rank .sandbox-table__handle { opacity: 1; transform: translate(-50%, -50%) scale(1);}
.worker-table-sandbox .sandbox-table__handle:hover,.worker-table-sandbox .sandbox-table__handle:focus-visible,[data-dnd-overlay='true'] .sandbox-table__handle { background: color-mix(in srgb, var(--sl-color-accent-high) 8%, transparent);}
.worker-table-sandbox .sandbox-table__grip,[data-dnd-overlay='true'] .sandbox-table__grip { display: block; width: 0.72rem; height: 1.08rem; color: color-mix(in srgb, var(--sl-color-gray-3) 88%, var(--sl-color-text)); overflow: visible;}
.worker-table-sandbox .sandbox-table__task,[data-dnd-overlay='true'] .sandbox-table__task { display: grid; gap: 0.35rem;}
.worker-table-sandbox .sandbox-table__task-title,[data-dnd-overlay='true'] .sandbox-table__task-title { margin: 0; font-size: 0.98rem; font-weight: 700; line-height: 1.4;}
.worker-table-sandbox .sandbox-table__task-meta,[data-dnd-overlay='true'] .sandbox-table__task-meta { color: var(--sl-color-gray-2); font-size: 0.82rem;}
.worker-table-sandbox .sandbox-table__owner,.worker-table-sandbox .sandbox-table__eta,[data-dnd-overlay='true'] .sandbox-table__owner,[data-dnd-overlay='true'] .sandbox-table__eta { display: inline-block; color: var(--sl-color-text); font-weight: 600;}
.worker-table-sandbox .sandbox-table__status,[data-dnd-overlay='true'] .sandbox-table__status { display: inline-flex; align-items: center; padding: 0.3rem 0.65rem; border-radius: 999px; white-space: nowrap; font-size: 0.78rem; font-weight: 800; letter-spacing: 0.03em;}
.worker-table-sandbox .sandbox-table__status--blocked,[data-dnd-overlay='true'] .sandbox-table__status--blocked { background: color-mix(in srgb, #f59e0b 16%, transparent); color: color-mix(in srgb, #f59e0b 78%, var(--sl-color-text));}
.worker-table-sandbox .sandbox-table__status--ready,[data-dnd-overlay='true'] .sandbox-table__status--ready { background: color-mix(in srgb, #41b883 16%, transparent); color: color-mix(in srgb, #41b883 78%, var(--sl-color-text));}
.worker-table-sandbox .sandbox-table__status--review,[data-dnd-overlay='true'] .sandbox-table__status--review { background: color-mix(in srgb, #38bdf8 16%, transparent); color: color-mix(in srgb, #0ea5e9 82%, var(--sl-color-text));}
.worker-table-sandbox [data-dnd-dragging='true'] { visibility: hidden; opacity: 0; pointer-events: none;}
[data-dnd-overlay='true'] { --worker-sandbox-border: color-mix(in srgb, var(--sl-color-hairline-light) 78%, transparent); position: fixed; top: 0; left: 0; z-index: 9999; width: var(--dnd-overlay-width); pointer-events: none; transform: translate3d(-9999px, -9999px, 0); color: var(--sl-color-text); font: inherit;}
[data-dnd-overlay='true']::after { content: var(--worker-dragging-label); position: absolute; top: -0.65rem; right: 0; display: inline-flex; align-items: center; padding: 0.18rem 0.55rem; border-radius: 999px; background: color-mix(in srgb, var(--sl-color-accent-high) 20%, var(--sl-color-bg)); border: 1px solid color-mix(in srgb, var(--sl-color-accent-high) 42%, var(--worker-sandbox-border)); color: var(--sl-color-text-accent); font-size: 0.68rem; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; box-shadow: 0 0.6rem 1.2rem -0.9rem color-mix(in srgb, var(--sl-color-accent-high) 60%, transparent);}
[data-dnd-overlay='true'] table { width: 100%; border-collapse: collapse; border-spacing: 0; table-layout: fixed; background: color-mix(in srgb, var(--sl-color-bg) 96%, var(--sl-color-white)); border: 1px solid color-mix(in srgb, var(--sl-color-hairline-light) 72%, transparent); border-radius: 0.5rem; overflow: hidden; box-shadow: 0 1.25rem 2.4rem -1.3rem color-mix(in srgb, var(--sl-color-black) 40%, transparent);}
[data-dnd-overlay='true'] .sandbox-table__cell { background: color-mix(in srgb, var(--sl-color-bg) 97%, var(--sl-color-white));}
[data-dnd-overlay='true'] .sandbox-table__task-title,[data-dnd-overlay='true'] .sandbox-table__task-meta,[data-dnd-overlay='true'] .sandbox-table__owner,[data-dnd-overlay='true'] .sandbox-table__eta { color: inherit;}
[data-dnd-overlay='true'] .sandbox-table__handle { cursor: grabbing;}
.worker-table-sandbox [data-dnd-placeholder='true'] td { background: linear-gradient(180deg, color-mix(in srgb, var(--sl-color-accent-low) 20%, transparent), transparent), color-mix(in srgb, var(--sl-color-accent-high) 7%, var(--sl-color-bg)); border-top: 2px dashed color-mix(in srgb, var(--sl-color-accent-high) 45%, var(--worker-sandbox-border)); border-bottom: 2px dashed color-mix(in srgb, var(--sl-color-accent-high) 45%, var(--worker-sandbox-border)); box-shadow: none;}
.worker-table-sandbox [data-dnd-placeholder='true'] td > * { visibility: hidden;}
@media (max-width: 52rem) { .worker-table-sandbox .sandbox-table { min-width: 42rem; }}