/*  @import MUST BE THE FIRST THING IN THIS FILE.

    CSS drops an @import that appears after any style rule - not "later",
    dropped, silently, with nothing in the console. This one was on line 7
    behind two rules, so Tajawal never loaded for anybody; it only looked
    right on the one machine that had the font installed in Windows.

    NOTHING GOES ABOVE THIS LINE. If you need a rule at the top of the file,
    it goes below the import.  */
@import url('fonts/fonts.css?v=2');

/* Nothing here is a document to read: dragging across a label selected the
   interface text, and a double-click highlighted it like a web page. Inputs
   are exempted, because typing in them requires selection to work. */
*, *::before, *::after { -webkit-user-select: none; user-select: none; }
input, textarea { -webkit-user-select: text; user-select: text; }


:root {
    /* MENU SCALE, set from config.lua.
       `zoom` rather than a transform: a transform scales the box but not
       the layout around it, so a scaled panel would keep the hit areas
       and scroll heights of the unscaled one. zoom scales both, and CEF
       supports it. 1 is the built-in size. */
    --ui-scale: 1;
    --bg: #0b0714;
    --panel: #120a20;
    --card: #1a1030;
    --card-hover: #241a3f;
    --card-active: linear-gradient(135deg, #9257ff, #6d28d9);
    --border: rgba(167, 139, 250, 0.14);
    --border-strong: rgba(167, 139, 250, 0.35);
    --accent: #8b5cf6;
    --accent-2: #a855f7;
    --accent-soft: rgba(139, 92, 246, 0.14);
    --text: #f3f0fa;
    --text-dim: #a99dc7;
    --text-faint: #6f6389;
    --warn: #f59e0b;
    --danger: #ef4444;
    --danger-soft: rgba(239, 68, 68, 0.14);
    --overlay: rgba(6, 3, 12, 0.14);
    /* secondary action colour, so not every emphasised control is the same
       purple as the "this tab is active" highlight */
    --primary-alt: linear-gradient(135deg, #2dd4bf, #0d9488);
    /* per-category accents - the menu was almost entirely two shades of
       purple, which made every row look identical at a glance */
    --c-blue: #60a5fa;
    --c-indigo: #818cf8;
    --c-purple: #c084fc;
    --c-pink: #f472b6;
    --c-red: #f87171;
    --c-orange: #fb923c;
    --c-amber: #fbbf24;
    --c-green: #4ade80;
    --c-teal: #2dd4bf;
    --c-gray: #94a3b8;
    --radius: 14px;
    --radius-sm: 10px;
    --ease: cubic-bezier(.2, .8, .2, 1);
}

:root[data-theme="light"] {
    --bg: #efe9f9;
    --panel: #ffffff;
    --card: #f4f0fb;
    --card-hover: #e8e0f9;
    --card-active: linear-gradient(135deg, #a266ff, #7c3aed);
    --border: rgba(124, 58, 237, 0.14);
    --border-strong: rgba(124, 58, 237, 0.32);
    --accent: #7c3aed;
    --accent-2: #9257ff;
    --accent-soft: rgba(124, 58, 237, 0.1);
    --text: #251a3d;
    --text-dim: #6a5c8a;
    --text-faint: #9689b3;
    --overlay: rgba(60, 50, 90, 0.16);
    --primary-alt: linear-gradient(135deg, #14b8a6, #0f766e);
    /* slightly deeper on light theme so the icons keep enough contrast */
    --c-blue: #3b82f6;
    --c-indigo: #6366f1;
    --c-purple: #a855f7;
    --c-pink: #ec4899;
    --c-red: #ef4444;
    --c-orange: #f97316;
    --c-amber: #f59e0b;
    --c-green: #22c55e;
    --c-teal: #14b8a6;
    --c-gray: #64748b;
}

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

html, body { background: transparent; height: 100%; }

body {
    font-family: 'Tajawal', -apple-system, 'Segoe UI', Tahoma, sans-serif;
    color: var(--text);
    -webkit-font-smoothing: antialiased;
}

button, input { font-family: inherit; }

#app {
    /* fixed + physical `right` on purpose: a normal-flow block with both
       margin-left and margin-right set explicitly gets re-solved by the
       browser under dir="rtl" (the over-constrained box-model rule picks
       one margin over the other depending on direction), which is what
       was shoving the whole panel around between languages before.
       Fixed positioning with a physical offset has no such ambiguity,
       in either direction - the panel always docks to the right. */
    position: fixed;
    top: 4vh;
    right: 4vh;
    display: flex;
    flex-direction: column;
    width: 513px;
    height: 92vh;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 18px;
    overflow: hidden;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.45), 0 0 0 1px rgba(139, 92, 246, 0.06);
    /* THE CLOSED POSE LIVES HERE, NOT IN A CLASS.
       This is the fix for "the animation never plays the first time I open the
       script after joining", reported over and over.
       The entrance was a transition FROM a state applied by adding `.enter`
       and removing it in the same frame. That works only if the browser
       commits the in-between state, and on the very first open - fonts still
       loading, the game compositing the NUI for the first time - it does not.
       No committed start, no transition, so the panel just appeared.
       Putting the closed pose on #app ITSELF means the start state has been
       committed since the page loaded. There is nothing to flush and nothing
       to race: adding `.visible` always has somewhere to travel from.
       visibility stays for the hit-test tree, and is switched at t=0 on the
       way in and delayed to the end on the way out, so it never clips the
       motion. */
    visibility: hidden;
    opacity: 0;
    transform: translateY(26px) scale(.975);
    pointer-events: none;
    z-index: 1;
    transition: opacity .42s cubic-bezier(.16, .84, .28, 1),
                transform .42s cubic-bezier(.16, .84, .28, 1),
                visibility 0s linear .42s;
}

/* The entrance and exit live further down, as transitions between two
   committed states. Keyframes were tried first and lost their opening frames
   whenever the class landed in a heavy moment - the first open of a session
   showed no motion at all - so showApp() flushes the start state instead and
   lets a transition, which cannot be skipped that way, do the work. */

#app.visible {
    visibility: visible;
    pointer-events: auto;
    /* The entrance itself is further down, as a transition. This rule used
       to run `animation: appIn` here and the later one overrode it with
       `animation: none` - two rules disagreeing about the same property is
       how somebody loses an afternoon deciding which one is real. */
}

/* Added by hideApp() for the length of the exit, then removed with .visible.
   The exit MOTION is the `.visible.closing` transition further down; this
   rule only keeps the panel painted and untouchable while it plays. It used
   to run `animation: appOut` here too, against keyframes that no longer
   exist. */
#app.closing {
    visibility: visible;
    pointer-events: none;
}

#app.lang-switching .scroll-area,
#app.lang-switching .topbar,
#app.lang-switching .search-wrap {
    opacity: 0;
    transition: opacity .14s var(--ease);
}

[dir="rtl"] { text-align: right; }

/* ---------- Header ---------- */

.topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 18px 12px;
}

.brand { display: flex; align-items: center; gap: 10px; }

.brand-icon {
    width: 30px;
    height: 30px;
    border-radius: 9px;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--card-active);
    box-shadow: 0 4px 14px rgba(139, 92, 246, 0.35);
    flex-shrink: 0;
}

.brand-icon img, .brand-icon svg { width: 100%; height: 100%; display: block; object-fit: cover; }
/* the fallback clapperboard is a stroked icon, not artwork - it needs room */
.brand-icon.is-glyph { padding: 6px; color: #fff; }
.brand-icon.is-glyph svg { width: 100%; height: 100%; object-fit: contain; }

.brand-title {
    font-size: 16px;
    font-weight: 700;
    letter-spacing: .2px;
}

.topbar-actions { display: flex; align-items: center; gap: 8px; }

.chip {
    display: flex;
    align-items: center;
    gap: 6px;
    height: 30px;
    padding: 0 12px;
    border-radius: 9px;
    background: var(--card);
    border: 1px solid var(--border);
    font-size: 12px;
    font-weight: 700;
    color: var(--text-dim);
    cursor: pointer;
    transition: background .15s var(--ease), border-color .15s var(--ease), color .15s var(--ease);
    user-select: none;
}

.chip:hover { background: var(--card-hover); color: var(--text); border-color: var(--border-strong); }

.chip svg { width: 11px; height: 11px; opacity: .8; }

.count-chip { color: var(--text); cursor: default; }
.count-chip:hover { background: var(--card); border-color: var(--border); }
.count-chip span { color: var(--accent-2); }

/* ---------- Search ---------- */

.search-wrap {
    margin: 4px 18px 14px;
    display: flex;
    align-items: center;
    gap: 10px;
    height: 46px;
    padding: 0 14px;
    border-radius: 8px;
    background: var(--card);
    border: 1px solid var(--border);
    transition: border-color .15s var(--ease), background .15s var(--ease);
}

.search-wrap:focus-within { border-color: var(--accent); background: var(--card-hover); }

.search-wrap svg { width: 15px; height: 15px; color: var(--text-faint); flex-shrink: 0; }

.search-wrap input {
    flex: 1;
    width: 0;
    background: none;
    border: none;
    outline: none;
    color: var(--text);
    font-size: 13px;
}

.search-wrap input::placeholder { color: var(--text-faint); }

/* ---------- Edit mode bar ---------- */

.edit-bar {
    display: none;
    align-items: center;
    justify-content: space-between;
    margin: 0 18px 12px;
    padding: 9px 12px;
    border-radius: var(--radius-sm);
    background: var(--accent-soft);
    border: 1px dashed var(--border-strong);
    font-size: 11.5px;
    font-weight: 700;
    color: var(--accent-2);
}

.edit-bar.visible { display: flex; }

.edit-bar button {
    height: 26px;
    padding: 0 12px;
    border-radius: 7px;
    border: none;
    background: var(--card-active);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    cursor: pointer;
}

/* Now Playing / Stop - shown across every tab whenever a scene is active */

.now-playing {
    display: none;
    margin: 0 18px 12px;
    padding: 12px 14px;
    border-radius: var(--radius-sm);
    background: var(--card);
    border: 1px solid var(--border);
}
.now-playing.visible { display: block; }

.now-playing-header { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 8px; }

.now-playing-label {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .5px;
    text-transform: uppercase;
    color: var(--accent-2);
}
.now-playing-dot {
    width: 7px; height: 7px;
    border-radius: 50%;
    background: var(--accent-2);
    animation: blink 1.4s ease-in-out infinite;
}

.now-playing-stop {
    display: flex;
    align-items: center;
    gap: 5px;
    height: 26px;
    padding: 0 10px;
    border-radius: 7px;
    border: 1px solid rgba(239, 68, 68, 0.35);
    background: var(--danger-soft);
    color: #f87171;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .3px;
    text-transform: uppercase;
    cursor: pointer;
    transition: background .15s var(--ease);
}
.now-playing-stop svg { width: 10px; height: 10px; }
.now-playing-stop:hover { background: rgba(239, 68, 68, 0.22); }

.now-playing-name {
    font-size: 13px;
    font-weight: 700;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    margin-bottom: 8px;
}

.now-playing-meta { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.now-playing-meta .meta-chip { display: inline-flex; align-items: center; gap: 4px; font-size: 11px; color: var(--text-faint); }
.now-playing-meta .meta-chip svg { width: 12px; height: 12px; }

/* ---------- Content scroll ---------- */

.scroll-area { flex: 1; min-height: 0; overflow-y: auto; padding: 0 18px 16px; }
.scroll-area::-webkit-scrollbar { width: 6px; }
.scroll-area::-webkit-scrollbar-thumb { background: rgba(139, 92, 246, 0.25); border-radius: 3px; }
.scroll-area::-webkit-scrollbar-track { background: transparent; }

/* ---------- Unified menu grid ---------- */

/* Six half-columns rather than three full ones. A tile spans two, so it
   still reads as a 3-up grid - but a row that does not fill up can start
   half a column in and sit centred, instead of hugging one edge with a
   hole beside it. renderBlocks() sets --col-start on the first tile of a
   partial last row. */
.nav-grid {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 8px;
    margin-bottom: 12px; /* breathing room under the divider drawn below */
}

.block {
    /* NOT `grid-column: span 2` + a start override: that shorthand puts the
       span in grid-column-START, so setting the start afterwards silently
       throws the span away and the tiles pack six to a row. The span has to
       live on the END for --col-start to be able to move a tile. */
    grid-column-start: var(--col-start, auto);
    grid-column-end: span 2;
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 62px;
    border-radius: var(--radius-sm);
    background: var(--card);
    border: 1px solid var(--border);
    color: var(--text-dim);
    cursor: pointer;
    text-align: center;
    padding: 6px 4px;
    opacity: 0;
    animation: pop-in .32s var(--ease) forwards;
    animation-delay: calc(var(--i) * 22ms);
    transition: background .15s var(--ease), border-color .15s var(--ease), transform .12s var(--ease), color .15s var(--ease), opacity .15s var(--ease);
}

.block:hover { background: var(--card-hover); border-color: var(--border-strong); color: var(--text); transform: translateY(-1px); }
.block:active { transform: translateY(0) scale(.97); }

.block.active { background: var(--card-active); border-color: transparent; color: #fff; box-shadow: 0 6px 18px rgba(139, 92, 246, 0.3); }

/* The main entry points - Bot Control, Custom Scenes and (once it returns)
   the object spawner. Distinct enough to find without looking, but built
   from the panel's own violet rather than a colour imported from nowhere:
   a lifted surface, a brighter edge, and a stripe down the leading side. */
.block.featured {
    background:
        linear-gradient(135deg,
            color-mix(in srgb, var(--accent) 20%, transparent),
            color-mix(in srgb, var(--c-indigo) 10%, transparent));
    border-color: color-mix(in srgb, var(--accent-2) 34%, transparent);
    border-inline-start: 2px solid var(--accent-2);
    color: #ddd0ff;
}
.block.featured svg { color: var(--accent-2); }
.block.featured:hover {
    background:
        linear-gradient(135deg,
            color-mix(in srgb, var(--accent) 30%, transparent),
            color-mix(in srgb, var(--c-indigo) 16%, transparent));
    border-color: color-mix(in srgb, var(--accent-2) 55%, transparent);
    color: #fff;
}
.block.featured.active { background: var(--card-active); border-inline-start-color: transparent; color: #fff; }
.block.featured.active svg { color: #fff; }
.block.accent-text { color: #b79bff; }
.block.accent-text.active { color: #fff; }

.block svg { width: 17px; height: 17px; }

.block .label { font-size: 10.5px; font-weight: 700; letter-spacing: .3px; text-transform: uppercase; line-height: 1.1; }

.block .badge {
    position: absolute;
    top: 5px;
    right: 5px;
    font-size: 9px;
    font-weight: 700;
    padding: 1px 5px;
    border-radius: 6px;
    background: var(--accent-soft);
    color: #c9b8ff;
}
.block .badge.warn { background: rgba(245, 158, 11, 0.16); color: var(--warn); }
[dir="rtl"] .block .badge { right: auto; left: 5px; }

/* wide block = full-width bar */

.block.wide {
    grid-column: 1 / -1;
    flex-direction: row;
    height: 46px;
    font-size: 11.5px;
    letter-spacing: .4px;
}
.block.wide .label { font-size: 11.5px; }
/* Object Spooner: was the same purple as the active-tab highlight, which
   made it read as "currently selected". Teal keeps it obviously a primary
   action while staying inside the palette. */

/* thin separator between the nav grid and whatever the active tab renders
   below it - kept faint and hairline so it reads as a divider, not a box */
.nav-grid { position: relative; padding-bottom: 10px; }
.nav-grid::after {
    content: '';
    position: absolute;
    left: 8%;
    right: 8%;
    bottom: 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--border-strong), transparent);
}

/* edit-mode controls on a block */

.block .edit-handle,
.block .edit-eye,
.block .edit-size {
    display: none;
    position: absolute;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: 6px;
    background: rgba(0, 0, 0, 0.35);
    color: #fff;
    cursor: pointer;
    z-index: 2;
}
.block .edit-handle svg, .block .edit-eye svg, .block .edit-size svg { width: 11px; height: 11px; }
.block .edit-handle { top: 4px; left: 4px; cursor: grab; }
.block .edit-eye { top: 4px; right: 4px; }
.block .edit-size { bottom: 4px; right: 4px; }
[dir="rtl"] .block .edit-handle { left: auto; right: 4px; }
[dir="rtl"] .block .edit-eye { right: auto; left: 4px; }
[dir="rtl"] .block .edit-size { right: auto; left: 4px; }

.editing .block { cursor: grab; }
.editing .block .edit-handle,
.editing .block .edit-eye,
.editing .block .edit-size { display: flex; }
.editing .block.hidden-block { opacity: .35; }
.editing .block:hover { transform: none; }
.editing .block.drag-over { outline: 2px dashed var(--accent); outline-offset: 2px; }
.editing .block.dragging { opacity: .5; }
.editing .edit-handle { touch-action: none; }

.hidden-block:not(.editing .hidden-block) { display: none; }

/* ---------- Scene list ---------- */

.scene-list { display: flex; flex-direction: column; gap: 6px; }

.scene-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    background: var(--card);
    border: 1px solid var(--border);
    cursor: pointer;
    opacity: 0;
    animation: fade-up .28s var(--ease) forwards;
    animation-delay: calc(var(--i) * 18ms);
    transition: background .15s var(--ease), border-color .15s var(--ease), transform .12s var(--ease);
}

.scene-row:hover { background: var(--card-hover); border-color: var(--border-strong); transform: translateX(2px); }
[dir="rtl"] .scene-row:hover { transform: translateX(-2px); }

.scene-row .icon-wrap {
    width: 34px;
    height: 34px;
    border-radius: 9px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--accent-soft);
    color: #c9b8ff;
    flex-shrink: 0;
}
.scene-row .icon-wrap svg { width: 16px; height: 16px; }

/* per-category tint (see CATEGORY_COLORS in script.js) - the chip keeps
   the same shape, only the hue changes, so the list stays uniform in
   layout while being instantly scannable */
.icon-wrap[data-color="blue"]   { background: color-mix(in srgb, var(--c-blue) 16%, transparent);   color: var(--c-blue); }
.icon-wrap[data-color="indigo"] { background: color-mix(in srgb, var(--c-indigo) 16%, transparent); color: var(--c-indigo); }
.icon-wrap[data-color="purple"] { background: color-mix(in srgb, var(--c-purple) 16%, transparent); color: var(--c-purple); }
.icon-wrap[data-color="pink"]   { background: color-mix(in srgb, var(--c-pink) 16%, transparent);   color: var(--c-pink); }
.icon-wrap[data-color="red"]    { background: color-mix(in srgb, var(--c-red) 16%, transparent);    color: var(--c-red); }
.icon-wrap[data-color="orange"] { background: color-mix(in srgb, var(--c-orange) 16%, transparent); color: var(--c-orange); }
.icon-wrap[data-color="amber"]  { background: color-mix(in srgb, var(--c-amber) 16%, transparent);  color: var(--c-amber); }
.icon-wrap[data-color="green"]  { background: color-mix(in srgb, var(--c-green) 16%, transparent);  color: var(--c-green); }
.icon-wrap[data-color="teal"]   { background: color-mix(in srgb, var(--c-teal) 16%, transparent);   color: var(--c-teal); }
.icon-wrap[data-color="gray"]   { background: color-mix(in srgb, var(--c-gray) 16%, transparent);   color: var(--c-gray); }

.scene-row.danger .icon-wrap { background: var(--danger-soft); color: #f87171; }

.scene-row .info { flex: 1; min-width: 0; }
.scene-row .name { font-size: 13px; font-weight: 700; }
.scene-row .count { font-size: 11px; color: var(--text-faint); margin-top: 1px; }

.scene-row > svg { width: 14px; height: 14px; color: var(--text-faint); flex-shrink: 0; }
[dir="rtl"] .scene-row > svg { transform: scaleX(-1); }

.empty-state { text-align: center; color: var(--text-faint); font-size: 12px; padding: 30px 0; }

/* individual scene row (inside a category / search / favorites) */

.scene-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    background: var(--card);
    border: 1px solid var(--border);
    cursor: pointer;
    opacity: 0;
    animation: fade-up .28s var(--ease) forwards;
    animation-delay: calc(var(--i) * 14ms);
    transition: background .15s var(--ease), border-color .15s var(--ease);
}
.scene-item:hover { background: var(--card-hover); border-color: var(--border-strong); }

.scene-item-main { flex: 1; min-width: 0; }
.scene-item-name { font-size: 13px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.scene-item-meta { display: flex; align-items: center; gap: 6px; margin-top: 4px; }

.scene-item-meta .tag {
    font-size: 9.5px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .3px;
    padding: 2px 6px;
    border-radius: 5px;
    background: var(--accent-soft);
    color: #c9b8ff;
}

.scene-item-meta .meta-chip {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-size: 10.5px;
    color: var(--text-faint);
}
.scene-item-meta .meta-chip svg { width: 11px; height: 11px; }

.fav-btn {
    width: 28px; height: 28px;
    border-radius: 8px;
    border: none;
    background: transparent;
    color: var(--text-faint);
    display: flex; align-items: center; justify-content: center;
    cursor: pointer;
    flex-shrink: 0;
}
.fav-btn svg { width: 15px; height: 15px; }
.fav-btn:hover { background: var(--accent-soft); color: #c9b8ff; }
.fav-btn.active { color: var(--warn); }
.fav-btn.active svg { fill: var(--warn); }

/* ---------- Footer ---------- */

.statusbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 16px;
    border-top: 1px solid var(--border);
    background: rgba(0, 0, 0, 0.12);
}
:root[data-theme="light"] .statusbar { background: rgba(124, 58, 237, 0.04); }

.rec-pill {
    display: flex;
    align-items: center;
    gap: 6px;
    height: 26px;
    padding: 0 10px;
    border: 1px solid rgba(239, 68, 68, 0.3);
    border-radius: 7px;
    background: var(--danger-soft);
    color: #f66;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .3px;
    cursor: pointer;
    transition: background .15s var(--ease);
}
.rec-pill:hover { background: rgba(239, 68, 68, 0.22); }
.rec-pill.recording { background: var(--danger); color: #fff; border-color: transparent; }

.rec-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--danger); animation: blink 1.4s ease-in-out infinite; }
.rec-pill.recording .rec-dot { background: #fff; }

.status-actions { display: flex; align-items: center; gap: 6px; }

/* Hide me. Sits next to REC because that is when it is wanted: you are
   about to record and your own character is standing in the frame. */
.hide-pill {
    display: flex;
    align-items: center;
    gap: 6px;
    height: 26px;
    padding: 0 10px;
    border: 1px solid var(--border);
    border-radius: 7px;
    background: var(--card);
    color: var(--text-dim);
    font-family: inherit;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .3px;
    cursor: pointer;
    transition: background .15s var(--ease), color .15s var(--ease), border-color .15s var(--ease);
}
.hide-pill svg { width: 12px; height: 12px; }
.hide-pill:hover { background: var(--card-hover); color: var(--text); border-color: var(--border-strong); }
.hide-pill.hidden-on {
    background: var(--accent-soft);
    border-color: var(--accent);
    color: #c9b8ff;
}

.status-text { font-size: 10.5px; color: var(--text-faint); }
.status-text kbd { background: var(--card); border: 1px solid var(--border); border-radius: 4px; padding: 1px 5px; font-size: 9.5px; font-family: inherit; }

.settings-trigger {
    width: 26px;
    height: 26px;
    border-radius: 7px;
    border: 1px solid transparent;
    background: transparent;
    color: var(--accent);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background .15s var(--ease), border-color .15s var(--ease), transform .15s var(--ease);
}
.settings-trigger:hover { background: var(--accent-soft); border-color: var(--border); transform: rotate(35deg); }
.settings-trigger svg { width: 15px; height: 15px; }

/* ---------- Settings drawer ---------- */

.settings-view {
    position: absolute;
    inset: 0;
    background: var(--panel);
    display: flex;
    flex-direction: column;
    transform: translateX(100%);
    transition: transform .24s var(--ease);
    z-index: 10;
}
[dir="rtl"] .settings-view { transform: translateX(-100%); }
.settings-view.visible { transform: translateX(0); }

.settings-header {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 16px 18px;
    border-bottom: 1px solid var(--border);
}
.settings-header .back-btn {
    width: 30px; height: 30px;
    border-radius: 9px;
    border: 1px solid var(--border);
    background: var(--card);
    color: var(--text);
    display: flex; align-items: center; justify-content: center;
    cursor: pointer;
}
.settings-header .back-btn svg { width: 14px; height: 14px; }
[dir="rtl"] .settings-header .back-btn svg { transform: scaleX(-1); }
.settings-header h2 { font-size: 15px; font-weight: 700; }

.settings-body { flex: 1; overflow-y: auto; padding: 16px 18px 24px; display: flex; flex-direction: column; gap: 22px; }

.settings-section .sec-title { font-size: 11px; font-weight: 700; letter-spacing: .5px; text-transform: uppercase; color: var(--text-faint); margin-bottom: 10px; }
.settings-section .sec-desc { font-size: 11.5px; color: var(--text-faint); margin-top: 6px; }

.speed-slider-row { display: flex; align-items: center; gap: 12px; }

.speed-slider-row input[type="range"] {
    flex: 1;
    -webkit-appearance: none;
    appearance: none;
    height: 6px;
    border-radius: 3px;
    background: var(--border-strong);
    outline: none;
    cursor: pointer;
}
.speed-slider-row input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 17px;
    height: 17px;
    border-radius: 50%;
    background: var(--card-active);
    box-shadow: 0 2px 6px rgba(139, 92, 246, 0.4);
    cursor: pointer;
}

.speed-slider-row .speed-value {
    flex-shrink: 0;
    width: 46px;
    text-align: center;
    font-size: 12px;
    font-weight: 700;
    color: var(--accent-2);
}

.seg-control { display: flex; gap: 8px; }
.seg-btn {
    flex: 1;
    display: flex; align-items: center; justify-content: center; gap: 7px;
    height: 42px;
    border-radius: var(--radius-sm);
    background: var(--card);
    border: 1px solid var(--border);
    color: var(--text-dim);
    font-size: 12.5px;
    font-weight: 700;
    cursor: pointer;
    transition: all .15s var(--ease);
}
.seg-btn:hover { border-color: var(--border-strong); }
.seg-btn.active { background: var(--card-active); border-color: transparent; color: #fff; box-shadow: 0 6px 16px rgba(139, 92, 246, 0.28); }
.seg-btn svg { width: 14px; height: 14px; }
.swatch { width: 12px; height: 12px; border-radius: 50%; border: 1px solid rgba(255,255,255,0.3); }
.swatch.dark { background: #150c28; }
.swatch.light { background: #efe9f9; }

.settings-btn {
    width: 100%;
    display: flex; align-items: center; justify-content: center; gap: 8px;
    height: 42px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    background: var(--card);
    color: var(--text);
    font-size: 12.5px;
    font-weight: 700;
    cursor: pointer;
    transition: background .15s var(--ease), border-color .15s var(--ease);
}
.settings-btn:hover { background: var(--card-hover); border-color: var(--border-strong); }
.settings-btn svg { width: 14px; height: 14px; }

.settings-btn.link { background: none; border: none; color: var(--accent-2); text-decoration: underline; height: auto; padding: 4px 0; justify-content: flex-start; }
[dir="rtl"] .settings-btn.link { justify-content: flex-end; }

.settings-btn.danger { background: var(--danger-soft); border-color: rgba(239, 68, 68, 0.3); color: #f87171; }
.settings-btn.danger:hover { background: rgba(239, 68, 68, 0.22); }

/* ---------- Modal ---------- */

.modal-overlay {
    position: fixed;
    inset: 0;
    background: var(--overlay);
    /* visibility+opacity, NOT display:none - same reasoning as #app: a
       display swap happens instantly with no transition, so the fade-out
       on close could never actually play, only the fade-in ever showed */
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 20;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity .2s var(--ease), visibility 0s linear .2s;
    /* backdrop-filter removed on purpose: FiveM's NUI layer sits over the
       actual 3D game frame, not normal web content, and CEF frequently
       can't sample that properly for a blur - instead of a soft blur it
       was rendering the whole game view behind it as solid black,
       regardless of how low the overlay color's own opacity was set. The
       tint below is the only dimming now, no blur involved at all. */
}
.modal-overlay.visible {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transition: opacity .2s var(--ease), visibility 0s linear 0s;
}

.modal-card {
    width: 86%;
    max-width: 400px;
    background: var(--panel);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius);
    padding: 20px;
    box-shadow: 0 20px 50px rgba(0,0,0,0.4);
    transform: translateY(8px) scale(.97);
    transition: transform .18s var(--ease);
}
.modal-overlay.visible .modal-card { transform: translateY(0) scale(1); }

.modal-card .modal-icon {
    width: 40px; height: 40px;
    border-radius: 10px;
    background: var(--danger-soft);
    color: #f87171;
    display: flex; align-items: center; justify-content: center;
    margin-bottom: 12px;
}
.modal-card .modal-icon svg { width: 20px; height: 20px; }
.modal-card h3 { font-size: 15px; font-weight: 700; margin-bottom: 6px; }
.modal-card p { font-size: 12px; color: var(--text-dim); line-height: 1.5; margin-bottom: 16px; }
.modal-actions { display: flex; gap: 8px; }
.modal-actions button {
    flex: 1;
    height: 40px;
    border-radius: var(--radius-sm);
    font-size: 12.5px;
    font-weight: 700;
    cursor: pointer;
    border: 1px solid var(--border);
    background: var(--card);
    color: var(--text);
}
.modal-actions button.confirm { background: var(--danger); border-color: transparent; color: #fff; }

/* ---------- Category header (inside a category / search results) ---------- */

.category-header {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 10px;
}

.category-header .back-chip {
    display: flex;
    align-items: center;
    gap: 4px;
    height: 30px;
    padding: 0 10px;
    border-radius: var(--radius-sm);
    background: var(--card);
    border: 1px solid var(--border);
    color: var(--text-dim);
    font-size: 11.5px;
    font-weight: 700;
    cursor: pointer;
    flex-shrink: 0;
}
.category-header .back-chip:hover { background: var(--card-hover); color: var(--text); }
.category-header .back-chip svg { width: 12px; height: 12px; transform: scaleX(-1); }
[dir="rtl"] .category-header .back-chip svg { transform: scaleX(1); }

.category-header .title { flex: 1; min-width: 0; font-size: 14px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.category-header .count-badge { flex-shrink: 0; font-size: 10.5px; font-weight: 700; color: var(--text-faint); background: var(--card); border: 1px solid var(--border); border-radius: 7px; padding: 3px 8px; }

.loading-state { text-align: center; color: var(--text-faint); font-size: 12px; padding: 30px 0; }

/* ---------- Select Ped Models modal ---------- */

.ped-modal { width: 92%; max-width: 460px; max-height: 88vh; overflow-y: auto; padding: 18px; }

.ped-modal-header { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.ped-modal-header > svg { width: 18px; height: 18px; color: var(--accent); flex-shrink: 0; }
.ped-modal-header h3 { flex: 1; font-size: 14.5px; font-weight: 700; }
.ped-modal-header .icon-btn {
    width: 26px; height: 26px;
    border-radius: 7px;
    border: 1px solid var(--border);
    background: var(--card);
    color: var(--text-dim);
    display: flex; align-items: center; justify-content: center;
    cursor: pointer;
}
.ped-modal-header .icon-btn:hover { background: var(--card-hover); color: var(--text); }
.ped-modal-header .icon-btn svg { width: 12px; height: 12px; }

.ped-modal-scene-name { font-size: 11.5px; color: var(--text-faint); font-style: italic; margin-bottom: 14px; }

.ped-modal-body { display: flex; flex-direction: column; gap: 10px; }

.actor-card {
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--card);
    padding: 10px 12px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.actor-card .actor-label { display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 700; color: var(--text-dim); }
.actor-card .actor-label svg { width: 13px; height: 13px; color: var(--accent); }

.field-select-wrap { position: relative; }
.field-select {
    width: 100%;
    height: 38px;
    padding: 0 30px 0 12px;
    border-radius: 8px;
    background: var(--panel);
    border: 1px solid var(--border);
    color: var(--text);
    font-size: 12.5px;
    font-family: inherit;
    appearance: none;
    cursor: pointer;
}
[dir="rtl"] .field-select { padding: 0 12px 0 30px; }
.field-select:focus { outline: none; border-color: var(--accent); }
.field-select-wrap::after {
    content: '';
    position: absolute;
    top: 50%; right: 11px;
    width: 8px; height: 8px;
    border-right: 2px solid var(--text-faint);
    border-bottom: 2px solid var(--text-faint);
    transform: translateY(-70%) rotate(45deg);
    pointer-events: none;
}
[dir="rtl"] .field-select-wrap::after { right: auto; left: 11px; }

.field-select-wrap.weapon .field-select { color: var(--text-dim); }

.section-label {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .4px;
    text-transform: uppercase;
    color: var(--accent-2);
    margin: 4px 0 2px;
}
.section-label svg { width: 12px; height: 12px; }

.object-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    height: 38px;
    padding: 0 12px;
    border-radius: 8px;
    background: var(--card);
    border: 1px solid var(--border);
    font-size: 11.5px;
    color: var(--text-dim);
}
.object-row .object-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* small on/off switch, used for object toggles and the Loop control */
.switch { position: relative; display: inline-flex; align-items: center; cursor: pointer; flex-shrink: 0; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch .toggle-track {
    width: 34px; height: 19px;
    border-radius: 10px;
    background: var(--border-strong);
    transition: background .15s var(--ease);
    position: relative;
    flex-shrink: 0;
}
.switch .toggle-thumb {
    position: absolute;
    top: 2px; left: 2px;
    width: 15px; height: 15px;
    border-radius: 50%;
    background: #fff;
    transition: transform .15s var(--ease);
}
.switch input:checked + .toggle-track { background: var(--accent); }
.switch input:checked + .toggle-track .toggle-thumb { transform: translateX(15px); }

/* the base "off" position also has to flip in RTL, not just the "on"
   transform - otherwise checking it in Arabic slides the thumb an extra
   15px off the LTR-anchored left:2px base, pushing it clean off the track */
[dir="rtl"] .switch .toggle-thumb { left: auto; right: 2px; }
[dir="rtl"] .switch input:checked + .toggle-track .toggle-thumb { transform: translateX(-15px); }

.loop-toggle { display: flex; align-items: center; gap: 8px; font-size: 12px; font-weight: 700; color: var(--text-dim); }

.ped-modal-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid var(--border);
}

.ped-modal-actions { display: flex; gap: 8px; }
/* An inline <svg> with no width/height attribute falls back to 300x150 -
   the CSS default for a replaced element. Every one of these buttons carries
   an icon, so without a size rule the icon rendered enormous, shoved the
   label out of the button and overlapped whatever was next to it. That is
   what the broken "Place" button was. */
.modal-btn {
    height: 38px;
    padding: 0 16px;
    border-radius: var(--radius-sm);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    font-size: 12px;
    font-weight: 700;
    cursor: pointer;
    border: 1px solid var(--border);
    background: var(--card);
    color: var(--text);
    transition: background .15s var(--ease), filter .15s var(--ease);
}
.modal-btn svg { width: 14px; height: 14px; flex: none; }
.modal-btn:disabled { opacity: .45; cursor: default; }
.modal-btn:hover { background: var(--card-hover); }
.modal-btn.cancel { color: #f87171; border-color: rgba(239, 68, 68, 0.3); background: var(--danger-soft); }
.modal-btn.cancel:hover { background: rgba(239, 68, 68, 0.22); }
.modal-btn.place { background: var(--card); border-color: var(--border-strong); }
.modal-btn.play { background: var(--card-active); border-color: transparent; color: #fff; }
.modal-btn.play:hover { filter: brightness(1.08); }

/* ---------- Placement HUD (native camera mode is active; NUI has no focus) ---------- */

.placement-hud {
    position: fixed;
    top: 14px;
    left: 50%;
    transform: translateX(-50%);
    display: none;
    align-items: center;
    gap: 10px;
    padding: 8px 16px;
    border-radius: 10px;
    background: rgba(10, 6, 18, 0.55);
    border: 1px solid rgba(255, 255, 255, 0.08);
    font-family: 'Tajawal', sans-serif;
    font-size: 12px;
    font-weight: 700;
    color: #e9e4f5;
    white-space: nowrap;
    z-index: 999;
}
.placement-hud.visible { display: flex; }
.placement-hud .placement-mode { color: #a78bfa; letter-spacing: .4px; }
.placement-hud.frozen .placement-mode { color: #9c94ad; }
.placement-hud .placement-sep { color: rgba(255,255,255,0.25); }
.placement-hud .placement-hint { color: #cfc8e0; font-weight: 600; }
.placement-hud .placement-slowmo {
    display: none;
    padding: 2px 7px;
    border-radius: 5px;
    background: rgba(139, 92, 246, 0.25);
    color: #d8c9ff;
    font-size: 10.5px;
}
.placement-hud .placement-slowmo.visible { display: inline-block; }

/* ---------- Toast ---------- */

.toast {
    position: absolute;
    bottom: 56px;
    left: 50%;
    transform: translateX(-50%) translateY(8px);
    padding: 10px 16px;
    border-radius: 10px;
    background: var(--card-active);
    color: #fff;
    font-size: 12px;
    font-weight: 700;
    box-shadow: 0 10px 30px rgba(0,0,0,0.35);
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s var(--ease), transform .2s var(--ease);
    z-index: 30;
    white-space: nowrap;
}
.toast.visible { opacity: 1; transform: translateX(-50%) translateY(0); }

/* ---------- Appearance editor ("Native Ped Studio" style) ---------- */

.appearance-view {
    position: absolute;
    inset: 0;
    background: var(--panel);
    display: flex;
    flex-direction: column;
    transform: translateX(100%);
    transition: transform .24s var(--ease);
    z-index: 10;
}
[dir="rtl"] .appearance-view { transform: translateX(-100%); }
.appearance-view.visible { transform: translateX(0); }

.appearance-header {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 16px 18px 12px;
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}
.appearance-icon {
    width: 30px; height: 30px;
    border-radius: 9px;
    background: var(--card-active);
    box-shadow: 0 4px 14px rgba(139, 92, 246, 0.35);
    flex-shrink: 0;
}
.appearance-icon svg, .appearance-icon img { width: 100%; height: 100%; display: block; object-fit: cover; }
.appearance-titles { flex: 1; min-width: 0; }
.appearance-eyebrow { font-size: 9.5px; font-weight: 700; letter-spacing: .5px; text-transform: uppercase; color: var(--text-faint); }
.appearance-titles h2 { font-size: 14.5px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.native-badge {
    flex-shrink: 0;
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: .3px;
    text-transform: uppercase;
    padding: 3px 8px;
    border-radius: 6px;
    background: rgba(34, 197, 94, 0.16);
    color: #4ade80;
}

.appearance-cam-row {
    display: flex;
    gap: 10px;
    padding: 12px 18px;
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}
.cam-group { flex: 1; min-width: 0; }
.cam-group-label { font-size: 9.5px; font-weight: 700; letter-spacing: .5px; text-transform: uppercase; color: var(--text-faint); margin-bottom: 6px; }

.seg-control.tiny { gap: 5px; }
.seg-control.tiny .seg-btn {
    height: 34px;
    font-size: 10.5px;
    gap: 4px;
    border-radius: 8px;
}
.seg-control.tiny .seg-btn svg { width: 12px; height: 12px; }

.appearance-tabs {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 4px;
    padding: 10px 12px;
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}
.appearance-tab {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    height: 52px;
    border-radius: var(--radius-sm);
    background: transparent;
    border: 1px solid transparent;
    color: var(--text-faint);
    cursor: pointer;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: .2px;
    text-align: center;
    padding: 4px 2px;
    transition: background .15s var(--ease), color .15s var(--ease), border-color .15s var(--ease);
}
.appearance-tab svg { width: 16px; height: 16px; }
.appearance-tab:hover { background: var(--card-hover); color: var(--text); }
.appearance-tab.active { background: var(--accent-soft); border-color: var(--border-strong); color: var(--accent-2); }

.appearance-body { flex: 1; min-height: 0; overflow-y: auto; padding: 14px 18px 20px; display: flex; flex-direction: column; gap: 14px; }
/* tab content fades in on every switch, so changing tabs doesn't just
   hard-swap the whole panel contents */
.appearance-body > * { animation: fade-up .24s var(--ease) both; }
.appearance-body::-webkit-scrollbar { width: 6px; }
.appearance-body::-webkit-scrollbar-thumb { background: rgba(139, 92, 246, 0.25); border-radius: 3px; }

.appearance-section-title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .5px;
    text-transform: uppercase;
    color: var(--text-faint);
}
.appearance-section-title .count { color: var(--accent-2); }

/* generic slider row: label + numeric value + range input, used for face
   sculpt features, heritage mixes, overlay opacity */
.slider-row { display: flex; flex-direction: column; gap: 6px; }
.slider-row .slider-top { display: flex; align-items: center; justify-content: space-between; }
.slider-row .slider-label { font-size: 12px; font-weight: 700; color: var(--text-dim); }
.slider-row .slider-value { font-size: 11.5px; font-weight: 700; color: var(--accent-2); flex-shrink: 0; direction: ltr; }
.slider-row input[type="range"] {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    height: 6px;
    border-radius: 3px;
    background: var(--border-strong);
    outline: none;
    cursor: pointer;
}
.slider-row input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 15px; height: 15px;
    border-radius: 50%;
    background: var(--card-active);
    box-shadow: 0 2px 6px rgba(139, 92, 246, 0.4);
    cursor: pointer;
}

/* stepper: prev / value / next, used for parent ids, hair/drawable/texture
   indices, eye color - anything that's an integer index into a fixed list */
.stepper {
    display: flex;
    align-items: center;
    gap: 8px;
    height: 36px;
}

/* Arrow semantics follow reading direction, which is what players expect:
   "forward / increase" is the RIGHT arrow in English and the LEFT arrow in
   Arabic, because in RTL forward IS leftward. The row therefore keeps its
   natural direction (RTL flips which button sits on which side) and only
   the arrow glyphs are mirrored to match. The numeric value itself is
   pinned to ltr separately below so "0/45" never reorders. */
.stepper-btn.prev svg { transform: scaleX(-1); }
.stepper-btn.next svg { transform: none; }
[dir="rtl"] .stepper-btn.prev svg { transform: none; }
[dir="rtl"] .stepper-btn.next svg { transform: scaleX(-1); }
.stepper-btn {
    width: 30px; height: 30px;
    flex-shrink: 0;
    border-radius: 8px;
    border: 1px solid var(--border);
    background: var(--card);
    color: var(--text-dim);
    display: flex; align-items: center; justify-content: center;
    cursor: pointer;
}
.stepper-btn:hover { background: var(--card-hover); color: var(--text); border-color: var(--border-strong); }
.stepper-btn svg { width: 11px; height: 11px; }
.stepper-value {
    flex: 1;
    min-width: 0;
    text-align: center;
    font-size: 12.5px;
    font-weight: 700;
    color: var(--text);
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 8px;
    height: 30px;
    display: flex; align-items: center; justify-content: center;
    gap: 1px;
    transition: border-color .15s var(--ease);
    /* "12/45" is two Latin-digit runs joined by a neutral "/" - inside an
       RTL-direction ancestor the bidi algorithm can reorder those two runs
       around the neutral character (renders as "45/12"). Forcing ltr here
       keeps it in the order the DOM actually put it in, in both languages. */
    direction: ltr;
}
.stepper-value:focus-within { border-color: var(--accent); }
.stepper-value .max { color: var(--text-faint); font-weight: 600; flex-shrink: 0; }

/* the typed-in number itself - sized to its content so "0" and "/236"
   stay visually centred together as one unit */
.stepper-input {
    width: 3.5em;
    min-width: 0;
    text-align: right;
    background: none;
    border: none;
    outline: none;
    color: var(--text);
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 700;
    padding: 0;
}
.stepper-input::-webkit-outer-spin-button,
.stepper-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

.field-block { display: flex; flex-direction: column; gap: 6px; }
.field-block .field-label { font-size: 11px; font-weight: 700; color: var(--text-dim); }

.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

/* color swatches: hair/highlight/makeup color pickers - kept small and
   dense (small squares, ~15 per row) rather than a handful of oversized
   tiles, matching the reference layout instead of eating the whole panel */
.swatch-grid { display: grid; grid-template-columns: repeat(14, 1fr); gap: 3px; }
.color-swatch {
    width: 100%;
    aspect-ratio: 1;
    border-radius: 4px;
    border: 1px solid transparent;
    cursor: pointer;
    box-shadow: inset 0 0 0 1px rgba(0,0,0,0.15);
}
.color-swatch.active { border-color: #fff; box-shadow: 0 0 0 2px var(--accent); }

/* clothing/accessory component card */
.component-card, .overlay-row {
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--card);
    padding: 10px 12px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.component-card .component-label, .overlay-row .overlay-label {
    display: flex; align-items: center; justify-content: space-between;
    font-size: 12px; font-weight: 700; color: var(--text-dim);
}
.component-card .component-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.component-card .component-fields .field-label { font-size: 9.5px; color: var(--text-faint); margin-bottom: 3px; }

.overlay-row .overlay-colors { display: flex; gap: 5px; }

/* tattoos tab: zone header + wrapping chip list */
.tattoo-zone { display: flex; flex-direction: column; gap: 8px; }
.tattoo-zone-title {
    font-size: 10px; font-weight: 700; letter-spacing: .4px; text-transform: uppercase;
    color: var(--accent-2);
}
.tattoo-chip-list { display: flex; flex-wrap: wrap; gap: 6px; }
.tattoo-chip {
    padding: 6px 10px;
    border-radius: 7px;
    border: 1px solid var(--border);
    background: var(--card);
    color: var(--text-dim);
    font-size: 11px;
    font-weight: 600;
    cursor: pointer;
    transition: background .15s var(--ease), border-color .15s var(--ease), color .15s var(--ease);
}
.tattoo-chip:hover { background: var(--card-hover); border-color: var(--border-strong); }
.tattoo-chip.active { background: var(--card-active); border-color: transparent; color: #fff; }

.appearance-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 12px 18px;
    border-top: 1px solid var(--border);
    flex-shrink: 0;
}
.live-preview { display: flex; align-items: center; gap: 8px; min-width: 0; }
.live-dot { width: 8px; height: 8px; border-radius: 50%; background: #4ade80; animation: blink 1.4s ease-in-out infinite; flex-shrink: 0; }
.live-text { min-width: 0; }
.live-title { font-size: 11.5px; font-weight: 700; color: var(--text); }
.live-desc { font-size: 10px; color: var(--text-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.appearance-actions { display: flex; gap: 8px; flex-shrink: 0; }

/* ---------- Notifications ---------- */

/* bottom-left: the panel is docked right, so messages never sit on top of
   what they are reporting about. Stacks upward as more arrive. */
.notify-stack {
    position: fixed;
    left: 24px;
    bottom: 24px;
    display: flex;
    flex-direction: column-reverse;
    gap: 8px;
    z-index: 60;
    pointer-events: none;
    max-width: 340px;
}

.notify {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 14px;
    border-radius: var(--radius-sm);
    background: var(--panel);
    border: 1px solid var(--border);
    border-left: 3px solid var(--accent);
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
    color: var(--text);
    font-size: 12px;
    font-weight: 700;
    animation: notify-in .22s var(--ease) both;
}
.notify.leaving { animation: notify-out .2s var(--ease) forwards; }

[dir="rtl"] .notify { border-left-width: 1px; border-right: 3px solid var(--accent); }

.notify-icon { display: flex; flex-shrink: 0; }
.notify-icon svg { width: 15px; height: 15px; }
.notify-text { min-width: 0; line-height: 1.35; }

.notify.success { border-left-color: var(--c-green); }
.notify.success .notify-icon { color: var(--c-green); }
[dir="rtl"] .notify.success { border-right-color: var(--c-green); }

.notify.error { border-left-color: var(--c-red); }
.notify.error .notify-icon { color: var(--c-red); }
[dir="rtl"] .notify.error { border-right-color: var(--c-red); }

.notify.info { border-left-color: var(--c-blue); }
.notify.info .notify-icon { color: var(--c-blue); }
[dir="rtl"] .notify.info { border-right-color: var(--c-blue); }

@keyframes notify-in  { from { opacity: 0; transform: translateX(-16px); } to { opacity: 1; transform: none; } }
@keyframes notify-out { to { opacity: 0; transform: translateX(-16px); } }
[dir="rtl"] .notify { animation-name: notify-in-rtl; }
[dir="rtl"] .notify.leaving { animation-name: notify-out-rtl; }
@keyframes notify-in-rtl  { from { opacity: 0; transform: translateX(16px); } to { opacity: 1; transform: none; } }
@keyframes notify-out-rtl { to { opacity: 0; transform: translateX(16px); } }

/* ---------- Animations ---------- */

/* Three columns, one per toggle pair (Normal/Loop, Fly/Ground,
   All/Favorites) - each choice's two options stack in their own column so
   related buttons read as a group. Two rows total also keeps the list from
   starting too far down the panel. */
.anim-filters { display: grid; grid-template-columns: repeat(3, 1fr); gap: 5px; margin-bottom: 8px; }
.filter-group { display: flex; flex-direction: column; gap: 5px; }

.filter-pill {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    height: 32px;
    border-radius: var(--radius-sm);
    background: var(--card);
    border: 1px solid var(--border);
    color: var(--text-dim);
    font-family: inherit;
    font-size: 11.5px;
    font-weight: 700;
    cursor: pointer;
    transition: background .15s var(--ease), border-color .15s var(--ease), color .15s var(--ease);
}
.filter-pill svg { width: 13px; height: 13px; }
.filter-pill:hover { background: var(--card-hover); color: var(--text); }
/* amber rather than the panel purple, so an enabled filter never reads as
   "this tab is selected" - matches the reference layout */
.filter-pill.active {
    background: color-mix(in srgb, var(--c-amber) 16%, transparent);
    border-color: color-mix(in srgb, var(--c-amber) 45%, transparent);
    color: var(--c-amber);
}

.anim-count {
    font-size: 10.5px;
    color: var(--text-faint);
    padding: 2px 2px 8px;
    border-bottom: 1px solid var(--border);
    margin-bottom: 8px;
    animation: fade-up .26s var(--ease) both .06s;
}

/* the filter block eases in with the tab too, so entering Animations
   animates as a whole instead of the rows appearing under a static header */
.anim-filters .filter-group { animation: fade-up .26s var(--ease) both; }
.anim-filters .filter-group:nth-child(2) { animation-delay: .04s; }
.anim-filters .filter-group:nth-child(3) { animation-delay: .08s; }

.anim-item {
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 12px;
    border-radius: var(--radius-sm);
    background: var(--card);
    border: 1px solid var(--border);
    cursor: pointer;
    opacity: 0;
    animation: fade-up .24s var(--ease) forwards;
    animation-delay: calc(var(--i) * 10ms);
    transition: background .15s var(--ease), border-color .15s var(--ease);
}

/* Loading bar: fills across the bottom of the hovered row for exactly the
   debounce duration, so the short wait before the preview ped appears
   reads as progress rather than as a dead pause. Duration is kept in sync
   with PREVIEW_DEBOUNCE_MS in script.js. */
.anim-item::after {
    content: '';
    position: absolute;
    left: 0;
    bottom: 0;
    height: 2px;
    width: 0;
    background: linear-gradient(90deg, var(--c-amber), var(--accent-2));
    border-radius: 2px;
    opacity: 0;
}
.anim-item.previewing::after {
    animation: anim-preview-load 260ms var(--ease) forwards;
}
@keyframes anim-preview-load {
    from { width: 0; opacity: 1; }
    to   { width: 100%; opacity: 1; }
}
.anim-item:hover { background: var(--card-hover); border-color: color-mix(in srgb, var(--c-amber) 40%, transparent); }

.anim-item-main { flex: 1; min-width: 0; }
.anim-item-name {
    font-size: 12.5px;
    font-weight: 700;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    /* animation names are engine identifiers - never mirrored by RTL */
    direction: ltr;
    text-align: left;
}
.anim-item-dict {
    font-size: 10px;
    color: var(--c-amber);
    opacity: .75;
    margin-top: 2px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    direction: ltr;
    text-align: left;
}

/* Custom Anims: the label is human-written so it follows page direction,
   unlike the raw engine identifiers in the Animations tab */
.custom-label { direction: inherit; text-align: inherit; }

/* Own grid definition: .filter-row lost its rule when the Animations
   filters were rebuilt as columns, which left this category row with no
   layout at all - the four pills fell back to stacking as plain blocks. */
.cat-row {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 5px;
    margin-bottom: 8px;
}
.cat-pill { font-size: 10.5px; padding: 0 4px; }
.cat-pill span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.cat-tag {
    flex-shrink: 0;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: .3px;
    text-transform: uppercase;
    padding: 3px 7px;
    border-radius: 5px;
}
.cat-tag.cat-dances { background: color-mix(in srgb, var(--c-pink) 16%, transparent); color: var(--c-pink); }
.cat-tag.cat-emotes { background: color-mix(in srgb, var(--c-blue) 16%, transparent); color: var(--c-blue); }
.cat-tag.cat-props  { background: color-mix(in srgb, var(--c-green) 16%, transparent); color: var(--c-green); }

.prop-tag { display: flex; color: var(--text-faint); flex-shrink: 0; }
.prop-tag svg { width: 12px; height: 12px; }

/* the little play glyph only shows on hover, hinting the row is clickable */
.anim-play-hint { display: flex; color: var(--text-faint); opacity: 0; transition: opacity .15s var(--ease); flex-shrink: 0; }
.anim-play-hint svg { width: 12px; height: 12px; }
.anim-item:hover .anim-play-hint { opacity: 1; color: var(--c-amber); }

/* ---------- My Peds ---------- */

.my-peds-form { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; margin-bottom: 16px; }

.settings-btn:disabled { opacity: .5; cursor: not-allowed; pointer-events: none; }

.new-folder-btn {
    align-self: flex-start;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 28px;
    padding: 0 10px;
    border-radius: 7px;
    border: 1px solid var(--border);
    background: var(--card);
    color: var(--text-dim);
    font-size: 10.5px;
    font-weight: 700;
    cursor: pointer;
    transition: background .15s var(--ease), color .15s var(--ease);
}
.new-folder-btn svg { width: 11px; height: 11px; }
.new-folder-btn:hover { background: var(--card-hover); color: var(--text); }

.ped-name-row { display: flex; gap: 8px; }
.ped-name-row input {
    flex: 1;
    width: 0;
    height: 42px;
    padding: 0 14px;
    border-radius: var(--radius-sm);
    background: var(--card);
    border: 1px solid var(--border);
    color: var(--text);
    font-size: 12.5px;
    outline: none;
}
.ped-name-row input:focus { border-color: var(--accent); }
.ped-name-row input::placeholder { color: var(--text-faint); }

.gender-toggle { display: flex; gap: 6px; flex-shrink: 0; }
.gender-btn {
    width: 42px; height: 42px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    background: var(--card);
    color: var(--text-faint);
    display: flex; align-items: center; justify-content: center;
    cursor: pointer;
    transition: background .15s var(--ease), border-color .15s var(--ease), color .15s var(--ease);
}
.gender-btn svg { width: 16px; height: 16px; }
.gender-btn:hover { background: var(--card-hover); color: var(--text); }
.gender-btn.active { background: var(--card-active); border-color: transparent; color: #fff; }

.settings-btn.primary-btn { background: var(--card-active); border-color: transparent; color: #fff; box-shadow: 0 6px 16px rgba(139, 92, 246, 0.28); }
.settings-btn.primary-btn:hover { filter: brightness(1.08); background: var(--card-active); }

.new-folder-row, .inline-edit-row {
    display: flex;
    align-items: center;
    gap: 8px;
}
.new-folder-row input, .inline-edit-row input, .inline-edit-row select {
    flex: 1;
    width: 0;
    height: 38px;
    padding: 0 12px;
    border-radius: var(--radius-sm);
    background: var(--card);
    border: 1px solid var(--border-strong);
    color: var(--text);
    font-size: 12.5px;
    font-family: inherit;
    outline: none;
}

.icon-confirm-btn, .icon-cancel-btn {
    width: 34px; height: 34px;
    flex-shrink: 0;
    border-radius: 8px;
    border: none;
    display: flex; align-items: center; justify-content: center;
    cursor: pointer;
}
.icon-confirm-btn svg, .icon-cancel-btn svg { width: 14px; height: 14px; }
.icon-confirm-btn { background: var(--card-active); color: #fff; }
.icon-confirm-btn:hover { filter: brightness(1.08); }
.icon-cancel-btn { background: var(--danger-soft); color: #f87171; }
.icon-cancel-btn:hover { background: rgba(239, 68, 68, 0.22); }

.folder-header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 2px 4px;
    color: var(--text-faint);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .3px;
}
.folder-header svg { width: 13px; height: 13px; color: var(--accent-2); }
.folder-header .count-badge { margin-inline-start: auto; }

/* staggered entrance: rows cascade in instead of all appearing at once */
.ped-list { display: flex; flex-direction: column; gap: 6px; }
.ped-list > .ped-row:nth-child(1) { animation-delay: 0ms; }
.ped-list > .ped-row:nth-child(2) { animation-delay: 35ms; }
.ped-list > .ped-row:nth-child(3) { animation-delay: 70ms; }
.ped-list > .ped-row:nth-child(4) { animation-delay: 105ms; }
.ped-list > .ped-row:nth-child(5) { animation-delay: 140ms; }
.ped-list > .ped-row:nth-child(n+6) { animation-delay: 170ms; }

/* the create form itself slides in when the tab opens */
.my-peds-form { animation: fade-up .3s var(--ease) both; }

.ped-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    background: var(--card);
    border: 1px solid var(--border);
    /* every row eases in rather than snapping into place */
    opacity: 0;
    animation: fade-up .26s var(--ease) forwards;
    transition: background .15s var(--ease), border-color .15s var(--ease), transform .12s var(--ease);
}
.ped-row:hover { background: var(--card-hover); border-color: var(--border-strong); }

/* folder row: clickable as a whole, with a chevron hinting you go into it */
.folder-row { cursor: pointer; }
.folder-row:hover { transform: translateX(2px); }
[dir="rtl"] .folder-row:hover { transform: translateX(-2px); }

/* matches the scene-row category chip size so folders don't look like a
   different, smaller kind of row */
.folder-icon {
    width: 36px; height: 36px;
    border-radius: 10px;
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
    background: color-mix(in srgb, var(--c-amber) 18%, transparent);
    color: var(--c-amber);
}
.folder-icon svg { width: 19px; height: 19px; }

.folder-row { padding: 9px 12px; }
.folder-row .ped-row-info { flex: 1; }
/* actions stay quiet until the row is hovered, so the row reads as
   "a folder you open" first and a set of buttons second */
.folder-row .ped-actions { opacity: 0; transition: opacity .15s var(--ease); }
.folder-row:hover .ped-actions { opacity: 1; }

.folder-chevron { display: flex; color: var(--text-faint); flex-shrink: 0; }
.folder-chevron svg { width: 15px; height: 15px; }
[dir="rtl"] .folder-chevron svg { transform: scaleX(-1); }

/* header shown while browsing inside a folder */
.folder-crumb {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 4px 10px;
    margin-bottom: 2px;
    border-bottom: 1px solid var(--border);
}
.folder-crumb .back-chip {
    width: 30px; height: 30px;
    flex-shrink: 0;
    border-radius: 8px;
    border: 1px solid var(--border);
    background: var(--card);
    color: var(--text-dim);
    display: flex; align-items: center; justify-content: center;
    cursor: pointer;
}
.folder-crumb .back-chip:hover { background: var(--card-hover); color: var(--text); }
.folder-crumb .back-chip svg { width: 13px; height: 13px; transform: scaleX(-1); }
[dir="rtl"] .folder-crumb .back-chip svg { transform: scaleX(1); }
.folder-crumb .folder-icon { width: 32px; height: 32px; }
.folder-crumb .folder-icon svg { width: 17px; height: 17px; }
.ped-row-info { min-width: 0; }
.ped-row-name { font-size: 13px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ped-row-gender { display: flex; align-items: center; gap: 4px; font-size: 10.5px; color: var(--text-faint); margin-top: 2px; }
.ped-row-gender svg { width: 11px; height: 11px; }

.ped-actions { display: flex; align-items: center; gap: 2px; flex-shrink: 0; }
.ped-icon-btn {
    width: 26px; height: 26px;
    border-radius: 6px;
    border: none;
    background: transparent;
    color: var(--text-faint);
    display: flex; align-items: center; justify-content: center;
    cursor: pointer;
    transition: background .15s var(--ease), color .15s var(--ease);
}
.ped-icon-btn svg { width: 13px; height: 13px; }
.ped-icon-btn:hover { background: var(--accent-soft); color: #c9b8ff; }
.ped-icon-btn.danger:hover { background: var(--danger-soft); color: #f87171; }

.confirm-row {
    display: flex;
    align-items: center;
    gap: 8px;
    background: var(--danger-soft);
    border-color: rgba(239, 68, 68, 0.3);
}
.confirm-row .confirm-icon { color: #f87171; flex-shrink: 0; display: flex; }
.confirm-row .confirm-icon svg { width: 15px; height: 15px; }
.confirm-row .confirm-text { flex: 1; min-width: 0; font-size: 12px; font-weight: 700; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.confirm-row .confirm-actions { display: flex; gap: 6px; flex-shrink: 0; }








/* stand-in for a real thumbnail render (no per-model image pipeline yet) -
   a kind-tinted icon so the bar isn't bare text next to the buttons */
.ghost-icon {
    width: 34px; height: 34px; border-radius: 9px; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    background: var(--accent-soft); color: var(--accent-2);
}
.ghost-icon svg { width: 18px; height: 18px; }
.modal-btn.engine { background: color-mix(in srgb, var(--c-green) 18%, transparent); border-color: color-mix(in srgb, var(--c-green) 45%, transparent); color: var(--c-green); }
.modal-btn.replace { background: color-mix(in srgb, var(--c-orange) 18%, transparent); border-color: color-mix(in srgb, var(--c-orange) 45%, transparent); color: var(--c-orange); }

.sc-head { display: flex; align-items: center; gap: 10px; }
.sc-icon {
    width: 30px; height: 30px; border-radius: 9px; flex-shrink: 0; background: var(--card-active);
    box-shadow: 0 4px 14px color-mix(in srgb, var(--accent) 55%, transparent);
    transition: background .25s var(--ease), box-shadow .25s var(--ease);
}
.sc-titles { flex: 1; min-width: 0; }
.sc-eyebrow { font-size: 9px; font-weight: 700; letter-spacing: .5px; text-transform: uppercase; color: var(--text-faint); }
.sc-title { font-size: 14px; font-weight: 700; }
.sc-modes { display: flex; gap: 6px; }
.sc-mode {
    height: 28px; padding: 0 11px; border-radius: 7px; border: 1px solid var(--border);
    background: var(--card); color: var(--text-dim);
    font-family: inherit; font-size: 10.5px; font-weight: 700; letter-spacing: .3px; text-transform: uppercase; cursor: pointer;
    display: inline-flex; align-items: center; gap: 6px;
    opacity: 0; animation: fade-up .2s var(--ease) forwards; animation-delay: calc(var(--mi, 0) * 30ms);
    transition: background .15s var(--ease), color .15s var(--ease), border-color .15s var(--ease);
}
.sc-mode:hover { background: var(--card-hover); color: var(--text); }
.sc-mode.active {
    background: color-mix(in srgb, var(--accent) 18%, transparent);
    border-color: color-mix(in srgb, var(--accent) 45%, transparent); color: var(--accent-2);
}
.sc-mode.cam.active {
    background: color-mix(in srgb, var(--c-amber) 16%, transparent);
    border-color: color-mix(in srgb, var(--c-amber) 45%, transparent); color: var(--c-amber);
}
.sc-mode.cam svg, .sc-mode svg { width: 13px; height: 13px; }

.sc-transform { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.sc-group {
    display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-radius: var(--radius-sm);
    background: var(--card); border: 1px solid var(--border); direction: ltr;
    opacity: 0; animation: fade-up .2s var(--ease) forwards;
}
.sc-group-label { font-size: 9px; font-weight: 700; letter-spacing: .4px; text-transform: uppercase; color: var(--text-faint); flex-shrink: 0; }
.sc-axis { display: flex; align-items: baseline; gap: 3px; font-size: 11px; font-weight: 700; transition: color .12s var(--ease); }
.sc-axis .k { font-size: 9px; }
.sc-axis.x .k { color: var(--c-red); }
.sc-axis.y .k { color: var(--c-green); }
.sc-axis.z .k { color: var(--c-blue); }

.sc-keys { display: flex; flex-wrap: wrap; gap: 5px 8px; }
.sc-key {
    display: inline-flex; align-items: center; gap: 5px; font-size: 10px; color: var(--text-faint);
    opacity: 0; animation: fade-up .18s var(--ease) forwards; animation-delay: calc(var(--ki, 0) * 18ms);
}
.sc-key kbd { background: var(--card); border: 1px solid var(--border); border-radius: 4px; padding: 2px 6px; font-size: 9px; font-family: inherit; font-weight: 700; color: var(--text-dim); }

.insp-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 12px 14px; border-bottom: 1px solid var(--border); }
.insp-title { font-size: 11px; font-weight: 700; letter-spacing: .5px; text-transform: uppercase; color: var(--text-dim); }
.insp-count { font-size: 10.5px; font-weight: 700; color: var(--accent-2); }
.insp-body { flex: 1; min-height: 0; overflow-y: auto; padding: 14px; display: flex; flex-direction: column; gap: 14px; }
.insp-body > * { animation: fade-up .22s var(--ease) both; }
.insp-body > *:nth-child(2) { animation-delay: .03s; }
.insp-body > *:nth-child(3) { animation-delay: .06s; }
.insp-body > *:nth-child(4) { animation-delay: .09s; }
.insp-body > *:nth-child(n+5) { animation-delay: .12s; }
.insp-body::-webkit-scrollbar { width: 6px; }
.insp-body::-webkit-scrollbar-thumb { background: rgba(139, 92, 246, 0.25); border-radius: 3px; }
.insp-section-title { font-size: 9.5px; font-weight: 700; letter-spacing: .5px; text-transform: uppercase; color: var(--text-faint); margin-bottom: 7px; }
/* X/Y/Z is an axis triple, not prose - it must stay in that order and
   stay left-aligned even under RTL, or the columns reorder to Z/Y/X and
   the labels drift away from their own inputs. */
.insp-vec { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; direction: ltr; text-align: left; }
.insp-field { display: flex; flex-direction: column; gap: 3px; direction: ltr; text-align: left; }
.insp-field label { font-size: 9px; font-weight: 700; color: var(--text-faint); text-align: left; }
.insp-field.x label { color: var(--c-red); }
.insp-field.y label { color: var(--c-green); }
.insp-field.z label { color: var(--c-blue); }
.insp-field input {
    height: 30px; width: 100%; padding: 0 6px; border-radius: 7px; background: var(--bg);
    border: 1px solid var(--border); color: var(--text);
    font-family: inherit; font-size: 10.5px; font-weight: 700; outline: none; min-width: 0;
    overflow: hidden; text-overflow: ellipsis;
}
.insp-field input:focus { border-color: var(--accent); }
.insp-row { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.insp-btn {
    height: 32px; display: flex; align-items: center; justify-content: center; gap: 5px;
    border-radius: 8px; border: 1px solid var(--border); background: var(--card); color: var(--text);
    font-family: inherit; font-size: 11px; font-weight: 700; cursor: pointer;
    transition: background .15s var(--ease), border-color .15s var(--ease);
}
.insp-btn:hover:not(:disabled) { background: var(--card-hover); border-color: var(--border-strong); }
.insp-btn:disabled { opacity: .4; cursor: not-allowed; }
.insp-btn.primary { background: var(--card-active); border-color: transparent; color: #fff; }
.insp-btn.danger { background: var(--danger-soft); border-color: rgba(239,68,68,0.3); color: #f87171; }
.insp-btn.toggle.on {
    background: color-mix(in srgb, var(--c-teal) 18%, transparent);
    border-color: color-mix(in srgb, var(--c-teal) 45%, transparent); color: var(--c-teal);
}
.insp-slider-row { display: flex; align-items: center; gap: 10px; }
.insp-slider-row input[type="range"] {
    flex: 1; -webkit-appearance: none; appearance: none; height: 5px; border-radius: 3px;
    background: var(--border-strong); outline: none; cursor: pointer;
}
.insp-slider-row input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none; appearance: none; width: 14px; height: 14px; border-radius: 50%;
    background: var(--card-active); box-shadow: 0 2px 6px rgba(139,92,246,.4); cursor: pointer;
}
.insp-slider-val { font-size: 11px; font-weight: 700; color: var(--accent-2); width: 44px; text-align: end; direction: ltr; }
.insp-empty { text-align: center; color: var(--text-faint); font-size: 11.5px; padding: 26px 8px; line-height: 1.6; }

/* ---------- Bot Control ----------
   Same full-screen-layer pattern as Object Spooner (own leading-edge
   catalogue), reusing the same tokens/animations - this round is Actors
   only, so there's no inspector or bottom bar yet. */

/* Bot Control's own stylesheet lives in web/bot/style.css - it is a separate
   document inside the frame, so nothing in it can reach these rules. */
.bot-frame {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
    display: none;
    background: transparent;
    z-index: 20;
}
.bot-frame.visible { display: block; }

/* ---------- Animations ---------- */

@keyframes pop-in { from { opacity: 0; transform: translateY(6px) scale(.96); } to { opacity: 1; transform: translateY(0) scale(1); } }
@keyframes fade-up { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }
@keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }

/* ---------- World Control ---------- */

.world-view { display: flex; flex-direction: column; gap: 10px; padding: 2px 2px 18px; }

/* The cards come in staggered, the same way animation rows and menu tiles
   do. This tab was the only one that simply appeared. */
.world-view > * {
    opacity: 0;
    animation: fade-up .26s var(--ease) forwards;
}
.world-view > *:nth-child(1) { animation-delay: 0ms; }
.world-view > *:nth-child(2) { animation-delay: 40ms; }
.world-view > *:nth-child(3) { animation-delay: 80ms; }
.world-view > *:nth-child(4) { animation-delay: 120ms; }
.world-view > *:nth-child(5) { animation-delay: 160ms; }
.world-view > *:nth-child(6) { animation-delay: 200ms; }
.world-view > *:nth-child(n+7) { animation-delay: 240ms; }

.w-note {
    display: flex; align-items: flex-start; gap: 8px;
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    background: var(--accent-soft);
    border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
    font-size: 10.5px; line-height: 1.65;
    color: var(--text-dim);
}
.w-note svg { width: 14px; height: 14px; flex: none; margin-top: 1px; color: var(--accent-2); }

.w-card {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 12px 13px 14px;
    display: flex; flex-direction: column; gap: 10px;
}
.w-card-head {
    display: flex; align-items: center; gap: 8px;
    font-size: 10px; font-weight: 800; letter-spacing: 1.2px;
    color: var(--text-faint);
}
.w-card-head svg { width: 14px; height: 14px; color: var(--accent-2); }

/* ---- weather ---- */

.w-weather { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.w-wx {
    display: flex; flex-direction: column; align-items: center; gap: 5px;
    padding: 10px 4px 8px;
    border-radius: var(--radius-sm);
    background: var(--bg);
    border: 1px solid var(--border);
    color: var(--text-dim);
}
.w-wx:hover { background: var(--card-hover); color: var(--text); }
.w-wx.active {
    background: var(--card-active);
    border-color: transparent;
    color: #fff;
    box-shadow: 0 6px 18px rgba(139, 92, 246, .28);
}
.w-wx-emoji { font-size: 19px; line-height: 1; }
.w-wx-name { font-size: 9.5px; font-weight: 700; }

/* ---- time ---- */

.w-clock { text-align: center; padding: 2px 0 4px; }
.w-clock-time {
    font-size: 34px; font-weight: 800; line-height: 1;
    letter-spacing: 1px;
    color: var(--text);
    direction: ltr;
    font-variant-numeric: tabular-nums;
}
.w-clock-phase { font-size: 10.5px; font-weight: 700; color: var(--accent-2); margin-top: 4px; }

/* The strip's fill is the sky at that hour, so the handle sits in a colour
   you can read at a glance instead of a number you have to translate. */
.w-daystrip { display: flex; flex-direction: column; gap: 4px; }
.w-daystrip input[type="range"] {
    -webkit-appearance: none; appearance: none;
    width: 100%; height: 26px;
    border-radius: 8px;
    border: 1px solid var(--border);
    outline: none;
    direction: ltr;
}
.w-daystrip input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none; appearance: none;
    width: 8px; height: 34px;
    border-radius: 4px;
    background: #fff;
    border: 2px solid rgba(0,0,0,.55);
    cursor: ew-resize;
    box-shadow: 0 2px 10px rgba(0,0,0,.6);
}
.w-daystrip-marks {
    display: flex; justify-content: space-between;
    font-size: 8.5px; font-weight: 700; color: var(--text-faint);
    direction: ltr;
    padding: 0 2px;
}

.w-presets { display: grid; grid-template-columns: repeat(3, 1fr); gap: 5px; }
.w-preset {
    padding: 7px 4px;
    border-radius: 8px;
    background: var(--bg);
    border: 1px solid var(--border);
    color: var(--text-dim);
    font-size: 10px; font-weight: 700;
}
.w-preset:hover { background: var(--card-hover); color: var(--text); }
.w-preset.active { background: var(--accent-soft); border-color: var(--accent); color: var(--text); }

/* ---- shared controls ---- */

.w-slider { display: flex; flex-direction: column; gap: 6px; }
.w-slider-top {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    font-size: 11px; font-weight: 700; color: var(--text-dim);
}
.w-slider-top.plain { margin-bottom: -2px; }
.w-value {
    font-size: 11px; font-weight: 800;
    color: var(--accent-2);
    font-variant-numeric: tabular-nums;
    direction: ltr;
}

.w-toggle { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.w-toggle-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.w-toggle-label { font-size: 11.5px; font-weight: 700; color: var(--text-dim); }
.w-toggle-desc { font-size: 9.5px; line-height: 1.5; color: var(--text-faint); }

.w-btn {
    display: flex; align-items: center; justify-content: center; gap: 7px;
    padding: 10px;
    border-radius: var(--radius-sm);
    background: var(--bg);
    border: 1px solid var(--border);
    color: var(--text-dim);
    font-size: 11.5px; font-weight: 700;
}
.w-btn:hover { background: var(--card-hover); color: var(--text); }
.w-btn svg { width: 14px; height: 14px; }
.w-btn.danger { background: var(--danger-soft); color: var(--danger); border-color: transparent; }
.w-btn.danger:hover { background: var(--danger); color: #fff; }

.w-hint { font-size: 9.5px; line-height: 1.6; color: var(--text-faint); }

/* ---------- Effects ---------- */

/* The tab itself borrows the animation-list furniture (.anim-filters,
   .anim-item, .anim-count, .scene-list) so it reads as part of the same
   script rather than a bolted-on screen. Only what is genuinely new to
   effects is defined here. */

/* The All / Favourites switch. Reuses the panel's segmented control
   rather than .anim-filters: that grid is sized for the Animations tab's
   three pairs, and a lone pair in it collapsed into a narrow stack. */
.fx-seg { margin-bottom: 10px; animation: fade-up .26s var(--ease) both; }
.fx-seg .seg-btn { height: 34px; font-size: 11.5px; }
.fx-seg .seg-btn svg { width: 13px; height: 13px; }

.fx-card { margin-bottom: 10px; }
.fx-hint { font-size: 9.5px; line-height: 1.6; color: var(--text-faint); margin-top: 2px; }

.fx-item .anim-item-name,
.fx-item .anim-item-dict { direction: ltr; text-align: start; }

.fx-item.previewing {
    border-color: var(--accent-2);
    background: var(--accent-soft);
}

.fx-place-btn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    flex: none;
    height: 26px;
    padding: 0 10px;
    border-radius: 7px;
    border: 1px solid var(--accent);
    background: var(--accent-soft);
    color: #c9b8ff;
    font-family: inherit;
    font-size: 10px;
    font-weight: 800;
    letter-spacing: .3px;
    text-transform: uppercase;
    cursor: pointer;
    transition: background .15s var(--ease), color .15s var(--ease);
}
.fx-place-btn svg { width: 12px; height: 12px; }
.fx-place-btn:hover { background: var(--accent); color: #fff; }

/* ---------- Effects bar (top of the panel, every tab) ----------
   Sits directly under Now Playing and behaves the same way: it is the
   thing you reach for while a shot is running, so it must never be more
   than one glance away, whatever tab is open. */

.fx-bar {
    display: none;
    margin: 0 18px 12px;
    padding: 10px 12px 11px;
    border-radius: var(--radius-sm);
    background: var(--card);
    border: 1px solid var(--border);
    animation: fade-up .22s var(--ease) both;
}
.fx-bar.visible { display: block; }

.fx-bar-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 8px;
}

.fx-bar-label {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 10px;
    font-weight: 800;
    letter-spacing: .5px;
    text-transform: uppercase;
    color: var(--accent-2);
}
.fx-bar-dot {
    width: 7px; height: 7px;
    border-radius: 50%;
    background: var(--accent-2);
    animation: blink 1.4s ease-in-out infinite;
}

.fx-bar-clear {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 24px;
    padding: 0 9px;
    border-radius: 7px;
    border: 1px solid rgba(239, 68, 68, 0.35);
    background: var(--danger-soft);
    color: #f87171;
    font-family: inherit;
    font-size: 10px;
    font-weight: 800;
    letter-spacing: .3px;
    text-transform: uppercase;
    cursor: pointer;
    transition: background .15s var(--ease);
}
.fx-bar-clear svg { width: 11px; height: 11px; }
.fx-bar-clear:hover { background: rgba(239, 68, 68, 0.22); }

/* capped so a dozen placed effects cannot push the whole menu off screen */
.fx-bar-list {
    display: flex;
    flex-direction: column;
    gap: 5px;
    max-height: 168px;
    overflow-y: auto;
}
.fx-bar-list::-webkit-scrollbar { width: 5px; }
.fx-bar-list::-webkit-scrollbar-thumb { background: rgba(139, 92, 246, 0.25); border-radius: 3px; }
.fx-bar-list::-webkit-scrollbar-track { background: transparent; }

.fx-chip {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    border-radius: 8px;
    background: var(--panel);
    border: 1px solid var(--border);
    border-inline-start: 2px solid var(--text-faint);
    transition: border-color .15s var(--ease);
}
.fx-chip.live { border-inline-start-color: var(--accent-2); }

.fx-chip-main { flex: 1; min-width: 0; }
.fx-chip-name {
    font-size: 11px;
    font-weight: 700;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    direction: ltr;
    text-align: start;
}
.fx-chip-sub {
    font-size: 9px;
    color: var(--text-faint);
    margin-top: 1px;
    direction: ltr;
    text-align: start;
}

/* The trigger. Deliberately the biggest, leftmost thing in the row - it is
   the button that gets hit on a cue. */
.fx-chip-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 30px; height: 30px;
    border-radius: 8px;
    border: 1px solid var(--border);
    background: var(--card-hover);
    color: var(--text-dim);
    cursor: pointer;
    transition: background .15s var(--ease), color .15s var(--ease), border-color .15s var(--ease);
}
.fx-chip-toggle svg { width: 13px; height: 13px; }
.fx-chip-toggle:hover { border-color: var(--border-strong); color: var(--text); }
.fx-chip.live .fx-chip-toggle {
    background: var(--accent-soft);
    border-color: var(--accent);
    color: #c9b8ff;
    box-shadow: 0 0 10px rgba(139, 92, 246, 0.25);
}

.fx-chip-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 26px; height: 26px;
    border-radius: 7px;
    border: 1px solid var(--border);
    background: transparent;
    color: var(--text-faint);
    cursor: pointer;
    transition: background .15s var(--ease), color .15s var(--ease);
}
.fx-chip-btn svg { width: 12px; height: 12px; }
.fx-chip-btn:hover { background: var(--accent); border-color: var(--accent); color: #fff; }
.fx-chip-btn.danger:hover { background: var(--danger); border-color: var(--danger); color: #fff; }

/* ============================================================
   Cinematic Director
   ============================================================ */

/* .icon-btn had no standalone rule at all - it was only ever styled inside
   .ped-modal-header. Used anywhere else it rendered as an unstyled button
   with a zero-size icon: a bare white outline with nothing in it, which is
   what turned every row action into a "white line". The header keeps its own
   more specific rule, so nothing there changes. */
.icon-btn {
    flex: none;
    display: inline-flex; align-items: center; justify-content: center;
    width: 26px; height: 26px;
    border-radius: 7px;
    border: 1px solid var(--border);
    background: transparent;
    color: var(--text-faint);
    cursor: pointer;
    transition: background .15s var(--ease), color .15s var(--ease), border-color .15s var(--ease);
}
.icon-btn svg { width: 13px; height: 13px; flex: none; }
.icon-btn:hover { background: var(--card-hover); border-color: var(--border-strong); color: var(--text); }
.icon-btn.danger:hover { background: var(--danger); border-color: var(--danger); color: #fff; }

/* Icons inside flex rows shrink to nothing unless told not to. */
.cine-view svg, .cine-modal svg { flex: none; }

.cine-view { display: flex; flex-direction: column; gap: 10px; padding: 2px 2px 18px; }

.cine-new {
    display: flex; align-items: center; justify-content: center; gap: 8px;
    height: 40px; border-radius: var(--radius-sm);
    background: var(--card-active); border: none; color: #fff;
    font-family: inherit; font-size: 12.5px; font-weight: 800; cursor: pointer;
    box-shadow: 0 6px 18px rgba(139, 92, 246, .3);
}
.cine-new svg { width: 15px; height: 15px; }

.cine-projects { display: flex; flex-direction: column; gap: 6px; }
.cine-project {
    display: flex; align-items: center; gap: 8px;
    padding: 10px 12px; border-radius: var(--radius-sm);
    background: var(--card); border: 1px solid var(--border); cursor: pointer;
    opacity: 0; animation: fade-up .24s var(--ease) forwards;
    animation-delay: calc(var(--i) * 12ms);
}
.cine-project:hover { background: var(--card-hover); border-color: var(--border-strong); }
.cine-project-main { flex: 1; min-width: 0; }
.cine-project-name { font-size: 12.5px; font-weight: 700; }
.cine-project-meta { font-size: 10px; color: var(--text-faint); margin-top: 2px; }

.cine-name-row { display: flex; gap: 6px; }
.cine-name-row input {
    flex: 1; height: 34px; padding: 0 10px;
    border-radius: var(--radius-sm); background: var(--card);
    border: 1px solid var(--accent); color: var(--text);
    font-family: inherit; font-size: 12px;
}
.cine-name-ok, .cine-name-cancel {
    width: 34px; height: 34px; border-radius: var(--radius-sm);
    display: flex; align-items: center; justify-content: center;
    border: 1px solid var(--border); background: var(--card);
    color: var(--text-dim); cursor: pointer;
}
.cine-name-ok { background: var(--accent); border-color: var(--accent); color: #fff; }
.cine-name-ok svg, .cine-name-cancel svg { width: 14px; height: 14px; }

.cine-head { display: flex; align-items: center; gap: 8px; }
.cine-title { flex: 1; display: flex; align-items: center; gap: 7px; font-size: 13px; font-weight: 800; }
.cine-title svg { width: 15px; height: 15px; color: var(--accent-2); }

.cine-entries-label {
    font-size: 9.5px; font-weight: 800; letter-spacing: .5px;
    text-transform: uppercase; color: var(--text-faint);
}
.cine-entries { display: flex; flex-direction: column; gap: 6px; }

.cine-entry {
    padding: 9px 10px; border-radius: var(--radius-sm);
    background: var(--card); border: 1px solid var(--border);
    border-inline-start: 2px solid var(--text-faint);
    display: flex; flex-direction: column; gap: 7px;
    opacity: 0; animation: fade-up .24s var(--ease) forwards;
    animation-delay: calc(var(--i) * 12ms);
}
.cine-entry.live { border-inline-start-color: var(--accent-2); }
.cine-entry-top { display: flex; align-items: center; gap: 7px; }
.cine-entry-name { flex: 1; min-width: 0; font-size: 11.5px; font-weight: 700;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cine-entry-pos {
    display: inline-flex; align-items: center; gap: 3px;
    font-size: 9px; color: var(--text-faint); direction: ltr;
}
.cine-entry-pos svg { width: 10px; height: 10px; }

.cine-badge {
    flex: none; padding: 2px 7px; border-radius: 5px;
    font-size: 8.5px; font-weight: 800; letter-spacing: .3px;
    background: var(--accent-soft); color: var(--accent-2);
}
.cine-badge.k-scene { background: color-mix(in srgb, var(--c-blue) 18%, transparent); color: var(--c-blue); }
.cine-badge.k-effect { background: color-mix(in srgb, var(--c-teal) 18%, transparent); color: var(--c-teal); }
.cine-badge.k-pedReplay,
.cine-badge.k-vehReplay { background: color-mix(in srgb, var(--c-amber) 18%, transparent); color: var(--c-amber); }

.cine-entry-delay { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.cine-delay-label {
    display: inline-flex; align-items: center; gap: 4px;
    font-size: 9px; font-weight: 700; color: var(--text-faint); margin-inline-end: 2px;
}
.cine-delay-label svg { width: 11px; height: 11px; }
.cine-chip {
    height: 20px; padding: 0 7px; border-radius: 5px;
    border: 1px solid var(--border); background: transparent;
    color: var(--text-faint); font-family: inherit;
    font-size: 10px; font-weight: 700; cursor: pointer;
}
.cine-chip:hover { border-color: var(--border-strong); color: var(--text); }
.cine-chip.on { background: var(--accent); border-color: var(--accent); color: #fff; }
.cine-delay-input {
    width: 54px; height: 20px; padding: 0 6px; border-radius: 5px;
    background: var(--card-hover); border: 1px solid var(--accent);
    color: var(--text); font-family: inherit; font-size: 9px;
}

.cine-add-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.cine-add {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px;
    height: 54px; border-radius: var(--radius-sm);
    background: var(--card); border: 1px solid var(--border);
    color: var(--text-dim); font-family: inherit;
    font-size: 10px; font-weight: 700; cursor: pointer;
    transition: background .15s var(--ease), border-color .15s var(--ease), color .15s var(--ease);
}
.cine-add:hover { background: var(--card-hover); border-color: var(--border-strong); color: var(--text); }
.cine-add svg { width: 15px; height: 15px; }

.cine-playback {
    display: flex; flex-direction: column; gap: 8px;
    padding: 10px 11px; border-radius: var(--radius-sm);
    background: var(--card); border: 1px solid var(--border);
}
.cine-playback-head {
    display: flex; align-items: center; gap: 6px;
    font-size: 9.5px; font-weight: 800; letter-spacing: .5px;
    text-transform: uppercase; color: var(--text-faint);
}
.cine-playback-head svg { width: 12px; height: 12px; }
.cine-playback-row { display: flex; gap: 6px; }

.cine-btn {
    flex: 1; display: flex; align-items: center; justify-content: center; gap: 6px;
    height: 34px; border-radius: 8px;
    border: 1px solid var(--border); background: var(--card-hover);
    color: var(--text-dim); font-family: inherit;
    font-size: 11px; font-weight: 800; cursor: pointer;
    transition: background .15s var(--ease), color .15s var(--ease), border-color .15s var(--ease);
}
.cine-btn svg { width: 13px; height: 13px; }
.cine-btn:hover { color: var(--text); border-color: var(--border-strong); }
.cine-btn.test.on { background: var(--accent); border-color: transparent; color: #fff; }
.cine-btn.action {
    border-color: rgba(239, 68, 68, .35); background: var(--danger-soft); color: #f87171;
}
.cine-btn.action:hover { background: rgba(239, 68, 68, .22); }
.cine-btn.action.on { background: var(--danger); border-color: transparent; color: #fff; }
.cine-btn.action.on svg { animation: blink 1.4s ease-in-out infinite; }
.cine-btn.marks {
    flex: none; width: 40px;
    border-color: color-mix(in srgb, var(--c-green) 40%, transparent);
    background: color-mix(in srgb, var(--c-green) 14%, transparent);
    color: var(--c-green);
}
.cine-btn.marks:hover { background: color-mix(in srgb, var(--c-green) 26%, transparent); color: #fff; }

.cine-countdown { display: flex; align-items: center; gap: 7px; font-size: 10px; color: var(--text-faint); }
.cine-countdown input {
    width: 52px; height: 26px; padding: 0 8px; border-radius: 6px;
    background: var(--card-hover); border: 1px solid var(--border);
    color: var(--text); font-family: inherit; font-size: 11px; text-align: center;
}

/* ---- the add/edit modal ---- */

.cine-modal { width: min(560px, 92vw); max-height: 82vh; display: flex; flex-direction: column; }
.cine-modal-body { flex: 1; min-height: 0; overflow-y: auto; padding: 12px 14px 14px; display: flex; flex-direction: column; gap: 9px; }
.cine-modal-icon { width: 18px; height: 18px; border-radius: 5px; background: var(--card-active); flex: none; }

.cine-tabs { margin-bottom: 2px; }
.cine-search { margin: 0; }

.cine-record {
    display: flex; align-items: center; justify-content: center; gap: 7px;
    height: 38px; border-radius: var(--radius-sm);
    border: 1px solid rgba(239, 68, 68, .35); background: var(--danger-soft);
    color: #f87171; font-family: inherit; font-size: 11.5px; font-weight: 800; cursor: pointer;
}
.cine-record:hover { background: rgba(239, 68, 68, .22); }
.cine-record svg { width: 13px; height: 13px; }

.cine-rows { display: flex; flex-direction: column; gap: 4px; max-height: 46vh; overflow-y: auto; }
.cine-row {
    display: flex; align-items: center; gap: 8px;
    padding: 9px 10px; border-radius: var(--radius-sm);
    background: var(--card); border: 1px solid var(--border); cursor: pointer;
    opacity: 0; animation: fade-up .2s var(--ease) forwards;
    animation-delay: calc(var(--i) * 8ms);
}
.cine-row:hover { background: var(--card-hover); border-color: var(--border-strong); }
.cine-row svg { width: 14px; height: 14px; flex: none; color: var(--text-faint); }
.cine-row-main { flex: 1; min-width: 0; }
.cine-row-name { font-size: 11.5px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cine-row-meta { display: flex; align-items: center; gap: 5px; font-size: 9px; color: var(--text-faint); margin-top: 2px; }
.cine-row-meta svg { width: 10px; height: 10px; }

.cine-back {
    align-self: flex-start; display: flex; align-items: center; gap: 5px;
    height: 26px; padding: 0 9px; border-radius: 7px;
    background: var(--card); border: 1px solid var(--border);
    color: var(--text-dim); font-family: inherit; font-size: 10.5px; font-weight: 700; cursor: pointer;
}
.cine-back svg { width: 12px; height: 12px; transform: scaleX(-1); }

.cine-config { display: flex; flex-direction: column; gap: 9px; }
.cine-config-name { font-size: 13px; font-weight: 800; display: flex; flex-direction: column; gap: 2px; }
.cine-config-sub { font-size: 9.5px; font-weight: 600; color: var(--text-faint); direction: ltr; text-align: start; }
.cine-check { display: flex; align-items: center; gap: 7px; font-size: 11px; color: var(--text-dim); }

.cine-config-actions { display: flex; justify-content: flex-end; gap: 8px; padding: 10px 14px 12px; border-top: 1px solid var(--border); }

/* ---- recording HUD ----
   The panel is gone while recording, so this is the only thing telling you
   it is running and how to stop it. */

.cine-rec-hud {
    position: fixed; top: 5vh; left: 50%; transform: translateX(-50%);
    display: none; flex-direction: column; align-items: center; gap: 3px;
    padding: 12px 26px; border-radius: 14px;
    background: rgba(12, 6, 22, .88); border: 1px solid var(--border);
    box-shadow: 0 16px 44px rgba(0, 0, 0, .5);
    z-index: 40; pointer-events: none;
}
.cine-rec-hud.visible { display: flex; }
.cine-rec-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--danger); animation: blink 1.2s ease-in-out infinite; }
.cine-rec-title { font-size: 11px; font-weight: 800; letter-spacing: .6px; color: #f5f2ff; }
.cine-rec-time { font-size: 22px; font-weight: 800; font-variant-numeric: tabular-nums; direction: ltr; color: #fff; }
.cine-rec-hint { font-size: 10px; color: var(--text-faint); }

.cine-countdown-hud {
    position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
    display: none; font-size: 96px; font-weight: 800; color: #fff;
    text-shadow: 0 8px 40px rgba(0, 0, 0, .8);
    z-index: 41; pointer-events: none;
}
.cine-countdown-hud.visible { display: block; animation: pop-in .3s var(--ease); }

.cine-toast {
    position: fixed; bottom: 6vh; left: 50%; transform: translateX(-50%) translateY(8px);
    padding: 9px 16px; border-radius: 10px;
    background: var(--panel); border: 1px solid var(--border);
    color: var(--text); font-size: 11.5px; font-weight: 700;
    opacity: 0; pointer-events: none; z-index: 42;
    transition: opacity .18s var(--ease), transform .18s var(--ease);
}
.cine-toast.visible { opacity: 1; transform: translateX(-50%) translateY(0); }

.cine-save-card { width: min(380px, 90vw); }
.cine-save-body { display: flex; flex-direction: column; gap: 7px; padding: 12px 14px; }
.cine-save-body input {
    height: 34px; padding: 0 10px; border-radius: var(--radius-sm);
    background: var(--card); border: 1px solid var(--accent);
    color: var(--text); font-family: inherit; font-size: 12px;
}
.cine-save-body label { font-size: 10px; font-weight: 700; color: var(--text-faint); }
.cine-save-meta { font-size: 10px; color: var(--text-faint); }

/* ---- project data, docked left ----
   Slides in from the edge when a project opens. Physical `left`, not an
   inline offset: the main panel is docked right in both languages, so this
   sits opposite it either way rather than jumping sides with the text. */

.cine-data {
    position: fixed;
    top: 4vh;
    left: 4vh;
    width: 268px;
    max-height: 62vh;
    display: flex;
    flex-direction: column;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 16px;
    overflow: hidden;
    box-shadow: 0 20px 60px rgba(0, 0, 0, .45);
    z-index: 2;

    /* hidden with visibility rather than display, so the entrance has a
       state to animate from - same reason as the main panel */
    visibility: hidden;
    opacity: 0;
    pointer-events: none;
    transform: translateX(-24px);
}

.cine-data.visible {
    visibility: visible;
    pointer-events: auto;
    animation: cineDataIn .34s var(--ease) both;
}

@keyframes cineDataIn {
    from { opacity: 0; transform: translateX(-28px) scale(.97); }
    to   { opacity: 1; transform: none; }
}

.cine-data-head {
    display: flex; align-items: center; gap: 8px;
    padding: 12px 14px 9px;
    border-bottom: 1px solid var(--border);
}
.cine-data-titles { min-width: 0; }
.cine-data-eyebrow {
    font-size: 9px; font-weight: 800; letter-spacing: .6px;
    text-transform: uppercase; color: var(--accent-2);
}
.cine-data-head h3 {
    font-size: 14px; font-weight: 800; margin-top: 2px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.cine-data-counts {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 8px 14px;
    border-bottom: 1px solid var(--border);
}
.cine-data-count {
    display: inline-flex; align-items: center; gap: 4px;
    font-size: 10.5px; font-weight: 800; color: var(--text-dim);
}
.cine-data-count svg { width: 12px; height: 12px; color: var(--accent-2); flex: none; }
.cine-data-empty { font-size: 10px; color: var(--text-faint); }

.cine-data-body {
    flex: 1; min-height: 0; overflow-y: auto;
    padding: 9px 10px 12px;
    display: flex; flex-direction: column; gap: 5px;
}
.cine-data-body::-webkit-scrollbar { width: 5px; }
.cine-data-body::-webkit-scrollbar-thumb { background: rgba(139, 92, 246, .25); border-radius: 3px; }

.cine-data-row {
    display: flex; align-items: center; gap: 8px;
    padding: 7px 8px;
    border-radius: 9px;
    background: var(--card);
    border: 1px solid var(--border);
    border-inline-start: 2px solid var(--text-faint);
    opacity: 0; animation: fade-up .22s var(--ease) forwards;
    animation-delay: calc(var(--i) * 14ms);
}
.cine-data-row.live { border-inline-start-color: var(--accent-2); }
.cine-data-icon { display: inline-flex; flex: none; color: var(--accent-2); }
.cine-data-icon svg { width: 14px; height: 14px; }
.cine-data-main { flex: 1; min-width: 0; }
.cine-data-name {
    font-size: 11px; font-weight: 700;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cine-data-meta { font-size: 9px; color: var(--text-faint); margin-top: 1px; }
.cine-data-row .icon-btn { width: 22px; height: 22px; }
.cine-data-row .icon-btn svg { width: 11px; height: 11px; }

.cine-data-blank {
    padding: 22px 10px; text-align: center;
    font-size: 10.5px; color: var(--text-faint); line-height: 1.7;
}

/* ---- folders, frames, settings, attachments ---- */

/* The trail across the top: which screen you are on and the way back. */
.cine-trail {
    display: flex; align-items: center; gap: 8px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--border);
}
.cine-trail-name {
    flex: 1; min-width: 0;
    display: flex; align-items: center; gap: 6px;
    font-size: 12.5px; font-weight: 800;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cine-trail-name svg { width: 14px; height: 14px; color: var(--accent-2); }
.cine-trail-meta { font-size: 10px; color: var(--text-faint); font-variant-numeric: tabular-nums; }

.cine-folder-icon { display: inline-flex; flex: none; color: var(--c-amber); }
.cine-folder-icon svg { width: 15px; height: 15px; }

.cine-row.off { opacity: .5; }
.cine-row.picked { border-color: var(--accent); background: var(--accent-soft); }

.cine-inline-name { display: flex; gap: 6px; margin-bottom: 4px; }
.cine-inline-name input {
    flex: 1; height: 34px; padding: 0 10px;
    border-radius: var(--radius-sm); background: var(--card);
    border: 1px solid var(--accent); color: var(--text);
    font-family: inherit; font-size: 12px;
}

.cine-config-actions.inline { border-top: none; padding: 4px 0 0; }

/* one setting per row, label left, control right */
.cine-settings { display: flex; flex-direction: column; gap: 6px; }
.cine-setting {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    padding: 8px 10px; border-radius: var(--radius-sm);
    background: var(--card); border: 1px solid var(--border);
    font-size: 11px; color: var(--text-dim);
}
.cine-setting.col { flex-direction: column; align-items: stretch; gap: 6px; }
.cine-setting.col > span { font-size: 10px; font-weight: 700; color: var(--text-faint); }

.seg-control.tiny .seg-btn { height: 28px; font-size: 10.5px; }
.seg-control.tiny .seg-btn svg { width: 11px; height: 11px; }

.cine-attach-list { display: flex; flex-direction: column; gap: 5px; }
.cine-attach {
    display: flex; align-items: center; gap: 8px;
    padding: 8px 9px; border-radius: var(--radius-sm);
    background: var(--card); border: 1px solid var(--border);
    border-inline-start: 2px solid var(--c-teal);
}
.cine-attach-icon { display: inline-flex; flex: none; color: var(--c-teal); }
.cine-attach-icon svg { width: 14px; height: 14px; }
.cine-attach-empty {
    padding: 14px 10px; text-align: center;
    font-size: 10.5px; color: var(--text-faint);
}

.cine-add-attach {
    display: flex; align-items: center; justify-content: center; gap: 7px;
    height: 34px; border-radius: var(--radius-sm);
    background: color-mix(in srgb, var(--c-teal) 14%, transparent);
    border: 1px solid color-mix(in srgb, var(--c-teal) 40%, transparent);
    color: var(--c-teal); font-family: inherit;
    font-size: 11px; font-weight: 800; cursor: pointer;
}
.cine-add-attach:hover { background: color-mix(in srgb, var(--c-teal) 26%, transparent); color: #fff; }
.cine-add-attach svg { width: 13px; height: 13px; }

/* the offset sliders, previewed live on the real car */
.cine-place-box {
    display: flex; flex-direction: column; gap: 8px;
    padding: 11px 12px; border-radius: var(--radius-sm);
    background: var(--card); border: 1px solid var(--accent);
}
.cine-place-title {
    display: flex; align-items: center; gap: 6px;
    font-size: 11.5px; font-weight: 800; color: var(--accent-2);
}
.cine-place-title svg { width: 13px; height: 13px; }

.insp-pick {
    display: inline-flex; align-items: center; justify-content: center;
    flex: none; width: 20px; height: 20px;
    border-radius: 6px;
    border: 1px solid var(--border-strong);
    background: transparent; color: transparent; cursor: pointer;
    transition: background .15s var(--ease), color .15s var(--ease), border-color .15s var(--ease);
}
.insp-pick svg { width: 12px; height: 12px; }
.insp-pick.on { background: var(--accent); border-color: var(--accent); color: #fff; }

.switch.small .toggle-track { transform: scale(.8); }

/* ============================================================
   Shared list chrome
   ============================================================ */

/* CEF draws the platform scrollbar by default: a wide grey track with a
   stepper ARROW BUTTON at each end. Those arrows are what looked wrong in
   every long list - nothing else on screen has a raised grey button on it.
   Styled once, globally, rather than per-list, because every list added
   later would otherwise arrive with the arrows back. */
::-webkit-scrollbar { width: 7px; height: 7px; }
::-webkit-scrollbar-button { display: none; width: 0; height: 0; }
::-webkit-scrollbar-corner { background: transparent; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
    background: rgba(139, 92, 246, .28);
    border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover { background: rgba(139, 92, 246, .5); }

/* A row you can drill into says so by moving, not by carrying a chevron.
   Six chevrons stacked down a list read as decoration; a row that slides a
   couple of pixels under the cursor reads as a door. */
.cine-row {
    transition: transform .14s var(--ease), background .14s var(--ease), border-color .14s var(--ease);
}
.cine-row.link:hover { transform: translateX(-3px); }
[dir="ltr"] .cine-row.link:hover { transform: translateX(3px); }

/* the little star that turns a row into a favourite */
.row-fav {
    display: inline-flex; align-items: center; justify-content: center;
    flex: none; width: 24px; height: 24px; border-radius: 7px;
    background: transparent; border: 1px solid transparent;
    color: var(--text-faint); cursor: pointer;
    transition: color .15s var(--ease), background .15s var(--ease);
}
.row-fav svg { width: 13px; height: 13px; }
.row-fav:hover { background: var(--card-hover); color: var(--c-amber); }
.row-fav.on { color: var(--c-amber); }
.row-fav.on svg { fill: currentColor; }

/* ============================================================
   Cinematic Director - pickers
   ============================================================ */

/* The generic .modal-card caps everything at max-width: 400px, and a
   max-width beats a width no matter which rule comes last - which is why
   these screens stayed letterboxed into a narrow strip however wide the
   width was set. Both caps have to be raised, not just the width. */
.cine-modal {
    width: min(620px, 94vw);
    max-width: min(620px, 94vw);
    height: min(760px, 88vh);
    max-height: min(760px, 88vh);
    padding: 0;
}
.cine-modal-body { gap: 10px; }

/* The list is the body of the screen, so it takes the room that is left
   rather than a fixed slice of the viewport - that is why these modals were
   letterboxed into a strip with everything crammed underneath. */
.cine-rows { max-height: none; flex: 1 1 auto; min-height: 120px; padding-inline-end: 2px; }
.cine-rows.short { flex: 0 1 auto; max-height: 34vh; }

.cine-head-row {
    display: flex; align-items: center; gap: 8px;
    padding-bottom: 9px; border-bottom: 1px solid var(--border);
}
.cine-head-icon {
    display: inline-flex; align-items: center; justify-content: center;
    flex: none; width: 30px; height: 30px; border-radius: 9px;
    background: var(--accent-soft); color: var(--accent-2);
}
.cine-head-icon svg { width: 16px; height: 16px; }
.cine-head-titles { flex: 1; min-width: 0; }
.cine-head-name {
    font-size: 13px; font-weight: 800;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cine-head-sub {
    font-size: 9.5px; color: var(--text-faint); margin-top: 2px;
    direction: ltr; text-align: start;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.cine-count {
    display: flex; align-items: center; gap: 6px;
    font-size: 9.5px; font-weight: 700; letter-spacing: .3px;
    color: var(--text-faint); text-transform: uppercase;
}
.cine-count svg { width: 11px; height: 11px; }

/* ---- the config step ---- */

.cine-config { gap: 11px; flex: 1 1 auto; overflow-y: auto; padding-inline-end: 2px; }

/* Actor cards were a stack of grey boxes that all looked the same. A tinted
   left edge and a numbered chip make "actor 3" findable at a glance. */
.actor-card {
    border-inline-start: 2px solid var(--accent);
    position: relative;
}
.actor-card.off { opacity: .5; border-inline-start-color: var(--text-faint); }
.actor-num {
    display: inline-flex; align-items: center; justify-content: center;
    flex: none; min-width: 18px; height: 18px; padding: 0 5px;
    border-radius: 6px; background: var(--accent-soft);
    color: var(--accent-2); font-size: 9.5px; font-weight: 800;
}
.actor-card .actor-label { justify-content: flex-start; gap: 7px; }
.actor-card .actor-label .spacer { flex: 1; }

.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.field-label {
    font-size: 9.5px; font-weight: 700; letter-spacing: .3px;
    color: var(--text-faint); text-transform: uppercase; margin-bottom: 4px;
}

.cine-config-actions {
    display: flex; gap: 8px; padding-top: 10px;
    border-top: 1px solid var(--border);
}
.cine-config-actions .modal-btn { flex: 1; }
.cine-config-actions .modal-btn.place {
    background: var(--card-active); border-color: transparent; color: #fff;
}
.cine-config-actions .modal-btn.place:hover { filter: brightness(1.08); }

/* ---- frames, riders ---- */

.cine-sub-actions { display: flex; gap: 6px; }
.cine-sub-actions .modal-btn { flex: 1; height: 34px; font-size: 11px; }

.rider-card {
    display: flex; align-items: center; gap: 8px;
    padding: 8px 9px; border-radius: var(--radius-sm);
    background: var(--card); border: 1px solid var(--border);
}
.rider-card.seat { border-inline-start: 2px solid var(--c-blue); }
.rider-card.stuck { border-inline-start: 2px solid var(--c-teal); }
.rider-icon { display: inline-flex; flex: none; }
.rider-icon svg { width: 14px; height: 14px; }
.rider-card.seat .rider-icon { color: var(--c-blue); }
.rider-card.stuck .rider-icon { color: var(--c-teal); }

.add-btn {
    display: flex; align-items: center; justify-content: center; gap: 7px;
    height: 34px; border-radius: var(--radius-sm);
    background: var(--accent-soft);
    border: 1px dashed var(--border-strong);
    color: var(--accent-2); font-family: inherit;
    font-size: 11px; font-weight: 800; cursor: pointer;
    transition: background .15s var(--ease), color .15s var(--ease);
}
.add-btn:hover { background: var(--card-hover); color: #fff; }
.add-btn svg { width: 13px; height: 13px; flex: none; }
.add-btn.teal { background: color-mix(in srgb, var(--c-teal) 13%, transparent); color: var(--c-teal); border-color: color-mix(in srgb, var(--c-teal) 40%, transparent); }
.add-btn.blue { background: color-mix(in srgb, var(--c-blue) 13%, transparent); color: var(--c-blue); border-color: color-mix(in srgb, var(--c-blue) 40%, transparent); }

/* ============================================================
   Recording countdown
   ============================================================ */

.rec-countdown {
    position: fixed; inset: 0; z-index: 60;
    display: none; align-items: center; justify-content: center;
    pointer-events: none;
}
.rec-countdown.visible { display: flex; }

.rec-count-num {
    font-size: 148px; font-weight: 900; line-height: 1;
    color: #fff;
    text-shadow: 0 0 60px rgba(139, 92, 246, .85), 0 8px 40px rgba(0,0,0,.6);
    animation: countPop .95s var(--ease) both;
}
.rec-count-ring {
    position: absolute; width: 230px; height: 230px; border-radius: 50%;
    border: 3px solid rgba(167, 139, 250, .5);
    animation: countRing .95s var(--ease) both;
}
.rec-count-go {
    font-size: 74px; font-weight: 900; letter-spacing: 6px;
    color: var(--c-red);
    text-shadow: 0 0 60px rgba(239, 68, 68, .8);
    animation: countGo .7s var(--ease) both;
}
.rec-count-label {
    position: absolute; bottom: 26%;
    font-size: 12px; font-weight: 700; letter-spacing: 2px;
    text-transform: uppercase; color: var(--text-dim);
}

@keyframes countPop {
    0%   { opacity: 0; transform: scale(1.9); }
    22%  { opacity: 1; transform: scale(1); }
    75%  { opacity: 1; transform: scale(1); }
    100% { opacity: 0; transform: scale(.82); }
}
@keyframes countRing {
    0%   { opacity: 0; transform: scale(.5); }
    25%  { opacity: 1; transform: scale(1); }
    100% { opacity: 0; transform: scale(1.5); }
}
@keyframes countGo {
    0%   { opacity: 0; transform: scale(.4); }
    30%  { opacity: 1; transform: scale(1.08); }
    60%  { opacity: 1; transform: scale(1); }
    100% { opacity: 0; transform: scale(1.25); }
}

/* ============================================================
   The gizmo
   ============================================================ */

/* The canvas MUST carry a real size, and MUST be pinned by left/top only.

   `inset: 0` sets left AND right. On an ordinary element that is what
   resolves the width - but an <svg> is a REPLACED element, so `width: auto`
   means its intrinsic 300x150 instead, and the box is then over-constrained:
   one of left/right has to be discarded, and the document's direction picks
   which. This page is RTL, so `left` was the one dropped and the SVG's
   coordinate origin ended up 1620px in from the left edge.

   Every handle was therefore drawn 1620px to the right of the thing it
   moves, while the toolbar - a plain div, whose width resolves normally -
   stayed correctly on the target. That is the entire bug, and it is why the
   projection kept measuring as exact: the maths was always right, the paper
   it was drawn on was in the wrong place. */
.d-gizmo {
    position: fixed;
    left: 0; top: 0; right: auto; bottom: auto;
    width: 100vw; height: 100vh;
    z-index: 35;
    display: none; pointer-events: none; overflow: visible;
}
.d-gizmo.visible { display: block; }
.d-gizmo .handle { pointer-events: auto; cursor: grab; }
.d-gizmo .handle.on { cursor: grabbing; }
.d-gizmo .handle.dim { opacity: .25; }

.d-gizmo .shaft { stroke-width: 3.2; stroke-linecap: round; }
.d-gizmo .hit { stroke: transparent; stroke-width: 16; fill: none; }
.d-gizmo .hit.area { stroke: none; }
.d-gizmo .ring { fill: none; stroke-width: 3.2; }
.d-gizmo .plane { opacity: .3; }
.d-gizmo .origin { fill: #f5f2ff; stroke: rgba(0,0,0,.5); stroke-width: 1.5; }
.d-gizmo .screen-ring { fill: none; stroke: rgba(245, 242, 255, .3); stroke-width: 1.5; }
.d-gizmo .label { font-size: 11px; font-weight: 800; fill: #f5f2ff; text-anchor: middle; }

.d-gizmo .ax-x .shaft, .d-gizmo .ax-x .ring { stroke: #f87171; }
.d-gizmo .ax-x .head, .d-gizmo .ax-x .plane { fill: #f87171; }
.d-gizmo .ax-y .shaft, .d-gizmo .ax-y .ring { stroke: #4ade80; }
.d-gizmo .ax-y .head, .d-gizmo .ax-y .plane { fill: #4ade80; }
.d-gizmo .ax-z .shaft, .d-gizmo .ax-z .ring { stroke: #60a5fa; }
.d-gizmo .ax-z .head, .d-gizmo .ax-z .plane { fill: #60a5fa; }
.d-gizmo .pl-xy .plane { fill: #60a5fa; }
.d-gizmo .pl-xz .plane { fill: #4ade80; }
.d-gizmo .pl-yz .plane { fill: #f87171; }

.d-gizmo .handle:hover .shaft, .d-gizmo .handle.on .shaft,
.d-gizmo .handle:hover .ring,  .d-gizmo .handle.on .ring { stroke: #fbbf24; }
.d-gizmo .handle:hover .head,  .d-gizmo .handle.on .head,
.d-gizmo .handle:hover .plane, .d-gizmo .handle.on .plane { fill: #fbbf24; }

.d-gizmo-bar {
    position: fixed; z-index: 36;
    transform: translateX(-50%);
    display: none; align-items: center; gap: 4px;
    padding: 5px 6px; border-radius: 11px;
    background: rgba(12, 7, 22, .92);
    border: 1px solid var(--border);
    box-shadow: 0 12px 34px rgba(0,0,0,.5);
}
.d-gizmo-bar.visible { display: flex; }
.d-gizmo-bar button {
    display: inline-flex; align-items: center; gap: 5px;
    height: 27px; padding: 0 9px; border-radius: 8px;
    background: transparent; border: none; color: var(--text-dim);
    font-family: inherit; font-size: 10.5px; font-weight: 700; cursor: pointer;
}
.d-gizmo-bar button svg { width: 12px; height: 12px; flex: none; }
.d-gizmo-bar button:hover { background: var(--card-hover); color: var(--text); }
.d-gizmo-bar button.active { background: var(--accent-soft); color: var(--accent-2); }
.d-gizmo-bar kbd {
    font-family: inherit; font-size: 8.5px; font-weight: 700;
    padding: 1px 4px; border-radius: 4px;
    background: rgba(255,255,255,.07); color: var(--text-faint);
}
.d-gizmo-bar .sep { width: 1px; height: 16px; background: var(--border); }

/* the strip that says the camera has the keyboard */
.d-gizmo-hint {
    position: fixed; top: 14px; left: 50%; transform: translateX(-50%);
    z-index: 36; display: none; align-items: center; gap: 12px;
    padding: 8px 16px; border-radius: 10px;
    background: rgba(10, 6, 18, .78);
    border: 1px solid var(--border);
    font-size: 11px; color: var(--text-dim);
    animation: fade-down .24s var(--ease) both;
}
.d-gizmo-hint.visible { display: flex; }
.d-gizmo-hint b { color: var(--text); font-weight: 800; }
.d-gizmo-hint .k {
    padding: 2px 6px; border-radius: 5px;
    background: rgba(255,255,255,.08); color: var(--text);
    font-size: 10px; font-weight: 800;
}

@keyframes fade-down {
    from { opacity: 0; transform: translate(-50%, -10px); }
    to   { opacity: 1; transform: translate(-50%, 0); }
}

/* ============================================================
   Data panel
   ============================================================ */

.cine-data-group { display: flex; flex-direction: column; gap: 4px; }
.cine-data-group + .cine-data-group { margin-top: 7px; }

.cine-data-row { cursor: pointer; }
.cine-data-row .icon-btn { opacity: 0; transition: opacity .14s var(--ease); }
.cine-data-row:hover .icon-btn, .cine-data-row.open .icon-btn { opacity: 1; }

/* one line per real entity standing in the world */
.cine-ent {
    display: flex; align-items: center; gap: 7px;
    margin-inline-start: 14px;
    padding: 5px 7px; border-radius: 8px;
    background: rgba(255,255,255,.02);
    border: 1px solid transparent;
    border-inline-start: 2px solid var(--border-strong);
    cursor: pointer;
    transition: background .14s var(--ease), border-color .14s var(--ease);
}
.cine-ent:hover { background: var(--card-hover); }
.cine-ent.selected { border-color: var(--accent); background: var(--accent-soft); }
.cine-ent-icon { display: inline-flex; flex: none; color: var(--text-faint); }
.cine-ent-icon svg { width: 12px; height: 12px; }
.cine-ent-name {
    flex: 1; min-width: 0; font-size: 10px; font-weight: 700; color: var(--text-dim);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cine-ent-tag {
    font-size: 8.5px; font-weight: 800; letter-spacing: .3px;
    padding: 1px 5px; border-radius: 4px; text-transform: uppercase;
    background: var(--accent-soft); color: var(--accent-2);
}

.cine-data-actions {
    display: flex; gap: 5px; padding: 8px 10px;
    border-top: 1px solid var(--border);
}
.cine-data-actions button {
    flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 5px;
    height: 30px; border-radius: 8px;
    background: var(--card); border: 1px solid var(--border);
    color: var(--text-dim); font-family: inherit;
    font-size: 10px; font-weight: 700; cursor: pointer;
}
.cine-data-actions button svg { width: 12px; height: 12px; flex: none; }
.cine-data-actions button:hover { background: var(--card-hover); color: var(--text); }
.cine-data-actions button.on { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-2); }

/* ============================================================
   Icon sizing, once and for all
   ============================================================ */

/* An inline <svg> with no width/height attribute falls back to 300x150 - the
   CSS default for a replaced element. Every icon in this file is inline SVG,
   so ANY container that was never given a rule renders a icon the size of a
   postcard. That is what the giant clock over "start delay" and the giant
   speedometer over "playback speed" were.

   Rather than keep finding these one screen at a time, every icon defaults to
   a sane size and the specific rules above override it where a different size
   is wanted. A missing rule now produces a slightly-wrong icon instead of a
   broken layout. */
/* :where() so this has ZERO specificity - it is a FALLBACK, and every rule
   that already sizes an icon must beat it.

   Written as `#app svg` first, which carries an ID and therefore outranked
   almost every icon rule in this file. That silently resized the nav tiles,
   the brand mark, the status bar, the appearance editor - every icon in the
   app - to 14px. A default that overrides the thing it is defaulting for is
   not a default. */
:where(#app, .cine-data, .modal-card, .d-gizmo-bar, .rec-countdown, .cine-toast) svg {
    width: 14px;
    height: 14px;
    flex: none;
}
/* the gizmo itself is a full-screen canvas, not an icon */
/* exempt from the icon default above - it is a canvas, not an icon - but it
   keeps the explicit viewport size set with the rest of its rules */
svg.d-gizmo { width: 100vw; height: 100vh; }

.w-slider-top { gap: 8px; }
.w-slider-top > span:first-child {
    display: inline-flex; align-items: center; gap: 6px;
    min-width: 0;
}
.w-slider-top svg { width: 12px; height: 12px; color: var(--accent-2); }

.section-label svg { width: 12px; height: 12px; }
.cine-row-meta svg { width: 10px; height: 10px; }
.cine-count svg { width: 11px; height: 11px; }
.cine-head-icon svg { width: 16px; height: 16px; }
.icon-btn svg { width: 13px; height: 13px; }

/* ============================================================
   Riders
   ============================================================ */

/* The dashed "add" buttons read as placeholders rather than controls. A
   solid tinted bar with a leading + is unambiguous. */
.add-btn {
    border-style: solid;
    justify-content: flex-start;
    padding: 0 12px;
    gap: 9px;
}
.add-btn svg { width: 12px; height: 12px; }

.rider-card .cine-row-meta { gap: 6px; }
.rider-weapon {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 1px 6px; border-radius: 5px;
    background: color-mix(in srgb, var(--c-orange) 16%, transparent);
    color: var(--c-orange);
    font-size: 8.5px; font-weight: 800;
}

/* the seat map: a diagram beats a numbered list for "which seat is that" */
.seat-map {
    display: grid; grid-template-columns: 1fr 1fr; gap: 7px;
    padding: 12px; border-radius: var(--radius-sm);
    background: var(--card); border: 1px solid var(--border);
}
.seat-btn {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 3px; height: 52px; border-radius: 9px;
    background: var(--panel); border: 1px solid var(--border);
    color: var(--text-dim); font-family: inherit; cursor: pointer;
    transition: background .15s var(--ease), border-color .15s var(--ease), color .15s var(--ease);
}
.seat-btn svg { width: 14px; height: 14px; }
.seat-btn span { font-size: 10px; font-weight: 700; }
.seat-btn small { font-size: 8.5px; color: var(--text-faint); }
.seat-btn:hover { background: var(--card-hover); color: var(--text); }
.seat-btn.active {
    background: var(--accent-soft); border-color: var(--accent); color: var(--accent-2);
}
.seat-btn.active small { color: var(--accent-2); }
.seat-btn:disabled { opacity: .3; cursor: default; }
.seat-map-hood { grid-column: 1 / -1; }

/* ============================================================
   The countdown - one for every count-in in the script
   ============================================================ */

/* The take used to count down with a bare number in a corner and recording
   had its own separate thing. Same event, same treatment: one component,
   used by both, so a count-in always looks like a count-in. */
.rec-countdown { flex-direction: column; gap: 0; }

.rec-count-stage {
    position: relative;
    display: flex; align-items: center; justify-content: center;
    width: 300px; height: 300px;
}

/* the sweep: a ring that empties over exactly one second */
.rec-count-dial { position: absolute; inset: 0; transform: rotate(-90deg); }
.rec-count-dial circle { fill: none; stroke-width: 3; }
.rec-count-dial .track { stroke: rgba(167, 139, 250, .16); }
.rec-count-dial .sweep {
    stroke: var(--accent-2);
    stroke-linecap: round;
    filter: drop-shadow(0 0 8px rgba(168, 85, 247, .8));
    animation: countSweep 1s linear both;
}
@keyframes countSweep {
    from { stroke-dashoffset: 0; }
    to   { stroke-dashoffset: var(--circ); }
}

.rec-count-num {
    position: relative;
    font-size: 120px; font-weight: 900; line-height: 1;
    background: linear-gradient(180deg, #fff 30%, #b98cff);
    -webkit-background-clip: text; background-clip: text; color: transparent;
    filter: drop-shadow(0 0 34px rgba(139, 92, 246, .75));
    animation: countPop 1s var(--ease) both;
}

.rec-count-ring {
    position: absolute; width: 230px; height: 230px; border-radius: 50%;
    border: 2px solid rgba(167, 139, 250, .45);
    animation: countRing 1s var(--ease) both;
}

.rec-count-go {
    font-size: 84px; font-weight: 900; letter-spacing: 8px;
    color: #fff;
    text-shadow: 0 0 50px rgba(239, 68, 68, .95), 0 0 120px rgba(239, 68, 68, .5);
    animation: countGo .8s var(--ease) both;
}

.rec-count-label {
    margin-top: 6px;
    font-size: 12px; font-weight: 800; letter-spacing: 3px;
    text-transform: uppercase; color: var(--text-dim);
    animation: fade-up .4s var(--ease) both;
}
.rec-count-label.action { color: var(--c-red); }

/* the vignette, so the count reads over a bright sky */
.rec-countdown::before {
    content: '';
    position: absolute; inset: 0;
    background: radial-gradient(ellipse at center, rgba(6,3,12,.55) 0%, rgba(6,3,12,0) 62%);
    animation: fade-up .3s var(--ease) both;
}

@keyframes countPop {
    0%   { opacity: 0; transform: scale(1.7); }
    18%  { opacity: 1; transform: scale(1); }
    80%  { opacity: 1; transform: scale(1); }
    100% { opacity: 0; transform: scale(.86); }
}
@keyframes countRing {
    0%   { opacity: 0; transform: scale(.55); }
    22%  { opacity: .9; transform: scale(1); }
    100% { opacity: 0; transform: scale(1.45); }
}
@keyframes countGo {
    0%   { opacity: 0; transform: scale(.4); }
    26%  { opacity: 1; transform: scale(1.1); }
    58%  { opacity: 1; transform: scale(1); }
    100% { opacity: 0; transform: scale(1.3); }
}

/* the old corner number is superseded by the component above */
.cine-countdown-hud { display: none !important; }

/* ============================================================
   Control mode
   ============================================================ */

/* Place mode takes the camera and the keyboard away from control mode, so
   the panel dims rather than sitting there looking usable. */
#app.handing-over, .cine-data.handing-over {
    opacity: 0;
    transform: scale(.985);
    transition: opacity .18s var(--ease), transform .18s var(--ease);
    pointer-events: none;
}

/* ============================================================
   Modal header
   ============================================================ */

/* The card's own padding is zero so the body can scroll edge to edge, which
   means the header has to bring its own. The mark on the left used to be an
   empty purple square - a styled box with nothing in it - and the close
   button had no room around it. */
.cine-modal-header {
    display: flex; align-items: center; gap: 10px;
    flex: none;
    padding: 14px 16px;
    border-bottom: 1px solid var(--border);
    margin: 0;
}
.cine-modal-header h3 {
    flex: 1; min-width: 0; margin: 0;
    font-size: 14px; font-weight: 800;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cine-modal-icon {
    display: inline-flex; align-items: center; justify-content: center;
    flex: none; width: 30px; height: 30px;
    border-radius: 9px;
    background: var(--card-active);
    color: #fff;
    box-shadow: 0 4px 14px rgba(139, 92, 246, .35);
}
.cine-modal-icon svg { width: 16px; height: 16px; }

.cine-modal-header .icon-btn {
    width: 28px; height: 28px;
    border-color: var(--border);
    background: var(--card);
    color: var(--text-dim);
}
.cine-modal-header .icon-btn:hover {
    background: var(--danger-soft);
    border-color: rgba(239, 68, 68, .35);
    color: #f87171;
}
.cine-modal-header .icon-btn svg { width: 12px; height: 12px; }

.cine-modal-body { padding: 12px 16px 16px; }

/* ============================================================
   Seat map
   ============================================================ */

/* The numbers under each seat were the game's seat indices, which is exactly
   the thing the map exists to hide. The seat's position IS its name. */
.seat-map {
    grid-template-areas:
        "fl fr"
        "bl br"
        "bm bm";
    gap: 8px;
    padding: 14px;
}
.seat-btn { height: 46px; gap: 5px; flex-direction: row; }
.seat-btn span { font-size: 10.5px; font-weight: 700; }
.seat-btn small { display: none; }

.seat-btn[data-slot="driver"] { grid-area: fl; }
.seat-btn[data-seat="0"] { grid-area: fr; }
.seat-btn[data-seat="1"] { grid-area: bl; }
.seat-btn[data-seat="2"] { grid-area: br; }
.seat-btn[data-seat="3"] { grid-area: bm; }

/* the seat marker: a small filled square with a back, so it reads as a seat
   from above rather than as another generic person icon */
.seat-dot {
    display: inline-flex; flex: none;
    width: 15px; height: 15px;
    border-radius: 4px 4px 6px 6px;
    border: 1.5px solid currentColor;
    border-top-width: 4px;
    opacity: .75;
}
.seat-btn.active .seat-dot { background: color-mix(in srgb, currentColor 22%, transparent); opacity: 1; }

/* the driver's place is shown, never offered - the recording is the driver */
.seat-btn.taken {
    background: repeating-linear-gradient(135deg,
        rgba(255,255,255,.02) 0 6px, transparent 6px 12px);
    border-style: dashed;
    color: var(--text-faint);
    cursor: default;
}
.seat-btn.taken:hover { background: repeating-linear-gradient(135deg,
        rgba(255,255,255,.02) 0 6px, transparent 6px 12px); color: var(--text-faint); }

.seat-map-note {
    grid-column: 1 / -1;
    font-size: 9px; color: var(--text-faint); text-align: center;
    letter-spacing: .3px;
}

/* ============================================================
   Data panel actions
   ============================================================ */

/* Three cramped pills with wrapping labels. The one that matters - leaving
   control mode - is now a full-width bar in a colour that says "this ends
   something", and the two secondary actions share the row beneath it. */
.cine-data-actions {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 6px;
    padding: 9px 10px;
}
.cine-data-actions button {
    height: 32px;
    font-size: 10.5px;
    font-weight: 700;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.cine-data-actions button[data-act="gizmo"] {
    grid-column: 1 / -1;
    height: 36px;
    font-size: 11.5px;
    font-weight: 800;
    background: var(--accent-soft);
    border-color: color-mix(in srgb, var(--accent) 45%, transparent);
    color: var(--accent-2);
}
.cine-data-actions button[data-act="gizmo"]:hover {
    background: color-mix(in srgb, var(--accent) 26%, transparent);
    color: #fff;
}
.cine-data-actions button[data-act="gizmo"].on {
    background: var(--danger-soft);
    border-color: rgba(239, 68, 68, .4);
    color: #f87171;
}
.cine-data-actions button[data-act="gizmo"].on:hover {
    background: rgba(239, 68, 68, .24);
    color: #fff;
}

/* a scene is one row, and reads as one */
.cine-ent[data-handle].selected .cine-ent-name { color: var(--text); }

/* ============================================================
   Vehicles
   ============================================================ */

.veh-view { display: flex; flex-direction: column; gap: 11px; padding: 2px 2px 18px; }
.veh-cats { margin-bottom: 2px; }
.veh-cats .seg-btn { gap: 6px; }
.veh-cats .seg-btn svg { width: 13px; height: 13px; }

#vehBody { display: flex; flex-direction: column; gap: 11px; }

.veh-card {
    display: flex; flex-direction: column; gap: 9px;
    padding: 13px; border-radius: var(--radius-sm);
    background: var(--card); border: 1px solid var(--border);
    border-inline-start: 2px solid var(--accent);
}

/* the three tempers, coloured by how much trouble they are */
.seg-btn.st-calm.active { background: color-mix(in srgb, var(--c-green) 22%, transparent); color: var(--c-green); }
.seg-btn.st-hard.active { background: color-mix(in srgb, var(--c-orange) 22%, transparent); color: var(--c-orange); }
.seg-btn.st-kill.active { background: color-mix(in srgb, var(--danger) 26%, transparent); color: #f87171; }

.veh-go {
    display: flex; align-items: center; justify-content: center; gap: 8px;
    height: 42px; border-radius: var(--radius-sm);
    background: var(--card-active); border: none; color: #fff;
    font-family: inherit; font-size: 12.5px; font-weight: 800; cursor: pointer;
    box-shadow: 0 6px 18px rgba(139, 92, 246, .3);
}
.veh-go:hover { filter: brightness(1.08); }
.veh-go svg { width: 15px; height: 15px; }
.veh-go.stop {
    background: var(--danger-soft); color: #f87171;
    border: 1px solid rgba(239, 68, 68, .4); box-shadow: none;
}

.veh-code {
    height: 34px; padding: 0 11px; border-radius: var(--radius-sm);
    background: var(--panel); border: 1px solid var(--accent);
    color: var(--text); font-family: inherit; font-size: 12px;
    direction: ltr; text-align: start;
}

/* ---- the shapes ---- */

/* A name like "arc" tells you nothing. Five rectangles arranged in an arc
   tells you everything, so each shape is drawn from the same offsets the
   game uses to place it. */
.veh-shapes {
    display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px;
}
.veh-shape {
    position: relative;
    display: flex; flex-direction: column; align-items: center; gap: 6px;
    padding: 11px 6px 9px; border-radius: var(--radius-sm);
    background: var(--card); border: 1px solid var(--border);
    color: var(--text-dim); font-family: inherit; cursor: pointer;
    transition: background .15s var(--ease), border-color .15s var(--ease), color .15s var(--ease);
}
.veh-shape:hover { background: var(--card-hover); color: var(--text); }
.veh-shape.active {
    background: var(--accent-soft); border-color: var(--accent); color: var(--accent-2);
}
.veh-shape-art { display: block; width: 100%; height: 54px; }
.veh-shape-art svg.shape-art { width: 100%; height: 100%; }
.veh-shape-art rect { fill: currentColor; opacity: .55; }
.veh-shape.active .veh-shape-art rect { opacity: 1; }
.veh-shape-name { font-size: 10px; font-weight: 700; text-align: center; line-height: 1.3; }
.veh-shape-n {
    position: absolute; top: 6px; inset-inline-end: 7px;
    font-size: 9px; font-weight: 800; color: var(--text-faint);
}

/* ---- one car's slot ---- */

.veh-slots { display: flex; flex-direction: column; gap: 7px; }
.veh-slot {
    display: flex; flex-direction: column; gap: 7px;
    padding: 10px 11px; border-radius: var(--radius-sm);
    background: var(--card); border: 1px solid var(--border);
    border-inline-start: 2px solid var(--c-blue);
}
.veh-slot.off { opacity: .45; border-inline-start-color: var(--text-faint); }
.veh-slot-head { display: flex; align-items: center; gap: 8px; }
.veh-slot-head .spacer { flex: 1; }
.veh-slot-n {
    display: inline-flex; align-items: center; justify-content: center;
    width: 20px; height: 20px; border-radius: 6px;
    background: color-mix(in srgb, var(--c-blue) 20%, transparent);
    color: var(--c-blue); font-size: 10px; font-weight: 800;
}

/* ---- the placed list ---- */

.veh-data .cine-data-actions { grid-template-columns: 1fr; }
.veh-data .cine-data-actions button {
    background: var(--danger-soft);
    border-color: rgba(239, 68, 68, .3);
    color: #f87171;
}
.veh-data .cine-data-actions button:hover { background: rgba(239, 68, 68, .22); color: #fff; }

/* the three actions under the placed-vehicle list */
.veh-actions { grid-template-columns: 1fr 1fr; }
.veh-actions button[data-act="clear"] { grid-column: 1 / -1; }
.veh-actions button[data-act="enginesOn"] {
    background: color-mix(in srgb, var(--c-green) 15%, transparent);
    border-color: color-mix(in srgb, var(--c-green) 40%, transparent);
    color: var(--c-green);
}
.veh-actions button[data-act="enginesOn"]:hover { background: color-mix(in srgb, var(--c-green) 28%, transparent); color: #fff; }
.veh-actions button[data-act="enginesOff"] { background: var(--card); border-color: var(--border); color: var(--text-dim); }
.veh-actions button[data-act="clear"] {
    background: var(--danger-soft); border-color: rgba(239,68,68,.3); color: #f87171;
}

/* the list itself: a formation is a card, its cars are the lines inside it */
.veh-data .cine-data-group {
    padding: 7px; border-radius: 11px;
    background: rgba(255,255,255,.02);
    border: 1px solid var(--border);
}
.veh-data .cine-data-row { background: transparent; border: none; padding: 3px 4px 6px; }
.veh-data .cine-data-row .cine-data-name { font-size: 11px; }
.veh-data .cine-ent { margin-inline-start: 0; border-inline-start-width: 2px; }

/* ---- shape art: a car from above, not a rectangle ---- */
.veh-shape-art svg.shape-art { width: 100%; height: 100%; overflow: visible; }
.shape-art .road { stroke: currentColor; stroke-width: .6; opacity: .15; stroke-dasharray: 3 3; }
.shape-art .car-body { fill: currentColor; opacity: .5; }
.shape-art .car-glass { fill: var(--panel); opacity: .85; }
.shape-art .car-bar { fill: var(--c-blue); opacity: .9; }
.veh-shape.active .shape-art .car-body { opacity: 1; }
.veh-shape.active .shape-art .car-bar { fill: var(--c-red); }
.veh-shape-art { height: 66px; }

/* ---- control centre ---- */
.veh-control {
    display: flex; flex-direction: column; gap: 8px;
    padding: 12px; border-radius: var(--radius-sm);
    background: linear-gradient(135deg, rgba(139,92,246,.13), rgba(139,92,246,.04));
    border: 1px solid var(--border-strong);
}
.veh-control-head {
    display: flex; align-items: center; gap: 7px;
    font-size: 11px; font-weight: 800; letter-spacing: .3px;
    text-transform: uppercase; color: var(--accent-2);
}
.veh-control-row { display: grid; grid-template-columns: 1fr 108px; gap: 8px; }
.veh-apply {
    display: flex; align-items: center; justify-content: center; gap: 7px;
    height: 32px; border-radius: var(--radius-sm);
    background: var(--accent-soft); border: 1px solid var(--accent);
    color: var(--accent-2); font-family: inherit;
    font-size: 11px; font-weight: 800; cursor: pointer;
}
.veh-apply:hover { background: var(--accent); color: #fff; }

/* ---- the plate ---- */
.veh-code.plate {
    text-align: center; letter-spacing: 2px; font-weight: 800; font-size: 11.5px;
    text-transform: uppercase;
    background: #f3f0e4; color: #16121f; border-color: #b9b39d;
    border-radius: 5px; height: 32px;
}
.veh-code.plate::placeholder { color: #8b8676; letter-spacing: 1px; font-weight: 600; }

/* ---- slot card ---- */
.veh-slot-head { gap: 8px; }
.veh-slot-main { flex: 1; min-width: 0; }
.veh-slot-row { display: grid; grid-template-columns: 108px 1fr; gap: 8px; align-items: center; }
.veh-mini { display: flex; align-items: center; gap: 6px; font-size: 10.5px; color: var(--text-dim); }
.veh-mini input { accent-color: var(--accent); }

/* doors: one row of chips, so the card never grows */
/* THREE across, not six. Six chips on one row left ~40px each, which is
   why the labels had been cut to two letters - and two Arabic letters are
   not an abbreviation, they are noise. Two rows of three is twice the
   width and fits a readable word in either language. */
.veh-doors { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; }
.door-chip {
    height: 26px; border-radius: 6px;
    background: var(--panel); border: 1px solid var(--border);
    color: var(--text-faint); font-family: inherit;
    font-size: 9px; font-weight: 800; cursor: pointer;
    transition: background .14s var(--ease), color .14s var(--ease), border-color .14s var(--ease), transform .14s var(--ease);
}
.door-chip:hover { color: var(--text); border-color: var(--border-strong); }
.door-chip.on {
    background: color-mix(in srgb, var(--c-amber) 22%, transparent);
    border-color: color-mix(in srgb, var(--c-amber) 55%, transparent);
    color: var(--c-amber);
    transform: translateY(-2px);
}

/* ---- selection has to be obvious AND readable ----
   The chase styles tinted the background with the same colour as the text,
   so the chosen one was the hardest of the three to read - selection made an
   option disappear instead of standing out. A ring plus white text does the
   job: the colour says which one, the ring says it is chosen. */
.veh-view .seg-btn.active,
.seg-btn.st-calm.active, .seg-btn.st-hard.active, .seg-btn.st-kill.active {
    color: #fff;
    font-weight: 800;
    box-shadow: 0 0 0 1.5px currentColor inset, 0 4px 14px rgba(0,0,0,.35);
}
.seg-btn.st-calm.active { background: color-mix(in srgb, var(--c-green) 34%, transparent); }
.seg-btn.st-hard.active { background: color-mix(in srgb, var(--c-orange) 38%, transparent); }
.seg-btn.st-kill.active { background: color-mix(in srgb, var(--danger) 46%, transparent); }

/* the same for the shape tiles: chosen should read at a glance */
.veh-shape.active {
    box-shadow: 0 0 0 1.5px var(--accent) inset, 0 6px 18px rgba(139,92,246,.28);
    color: #fff;
}
.veh-shape.active .veh-shape-name { color: #fff; }

/* ---- chase speed ---- */
.veh-speed-row { display: flex; align-items: center; gap: 10px; }
.veh-speed-row input[type="range"] { flex: 1; }
.veh-speed-val {
    min-width: 66px; text-align: center;
    font-size: 11px; font-weight: 800; color: var(--accent-2);
    font-variant-numeric: tabular-nums;
}

/* your own car in the escort diagrams, so the shape reads from where you are */
.shape-art .car-you { fill: var(--accent-2); opacity: .95; }
.veh-shapes.moving { grid-template-columns: repeat(3, 1fr); }

/* the panel's two lists */
.veh-data-tabs { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; }
.veh-data-tabs button {
    height: 24px; border-radius: 7px;
    background: transparent; border: 1px solid var(--border);
    color: var(--text-faint); font-family: inherit;
    font-size: 9.5px; font-weight: 800; cursor: pointer;
}
.veh-data-tabs button.on {
    background: var(--accent-soft); border-color: var(--accent); color: var(--accent-2);
}
.veh-data-tabs button:disabled { opacity: .35; cursor: default; }

/* an escort car is carried, so it is listed but not grabbable */
.cine-ent.locked { cursor: default; opacity: .8; border-inline-start-color: var(--c-teal); }
.cine-ent.locked:hover { background: rgba(255,255,255,.02); }


/* ---------------- the unified world ---------------- */

/* Badge colours for entries owned by the other menus. Scoped to the badge
   class alone - nothing here can leak into another menu's styling. */
.cine-badge.k-bot   { background: rgba(122, 162, 247, .16); color: #7aa2f7; }
.cine-badge.k-crowd { background: rgba(245, 197, 24, .14);  color: #f5c518; }
.cine-badge.k-prop  { background: rgba(61, 220, 151, .14);  color: #3ddc97; }

.cine-crowd-n { font-size: 10px; color: var(--text-faint); font-weight: 800; }

/* The switcher: the other two menus from inside the project. Two equal
   buttons - neither is the main one, both are one press. */
.cine-switch { display: grid; grid-template-columns: 1fr 1fr; gap: 7px; }
.cine-switch-btn {
    display: flex; align-items: center; justify-content: center; gap: 7px;
    padding: 9px 10px; border-radius: 10px;
    background: var(--card); border: 1px solid var(--border);
    color: var(--text-dim); font-family: inherit; font-size: 11.5px; font-weight: 800;
    cursor: pointer;
    transition: border-color .15s var(--ease), background .15s var(--ease), color .15s var(--ease);
}
.cine-switch-btn:hover { background: var(--card-hover); border-color: var(--accent); color: var(--text); }
.cine-switch-btn svg { width: 14px; height: 14px; }


/* A bot's timeline on its Data row: transport, progress, length, editor. */
.cine-tl {
    display: flex; align-items: center; gap: 7px;
    padding: 5px 9px 7px 9px;
    background: rgba(255, 255, 255, .02);
}
.cine-tl.none { justify-content: space-between; }
.cine-tl-empty { font-size: 9.5px; color: var(--text-faint); font-weight: 700; }

.cine-tl-btn {
    flex: none; display: flex; align-items: center; gap: 5px;
    height: 22px; padding: 0 8px; border-radius: 6px;
    background: var(--card); border: 1px solid var(--border);
    color: var(--text-dim); font-family: inherit; font-size: 9.5px; font-weight: 800;
    cursor: pointer;
    transition: background .15s var(--ease), border-color .15s var(--ease), color .15s var(--ease);
}
.cine-tl-btn:hover { background: var(--card-hover); border-color: var(--accent); color: var(--text); }
.cine-tl-btn svg { width: 11px; height: 11px; }
.cine-tl-btn.play { width: 24px; padding: 0; justify-content: center; }
.cine-tl.playing .cine-tl-btn.play { border-color: var(--accent); color: var(--accent-2); }

.cine-tl-bar {
    flex: 1; min-width: 0; height: 4px; border-radius: 999px;
    background: rgba(255, 255, 255, .08); overflow: hidden;
}
.cine-tl-fill {
    height: 100%; border-radius: 999px;
    background: var(--accent);
    transition: width .2s linear;
}
.cine-tl-len {
    flex: none; font-size: 9px; font-weight: 800; color: var(--text-faint);
    font-variant-numeric: tabular-nums;
}


/* ---------------- the garage ---------------- */

.garage-panel {
    /* PHYSICAL left, deliberately. inset-inline-start flips to the RIGHT in
       Arabic, which parked the garage on top of the cinematic picker - the
       user's screenshot of it sitting exactly where it should not. The
       garage REPLACES the Data panel while it is open, and the Data panel
       is pinned physical-left, so the garage pins the same way. */
    position: fixed;
    left: var(--gap, 14px);
    top: var(--gap, 14px);
    bottom: var(--gap, 14px);
    width: 330px;
    display: none;
    flex-direction: column;
    background: var(--panel);
    border: 1px solid var(--border-strong);
    border-radius: 18px;
    overflow: hidden;
    box-shadow: 0 20px 60px rgba(0,0,0,.5);
    z-index: 36;
}
.garage-panel.visible {
    display: flex;
    /* its own entrance, restated on the VISIBLE state: an animation on the
       base rule plays at page load against display:none and is spent by
       the first real open */
    animation: garageIn .28s var(--ease) both;
}
@keyframes garageIn {
    from { opacity: 0; transform: translateX(-14px); }
    to   { opacity: 1; transform: none; }
}
/* while the garage is up, the Data panel yields the column */
body.garage-open #cineData { display: none; }

.g-head {
    display: flex; align-items: center; gap: 8px;
    padding: 12px 14px; flex: none;
    border-bottom: 1px solid var(--border);
}
.g-icon { display: flex; color: var(--accent-2); }
.g-icon svg { width: 16px; height: 16px; }
.g-title { flex: 1; font-size: 13px; font-weight: 800; direction: ltr; text-align: start; }

/* THE TABS.
 *
 * These were written with `.pop-tab`, which lives in Bot Control's
 * stylesheet and not in this one - so they rendered as four bare buttons
 * with no fill, no border and no way to tell which one was open. Borrowing a
 * class across two documents only ever looks right by accident.
 *
 * Each tab carries its own accent, because the four are different KINDS of
 * work - paint is colour, parts are mechanical, extras are lights, the plate
 * is text - and a single purple for all four says they are interchangeable
 * when they are not. */
.g-tabs {
    display: grid; grid-template-columns: repeat(4, 1fr); gap: 5px;
    padding: 11px 12px 12px; flex: none;
}

.g-tab {
    --tab: var(--accent);
    position: relative;
    display: flex; align-items: center; justify-content: center;
    height: 30px; padding: 0 6px;
    border-radius: 9px;
    background: var(--card);
    border: 1px solid var(--border);
    color: var(--text-faint);
    font-family: inherit; font-size: 10.5px; font-weight: 800;
    cursor: pointer; overflow: hidden;
    transition: color .18s var(--ease), border-color .18s var(--ease),
                background .18s var(--ease), transform .1s var(--ease);
}

/* the wash sits UNDER the label and grows in, so the colour arrives rather
   than blinking on */
.g-tab::before {
    content: '';
    position: absolute; inset: 0;
    background: var(--tab);
    opacity: 0;
    transform: scaleY(.4);
    transform-origin: bottom;
    transition: opacity .2s var(--ease), transform .2s var(--ease);
}
.g-tab > * { position: relative; }

.g-tab:hover {
    color: var(--text);
    border-color: color-mix(in srgb, var(--tab) 55%, transparent);
}
.g-tab:hover::before { opacity: .10; transform: scaleY(1); }
.g-tab:active { transform: scale(.96); }

.g-tab.active {
    color: #fff;
    border-color: var(--tab);
    box-shadow: 0 3px 14px -4px var(--tab);
}
.g-tab.active::before { opacity: .30; transform: scaleY(1); }

/* and a bar along the bottom edge of the open one */
.g-tab::after {
    content: '';
    position: absolute; left: 22%; right: 22%; bottom: 0;
    height: 2px; border-radius: 2px 2px 0 0;
    background: var(--tab);
    transform: scaleX(0);
    transition: transform .22s var(--ease);
}
.g-tab.active::after { transform: scaleX(1); }

/* one accent per kind of work */
.g-tab[data-gtab="paint"]  { --tab: #e0457b; }
.g-tab[data-gtab="mods"]   { --tab: #3aa0ff; }
.g-tab[data-gtab="extras"] { --tab: #f5c518; }
.g-tab[data-gtab="plate"]  { --tab: #3ddc97; }
.g-body { flex: 1; min-height: 0; overflow-y: auto; padding: 12px; display: flex; flex-direction: column; gap: 12px; }

.g-section { display: flex; flex-direction: column; gap: 7px; }
.g-label {
    font-size: 9px; font-weight: 800; letter-spacing: .5px;
    color: var(--text-faint); text-transform: uppercase;
}

/* Swatches, not a numbered list: nobody picks "colour 134" by name. */
.g-swatches { display: grid; grid-template-columns: repeat(10, 1fr); gap: 4px; }
.g-swatch {
    aspect-ratio: 1; border-radius: 5px; cursor: pointer;
    border: 1px solid rgba(255,255,255,.10);
    transition: transform .12s var(--ease), border-color .12s var(--ease);
}
.g-swatch:hover { transform: scale(1.18); border-color: var(--text-dim); }
.g-swatch.on { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent); }

.g-row { display: flex; align-items: center; gap: 8px; min-height: 30px; }
.g-row label { flex: 1; font-size: 10.5px; font-weight: 700; color: var(--text-dim); }
.g-row select, .g-row input[type="text"], .g-row input[type="number"] {
    width: 140px; flex: none; height: 30px;
    background: var(--card); border: 1px solid var(--border); border-radius: 8px;
    padding: 0 9px; font-size: 10.5px; font-family: inherit; color: var(--text); outline: none;
}
.g-row select:focus, .g-row input:focus { border-color: var(--accent); }
.g-row input[type="text"] { direction: ltr; text-align: center; letter-spacing: 1px; font-weight: 800; }
.g-row input[type="range"] { width: 140px; flex: none; }
.g-row input[type="color"] {
    width: 44px; height: 28px; flex: none; padding: 0;
    background: none; border: 1px solid var(--border); border-radius: 7px; cursor: pointer;
}

.g-toggles { display: flex; flex-wrap: wrap; gap: 5px; }
.g-toggle {
    padding: 6px 10px; border-radius: 8px;
    background: var(--card); border: 1px solid var(--border);
    color: var(--text-faint); font-family: inherit; font-size: 10px; font-weight: 800;
    cursor: pointer;
    transition: background .15s var(--ease), border-color .15s var(--ease), color .15s var(--ease);
}
.g-toggle:hover { border-color: var(--border-strong); color: var(--text); }
.g-toggle.on { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-2); }

.g-actions { display: flex; flex-direction: column; gap: 6px; margin-top: 4px; }
.g-empty { font-size: 10px; color: var(--text-faint); font-weight: 700; padding: 6px 2px; }

/* the gear on a vehicle line: quiet until the line is hovered */
.cine-ent .garage-btn { opacity: 0; transition: opacity .15s var(--ease); }
.cine-ent:hover .garage-btn, .cine-ent.selected .garage-btn { opacity: 1; }


/* The three actions at the bottom of the plate tab. Same story as the tabs:
   they were written with `.pop-btn`, which is Bot Control's class and not
   one this document has, so they rendered as bare text. */
.g-btn {
    position: relative;
    display: flex; align-items: center; justify-content: center; gap: 7px;
    height: 34px; padding: 0 12px;
    border-radius: 10px;
    background: var(--card);
    border: 1px solid var(--border);
    color: var(--text-dim);
    font-family: inherit; font-size: 11px; font-weight: 800;
    cursor: pointer; overflow: hidden;
    transition: color .18s var(--ease), border-color .18s var(--ease),
                transform .1s var(--ease);
}
.g-btn::before {
    content: '';
    position: absolute; inset: 0;
    background: var(--accent);
    opacity: 0;
    transition: opacity .18s var(--ease);
}
.g-btn > * { position: relative; }
.g-btn svg { width: 13px; height: 13px; }

.g-btn:hover { color: #fff; border-color: var(--accent); }
.g-btn:hover::before { opacity: .18; }
.g-btn:active { transform: scale(.97); }

/* repair reads as a fix and randomise as a roll of the dice, so they are not
   the same colour as "put everything back" */
.g-btn.repair::before { background: #3ddc97; }
.g-btn.repair:hover   { border-color: #3ddc97; }
.g-btn.wand::before   { background: #f5c518; }
.g-btn.wand:hover     { border-color: #f5c518; }

/* the swatch grid gets a moment of lift on the one that is set, so the
   chosen colour is findable in 116 of them */
.g-swatch.on { transform: scale(1.12); z-index: 1; }


/* The warm-up note under the ped record button. An advisory, not a warning:
   amber rather than red, and quiet enough to read once and stop noticing. */
.cine-warmup {
    display: flex; align-items: flex-start; gap: 7px;
    margin-top: 8px; padding: 8px 10px;
    border-radius: 9px;
    background: rgba(245, 197, 24, .07);
    border: 1px solid rgba(245, 197, 24, .22);
    color: var(--text-dim);
    font-size: 10px; font-weight: 600; line-height: 1.55;
}
.cine-warmup svg { width: 13px; height: 13px; flex: none; margin-top: 1px; color: #f5c518; }


/* ==================== UI FX (fx-off turns all of it off) ==================== */

/* The three big tiles. Effects are transform/opacity only - they ride the
   compositor, not the layout engine, so the cost is one layer each. */
body:not(.fx-off) .block.featured {
    position: relative;
    overflow: hidden;
    transition: transform .18s var(--ease), box-shadow .25s var(--ease);
}
body:not(.fx-off) .block.featured::after {
    content: '';
    position: absolute; top: 0; bottom: 0; width: 45%;
    inset-inline-start: -60%;
    background: linear-gradient(100deg, transparent, rgba(255,255,255,.06), transparent);
    transform: skewX(-18deg);
    transition: inset-inline-start .55s var(--ease);
    pointer-events: none;
}
body:not(.fx-off) .block.featured:hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 30px -12px var(--accent);
}
body:not(.fx-off) .block.featured:hover::after { inset-inline-start: 115%; }
body:not(.fx-off) .block.featured:active { transform: translateY(0) scale(.985); }
body:not(.fx-off) .block.featured svg {
    transition: transform .22s var(--ease);
}
body:not(.fx-off) .block.featured:hover svg { transform: translateY(-1px) scale(1.12); }

/* fx-off: the entrance staggers across the app fall back to plain visible */
body.fx-off * { animation-duration: 0s !important; transition-duration: 0s !important; }

/* ==================== the sliders, everywhere ==================== */

/* One look for every range input in the app. The native control was leaking
   through on the ones nobody had styled - that is the blue bar. */
input[type="range"] {
    -webkit-appearance: none;
    appearance: none;
    height: 5px;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--accent), var(--accent-2, #a78bfa));
    box-shadow: inset 0 0 0 1px rgba(255,255,255,.05);
    outline: none;
    cursor: pointer;
}
input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 15px; height: 15px;
    border-radius: 50%;
    background: #fff;
    border: 3px solid var(--accent);
    box-shadow: 0 0 0 3px rgba(124, 92, 255, .18), 0 2px 8px rgba(0,0,0,.45);
    transition: transform .12s var(--ease), box-shadow .15s var(--ease);
}
body:not(.fx-off) input[type="range"]::-webkit-slider-thumb:hover { transform: scale(1.18); }
body:not(.fx-off) input[type="range"]:active::-webkit-slider-thumb {
    transform: scale(1.28);
    box-shadow: 0 0 0 6px rgba(124, 92, 255, .22), 0 2px 8px rgba(0,0,0,.45);
}

/* ==================== the vehicles menu animates like the rest ============ */
.veh-view > * {
    opacity: 0;
    animation: fade-up .26s var(--ease) forwards;
}
.veh-view > *:nth-child(1) { animation-delay: 0ms; }
.veh-view > *:nth-child(2) { animation-delay: 40ms; }
.veh-view > *:nth-child(3) { animation-delay: 80ms; }
.veh-view > *:nth-child(4) { animation-delay: 120ms; }
.veh-view > *:nth-child(5) { animation-delay: 160ms; }
.veh-view > *:nth-child(n+6) { animation-delay: 200ms; }

/* ==================== first-open priming ==================== */
#app.preopen { display: flex; opacity: 0; }

/* ==================== the data panel: enter once ==================== */
#cineDataBody.no-anim .cine-data-group { animation: none; opacity: 1; }

/* ==================== the schedule ==================== */
.cine-sched {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 10px 12px 12px;
    display: flex; flex-direction: column; gap: 6px;
}
.cine-sched:empty { display: none; }
.cs-head {
    display: flex; align-items: center; gap: 6px;
    font-size: 10px; font-weight: 800; color: var(--text-dim);
}
.cs-head svg { width: 12px; height: 12px; color: var(--accent-2, #a78bfa); }
.cs-total {
    margin-inline-start: auto; font-size: 9.5px; color: var(--text-faint);
    font-variant-numeric: tabular-nums;
}

.cs-tick {
    position: absolute; top: 0;
    font-size: 8px; color: var(--text-faint); font-variant-numeric: tabular-nums;
    transform: translateX(50%);
}
html[dir="ltr"] .cs-tick { transform: translateX(-50%); }



.cs-bar {
    position: absolute; top: 0; height: 100%;
    border-radius: 999px;
    background: var(--accent);
    box-shadow: 0 0 8px -2px var(--accent);
}
.cs-bar.k-anim      { background: #a78bfa; box-shadow: 0 0 8px -2px #a78bfa; }
.cs-bar.k-scene     { background: #7aa2f7; box-shadow: 0 0 8px -2px #7aa2f7; }
.cs-bar.k-effect    { background: #f2994a; box-shadow: 0 0 8px -2px #f2994a; }
.cs-bar.k-pedReplay { background: #3ddc97; box-shadow: 0 0 8px -2px #3ddc97; }
.cs-bar.k-vehReplay { background: #22d3ee; box-shadow: 0 0 8px -2px #22d3ee; }
.cs-bar.k-bot       { background: #7aa2f7; box-shadow: 0 0 8px -2px #7aa2f7; }
.cs-bar.k-crowd     { background: #f5c518; box-shadow: 0 0 8px -2px #f5c518; }
.cs-bar.k-prop      { background: #3ddc97; box-shadow: 0 0 8px -2px #3ddc97; }

/* ==================== the two replay add-buttons ==================== */
/* They were thin outline pills that read as disabled. Same card language as
   every other button in this panel: a surface, a border, a hover that
   answers. Colour kept - blue for the seat, green for the companion. */
.add-btn {
    display: flex; align-items: center; justify-content: center; gap: 7px;
    width: 100%; padding: 10px;
    border-radius: 10px;
    background: var(--card);
    border: 1px solid var(--border);
    color: var(--text-dim);
    font-family: inherit; font-size: 11px; font-weight: 800;
    cursor: pointer;
    transition: border-color .16s var(--ease), background .16s var(--ease),
                color .16s var(--ease), transform .1s var(--ease);
}
.add-btn svg { width: 13px; height: 13px; }
.add-btn:active { transform: scale(.98); }
.add-btn.blue:hover  { border-color: #7aa2f7; color: #fff; background: rgba(122,162,247,.12); }
.add-btn.green:hover { border-color: #3ddc97; color: #fff; background: rgba(61,220,151,.12); }

/* ==================== the keybind list ==================== */
.keybind-list { display: flex; flex-direction: column; gap: 5px; }
.keybind-row {
    display: flex; align-items: center; gap: 8px;
    padding: 8px 10px;
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 9px;
}
.kb-name { flex: 1; font-size: 10.5px; font-weight: 800; }
.kb-cmd  { font-size: 9px; color: var(--text-faint); direction: ltr; }
.kb-key  {
    font-size: 9px; font-weight: 800; padding: 2px 7px;
    border-radius: 5px;
    background: rgba(255,255,255,.06);
    border: 1px solid var(--border-strong);
    color: var(--text-dim);
}


/* ==================== round 2 ==================== */

/* the entrance as a transition (see showApp): both ends live here */
/* The end state is written OUT, not inherited from an animation fill:
   the old rule reached opacity 1 through `animation: appIn both`, and
   turning the animation off without stating the destination left the menu
   permanently invisible - the probe caught it before the game did. */
/* Entrance AND exit, as transitions between committed states.
   `.closing` is added while `.visible` is still present, so the
   `animation: none` here silenced appOut - the menu opened with motion and
   vanished without any. Both ends belong to the same mechanism. */
/* ENTRANCE AND EXIT ARE NOT THE SAME MOVE.
 *
 * Both were one 0.3s transition with 14px of travel, and the entrance read
 * as a bare fade that appeared out of nowhere while the exit read fine. That
 * is not a bug in the code, it is the wrong curve: a panel arriving should
 * decelerate INTO place - fast at first, settling at the end - and it needs
 * enough travel and time for that settle to be visible at all. A panel
 * leaving should do the opposite and get out of the way quickly.
 *
 * So the entrance now has more distance, a little more time, and an
 * ease-out that lands rather than stops; the exit stays short and eases in.
 * The mechanism is unchanged - still two committed states with a transition
 * between them, which is what made the first open of a session animate at
 * all after a keyframe animation kept getting its opening frames eaten.
 */
#app.visible {
    animation: none;
    visibility: visible;
    opacity: 1;
    transform: none;
    pointer-events: auto;
    /* arriving: 0.42s, decelerating - and visible from t=0 so the whole
       0.42s is spent on screen rather than half of it behind visibility */
    transition: opacity .42s cubic-bezier(.16, .84, .28, 1),
                transform .42s cubic-bezier(.16, .84, .28, 1),
                visibility 0s linear 0s;
}
/* kept so showApp's existing add/remove is harmless: it now names the same
   pose the base rule already holds, rather than being the only place it
   exists */
#app.visible.enter {
    opacity: 0;
    transform: translateY(26px) scale(.975);
}
#app.visible.closing {
    opacity: 0;
    transform: translateY(12px) scale(.985);
    /* leaving: shorter, accelerating */
    transition: opacity .2s cubic-bezier(.5, 0, .84, .3),
                transform .2s cubic-bezier(.5, 0, .84, .3);
}

/* THE THREE TILES, reshaped: an icon chip, a name with a line under it that
   says what lives inside, and a chevron that says "this opens something". */
.block.featured {
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 13px;
    min-height: 64px;
    padding: 13px 16px;
    text-align: start;
    background: linear-gradient(135deg, var(--card), rgba(124, 92, 255, .10));
    border: 1px solid var(--border-strong);
}
.block.featured .feat-icon {
    flex: none;
    width: 38px; height: 38px;
    border-radius: 12px;
    display: flex; align-items: center; justify-content: center;
    background: var(--accent-soft, rgba(124,92,255,.16));
    color: var(--accent-2, #a78bfa);
}
.block.featured .feat-icon svg { width: 19px; height: 19px; }
.block.featured .feat-text {
    flex: 1; min-width: 0;
    display: flex; flex-direction: column; gap: 2px;
}
.block.featured .feat-text .label { font-size: 13px; font-weight: 800; }
/* Was --text-faint, which is tuned for a dark card and disappears against
   the accent fill an active tile carries. */
.block.featured .feat-desc {
    font-size: 9.5px; font-weight: 600;
    color: var(--text-dim);
    opacity: .85;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.block.featured.active .feat-desc { color: rgba(255,255,255,.82); opacity: 1; }
.block.featured .feat-chev { flex: none; opacity: .45; display: flex; }
.block.featured .feat-chev svg { width: 14px; height: 14px; transform: scaleX(-1); }
html[dir="ltr"] .block.featured .feat-chev svg { transform: none; }
body:not(.fx-off) .block.featured:hover .feat-chev { opacity: .9; }
body:not(.fx-off) .block.featured:hover .feat-icon { transform: scale(1.08); }
.block.featured .feat-icon { transition: transform .2s var(--ease); }

/* the picker's search box: the same field as everywhere else, not a sliver */
.cine-search {
    display: flex; align-items: center; gap: 8px;
    padding: 10px 12px;
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 11px;
    transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.cine-search:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(124, 92, 255, .14);
}
.cine-search svg { width: 14px; height: 14px; color: var(--text-faint); flex: none; }
.cine-search input {
    flex: 1; min-width: 0;
    background: none; border: none; outline: none;
    font-family: inherit; font-size: 12px; color: var(--text);
}

/* the data panel: NOTHING re-animates on a push, whatever it is */
/* Killing an entrance animation must also state where it was GOING.
   These rows start at opacity 0 and are carried to 1 by the animation, so
   `animation: none` alone leaves them present, sized and invisible - the
   empty grey panel with gaps where rows should be. Exactly the mistake the
   #app entrance override made; caught there, repeated here. */
#cineDataBody.no-anim *,
#cineDataBody.no-anim .cine-data-group,
#cineDataBody.no-anim .cine-ent {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
}

/* the schedule, readable: room for the name, the times written out */





.cs-hint { font-size: 8.5px; color: var(--text-faint); font-weight: 600; }


/* ---------- world-zone picker card ---------- */
.world-pick-hud {
    position: fixed;
    left: 0; right: 0; margin-inline: auto;
    bottom: 26px;
    width: max-content; max-width: 90vw;
    display: none;
    align-items: center; gap: 12px;
    padding: 10px 18px;
    background: var(--panel);
    border: 1px solid var(--border-strong);
    border-radius: 999px;
    box-shadow: 0 14px 40px rgba(0,0,0,.5);
    font-size: 12.5px; color: var(--text);
    z-index: 60;
}
.world-pick-hud.visible { display: flex; animation: fade-up .25s var(--ease) both; }
.world-pick-hud .wp-count {
    font-weight: 800; font-size: 14px;
    color: var(--accent);
}
.world-pick-hud .wp-sep { width: 1px; height: 14px; background: var(--border); }

.world-pick-hud .wp-close { color: #50dc78; font-weight: 700; }


/* ---------- inline entry rename ---------- */
.cine-rename-input {
    background: var(--card);
    border: 1px solid var(--accent);
    border-radius: 8px;
    color: var(--text);
    font: inherit; font-size: 12.5px;
    padding: 3px 8px;
    width: 100%;
    outline: none;
}

/* ---------- the countdown's mark ---------- */



/* ---------- the schedule invites the hand ---------- */
.cs-bar { cursor: grab; transition: filter .15s var(--ease); }
.cs-bar:hover { filter: brightness(1.35); }
.cs-bar:active { cursor: grabbing; }

/* ---------- garage: the extras tab reads as a form ---------- */
.g-body .g-section-title {
    font-size: 10px; font-weight: 800; letter-spacing: .6px;
    text-transform: uppercase; color: var(--text-faint);
    margin: 14px 0 8px;
}
.g-body input[type="color"] {
    -webkit-appearance: none; appearance: none;
    width: 46px; height: 30px;
    border: 1px solid var(--border-strong);
    border-radius: 8px;
    background: var(--card);
    padding: 3px;
    cursor: pointer;
}
.g-body input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
.g-body input[type="color"]::-webkit-color-swatch { border: none; border-radius: 5px; }
.g-row {
    display: flex; align-items: center; justify-content: space-between;
    gap: 10px; padding: 6px 0;
}


/* ==================== the schedule, as a grid ====================

   Two tracks: a fixed name column and everything else. A cell cannot push
   its neighbours, which is the whole point - the old flex row grew its
   time label as a bar moved and shoved the track through the panel's edge.
   The time rides inside the bar now and costs no layout at all. */
.cs-grid {
    position: relative;
    display: grid;
    grid-template-columns: 92px 1fr;
    align-items: center;
    gap: 5px 8px;
}
.cs-corner { grid-column: 1; }

.cs-ruler {
    position: relative;
    grid-column: 2;
    height: 13px;
    border-bottom: 1px solid var(--border);
}
.cs-tick {
    position: absolute; top: 0;
    font-size: 8px; color: var(--text-faint);
    font-variant-numeric: tabular-nums;
    transform: translateX(50%);
    pointer-events: none;
}
html[dir="ltr"] .cs-tick { transform: translateX(-50%); }

.cs-name {
    grid-column: 1;
    font-size: 9.5px; font-weight: 700; color: var(--text-dim);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.cs-track {
    grid-column: 2;
    position: relative;
    height: 14px;
    background: rgba(255,255,255,.04);
    border-radius: 999px;
    overflow: hidden;          /* nothing escapes its lane, ever */
}

.cs-bar {
    position: absolute; top: 0; height: 100%;
    min-width: 26px;
    border-radius: 999px;
    background: var(--accent);
    display: flex; align-items: center; justify-content: center;
    cursor: grab;
    transition: filter .14s var(--ease), box-shadow .14s var(--ease);
}
.cs-bar:hover { filter: brightness(1.3); }
.cs-bar.dragging { cursor: grabbing; filter: brightness(1.45); z-index: 3; }
.cs-bar-time {
    font-size: 8px; font-weight: 800;
    color: rgba(0,0,0,.72);
    font-variant-numeric: tabular-nums;
    pointer-events: none;
    padding: 0 4px;
}

/* the playhead sweeps the track column across every row */
.cs-playhead {
    position: absolute;
    top: 13px; bottom: 0;
    inset-inline-start: 0;
    width: 2px;
    margin-inline-start: 100px;   /* the name column + the grid gap */
    background: #ff5f6d;
    box-shadow: 0 0 10px 1px rgba(255,95,109,.8);
    display: none;
    pointer-events: none;
    z-index: 4;
}
.cs-playhead.visible { display: block; }

.cs-hint { font-size: 8.5px; color: var(--text-faint); margin-top: 2px; }


/* ==================== the count-in, across the whole frame ====================

   A count-in is the moment the shot goes live, and the old one happened
   entirely inside a 300px box in the middle of an empty screen. This layer
   lights the FRAME: bars sweeping in from all four edges, a cinema
   letterbox, and a vignette that breathes with every second.

   Everything here is pointer-events:none inside a layer that is itself
   pointer-events:none - a decorative overlay must never be able to eat a
   click, which is the lesson the focus bug taught the hard way. */

.rc-frame { position: absolute; inset: 0; pointer-events: none; }
.rc-frame * { pointer-events: none; }

/* the four edges */
.rc-edge {
    position: absolute;
    background: linear-gradient(90deg, transparent, var(--accent-2, #a78bfa), transparent);
    opacity: .9;
    filter: drop-shadow(0 0 14px rgba(167,139,250,.9));
}
.rc-e-top, .rc-e-bottom { left: 0; right: 0; height: 3px; }
.rc-e-left, .rc-e-right { top: 0; bottom: 0; width: 3px;
    background: linear-gradient(180deg, transparent, var(--accent-2, #a78bfa), transparent); }
.rc-e-top    { top: 0;    animation: rcEdgeH .5s var(--ease) both; }
.rc-e-bottom { bottom: 0; animation: rcEdgeH .5s var(--ease) both .06s; }
.rc-e-left   { left: 0;   animation: rcEdgeV .5s var(--ease) both .12s; }
.rc-e-right  { right: 0;  animation: rcEdgeV .5s var(--ease) both .18s; }

@keyframes rcEdgeH { from { opacity: 0; transform: scaleX(.2); } to { opacity: .9; transform: none; } }
@keyframes rcEdgeV { from { opacity: 0; transform: scaleY(.2); } to { opacity: .9; transform: none; } }

/* a pulse per tick, added and removed by the renderer */
.rc-frame.pulse .rc-edge { animation: rcPulse .55s var(--ease) both; }
@keyframes rcPulse {
    0%   { opacity: 1; filter: drop-shadow(0 0 26px rgba(167,139,250,1)); }
    100% { opacity: .55; filter: drop-shadow(0 0 10px rgba(167,139,250,.7)); }
}





/* the vignette breathes */
.rc-vignette {
    position: absolute; inset: 0;
    background: radial-gradient(ellipse at center,
        transparent 42%, rgba(0,0,0,.45) 100%);
    animation: rcBreathe 1s var(--ease) infinite;
}
@keyframes rcBreathe { 0%,100% { opacity: .75; } 50% { opacity: 1; } }

/* zero: the frame goes hot */
.rc-frame.live .rc-edge {
    background: linear-gradient(90deg, transparent, #ff3b4e, transparent);
    filter: drop-shadow(0 0 30px rgba(255,59,78,1));
    animation: rcHot .9s var(--ease) both;
}
.rc-frame.live .rc-e-left, .rc-frame.live .rc-e-right {
    background: linear-gradient(180deg, transparent, #ff3b4e, transparent);
}
@keyframes rcHot { 0% { opacity: 1; } 60% { opacity: 1; } 100% { opacity: 0; } }

/* the white flash on zero */
.rec-countdown.go::before {
    content: '';
    position: absolute; inset: 0;
    background: #fff;
    animation: rcFlash .5s var(--ease) both;
    pointer-events: none;
}
@keyframes rcFlash { 0% { opacity: .85; } 100% { opacity: 0; } }

/* the digit flies through */



.rec-count-stage { position: relative; z-index: 2; }
.rec-count-label { position: relative; z-index: 2; }
.rec-count-label.action { color: #ff6b7d; }
.rec-count-go  { position: relative; z-index: 2;
                 animation: rcGo .9s var(--ease) both !important; }
@keyframes rcGo {
    0%   { opacity: 0; transform: scale(.6); letter-spacing: 26px; }
    30%  { opacity: 1; transform: scale(1.06); letter-spacing: 8px; }
    100% { opacity: 0; transform: scale(1); letter-spacing: 8px; }
}





/* ==================== the replay trim bar ====================
   The point is that the cut is VISIBLE: the kept span is solid, the
   trimmed head and tail stay on screen as dimmed hatched stubs. Trimming
   blind was the complaint; this is the answer. */
.ft-wrap {
    /* WIDE ENOUGH TO AIM AT.
       A fixed 118px across a ten-second take put the handles almost on top
       of each other, and the row's flexible NAME column then squeezed even
       that down to about forty pixels - the cut was pure guesswork.
       The trim bar is the instrument on this row, so it gets the space and
       the name yields: a name can ellipsis, a timeline cannot. */
    flex: 1 1 190px;
    min-width: 150px;
    display: flex; flex-direction: column; gap: 3px;
    margin-inline-end: 4px;
}
.ft-bar {
    /* AN LTR ISLAND INSIDE AN RTL PAGE.
       A timeline is a physical metaphor - time runs left to right in every
       editor ever made - so this strip does not mirror with the language.
       Logical insets flipped it in Arabic and put the in-point on the
       right, which made the left handle trim the END. */
    direction: ltr;
    position: relative;
    height: 16px;
    border-radius: 999px;
    background: rgba(255,255,255,.05);
    overflow: visible;
}
.ft-keep {
    position: absolute; top: 0; height: 100%;
    background: var(--accent);
    border-radius: 999px;
    box-shadow: 0 0 8px -2px var(--accent);
}
.ft-cut {
    position: absolute; top: 0; height: 100%;
    border-radius: 999px;
    background-image: repeating-linear-gradient(
        45deg, rgba(255,255,255,.16) 0 3px, transparent 3px 6px);
    background-color: rgba(255,255,255,.05);
}
.ft-handle {
    position: absolute; top: 50%;
    width: 11px; height: 22px;
    margin-left: -5.5px;
    transform: translateY(-50%);
    border-radius: 3px;
    background: #fff;
    border: 1px solid rgba(0,0,0,.35);
    box-shadow: 0 2px 8px rgba(0,0,0,.5);
    cursor: ew-resize;
    z-index: 2;
}
.ft-handle:hover { background: var(--accent); }
.ft-read {
    font-size: 8.5px; font-weight: 700;
    color: var(--text-faint);
    font-variant-numeric: tabular-nums;
    text-align: center;
}
.ft-wrap.trimmed .ft-read { color: var(--accent); }
.ft-of { opacity: .6; font-weight: 500; }




/* ---------- the schedule bar's end grip ----------
   Grab the end of a bar to say how long the entry occupies the shot. It is
   deliberately a separate hit area from the bar's body, which MOVES the
   cue - two gestures, two handles, no mode to remember. */
/* THE HANDLE YOU PULL THE END IN WITH.
   It used to be 9px wide and fully transparent until the bar was hovered,
   which is the same as not being there: on a bar a few percent wide there was
   no arrow to aim at and no way to know the bar could be shortened at all.
   Now it is always visible on any bar that HAS a length, wide enough to hit,
   and carries two grip lines so it reads as something to drag. */
.cs-grip {
    position: absolute;
    inset-inline-end: 0; top: 0; bottom: 0;
    width: 14px;
    border-start-end-radius: 999px;
    border-end-end-radius: 999px;
    background: rgba(0, 0, 0, .34);
    cursor: ew-resize;
    opacity: .82;
    transition: opacity .14s var(--ease), background .14s var(--ease);
}
.cs-bar:hover .cs-grip, .cs-bar.resizing .cs-grip {
    opacity: 1;
    background: rgba(0, 0, 0, .5);
}
/* two lines, the universal "drag this edge" */
.cs-grip::before, .cs-grip::after {
    content: '';
    position: absolute; top: 50%;
    width: 2px; height: 9px;
    transform: translateY(-50%);
    background: rgba(255, 255, 255, .9);
    border-radius: 1px;
}
.cs-grip::before { inset-inline-end: 8px; }
.cs-grip::after  { inset-inline-end: 4px; }
.cs-bar.resizing { filter: brightness(1.45); z-index: 3; }
/* a bar the director has shortened by hand wears a cut edge */
.cs-bar.shortened {
    border-start-end-radius: 3px;
    border-end-end-radius: 3px;
    box-shadow: inset -3px 0 0 rgba(255,255,255,.55);
}


/* ==================== the project branch ====================

   A project hangs OFF the Director tile the way a sub-item hangs off a
   category. The first attempt floated it loose in the middle of the menu
   and it read as a stray row belonging to nothing; an elbow connector and
   an indent are what make it read as "this belongs to the tile above".

   It spans the same grid columns as the featured tiles so it lines up with
   them exactly, whatever the layout is doing. */
.proj-branch {
    grid-column: 1 / -1;
    margin: -2px 0 6px;
    padding-inline-start: 22px;
    position: relative;
    animation: fade-up .26s var(--ease) both;
}

/* the elbow: down from the tile, then across into the row */
.pb-elbow {
    position: absolute;
    inset-inline-start: 8px;
    top: -6px; bottom: 50%;
    width: 10px;
    border-inline-start: 2px solid var(--border-strong);
    border-end-start-radius: 8px;
    border-bottom: 2px solid var(--border-strong);
    pointer-events: none;
}
.proj-branch.live .pb-elbow { border-color: color-mix(in srgb, var(--accent) 60%, transparent); }

.pb-head {
    width: 100%;
    display: flex; align-items: center; gap: 8px;
    padding: 7px 10px;
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 10px;
    color: var(--text-dim);
    font-size: 11px; font-weight: 700;
    cursor: pointer;
    transition: background .15s var(--ease), border-color .15s var(--ease);
}
.pb-head:hover { background: var(--card-hover); color: var(--text); }
.proj-branch.live .pb-head {
    border-color: color-mix(in srgb, var(--accent) 50%, transparent);
    background: color-mix(in srgb, var(--accent) 12%, var(--card));
    color: var(--text);
}
.pb-title { flex: 1; text-align: start; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pb-count {
    font-size: 9px; color: var(--text-faint);
    background: rgba(255,255,255,.06);
    padding: 1px 7px; border-radius: 999px;
}
.proj-branch.live .pb-count { color: var(--accent); background: color-mix(in srgb, var(--accent) 18%, transparent); }
.pb-chev { display: flex; transition: transform .2s var(--ease); }
.pb-chev svg { width: 12px; height: 12px; }
.proj-branch.open .pb-chev { transform: rotate(-90deg); }

/* the list only exists when the branch is open */
.pb-list { display: none; margin-top: 4px; }
.proj-branch.open .pb-list { display: flex; flex-direction: column; gap: 3px; }

.pb-row {
    display: flex; align-items: center; gap: 8px;
    padding: 6px 10px;
    border-radius: 9px;
    background: rgba(255,255,255,.03);
    font-size: 11px;
    cursor: pointer;
    animation: fade-up .22s var(--ease) both;
    transition: background .14s var(--ease);
}
.pb-row:hover { background: rgba(255,255,255,.07); }
.pb-dot {
    width: 6px; height: 6px; border-radius: 50%;
    background: var(--text-faint); flex: none;
}
.pb-row.current .pb-dot {
    background: var(--accent);
    box-shadow: 0 0 8px var(--accent);
}
.pb-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pb-x { flex: none; }


/* ---------- entrances play once ----------
   A container marked `no-anim` (every render after the first - see
   settleAnim in script.js) switches the staggered entrance off for its
   children. Without this every redraw replayed the whole shimmer, which
   is what made the menus feel like they never settled. */
.no-anim > *,
.no-anim .scene-item,
.no-anim .scene-row,
.no-anim .anim-item,
.no-anim .fx-item,
.no-anim .cine-project,
.no-anim .cine-entry,
.no-anim .cine-data-group,
.no-anim .cine-ent,
.no-anim .cine-row,
.no-anim .block,
.no-anim .ped-card,
.no-anim .ped-row,
.no-anim .folder-row,
.no-anim .ped-list > .ped-row,
.no-anim .pb-row {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
}


/* the two handles read as IN and OUT, not as two identical grips */
.ft-in  { border-radius: 3px 1px 1px 3px; }
.ft-out { border-radius: 1px 3px 3px 1px; }
.ft-in::after, .ft-out::after {
    content: '';
    position: absolute; top: 50%; left: 50%;
    width: 1px; height: 9px;
    transform: translate(-50%, -50%);
    background: rgba(0,0,0,.45);
}
/* the kept span carries the time; the trimmed ends stay visible but muted */
.ft-keep { z-index: 1; }
.ft-cut  { opacity: .55; }


/* ---------- the count-in digit ----------
   Three tries at this. The first blurred and shrank, which read as smeared;
   the second rose and settled, which read as flat. A count-in has a PULSE -
   the number lands, holds, and is gone before the next arrives - so this
   one snaps in fast, holds dead still for most of the second, then leaves
   quickly upward. The ring behind it expands on the same beat. */
.rec-count-num { animation: rcDigit3 1s cubic-bezier(.2,.9,.25,1) both !important; }
@keyframes rcDigit3 {
    0%   { opacity: 0; transform: scale(1.65) translateY(6px); }
    12%  { opacity: 1; transform: scale(1)    translateY(0); }
    16%  { transform: scale(1.06); }
    24%  { transform: scale(1); }
    76%  { opacity: 1; transform: scale(1) translateY(0); }
    100% { opacity: 0; transform: scale(.94) translateY(-16px); }
}

/* the ring pushes out with the digit rather than sitting still */
.rec-count-ring { animation: rcRing3 1s cubic-bezier(.2,.9,.25,1) both !important; }
@keyframes rcRing3 {
    0%   { opacity: 0; transform: scale(.7); }
    14%  { opacity: .85; transform: scale(1); }
    100% { opacity: 0; transform: scale(1.28); }
}

/* the edge lines breathe once per tick instead of fading flat */
.rc-frame.pulse .rc-edge { animation: rcPulse2 1s cubic-bezier(.2,.9,.25,1) both !important; }
@keyframes rcPulse2 {
    0%   { opacity: 1;   filter: drop-shadow(0 0 30px rgba(167,139,250,1)); }
    18%  { opacity: .95; filter: drop-shadow(0 0 18px rgba(167,139,250,.9)); }
    100% { opacity: .45; filter: drop-shadow(0 0 8px rgba(167,139,250,.6)); }
}


/* ==================== the live-chase banner ====================

   Same shape as the recording indicator, on purpose: it is the same kind of
   thing - a card that reports live state and names the key that ends it -
   so it should read as the same kind of thing. It borrows .cine-rec-dot /
   -title / -hint rather than restating them, which is also what keeps the
   two from drifting apart.

   It sits BELOW the recorder rather than on top of it, so a chase being
   recorded shows both instead of one hiding the other. */
.chase-hud {
    position: fixed; top: 5vh; left: 50%; transform: translateX(-50%);
    display: none; flex-direction: column; align-items: center; gap: 3px;
    padding: 12px 26px; border-radius: 14px;
    background: rgba(12, 6, 22, .88);
    border: 1px solid rgba(255, 59, 78, .5);
    box-shadow: 0 16px 44px rgba(0, 0, 0, .5);
    z-index: 40; pointer-events: none;
}
/* Its own entrance, NOT the shared fade-up.
   fade-up ends on `transform: translateY(0)`, and a running animation beats
   the stylesheet - so it overwrote the translateX(-50%) doing the centring
   and the banner sat off to one side. Measured at 194px wide, 105px left of
   centre. Anything positioned with a transform needs an entrance that keeps
   that transform in every frame. */
.chase-hud.visible { display: flex; animation: chaseHudIn .3s var(--ease) both; }
@keyframes chaseHudIn {
    from { opacity: 0; transform: translateX(-50%) translateY(4px); }
    to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}
/* clear of the recorder when both are up */
.cine-rec-hud.visible ~ .chase-hud.visible { top: calc(5vh + 88px); }


/* ==================== small motion, everywhere ====================

   The brief was "not loud, not dead". These are the touches that make a
   panel feel built rather than drawn: a card lifts a little under the
   cursor, a pressed button gives, a primary action carries one slow sheen.
   Nothing here loops fast enough to notice while you work, and all of it
   goes silent under the fx-off setting. */

.block, .cine-row, .cine-project, .scene-item, .anim-item, .ped-card, .pb-row {
    transition: transform .16s var(--ease), box-shadow .16s var(--ease),
                background .16s var(--ease);
}
.block:hover, .cine-row:hover, .cine-project:hover,
.scene-item:hover, .anim-item:hover, .ped-card:hover {
    transform: translateY(-1px);
}
.block:active, .cine-row:active, .cine-project:active,
.scene-item:active, .anim-item:active { transform: translateY(0) scale(.995); }

/* the featured tiles lift a touch more and light their own edge */
.block.featured { transition: transform .18s var(--ease), box-shadow .18s var(--ease); }
.block.featured:hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 30px -12px color-mix(in srgb, var(--accent) 70%, transparent);
}

/* one slow sheen across the primary action - three seconds apart, so it
   reads as a highlight rather than a loading bar */
.cine-record, .modal-btn.place, .ch-stop {
    position: relative;
    overflow: hidden;
}
.cine-record::after, .modal-btn.place::after {
    content: '';
    position: absolute; inset: 0;
    background: linear-gradient(105deg, transparent 38%,
        rgba(255,255,255,.16) 50%, transparent 62%);
    transform: translateX(-120%);
    animation: sheen 3.2s ease-in-out infinite;
    pointer-events: none;
}
@keyframes sheen {
    0%, 72% { transform: translateX(-120%); }
    100%    { transform: translateX(120%); }
}

/* buttons acknowledge the press */
.icon-btn, .modal-btn, .seg-btn, .chip-btn {
    transition: transform .12s var(--ease), background .14s var(--ease),
                border-color .14s var(--ease);
}
.icon-btn:active, .modal-btn:active, .seg-btn:active, .chip-btn:active {
    transform: scale(.94);
}

/* the fx-off switch silences every one of these */
body.fx-off .block, body.fx-off .cine-row, body.fx-off .cine-project,
body.fx-off .scene-item, body.fx-off .anim-item, body.fx-off .ped-card,
body.fx-off .pb-row, body.fx-off .icon-btn, body.fx-off .modal-btn,
body.fx-off .seg-btn, body.fx-off .chip-btn {
    transition: none !important;
    transform: none !important;
}
body.fx-off .cine-record::after,
body.fx-off .modal-btn.place::after { animation: none; opacity: 0; }


/* the frame row gives the trim bar its room: the NAME shrinks, the
   instrument does not */
.cine-row .cine-row-main { flex: 0 1 auto; min-width: 60px; overflow: hidden; }
.cine-row .cine-row-name,
.cine-row .cine-row-meta { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }


/* the My Peds list staggers with per-row animation-delay rules, which the
   generic no-anim block above cannot reach - the delay still applies to a
   fresh element even when the animation is off. Named explicitly. */
.no-anim .ped-list > .ped-row,
.no-anim .ped-list > .folder-row {
    animation: none !important;
    animation-delay: 0ms !important;
    opacity: 1 !important;
    transform: none !important;
}


/* ==================== sharing a set with the player next to you ====================

   One overlay for both ends of the transfer - picking what to send, and
   answering an offer that arrived. It is deliberately a plain centred card
   rather than a panel: it appears on top of whatever you were doing, on both
   machines, and has to read as an interruption that ends. */
.share-overlay {
    position: fixed; inset: 0;
    display: none; align-items: center; justify-content: center;
    /* NO backdrop-filter. Same trap the modal overlay documents further up:
       FiveM's NUI layer sits over the 3D game frame rather than over web
       content, and CEF cannot sample that for a blur - it renders the whole
       game view behind the overlay as SOLID BLACK no matter how transparent
       the tint is. A plain tint is the only dimming here. */
    background: rgba(6, 3, 12, .62);
    z-index: 70;
}
.share-overlay.visible { display: flex; }

.share-card {
    width: min(420px, 92vw);
    max-height: 84vh; overflow-y: auto;
    padding: 16px 18px 18px;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 18px;
    box-shadow: 0 30px 80px rgba(0, 0, 0, .6);
    animation: shareIn .26s var(--ease) both;
}
@keyframes shareIn {
    from { opacity: 0; transform: translateY(10px) scale(.98); }
    to   { opacity: 1; transform: none; }
}

.share-head { display: flex; align-items: flex-start; gap: 11px; margin-bottom: 14px; }
.share-head-text { flex: 1 1 auto; min-width: 0; }
.share-head h3 { margin: 0; font-size: 14.5px; font-weight: 800; color: var(--text); }
.share-head p  { margin: 3px 0 0; font-size: 11.5px; color: var(--text-faint); line-height: 1.45; }
.share-icon {
    flex: 0 0 auto; display: grid; place-items: center;
    width: 32px; height: 32px; border-radius: 10px;
    background: rgba(139, 92, 246, .16); color: var(--accent-2);
}
.share-icon svg { width: 16px; height: 16px; }
.share-x { flex: 0 0 auto; }

.share-sec {
    font-size: 10.5px; font-weight: 800; letter-spacing: .5px;
    color: var(--text-faint); text-transform: uppercase;
    margin: 14px 0 7px;
}

.share-who-list { display: flex; flex-direction: column; gap: 5px; }
.share-who {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    width: 100%; padding: 9px 12px;
    background: rgba(255, 255, 255, .035);
    border: 1px solid var(--border); border-radius: 11px;
    color: var(--text); font: inherit; font-size: 12px; font-weight: 700;
    cursor: pointer; text-align: start;
    transition: background .15s var(--ease), border-color .15s var(--ease);
}
.share-who:hover { background: rgba(255, 255, 255, .07); }
.share-who.on { border-color: var(--accent-2); background: rgba(139, 92, 246, .16); }
.sw-dist { font-size: 10.5px; color: var(--text-faint); font-variant-numeric: tabular-nums; direction: ltr; }
.share-empty { margin: 0; padding: 12px; font-size: 11.5px; color: var(--text-faint);
               background: rgba(255,255,255,.03); border-radius: 11px; line-height: 1.5; }

.share-kinds { display: grid; grid-template-columns: 1fr 1fr; gap: 5px; }
.share-kind {
    display: flex; align-items: center; gap: 9px;
    padding: 9px 10px; border-radius: 10px;
    background: rgba(255, 255, 255, .035);
    border: 1px solid var(--border);
    font-size: 11.5px; font-weight: 700; color: var(--text);
    cursor: pointer;
    transition: background .15s var(--ease), border-color .15s var(--ease);
}
.share-kind:not(.off):hover { background: rgba(255, 255, 255, .07); }
.share-kind:has(input:checked) { border-color: var(--accent-2); background: rgba(139, 92, 246, .14); }
.share-kind.off { opacity: .4; cursor: default; }

/* THE TICK, DRAWN RATHER THAN LEFT TO THE BROWSER.
   A native checkbox in CEF renders as the operating system's - a flat blue
   Windows square with a hairline tick - which is the one thing on this panel
   that looks like it came from somewhere else. This is the same rounded
   square, border and accent as every other control here. */
.share-kind input[type="checkbox"] {
    appearance: none; -webkit-appearance: none;
    flex: 0 0 auto; position: relative;
    width: 16px; height: 16px; margin: 0;
    border: 1.5px solid var(--border);
    border-radius: 5px;
    background: rgba(0, 0, 0, .25);
    cursor: inherit;
    transition: background .15s var(--ease), border-color .15s var(--ease);
}
.share-kind input[type="checkbox"]:hover:not(:disabled) { border-color: var(--accent-2); }
.share-kind input[type="checkbox"]:checked {
    background: var(--accent-2);
    border-color: var(--accent-2);
}
/* the tick itself: two borders on a rotated box, so it scales cleanly and
   needs no image */
.share-kind input[type="checkbox"]:checked::after {
    content: '';
    position: absolute;
    left: 4.5px; top: 1.5px;
    width: 4px; height: 8px;
    border: solid #fff;
    border-width: 0 2px 2px 0;
    transform: rotate(42deg);
}
.share-kind input[type="checkbox"]:disabled { opacity: .5; }
.share-kind .sk-name { flex: 1 1 auto; min-width: 0; }
.share-kind .sk-count {
    flex: 0 0 auto; min-width: 20px; padding: 1px 6px;
    background: rgba(139, 92, 246, .2); border-radius: 999px;
    font-size: 10px; text-align: center; font-variant-numeric: tabular-nums;
}

.share-list { margin: 0; padding: 12px 14px; list-style: none;
              background: rgba(255,255,255,.03); border-radius: 12px; }
.share-list li { font-size: 12px; color: var(--text); padding: 2px 0; }
.share-note { margin: 9px 0 0; font-size: 10.5px; color: var(--text-faint); }

.share-bar {
    height: 6px; border-radius: 999px; overflow: hidden;
    background: rgba(255, 255, 255, .08);
}
/* LTR island: a progress bar fills from its start, and in RTL `width` on a
   child would still grow rightwards while the eye expects the opposite. */
.share-bar { direction: ltr; }
.share-bar span {
    display: block; height: 100%;
    background: linear-gradient(90deg, var(--accent-2), var(--accent));
    transition: width .2s var(--ease);
}

.share-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 16px; }
.share-actions button { padding: 9px 16px; border-radius: 10px; font: inherit; font-size: 12px; font-weight: 800; cursor: pointer; }
.share-actions .btn-ghost { background: rgba(255,255,255,.05); border: 1px solid var(--border); color: var(--text); }
.share-actions .btn-ghost:hover { background: rgba(255,255,255,.09); }
.share-actions .btn-primary { background: var(--accent-2); border: 0; color: #fff; }
.share-actions .btn-primary:hover { filter: brightness(1.1); }
.share-actions .btn-primary:disabled { opacity: .4; cursor: default; filter: none; }

/* The share button lives on each PROJECT ROW, beside its delete button -
   that is the row the set belongs to, and it is where the eye already goes
   for per-project actions. It was on the branch header first, which reads as
   "share the menu" rather than "share this project". */
.cine-project [data-act="share"] { color: var(--accent-2); }
.cine-project [data-act="share"]:hover { background: rgba(139, 92, 246, .2); }


/* the scale from config.lua, applied to the panel itself. HUDs and the
   count-in stay at 1: those are read at a glance from across the room and
   are already sized for that. */
#app { zoom: var(--ui-scale); }

/* Who built this character. Only ever present on a shared shelf, where a
   delete affects everybody - so the list has to say whose work it is before
   somebody removes it. */
.ped-row-author {
    margin-inline-start: 8px;
    padding: 1px 7px;
    border-radius: 999px;
    background: var(--accent-soft);
    color: var(--text-faint);
    font-size: 9.5px; font-weight: 700;
    white-space: nowrap;
}

/* THE ROW YOU PICKED, in every Director picker - animations, scenes, effects.
   Nothing marked the choice before: the click jumped to the config screen and
   the list kept no memory of it, so a slow jump read as an ignored click and
   coming back showed no trace of what you had chosen. Same accent as the
   active tab, because it means the same thing. */
.cine-row.selected {
    border-color: var(--accent-2);
    background: var(--accent-soft);
}
.cine-row.selected .cine-row-name { color: #fff; }
/* the marker rides on the inline START edge, so it is on the correct side in
   Arabic without a second rule */
.cine-row.selected::before {
    content: '';
    position: absolute;
    inset-inline-start: 0; top: 12%; bottom: 12%;
    width: 3px; border-radius: 999px;
    background: var(--accent-2);
}
.cine-row { position: relative; }

/* ==================== THE COUNT-IN, MADE CHEAP ====================

   What it cost before: four screen-width edges each carrying an ANIMATED
   `filter: drop-shadow`, a stroked SVG circle with another animated
   drop-shadow, and gradient-clipped text with a third - all re-running every
   tick of the count.

   An animated filter is the most expensive thing a page can do. It cannot be
   handed to the compositor, so every frame of it re-rasterises the element -
   and these elements are the size of the screen. That is where the frames
   went during ACTION and the timer.

   Nothing here changes how it LOOKS at rest. The glows stay; they are simply
   static now, and only `opacity` and `transform` animate - the two properties
   the compositor can do on its own thread without touching the rasteriser. */

.rc-frame.pulse .rc-edge {
    /* was: animating filter: drop-shadow */
    animation: rcPulseCheap .55s var(--ease) both;
}
@keyframes rcPulseCheap {
    0%   { opacity: 1; }
    100% { opacity: .55; }
}

.rec-count-dial .sweep {
    /* the glow, once, instead of per frame */
    filter: drop-shadow(0 0 8px rgba(168, 85, 247, .8));
    will-change: stroke-dashoffset;
}

.rec-count-num,
.rec-count-ring,
.rc-edge {
    will-change: opacity, transform;
}

/* ---- and the whole frame comes off when effects are turned down ----
   Settings > Effects > Off. For a machine that needs the frames more than it
   needs the ceremony: the number, the label and the ring stay, everything
   that paints across the screen goes. */
body.fx-off .rc-frame,
body.fx-off .rc-vignette,
body.fx-off .rc-edge {
    display: none !important;
}
body.fx-off .rec-count-num,
body.fx-off .rec-count-ring,
body.fx-off .rec-count-go,
body.fx-off .rec-count-dial .sweep {
    animation: none !important;
    filter: none !important;
}
body.fx-off .rec-count-num {
    background: none;
    -webkit-background-clip: border-box;
    background-clip: border-box;
    color: #fff;
}

/* ---- THE COUNT-IN LEAVES, RATHER THAN VANISHING ----
   It faded in and then simply disappeared: the class was removed and the
   innerHTML emptied in the same instant, with nothing to animate. Now the
   overlay fades and settles back a little on its way out, which is the same
   shape as every other exit in the panel. */
#recCountdown {
    transition: opacity .28s var(--ease), transform .28s var(--ease);
}
#recCountdown.leaving {
    opacity: 0;
    transform: scale(1.04);
    pointer-events: none;
}
body.fx-off #recCountdown { transition: opacity .12s linear; }
body.fx-off #recCountdown.leaving { transform: none; }


/* ==================== the admin panel and the private world ====================

   Small tools pinned physically top-left (the game world is the workspace;
   the main menu owns the right). They reuse the script's tokens, so a server
   that recolours the menu recolours these with it. */
.side-tool {
    position: fixed; left: 16px; top: 16px;
    width: 322px; max-height: 84vh;
    display: none; flex-direction: column;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 16px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, .5);
    z-index: 66;
    overflow: hidden;
}
.side-tool.visible { display: flex; animation: sideToolIn .26s var(--ease) both; }
/* the exit: same move, reversed, slightly quicker - a panel leaving should
   get out of the way */
.side-tool.visible.closing { animation: sideToolOut .2s var(--ease) both; }
@keyframes sideToolOut {
    from { opacity: 1; transform: none; }
    to   { opacity: 0; transform: translateX(-14px); }
}

.st-grant-row { display: flex; gap: 6px; margin: 0 0 10px; }
.st-grant-row input {
    flex: 1; min-width: 0;
    padding: 8px 11px; border-radius: 9px;
    border: 1px solid var(--border);
    background: rgba(0, 0, 0, .25); color: var(--text);
    font: inherit; font-size: 11.5px;
}
.st-grant-row input:focus { outline: none; border-color: var(--accent-2); }
@keyframes sideToolIn {
    from { opacity: 0; transform: translateX(-14px); }
    to   { opacity: 1; transform: none; }
}
.pworld-panel { top: auto; bottom: 16px; }

.st-head {
    display: flex; align-items: center; gap: 9px;
    padding: 12px 14px;
    border-bottom: 1px solid var(--border);
}
.st-head .st-icon {
    display: grid; place-items: center;
    width: 28px; height: 28px; border-radius: 9px;
    background: var(--accent-soft); color: var(--accent-2);
}
.st-head .st-icon svg { width: 14px; height: 14px; }
.st-head h3 { flex: 1; margin: 0; font-size: 13px; font-weight: 800; color: var(--text); }
.st-body { overflow-y: auto; padding: 10px 12px 12px; }
.st-body::-webkit-scrollbar { width: 5px; }
.st-body::-webkit-scrollbar-thumb { background: rgba(139,92,246,.25); border-radius: 3px; }

.st-player {
    border: 1px solid var(--border); border-radius: 12px;
    padding: 9px 11px; margin-bottom: 7px;
    background: rgba(255,255,255,.03);
}
.st-player-row { display: flex; align-items: center; gap: 8px; }
.st-player-name { flex: 1; min-width: 0; font-size: 12px; font-weight: 800; color: var(--text);
                  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.st-player-id { font-size: 10px; color: var(--text-faint); font-variant-numeric: tabular-nums; }
.st-chip {
    padding: 2px 8px; border-radius: 999px;
    font-size: 9.5px; font-weight: 800;
    background: var(--accent-soft); color: var(--accent-2);
}
.st-chip.warn { background: rgba(239,68,68,.15); color: var(--danger); }

.st-actions { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 8px; }
.st-btn {
    padding: 6px 11px; border-radius: 9px;
    border: 1px solid var(--border);
    background: rgba(255,255,255,.05); color: var(--text);
    font: inherit; font-size: 10.5px; font-weight: 800; cursor: pointer;
    transition: background .14s var(--ease), border-color .14s var(--ease);
}
.st-btn:hover { background: rgba(255,255,255,.09); }
.st-btn.primary { background: var(--accent-2); border-color: var(--accent-2); color: #fff; }
.st-btn.primary:hover { filter: brightness(1.1); }
.st-btn.danger { color: var(--danger); border-color: rgba(239,68,68,.4); }
.st-btn.danger:hover { background: rgba(239,68,68,.14); }

/* the per-player menu switches, shown when a player row is expanded */
.st-menus { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; margin-top: 8px; }
.st-menu {
    display: flex; align-items: center; gap: 6px;
    padding: 5px 8px; border-radius: 8px;
    border: 1px solid var(--border);
    font-size: 10px; font-weight: 700; color: var(--text);
    cursor: pointer; background: rgba(255,255,255,.03);
}
.st-menu.off { opacity: .45; text-decoration: line-through; }
.st-menu .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent-2); flex: 0 0 auto; }
.st-menu.off .dot { background: var(--text-faint); }

.st-note { font-size: 10px; color: var(--text-faint); line-height: 1.5; margin: 4px 2px 8px; }
.st-empty { padding: 14px; text-align: center; font-size: 11px; color: var(--text-faint); }

/* the crew list in the private world */
.st-crew { display: flex; flex-direction: column; gap: 5px; margin-top: 8px; }
.st-crew-row {
    display: flex; align-items: center; gap: 8px;
    padding: 7px 10px; border-radius: 10px;
    background: rgba(255,255,255,.03); border: 1px solid var(--border);
    font-size: 11px; font-weight: 700; color: var(--text);
}
.st-crew-row .dot { width: 8px; height: 8px; border-radius: 50%; background: #22c55e; }

.pw-state {
    margin: 4px 0 10px; padding: 10px 12px; border-radius: 11px;
    font-size: 11.5px; font-weight: 800; text-align: center;
}
.pw-state.in  { background: rgba(34,197,94,.12); color: #4ade80; border: 1px solid rgba(34,197,94,.3); }
.pw-state.out { background: rgba(255,255,255,.04); color: var(--text-faint); border: 1px solid var(--border); }


/* World Control's coexistence notice: another script owns weather/time on
   this server, and pretending otherwise makes both look broken. */
.world-rival {
    display: flex; align-items: center; gap: 9px;
    margin: 0 0 10px; padding: 10px 13px;
    border-radius: 11px;
    background: rgba(245, 158, 11, .1);
    border: 1px solid rgba(245, 158, 11, .35);
    color: #fbbf24; font-size: 11.5px; font-weight: 700; line-height: 1.5;
}
.world-rival svg { width: 15px; height: 15px; flex: 0 0 auto; }

/* the pworld invite row */
.pw-invite { display: flex; gap: 6px; margin-top: 10px; }
.pw-invite input {
    flex: 1; min-width: 0; padding: 8px 11px; border-radius: 9px;
    border: 1px solid var(--border); background: rgba(0,0,0,.25);
    color: var(--text); font: inherit; font-size: 11.5px;
}
.pw-invite input:focus { outline: none; border-color: var(--accent-2); }


/* the grant picker sheet */
.st-grant-sheet { border-color: var(--accent-2); }
.st-menu.pw .dot { background: #22c55e; }
.st-menu.pw.off .dot { background: var(--text-faint); }

/* THE PRIVATE-WORLD TOGGLE: lit when they have it, dim when they do not -
   the state is readable before it is clickable. */
.st-btn.pw-toggle { display: inline-flex; align-items: center; gap: 6px; opacity: .5; }
.st-btn.pw-toggle .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--text-faint); }
.st-btn.pw-toggle.on {
    opacity: 1;
    border-color: rgba(34, 197, 94, .5);
    color: #4ade80;
}
.st-btn.pw-toggle.on .dot { background: #22c55e; box-shadow: 0 0 6px #22c55e; }


/* The take-length row. The chips are the common answers; the box is for
   when the shot is 47 seconds and nobody's preset covers it. */
.cine-takelen input::placeholder { color: var(--text-faint); opacity: .8; }
.cine-len-chips { display: flex; gap: 5px; flex-wrap: wrap; margin-top: 7px; }
.cine-len-chip {
    flex: 1 1 auto; min-width: 44px;
    padding: 5px 8px; border-radius: 7px;
    background: var(--panel); border: 1px solid var(--border);
    color: var(--text-faint); font-family: inherit;
    font-size: 10px; font-weight: 700; cursor: pointer;
    transition: background .14s var(--ease), color .14s var(--ease), border-color .14s var(--ease);
}
.cine-len-chip:hover { color: var(--text); border-color: var(--border-strong); }
.cine-len-chip.on {
    background: color-mix(in srgb, var(--accent-2) 20%, transparent);
    border-color: color-mix(in srgb, var(--accent-2) 55%, transparent);
    color: var(--accent-2);
}


/* An entry held OPEN past its own length - the counterpart to .shortened.
   Different colour, because it is the opposite edit and reading the timeline
   at a glance is the whole point of it. */
.cs-bar.extended {
    background: linear-gradient(90deg,
        color-mix(in srgb, var(--accent-2) 55%, transparent),
        color-mix(in srgb, var(--accent-2) 25%, transparent));
    border-color: color-mix(in srgb, var(--accent-2) 60%, transparent);
}
.cs-bar.extended .cs-bar-time { color: var(--accent-2); }


/* THE VISIBILITY CHOICE, on the new-project row. Two buttons rather than a
   checkbox: "shared" and "mine alone" are both real answers and a checkbox
   makes one of them look like the absence of the other. */
.cine-share-row {
    display: flex; flex-wrap: wrap; gap: 6px;
    margin: 0 0 8px; padding: 8px;
    border-radius: 10px;
    background: rgba(0,0,0,.18);
    border: 1px solid var(--border);
}
.cine-share-opt {
    flex: 1 1 40%;
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    padding: 7px 10px; border-radius: 8px;
    background: var(--panel); border: 1px solid var(--border);
    color: var(--text-faint); font-family: inherit;
    font-size: 11px; font-weight: 700; cursor: pointer;
    transition: background .14s var(--ease), color .14s var(--ease), border-color .14s var(--ease);
}
.cine-share-opt svg { width: 13px; height: 13px; }
.cine-share-opt:hover { color: var(--text); border-color: var(--border-strong); }
.cine-share-opt.on {
    background: color-mix(in srgb, var(--accent-2) 20%, transparent);
    border-color: color-mix(in srgb, var(--accent-2) 55%, transparent);
    color: var(--accent-2);
}
.cine-share-hint {
    flex: 1 1 100%; margin: 2px 0 0;
    font-size: 10px; line-height: 1.5; color: var(--text-faint);
}

/* and the reminder in the header of an open project */
.cine-share-badge {
    display: inline-flex; align-items: center;
    margin-inline-start: 6px;
    color: var(--accent-2); opacity: .85;
}
.cine-share-badge.solo { color: var(--text-faint); }
.cine-share-badge svg { width: 14px; height: 14px; }


/* An icon button that is ON says so. The crowd row's lock (solid/passable)
   carried this class with no rule behind it - an active state in the markup
   and nothing on the screen. */
.icon-btn.on {
    color: var(--accent-2);
    border-color: color-mix(in srgb, var(--accent-2) 55%, transparent);
    background: color-mix(in srgb, var(--accent-2) 16%, transparent);
}
