body {
    background: var(--bs-tertiary-bg);
}

.workspace-sidebar {
    width: 17rem;
}

.workspace-sidebar .nav-link {
    color: var(--bs-secondary-color);
}

.workspace-sidebar .nav-link.active {
    background: var(--bs-primary-bg-subtle);
    color: var(--bs-primary-text-emphasis);
    font-weight: 600;
}

@media (min-width: 992px) {
    .workspace-sidebar {
        min-height: calc(100vh - 57px);
    }
}

.scene-import-paragraph {
    cursor: pointer;
    transition: background-color .15s ease-in-out;
}

.scene-import-paragraph:not(.scene-import-paragraph--first):hover {
    background: var(--bs-primary-bg-subtle);
}

.scene-import-paragraph--first {
    cursor: default;
}

.scene-import-paragraph__marker {
    display: none;
}

.scene-import-paragraph--boundary:not(.scene-import-paragraph--first) {
    border-top: 3px solid var(--bs-primary);
}

.scene-import-paragraph--boundary:not(.scene-import-paragraph--first) .scene-import-paragraph__marker {
    display: block;
}

.scene-import-paragraph--discarded,
.scene-import-paragraph--discarded:hover {
    background: var(--bs-tertiary-bg);
    color: var(--bs-tertiary-color);
}

/*
 * Story version colors — a small curated pastel palette (mirrors
 * App\Entity\StoryVersion::COLORS; keep both lists in sync). Each
 * .story-color-* class only defines the two custom properties; the actual
 * background application lives in the generic [class*="story-color-"]
 * rule below, so the sidebar/header chrome for whichever version is
 * "active" picks up the right tint without one rule per color.
 */
.story-color-blue { --story-bg: #dbe9fb; --story-accent: #6ea8dc; }
.story-color-green { --story-bg: #dcf3e3; --story-accent: #6cbf8b; }
.story-color-purple { --story-bg: #e6ddf7; --story-accent: #9b7bd4; }
.story-color-pink { --story-bg: #fbdde9; --story-accent: #dd6f9c; }
.story-color-orange { --story-bg: #fde7d0; --story-accent: #e0983f; }
.story-color-yellow { --story-bg: #faf1bf; --story-accent: #d4b23f; }
.story-color-teal { --story-bg: #d7f1ee; --story-accent: #3fa89e; }
.story-color-red { --story-bg: #fadcda; --story-accent: #d97066; }

.workspace-sidebar[class*="story-color-"] {
    /* Both elements also carry Bootstrap's .bg-body utility class, which —
       like all Bootstrap utilities — is itself declared with !important so
       it reliably wins over component styles. Matching that here is what
       actually lets this rule take effect; without it, .bg-body's
       !important wins regardless of this selector's higher specificity,
       since specificity is only a tiebreaker among rules of equal
       !important weight. */
    background-color: var(--story-bg) !important;
}

/* The story version list on the project overview page: the version
   currently active elsewhere in the workspace (see project/_sidebar's
   "Overview" link, which carries it back via ?version=) gets a colored
   left border instead of the shared background tint above, since several
   list items sit close together here rather than filling the whole
   sidebar. */
.list-group-item.active-version[class*="story-color-"] {
    border-left: 4px solid var(--story-accent);
}

/* The per-scene version badge on the scene list page: same override
   rationale as .workspace-sidebar above — .text-bg-secondary sets its own
   background-color/color with !important, so this needs !important too to
   win, not higher specificity. Text color is fixed dark rather than
   var(--story-accent) since the accent tone is calibrated for use as a thin
   border/dot against a light background, not as body text on the lighter
   --story-bg fill these badges use. */
.badge[class*="story-color-"] {
    background-color: var(--story-bg) !important;
    color: #3a3a3a !important;
}

.story-color-dot {
    display: inline-block;
    width: .7rem;
    height: .7rem;
    border-radius: 50%;
    background: var(--story-accent);
    flex-shrink: 0;
}

/* The color picker on the "new version"/"edit version" forms: reskins
   Symfony's expanded ChoiceType radios as clickable pastel circles,
   Chrome-profile-picker style. Hex values here are the same 8 as above,
   duplicated because there's no per-choice class to hook a custom
   property to (Symfony gives each radio a "value" attribute instead).
   Bootstrap's choice_widget_expanded block wraps the radios in its own
   generated <div> (no class of its own) inside .story-color-picker, so the
   flex layout has to target that direct child rather than
   .story-color-picker itself — putting it on .story-color-picker was a
   no-op, since it then had only that one wrapper div as its sole flex
   item and the radios inside it kept stacking as ordinary block-level
   divs. */
.story-color-picker > div {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}

.story-color-picker .form-check {
    margin: 0;
    padding: 0;
}

.story-color-picker .form-check-input {
    appearance: none;
    width: 1.75rem;
    height: 1.75rem;
    margin: 0;
    border-radius: 50%;
    border: 2px solid rgba(0, 0, 0, .1);
    cursor: pointer;
}

.story-color-picker .form-check-input:checked {
    border-color: darkgray;
    box-shadow: 0 0 0 2px darkgray, 0 0 0 4px darkgray;
}

.story-color-picker .form-check-label {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.story-color-picker input[value="blue"] { background-color: #dbe9fb; }
.story-color-picker input[value="green"] { background-color: #dcf3e3; }
.story-color-picker input[value="purple"] { background-color: #e6ddf7; }
.story-color-picker input[value="pink"] { background-color: #fbdde9; }
.story-color-picker input[value="orange"] { background-color: #fde7d0; }
.story-color-picker input[value="yellow"] { background-color: #faf1bf; }
.story-color-picker input[value="teal"] { background-color: #d7f1ee; }
.story-color-picker input[value="red"] { background-color: #fadcda; }

/*
 * Organisational unit outline tree — nested, draggable lists of folders
 * (acts/chapters/custom-typed units) and scenes, rendered by Sortable.js
 * (organisational_unit_tree_controller.js). Indentation comes from nesting
 * plain <ul>/<li> elements, not absolute positioning, so no pixel constants
 * need to stay in sync with the JS the way the old scene graph's did.
 */
.organisational-unit-tree,
.organisational-unit-tree .organisational-unit-tree {
    list-style: none;
    margin: 0;
    padding: 0;
}

.organisational-unit-tree .organisational-unit-tree {
    margin-top: .25rem;
    margin-left: 1.25rem;
    padding-left: .75rem;
    border-left: 1px solid var(--bs-border-color);
}

/* The <li> wrapping an OU node also wraps its own nested <ul> of children
   (the standard nested-Sortable-lists shape) — .organisational-unit-item is
   that plain wrapper, while .organisational-unit-node is the visual "row"
   card, either the wrapped <div> for an OU or the <li> itself for a
   childless Scene leaf. */
.organisational-unit-item {
    margin-bottom: .25rem;
}

.organisational-unit-node {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .4rem .5rem;
    background-color: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    border-left: 3px solid var(--story-accent, var(--bs-secondary));
    border-radius: .375rem;
}

.organisational-unit-node--scene {
    border-left-style: dashed;
    margin-bottom: .25rem;
}

.organisational-unit-tree .drag-handle {
    cursor: grab;
    color: var(--bs-secondary-color);
    flex: 0 0 auto;
}

.organisational-unit-tree li.sortable-ghost {
    opacity: .4;
}

.organisational-unit-tree li.sortable-chosen > .organisational-unit-node {
    box-shadow: 0 1px 4px rgba(0, 0, 0, .12);
}

.organisational-unit-toast {
    position: fixed;
    bottom: 1rem;
    left: 50%;
    transform: translateX(-50%);
    z-index: 1080;
    margin: 0;
    white-space: nowrap;
}

/*
 * Compile page's scene-selection tree — a non-draggable cousin of the
 * organisational unit outline tree above (nested <ul>/<li>, indentation via
 * a left border, the same OU-vs-Scene "wrapped <div> or the <li> itself"
 * node styling convention), but every node carries a checkbox: a folder's
 * is a client-side group toggle (checked/unchecked/indeterminate, derived
 * from its descendant scenes — see compile_form_controller.js), a scene's
 * is what actually gets submitted.
 */
.compile-scene-selection-tree,
.compile-scene-selection-tree .compile-scene-selection-tree {
    list-style: none;
    margin: 0;
    padding: 0;
}

.compile-scene-selection-tree .compile-scene-selection-tree {
    margin-top: .25rem;
    margin-left: 1.25rem;
    padding-left: .75rem;
    border-left: 1px solid var(--bs-border-color);
}

.compile-scene-selection-item {
    margin-bottom: .25rem;
}

.compile-scene-selection-node {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .4rem .5rem;
    background-color: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    border-left: 3px solid var(--story-accent, var(--bs-secondary));
    border-radius: .375rem;
}

.compile-scene-selection-node--scene {
    border-left-style: dashed;
    margin-bottom: .25rem;
}

.compile-status-badge {
    cursor: pointer;
    border: 0;
}

/* The "Select all"/"Select none" quick-select badges above the scene tree —
   unlike the by-status badges below them, which get their fill from the
   project's own story-color palette, these two have no per-item color of
   their own, so they get a small dedicated filled/outline pair instead:
   "Select all" solid, "Select none" just an outline. Both share the same
   border so switching between the two doesn't shift either badge's size. */
.compile-quick-select-badge {
    cursor: pointer;
    border: 1px solid var(--bs-primary);
}

.compile-quick-select-badge--outline {
    background-color: transparent;
    color: var(--bs-primary);
}

.compile-step-pill.active {
    pointer-events: none;
}

/* The organize view's right-click context menu (organisational-unit-
   context-menu controller): position: fixed is set here rather than
   inline alongside the JS-set left/top, since the menu is appended
   straight to <body> — escaping the tree card's own stacking context — and
   a max-height/scroll guards against a "change status" submenu overflowing
   the viewport on a project with a long status list. */
.organisational-unit-context-menu {
    position: fixed;
    max-height: 80vh;
    overflow-y: auto;
}

.organisational-unit-context-menu .dropdown-item {
    cursor: pointer;
}
