/* studio-kit.css — curated component layer built on tokens.studio.css.
 * A self-contained subset of the Forge editor's visual idioms (NOT the 64 KB
 * editor.css). Mirrors: dock-panel/panel-header/title/footer/search, tree-item,
 * prop-row/prop-input/prop-section/transform-grid, center-dock-tab, buttons.
 */

* { box-sizing: border-box; margin: 0; padding: 0; }

html, body { width: 100%; height: 100%; }

body {
    overflow: hidden;
    background-color: var(--bg-1);
    color: var(--text-0);
    font-family: "Inter", "ForgeUI Studio CJK", sans-serif;
    font-size: 11px;
    user-select: none;
}

input, button, select, textarea { font: inherit; color: inherit; }

/* Accent ownership: #studio-root deliberately does NOT re-declare --primary.
 * A self-referential `--primary: var(--primary)` stood here and poisoned the
 * token on the shell root — invalid at computed-value time per CSS custom
 * properties (cycles → guaranteed-invalid), so every var(--primary) inside the
 * shell resolved to nothing. theme.mako.css owns the Mako accent on :root and
 * the shell inherits it like any other element. Locked by
 * tests/studio/css_token_cycles.test.mjs. */

/* Material Symbols icon font helper */
.ms-icon {
    font-family: "Material Symbols Outlined";
    font-weight: normal;
    font-style: normal;
    font-size: 16px;
    line-height: 1;
    letter-spacing: normal;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 1em;
    width: 1em;
    min-width: 1em;
    max-width: 1em;
    overflow: hidden;
    white-space: nowrap;
    text-transform: none;
    -webkit-font-feature-settings: "liga";
    user-select: none;
}

/* Scrollbars */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb {
    background: rgba(65, 71, 85, 0.45);
    border-radius: 6px;
    border: 2px solid transparent;
    background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: rgba(65, 71, 85, 0.7); background-clip: content-box; }
::-webkit-scrollbar-track { background: transparent; }

/* ── Dock panel ─────────────────────────────────────────────────────────── */
.dock-panel {
    display: flex;
    flex-direction: column;
    min-height: 0;
    min-width: 0;
    background: var(--bg-2);
    border: 1px solid rgba(65, 71, 85, 0.22);
    overflow: hidden;
}

.panel-header {
    display: flex;
    align-items: center;
    gap: 6px;
    height: 34px;
    padding: 0 10px;
    background: var(--bg-1);
    border-bottom: 1px solid rgba(65, 71, 85, 0.28);
    flex: 0 0 auto;
}

.panel-title {
    font-size: 10px;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-1);
    flex: 1 1 auto;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.panel-actions { display: flex; align-items: center; gap: 2px; }

.panel-body { flex: 1 1 auto; min-height: 0; overflow: auto; }

.panel-footer {
    display: flex;
    align-items: center;
    gap: 8px;
    height: 26px;
    padding: 0 10px;
    background: var(--bg-1);
    border-top: 1px solid rgba(65, 71, 85, 0.28);
    color: var(--text-2);
    font-size: 10px;
    flex: 0 0 auto;
}
.panel-footer-label { color: var(--text-2); }
.panel-footer-value { color: var(--text-1); margin-left: auto; }

.panel-search {
    display: flex;
    align-items: center;
    gap: 6px;
    height: 32px;
    padding: 0 8px;
    margin: 6px;
    background: var(--bg-3);
    border: 1px solid rgba(65, 71, 85, 0.3);
    border-radius: 4px;
    color: var(--text-2);
}
.panel-search input {
    flex: 1 1 auto;
    background: transparent;
    border: none;
    outline: none;
    color: var(--text-0);
}
.panel-search .ms-icon { font-size: 14px; color: var(--text-2); }

/* ── Buttons ────────────────────────────────────────────────────────────── */
.icon-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 24px;
    min-width: 24px;
    min-height: 24px;
    width: 24px;
    height: 24px;
    border: none;
    border-radius: 4px;
    background: transparent;
    color: var(--text-2);
    cursor: pointer;
}
.icon-btn:hover { background: rgba(33, 147, 251, 0.12); color: var(--text-0); }
.icon-btn.active { background: rgba(33, 147, 251, 0.18); color: var(--primary); }
.icon-btn.on { background: rgba(33, 147, 251, 0.18); color: var(--primary); }
.icon-btn:disabled,
.chip:disabled,
.small-primary-btn:disabled,
.dock-tab-btn:disabled,
.center-dock-tab:disabled {
    opacity: 0.45;
    cursor: default;
    filter: none;
}
.icon-btn:disabled:hover,
.chip:disabled:hover,
.small-primary-btn:disabled:hover,
.dock-tab-btn:disabled:hover,
.center-dock-tab:disabled:hover {
    background: transparent;
    color: var(--text-2);
}

/* Slice 3 — .rail-btn / .rail-label / .studio-rail rules removed with the
   vertical rail itself. The left dock tab strip uses .dock-tab-btn like the
   other docks, so no rail-specific chrome remains. */

.studio-empty-state {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin: 12px;
    padding: 14px;
    border: 1px solid rgba(65, 71, 85, 0.35);
    border-radius: 6px;
    background: rgba(255, 255, 255, 0.025);
    color: var(--text-2);
}
.insert-empty,
.prop-empty,
.jsedit-empty,
.uikit-list-empty {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin: 10px;
    padding: 12px;
    border: 1px dashed rgba(65, 71, 85, 0.42);
    border-radius: 6px;
    background: rgba(255, 255, 255, 0.018);
    color: var(--text-2);
}
.studio-empty-icon {
    font-size: 22px;
    color: var(--primary);
}
.studio-empty-title {
    color: var(--text-0);
    font-size: 12px;
    font-weight: 800;
}
.studio-empty-text {
    color: var(--text-2);
    font-size: 11px;
    line-height: 1.45;
}

.small-primary-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 28px;
    padding: 0 12px;
    border: none;
    border-radius: 4px;
    background: var(--primary-strong);
    color: #06223c;
    font-weight: 700;
    cursor: pointer;
}
.small-primary-btn:hover { filter: brightness(1.08); }
.small-primary-btn.on {
    background: var(--tertiary);
    color: #150f04;
}

.chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
    height: 24px;
    padding: 0 8px;
    background: var(--bg-3);
    border: 1px solid rgba(65, 71, 85, 0.3);
    border-radius: 4px;
    color: var(--text-1);
    cursor: pointer;
    overflow: hidden;
}
.chip:hover { border-color: rgba(33, 147, 251, 0.5); }
.chip:disabled:hover { border-color: rgba(65, 71, 85, 0.3); }
.chip.on {
    background: var(--primary-strong);
    color: #06223c;
    border-color: var(--primary-strong);
}
.breakpoint-chip {
    max-width: 150px;
}
.breakpoint-chip span:not(.ms-icon) {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* Segmented control row (visual flex/grid editor) */
.seg { display: flex; flex-wrap: wrap; gap: 4px; padding: 2px 8px 6px; }
.seg .chip { height: 22px; padding: 0 7px; font-size: 11px; }

/* ── Tree (Navigator) ───────────────────────────────────────────────────── */
/* Insert palette: searchable HTML/CSS/JS building blocks. */
.insert-toolbar {
    position: sticky;
    top: 0;
    z-index: 1;
    padding: 8px;
    background: var(--bg-2);
    border-bottom: 1px solid rgba(65, 71, 85, 0.25);
}
.insert-search {
    width: 100%;
    height: 28px;
    padding: 0 9px;
    border: 1px solid rgba(65, 71, 85, 0.35);
    border-radius: 4px;
    background: var(--bg-3);
    color: var(--text-0);
    outline: none;
}
.insert-search:focus { border-color: var(--primary-strong); }
.insert-target {
    display: flex;
    align-items: center;
    gap: 6px;
    min-height: 28px;
    margin: 8px 0 12px;
    padding: 5px 8px;
    border: 1px solid rgba(33, 147, 251, 0.38);
    border-radius: 4px;
    background: rgba(33, 147, 251, 0.09);
    color: var(--text-1);
    font-size: 11px;
    line-height: 16px;
}
.insert-target .ms-icon {
    flex: 0 0 auto;
    color: var(--primary);
    font-size: 16px;
}
.insert-target span:last-child {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.insert-smart {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding-top: 7px;
}
.insert-smart-heading {
    flex: 1 0 100%;
    color: var(--text-2);
    font-size: 9px;
    font-weight: 800;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}
.insert-smart-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 34px;
    max-width: 156px;
    padding: 4px 7px;
    border: 1px solid rgba(33, 147, 251, 0.38);
    border-radius: 4px;
    background: rgba(33, 147, 251, 0.10);
    color: var(--text-0);
    cursor: pointer;
}
.insert-smart-btn:hover {
    border-color: rgba(33, 147, 251, 0.65);
    background: rgba(33, 147, 251, 0.16);
}
.insert-smart-btn .ms-icon {
    flex: 0 0 auto;
    color: var(--primary);
    font-size: 14px;
}
.insert-smart-text {
    display: flex;
    flex-direction: column;
    justify-content: center;
    /* The two explicit line boxes are 12px + 11px. A fixed composed height
       lets the button's align-items:center place the visible glyph group;
       align-self:stretch made max-width templates start at the top edge in
       ForgeUI's flex pass even though the empty container itself was centred. */
    flex: 1 1 auto;
    height: 23px;
    min-width: 0;
}
.insert-smart-btn strong,
.insert-smart-btn small {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.insert-smart-btn strong {
    display: block;
    font-size: 10px;
    font-weight: 800;
    line-height: 12px;
}
.insert-smart-btn small {
    display: block;
    color: var(--text-2);
    font-size: 9px;
    line-height: 11px;
}
.insert-tabs {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px;
    padding-top: 7px;
    overflow-x: visible;
}
.insert-meta {
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: 20px;
    padding-top: 6px;
    color: var(--text-2);
    font-size: 10px;
}
.insert-meta-scope {
    min-width: 0;
    max-width: 140px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text-1);
}
.insert-meta-count {
    margin-left: auto;
    color: var(--primary);
    font-weight: 800;
}
.insert-tab {
    flex: 0 0 auto;
    height: 22px;
    padding: 0 8px;
    border: 1px solid rgba(65, 71, 85, 0.38);
    border-radius: 4px;
    background: var(--bg-3);
    color: var(--text-2);
    font: inherit;
    font-size: 10px;
    font-weight: 700;
    cursor: pointer;
}
.insert-tab:hover { color: var(--text-0); border-color: rgba(33, 147, 251, 0.45); }
.insert-tab.active {
    background: rgba(33, 147, 251, 0.18);
    border-color: rgba(33, 147, 251, 0.55);
    color: var(--primary);
}
.insert-cat-heading {
    padding: 8px 10px 4px;
    color: var(--text-2);
    text-transform: uppercase;
    font-size: 9px;
    font-weight: 800;
    letter-spacing: 0.06em;
}
.insert-empty {
    display: none;
    margin: 16px 8px;
    padding: 16px 12px;
    border: 1px dashed rgba(65, 71, 85, 0.45);
    border-radius: 6px;
    color: var(--text-2);
    text-align: center;
    font-size: 11px;
    line-height: 1.45;
}
.insert-empty-title {
    color: var(--text-0);
    font-weight: 800;
    margin-bottom: 4px;
}
.ins-item {
    min-height: 28px;
}
.ins-item:hover { background: rgba(33, 147, 251, 0.12) !important; }
.insert-item-icon {
    flex: 0 0 auto;
    font-size: 15px;
    color: var(--primary);
}
.insert-item-label {
    min-width: 0;
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.ins-prop {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border: 0;
    border-radius: 4px;
    background: transparent;
    color: var(--text-2);
    cursor: pointer;
}
.ins-prop:hover {
    background: rgba(33, 147, 251, 0.16);
    color: var(--text-0);
}

.tree-item {
    display: flex;
    align-items: center;
    gap: 4px;
    height: 24px;
    padding: 0 8px;
    color: var(--text-1);
    cursor: pointer;
    outline: none;
    white-space: nowrap;
}
.tree-item:hover { background: rgba(255, 255, 255, 0.03); }
.tree-item.hovered {
    background: rgba(33, 147, 251, 0.10);
    box-shadow: inset 2px 0 0 rgba(33, 147, 251, 0.45);
}
.tree-item:focus {
    background: rgba(33, 147, 251, 0.10);
    box-shadow: inset 2px 0 0 rgba(33, 147, 251, 0.65);
}
.tree-item.pressed {
    background: rgba(33, 147, 251, 0.12);
}
.tree-item.selected {
    background: rgba(33, 147, 251, 0.22);
    box-shadow: inset 2px 0 0 var(--primary-strong);
    color: var(--text-0);
}
.tree-item.selected .tree-label { color: var(--text-0); }
.tree-item.runtime { opacity: 0.55; font-style: italic; }
.tree-item.dragging { opacity: 0.4; }
.tree-item.drop-before { box-shadow: inset 0 2px 0 var(--primary); }
.tree-item.drop-after { box-shadow: inset 0 -2px 0 var(--primary); }
.tree-item.drop-inside {
    background: rgba(33, 147, 251, 0.22);
    box-shadow: inset 0 0 0 1px var(--primary);
}
.tree-icon { font-size: 14px; color: var(--text-2); }
.tree-twisty { width: 14px; color: var(--text-2); cursor: pointer; }
.tree-label {
    flex: 0 0 auto;
    color: var(--text-1);
}

/* Layers never scrolls sideways: a deep tree indents its rows past the panel
 * width, and a horizontal scrollbar there means hunting for a name in two
 * axes. The row stays inside the panel and the name truncates instead —
 * widening the panel is how you read more of it. */
#navigator-tree { overflow-x: hidden; }
#navigator-tree .tree-item { width: 100%; box-sizing: border-box; }
#navigator-tree .tree-label {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}
.tree-id-chip,
.tree-class-chip,
.tree-uid-chip {
    min-width: 0;
    max-width: 92px;
    overflow: hidden;
    text-overflow: ellipsis;
    padding: 1px 4px;
    border-radius: 3px;
    font-size: 10px;
    line-height: 14px;
}
.tree-uid-chip {
    color: var(--text-2);
    background: rgba(65, 71, 85, 0.18);
}
.tree-id-chip {
    color: var(--primary);
    background: rgba(33, 147, 251, 0.11);
}
.tree-class-chip {
    flex: 0 1 auto;
    max-width: 72px;
    color: var(--tertiary);
    background: rgba(239, 103, 25, 0.12);
}
.tree-badge {
    margin-left: 6px;
    font-size: 9px;
    padding: 1px 4px;
    border-radius: 3px;
    background: rgba(239, 103, 25, 0.18);
    color: var(--tertiary);
}

/* ── Property grid (Inspector / Style) ──────────────────────────────────── */
.inspector-summary {
    padding: 10px;
    border-bottom: 1px solid rgba(65, 71, 85, 0.28);
    background: linear-gradient(180deg, rgba(33, 147, 251, 0.07), transparent);
}
.inspector-summary-eyebrow {
    color: var(--text-2);
    font-size: 9px;
    font-weight: 800;
    letter-spacing: 0.07em;
    text-transform: uppercase;
}
.inspector-summary-title {
    margin-top: 4px;
    color: var(--text-0);
    font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
    font-size: 14px;
    font-weight: 800;
}
.inspector-summary-path {
    margin-top: 5px;
    color: var(--text-2);
    font: 10px/1.35 ui-monospace, "Cascadia Code", Consolas, monospace;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.inspector-token-strip {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: 7px;
}
.inspector-token {
    max-width: 128px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding: 2px 6px;
    border-radius: 3px;
    font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
    font-size: 10px;
}
.inspector-token.id {
    color: var(--primary);
    background: rgba(33, 147, 251, 0.13);
}
.inspector-token.cls {
    color: var(--tertiary);
    background: rgba(239, 103, 25, 0.13);
}
.inspector-token.muted {
    color: var(--text-2);
    background: rgba(65, 71, 85, 0.18);
}
.inspector-meta-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    margin-top: 9px;
}
.inspector-meta-item {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 52px;
    flex: 1 1 52px;
    padding: 5px 7px;
    border: 1px solid rgba(65, 71, 85, 0.28);
    border-radius: 4px;
    background: rgba(255, 255, 255, 0.025);
}
.inspector-meta-label {
    color: var(--text-2);
    font-size: 9px;
    text-transform: uppercase;
}
.inspector-meta-item strong {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text-0);
    font: 11px/1.2 ui-monospace, "Cascadia Code", Consolas, monospace;
}
.inspector-summary-actions {
    display: flex;
    gap: 4px;
    margin-top: 8px;
}
.prop-empty {
    padding: 7px 10px;
    color: var(--text-2);
    font-size: 11px;
}

.prop-section { border-bottom: 1px solid rgba(65, 71, 85, 0.2); }
.prop-section-header {
    display: flex;
    align-items: center;
    gap: 6px;
    height: 28px;
    padding: 0 10px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-1);
    cursor: pointer;
    background: var(--bg-3);
}
.prop-section-header .ms-icon { font-size: 14px; color: var(--text-2); }
.prop-section-body { padding: 6px 10px 10px; }

.prop-row {
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: 26px;
    margin: 3px 0;
}
.prop-label {
    /* width alongside basis: the engine drops flex-basis on text leaves —
     * without the explicit width every label hugs its text and the control
     * column turns ragged. */
    flex: 0 0 92px;
    width: 92px;
    color: var(--text-2);
    font-size: 10px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.prop-input {
    flex: 1 1 auto;
    box-sizing: border-box;
    height: 26px;
    min-width: 0;
    padding: 0 8px;
    background: var(--bg-3);
    border: 1px solid rgba(65, 71, 85, 0.3);
    border-radius: 4px;
    color: var(--text-0);
    font: inherit;
    line-height: 24px;
    vertical-align: middle;
    outline: none;
}
.prop-input:focus { border-color: var(--primary-strong); }
.prop-select-field {
    position: relative;
    display: block;
    flex: 1 1 auto;
    min-width: 0;
    height: 26px;
}
.prop-select-field > .prop-input {
    display: block;
    width: 100%;
    height: 100%;
    padding-right: 26px;
    -webkit-appearance: none;
    appearance: none;
    cursor: pointer;
}
.prop-select-chevron {
    position: absolute;
    top: 0;
    right: 6px;
    height: 26px;
    color: var(--text-2);
    font-size: 16px;
    line-height: 26px;
    pointer-events: none;
}
.prop-select-field:focus-within .prop-select-chevron {
    color: var(--text-0);
}
.prop-select-popup {
    position: fixed;
    z-index: 10020;
    box-sizing: border-box;
    max-height: 240px;
    overflow-y: auto;
    padding: 4px;
    background: var(--bg-3);
    border: 1px solid var(--line);
    border-radius: 6px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.48);
    outline: none;
}
.prop-select-option {
    display: block;
    width: 100%;
    min-height: 26px;
    padding: 4px 9px;
    background: transparent;
    border: 0;
    border-radius: 4px;
    color: var(--text-1);
    font: 11px/18px Inter, sans-serif;
    text-align: left;
    white-space: nowrap;
    cursor: pointer;
    outline: none;
}
.prop-select-option:hover:not(:disabled),
.prop-select-option:focus:not(:disabled) {
    background: rgba(33, 147, 251, 0.16);
    color: var(--text-0);
}
.prop-select-option.is-selected:not(:disabled) {
    background: rgba(33, 147, 251, 0.24);
    color: var(--text-0);
}
.prop-select-option:disabled {
    color: var(--text-3);
    cursor: default;
}
.prop-unit-select {
    flex: none;
}
.prop-unit-select-field {
    flex: 0 0 58px;
    width: 58px;
}
.prop-color-picker-btn {
    position: relative;
    width: 26px;
    height: 26px;
    flex: 0 0 26px;
    min-width: 26px;
    padding: 0;
    border: 1px solid rgba(65, 71, 85, 0.38);
    border-radius: 4px;
    background: var(--bg-3);
    cursor: pointer;
    overflow: hidden;
}
.prop-color-picker-btn:hover {
    border-color: var(--primary-strong);
}
.prop-color-picker-btn .prop-color-chip {
    position: absolute;
    inset: 2px;
    border-radius: 3px;
    pointer-events: none;
}
.prop-color-picker-btn .ms-icon {
    position: relative;
    z-index: 1;
    display: block;
    font-size: 15px;
    line-height: 24px;
    color: rgba(255, 255, 255, 0.9);
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
    pointer-events: none;
}
.prop-row--stack {
    align-items: flex-start;
    flex-wrap: wrap;
}
.prop-input-text {
    height: auto;
    min-height: 58px;
    padding: 6px 8px;
    line-height: 1.35;
    resize: vertical;
}
.prop-row--stack > .prop-hint-primary-only {
    box-sizing: border-box;
    padding-left: 100px;
}
.prop-input-check { width: 16px; height: 16px; flex: 0 0 auto; }
.studio-color-picker {
    position: fixed;
    z-index: 10000;
    width: 232px;
    border: 1px solid rgba(65, 71, 85, 0.48);
    border-radius: 6px;
    background: var(--bg-1);
    box-shadow: 0 18px 40px rgba(0, 0, 0, 0.36);
}
.scp-titlebar {
    height: 28px;
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 0 8px;
    border-bottom: 1px solid rgba(65, 71, 85, 0.28);
    background: var(--bg-3);
}
.scp-drag { font-size: 14px; color: var(--text-2); }
.scp-title {
    font-size: 10px;
    font-weight: 800;
    text-transform: uppercase;
    color: var(--text-1);
}
.scp-spacer { flex: 1; }
.scp-close {
    width: 22px;
    height: 22px;
    flex: 0 0 22px;
}
.scp-body {
    display: flex;
    flex-direction: column;
    gap: 9px;
    padding: 10px;
}
.scp-sv-area {
    position: relative;
    height: 136px;
    border-radius: 4px;
    cursor: crosshair;
    overflow: hidden;
}
.scp-sv-white,
.scp-sv-black {
    position: absolute;
    inset: 0;
}
.scp-sv-white {
    background: linear-gradient(to right, #ffffff, rgba(255, 255, 255, 0));
}
.scp-sv-black {
    background: linear-gradient(to top, #000000, rgba(0, 0, 0, 0));
}
.scp-sv-cursor {
    position: absolute;
    width: 12px;
    height: 12px;
    border: 2px solid #ffffff;
    border-radius: 50%;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.75);
    transform: translate(-50%, -50%);
    pointer-events: none;
}
.scp-hue-bar {
    position: relative;
    height: 12px;
    border-radius: 4px;
    background: linear-gradient(to right, #ff0000, #ffff00, #00ff00, #00ffff, #0000ff, #ff00ff, #ff0000);
    cursor: pointer;
}
.scp-sv-area:focus-visible,
.scp-hue-bar:focus-visible,
.scp-alpha-bar:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}
.scp-hue-cursor {
    position: absolute;
    top: -2px;
    width: 6px;
    height: 16px;
    border-radius: 3px;
    background: #ffffff;
    transform: translateX(-50%);
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.75);
    pointer-events: none;
}
.scp-preview-row {
    display: flex;
    gap: 4px;
}
.scp-mode-row,
.scp-btn-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 4px;
}
.scp-mode-row.has-eyedropper {
    grid-template-columns: 26px minmax(0, 1fr) minmax(0, 1fr);
}
.scp-mode-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 0;
    height: 24px;
    padding: 0 6px;
    border: 1px solid rgba(65, 71, 85, 0.30);
    border-radius: 4px;
    background: var(--bg-3);
    color: var(--text-1);
    font-size: 9px;
    font-weight: 800;
    line-height: 22px;
    white-space: nowrap;
    cursor: pointer;
}
.scp-mode-btn.on {
    border-color: var(--primary-strong);
    color: var(--primary);
    background: rgba(33, 147, 251, 0.14);
}
.scp-channels {
    display: flex;
    flex-direction: column;
    gap: 5px;
}
.scp-channel-row,
.scp-hex-row {
    display: flex;
    align-items: center;
    gap: 8px;
}
.scp-label {
    flex: 0 0 34px;
    width: 34px;
    color: var(--text-2);
    font-size: 10px;
    font-weight: 700;
}
.scp-channel-input,
.scp-hex-input {
    height: 26px;
}
.scp-preview-old,
.scp-preview-new {
    flex: 1;
    height: 24px;
    border-radius: 4px;
    border: 1px solid rgba(65, 71, 85, 0.25);
}
.scp-btn-row .btn-secondary,
.scp-btn-row .btn-primary {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 0;
    height: 26px;
    padding: 0 8px;
    border: 1px solid rgba(65, 71, 85, 0.30);
    border-radius: 4px;
    font-size: 10px;
    font-weight: 800;
    line-height: 24px;
    white-space: nowrap;
    cursor: pointer;
}
.scp-btn-row .scp-extract-token {
    grid-column: 1 / -1;
    color: var(--primary);
}
.studio-color-picker.extracting .scp-body {
    opacity: 0.72;
    cursor: progress;
}
.studio-color-picker.extracting button:disabled {
    cursor: progress;
}
.scp-btn-row .btn-secondary {
    background: var(--bg-3);
    color: var(--text-1);
}
.scp-btn-row .btn-primary {
    border-color: var(--primary-strong);
    background: var(--primary);
    color: #ffffff;
}
.box-edge-control {
    margin: 7px 0 3px;
    padding: 7px;
    border: 1px solid rgba(65, 71, 85, 0.24);
    border-radius: 5px;
    background: rgba(255, 255, 255, 0.018);
}
.box-edge-title {
    margin-bottom: 6px;
    color: var(--text-1);
    font-size: 10px;
    font-weight: 800;
    text-transform: uppercase;
}
.box-edge-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 5px;
}
.box-edge-cell {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
}
.box-edge-cell span {
    color: var(--text-2);
    font-size: 9px;
    font-weight: 800;
}
.box-edge-cell .prop-input {
    width: 100%;
    height: 24px;
    padding: 0 5px;
    font-size: 10px;
    line-height: 22px;
}
.pos-anchor-grid {
    display: grid;
    grid-template-columns: repeat(2, 22px);
    grid-auto-rows: 22px;
    gap: 3px;
    /* Explicit track sum prevents this intrinsic grid from stretching to the
       remaining flex-row width in embedded hosts (which pushed the 3x3
       medallion 15px outside the Inspector and created a horizontal bar). */
    flex: 0 0 47px;
    width: 47px;
    max-width: 47px;
}
.pos-anchor-grid--3 {
    grid-template-columns: repeat(3, 22px);
    flex-basis: 72px;
    width: 72px;
    max-width: 72px;
}
.pos-anchor-grid--error .pos-anchor-cell {
    border-color: var(--danger, #e5484d);
    box-shadow: 0 0 0 1px var(--danger, #e5484d);
}
.pos-anchor-cell {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    padding: 0;
    border: 1px solid var(--line-2);
    border-radius: 4px;
    background: var(--surface-2);
    color: var(--text-2);
    font-size: 12px;
    line-height: 1;
    cursor: pointer;
    overflow: hidden;
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.12);
}
.pos-anchor-cell::before {
    content: "";
    position: absolute;
    inset: 4px;
    border: 1px solid rgba(153, 164, 184, 0.42);
    border-radius: 2px;
    pointer-events: none;
}
.pos-anchor-cell:hover {
    color: var(--text-1);
    border-color: var(--text-3);
    background: rgba(255, 255, 255, 0.04);
}
.pos-anchor-cell.on {
    background: var(--accent, #2f6fed);
    border-color: var(--accent, #2f6fed);
    color: #fff;
}
.pos-anchor-cell.on::before {
    border-color: rgba(255, 255, 255, 0.58);
}
.pos-anchor-rep {
    position: absolute;
    z-index: 1;
    display: block;
    min-width: 3px;
    min-height: 3px;
    background: currentColor;
    border-radius: 1px;
    opacity: 0.86;
    pointer-events: none;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.18);
}
.pos-anchor-cell.on .pos-anchor-rep {
    opacity: 1;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.22);
}
.prop-state-dot {
    width: 6px; height: 6px; border-radius: 50%;
    background: var(--text-2); flex: 0 0 auto;
}
.prop-state-dot.authored { background: var(--primary-strong); }
/* Inherited: hollow ring — visibly distinct from "authored" (filled) and
   the faint "unset" default, so the tri-state actually reads. */
.prop-state-dot.inherited {
    background: transparent;
    box-shadow: inset 0 0 0 1.5px var(--text-2);
}
.prop-state-dot.overridden { background: var(--tertiary); }

/* Cascade trace — winning rule highlighted, overridden ones
   struck-through (plan: Webflow/Noesis cascade-source indicators).
   Honest: selector + specificity + origin only (Core has no file:line). */
/* D-17 — collapsed by default: the 60-row panel stays compact, the
   trace reveals while its row is hovered (CSS sibling) or
   keyboard-focused / hovered where the engine only fires JS events
   (.is-open toggled by style-panel). Additive — engines without the
   sibling/focus-within selectors just use .is-open. */
.prop-cascade {
    display: none; flex-direction: column; gap: 1px;
    margin: 0 0 4px 16px; padding-left: 6px;
    border-left: 1px solid var(--line);
}
.prop-cascade.is-open,
.prop-row:hover + .prop-cascade,
.prop-row:focus-within + .prop-cascade { display: flex; }
.cascade-src {
    display: flex; align-items: baseline; gap: 8px;
    font-size: 10px; line-height: 1.4;
}
.cascade-sel {
    font-family: ui-monospace, Menlo, Consolas, monospace;
    color: var(--text-1); white-space: nowrap;
    overflow: hidden; text-overflow: ellipsis;
}
.cascade-val {
    font-family: ui-monospace, Menlo, Consolas, monospace;
    color: var(--text-1); white-space: nowrap;
    overflow: hidden; text-overflow: ellipsis; flex: 1;
}
.cascade-src.win .cascade-sel { color: var(--primary); }
.cascade-src.win .cascade-val { color: var(--text-0); }
.cascade-src.over { opacity: 0.6; }
.cascade-src.over .cascade-sel,
.cascade-src.over .cascade-val {
    text-decoration: line-through; color: var(--text-2);
}
.cascade-meta { margin-left: auto; color: var(--text-2); white-space: nowrap; }

.transform-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 6px;
}
.transform-grid .prop-input { text-align: right; }

/* ── Center-dock tabs ───────────────────────────────────────────────────── */
.center-dock-tabs {
    display: flex;
    align-items: stretch;
    flex: 0 0 34px;
    height: 34px;
    min-height: 34px;
    min-width: 0;
    background: var(--bg-1);
    border-bottom: 1px solid rgba(65, 71, 85, 0.28);
    overflow: hidden;
}
.center-dock-tab {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
    max-width: 122px;
    padding: 0 12px;
    border: none;
    border-right: 1px solid rgba(65, 71, 85, 0.22);
    background: transparent;
    color: var(--text-2);
    cursor: pointer;
}
.center-dock-tab .ms-icon { flex: 0 0 auto; font-size: 15px; }
.center-dock-tab span:not(.ms-icon) {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* The bottom strip can contain every production tool panel. Do not let the
   flex algorithm shrink buttons below their text layout width: ForgeUI's
   incremental flex pass otherwise paints several labels into the same slot.
   Horizontal overflow keeps every tab reachable at narrow Studio widths. */
#bottom-dock-tabs {
    flex: 1 1 auto;
    overflow-x: auto;
    overflow-y: hidden;
    /* Keep the full production tab set reachable without dedicating a
       permanent 10px strip to native scrollbar chrome. Keyboard focus and
       horizontal wheel/trackpad scrolling still use the real scrollport. */
    scrollbar-width: none;
}
#bottom-dock-tabs::-webkit-scrollbar { width: 0; height: 0; }
#bottom-dock-tabs .center-dock-tab {
    flex: 0 0 auto;
    min-width: 96px;
}
#bottom-dock-tabs .bottom-tab-overflow-hidden { display: none; }
.bottom-tabs-header {
    display: flex;
    flex: 0 0 34px;
    min-width: 0;
    min-height: 34px;
    max-height: 34px;
    height: 34px;
    overflow: hidden;
    background: var(--bg-1);
}
/* Core's incremental flex/grid flow can advance by the inherited control
   height even while the 34px tab header paints at its requested size. Give
   the two dock regions explicit bounds: the header owns [0,34px), and every
   mutually-exclusive panel owns [34px,bottom). This prevents the overflow
   trigger from ever sharing hit-test space with panel actions below it. */
.studio-dock-bottom > .dock-panel {
    display: block;
    position: relative;
    width: 100%;
    height: 100%;
    min-height: 0;
}
.studio-dock-bottom > .dock-panel > .bottom-tabs-header {
    position: relative;
    width: 100%;
    z-index: 2;
}
.studio-dock-bottom > .dock-panel > .panel-body {
    position: absolute;
    top: 34px;
    bottom: 0;
    left: 0;
    width: 100%;
    height: auto;
    box-sizing: border-box;
}
/* Core's nested absolute layout currently advances the panel by less than the
   declared 34px.  Keep the Console action in a reserved footer instead of the
   tab axis, so its hit region cannot intersect any tab or the More trigger. */
#console-panel { padding-bottom: 34px; }
#console-panel-chrome {
    position: absolute !important;
    top: auto !important;
    right: 0;
    bottom: 0;
    left: 0;
    justify-content: flex-end !important;
}
/* ── Slice 2 — groupes du dock bas ───────────────────────────────────────
   Un onglet fixe (Audit, Runtime) ouvre un CONTENEUR qui possede sa propre
   bande de sous-onglets et occupe exactement la meme boite que les panneaux
   simples : [34px, bas). Les panneaux membres gardent leur id et leur
   display flex/none ; ils sont simplement absolus dans le corps du groupe,
   ce qui leur donne enfin des bornes de hauteur (avant, un panneau membre
   etait un enfant en flux du dock en display:block et pouvait deborder). */
.bottom-group {
    display: none;
    flex-direction: column;
    min-height: 0;
    box-sizing: border-box;
}
.studio-dock-bottom > .dock-panel > .bottom-group {
    position: absolute;
    top: 34px;
    bottom: 0;
    left: 0;
    width: 100%;
    height: auto;
    overflow: hidden;
    background: var(--bg-2);
}
.bottom-group > .bottom-subtabs {
    display: flex;
    align-items: stretch;
    flex: 0 0 26px;
    height: 26px;
    min-height: 26px;
    max-height: 26px;
    min-width: 0;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
    background: var(--bg-1);
    border-bottom: 1px solid rgba(65, 71, 85, 0.28);
}
.bottom-group > .bottom-subtabs::-webkit-scrollbar { width: 0; height: 0; }
.bottom-subtabs .center-dock-tab {
    flex: 0 0 auto;
    min-width: 84px;
    height: 26px;
    padding: 0 10px;
    font-size: 11px;
}
.bottom-subtabs .center-dock-tab .ms-icon { font-size: 14px; }
.bottom-group > .bottom-group-body {
    position: relative;
    flex: 1 1 0;
    min-height: 0;
    overflow: hidden;
    background: var(--bg-2);
}
.bottom-group > .bottom-group-body > * {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    width: auto;
    height: auto;
    box-sizing: border-box;
}
/* Une extension installee reste un onglet de premier plan, pousse apres les
   six onglets fixes et separe d'eux — jamais range dans un menu. */
#bottom-dock-tabs .center-dock-tab.bottom-tab-extension {
    border-left: 1px solid rgba(65, 71, 85, 0.5);
}
.bottom-tabs-overflow-btn {
    position: relative;
    flex: 0 0 34px;
    display: none;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    min-height: 34px;
    max-height: 34px;
    padding: 0;
    border: 0;
    border-left: 1px solid rgba(65, 71, 85, .38);
    border-bottom: 1px solid rgba(65, 71, 85, .28);
    background: var(--bg-1);
    color: var(--text-1);
    cursor: pointer;
}
.bottom-tabs-overflow-btn:hover { color: var(--text-0); background: var(--bg-2); }
.bottom-tabs-overflow-btn .ms-icon { font-size: 16px; }
.center-dock-tab.center-dock-tab-active {
    background: var(--bg-2);
    color: var(--text-0);
    box-shadow: inset 0 -2px 0 var(--primary-strong);
}
.center-dock-tab-close { font-size: 14px; opacity: 0.6; }
.center-dock-tab-close:hover { opacity: 1; color: var(--danger); }

/* A safe, useful first paint for the heavyweight Figma extension. The full
   workflow graph is imported only after the explicit action. */
.figma-entry-state {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 18px 24px;
    color: var(--text-1);
    background: linear-gradient(135deg, rgba(90, 210, 138, 0.055), transparent 42%), var(--bg-2);
}
.figma-entry-icon {
    flex: 0 0 34px;
    width: 34px;
    height: 34px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid rgba(90, 210, 138, 0.32);
    border-radius: 7px;
    color: var(--accent);
    background: rgba(90, 210, 138, 0.08);
}
.figma-entry-copy { display: flex; flex-direction: column; gap: 3px; max-width: 430px; }
.figma-entry-copy strong { color: var(--text-0); font-size: 12px; }
.figma-entry-copy span { color: var(--text-2); font-size: 10px; line-height: 1.45; }
.figma-entry-action {
    flex: 0 0 auto;
    min-height: 28px;
    padding: 0 11px;
    border: 1px solid rgba(90, 210, 138, 0.38);
    border-radius: 5px;
    color: var(--text-0);
    background: rgba(90, 210, 138, 0.11);
    cursor: pointer;
}
.figma-entry-action:hover { border-color: var(--accent); background: rgba(90, 210, 138, 0.17); }
.figma-entry-action:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.figma-entry-action:disabled { opacity: 0.62; cursor: progress; }

/* ── Command palette (#51, Ctrl/Cmd+K) ───────────────────────────────────── */
.cmd-palette-overlay {
    position: absolute;
    inset: 0;
    z-index: 9800;
    background: rgba(0, 0, 0, 0.45);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding-top: 12vh;
}
.cmd-palette {
    width: 460px;
    max-width: 90%;
    max-height: 60vh;
    display: flex;
    flex-direction: column;
    /* Slice 6 — floating surface token (--s-float); themes that do not
       define it fall back to the panel surface, as before. */
    background: var(--s-float, var(--bg-2, #1c1b1b));
    border: 1px solid var(--line, rgba(65, 71, 85, 0.5));
    border-radius: 10px;
    box-shadow: 0 24px 64px rgba(0, 0, 0, 0.62), 0 2px 8px rgba(0, 0, 0, 0.45);
    overflow: hidden;
    font: 12px Inter, sans-serif;
}
.cmd-palette-input {
    margin: 0;
    padding: 12px 14px;
    border: 0;
    border-bottom: 1px solid rgba(65, 71, 85, 0.4);
    background: transparent;
    color: var(--text-0, #e5e2e1);
    font: 14px Inter, sans-serif;
    outline: none;
}
.cmd-palette-list { overflow-y: auto; padding: 4px; }
.cmd-palette-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 8px 10px;
    border-radius: 4px;
    color: var(--text-1, #c1c6d7);
    cursor: pointer;
}
/* UX audit m2: the key chips were clipped at the right edge — the LABEL
   truncates, the chips never shrink. */
.cmd-palette-row > span:first-child {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.cmd-palette-row > span:last-child { flex: 0 0 auto; }
/* Re-audit m2: the key column is an explicit flex row — inline chips in
   an inline span drifted ~a line below their label (baseline sizing in
   the engine) and hugged the overlay scrollbar at the right edge. */
.cmd-palette-row .kbd-keys {
    display: flex;
    align-items: center;
    gap: 4px;
    flex: 0 0 auto;
}
#shortcuts-help .cmd-palette-list { padding-right: 12px; }
.cmd-palette-row.sel {
    background: rgba(33, 147, 251, 0.18);
    color: var(--text-0, #e5e2e1);
}
.cmd-palette-kbd {
    display: inline-block;
    font-size: 10px;
    line-height: 1.3;
    white-space: nowrap;
    color: var(--text-2, #8b90a0);
    border: 1px solid rgba(65, 71, 85, 0.5);
    border-radius: 3px;
    padding: 1px 5px;
}
/* Slice 6 — empty state: icon + verdict + next step, not a bare line. */
.cmd-palette-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 26px 18px;
    text-align: center;
    color: var(--text-2, #8b90a0);
}
.cmd-palette-empty .ms-icon { font-size: 28px; opacity: 0.7; }
.cmd-palette-empty strong { color: var(--text-1, #c1c6d7); font-weight: 700; }
.cmd-palette-empty span:last-child { max-width: 30ch; line-height: 1.45; }
/* Slice 6 — chrome-origin chip (e.g. a Tools-menu command). */
.cmd-palette-group {
    flex: 0 0 auto;
    margin-left: auto;
    font-size: 10px;
    letter-spacing: 0.3px;
    text-transform: uppercase;
    color: var(--text-2, #8b90a0);
    border: 1px solid var(--line, rgba(65, 71, 85, 0.5));
    border-radius: 999px;
    padding: 1px 7px;
}
.cmd-palette-row > .cmd-palette-group + span:last-child { margin-left: 0; }
/* Slice 6 — footer: how many commands exist, and the key contract. */
.cmd-palette-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 6px 10px;
    border-top: 1px solid var(--line, rgba(65, 71, 85, 0.4));
    font-size: 10px;
    color: var(--text-2, #8b90a0);
}
.cmd-palette-hints { display: flex; align-items: center; gap: 10px; }
.cmd-palette-hint { display: flex; align-items: center; gap: 3px; }
.cmd-palette-hint-label { margin-left: 2px; }
/* The selected row must never hide under the sticky footer/edges. */
.cmd-palette-row { scroll-margin: 4px; }
/* Shortcuts-help section header (e.g. "Canvas & gestures"). */
.cmd-palette-section {
    padding: 10px 10px 4px;
    font-size: 10px;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: var(--text-2, #8b90a0);
    border-top: 1px solid rgba(65, 71, 85, 0.35);
    margin-top: 4px;
}
.cmd-palette-row.disabled {
    opacity: 0.45;
    cursor: not-allowed;
}
.cmd-palette-row.disabled.sel { background: rgba(65, 71, 85, 0.18); }
.cmd-palette-why {
    font-size: 10px;
    font-style: italic;
    color: var(--text-2, #8b90a0);
}
/* Assets panel image thumbnail (replaces the glyph icon when resolved) */
.asset-preview {
    margin: 6px 10px 8px;
    border: 1px solid rgba(65, 71, 85, 0.28);
    border-radius: 5px;
    background: rgba(255, 255, 255, 0.025);
    overflow: hidden;
}
.asset-preview-media {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 132px;
    background-color: #10151d;
    background-image:
        linear-gradient(45deg, rgba(255,255,255,.20) 25%, transparent 25%),
        linear-gradient(-45deg, rgba(255,255,255,.20) 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, rgba(255,255,255,.20) 75%),
        linear-gradient(-45deg, transparent 75%, rgba(255,255,255,.20) 75%);
    background-size: 18px 18px;
    background-position: 0 0, 0 9px, 9px -9px, -9px 0;
}
.asset-preview-img {
    max-width: 100%;
    max-height: 132px;
    object-fit: contain;
    padding: 8px;
    box-sizing: border-box;
    background: transparent;
}
.asset-pixel-image {
    position: relative;
    display: block;
    padding: 0;
    flex: 0 0 auto;
    overflow: hidden;
    image-rendering: pixelated;
    background: transparent;
}
.asset-pixel-image i {
    position: absolute;
    display: block;
    min-width: 0;
    min-height: 0;
    font-style: normal;
}
.asset-preview-meta {
    padding: 7px 8px 8px;
    border-top: 1px solid rgba(65, 71, 85, 0.22);
    font-size: 10px;
}
.asset-preview-name {
    color: var(--text-0);
    font-weight: 800;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.asset-preview-path,
.asset-preview-dims {
    margin-top: 3px;
    color: var(--text-2);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.asset-thumb {
    width: 16px;
    height: 16px;
    object-fit: contain;
    border-radius: 2px;
    flex: 0 0 auto;
    background:
        linear-gradient(45deg, rgba(255,255,255,.13) 25%, transparent 25%),
        linear-gradient(-45deg, rgba(255,255,255,.13) 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, rgba(255,255,255,.13) 75%),
        linear-gradient(-45deg, transparent 75%, rgba(255,255,255,.13) 75%),
        #18202b;
    background-size: 8px 8px;
    background-position: 0 0, 0 4px, 4px -4px, -4px 0, 0 0;
    border: 1px solid rgba(255,255,255,.12);
}
.stage-viewport.asset-drop-target {
    box-shadow: inset 0 0 0 2px var(--primary-strong);
}
.asset-drag-ghost {
    position: fixed;
    z-index: 99999;
    display: flex;
    align-items: center;
    gap: 6px;
    max-width: 220px;
    padding: 6px 9px;
    border-radius: 6px;
    border: 1px solid rgba(255,255,255,.18);
    background: rgba(18, 23, 32, .94);
    color: var(--text-0);
    box-shadow: 0 10px 24px rgba(0,0,0,.26);
    font-size: 11px;
    pointer-events: none;
}
.asset-drag-ghost span:last-child {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ── Designer-bar color picker (alpha / eyedropper / swatch rows) ──────────
   Additive rules only. .scp-checker is the shared transparency backdrop
   (same repeating-conic idiom as .uikit-stage — engine-proven); a color
   paints OVER it via the absolutely-inset .scp-fill child, so translucent
   values composite honestly instead of losing their swatch. */
.scp-checker {
    position: relative;
    overflow: hidden;
    background: repeating-conic-gradient(#3d434f 0% 25%, #23272f 0% 50%)
        0 0 / 8px 8px;
}
.scp-fill {
    position: absolute;
    inset: 0;
    pointer-events: none;
}
.scp-alpha-bar {
    position: relative;
    height: 12px;
    border-radius: 4px;
    cursor: pointer;
}
.scp-alpha-fill {
    position: absolute;
    inset: 0;
    border-radius: 4px;
    pointer-events: none;
}
.scp-alpha-cursor {
    position: absolute;
    top: -2px;
    width: 6px;
    height: 16px;
    border-radius: 3px;
    background: #ffffff;
    transform: translateX(-50%);
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.75);
    pointer-events: none;
    z-index: 1;
}
.scp-eyedropper {
    width: 26px;
    height: 24px;
    flex: 0 0 26px;
    border: 1px solid rgba(65, 71, 85, 0.30);
    border-radius: 4px;
    background: var(--bg-3);
}
.scp-eyedropper .ms-icon { font-size: 14px; }
.scp-swatch-groups {
    display: flex;
    flex-direction: column;
    gap: 7px;
}
.scp-swatch-title {
    margin-bottom: 3px;
    font-size: 9px;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: var(--text-2);
}
.scp-swatches {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
}
.scp-swatch {
    width: 18px;
    height: 18px;
    flex: 0 0 18px;
    padding: 0;
    border: 1px solid rgba(65, 71, 85, 0.45);
    border-radius: 3px;
    cursor: pointer;
}
.scp-swatch:hover { border-color: var(--primary-strong); }
.scp-swatch.on {
    border-color: var(--primary);
    box-shadow: 0 0 0 1px var(--primary);
}

/* ── Gradient editor (inspector "Gradient" section) ─────────────────────────
 * Stop bar = checkerboard under a horizontal strip of the stops; chips are
 * absolutely-positioned buttons (margin-left centers them — no transform,
 * the embedded engine's safest path). */
.grad-bar {
    position: relative;
    height: 24px;
    margin: 10px 2px 16px;
    border-radius: 5px;
    border: 1px solid rgba(255, 255, 255, 0.14);
    background:
        linear-gradient(45deg, rgba(255,255,255,.13) 25%, transparent 25%),
        linear-gradient(-45deg, rgba(255,255,255,.13) 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, rgba(255,255,255,.13) 75%),
        linear-gradient(-45deg, transparent 75%, rgba(255,255,255,.13) 75%),
        #18202b;
    background-size: 8px 8px;
    background-position: 0 0, 0 4px, 4px -4px, -4px 0, 0 0;
    cursor: copy;
}
.grad-bar-fill {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    border-radius: 4px;
}
.grad-stop {
    position: absolute;
    top: -5px;
    bottom: -5px;
    width: 14px;
    margin-left: -7px;
    padding: 2px;
    border: 2px solid rgba(255, 255, 255, 0.75);
    border-radius: 4px;
    background: rgba(18, 23, 32, 0.9);
    cursor: ew-resize;
}
.grad-stop.on {
    border-color: var(--primary-strong);
    box-shadow: 0 0 0 1px var(--primary-strong);
}
.grad-stop-swatch {
    display: block;
    width: 100%;
    height: 100%;
    border-radius: 2px;
    pointer-events: none;
}
.grad-preview {
    height: 34px;
    margin: 4px 2px 8px;
    border-radius: 6px;
    border: 1px solid rgba(255, 255, 255, 0.12);
}
.grad-presets {
    display: flex;
    gap: 2px;
    flex: 0 0 auto;
}
.grad-presets .icon-btn { width: 22px; height: 22px; }
.grad-raw-hint {
    padding: 3px 2px 6px;
    color: var(--text-2);
    font-size: 10px;
}

/* ── Effects stack editor (inspector "Effects" section) ────────────────── */
.fx-group { margin: 4px 0 12px; }
.fx-group-head {
    display: flex;
    align-items: center;
    gap: 4px;
    min-height: 24px;
    margin-bottom: 2px;
}
.fx-group-title {
    flex: 1 1 auto;
    color: var(--text-2);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.fx-btn { width: 20px; height: 20px; }
.fx-btn .ms-icon { font-size: 13px; }
.fx-btn.on { color: var(--primary-strong); border-color: var(--primary-strong); }
.fx-add-select {
    flex: 0 0 auto;
    width: 92px;
    height: 22px;
    font-size: 10px;
}
.fx-row {
    margin: 4px 0;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 6px;
    background: rgba(255, 255, 255, 0.02);
}
.fx-row.open { border-color: rgba(255, 255, 255, 0.18); }
.fx-row-head {
    display: flex;
    align-items: center;
    gap: 6px;
    min-height: 26px;
    padding: 2px 6px;
    cursor: pointer;
}
.fx-row--flat .fx-row-head { cursor: default; }
.fx-swatch {
    flex: 0 0 14px;
    width: 14px;
    height: 14px;
    border-radius: 4px;
    border: 1px solid rgba(255, 255, 255, 0.25);
}
.fx-row-label {
    flex: 1 1 auto;
    min-width: 0;
    color: var(--text-0);
    font-size: 11px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.fx-badge {
    flex: 0 0 auto;
    padding: 1px 5px;
    border-radius: 6px;
    border: 1px solid rgba(255, 255, 255, 0.18);
    color: var(--text-2);
    font-size: 9px;
    text-transform: uppercase;
}
.fx-row-body {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 4px 8px 8px;
    border-top: 1px solid rgba(255, 255, 255, 0.06);
}
.fx-grid {
    display: flex;
    gap: 4px;
}
.fx-cell {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1 1 0;
    min-width: 0;
}
.fx-cell span {
    color: var(--text-2);
    font-size: 9px;
    text-transform: uppercase;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.fx-cell .prop-input { width: 100%; padding: 0 5px; }
.fx-inset-row { cursor: pointer; }
.fx-inset-row .prop-label { width: auto; flex: 0 0 auto; margin-left: 6px; }
.fx-color-field {
    display: flex;
    align-items: center;
    gap: 4px;
    flex: 1 1 auto;
    min-width: 0;
}
.fx-fn-value {
    flex: 1 1 auto;
    min-width: 0;
    height: 22px;
}
.fx-empty {
    padding: 2px 2px 4px;
    color: var(--text-2);
    font-size: 10px;
}

/* ── Motion authoring (timeline drag chips / easing preview / binding
   validation reasons) — additive block, motion wave ─────────────────────── */
.anim-stop-chip {
    position: absolute;
    top: 6px;
    transform: translateX(-50%);
    font-size: 9px;
    background: var(--primary);
    color: #04121f;
    border: 0;
    border-radius: 3px;
    padding: 2px 4px;
    cursor: grab;
    touch-action: none; /* pointer-drag owns the gesture (no scroll steal) */
}
.anim-stop-chip:focus {
    outline: 1px solid var(--text-0, #e5e2e1);
    outline-offset: 1px;
}
.anim-stop-chip.dragging {
    cursor: grabbing;
    z-index: 2;
}
/* Easing preview: a static mid-curve marker. ForgeUI Core currently leaks
   active transform animation/transition values across the Studio tree, so the
   panel deliberately communicates easing bias without background motion. */
.ease-preview {
    position: relative;
    flex: 0 0 auto;
    width: 64px;
    height: 14px;
    overflow: hidden;
    border: 1px solid rgba(65, 71, 85, 0.4);
    border-radius: 7px;
    background: color-mix(in srgb, var(--primary) 12%, transparent);
}
.ease-preview::before {
    content: "";
    position: absolute;
    left: 6px;
    right: 6px;
    top: 6px;
    height: 1px;
    background: rgba(229, 226, 225, 0.28);
}
.ease-preview-dot {
    position: absolute;
    top: 2px;
    left: 28px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--primary);
}
.ease-preview:focus-visible { outline: 1px solid var(--primary); outline-offset: 1px; }
/* Invalid free-entry fields (duration / cubic-bezier) */
.prop-input.invalid {
    border-color: var(--danger, #e05252);
}
/* Inline blocked-action reason under a form row (bindings validation) */
.bind-reason {
    flex: 1 1 100%;
    color: var(--danger, #e05252);
    font-size: 10px;
    padding: 0 2px;
}

/* ── Multi-select + component-trust chrome (selection-model wave) ─────────
 * Additive only. Navigator: secondary members of a 2+ selection get a
 * lighter tint than the primary's .selected; search matches from the
 * pure filterTree matches-set highlight their label; component-instance
 * roots carry a small blue chip (same idiom as the runtime badge).
 * Panels: "Mixed" multi-edit fields stay editable but read as
 * placeholders, and the Inspector component actions lay out as chips. */
.tree-item.multi-selected {
    background: rgba(33, 147, 251, 0.10);
}
.tree-item.multi-selected:not(.selected) {
    box-shadow: inset 2px 0 0 rgba(33, 147, 251, 0.55);
}
.tree-item.filter-match > .tree-label {
    background: rgba(239, 103, 25, 0.18);
    border-radius: 3px;
    padding: 0 3px;
}
.tree-badge.comp {
    background: rgba(33, 147, 251, 0.16);
    color: var(--primary);
}
.prop-input.mixed::placeholder {
    color: var(--tertiary);
    opacity: 0.9;
    font-style: italic;
}
select.prop-input.mixed {
    color: var(--tertiary);
    font-style: italic;
}
.chip.mixed {
    color: var(--tertiary);
    border-style: dashed;
    font-style: italic;
    cursor: default;
}
.prop-hint-primary-only {
    flex: 1 1 100%;
    color: var(--text-2);
    font-size: 10px;
    padding: 2px 2px 0;
}
.inspector-component-actions {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}
.inspector-component-actions .chip {
    height: auto;
    padding: 3px 10px;
    cursor: pointer;
}

/* ── Responsive trust wave: breakpoint-scoped editing chrome ─────────── */
/* Slim scope banner at the top of the style surface (Style panel +
   Inspector quick-CSS): says WHERE edits land when a non-base
   breakpoint is active, with the "Edit base instead" toggle. */
.bp-scope-banner {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 6px 8px 4px;
    padding: 5px 8px;
    border-radius: 6px;
    background: rgba(33, 147, 251, 0.10);
    border: 1px solid rgba(33, 147, 251, 0.35);
    color: var(--text-1);
    font-size: 11px;
    line-height: 1.35;
}
.bp-scope-banner .ms-icon {
    font-size: 14px;
    color: var(--primary);
    flex: 0 0 auto;
}
.bp-scope-banner.base {
    background: rgba(150, 150, 160, 0.08);
    border-color: rgba(150, 150, 160, 0.30);
}
.bp-scope-banner.base .ms-icon {
    color: var(--text-2);
}
.bp-scope-text {
    flex: 1;
    min-width: 0;
}
.bp-scope-toggle {
    flex: 0 0 auto;
    min-height: 22px;
    padding: 2px 8px;
    border-radius: 10px;
    border: 1px solid rgba(33, 147, 251, 0.45);
    background: transparent;
    color: var(--primary);
    font-size: 10px;
    cursor: pointer;
    white-space: nowrap;
}
.bp-scope-toggle:hover {
    background: rgba(33, 147, 251, 0.15);
}
/* Per-field override badge: the active breakpoint overrides this
   property. Scoped mode → a removable dot; click removes the override
   (undoable — the flush rides Core history). */
.bp-override-dot {
    flex: 0 0 auto;
    width: 10px;
    height: 10px;
    padding: 0;
    border-radius: 50%;
    border: 1px solid rgba(33, 147, 251, 0.8);
    background: var(--primary);
    cursor: pointer;
}
.bp-override-dot:hover {
    background: #e66;
    border-color: #e66;
}
/* "Edit base" mode: an informational chip — why the canvas doesn't
   change (the breakpoint override still wins at this size). */
.bp-shadow-chip {
    flex: 0 0 auto;
    padding: 1px 6px;
    border-radius: 9px;
    border: 1px dashed rgba(33, 147, 251, 0.55);
    color: var(--primary);
    font-size: 9px;
    white-space: nowrap;
    cursor: help;
}
/* Base mode (D-43): discreet hint that other breakpoints override this
   property — informational only (no click), dimmer than the shadow chip. */
.bp-exists-chip {
    flex: 0 0 auto;
    padding: 1px 5px;
    border-radius: 8px;
    border: 1px solid var(--border, rgba(255, 255, 255, 0.14));
    color: var(--text-3, rgba(255, 255, 255, 0.45));
    font-size: 9px;
    white-space: nowrap;
    cursor: help;
}
/* Scope-guard dialog: the session "don't ask again" checkbox row. */
.scope-guard-remember {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 0 14px 10px;
    color: var(--text-2);
    font: 11px/1.4 Inter, sans-serif;
    cursor: pointer;
}
.scope-guard-remember input {
    margin: 0;
}

/* ── Context menu (right-click, command-registry-driven — workflow-gaps
   wave). Token-consistent with .studio-menu: bg-3 surface, line border,
   primary-tinted hover; sits ABOVE the header menus (z 60 > 50). ── */
.studio-context-menu {
    position: fixed;
    z-index: 60;
    min-width: 200px;
    max-height: 70vh;
    overflow-y: auto;
    padding: 4px;
    background: var(--bg-3);
    border: 1px solid var(--line);
    border-radius: 6px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
    outline: none;
}
.ctx-menu-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 5px 10px;
    background: none;
    border: 0;
    border-radius: 4px;
    color: var(--text-1);
    font: 12px/1.4 Inter, sans-serif;
    text-align: left;
    cursor: pointer;
}
.ctx-menu-item:hover:not(:disabled),
.ctx-menu-item:focus:not(:disabled) {
    background: rgba(33, 147, 251, 0.12);
    color: var(--text-0);
    outline: none;
}
/* Disabled rows stay visible (discoverability) with the commandState
   reason as their title — never a silently missing action. */
.ctx-menu-item:disabled {
    color: var(--text-2);
    opacity: 0.55;
    cursor: default;
}
.ctx-menu-label {
    flex: 1 1 auto;
    white-space: nowrap;
}
/* Shortcut chip — same single-source shortcut string the F1 overlay
   and the palette render. */
.ctx-menu-shortcut {
    flex: 0 0 auto;
    margin-left: auto;
    padding: 1px 6px;
    border: 1px solid rgba(65, 71, 85, 0.5);
    border-radius: 3px;
    color: var(--text-2);
    font-size: 9px;
    white-space: nowrap;
}
.ctx-menu-sep {
    height: 1px;
    margin: 4px 6px;
    background: var(--line);
}

/* ── Designer vocabulary + Layers naming (UX wave) — additive ────────── */
/* Named layer rows: the display name leads, bold; the tag summary stays
   reachable via the row title. */
.tree-label.named {
    color: var(--text-0);
    font-weight: 600;
}
/* Inline rename input (double-click a Layers row). Sized like the label
   it replaces; commits on Enter, cancels on Escape/blur. */
.tree-rename-input {
    flex: 1 1 auto;
    min-width: 60px;
    max-width: 160px;
    padding: 0 4px;
    border: 1px solid var(--primary);
    border-radius: 3px;
    background: rgba(13, 17, 23, 0.85);
    color: var(--text-0);
    font: inherit;
    font-size: 11px;
    line-height: 16px;
    outline: none;
}
/* "Developer labels" toggle in the Layers header — gates the uid chips
   here and the UID meta in the Inspector summary. */
.dev-labels-toggle {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    padding: 1px 4px;
    border-radius: 3px;
    color: var(--text-2);
    font-size: 10px;
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}
.dev-labels-toggle:hover { color: var(--text-0); background: rgba(33, 147, 251, 0.12); }
.dev-labels-toggle input {
    margin: 0;
    background-color: var(--bg-0);
    border-color: rgba(145, 153, 172, 0.78);
    accent-color: var(--primary-strong);
}
.dev-labels-toggle .ms-icon { font-size: 12px; }
.dev-labels-toggle .dev-labels-label { max-width: 110px; overflow: hidden; text-overflow: ellipsis; }
/* "All properties (N)" disclosure — the collapsed vendor/rare tail of
   the Styles tab. */
.prop-disclosure { margin-top: 2px; }
.prop-disclosure-toggle {
    display: flex;
    align-items: center;
    gap: 4px;
    width: 100%;
    padding: 4px 8px;
    border: none;
    background: transparent;
    color: var(--text-2);
    font: inherit;
    font-size: 11px;
    text-align: left;
    cursor: pointer;
}
.prop-disclosure-toggle:hover { color: var(--text-0); background: rgba(33, 147, 251, 0.08); }
.prop-disclosure-toggle .ms-icon { font-size: 14px; }
.prop-disclosure-label { flex: 1 1 auto; }

/* ── OS-integration wave (additive) ──────────────────────────────────────
   Assets panel OS-file drop-target highlight — the Stage viewport reuses
   the existing .asset-drop-target affordance; this is the panel's own. */
#assets-panel.assets-drop-target {
    outline: 2px dashed var(--primary);
    outline-offset: -2px;
    background: rgba(33, 147, 251, 0.08);
}

/* ── Slice 4 — ONE Run toggle (additive) ─────────────────────────────────
   The toolbar carries a single, deliberately loud edit ⇄ run switch. It is
   the ONLY play affordance in the chrome: the stage lost its Design/Preview
   segment and the animation transport lives in the Timeline panel. Running
   is also announced by a discreet chrome tint (#studio-root.running) so the
   author can never be surprised by a document that eats their clicks. */
.run-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    flex: 0 0 auto;
    height: 26px;
    min-width: 84px;
    margin-right: 8px;
    padding: 0 12px;
    /* Green = "this launches a live session". --primary-strong is the strong
     * action fill from the theme layer; the fallback predates the token and is
     * kept only as a render guard. */
    border: 1px solid var(--primary-strong, #2fa864);
    border-radius: 5px;
    background: var(--primary-strong, #2fa864);
    color: #06130b;
    font: inherit;
    font-size: 11px;
    font-weight: 800;
    letter-spacing: .2px;
    white-space: nowrap;
    cursor: pointer;
}
.run-toggle .ms-icon { font-size: 16px; color: inherit; }
.run-toggle:hover { filter: brightness(1.08); }
.run-toggle:focus-visible { outline: 2px solid var(--text-0); outline-offset: 1px; }
.run-toggle:disabled { opacity: .45; cursor: default; filter: none; }
/* Running: the same control, now a Stop. Warm colour = "this is live". */
.run-toggle.running {
    border-color: var(--tertiary, #f28c33);
    background: var(--tertiary, #f28c33);
    color: #1a1103;
}
/* Discreet running chrome — a live seam on the header and the status bar,
   plus a hairline around the stage. No layout shift, no colour flood. */
#studio-root.running .studio-header { box-shadow: inset 0 -2px 0 rgba(242, 140, 51, 0.55); }
#studio-root.running .studio-statusbar { box-shadow: inset 0 2px 0 rgba(242, 140, 51, 0.55); }
#studio-root.running .stage-viewport {
    outline: 1px solid rgba(242, 140, 51, 0.28);
    outline-offset: -1px;
}
#status-runtime { white-space: nowrap; }
#studio-root.running #status-runtime { color: var(--tertiary, #f28c33); font-weight: 700; }

/* Slice 4 — Timeline transport (bottom dock). Icon-only chips sized so the
   play/pause control reads as the anchor of the row; the scrub slider keeps
   the remaining width. */
.anim-transport-btn {
    min-width: 26px;
    padding: 0 5px;
    justify-content: center;
}
.anim-transport-btn .ms-icon { font-size: 16px; }
.anim-transport-btn[aria-pressed="true"] { color: var(--primary-strong, #2fa864); }

/* Property×time Timeline matrix (mockup v1 drawer). */
.timeline-panel {
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
}
.timeline-panel.timeline-stop-details-open { overflow: auto; }
.timeline-toolbar,
.timeline-settings,
.anim-transport {
    display: flex;
    flex: 0 0 auto;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
    padding: 6px 8px;
    border-bottom: 1px solid var(--line, rgba(65, 71, 85, 0.4));
}
.timeline-field {
    display: inline-flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}
.timeline-source-badge {
    flex: 0 0 auto;
    padding: 3px 7px;
    border: 1px solid color-mix(in srgb, var(--primary) 42%, var(--line));
    border-radius: 999px;
    color: var(--primary);
    background: color-mix(in srgb, var(--primary) 8%, transparent);
    font: 600 9px/1.2 "Chivo Mono", ui-monospace, monospace;
    white-space: nowrap;
}
.timeline-field-label {
    font-size: 9px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-2);
}
.timeline-empty {
    padding: 16px 12px;
    color: var(--text-2);
    font-size: 11px;
}
.timeline-toolbar {
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
}
.timeline-toolbar > * {
    flex: 0 0 auto;
    white-space: nowrap;
}
@media (max-width: 1200px) {
    .timeline-readonly-source .timeline-new-clip-field,
    .timeline-readonly-source .timeline-add-clip,
    .timeline-readonly-source .timeline-delete-clip { display: none; }
    .timeline-readonly-source .timeline-toolbar { overflow-x: hidden; }
    .timeline-readonly-source .timeline-toolbar > select {
        flex: 1 1 160px;
        min-width: 160px;
        max-width: 240px;
    }
}
.timeline-grid {
    position: relative;
    display: grid;
    grid-template-columns: var(--timeline-property-col) minmax(0, 1fr);
    align-content: start;
    min-height: 56px;
    flex: 1 1 0;
    overflow: auto;
    --timeline-property-col: 212px;
    --timeline-axis-inset: 14px;
}
.timeline-readonly-source .timeline-grid { overflow-x: hidden; }
.anim-transport {
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
}
.anim-transport > :not(input[type="range"]) {
    flex: 0 0 auto;
    white-space: nowrap;
}
.anim-transport input[type="range"] {
    min-width: 80px;
    flex: 1 1 180px;
    background-color: transparent;
    accent-color: var(--primary);
    cursor: pointer;
}
.timeline-properties,
.timeline-time-viewport,
.timeline-time-axis,
.timeline-lanes { min-height: 0; }
.timeline-properties {
    grid-column: 1;
    border-right: 1px solid var(--line, rgba(65, 71, 85, 0.28));
}
.timeline-time-viewport {
    grid-column: 2;
    min-width: 0;
    padding: 0 var(--timeline-axis-inset);
    box-sizing: border-box;
}
.timeline-time-axis {
    position: relative;
    min-width: 0;
    cursor: ew-resize;
}
/* Legacy classes remain inert compatibility hooks for downstream source
   contract tests; the live matrix uses one two-column viewport above. */
.timeline-ruler-row,
.timeline-lane {
    display: grid;
    grid-template-columns: var(--timeline-property-col) minmax(0, 1fr);
    height: 28px;
    min-height: 28px;
    max-height: 28px;
    flex: 0 0 28px;
    border-bottom: 1px solid var(--line, rgba(65, 71, 85, 0.28));
}
.timeline-property-col {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    height: 28px;
    min-height: 28px;
    max-height: 28px;
    padding: 0 10px;
    box-sizing: border-box;
    font-size: 11px;
    color: var(--text-1);
    border-bottom: 1px solid var(--line, rgba(65, 71, 85, 0.28));
    min-width: 0;
}
.timeline-property-head {
    height: 24px;
    min-height: 24px;
    max-height: 24px;
    color: var(--text-2);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}
.timeline-lane-name { font-weight: 600; color: var(--text-0); }
.timeline-lane-value,
.timeline-timecode,
.timeline-tick {
    font-family: "Chivo Mono", ui-monospace, monospace;
    font-size: 10px;
    color: var(--text-2);
}
.timeline-lane-value {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.timeline-ruler,
.timeline-track {
    position: relative;
    box-sizing: border-box;
    border-bottom: 1px solid var(--line, rgba(65, 71, 85, 0.28));
}
.timeline-ruler {
    height: 24px;
    min-height: 24px;
    max-height: 24px;
}
.timeline-track {
    display: block;
    height: 28px;
    min-height: 28px;
    max-height: 28px;
}
.timeline-tick {
    position: absolute;
    top: 3px;
    transform: translateX(-50%);
    white-space: nowrap;
    pointer-events: none;
}
.timeline-tick-first { transform: none; }
.timeline-tick-last { transform: translateX(-100%); }
.timeline-bar {
    position: absolute;
    left: 0;
    right: 0;
    top: 12px;
    height: 3px;
    border-radius: 2px;
    background: linear-gradient(90deg, rgba(185, 202, 196, 0.13), rgba(185, 202, 196, 0.34));
    pointer-events: none;
}
.timeline-keyframe {
    width: 24px;
    height: 24px;
    top: 2px;
    padding: 0;
    background: transparent;
    color: transparent;
    font-size: 0;
    border: 0;
    border-radius: 0;
}
.timeline-keyframe::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 9px;
    height: 9px;
    margin: -4.5px 0 0 -4.5px;
    background: var(--bg-2, #121416);
    border: 1.5px solid var(--primary);
    transform: rotate(45deg);
    border-radius: 1px;
}
.timeline-keyframe:focus::before,
.timeline-keyframe.dragging::before,
.timeline-keyframe.selected::before,
.timeline-keyframe[aria-pressed="true"]::before {
    background: var(--primary);
}
.timeline-playhead {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 1px;
    background: var(--primary);
    pointer-events: none;
    z-index: 2;
}
.timeline-playhead::before {
    content: "";
    position: absolute;
    top: 0;
    left: -4px;
    width: 9px;
    height: 9px;
    background: var(--primary);
    clip-path: polygon(0 0, 100% 0, 50% 100%);
}
.timeline-confirm-body {
    padding: 14px;
    color: var(--text-1);
    font: 12px/1.5 "Manrope", sans-serif;
    white-space: pre-wrap;
}
.timeline-confirm-row {
    display: flex;
    gap: 8px;
    justify-content: flex-end;
    padding: 10px 14px;
    border-top: 1px solid var(--line, rgba(65, 71, 85, 0.4));
}
.timeline-stop-editor { padding: 0 10px 10px; }
.timeline-stop-head {
    font-size: 10px;
    color: var(--text-2);
    padding: 4px 0;
    display: flex;
    align-items: center;
    gap: 6px;
}
.tab-badge {
    display: inline-flex;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    margin-left: 4px;
    border-radius: 8px;
    align-items: center;
    justify-content: center;
    font-size: 9px;
    font-weight: 700;
    background: var(--bg-5, #282a2c);
    color: var(--text-0);
}
.tab-badge[data-kind="sel"] { background: var(--primary-strong); color: #04120a; }
.bottom-tabs-collapse-btn {
    flex: 0 0 34px;
    width: 34px;
    height: 34px;
    min-height: 34px;
    max-height: 34px;
    padding: 0;
    border: 0;
    border-left: 1px solid rgba(65, 71, 85, 0.38);
    background: var(--bg-1);
    color: var(--text-1);
    cursor: pointer;
}
.studio-dock-bottom[data-collapsed="true"] {
    height: 34px !important;
    min-height: 34px;
    flex: 0 0 34px !important;
    overflow: hidden;
}
.studio-dock-bottom[data-collapsed="true"] .panel-body,
.studio-dock-bottom[data-collapsed="true"] .bottom-group,
.studio-dock-bottom[data-collapsed="true"] #timeline-panel {
    display: none !important;
}
@media (prefers-reduced-motion: reduce) {
    .ease-preview-dot { animation: none !important; }
}
